quentin.dufour.io/_posts/2023-04-17-automatiser-la-p...

9.5 KiB

layout title date status sitemap category description
post Automatiser la publication des artefacts 2023-04-17T07:45:22.402+02:00 published true developpement 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 :

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 :

# 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 :

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 :

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 :

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.