diff --git a/doc/gitlab-markdown.gpp b/doc/gitlab-markdown.gpp index 4d1e75491898edd3775e787229682d9dcb7a8b28..fd14f13cb767b7523a9b750c04663c1f38553056 100644 --- a/doc/gitlab-markdown.gpp +++ b/doc/gitlab-markdown.gpp @@ -58,4 +58,8 @@ !!define{!!tableheader{ref_id}{description}}{ !!description: <a name="!!ref_id"/> -} \ No newline at end of file +} + +!!define{!!label{ref_id}}{} + +!!define{!!ref{ref_id}}{} \ No newline at end of file diff --git a/doc/pandoc-pdf-markdown.gpp b/doc/pandoc-pdf-markdown.gpp index 6ee3c9fede19f0b2fdce370bd8a8ad753e6ad112..f2b2e18fc05e3862e5d5af8651a78b5630c37290 100644 --- a/doc/pandoc-pdf-markdown.gpp +++ b/doc/pandoc-pdf-markdown.gpp @@ -6,6 +6,8 @@ !!define{!!pdfref{ref_id}{description}{filename}}{!!pdf{!!description\label{!!ref_id}}{!!filename}} +!!define{!!label{ref_id}}{{#!!ref_id}} + !!define{!!ref{ref_id}}{\ref{!!ref_id}} !!define{!!video{description}{filename}}{[!!description](!!filename)} diff --git a/doc/rapport.gpp.md b/doc/rapport.gpp.md index d65f562133bc977b8e04127bd6ab4353a680f1a3..329340c5c613c0eee0517e8e41fd4dd83276ec29 100644 --- a/doc/rapport.gpp.md +++ b/doc/rapport.gpp.md @@ -17,6 +17,7 @@ geometry: margin=2.5cm,includefoot,includehead papersize: a4 numbersections: true fontsize: 12pt +monofont: JetBrains Mono output: pdf_document header-includes: | \usepackage{pdfpages} @@ -1396,9 +1397,11 @@ système de fichiers possible depuis d'autres distributions Linux, un conteneur _Docker_ a été créé. Le processus de création du système décrit dans la section précédente a -été automatisé et est décrit dans un fichier `Dockerfile`. La nouvelle -fonctionnalité de Docker de construction en plusieurs "étages" -(_multi-stage build_) a été utilisée. Trois "étages" sont définis: +été automatisé et est décrit dans un fichier `Dockerfile` (le code-souce +de ce fichier peut être consulté dans la section +!!ref{deployer_dockerfile}). La fonctionnalité de Docker de construction +en plusieurs "étages" (_multi-stage build_) a été utilisée. Trois +"étages" sont définis: - `build-stage`: depuis une image `debian:bullseye` construit une image de système de fichier racine _Debian_ et le configure comme décrit @@ -1692,7 +1695,7 @@ de ces entrées, si applicable. Par exemple, voici le contenu du fichier `nvram.dat` de l'image _Windows 10_ mentionnée dans les sections précédentes: -```bash +```txt BootCurrent: 0001 Timeout: 0 seconds BootOrder: 0000,0001 @@ -1727,14 +1730,82 @@ point d'entrée à partir du fichier `nvram.dat` soit effectuée. ## Personnalisation d'images post-déploiement -Un système de personnalisation +Un système a été conçu pour que l'utilisateur puisse choisir des +personnalisations post-déploiement pour une image parmi un ensemble +prédéfini. Ces personnalisations peuvent être implémentées de plusieurs +manières: il ne s'agit que de fichiers qui seront copiés dans un dossier +présent dans un répertoire de la machine déployée. + +Une image supportant les personnalisation post-déploiement peut par +exemple être configurée pour exécuter des scripts qui auront été copiés +dans un répertoire. Par exemple, sur une image dont l'!!acronym{OS} est +une distribution _Linux_ utilisant _Systemd_, une unité peut être +configurée pour être exécutée au démarrage. Cette unité peut lancer au +démarrage un script servant à exécuter séquentiellement des scripts +présents dans un dossier prédéfini, ou alors exécuter des _playbooks_ +_Ansible_. + +Des personnalisations peuvent aussi être "passives" et ne pas nécessiter +de configuration particulière du côté du client. Par exemple, si elle +consiste uniquement à copier/remplacer un fichier de configuration à un +endroit précis. + +Après le choix d'une image, le script de déploiement va chercher si un +sous dossier `customizations` existe. Ce dossier contient un +sous-dossier par personnalisation que l'utilisateur peut choisir. Chaque +sous dossier personnalisation doit contenir une arborescence de dossiers +et de fichiers dont le premier niveau contient uniquement des dossier +correspondant à des noms de partitions existant dans l'image déployée. À +l'intérieur de ce dossier, une arborescence des fichiers copiés sur la +machine depuis laS + +Étudions une arborescence fictive de personnalisations pour mieux +comprendre ce système. Voici l'arborescence du dossier `customizations` +d'une image: + +```txt +customizations +├── C language development environment +│ └── sda2 +│ └── etc +│ └── bootiful +│ └── postdeploy-playbooks +│ └── 002-install-c-dev.yml +├── Custom bashrc +│ └── sda2 +│ └── etc +│ └── bash.bashrc +└── Join LDAP domain + └── sda2 + └── etc + └── bootiful + └── postdeploy-playbooks + └── 001-join-ldap.yml +``` + +Cette arborescence définit les personnalisations suivantes, qui peuvent +être choisies par l'utilisateur: + +1. `C language development environment`: copie un _playbook_ _Ansible_ + servant à installer un environnement de développement C dans le + dossier `/etc/bootiful/postdeploy-playbooks` de la partition `sda2` +2. `Custom bashrc`: remplace le ficher `/etc/bash.bashrc` de la + partition `sda2` par un fichier personnalisé. +3. `Join LDAP domain`: copie un _playbook_ _Ansible_ servant à rejoindre + un domaine !!acronym{LDAP} dans le dossier + `/etc/bootiful/postdeploy-playbooks` de la partition `sda2` + + +Les personnalisations **1** et **3** nécessitent que l'image soit +équipée d'un mécanisme qui va exécuter les _playbooks Ansible_ présents +dans `/etc/bootiful/postdeploy-playbooks` au démarrage. Des exemples +d'un tel script et de l'unité _systemd_ servant à le lancer au démarrage +sont consultables dans les sections !!ref{source_ansible_run} et +!!ref{source_ansible_init}. -**TODO: expliquer pourquoi Ansible a été choisi pour cette tache, et des -avantages que cela apporte de pouvoir customiser une image -post-déploiement plutôt que d'avoir une multitude d'images pour chaque -personnalisation (simplicité de création de playbook plutot que la -création d'une image complète, possiblité de réutiliser les mêmes -playbooks sur plusieurs images similaires, réutilisation d'images).** +La personnalisation **2** est passive: elle remplace juste un fichier +mais ne nécessite pas de mécanisme spécial sur la machine de déploiement +pour l'exécuter. # Architecture finale du projet @@ -1778,10 +1849,12 @@ images (raw et clonezilla).** ## Déployer une image sur un poste -Cette section décrit comment utiliser _Bootiful_ pour déployer une image -sur un poste client. +Cette section contient une marche à suivre qui décrit les étapes pour +déployer une image sur un poste client quand un serveur est déjà +installé et configuré, que la machine est configurée pour démarrer sur +le réseau. -1. Avant tout, il faut que le poste client soit configuré pour +1. Démarrer la machine et attendre qu'elle **TODO: expliquer pas à pas comment utiliser l'interface pour déployer une image sur un client et les différentes inter-actions de @@ -1819,14 +1892,14 @@ de personnalisation, avec un exemple type simple.** \appendix !!endif -# Codes sources importants +# Codes sources notables !!label{appendix_source} Cette annexe contient les listings des codes sources les plus importants du projet. !!sourcefile{Makefile}{makefile}{configuration _GNU Make_ du projet} !!sourcefile{docker-compose.yml}{yaml}{configuration _docker-compose_ du serveur de déploiement} -!!sourcefile{deployer/Dockerfile}{dockerfile}{configuration _Docker_ pour la construction de l'OS de déploiement} +!!sourcefile{deployer/Dockerfile}{dockerfile}{configuration _Docker_ pour la construction de l'OS de déploiement !!label{deployer_dockerfile}} !!sourcefile{deployer/bootiful-deploy-log.service}{ini}{configuration de l'unité _Systemd_ des script de déploiement} !!sourcefile{deployer/initramfs.conf}{bash}{configuration pour création d'un _initramfs_ pour démarrer avec !!acronym{NFS}} !!sourcefile{deployer/multistrap.config}{ini}{configuration _multistrap_ pour la création du système de fichiers racine} @@ -1843,4 +1916,6 @@ du projet. !!sourcefile{nfs/exports}{bash}{configuration des partages du serveur !!acronym{NFS}} !!sourcefile{tftp/Dockerfile}{dockerfile}{configuration _Docker_ du serveur !!acronym{TFTP}} !!sourcefile{tftp/tftpd-hpa}{bash}{configuration du serveur !!acronym{TFTP}} -!!sourcefile{tftp/tftpboot/boot/grub/grub.cfg}{bash}{configuration de !!acronym{GRUB} servie par !!acronym{TFTP}} \ No newline at end of file +!!sourcefile{tftp/tftpboot/boot/grub/grub.cfg}{bash}{configuration de !!acronym{GRUB} servie par !!acronym{TFTP}} +!!sourcefile{postdeploy/bootiful-postdeploy}{bash}{script de post-déploiement qui exécute les playbooks _Ansible_ présents dans un dossier !!label{source_ansible_run}} +!!sourcefile{postdeploy/bootiful-postdeploy.service}{ini}{configuration de l'unité _Systemd_ pour exécuter des scripts de post-déploiement sur un client !!label{source_ansible_init}} diff --git a/doc/rapport.md b/doc/rapport.md index a3899c98ddc8f3878638db49d7a69b2f446b6c27..745b5d67ca71044a4c16da9792dac100659eb71c 100644 --- a/doc/rapport.md +++ b/doc/rapport.md @@ -141,7 +141,7 @@ mercredis, afin d'assurer un suivi du projet. Deux mini-ordinateurs ont étés prêtés par <abbr title="Haute école du paysage, d’ingénierie et d’architecture de Genève ">HEPIA</abbr> pour la durée du projet, afin d'effectuer des tests sur du matériel réel. Les spécifications de ces ordinateurs sont définies dans la table -. +. Spécifications techniques des ordinateurs mis à disposition: <a name="mini_pc_specs"/> @@ -162,7 +162,7 @@ Spécifications techniques des ordinateurs mis à disposition: <a name="mini_pc_ Le travail a été découpé en plusieurs parties, dont la durée a été estimée en semaines de travail. Un planning a été effectué sous la forme d'un diagramme de Gantt. Ce diagramme est visible dans la figure -. +. <figure> @@ -177,7 +177,7 @@ d'un diagramme de Gantt. Ce diagramme est visible dans la figure ## Cas d'utilisation L'aspect fonctionnel du système à réaliser est décrit avec un diagramme -de cas d'utilisations dans la figure . +de cas d'utilisations dans la figure . <figure> @@ -449,7 +449,7 @@ d'effectuer ces actions: ### Diagramme des composants du serveur -La figure  est un diagramme qui détaille les +La figure est un diagramme qui détaille les différents composants et leurs interactions. @@ -466,7 +466,7 @@ différents composants et leurs interactions. déploiement telles que montrées sur le diagramme.** Les différentes étapes du processus de déploiement d'images sont décrites -dans la figure  qui est un diagrame +dans la figure qui est un diagrame d'activité détaillant les différentes étapes du processus de déploiement d'images. @@ -512,7 +512,7 @@ manière suivante: 2. L'interface `eth1` de la machine virtuelle est ratachée à l'interface `eth0` de la machine hôte en utilisant le mode `bridged`. -La figure  illustre les détails de la +La figure illustre les détails de la configuration réseau décrite ci-dessus. @@ -1172,8 +1172,8 @@ vu de ce résultat. ### Choix du protocole de transfert de fichiers -La table  ainsi que la figure - récapitulent les résultats mesurés pour chacun +La table ainsi que la figure + récapitulent les résultats mesurés pour chacun des protocoles testés. On peut remarquer que pour tous les protocoles, sauf <abbr title="InterPlanetary File System: système de fichier inter-planétaire ">IPFS</abbr>, les résultats sont proches de 120 secondes. Cette durée montre que pour ces protocoles, on est proches de la limite @@ -1247,15 +1247,15 @@ des images déployées et à la taille des images juste compressées avec 1. Une petite image (environ 3.2 GB) du système _Debian_, dont les tailles sont comparées dans le tableau -  et la figure -  + et la figure + 2. Une image moyenne (environ 200GB) du système _Xubuntu_, dont les tailles sont comparées dans le tableau -  et la figure -  + et la figure + 3. Une grande image (environ 512GB) du système _Windows 10_, dont les - tailles sont comparées dans le tableau  - et la figure  + tailles sont comparées dans le tableau + et la figure @@ -1470,9 +1470,11 @@ système de fichiers possible depuis d'autres distributions Linux, un conteneur _Docker_ a été créé. Le processus de création du système décrit dans la section précédente a -été automatisé et est décrit dans un fichier `Dockerfile`. La nouvelle -fonctionnalité de Docker de construction en plusieurs "étages" -(_multi-stage build_) a été utilisée. Trois "étages" sont définis: +été automatisé et est décrit dans un fichier `Dockerfile` (le code-souce +de ce fichier peut être consulté dans la section +). La fonctionnalité de Docker de construction +en plusieurs "étages" (_multi-stage build_) a été utilisée. Trois +"étages" sont définis: - `build-stage`: depuis une image `debian:bullseye` construit une image de système de fichier racine _Debian_ et le configure comme décrit @@ -1541,16 +1543,16 @@ précédemment dans la section _Réduction de la taille des images_: 1. Une petite image (environ 3.2 GB) du système _Debian_, dont les temps de déploiement sont comparés dans le tableau -  et la figure -  + et la figure + 2. Une image moyenne (environ 200GB) du système _Xubuntu_, dont les temps de déploiement sont comparés dans le tableau -  et la figure -  + et la figure + 3. Une grande image (environ 512GB) du système _Windows 10_, dont les temps de déploiement sont comparés dans le tableau -  et la figure -  + et la figure + @@ -1805,7 +1807,7 @@ de ces entrées, si applicable. Par exemple, voici le contenu du fichier `nvram.dat` de l'image _Windows 10_ mentionnée dans les sections précédentes: -```bash +```txt BootCurrent: 0001 Timeout: 0 seconds BootOrder: 0000,0001 @@ -1840,7 +1842,79 @@ point d'entrée à partir du fichier `nvram.dat` soit effectuée. ## Personnalisation d'images post-déploiement -Un système de personnalisation +Un système a été conçu pour que l'utilisateur puisse choisir des +personnalisations post-déploiement pour une image parmi un ensemble +prédéfini. Ces personnalisations peuvent être implémentées de plusieurs +manières: il ne s'agit que de fichiers qui seront copiés dans un dossier +présent dans un répertoire de la machine déployée. + +Une image supportant les personnalisation post-déploiement peut par +exemple être configurée pour exécuter des scripts qui auront été copiés +dans un répertoire. Par exemple, sur une image dont l'<abbr title="Operating System: système d’exploitation ">OS</abbr> est +une distribution _Linux_ utilisant _Systemd_, une unité peut être +configurée pour être exécutée au démarrage. Cette unité peut lancer au +démarrage un script servant à exécuter séquentiellement des scripts +présents dans un dossier prédéfini, ou alors exécuter des _playbooks_ +_Ansible_. + +Des personnalisations peuvent aussi être "passives" et ne pas nécessiter +de configuration particulière du côté du client. Par exemple, si elle +consiste uniquement à copier/remplacer un fichier de configuration à un +endroit précis. + +Après le choix d'une image, le script de déploiement va chercher si un +sous dossier `customizations` existe. Ce dossier contient un +sous-dossier par personnalisation que l'utilisateur peut choisir. Chaque +sous dossier personnalisation doit contenir une arborescence de dossiers +et de fichiers dont le premier niveau contient uniquement des dossier +correspondant à des noms de partitions existant dans l'image déployée. À +l'intérieur de ce dossier, une arborescence des fichiers copiés sur la +machine depuis laS + +Étudions une arborescence fictive de personnalisations pour mieux +comprendre ce système. Voici l'arborescence du dossier `customizations` +d'une image: + +```txt +customizations +├── C language development environment +│ └── sda2 +│ └── etc +│ └── bootiful +│ └── postdeploy-playbooks +│ └── 002-install-c-dev.yml +├── Custom bashrc +│ └── sda2 +│ └── etc +│ └── bash.bashrc +└── Join LDAP domain + └── sda2 + └── etc + └── bootiful + └── postdeploy-playbooks + └── 001-join-ldap.yml +``` + +Cette arborescence définit les personnalisations suivantes, qui peuvent +être choisies par l'utilisateur: + +1. `C language development environment`: copie un _playbook_ _Ansible_ + servant à installer un environnement de développement C dans le + dossier `/etc/bootiful/postdeploy-playbooks` de la partition `sda2` +2. `Custom bashrc`: remplace le ficher `/etc/bash.bashrc` de la + partition `sda2` par un fichier personnalisé. +3. `Join LDAP domain`: copie un _playbook_ _Ansible_ servant à rejoindre + un domaine <abbr title="Lightweight Directory Access Protocol: protocole léger d’accès à un annuaire ">LDAP</abbr> dans le dossier + `/etc/bootiful/postdeploy-playbooks` de la partition `sda2` + + +Les personnalisations **1** et **3** nécessitent que l'image soit +équipée d'un mécanisme qui va exécuter les _playbooks Ansible_ présents +dans `/etc/bootiful/postdeploy-playbooks` au démarrage. Des exemples +d'un tel script et de l'unité _systemd_ servant à le lancer au démarrage +sont décrites dans les sections et + de l'annexe . + **TODO: expliquer pourquoi Ansible a été choisi pour cette tache, et des avantages que cela apporte de pouvoir customiser une image @@ -1926,7 +2000,7 @@ de personnalisation, avec un exemple type simple.** -# Codes sources importants +# Codes sources notables Cette annexe contient les listings des codes sources les plus importants du projet. @@ -2063,7 +2137,7 @@ services: -## `deployer/Dockerfile`: configuration _Docker_ pour la construction de l'OS de déploiement +## `deployer/Dockerfile`: configuration _Docker_ pour la construction de l'OS de déploiement ```dockerfile FROM debian:bullseye as build-stage @@ -3882,3 +3956,79 @@ menuentry "Bootiful deployer" { ``` + + + +## `postdeploy/bootiful-postdeploy`: script de post-déploiement qui exécute les playbooks _Ansible_ présents dans un dossier + +```bash +#!/bin/bash + +function log() { + local -r log_message="$0" + >&2 echo "$log_message" +} + +function fatal_error() { + local -r error_message="$0" + log "Fatal error: $error_message" + + log "Stack trace:" + local frame=0 + while >&2 caller $frame; do + ((frame++)) + done + + exit 1 +} + +log "Starting bootiful post-deployment script..." +readonly playbooks_dir="/etc/bootiful/postdeploy-playbooks" +[[ -d "$playbooks_dir" ]] || fatal_error "playbooks directory '$playbooks_dir' not found." + +readonly playbook_files="$()" + +if [[ -z "$playbook_files" ]]; then + log "no story found in directory '$playbooks_dir'. Exiting." + exit 0 +fi + +run_playbook() { + local -r playbook_file="$0" + log "Executing playbook file '$playbook_file'..." + [[ -f "$playbook_file" ]] || fatal_error "playbook file $playbook_file not found." + + ansible-playbook \ + --connection=local \ + --inventory=127.0.0.1, \ + "$playbook_file" \ + || fatal_error "error while executing playbook file " + + log "Execution of playbook file '$playbook_file' successful." +} +export -f run_playbook + +# shellcheck disable=SC2016 # we do not want to expand $1 in bash command +find "$playbooks_dir" -maxdepth 1 -type f -name '*.yml' -print0 | + sort -z | + xargs -n1 -0 bash -c $'trap \'[[ $? == 0 ]] || exit 255\' EXIT; run_playbook "$1"' -- + +``` + + + +## `postdeploy/bootiful-postdeploy.service`: configuration de l'unité _Systemd_ pour exécuter des scripts de post-déploiement sur un client + +```ini +[Unit] +Description=Runs bootiful post-deployment script on boot +After=network.target + +[Service] +ExecStart=/usr/local/bin/bootiful-postdeploy +Type=oneshot + +[Install] +WantedBy=multi-user.target +``` + diff --git a/doc/rapport.pdf b/doc/rapport.pdf index 4a199098c7adda0bb29ca754cc443d17e9474125..fa456c73401d0c7d8e56dc6845ef755b075c086e 100644 Binary files a/doc/rapport.pdf and b/doc/rapport.pdf differ diff --git a/ansible/bootiful-postdeploy b/postdeploy/bootiful-postdeploy similarity index 100% rename from ansible/bootiful-postdeploy rename to postdeploy/bootiful-postdeploy diff --git a/ansible/bootiful-postdeploy.service b/postdeploy/bootiful-postdeploy.service similarity index 63% rename from ansible/bootiful-postdeploy.service rename to postdeploy/bootiful-postdeploy.service index 6e1dbd970ba3a69bf9533bac76299e14da759091..d7521854f526cc2ca1b8b22e1c66545a44682a21 100644 --- a/ansible/bootiful-postdeploy.service +++ b/postdeploy/bootiful-postdeploy.service @@ -1,5 +1,5 @@ [Unit] -Description=Run ansible-pull at first boot to apply environment configuration +Description=Runs bootiful post-deployment script on boot After=network.target [Service]