Commit fb2a766ecd7c44f1ea15a6e20c50adbe4a0ea832

Authored by Antoine Duquenoy
1 parent aeee6ab0

Programme C serveur : lecture, compilation, flashage

* Scrutation d'un dossier pour repérer les expérimentations devant être lancées
* Script Ansible pour déployer les binaires et récupérer les résultats
* Image Docker compilant pour ARM Mbed
Ansible/ansible.yml 0 → 100644
@@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
  1 +---
  2 +
  3 +- hosts: "{{ servernames }}"
  4 +
  5 + tasks:
  6 +
  7 + - name: "Création du dossier de résulats"
  8 + file:
  9 + path: /home/pi/{{ servernames }}/res
  10 + state: directory
  11 + recurse: yes
  12 +
  13 + - name: "Copie du fichier de lecture série"
  14 + copy:
  15 + src: ~/pfe/serial
  16 + dest: /home/pi/{{ servernames }}/serial
  17 +
  18 + - name: "Copie du binaire pour le(s) capteur(s)"
  19 + copy:
  20 + src: ~/pfe/files/{{ binary_dir }}/out.bin
  21 + dest: /home/pi/{{ servernames }}/out.bin
  22 +
  23 + - name: "Lancement du programme de lecture série"
  24 + command: /home/pi/while
  25 + async: 3000000
  26 + poll: 0
  27 +
  28 + - name: "Exp en cours ..."
  29 + pause:
  30 + seconds: "{{ exp_duration }}"
  31 +
  32 + - name: "Kill de l'application"
  33 + shell: pkill while
  34 +
  35 + - name: "Récupération des noms des résultats"
  36 + shell: (cd /home/pi/{{ servernames }}/res; find . -maxdepth 1 -type f) | cut -d'/' -f2
  37 + register: files_to_copy
  38 +
  39 + - name: "Copie des résultats sur le serveur"
  40 + fetch:
  41 + src: /home/pi/{{ servernames }}/res/{{ item }}
  42 + dest: /home/antoine/pfe_results/{{ servernames }}/{{ ansible_host }}/
  43 + flat: yes
  44 + with_items: "{{ files_to_copy.stdout_lines }}"
  45 +
  46 + - name: "Suppression du dossier sur le noeud"
  47 + shell: rm -rf /home/pi/{{ servernames }}
Docker/arm_mbed/Dockerfile 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +FROM debian:latest
  2 +RUN apt-get update
  3 +RUN apt-get install -y git python2.7 python-pip gcc-arm-none-eabi && \
  4 + pip install mbed-cli
  5 +WORKDIR /arm
  6 +RUN mbed import https://github.com/ARMmbed/mbed-os-example-blinky && \
  7 + cd mbed-os-example-blinky && \
  8 + mbed compile -t GCC_ARM -m NUCLEO_F401RE && \
  9 + rm main.cpp && \
  10 + cd ..
  11 +COPY ./start.sh /arm
  12 +RUN chmod +x ./start.sh
  13 +ENTRYPOINT ./start.sh
  14 +
Docker/arm_mbed/start.sh 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +#!/bin/bash
  2 +
  3 +echo "Compilation de : " $SRC_NAME
  4 +cp /exp/$SRC_DIR/$SRC_NAME /arm/mbed-os-example-blinky/main.cpp
  5 +cd ./mbed-os-example-blinky
  6 +mbed compile -t GCC_ARM -m NUCLEO_F401RE
  7 +cd ./BUILD/NUCLEO_F401RE/GCC_ARM
  8 +mv mbed-os-example-blinky.bin out.bin
  9 +cp out.bin /exp/$SRC_DIR/
0 \ No newline at end of file 10 \ No newline at end of file
Serveur/exp_example.yml 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +date: 2019-02-07T01:33
  2 +file: main.cpp
  3 +nodes: [capteur1@192.168.0.27, capteur2@192.168.0.27]
  4 +exp_id: 8
  5 +name: test
  6 +time: 00:01
  7 +arch: arm
  8 +dir: pfe_1549034948676
Serveur/files/pfe_1549034948676/test.cpp 0 → 100644
@@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
  1 +/* mbed Microcontroller Library
  2 + * Copyright (c) 2018 ARM Limited
  3 + * SPDX-License-Identifier: Apache-2.0
  4 + */
  5 +
  6 +#include "mbed.h"
  7 +#include "stats_report.h"
  8 +
  9 +DigitalOut led1(LED1);
  10 +
  11 +#define SLEEP_TIME 500 // (msec)
  12 +#define PRINT_AFTER_N_LOOPS 20
  13 +
  14 +// main() runs in its own thread in the OS
  15 +int main()
  16 +{
  17 + SystemReport sys_state( SLEEP_TIME * PRINT_AFTER_N_LOOPS /* Loop delay time in ms */);
  18 +
  19 + int count = 0;
  20 + while (true) {
  21 + // Blink LED and wait 0.5 seconds
  22 + led1 = !led1;
  23 + wait_ms(SLEEP_TIME);
  24 +
  25 + if ((0 == count) || (PRINT_AFTER_N_LOOPS == count)) {
  26 + // Following the main thread wait, report on the current system status
  27 + sys_state.report_state();
  28 + count = 0;
  29 + }
  30 + ++count;
  31 + }
  32 +}
  33 +
Serveur/main 0 → 100755
No preview for this file type
Serveur/main.c 0 → 100644
@@ -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
Serveur/serial 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +blabla