\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 :
```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 }}" ```
Plus d'infos sur cette page : . 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 :
```bash docker exec gitea gitea admin user create --username "${USER}" --random-password \ --must-change-password=false --admin --email "${USER}@epita.fr" ```
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 :
```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" ```
Une fois lancé, rendez-vous sur l'interface de 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 :
```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" ```
L'environnement étant prêt, il ne reste plus qu'à nous lancer dans nos projets !