tuto 2022 5, 6

This commit is contained in:
nemunaire 2021-11-20 00:00:30 +01:00
parent 3d7c03fbbd
commit 2af52619c7
43 changed files with 1073 additions and 431 deletions

View file

@ -25,7 +25,7 @@ steps:
- make -C tutorial/4
- mv tutorial/4/tutorial.pdf dist/tutorial-4.pdf
- make -C tutorial/5
- mv tutorial/5/tutorial.pdf dist/tutorial-5.pdf
- mv tutorial/5/tutorial-5-srs.pdf tutorial/5/tutorial-5-gistre.pdf dist/
- make -C tutorial/k8s
- mv tutorial/k8s/tutorial.pdf dist/tutorial-6.pdf
- make -C subject/1

View file

@ -256,6 +256,7 @@ Et de ces quelques articles :
* [File-based capabilities](https://lwn.net/Articles/211883/)
* [A bid to resurrect Linux capabilities](https://lwn.net/Articles/199004/)
* [False Boundaries and Arbitrary Code Execution](https://forums.grsecurity.net/viewtopic.php?f=7&t=2522#p10271)
* [Linux Capabilities on HackTricks](https://book.hacktricks.xyz/linux-unix/privilege-escalation/linux-capabilities)
Pour revenir à Docker, un certain nombre de *capabilities* sont désactivées par
défaut ; vous pouvez en ajouter et en retirer via les arguments `--cap-add` et

View file

@ -1,20 +1,47 @@
include ../pandoc-opts.mk
SOURCES = tutorial.md \
SOURCES_SRS = tutorial-srs.md \
../devops/devops.md \
../devops/what.md \
../devops/tools.md \
../devops/tools-gitea.md \
../devops/tools-gitea-ansible.md \
../devops/tools-gitea-end.md \
../devops/tools-drone.md \
../devops/tools-drone-ansible.md \
../devops/tools-drone-oauth.md \
../devops/tools-drone-runner.md \
../devops/tools-drone-runner-ansible.md \
../devops/tools-end.md \
../devops/ci.md \
../devops/publish-docker.md \
../docker-internals/oci.md \
../docker-internals/registry.md \
rendu.md
rendu-srs.md
SOURCES_GISTRE = tutorial-gistre.md \
../devops/what-gistre.md \
../devops/what-gistre-see-srs.md \
../devops/tools.md \
../devops/tools-gitea.md \
../devops/tools-gitea-cmd.md \
../devops/tools-gitea-end.md \
../devops/tools-drone.md \
../devops/tools-drone-cmd.md \
../devops/tools-drone-oauth.md \
../devops/tools-drone-runner.md \
../devops/tools-drone-runner-cmd.md \
../devops/tools-end.md \
../devops/ci-gistre.md \
../devops/run-gistre.md \
rendu-gistre.md
all: tutorial.pdf
all: tutorial-5-srs.pdf tutorial-5-gistre.pdf
tutorial.pdf: ${SOURCES}
tutorial-5-srs.pdf: ${SOURCES_SRS}
pandoc ${PANDOCOPTS} -o $@ $+
tutorial-5-gistre.pdf: ${SOURCES_GISTRE}
pandoc ${PANDOCOPTS} -o $@ $+
clean::
rm tutorial.pdf
rm tutorial-5-srs.pdf tutorial-5-gistre.pdf

View file

@ -10,11 +10,15 @@ abstract: |
\vspace{1em}
À la demande de Nabih, ce TP a été raccourci
\vspace{1em}
Tous les éléments de ce TP (exercices et projet) sont à rendre à
<virli@nemunai.re> au plus tard le **mercredi 4 novembre 2020 à 12 h
<virli@nemunai.re> au plus tard le **jeudi 18 novembre 2021 à 23 h
42**. Consultez la dernière section de chaque partie pour plus d'informations
sur les éléments à rendre. Et n'oubliez pas de répondre aux [questions de
cours](https://virli.nemunai.re/quiz/5).
cours](https://virli.nemunai.re/quiz/13).
En tant que personnes sensibilisées à la sécurité des échanges électroniques,
vous devrez m'envoyer vos rendus signés avec votre clef PGP. Pensez à

View file

@ -0,0 +1,121 @@
\newpage
## Intégration continue
::::: {.question}
La mise en place de l'environnement de CI/CD n'est pas le cœur de la version
GISTRE du TP (elle l'est pour les SRS). Aussi cette partie est aussi guidée que
possible et toutes les commandes vous sont données pour réduire les frictions
de mise en œuvre.
Mais comme indiqué dans l'introduction au DevOps, vous serez susceptibles
d'arriver dans une entreprise qui pratique correctement le DevOps. Dans cette
situation, l'ensemble des développeurs et des administrateurs système (les
*Ops*), doivent faire en sorte que leurs travaux soient intégrés dans les
outils d'intégration continue. Les *Ops* vont évidemment plutôt gérer la mise
en place des outils, proprement, c'est ce que demande de faire le TP SRS. Pour
vous il s'agit plus de savoir interagir avec, en sachant manipuler la
configuration des dépôts.
:::::
Une fois Gitea et Drone installés et configurés, nous allons pouvoir rentrer
dans le vif du sujet : faire de l'intégration continue sur notre premier projet !
### Créez un dépôt pour `linky2influx`
Après avoir créé (ou migré pour les plus malins !) le dépôt
[`linky2influx`](https://git.nemunai.re/nemunaire/linky2influx) dans Drone,
synchronisez les dépôts, puis activez la surveillance de `linky2influx`.
Nous allons devoir rédiger un fichier `.drone.yml`, que l'on placera à la racine
du dépôt. C'est ce fichier qui sera traité par DroneCI pour savoir comment
compiler et tester le projet.
::::: {.warning}
Un fichier `.drone.yml` existe déjà à la racine du dépôt. Celui-ci pourra vous
servir d'inspiration, mais il ne fonctionnera pas directement sur votre
installation.
**Vous rencontrerez des problèmes inattendus si vous utilisez le fichier
`.drone.yml` du dépôt.** Vous **DEVEZ** partir d'un fichier vide et suivre la
documentation pour obtenir un `.drone.yml` fonctionnel.
:::::
### Définir les étapes d'intégration
Toutes les informations nécessaires à l'écriture du fichier `.drone.yml` se
trouvent dans [l'excellente documentation du
projet](https://docs.drone.io/pipeline/docker/examples/languages/golang/).
Les étapes sont sensiblement les mêmes que dans le `Dockerfile` présent sur le
dépôt.
Committons puis poussons notre travail. Dès qu'il sera reçu par Gitea, nous
devrions voir l'interface de Drone lancer les étapes décrites dans le fichier.
::::: {.warning}
**IMPORTANT :** si vous avez l'impression que ça ne marche pas et que vous avez
réutilisé le fichier présent sur le dépôt au lieu de partir de l'exemple donné
dans la documentation, **commencez en partant de l'exemple de la
documentation** ! Le fichier présent sur le dépôt **ne fonctionnera pas** dans
votre situation !
:::::
![Drone en action](../devops/drone-run-linky.png){height=7.5cm}
Lorsqu'apparaît enfin la ligne `git.nemunai.re/linky2influx`, le projet est compilé !
### Publier le binaire correspondant aux tags/jalons
Nous savons maintenant que notre projet compile bien dans un environnement
différent de celui du développeur ! Néanmoins, le binaire produit est perdu dès
lors que la compilation est terminée, car nous n'en faisons rien.
Ajoutons donc une nouvelle règle à notre `.droneci.yml` pour placer le binaire
au sein de la liste des fichiers téléchargeable aux côtés des tags.
Vous aurez sans doute besoin de :
- <https://docs.drone.io/pipeline/conditions/>
- <http://plugins.drone.io/drone-plugins/drone-gitea-release/>
Attention à ne pas stocker votre clef d'API dans le fichier YAML !
![Binaire publié automatiquement sur Gitea](../devops/tag-released.png){height=8cm}
::::: {.more}
Lorsque l'on est plusieurs à travailler sur le projet ou pour accroître la
sécurité, il convient de créer, un compte *bot* qui sera responsable de la
création des *releases*. Ce sera donc sa clef d'API que l'on indiquera dans
l'interface de Drone.
:::::
### Publier pour plusieurs architectures ?
Le compilateur Go est fourni avec l'ensemble des backends des différentes
architectures matérielles qu'il supporte, nous pouvons donc aisément faire de
la compilation croisée pour d'autres architectures.
Essayons maintenant de compiler `linky2influx` pour plusieurs architectures afin de
vérifier que cela fonctionne bien !
Un exemple est donné tout en haut de cette page :
<https://docs.drone.io/pipeline/environment/syntax/>.
En faisant varier `$GOARCH` en `mips`, `powerpc`, ... nous pouvons générer les
binaires correspondant à chaque architecture et système.
Ajoutez à votre fichier `.drone.yml` les deux architectures pour lesquelles les
Raspberry Pi d'Électropcool sont compatibles. Nommez les fichiers selon
l'architecture que pourrait renvoyer `uname -m`, cela pourrait nous simplifier la tâche ensuite...
\
Une fois taggé et poussé sur notre dépôt, nous aurons une version exécutable
utilisable à la fois sur notre machine de développement, mais aussi sur les
Raspberry Pi déjà déployées dans les bâtiments. Nous avons atteint l'un des
deux objectifs qui nous était demandé. Tâchons maintenant de trouver un

View file

@ -1,59 +1,66 @@
\newpage
Intégration continue
====================
## Intégration continue
Une fois Gitea et Drone installés et configurés, nous allons pouvoir rentré
Une fois Gitea et Drone installés et configurés, nous allons pouvoir rentrer
dans le vif du sujet : faire de l'intégration continue sur notre premier projet !
## `youp0m`
### Créez un dépôt pour `youp0m`
Reprenez les travaux réalisés au TP précédent. Nous allons notamment avoir
besoin du `Dockerfile` dans la section suivante.
Après avoir créé (ou migré pour les plus malins !) le dépôt
[`youp0m`](https://gitea.nemunai.re/nemunaire/youp0m), dans Drone,
[`youp0m`](https://git.nemunai.re/nemunaire/youp0m) dans Drone,
synchronisez les dépôts, puis activez la surveillance de `youp0m`.
Vous allez devoir rédiger un fichier `.drone.yml`, que l'on placera à la
racine du dépôt (celui qui existe déjà dans le dépôt pourra servir
d'inspiration, mais il ne fonctionnera pas directement sur votre
installation). C'est ce fichier qui sera traité par DroneCI pour savoir comment
Nous allons devoir rédiger un fichier `.drone.yml`, que l'on placera à la racine
du dépôt. C'est ce fichier qui sera traité par DroneCI pour savoir comment
compiler et tester le projet.
::::: {.warning}
Un fichier `.drone.yml` existe déjà à la racine du dépôt. Celui-ci pourra vous
servir d'inspiration, mais il ne fonctionnera pas directement sur votre
installation.
**Vous rencontrerez des problèmes inattendus si vous utilisez le fichier
`.drone.yml` du dépôt.** Vous **DEVEZ** partir d'un fichier vide et suivre la
documentation pour obtenir un `.drone.yml` fonctionnel.
:::::
### Définir les étapes d'intégration
Toutes les informations nécessaire à l'écriture du fichier `.drone.yml` se
Toutes les informations nécessaires à l'écriture du fichier `.drone.yml` se
trouvent dans [l'excellente documentation du
projet](https://docs.drone.io/pipeline/docker/examples/languages/golang/).
Les étapes sont sensiblement les mêmes que dans le `Dockerfile` que vous avez
Les étapes sont sensiblement les mêmes que dans le `Dockerfile` que nous avons
écrit lors du TP précédent.
Comittez puis pousser votre travail, dès qu'il sera reçu par Gitea, vous
devriez voir l'interface de Drone lancer les étapes décrites dans le fichier.
Committons puis poussons notre travail. Dès qu'il sera reçu par Gitea, nous
devrions voir l'interface de Drone lancer les étapes décrites dans le fichier.
![Drone en action](../devops/drone-run.png){height=6cm}
::::: {.warning}
**IMPORTANT :** si vous avez l'impression que ça ne marche pas et que vous avez
réutilisé le fichier présent sur le dépôt au lieu de partir de l'exemple donné
dans la documentation, **commencez en partant de l'exemple de la
documentation** ! Le fichier présent sur le dépôt ne fonctionnera pas dans
documentation** ! Le fichier présent sur le dépôt **ne fonctionnera pas** dans
votre situation !
![Drone en action](../devops/drone-run.png){height=8cm}
:::::
Lorsqu'apparaît enfin la ligne `git.nemunai.re/youp0m`, le projet est compilé !
### Inspection qualité
Nous n'avons pas encore de test à proprement parlé. Nous allons utiliser
Nous n'avons pas encore de test à proprement parler. Nous allons utiliser
[Sonarqube](https://www.sonarqube.org/) pour faire une revue qualité du code !
Tout d'abord, il faut lancer le conteneur Sonarqube (pensez à l'ajouter à votre
playbook !) :
Tout d'abord, il faut lancer le conteneur Sonarqube (SRS, pensez à l'ajouter à
votre playbook !) :
<div lang="en-US">
```bash
@ -83,7 +90,7 @@ différent de celui du développeur ! Néanmoins, le binaire produit est perdu d
lors que la compilation est terminée, car nous n'en faisons rien.
Ajoutons donc une nouvelle règle à notre `.droneci.yml` pour placer le binaire
au sein de la liste des fichiers téléchargeable aux côtés des tags.
au sein de la liste des fichiers téléchargeables aux côtés des tags.
Vous aurez sans doute besoin de :
@ -94,25 +101,9 @@ Attention à ne pas stocker votre clef d'API dans le fichier YAML !
![Binaire publié automatiquement sur Gitea](../devops/tag-released.png){height=8cm}
::::: {.more}
Lorsque l'on est plusieurs à travailler sur le projet ou pour accroître la
sécurité, il convient de créer, un compte *bot* qui sera responsable de la
création des *releases*. Ce sera donc sa clef d'API que l'on indiquera dans
l'interface de Drone.
### Publier pour plusieurs architectures ?
Le compilateur Go est fourni avec l'ensemble des backends des différentes
architectures matérielles qu'il supporte, nous pouvons donc aisément faire de
la compilation croisée pour d'autres architectures.
Essayons maintenant de compiler `youp0m` pour plusieurs architecture afin de
vérifier que cela fonctionne bien !
Un exemple est donné tout en haut de cette page :
<https://docs.drone.io/pipeline/environment/syntax/>.
En faisant varier `$GOARCH` en `arm`, `arm64`, `mips`, ... nous pouvons générer
les binaires correspondant à chaque architecture et système.
Ajoutez au moins 2 autres architectures à votre fichier `.drone.yml`.
:::::

View file

@ -4,7 +4,7 @@ Le mouvement DevOps
===================
Jusqu'à récemment, et encore dans de nombreuses entreprises, les développeurs
et les administrateurs systèmes faisaient partis de deux équipes différentes :
et les administrateurs système faisaient partie de deux équipes différentes :
les uns développant sur leurs machines avec les dernières bibliothèques,
utilisant les derniers frameworks à la mode, sans se préoccuper de la sécurité
(ils travaillent en `root` ou avec `sudo` ;)), tandis que les autres tentaient
@ -17,17 +17,17 @@ utilisé sur un système à jour, et qu'il ne tourne pas en `root`), qu'à la
mémoire, il ne faut pas que les autres services présents sur la même machine en
pâtissent).
Une guerre faisait donc rage entre les développeurs qui ne comprennaient pas
que les administrateurs système ne pouvaient pas maintenir autant de version
d'une bibliothèque qu'il y avait de service : par exemple dans le cas de
plusieurs services en PHP, on pouvait leur demander de déployer des
applications utilisant la version 5.1, et la 5.2 pour d'autres, ... lorsqu'il y
avait des incompatibilités mineures et plus personne pour s'occuper de la
maintenance d'un vieux service toujours utilisé.
Une guerre faisait donc rage entre les développeurs qui ne comprenaient pas que
les administrateurs système ne pouvaient pas maintenir autant de versions d'une
bibliothèque qu'il y avait de services : par exemple dans le cas de plusieurs
services en PHP, on pouvait leur demander de déployer des applications
utilisant la version 5.6, et la 7.2 pour d'autres, ... lorsqu'il y avait des
incompatibilités mineures et plus personne pour s'occuper de la maintenance
d'un vieux service toujours utilisé.
Le même principe est aussi valable pour Python, Ruby, ... : les développeurs
ont toujours eu tendance à vouloir utiliser les dernières améliorations d'un
langage, mais les administrateurs systèmes n'ont alors pas de paquets stables
langage, mais les administrateurs système n'ont alors pas de paquets stables
dans la distribution. En effet, les distributions stables telles que Debian,
RedHat ou CentOS ont des cycles de vie assez long et se concentrent plus sur la
stabilité.\
@ -58,10 +58,11 @@ sont chargées de développer la fiabilité des systèmes d'information de
production. Ce sont les équipes SRE, pour Site Reliability Engineering. On
confie alors complètement la responsabilité de l'environnement de production
aux développeurs qui sont chargés de l'automatiser. Au delà de l'automatisation
des déploiements des services, il s'agit ici de développer des mécanismes
des déploiements de services, il s'agit ici de développer des mécanismes
permettant au système de réagir face aux situations telles que les montées en
charges, les pannes, ...
::::: {.warning}
Attention par contre aux entreprises qui recrutent un profil DevOps, car cela a
autant de sens que recruter un développeur Scrum ou un développeur cycle en V :
DevOps est une méthodologie. Les entreprises qui recrutent un DevOps
@ -71,6 +72,7 @@ généralement assez difficile à vivre. Alors qu'au contraire, la mouvance DevO
doit être prise au sérieux par l'ensemble des développeurs. Lors d'un entretien
d'embauche pour ce genre de poste, assurez-vous bien de ne pas être le seul à
faire du DevOps.
:::::
## Intégration continue
@ -92,7 +94,7 @@ vers un dossier accessible. Cela permet ainsi aux développeurs de voir les
problèmes et de pousser les analyses avec leurs propres outils.
Sans déploiement continu (la section suivante), c'est également ces produits de
compilation que les administrateurs systèmes vont déployer sans peine, lorsque
compilation que les administrateurs système vont déployer sans peine, lorsque
les développeurs considéreront avoir atteint un jalon, une version stable.
@ -100,7 +102,7 @@ les développeurs considéreront avoir atteint un jalon, une version stable.
Une fois tous les tests passés et les objets produits (on parle d'*artifact* ou
d'*assets*), il est possible de déclencher un déploiement : il s'agit de rendre
accessible aux utilisateurs finaux le services ou les objets.
accessible aux utilisateurs finaux le service ou les objets.
Dans le cas d'un programme à télécharger
([Python](https://buildbot.python.org/all/#/), VLC,
@ -111,17 +113,19 @@ vers la dernière version (pour que les utilisateurs aient la notifications).
Ou bien dans le cas d'un service en ligne (GitHub, Netflix, GMail, ...), il
s'agira de mettre à jour le service.
Parfois les deux seront à faire : à la fois publier un paquet ou un conteneur
et mettre à jour un service en ligne : [le serveur
Synapse](https://buildkite.com/matrix-dot-org/synapse) du protocole de
messagerie Matrix ou encore
[Gitlab](https://gitlab.com/gitlab-org/gitlab/-/pipelines).\
Parfois les deux seront à faire : à la fois publier un paquet ou un
conteneur et mettre à jour un service en ligne : par exemple, [le
serveur Synapse](https://buildkite.com/matrix-dot-org/synapse) du
protocole de messagerie Matrix ou encore
[Gitlab](https://gitlab.com/gitlab-org/gitlab/-/pipelines), tous deux
publient des paquets à destination de leurs communautés, et mettent à
jour leur service en ligne.\
Il existe pour cela de très nombreuses stratégies : lorsque l'on n'a pas
beaucoup de trafic ni beaucoup de machines, on peut simplement éteindre
l'ancien service et démarrer le nouveau, si ça prend quelques millisecondes en
étant automatisé, cela peut être suffisant compte tenu du faible
traffic.
trafic.
Lorsque l'on a un trafic élevé, de nombreux clients et donc que le service est
réparti sur plusieurs machines, on ne peut pas se contenter de tout éteindre et
@ -143,8 +147,8 @@ surveiller afin d'être le plus proactif possible dans la résolution des
problèmes. La pire situation est celle dans laquelle c'est un utilisateur qui
nous informe d'un problème... (sur Twitter !?)
Nous avons réalisé durant le précédent TP, une partie collecte de métriques,
avec nos conteneurs TICK. Nous n'allons donc pas nous en occuper aujourd'hui.
Nous avons réalisé précédemment une partie collecte de métriques, avec nos
conteneurs TICK. Nous n'allons donc pas nous en occuper aujourd'hui.
\
Notez tout de même qu'il y a deux grandes catégories de logiciels de
@ -167,8 +171,8 @@ Kapacitor, qui permet après avoir analysé les données, d'alerter en fonction
d'une évolution.
L'instrumentation d'une application est une bonne manière de faire remonter des
métrique (combien de clients actuellement connectés, combien de
messages/transactions traités, ...). Ce sont autant d'information que l'on peut
métriques (combien de clients actuellement connectés, combien de
messages/transactions traités, ...). Ce sont autant d'informations que l'on peut
faire remonter dans sa base de données de métriques.
\
@ -185,12 +189,11 @@ un service distribuable, qui est proche de la surcharge, acheter de l'espace de
stockage supplémentaire auprès du fournisseur, ...
\
Enfin, citons dans cette partie le [Chaos
Monkey](https://fr.wikipedia.org/wiki/Chaos_Monkey), conçu par Netflix, qui est
un programme qui va casser de manière aléatoire des éléments de l'environnement
de production. Le but est de provoquer sciemment des pannes, des latences,
... à n'importe quel niveau du produit, afin d'en tester (brulatement certes)
sa résilience. Cela oblige les développeurs, les opérationnels et les
architectes à concevoir des services hautement tolérant aux pannes, ce qui fait
que le jour où une véritable panne survient, elle n'a aucun impact sur la
production (enfin on espère !).
Enfin, citons le [Chaos Monkey](https://fr.wikipedia.org/wiki/Chaos_Monkey),
conçu par Netflix, qui est un programme qui va casser de manière aléatoire des
éléments de l'environnement de production. Le but est de provoquer sciemment
des pannes, des latences, ... à n'importe quel niveau du produit, afin d'en
tester (brulatement certes) sa résilience. Cela oblige les développeurs, les
opérationnels et les architectes à concevoir des services hautement tolérant
aux pannes, ce qui fait que le jour où une véritable panne survient, elle n'a
aucun impact sur la production (enfin on espère !).

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

View file

@ -10,16 +10,18 @@ jour ensuite (par exemple, dans le cas de Firefox ou de LibreOffice, une fois
testés, les paquets sont envoyés sur le serveur d'où ils seront distribués ; il
n'y a pas de service/docker à relancer).
À l'inverse, `youp0m` est à la fois un programme que l'on peut télécharger et
un service un ligne qu'il faut déployer pour mettre à jour facilement. Pour
simplifier le déploiement, nous utilisons des images Docker. Il faut cependant
les générer ...
À l'inverse, `youp0m` ou `linky2influx` sont à la fois des programmes que l'on
peut télécharger et des services qu'il faut déployer pour les mettre à
jour. Pour simplifier le déploiement, nous utilisons des images Docker. Il faut
cependant les générer ...
## Mise en place du registre
*Si vous avez choisi Gitlab, vous pouvez utiliser directement le registre
Docker intégré. Si vous utilisez Gitea, continuez cette section.*
::::: {.more}
Si vous avez choisi Gitlab, vous pouvez utiliser directement le registre
Docker intégré. Si vous utilisez Gitea, continuez cette section.
:::::
Afin de disposer de notre propre registre Docker sur lequel publier nos images,
nous allons utiliser l'image de registre fournie par Docker. Elle se lance
@ -31,10 +33,11 @@ docker run --rm -d --name registry --network droneci -p 5000:5000 registry:2
```
</div>
Vous trouverez davantage d'informations
Vous trouverez davantage d'informations pour le déploiement
[ici](https://docs.docker.com/registry/deploying/).
Vous pouvez tester son bon fonctionnement avec la commande suivante :
Nous pouvons tester le bon fonctionnement de notre registre avec la commande
suivante :
<div lang="en-US">
```bash
@ -67,12 +70,14 @@ docker run --rm -p 8080:8080 localhost:5000/youp0m
```
</div>
::::: {.more}
On notera que ceci est possible exclusivement parce que le registre
`localhost:5000` est considéré non-sûr par défaut. C'est à dire qu'il n'a pas
besoin de certificat TLS sur sa connexion HTTP pour être utilisé.\
Si on avait dû utiliser un autre nom de domaine, il aurait fallu
[l'ajouter à la liste des
`insecure-registries`](https://docs.docker.com/registry/insecure/).
:::::
## Suite du déploiement
@ -80,9 +85,9 @@ Si on avait dû utiliser un autre nom de domaine, il aurait fallu
Pour aujourd'hui, nous en resterons là pour le déploiement, car nous n'avons
pas d'environnement de production sur lequel déployer notre service.
Vous pouvez néamnoins tester les plugins
Vous pouvez néanmoins tester les plugins
[`scp`](http://plugins.drone.io/appleboy/drone-scp/) ou
[`ansible`](http://plugins.drone.io/drone-plugins/drone-ansible/), si vous avez
[`ansible`](http://plugins.drone.io/drone-plugins/drone-ansible/) si vous avez
une machine virtuelle avec une connexion SSH. N'hésitez pas à l'ajouter à votre
`.droneci.yml`.

View file

@ -0,0 +1,194 @@
\newpage
## Lancement du module sur la machine cible
Mettons de côté le déploiement continu, pour nous concentrer sur la manière
dont nous allons pouvoir exécuter notre module de relevé de compteur Linky.
\
Le binaire de notre module se lance de la manière suivante :
<div lang="en-US">
```shell
42sh$ ./linky2influx --influx-host localhost --influx-username myuser \
--influx-password mypasswd /dev/ttyEnedis0
# or
42sh$ INFLUXDB_HOST=localhost INFLUXDB_USERNAME=myuser INFLUXDB_PASSWORD=mypasswd \
./linky2influx /dev/ttyEnedis0
```
</div>
`/dev/ttyEnedis0` est le périphérique correspondant à notre liaison série
vers le compteur. On considère qu'une règle `udev` a été écrite pour créer
l'entrée correspondante dans `/dev`.
\
L'objectif est d'établir la méthode qui sera la plus efficace pour
Électropcool, car elle devra sans doute demander à chacune des équipes de
réaliser le packaging des modules qu'elles maintiennent. Il faut pour cela en
tester plusieurs. Certaines peuvent sans doute déjà être éliminées car
inadaptés, c'est à vous de déterminer parmi les technologies d'empacketages
proposées, et celles que vous connaissez, lesquelles vous écartez d'emblée,
lesquelles vous souhaitez garder pour explorer davantage, et enfin laquelle
retient votre attention.
Vous êtes tenu de retenir au minimum 2 solutions distinctes (on considère que
les technologies listées sur la même lignes sont similaires).
La liste de technologies proposées est à la suivante :
- conteneur Docker ou podman,
- conteneur LXC (avec base alpine ou nu),
- conteneur OCI via runc,
- service systemd ou systemd-nspawn,
- packages `.ipk` via Yocto/Bitbake,
- package Nix,
- paquet Snap, FlatPack ou AppImage,
- [k3s](https://k3s.io/),
- ...
Les sections suivantes vous donneront une idée des éléments attendus pour chacun.
### Docker, podman, ...
Nous avons déjà un `Dockerfile` dans notre dépôt, vous avez juste à écrire un
script shell permettant de lancer le module, il doit bien évidemment avoir
accès au périphérique correspondant au compteur.
<div lang="en-US">
```
login_x-TP5/docker/run.sh
```
</div>
### Conteneur LXC
LXC peut s'utiliser de multiple manière différentes, y compris avec des images
OCI. Choisissez la méthode qui vous semble la plus appropriée, il est attendu
au moins un script pour lancer notre conteneur, s'il est différent d'un
<div lang="en-US">
```shell
42sh# lxc-create --template linky2influx --name l2i && lxc-start -n l2i`.
```
</div>
<div lang="en-US">
```
login_x-TP5/lxc/run.sh
```
</div>
En complément, vous pouvez inclure au dépôt de `linky2influx` le modèle
permettant de créer le conteneur LXC, ainsi qu'un exemple de configuration :
<div lang="en-US">
```
login_x-TP5/linky2influx/lxc-scripts/template.sh
login_x-TP5/linky2influx/lxc-scripts/sample.config
```
</div>
### Conteneur OCI via `runc`
`runc` a besoin d'un fichier `config.json` et éventuellement `runtime.json`. La
ligne de commande pour lancer `runc` n'est pas demandée, l'image OCI résultant
du `Dockerfile` sera utilisée et présente pour l'exécution.
### Service systemd ou systemd-nspawn
Le service `systemd` est redondant avec un système Yocto contenant `systemd`,
vous pourriez écrire le script `systemd` et profiter de l'utiliser dans votre
recette `bitbake`.
Un service basé sur `nspawn` peut par contre être potentiellement intéressant,
il pourra être intégré au dépôt :
<div lang="en-US">
```
login_x-TP5/linky2influx/systemd/linky2influx.nspawn
```
</div>
### Yocto
Vous pourriez vouloir écrire une recette Bitbake pour créer et déployer le
module via un paquet `.ipk` ou similaire en fonction de votre configuration.
Écrivez la recette au sein de `meta-electropcool` :
<div lang="en-US">
```
login_x-TP5/meta-electropcool/recipes-support/linky2influx/linky2influx_9999.bb
```
</div>
### Nix
L'expression Nix correspondant au paquet pourra être intégré au dépôt
<div lang="en-US">
```
login_x-TP5/linky2influx/linky2influx.nix
```
</div>
Précisez ensuite dans un `README-nix.md` à côté, la manière dont vous souhaitez
utiliser le package Nix ensuite.
### Snap, Flatpack, AppImage
Intégrez au dépôt le fichier de description, par exemple :
<div lang="en-US">
```
login_x-TP5/linky2influx/snapcraft.yaml
```
</div>
Il faudra également préciser avec un fichier `run.sh` la manière dont lancer
votre conteneur :
<div lang="en-US">
```
login_x-TP5/{snap,flatpack}/run.sh
```
</div>
### k3s
Nous en apprendrons davantage sur Kubernetes au prochain TP, mais si vous
connaissez déjà, vous pourriez vouloir écrire un *Chart* Helm :
<div lang="en-US">
```
login_x-TP5/k3s/linky2influx.yaml
```
</div>
Inutile de vous casser la tête avec ça si vous ne connaissez pas !
### Votre solution
N'hésitez pas à apporter une autre solution originale, que celles qui seraient
listées ici.
<div lang="en-US">
```
login_x-TP5/k3s/linky2influx.yaml
```
</div>
\
À vous de jouer !

View file

@ -0,0 +1,32 @@
Voici à quoi pourrait ressembler le playbook Ansible démarrant notre conteneur
Drone :
<div lang="en-US">
```yaml
- name: Launch drone container
docker_container:
name: droneci
image: drone/drone:1
volumes:
- /var/lib/drone:/data
state: started
restart_policy: unless-stopped
memory: 1G
memory_swap: 1G
networks:
- name: drone
- name: gitea
published_ports:
- "80:80"
env:
DRONE_GITEA_CLIENT_ID: "{{ client.id }}"
DRONE_GITEA_CLIENT_SECRET: "{{ client.secret }}"
DRONE_GITEA_SERVER: "http://gitea:3000"
DRONE_RPC_SECRET: "{{ shared_secret }}"
DRONE_SERVER_HOST: "droneci"
DRONE_SERVER_PROTO: "http"
```
</div>
C'est à vous de définir un `shared_secret`, c'est une chaîne aléatoire qui
permettra aux *Runner*s (section suivante) de s'authentifier.

View file

@ -0,0 +1,26 @@
Voici à quoi pourrait ressembler la ligne de commande démarrant notre conteneur
Drone :
<div lang="en-US">
```shell
export DRONE_GITEA_CLIENT_ID=#FIXME
export DRONE_GITEA_CLIENT_SECRET=#FIXME
export DRONE_RPC_SECRET=$(openssl rand -base64 30)
docker container run --name droneci -d \
-v /var/lib/drone:/data \
--network gitea -p 80:80 \
-e DRONE_GITEA_CLIENT_ID -e DRONE_GITEA_CLIENT_SECRET -e DRONE_GITEA_SERVER=http://gitea:3000 \
-e DRONE_RPC_SECRET -e DRONE_SERVER_HOST=droneci -e DRONE_SERVER_PROTO=http \
drone/drone:1
docker network connect drone droneci
```
</div>
La dernière commande permet à notre conteneur Drone d'être à la fois présent
dans le réseau `gitea` et `drone`, ce qui permet de garder les deux réseaux
distincts.
Gardez la variable d'environnement `DRONE_RPC_SECRET` dans un coin, nous en
aurons encore besoin juste après.

View file

@ -0,0 +1,15 @@
::::: {.question}
La version 2 de Drone, encore plus pratique et sympathique est disponible en
test. Vous pouvez tout à fait l'utiliser pour la suite du TP. Cela ne change
pas la version des *runners* à utiliser.
:::::
Une fois lancé, rendez-vous sur l'interface de DroneCI : <http://droneci/>
Vous serez automatiquement redirigé vers la page d'authentification de Gitea,
puis vers l'autorisation OAuth d'accès de Drone à Gitea. Il faut bien
évidemment valider cette demande, afin que Drone ait accès à nos dépôts.
![OAuth Drone](../devops/oauth-drone.png){width=9cm}

View file

@ -0,0 +1,25 @@
Voici à quoi pourrait ressembler le playbook Ansible démarrant notre agent Drone :
<div lang="en-US">
```yaml
- name: Launch drone runer
docker_container:
name: droneci-runner
image: "drone/drone-runner-docker:1"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
state: started
restart_policy: unless-stopped
memory: 2G
memory_swap: 2G
networks:
- name: drone
env:
DRONE_RPC_PROTO: "http"
DRONE_RPC_HOST: "droneci"
DRONE_RPC_SECRET: "{{ shared_secret }}"
DRONE_RUNNER_CAPACITY: "2"
DRONE_RUNNER_NAME: "my-runner"
DRONE_RUNNER_NETWORKS: "drone,gitea"
```
</div>

View file

@ -0,0 +1,11 @@
Voici à quoi pourrait ressembler la ligne de commande démarrant notre agent Drone :
<div lang="en-US">
```shell
docker container run --name droneci-runner -d \
-v /var/run/docker.sock:/var/run/docker.sock --network drone \
-e DRONE_RPC_PROTO=http -e DRONE_RPC_HOST=droneci -e DRONE_RPC_SECRET \
-e DRONE_RUNNER_CAPACITY=2 -e DRONE_RUNNER_NAME=my-runner -e DRONE_RUNNER_NETWORKS=drone,gitea \
drone/drone-runner-docker:1
```
</div>

View file

@ -0,0 +1,15 @@
### *Runner*
Notre conteneur `droneci` est uniquement une interface graphique qui va
centraliser d'un côté les nouveaux commits à traiter, et de l'autre les
résultats retournés par les agents chargés d'exécuter le code.
Il serait impensable d'exécuter arbitrairement du code en parallèle d'une
application privilégiée (ici, notre conteneur `droneci` a accès aux dépôts
potentiellement privés de Gitea). Les agents qui sont amenés à traiter du code
arbitraire s'exécutent à part et peuvent être de différents types. Dans le
vocabulaire de Drone, on les appelle des ~~blade~~*runners*.
Nous allons lancer un *runner* Docker : il s'agit d'un type d'agent qui va
exécuter nos étapes de compilation dans des conteneurs Docker (oui, quand on
disait que Drone était conçu autour de Docker, c'était pas pour rire !)

View file

@ -0,0 +1,24 @@
## Logiciel d'intégration continue
De nombreuses solutions sont disponibles sur Internet, la plupart du temps
gratuites pour les projets libres ([Travis CI](https://travis-ci.org/),
[CircleCI](https://circleci.com/), ...).
Mais nous allons déployer notre propre solution, en utilisant [Drone
CI](https://drone.io/). C'est une solution d'intégration continue libre et
moderne, conçue tout autour de Docker. Idéale pour nous !
### Interface de contrôle et de dispatch des tâches
La documentation du projet est extrêmement bien faite, suivons la marche à
suivre pour [relier Gitea à
Drone](https://docs.drone.io/server/provider/gitea/).
Drone va avoir besoin d'authentifier les utilisateurs afin d'accéder aux dépôts
privés (avec l'autorisation des utilisateurs). Pour cela, comme l'indique la
documentation de Drone, on va utiliser OAuth2 : dans Gitea, il va falloir créer
une *application OAuth2*. Le formulaire de création se trouve dans la
configuration du compte utilisateur, sous l'onglet *Applications*. Drone aura
également besoin d'une URL de redirection. Dans notre cas, ce sera :
`http://droneci/login`.

View file

@ -0,0 +1 @@
L'environnement étant prêt, il ne reste plus qu'à nous lancer dans nos projets !

View file

@ -0,0 +1,29 @@
Votre playbook ressemblera à quelque chose comme ça :
<div lang="en-US">
```yaml
- name: Launch gitea container
docker_container:
name: gitea
image: "gitea/gitea:{{ version }}"
volumes:
- /var/lib/gitea:/data
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
state: started
restart_policy: unless-stopped
memory: 1G
memory_swap: 1G
networks:
- name: gitea
published_ports:
- "2222:22"
- "3000:3000"
env:
RUN_MODE: "prod"
DOMAIN: "gitea"
SSH_DOMAIN: "gitea"
INSTALL_LOCK: "true"
SECRET_KEY: "{{ secret_key }}"
```
</div>

View file

@ -0,0 +1,13 @@
La ligne de commande pour lancer Gitea ressemblera à quelque chose comme ça :
<div lang="en-US">
```shell
export SECRET_KEY=$(openssl rand -base64 30)
docker container run --name gitea -d \
-v /var/lib/gitea:/data -v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro \
--network gitea -p 2222:22 -p 3000:3000 \
-e RUN_MODE=prod -e DOMAIN=gitea -e SSH_DOMAIN=gitea -e INSTALL_LOCK=true -e SECRET_KEY \
gitea/gitea:1
```
</div>

View file

@ -0,0 +1,15 @@
Plus d'infos sur cette page : <https://docs.gitea.io/en-us/install-with-docker/>.
Une fois le conteneur lancé, vous pouvez accéder à l'interface de gitea sur le
port 3000 de votre machine (à moins que vous n'ayez opté pour un autre port).
Vous pouvez ajouter un nouvel administrateur avec la commande suivante :
<div lang="en-US">
```bash
docker exec gitea gitea admin user create --username "${USER}" --random-password \
--must-change-password=false --admin --email "${USER}@epita.fr"
```
</div>
Notez le mot de passe généré pour [vous y connecter](http://localhost:3000/user/login).

View file

@ -0,0 +1,43 @@
## Gestionnaire de versions
Avant de pouvoir commencer notre aventure, il est nécessaire d'avoir un
gestionnaire de versions. Nous allons ici utiliser Git.
### Problématique du stockage des produits de compilation
Outre les interfaces rudimentaires fournies au dessus de Git
([gitweb](https://git.wiki.kernel.org/index.php/Gitweb)), il y a de nombreux
projets qui offrent davantage que le simple hébergement de dépôts. Vous pouvez
voir sur GitHub notamment qu'il est possible d'attacher à un tag un [certain
nombre de fichiers](https://github.com/docker/compose/releases/latest).
On notera également que depuis le 1er septembre, GitHub propose un [registre
Docker](https://github.blog/2020-09-01-introducing-github-container-registry/)
que l'on peut lier avec ses dépôts. Une fonctionnalité que GitLab propose
[depuis
2016](https://about.gitlab.com/blog/2016/05/23/gitlab-container-registry/).
En effet, la problématique du stockage des produits de compilation est
vaste. Si au début on peut se satisfaire d'un simple serveur web/FTP/SSH pour
les récupérer manuellement, on a vite envie de pouvoir utiliser les outils
standards directement : `docker pull ...`, `npm install ...`, ...
Des programmes et services se sont spécialisés là-dedans, citons notamment
[Artifactory](https://jfrog.com/artifactory/) ou [Nexus
Repository](https://www.sonatype.com/nexus/repository-oss) et bien d'autres.
Dans un premier temps, nous allons nous contenter de publier un binaire associé
à un tag de notre projet.
### Installation et configuration
Allez c'est parti ! première chose à faire : installer et configurer
[Gitea](https://gitea.io/) (ceux qui le souhaitent peuvent choisir
[gitlab](https://gitlab.org/) ou une autre plate-forme, mais la suite sera
moins guidée).
Nous allons utiliser l'image :
[`gitea/gitea`](https://hub.docker.com/r/gitea/gitea) (ou
[`gitlab/gitlab-ce`](https://hub.docker.com/r/gitlab/gitlab-ce)).

View file

@ -1,199 +1 @@
\newpage
Les bons outils
===============
## Gestionnaire de versions
Avant de pouvoir commencer notre aventure, il est nécessaire d'avoir un
gestionnaire de versions. Nous allons ici utiliser Git.
### Problématique du stockage des produits de compilation
Outre les interfaces rudimentaires fournies au dessus de Git
([gitweb](https://git.wiki.kernel.org/index.php/Gitweb)), il y a de nombreux
projets qui offrent davantage que le simple hébergement de dépôts. Vous pouvez
voir sur GitHub notamment qu'il est possible d'attacher à un tag un [certain
nombre de fichiers](https://github.com/docker/compose/releases/latest).
On notera également que depuis le 1er septembre, GitHub propose un [registre
Docker](https://github.blog/2020-09-01-introducing-github-container-registry/)
que l'on peut lier avec ses dépôts. Une fonctionnalité que GitLab propose
[depuis
2016](https://about.gitlab.com/blog/2016/05/23/gitlab-container-registry/).
En effet, la problématique du stockage des produits de compilation est
vaste. Si au début on peut se satisfaire d'un simple serveur web/FTP/SSH pour
les récupérer manuellement, on a vite envie de pouvoir utiliser les outils
standards directement : `docker pull ...`, `npm install ...`, ...
Des programmes et services se sont spécialisés là dedans, citons notamment
[Artifactory](https://jfrog.com/artifactory/) ou [Nexus
Repository](https://www.sonatype.com/nexus/repository-oss) et bien d'autres.
Dans la première partie du TP, nous allons nous contenter de publier un binaire
associé à un tag de notre projet.
### Installation et configuration
Aller c'est parti ! première chose à faire : installer et configurer
[Gitea](https://gitea.io/) (ceux qui le souhaitent peuvent choisir
[gitlab](https://gitlab.org/) ou une autre plate-forme, mais la suite du TP
sera moins guidée pour eux).
Nous allons utiliser l'image :
[`gitea/gitea`](https://hub.docker.com/r/gitea/gitea) (ou
[`gitlab/gitlab-ce`](https://hub.docker.com/r/gitlab/gitlab-ce)).
Votre playbook resemblera à quelque chose comme ça :
<div lang="en-US">
```yaml
- name: Launch gitea container
docker_container:
name: gitea
image: "gitea/gitea:{{ version }}"
volumes:
- /var/lib/gitea:/data
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
state: started
restart_policy: unless-stopped
memory: 1G
memory_swap: 1G
networks:
- name: gitea
published_ports:
- "2222:22"
- "3000:3000"
env:
RUN_MODE: "prod"
DOMAIN: "gitea"
SSH_DOMAIN: "gitea"
INSTALL_LOCK: "true"
SECRET_KEY: "{{ secret_key }}"
```
</div>
Plus d'infos sur cette page : <https://docs.gitea.io/en-us/install-with-docker/>.
Une fois le conteneur lancé, vous pouvez accéder à l'interface de gitea sur le
port 3000 de votre machine (à moins que vous n'ayez opté pour un autre port).
Vous pouvez ajouter un nouvel administrateur avec la commande suivante :
<div lang="en-US">
```bash
docker exec gitea gitea admin user create --username "${USER}" --random-password \
--must-change-password=false --admin --email "${USER}@epita.fr"
```
</div>
Notez le mot de passe généré pour [vous y connecter](http://localhost:3000/user/login).
## Logiciel d'intégration continue
De nombreuses solutions sont disponibles sur Internet, la plupart du temps
gratuite pour les projets libres ([Travis CI](https://travis-ci.org/),
[CircleCI](https://circleci.com/), ...).
Mais nous allons déployer notre propre solution, en utilisant [Drone
CI](https://drone.io/). C'est une solution d'intégration continue libre et
moderne, conçue tout autour de Docker. Idéale pour nous !
### Interface de contrôle et de dispatch des tâches
La documentation du projet est extrêmement bien faite, suivons la marche à
suivre pour [relier Gitea à
Drone](https://docs.drone.io/server/provider/gitea/).
L'URL de redirection sera dans notre cas : `http://droneci/login`.
Voici à quoi pourrait ressemble le playbook Ansible démarrant notre conteneur
Drone :
<div lang="en-US">
```yaml
- name: Launch drone container
docker_container:
name: droneci
image: drone/drone:1
volumes:
- /var/lib/drone:/data
state: started
restart_policy: unless-stopped
memory: 1G
memory_swap: 1G
networks:
- name: drone
- name: gitea
published_ports:
- "80:80"
env:
DRONE_GITEA_CLIENT_ID: "{{ client.id }}"
DRONE_GITEA_CLIENT_SECRET: "{{ client.secret }}"
DRONE_GITEA_SERVER: "http://gitea:3000"
DRONE_RPC_SECRET: "{{ shared_secret }}"
DRONE_SERVER_HOST: "droneci"
DRONE_SERVER_PROTO: "http"
```
</div>
Une fois lancé, rendez-vous sur l'interface de DroneCI : <http://droneci/>
Vous serez automatiquement redirigé vers la page d'authentification de Gitea,
puis vers l'autorisation OAuth d'accès de Drone à Gitea. Il faut bien
évidemment valider cette demande, afin que Drone ait accès à nos dépôts.
![OAuth Drone](../devops/oauth-drone.png){width=9cm}
### *Runner*
Notre conteneur `droneci` est uniquement une interface graphique qui va
centraliser d'un côté les nouveaux commits à traiter, et de l'autre les
résultats retournés par les agents chargés d'exécuter le code.
Il serait impensable d'exécuter arbitrairement du code en parallèle d'une
application privilégiée (ici, notre conteneur `droneci` a accès aux dépôts
potentiellement privés de Gitea). Les agents qui sont amenés à traiter du code
arbitraire s'exécutent à part et peuvent être de différents types. Dans le
vocabulaire de Drone, on les appelle des ~~blade~~*runners*.
Nous allons lancer un *runner* Docker : il s'agit d'un type d'agent qui va
exécuter nos étapes de compilation dans des conteneurs Docker (oui, quand on
disait que Drone était conçu autour de Docker, c'était pas pour rire !)
Voici à quoi pourrait ressemble le playbook Ansible démarrant notre agent Drone :
<div lang="en-US">
```yaml
- name: Launch drone runer
docker_container:
name: droneci-runner
image: "drone/drone-runner-docker:1"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
state: started
restart_policy: unless-stopped
memory: 2G
memory_swap: 2G
networks:
- drone
env:
DRONE_RPC_PROTO: "http"
DRONE_RPC_HOST: "droneci"
DRONE_RPC_SECRET: "{{ shared_secret }}"
DRONE_RUNNER_CAPACITY: 2
DRONE_RUNNER_NAME: "my-runner"
DRONE_RUNNER_NETWORKS: "drone,gitea"
```
</div>
L'environnement étant prêt, il ne reste plus qu'à nous lancer dans nos projets !

View file

@ -0,0 +1,10 @@
### Pour aller plus loin
Le mouvement DevOps tend à utiliser mettre en avant la CI/CD, ce ne leur est
évidemment pas exclusivement réservé. Toute entreprise ayant une méthodologie
de développement saine dispose d'outils automatisés de construction et de
tests.
Pour en savoir plus sur le DevOps, vous devriez lire la première partie du [TP
des SRS](https://virli.nemunai.re/tutorial-5-srs.pdf), qui traite justement de
ce sujet.

View file

@ -0,0 +1,127 @@
\newpage
Électropcool
============
Bienvenue dans la société Électropcool !
Électropcool est une société française spécialisée dans
l'[immotique](https://fr.wikipedia.org/wiki/Immotique), elle vend des
équipements IoT, principalement à destination des professionels du bâtiment. Le
produit phare est une plate-forme de
[GTB](https://fr.wikipedia.org/wiki/Gestion_technique_de_b%C3%A2timent)
modulaire de suivi de la vie d'un bâtiment où sont regroupés les différents
compteurs, capteurs et actionneurs que l'on retrouve dans les installations.
Les nouveaux bâtiments conçus autour la plate-forme permettent de faire de
sérieuses économies d'entretien (en ne faisant déplacer les techiciens que
lorsque c'est nécessaire) tout en permettant d'anticiper les problèmes (grâce à
un moteur de *machine-learning* capable d'anticiper les pannes) et les besoins
en combustible (liés à la météo)[^HOMEASSISTANT].
[^HOMEASSISTANT]: Si ça vous met l'eau à la bouche, jettez un œil du côté du
projet <https://www.home-assistant.io/> qui fait un peu moins de
*bullshit*, mais est bien réel !
La principale difficulté que rencontre Électropcool est qu'aucun bâtiment ne
dispose des mêmes références de pièces et qu'en dehors des nouveaux bâtiments
pour lesquels la société peut imposer des équipements électroniques
spécifiquement supportés et compatibles avec la plate-forme qu'elle vend, il lui
est bien souvent nécessaire de faire des développements spécifiques pour
s'interfacer avec de l'électronique existant : c'est notamment le cas pour les
chaudières et les
[VMC](https://fr.wikipedia.org/wiki/Ventilation_m%C3%A9canique_contr%C3%B4l%C3%A9e),
qui, compte tenu de leur coût de remplacement prohibitif, nécessitent souvent
de réaliser des interfaces électroniques spécifiques pour s'adapter à
l'existant.
L'entreprise est en train de prendre un tournant historique et
souhaite accélérer ses développements pour faire face à la concurrence
qui arrive sur le marché.
\
L'entreprise utilise principalement de nombreux équipements de la *Raspberry Pi
fundation*, notamment les [Compute Module 3 et
4](https://www.raspberrypi.com/products/compute-module-4/) et les [Raspberry Pi
Zero W](https://www.raspberrypi.com/products/raspberry-pi-zero-w/), ainsi que
de nombreux PCB fait par l'entreprise, à base de micro-contrôleurs AVR,
lorsqu'il est nécessaire de pour s'interfacer avec des équipements
propriétaires non prévu pour l'immotique.
Une grosse partie des travaux est donc réalisé avec un noyau Linux, sur du
matériel très performant, pour de l'embarqué.
\
Tous les modules logiciels qui interragissent avec les capteurs sont
aujourd'hui intégrés dans un système construit à l'aide de
[`bitbake`](https://www.yoctoproject.org/). L'entreprise grossissant à vue d'œil,
il devient de plus en plus difficile de synchroniser les équipes concilier la
stabilité des *releases* avec le besoin de déployer de nouvelles
fonctionnalités chaque semaine.
Vous avez été chargés d'étudier la meilleure façon de déployer les différents
modules, sans qu'il soit nécessaire de reconstruire une image Yocto à chaque
fois, mais tout en assurant la stabilité de la plate-forme.
Le directeur technique vous suggère de regarder du côté des conteneurs
applicatifs, qui sont légers et assurent un cloisonnement suffisant pour ne pas
entraver la stabilité de la plate-forme en cas de déploiement d'un module
défaillant.
Vous êtes également chargés de jeter les bases du système d'intégration continu
des modules. (La partie déploiement continu, sera réalisé plus tard par
l'équipe développant le nouveau système de base, suivant le meilleur outil que
retiendrez.)
\
Le projet qui vous servira de base pour vos tests sera
[`linky2influx`](https://git.nemunai.re/nemunaire/linky2influx) : à partir d'un
compteur [Linky](https://fr.wikipedia.org/wiki/Linky), branché sur les bornes
de [téléinformation client du
compteur](https://hallard.me/demystifier-la-teleinfo/) et [lisant le
protocole](https://www.enedis.fr/media/2035/download) pour enregistrer les
données dans une *Time-series database*, en l'occurrence InfluxDB.
![La prod chez Électropcool](../devops/electropcool.jpg)
Dans un premier temps, on voudra juste compiler notre projet, pour s'assurer
que chaque commit poussé ne contient pas d'erreur de compilation, dans
l'environnement défini comme étant celui de production. Ensuite, on ajoutera
quelques tests automatiques. Puis nous publierons automatiquement le binaire
`linky2influx` comme fichier associé à un tag au sein de l'interface web du
gestionnaire de versions.
Nous testerons enfin différentes solution pour déployer notre binaire, afin
d'établir quelle est la solution adéquate.
## Préparer le terrain
Tous les déploiements sont à faire sur votre machine et la plate-forme de CI
utilisera massivement les conteneurs Docker, qui seront regroupés au sein de
réseaux Docker. Cela vous permettra d'utiliser la résolution de noms entre vos
conteneurs.
Vous devriez dès maintenant créer les deux réseaux suivants sur votre machines :
<div lang="en-US">
```shell
docker network create gitea
docker network create drone
```
</div>
Étant donné que votre machine ne dispose pas de domaine sur Internet et que
l'on va essayer de simplifier au maximum l'installation, vous devriez ajouter
cette ligne à votre fichier `/etc/hosts` (ou
`\Windows\System32\drivers\etc\hosts`) :
<div lang="en-US">
```conf
127.0.0.1 gitea droneci
```
</div>
Cette ligne va vous permettre de résoudre les noms des conteneurs. Cela
permettra aux requêtes OAuth de se faire de manière transparente pour vous
lorsque vous serez dans votre navigateur.

View file

@ -4,19 +4,19 @@ But du TP
=========