quentin.dufour.io/_posts/2023-04-17-automatiser-la-publication-des-artefacts.md

174 lines
9.5 KiB
Markdown

---
layout: post
title: Automatiser la publication des artefacts
date: 2023-04-17T07:45:22.402+02:00
status: published
sitemap: true
category: developpement
description: Nous avons précédémment défini un workflow de publication
d'artefacts, maintenant on va chercher à l'automatiser un peu
---
Cet article fait suite aux 3 articles précédents :
- [Un registre statique Docker avec Garage](https://quentin.dufour.io/blog/2023-04-06/un-registre-statique-docker-avec-garage/)
- [Construire et publier des conteneurs sans daemon Docker](https://quentin.dufour.io/blog/2023-04-11/fabriquer-des-conteneurs-l%C3%A9gers-depuis-une-ci-cd/)
- [Spécifier un registre d'artefacts et l'intégrer dans un site web](https://quentin.dufour.io/blog/2023-04-12/un-outil-sans-daemon-pour-g%C3%A9rer-ses-artefacts-de-build/)
Mainteant qu'on comprend mieux le problème, on aimerait définir un outil pour nous faciliter la vie à la publication. Il sera indépendant (standalone) mais développé au sein du dépôt albatros car il est prévu pour être utilisé de pair. Dans ce billet, son nom de code est `alba`.
Commençons par les entrées de notre programme : un ensemble de fichiers qui doit être généré par nos outils Nix :
```bash
# static
nix build .#packages.x86_64-linux.albatros -o df/linux/amd64/albatros
nix build .#packages.i686-linux.albatros -o df/linux/386/albatros
nix build .#packages.aarch64-linux.albatros -o df/arm64/albatros
nix build .#packages.armv6l-linux.albatros -o df/linux/arm/albatros
# docker
nix build .#packages.x86_64-linux.docker.albatros -o docker/linux.amd64.tar.gz
nix build .#packages.armv6l-linux.docker.albatros -o docker/linux.arm.tar.gz
nix build .#packages.aarch64-linux.docker.albatros -o docker/linux.arm64.tar.gz
nix build .#packages.i686-linux.docker.albatros -o docker/linux.386.tar.gz
```
Et maintenant imaginons les commandes de base :
```bash
alba static push -t albatros:0.9 docker/ 's3://download.deuxfleurs.org?endpoint=garage.deuxfleurs.fr&region=garage&s3ForcePathStyle=true'
alba container push -t albatros:0.9 docker/ 's3://registry.deuxfleurs.org?endpoint=garage.deuxfleurs.fr&region=garage&s3ForcePathStyle=true'
alba container push -t albatros:0.9 docker/ 'docker://docker.io/dxflrs/albatros:0.9'
```
On pourra imaginer d'avantage de commandes par la suite comme :
```bash
alba static ls -t albatros 's3://download.deuxfleurs.org?endpoint=garage.deuxfleurs.fr&region=garage'
alba static rm -t albatros:0.8 's3://download.deuxfleurs.org?endpoint=garage.deuxfleurs.fr&region=garage'
alba static gc -t albatros --keep 10 's3://download.deuxfleurs.org?endpoint=garage.deuxfleurs.fr&region=garage'
```
Mais c'est en dehors du périmètre pour le moment !
## La glue
J'ai choisi d'utiliser un petit panel de bibliothèques pour faire la glue entre tout ça :
- Go CDK pour la publication des artefacts sur un object storage
- crane pour la publication d'images OCI sur un registre compatible
- Cobra comme framework CLI
- containers/image comme bibliothèque de manipulation des conteneurs
## Publier un binaire statique sur Garage
Après implémentation, voici la trace de la commande :
```
$ ./alba static push -t albatros:0.9 df/ 's3://download.deuxfleurs.org?endpoint=garage.deuxfleurs.fr&s3ForcePathStyle=true&region=garage'
df/linux/386/albatros -> df-dist-v1/albatros/0.9/linux/386/albatros
df/linux/amd64/albatros -> df-dist-v1/albatros/0.9/linux/amd64/albatros
df/linux/arm/albatros -> df-dist-v1/albatros/0.9/linux/arm/albatros
df/linux/arm64/albatros -> df-dist-v1/albatros/0.9/linux/arm64/albatros
tag -> df-dist-v1/albatros/0.9
manifest -> df-dist-v1/albatros
✅ push succeeded
```
On peut vérifier que tout fonctionne avec curl :
```
$ curl https://download.deuxfleurs.org/df-dist-v1/albatros
{"name":"albatros","tags":["0.9"]}
$ curl https://download.deuxfleurs.org/df-dist-v1/albatros/0.9
{"flavors":[{"resources":[{"path":"albatros"}],"platform":{"architecture":"386","os":"linux"}},{"resources":[{"path":"albatros"}],"platform":{"architecture":"amd64","os":"linux"}},{"resources":[{"path":"albatros"}],"platform":{"architecture":"arm","os":"linux"}},{"resources":[{"path":"albatros"}],"platform":{"architecture":"arm64","os":"linux"}}]}
$ curl -I https://download.deuxfleurs.org/df-dist-v1/albatros/0.9/linux/amd64/albatros
HTTP/2 200
content-type: application/octet-stream
```
## Publier un conteneur sur Garage
Après implémentation, voici la trace de la commande :
```
$ ./alba container push -t albatest:0.9 docker/ 's3://registry.deuxfleurs.org?endpoint=garage.deuxfleurs.fr&s3ForcePathStyle=true&region=garage'
-- load docker archives --
docker/linux.386.tar.gz -> [oci system image; os:linux, arch:386, path:/tmp/alba-oci4145280408/0]
docker/linux.amd64.tar.gz -> [oci system image; os:linux, arch:amd64, path:/tmp/alba-oci4145280408/1]
docker/linux.arm.tar.gz -> [oci system image; os:linux, arch:arm, path:/tmp/alba-oci4145280408/2]
docker/linux.arm64.tar.gz -> [oci system image; os:linux, arch:arm64, path:/tmp/alba-oci4145280408/3]
-- merge system images --
-> oci-layout
-> index.json
/tmp/alba-oci4145280408/0/blobs/sha256 -> /tmp/alba-oci4145280408/multi/blobs/sha256 (3 items)
/tmp/alba-oci4145280408/1/blobs/sha256 -> /tmp/alba-oci4145280408/multi/blobs/sha256 (3 items)
/tmp/alba-oci4145280408/2/blobs/sha256 -> /tmp/alba-oci4145280408/multi/blobs/sha256 (3 items)
/tmp/alba-oci4145280408/3/blobs/sha256 -> /tmp/alba-oci4145280408/multi/blobs/sha256 (3 items)
-- push to the s3 target --
[index] index.json -> v2/albatest/manifests/0.9
[index] index.json -> v2/albatest/manifests/sha256:5b522fa8bdd9c959c31c0dfd59cabe4e3f1c2a05fff794f1b371af9cd60e106f
[manifest linux 386] /tmp/alba-oci4145280408/multi/blobs/sha256/d81112fd42d4d055a449dfbf054bdce6e4862825f57ea713cd9a622f88b294e1 -> v2/albatest/manifests/sha256:d81112fd42d4d055a449dfbf054bdce6e4862825f57ea713cd9a622f88b294e1
[manifest linux amd64] /tmp/alba-oci4145280408/multi/blobs/sha256/db570b83c5f5f2f0dca7ab9c814d45395654fd91a01bfd573d729ff8cb9cba5c -> v2/albatest/manifests/sha256:db570b83c5f5f2f0dca7ab9c814d45395654fd91a01bfd573d729ff8cb9cba5c
[manifest linux arm] /tmp/alba-oci4145280408/multi/blobs/sha256/0a1d95229adc211231f0114d49b05b8f1dd1005a15e46b67d94d2ff6995eb0ff -> v2/albatest/manifests/sha256:0a1d95229adc211231f0114d49b05b8f1dd1005a15e46b67d94d2ff6995eb0ff
[manifest linux arm64] /tmp/alba-oci4145280408/multi/blobs/sha256/7e3c758750bcec00f384e7a48037ced80745ec06b4140aab8e1ceb76d635029f -> v2/albatest/manifests/sha256:7e3c758750bcec00f384e7a48037ced80745ec06b4140aab8e1ceb76d635029f
[config linux 386] /tmp/alba-oci4145280408/multi/blobs/sha256/d69316bdcae505156be3560d0ec594c3b1f51c8590872a83b9f1735ac56c56bc -> v2/albatest/blobs/sha256:d69316bdcae505156be3560d0ec594c3b1f51c8590872a83b9f1735ac56c56bc
[blob linux 386] 1 items sent
[config linux amd64] /tmp/alba-oci4145280408/multi/blobs/sha256/f42e98b1f00892273b28d8f198f0a4e9138f19b0ceba8ceb6790cda6901d6e3f -> v2/albatest/blobs/sha256:f42e98b1f00892273b28d8f198f0a4e9138f19b0ceba8ceb6790cda6901d6e3f
[blob linux amd64] 1 items sent
[config linux arm] /tmp/alba-oci4145280408/multi/blobs/sha256/8830adff9feedffd3141a4aca5ea0ff2a8ae3b5731b4801eeb19aadad2d9ed05 -> v2/albatest/blobs/sha256:8830adff9feedffd3141a4aca5ea0ff2a8ae3b5731b4801eeb19aadad2d9ed05
[blob linux arm] 1 items sent
[config linux arm64] /tmp/alba-oci4145280408/multi/blobs/sha256/7add660d53f77f5c6ac6a833840ce5148015e0e1913a3d839ae0cf87a055e6c6 -> v2/albatest/blobs/sha256:7add660d53f77f5c6ac6a833840ce5148015e0e1913a3d839ae0cf87a055e6c6
[blob linux arm64] 1 items sent
Not yet implemented
✅ push succeeded
```
On voit que ça fonctionne comme prévu :
```
$ docker pull registry.deuxfleurs.org/albatest:0.9
0.9: Pulling from albatest
ca485cd5ee4e: Pull complete
Digest: sha256:5b522fa8bdd9c959c31c0dfd59cabe4e3f1c2a05fff794f1b371af9cd60e106f
Status: Downloaded newer image for registry.deuxfleurs.org/albatest:0.9
registry.deuxfleurs.org/albatest:0.9
```
On peut aussi lister les tags comme prévu :
```
$ crane ls registry.deuxfleurs.org/albatest
0.8
0.10
0.9
```
## Publier un conteneur sur un registre
Ici on partage le code de base avec la publication sur Garage, et ensuite, on utilise la logique de Crane.
```
$ ./alba container push -t albatest:0.9 ./docker 'docker://docker.io/superboum/albatest:0.9'
-- load docker archives --
docker/linux.386.tar.gz -> [oci system image; os:linux, arch:386, path:/tmp/alba-oci2921914546/0]
docker/linux.amd64.tar.gz -> [oci system image; os:linux, arch:amd64, path:/tmp/alba-oci2921914546/1]
docker/linux.arm.tar.gz -> [oci system image; os:linux, arch:arm, path:/tmp/alba-oci2921914546/2]
docker/linux.arm64.tar.gz -> [oci system image; os:linux, arch:arm64, path:/tmp/alba-oci2921914546/3]
-- merge system images --
-> oci-layout
-> index.json
/tmp/alba-oci2921914546/0/blobs/sha256 -> /tmp/alba-oci2921914546/multi/blobs/sha256 (3 items)
/tmp/alba-oci2921914546/1/blobs/sha256 -> /tmp/alba-oci2921914546/multi/blobs/sha256 (3 items)
/tmp/alba-oci2921914546/2/blobs/sha256 -> /tmp/alba-oci2921914546/multi/blobs/sha256 (3 items)
/tmp/alba-oci2921914546/3/blobs/sha256 -> /tmp/alba-oci2921914546/multi/blobs/sha256 (3 items)
--- push to registry ---
✅ push succeeded
```
On peut ensuite voir l'image sur le docker hub :
![](/assets/20230503_13h49m47s_grim.png)
## Conclusion
Ce petit outil du nom de alba permet de remplacer le script nix+shell que j'avais réalisé pour Garage, ainsi que Kaniko et manifest-tool. Il nous permet aussi pour la première fois de “transformer” Garage en registre statique. Enfin, pour la suite, il devait nous permettre d'implémenter aisément la garbage collection des artifacts dans le futur.