From fb2a766ecd7c44f1ea15a6e20c50adbe4a0ea832 Mon Sep 17 00:00:00 2001 From: Duquenoy Date: Sun, 17 Feb 2019 15:39:19 +0100 Subject: [PATCH] Programme C serveur : lecture, compilation, flashage --- Ansible/ansible.yml | 47 +++++++++++++++++++++++++++++++++++++++++++++++ Docker/arm_mbed/Dockerfile | 14 ++++++++++++++ Docker/arm_mbed/start.sh | 9 +++++++++ Serveur/exp_example.yml | 8 ++++++++ Serveur/files/pfe_1549034948676/test.cpp | 33 +++++++++++++++++++++++++++++++++ Serveur/main | Bin 0 -> 18048 bytes Serveur/main.c | 323 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Serveur/serial | 1 + 8 files changed, 435 insertions(+), 0 deletions(-) create mode 100644 Ansible/ansible.yml create mode 100644 Docker/arm_mbed/Dockerfile create mode 100644 Docker/arm_mbed/start.sh create mode 100644 Serveur/exp_example.yml create mode 100644 Serveur/files/pfe_1549034948676/test.cpp create mode 100755 Serveur/main create mode 100644 Serveur/main.c create mode 100644 Serveur/serial diff --git a/Ansible/ansible.yml b/Ansible/ansible.yml new file mode 100644 index 0000000..f8f97b4 --- /dev/null +++ b/Ansible/ansible.yml @@ -0,0 +1,47 @@ +--- + +- hosts: "{{ servernames }}" + + tasks: + + - name: "Création du dossier de résulats" + file: + path: /home/pi/{{ servernames }}/res + state: directory + recurse: yes + + - name: "Copie du fichier de lecture série" + copy: + src: ~/pfe/serial + dest: /home/pi/{{ servernames }}/serial + + - name: "Copie du binaire pour le(s) capteur(s)" + copy: + src: ~/pfe/files/{{ binary_dir }}/out.bin + dest: /home/pi/{{ servernames }}/out.bin + + - name: "Lancement du programme de lecture série" + command: /home/pi/while + async: 3000000 + poll: 0 + + - name: "Exp en cours ..." + pause: + seconds: "{{ exp_duration }}" + + - name: "Kill de l'application" + shell: pkill while + + - name: "Récupération des noms des résultats" + shell: (cd /home/pi/{{ servernames }}/res; find . -maxdepth 1 -type f) | cut -d'/' -f2 + register: files_to_copy + + - name: "Copie des résultats sur le serveur" + fetch: + src: /home/pi/{{ servernames }}/res/{{ item }} + dest: /home/antoine/pfe_results/{{ servernames }}/{{ ansible_host }}/ + flat: yes + with_items: "{{ files_to_copy.stdout_lines }}" + + - name: "Suppression du dossier sur le noeud" + shell: rm -rf /home/pi/{{ servernames }} diff --git a/Docker/arm_mbed/Dockerfile b/Docker/arm_mbed/Dockerfile new file mode 100644 index 0000000..d36b49a --- /dev/null +++ b/Docker/arm_mbed/Dockerfile @@ -0,0 +1,14 @@ +FROM debian:latest +RUN apt-get update +RUN apt-get install -y git python2.7 python-pip gcc-arm-none-eabi && \ + pip install mbed-cli +WORKDIR /arm +RUN mbed import https://github.com/ARMmbed/mbed-os-example-blinky && \ + cd mbed-os-example-blinky && \ + mbed compile -t GCC_ARM -m NUCLEO_F401RE && \ + rm main.cpp && \ + cd .. +COPY ./start.sh /arm +RUN chmod +x ./start.sh +ENTRYPOINT ./start.sh + diff --git a/Docker/arm_mbed/start.sh b/Docker/arm_mbed/start.sh new file mode 100644 index 0000000..f46a784 --- /dev/null +++ b/Docker/arm_mbed/start.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +echo "Compilation de : " $SRC_NAME +cp /exp/$SRC_DIR/$SRC_NAME /arm/mbed-os-example-blinky/main.cpp +cd ./mbed-os-example-blinky +mbed compile -t GCC_ARM -m NUCLEO_F401RE +cd ./BUILD/NUCLEO_F401RE/GCC_ARM +mv mbed-os-example-blinky.bin out.bin +cp out.bin /exp/$SRC_DIR/ \ No newline at end of file diff --git a/Serveur/exp_example.yml b/Serveur/exp_example.yml new file mode 100644 index 0000000..98785c9 --- /dev/null +++ b/Serveur/exp_example.yml @@ -0,0 +1,8 @@ +date: 2019-02-07T01:33 +file: main.cpp +nodes: [capteur1@192.168.0.27, capteur2@192.168.0.27] +exp_id: 8 +name: test +time: 00:01 +arch: arm +dir: pfe_1549034948676 diff --git a/Serveur/files/pfe_1549034948676/test.cpp b/Serveur/files/pfe_1549034948676/test.cpp new file mode 100644 index 0000000..f3d2639 --- /dev/null +++ b/Serveur/files/pfe_1549034948676/test.cpp @@ -0,0 +1,33 @@ +/* mbed Microcontroller Library + * Copyright (c) 2018 ARM Limited + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "mbed.h" +#include "stats_report.h" + +DigitalOut led1(LED1); + +#define SLEEP_TIME 500 // (msec) +#define PRINT_AFTER_N_LOOPS 20 + +// main() runs in its own thread in the OS +int main() +{ + SystemReport sys_state( SLEEP_TIME * PRINT_AFTER_N_LOOPS /* Loop delay time in ms */); + + int count = 0; + while (true) { + // Blink LED and wait 0.5 seconds + led1 = !led1; + wait_ms(SLEEP_TIME); + + if ((0 == count) || (PRINT_AFTER_N_LOOPS == count)) { + // Following the main thread wait, report on the current system status + sys_state.report_state(); + count = 0; + } + ++count; + } +} + diff --git a/Serveur/main b/Serveur/main new file mode 100755 index 0000000..14a6654 Binary files /dev/null and b/Serveur/main differ diff --git a/Serveur/main.c b/Serveur/main.c new file mode 100644 index 0000000..77842fa --- /dev/null +++ b/Serveur/main.c @@ -0,0 +1,323 @@ +#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/files/" +#define TOFLASH_PATH "./toflash/" + +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; + 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/sensors.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 /etc/ansible/roles/test.yml -i %s -e \"servernames=exp_%d exp_duration=%d binary_dir=%s\"\'", + USERNAME, + hosts_filename, + experiment->exp_id, + time_sec, + experiment->dir); + 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->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); + 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) { + char file_name[128]; + strcpy(file_name, TOFLASH_PATH); + strcat(file_name, dirent->d_name); + Experiment *experiment = read_file(file_name); +#ifdef DEBUG + print_exp(experiment); +#endif + if(!process_exp(experiment)) { + remove(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; +} \ No newline at end of file diff --git a/Serveur/serial b/Serveur/serial new file mode 100644 index 0000000..d35e62f --- /dev/null +++ b/Serveur/serial @@ -0,0 +1 @@ +blabla -- libgit2 0.21.2