| @@ -0,0 +1,323 @@ |
| @@ -0,0 +1,323 @@ |
| |
1
| +#include <stdio.h> |
| |
2
| +#include <time.h> |
| |
3
| +#include <unistd.h> |
| |
4
| +#include <stdlib.h> |
| |
5
| +#include <string.h> |
| |
6
| +#include <dirent.h> |
| |
7
| +#include <sys/types.h> |
| |
8
| + |
| |
9
| +#define MAX_NODES 128 |
| |
10
| +#define MAX_SENSORS 8 |
| |
11
| +#define MAX_BUFFER 1024 |
| |
12
| +#define USERNAME "antoine" |
| |
13
| +#define FILES_PATH "/home/antoine/pfe/files/" |
| |
14
| +#define TOFLASH_PATH "./toflash/" |
| |
15
| + |
| |
16
| +typedef struct node { |
| |
17
| + char *ip; |
| |
18
| + char *sensors[MAX_SENSORS]; |
| |
19
| + int n_sensors; |
| |
20
| +} Node; |
| |
21
| + |
| |
22
| +typedef struct experiment { |
| |
23
| + int exp_id; |
| |
24
| + int n_nodes; |
| |
25
| + char *date; |
| |
26
| + char *file; |
| |
27
| + char *duration; |
| |
28
| + char *name; |
| |
29
| + char *arch; |
| |
30
| + char *dir; |
| |
31
| + Node nodes[MAX_NODES]; |
| |
32
| +} Experiment; |
| |
33
| + |
| |
34
| +void process_line(char *line, Experiment *experiment) { |
| |
35
| + char *key; |
| |
36
| + char *value; |
| |
37
| + char *save_ptr; |
| |
38
| + key = strtok_r(line, ":", &save_ptr); |
| |
39
| + if(!strcmp(key, "date")) { |
| |
40
| + value = strtok_r(NULL, "\n", &save_ptr); |
| |
41
| + experiment->date = strdup(value + 1); |
| |
42
| + } |
| |
43
| + else if(!strcmp(key, "name")) { |
| |
44
| + value = strtok_r(NULL, "\n", &save_ptr); |
| |
45
| + experiment->name = strdup(value + 1); |
| |
46
| + } |
| |
47
| + else if(!strcmp(key, "dir")) { |
| |
48
| + value = strtok_r(NULL, "\n", &save_ptr); |
| |
49
| + experiment->dir = strdup(value + 1); |
| |
50
| + } |
| |
51
| + else if(!strcmp(key, "arch")) { |
| |
52
| + value = strtok_r(NULL, "\n", &save_ptr); |
| |
53
| + experiment->arch = strdup(value + 1); |
| |
54
| + } |
| |
55
| + else if(!strcmp(key, "exp_id")) { |
| |
56
| + value = strtok_r(NULL, "\n", &save_ptr); |
| |
57
| + experiment->exp_id = atoi(value + 1); |
| |
58
| + } |
| |
59
| + else if(!strcmp(key, "time")) { |
| |
60
| + value = strtok_r(NULL, "\n", &save_ptr); |
| |
61
| + experiment->duration = strdup(value + 1); |
| |
62
| + } |
| |
63
| + else if(!strcmp(key, "file")) { |
| |
64
| + value = strtok_r(NULL, "\n", &save_ptr); |
| |
65
| + experiment->file = strdup(value + 1); |
| |
66
| + } |
| |
67
| + else if(!strcmp(key, "nodes")) { |
| |
68
| + value = strtok_r(NULL, "\n", &save_ptr) + 2; |
| |
69
| + char *nodes_list = strtok_r(value, "]", &save_ptr); |
| |
70
| + char *node; |
| |
71
| + char *save_ptr_node; |
| |
72
| + int present = 0; |
| |
73
| + |
| |
74
| + node = strtok_r(nodes_list, ",", &save_ptr); |
| |
75
| + |
| |
76
| + while(node != NULL) { |
| |
77
| + char *sensor = strtok_r(node, "@", &save_ptr_node); |
| |
78
| + char *ip = strtok_r(NULL, "@", &save_ptr_node); |
| |
79
| + |
| |
80
| + if(experiment->n_nodes == 0) { |
| |
81
| + Node n; |
| |
82
| + n.n_sensors = 1; |
| |
83
| + n.ip = strdup(ip); |
| |
84
| + n.sensors[0] = strdup(sensor); |
| |
85
| + experiment->nodes[0] = n; |
| |
86
| + experiment->n_nodes++; |
| |
87
| + } |
| |
88
| + |
| |
89
| + else { |
| |
90
| + for(int i = 0; i < experiment->n_nodes; i++) { |
| |
91
| + if(!strcmp(experiment->nodes[i].ip, ip)) { |
| |
92
| + int nb = experiment->nodes[i].n_sensors; |
| |
93
| + experiment->nodes[i].sensors[nb] = strdup(sensor); |
| |
94
| + experiment->nodes[i].n_sensors++; |
| |
95
| + present = 1; |
| |
96
| + } |
| |
97
| + } |
| |
98
| + if(!present) { |
| |
99
| + Node n; |
| |
100
| + n.n_sensors = 1; |
| |
101
| + n.ip = strdup(ip); |
| |
102
| + n.sensors[0] = strdup(sensor); |
| |
103
| + experiment->nodes[experiment->n_nodes] = n; |
| |
104
| + experiment->n_nodes++; |
| |
105
| + } |
| |
106
| + present = 0; |
| |
107
| + } |
| |
108
| + |
| |
109
| + node = strtok_r(NULL, ",", &save_ptr); |
| |
110
| + if(node != NULL && *node == ' ') { |
| |
111
| + node++; |
| |
112
| + } |
| |
113
| + } |
| |
114
| + } |
| |
115
| +} |
| |
116
| + |
| |
117
| +Experiment *read_file(char *file_name) { |
| |
118
| + char ch; |
| |
119
| + char buffer[MAX_BUFFER]; |
| |
120
| + FILE *fp; |
| |
121
| + Experiment *experiment = (Experiment*) malloc(sizeof(Experiment)); |
| |
122
| + experiment->n_nodes = 0; |
| |
123
| + |
| |
124
| + fp = fopen(file_name, "r"); |
| |
125
| + |
| |
126
| + if(fp == NULL) { |
| |
127
| + perror("Error while opening the file.\n"); |
| |
128
| + exit(EXIT_FAILURE); |
| |
129
| + } |
| |
130
| + |
| |
131
| + while(fgets(buffer, MAX_BUFFER, fp) != NULL) { |
| |
132
| + process_line(buffer, experiment); |
| |
133
| + } |
| |
134
| + |
| |
135
| + fclose(fp); |
| |
136
| + return experiment; |
| |
137
| +} |
| |
138
| + |
| |
139
| +int check_date(Experiment *experiment) { |
| |
140
| + time_t now; |
| |
141
| + time(&now); |
| |
142
| + |
| |
143
| + struct tm tm = { 0 }; |
| |
144
| + strptime(experiment->date, "%Y-%m-%dT%H:M", &tm); |
| |
145
| + time_t t = mktime(&tm); |
| |
146
| + |
| |
147
| + if(t <= now) { |
| |
148
| + printf("Starting deployment of \"[%d] %s\" ...\n", experiment->exp_id, experiment->name); |
| |
149
| + return 0; |
| |
150
| + } |
| |
151
| + return 1; |
| |
152
| +} |
| |
153
| + |
| |
154
| +int process_time(Experiment *experiment) { |
| |
155
| + char duration[8]; |
| |
156
| + strcpy(duration, experiment->duration); |
| |
157
| + char *hour; |
| |
158
| + char *min; |
| |
159
| + hour = strtok(duration, ":"); |
| |
160
| + min = strtok(NULL, "\0"); |
| |
161
| + return atoi(hour) * 3600 + atoi(min) * 60; |
| |
162
| +} |
| |
163
| + |
| |
164
| +int binary_not_present(Experiment *experiment) { |
| |
165
| + char path[512]; |
| |
166
| + strcpy(path, FILES_PATH); |
| |
167
| + strcat(path, experiment->dir); |
| |
168
| + strcat(path, "/out.bin"); |
| |
169
| + FILE *file; |
| |
170
| + if(file = fopen(path, "r")) { |
| |
171
| + fclose(file); |
| |
172
| + return 0; |
| |
173
| + } |
| |
174
| + return 1; |
| |
175
| +} |
| |
176
| + |
| |
177
| +int process_exp(Experiment *experiment) { |
| |
178
| + if(check_date(experiment)) { |
| |
179
| + return 1; |
| |
180
| + } |
| |
181
| + |
| |
182
| + char docker_cmd[1024]; |
| |
183
| + |
| |
184
| + if(!strcmp(experiment->arch, "arm")) { |
| |
185
| + if(binary_not_present(experiment)) { |
| |
186
| + sprintf(docker_cmd, "docker run --rm -v %s:/exp -e SRC_NAME=\"%s\" -e SRC_DIR=\"%s\" arm_compiler", |
| |
187
| + FILES_PATH, |
| |
188
| + experiment->file, |
| |
189
| + experiment->dir |
| |
190
| + ); |
| |
191
| + exec_prog(docker_cmd); |
| |
192
| + } |
| |
193
| + } |
| |
194
| + |
| |
195
| + int time_sec = process_time(experiment); |
| |
196
| + char cmd1[1024]; |
| |
197
| + char cmd2[1024]; |
| |
198
| + char sensors_list[512]; |
| |
199
| + strcpy(sensors_list, ""); |
| |
200
| + for(int i = 0; i < experiment->n_nodes; i++) { |
| |
201
| + for(int j = 0; j < experiment->nodes[i].n_sensors; j++) { |
| |
202
| + strcat(sensors_list, experiment->nodes[i].sensors[j]); |
| |
203
| + if(j < experiment->nodes[i].n_sensors - 1) { |
| |
204
| + strcat(sensors_list, "\n"); |
| |
205
| + } |
| |
206
| + } |
| |
207
| + sprintf(cmd2, "mkdir ~/exp_%d", experiment->exp_id); |
| |
208
| + sprintf(cmd1, "runuser -l %s -c \'echo \"%s\" | ssh pi@%s \"%s && cat > ~/exp_%d/sensors.txt\"\'", |
| |
209
| + USERNAME, |
| |
210
| + sensors_list, |
| |
211
| + experiment->nodes[i].ip, |
| |
212
| + cmd2, |
| |
213
| + experiment->exp_id); |
| |
214
| + exec_prog(cmd1); |
| |
215
| + } |
| |
216
| + |
| |
217
| + char hosts_filename[64]; |
| |
218
| + sprintf(hosts_filename, "/etc/ansible/exp_%d.hosts", experiment->exp_id); |
| |
219
| + FILE *hosts_fp = fopen(hosts_filename, "w"); |
| |
220
| + fprintf(hosts_fp, "[exp_%d]\n", experiment->exp_id); |
| |
221
| + for(int i = 0; i < experiment->n_nodes; i++) { |
| |
222
| + fprintf(hosts_fp, "%s ansible_user=pi\n", experiment->nodes[i].ip); |
| |
223
| + } |
| |
224
| + fclose(hosts_fp); |
| |
225
| + |
| |
226
| + char ansible_command[512]; |
| |
227
| + sprintf(ansible_command, "runuser -l %s -c \'ansible-playbook /etc/ansible/roles/test.yml -i %s -e \"servernames=exp_%d exp_duration=%d binary_dir=%s\"\'", |
| |
228
| + USERNAME, |
| |
229
| + hosts_filename, |
| |
230
| + experiment->exp_id, |
| |
231
| + time_sec, |
| |
232
| + experiment->dir); |
| |
233
| + exec_prog_background(ansible_command); |
| |
234
| + |
| |
235
| + return 0; |
| |
236
| +} |
| |
237
| + |
| |
238
| +void print_exp(Experiment *experiment) { |
| |
239
| + printf("== EXP[%d] : %s ==\n%s during %s with the file %s (%s) on the %d nodes :\n", |
| |
240
| + experiment->exp_id, |
| |
241
| + experiment->name, |
| |
242
| + experiment->date, |
| |
243
| + experiment->duration, |
| |
244
| + experiment->file, |
| |
245
| + experiment->arch, |
| |
246
| + experiment->n_nodes); |
| |
247
| + for(int i = 0; i < experiment->n_nodes; i++) { |
| |
248
| + printf("* %s\n", experiment->nodes[i].ip); |
| |
249
| + for(int j = 0; j < experiment->nodes[i].n_sensors; j++) { |
| |
250
| + printf(" - %s\n", experiment->nodes[i].sensors[j]); |
| |
251
| + } |
| |
252
| + } |
| |
253
| +} |
| |
254
| + |
| |
255
| +void free_exp(Experiment *experiment) { |
| |
256
| + free(experiment->date); |
| |
257
| + free(experiment->duration); |
| |
258
| + free(experiment->file); |
| |
259
| + free(experiment->arch); |
| |
260
| + free(experiment->dir); |
| |
261
| + free(experiment->name); |
| |
262
| + for(int i = 0; i < experiment->n_nodes; i++) { |
| |
263
| + for(int j = 0; j < experiment->nodes[i].n_sensors; j++) { |
| |
264
| + free(experiment->nodes[i].sensors[j]); |
| |
265
| + } |
| |
266
| + free(experiment->nodes[i].ip); |
| |
267
| + } |
| |
268
| + free(experiment); |
| |
269
| +} |
| |
270
| + |
| |
271
| +void check_files() { |
| |
272
| + DIR *dir; |
| |
273
| + struct dirent *dirent; |
| |
274
| + dir = opendir(TOFLASH_PATH); |
| |
275
| + |
| |
276
| + if(dir != NULL) { |
| |
277
| + while(dirent = readdir(dir)) { |
| |
278
| + if(dirent->d_type == DT_REG) { |
| |
279
| + char file_name[128]; |
| |
280
| + strcpy(file_name, TOFLASH_PATH); |
| |
281
| + strcat(file_name, dirent->d_name); |
| |
282
| + Experiment *experiment = read_file(file_name); |
| |
283
| +#ifdef DEBUG |
| |
284
| + print_exp(experiment); |
| |
285
| +#endif |
| |
286
| + if(!process_exp(experiment)) { |
| |
287
| + remove(file_name); |
| |
288
| + } |
| |
289
| + free_exp(experiment); |
| |
290
| + } |
| |
291
| + } |
| |
292
| + closedir(dir); |
| |
293
| + } |
| |
294
| + else { |
| |
295
| + perror("Dossier toflash non trouvable"); |
| |
296
| + exit(EXIT_FAILURE); |
| |
297
| + } |
| |
298
| + |
| |
299
| + return; |
| |
300
| +} |
| |
301
| + |
| |
302
| +int exec_prog(char *cmd) { |
| |
303
| + if(system(cmd) == -1) { |
| |
304
| + return 1; |
| |
305
| + } |
| |
306
| + return 0; |
| |
307
| +} |
| |
308
| + |
| |
309
| +int exec_prog_background(char *cmd) { |
| |
310
| + if(!fork()) { |
| |
311
| + system(cmd); |
| |
312
| + return 0; |
| |
313
| + } |
| |
314
| + return 1; |
| |
315
| +} |
| |
316
| + |
| |
317
| +int main(int argc, char **argv) { |
| |
318
| + while(1) { |
| |
319
| + check_files(); |
| |
320
| + sleep(10); |
| |
321
| + } |
| |
322
| + return 0; |
| |
323
| +} |
0
| \ No newline at end of file |
324
| \ No newline at end of file |