#include #include #include #include #include #include #include #define MAX_NODES 128 #define MAX_SENSORS 8 #define MAX_BUFFER 1024 #define USERNAME "antoine" #define FILES_PATH "/home/antoine/PFE_DEMO/files/" #define TOFLASH_PATH "/home/antoine/PFE_DEMO/toflash/" #define PLAYBOOK_PATH "/home/antoine/PFE_DEMO/ansible.yml" typedef struct node { char *ip; char *sensors[MAX_SENSORS]; int n_sensors; } Node; typedef struct experiment { int exp_id; int n_nodes; char *date; char *file; char *duration; char *name; char *arch; char *dir; char *exp_name; Node nodes[MAX_NODES]; } Experiment; void process_line(char *line, Experiment *experiment) { char *key; char *value; char *save_ptr; key = strtok_r(line, ":", &save_ptr); if(!strcmp(key, "date")) { value = strtok_r(NULL, "\n", &save_ptr); experiment->date = strdup(value + 1); } else if(!strcmp(key, "name")) { value = strtok_r(NULL, "\n", &save_ptr); experiment->name = strdup(value + 1); } else if(!strcmp(key, "dir")) { value = strtok_r(NULL, "\n", &save_ptr); experiment->dir = strdup(value + 1); } else if(!strcmp(key, "arch")) { value = strtok_r(NULL, "\n", &save_ptr); experiment->arch = strdup(value + 1); } else if(!strcmp(key, "exp_id")) { value = strtok_r(NULL, "\n", &save_ptr); experiment->exp_id = atoi(value + 1); } else if(!strcmp(key, "time")) { value = strtok_r(NULL, "\n", &save_ptr); experiment->duration = strdup(value + 1); } else if(!strcmp(key, "file")) { value = strtok_r(NULL, "\n", &save_ptr); experiment->file = strdup(value + 1); } else if(!strcmp(key, "nodes")) { value = strtok_r(NULL, "\n", &save_ptr) + 2; char *nodes_list = strtok_r(value, "]", &save_ptr); char *node; char *save_ptr_node; int present = 0; node = strtok_r(nodes_list, ",", &save_ptr); while(node != NULL) { char *sensor = strtok_r(node, "@", &save_ptr_node); char *ip = strtok_r(NULL, "@", &save_ptr_node); if(experiment->n_nodes == 0) { Node n; n.n_sensors = 1; n.ip = strdup(ip); n.sensors[0] = strdup(sensor); experiment->nodes[0] = n; experiment->n_nodes++; } else { for(int i = 0; i < experiment->n_nodes; i++) { if(!strcmp(experiment->nodes[i].ip, ip)) { int nb = experiment->nodes[i].n_sensors; experiment->nodes[i].sensors[nb] = strdup(sensor); experiment->nodes[i].n_sensors++; present = 1; } } if(!present) { Node n; n.n_sensors = 1; n.ip = strdup(ip); n.sensors[0] = strdup(sensor); experiment->nodes[experiment->n_nodes] = n; experiment->n_nodes++; } present = 0; } node = strtok_r(NULL, ",", &save_ptr); if(node != NULL && *node == ' ') { node++; } } } } Experiment *read_file(char *file_name) { char ch; char buffer[MAX_BUFFER]; FILE *fp; Experiment *experiment = (Experiment*) malloc(sizeof(Experiment)); experiment->n_nodes = 0; fp = fopen(file_name, "r"); if(fp == NULL) { perror("Error while opening the file.\n"); exit(EXIT_FAILURE); } while(fgets(buffer, MAX_BUFFER, fp) != NULL) { process_line(buffer, experiment); } fclose(fp); return experiment; } int check_date(Experiment *experiment) { time_t now; time(&now); struct tm tm = { 0 }; strptime(experiment->date, "%Y-%m-%dT%H:%M", &tm); time_t t = mktime(&tm); if(t <= now) { printf("Starting deployment of \"[%d] %s\" ...\n", experiment->exp_id, experiment->name); return 0; } return 1; } int process_time(Experiment *experiment) { char duration[8]; strcpy(duration, experiment->duration); char *hour; char *min; hour = strtok(duration, ":"); min = strtok(NULL, "\0"); return atoi(hour) * 3600 + atoi(min) * 60; } int binary_not_present(Experiment *experiment) { char path[512]; strcpy(path, FILES_PATH); strcat(path, experiment->dir); strcat(path, "/out.bin"); FILE *file; if(file = fopen(path, "r")) { fclose(file); return 0; } return 1; } int process_exp(Experiment *experiment) { if(check_date(experiment)) { return 1; } char docker_cmd[1024]; if(!strcmp(experiment->arch, "arm")) { if(binary_not_present(experiment)) { sprintf(docker_cmd, "docker run --rm -v %s:/exp -e SRC_NAME=\"%s\" -e SRC_DIR=\"%s\" arm_compiler", FILES_PATH, experiment->file, experiment->dir ); exec_prog(docker_cmd); } } int time_sec = process_time(experiment); char cmd1[1024]; char cmd2[1024]; char sensors_list[512]; strcpy(sensors_list, ""); for(int i = 0; i < experiment->n_nodes; i++) { for(int j = 0; j < experiment->nodes[i].n_sensors; j++) { strcat(sensors_list, experiment->nodes[i].sensors[j]); if(j < experiment->nodes[i].n_sensors - 1) { strcat(sensors_list, "\n"); } } sprintf(cmd2, "mkdir ~/exp_%d", experiment->exp_id); sprintf(cmd1, "runuser -l %s -c \'echo \"%s\" | ssh pi@%s \"%s && cat > ~/exp_%d/config_experimentation.txt\"\'", USERNAME, sensors_list, experiment->nodes[i].ip, cmd2, experiment->exp_id); exec_prog(cmd1); } char hosts_filename[64]; sprintf(hosts_filename, "/etc/ansible/exp_%d.hosts", experiment->exp_id); FILE *hosts_fp = fopen(hosts_filename, "w"); fprintf(hosts_fp, "[exp_%d]\n", experiment->exp_id); for(int i = 0; i < experiment->n_nodes; i++) { fprintf(hosts_fp, "%s ansible_user=pi\n", experiment->nodes[i].ip); } fclose(hosts_fp); char ansible_command[512]; sprintf(ansible_command, "runuser -l %s -c \'ansible-playbook %s -i %s -e \"servernames=exp_%d exp_duration=%d binary_dir=%s exp_name=%s\"\'", USERNAME, PLAYBOOK_PATH, hosts_filename, experiment->exp_id, time_sec, experiment->dir, experiment->exp_name); exec_prog_background(ansible_command); return 0; } void print_exp(Experiment *experiment) { printf("== EXP[%d] : %s ==\n%s during %s with the file %s (%s) on the %d nodes :\n", experiment->exp_id, experiment->exp_name, experiment->date, experiment->duration, experiment->file, experiment->arch, experiment->n_nodes); for(int i = 0; i < experiment->n_nodes; i++) { printf("* %s\n", experiment->nodes[i].ip); for(int j = 0; j < experiment->nodes[i].n_sensors; j++) { printf(" - %s\n", experiment->nodes[i].sensors[j]); } } } void free_exp(Experiment *experiment) { free(experiment->date); free(experiment->duration); free(experiment->file); free(experiment->arch); free(experiment->dir); free(experiment->name); free(experiment->exp_name); for(int i = 0; i < experiment->n_nodes; i++) { for(int j = 0; j < experiment->nodes[i].n_sensors; j++) { free(experiment->nodes[i].sensors[j]); } free(experiment->nodes[i].ip); } free(experiment); } void check_files() { DIR *dir; struct dirent *dirent; dir = opendir(TOFLASH_PATH); if(dir != NULL) { while(dirent = readdir(dir)) { if((dirent->d_type == DT_REG) && (strstr(dirent->d_name, ".started") == NULL)) { char file_name[128]; char new_file_name[128]; strcpy(file_name, TOFLASH_PATH); strcat(file_name, dirent->d_name); Experiment *experiment = read_file(file_name); experiment->exp_name = strdup(dirent->d_name); #ifdef DEBUG print_exp(experiment); #endif if(!process_exp(experiment)) { strcpy(new_file_name, file_name); strcat(new_file_name, ".started"); rename(file_name, new_file_name); } free_exp(experiment); } } closedir(dir); } else { perror("Dossier toflash non trouvable"); exit(EXIT_FAILURE); } return; } int exec_prog(char *cmd) { if(system(cmd) == -1) { return 1; } return 0; } int exec_prog_background(char *cmd) { if(!fork()) { system(cmd); return 0; } return 1; } int main(int argc, char **argv) { while(1) { check_files(); sleep(10); } return 0; }