Mise en cache des packages APT dans le workflow Actions GitHub

9

J'utilise le workflow Actions Github suivant pour mon projet C. Le flux de travail se termine en ~ 40 secondes, mais plus de la moitié de ce temps est consacré à l'installation du valgrindpackage et de ses dépendances.

Je pense que la mise en cache pourrait m'aider à accélérer le flux de travail. Cela ne me dérange pas d'attendre quelques secondes supplémentaires, mais cela semble être un gaspillage inutile des ressources de GitHub.

name: C Workflow

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1

    - name: make
      run: make

    - name: valgrind
      run: |
        sudo apt-get install -y valgrind
        valgrind -v --leak-check=full --show-leak-kinds=all ./bin

L'exécution sudo apt-get install -y valgrindinstalle les packages suivants:

  • gdb
  • gdbserver
  • libbabeltrace1
  • libc6-dbg
  • libipt1
  • valgrind

Je sais que les actions prennent en charge la mise en cache d'un répertoire spécifique (et il y a déjà plusieurs questions et articles sur les réponses à ce sujet), mais je ne sais pas où se trouvent tous les différents packages installés par apt. Je suppose /bin/ou /usr/bin/ne suis pas le seul répertoire affecté par l'installation de packages.

Existe-t-il un moyen élégant de mettre en cache les packages système installés pour les futures exécutions de workflow?

natiiix
la source

Réponses:

5

Le but de cette réponse est de montrer comment la mise en cache peut être effectuée avec des actions github. Pas nécessairement pour montrer comment mettre en cache valgrind, ce qu'il montre, mais aussi pour montrer que tout ne peut / ne doit pas être mis en cache, et les compromis de la mise en cache et de la restauration d'un cache par rapport à la réinstallation de la dépendance doivent être pris en compte.


Vous utiliserez l' actions/cacheaction pour ce faire.

Ajoutez-le comme une étape (avant d'utiliser Valgrind):

- name: Cache valgrind
  uses: actions/[email protected]
  id: cache-valgrind
  with:
      path: "~/valgrind"
      key: ${{secrets.VALGRIND_VERSION}}

L'étape suivante doit tenter d'installer la version en cache, le cas échéant, ou d'installer à partir des référentiels:

- name: Install valgrind
  env:
    CACHE_HIT: ${{steps.cache-valgrind.outputs.cache-hit}}
    VALGRIND_VERSION: ${{secrets.VALGRIND_VERSION}}
  run: |
      if [[ "$CACHE_HIT" == 'true' ]]; then
        sudo cp --verbose --force --recursive ~/valgrind/* /
      else
        sudo apt-get install --yes valgrind="$VALGRIND_VERSION"
        mkdir -p ~/valgrind
        sudo dpkg -L valgrind | while IFS= read -r f; do if test -f $f; then echo $f; fi; done | xargs cp --parents --target-directory ~/valgrind/
      fi

Explication

Définissez VALGRIND_VERSIONsecret comme la sortie de:

apt-cache policy valgrind | grep -oP '(?<=Candidate:\s)(.+)'

cela vous permettra d'invalider le cache lorsqu'une nouvelle version est publiée simplement en changeant la valeur du secret.

dpkg -L valgrindest utilisé pour répertorier tous les fichiers installés lors de l'utilisation sudo apt-get install valgrind.

Ce que nous pouvons maintenant faire avec cette commande est de copier toutes les dépendances dans notre dossier cache:

dpkg -L valgrind | while IFS= read -r f; do if test -f $f; then echo $f; fi; done | xargs cp --parents --target-directory ~/valgrind/

en outre

En plus de copier tous les composants de valgrind, il peut également être nécessaire de copier les dépendances (comme libcdans ce cas), mais je ne recommande pas de continuer sur cette voie car la chaîne de dépendances ne fait que croître à partir de là. Pour être précis, les dépendances nécessaires pour copier pour enfin avoir un environnement adapté à Valgrind pour s'exécuter sont les suivantes:

  • libc6
  • libgcc1
  • gcc-8-base

Pour copier toutes ces dépendances, vous pouvez utiliser la même syntaxe que ci-dessus:

for dep in libc6 libgcc1 gcc-8-base; do
    dpkg -L $dep | while IFS= read -r f; do if test -f $f; then echo $f; fi; done | xargs cp --parents --target-directory ~/valgrind/
done

Est-ce que tout ce travail en vaut vraiment la peine alors que tout ce qui est nécessaire pour installer valgrinden premier lieu est de simplement exécuter sudo apt-get install valgrind? Si votre objectif est d'accélérer le processus de génération, vous devez également prendre en compte le temps qu'il faut pour restaurer (télécharger et extraire) le cache par rapport à simplement relancer la commande pour l'installer valgrind.


Et enfin pour restaurer le cache, en supposant qu'il soit stocké dans /tmp/valgrind, vous pouvez utiliser la commande:

cp --force --recursive /tmp/valgrind/* /

Ce qui copiera essentiellement tous les fichiers du cache vers la partition racine.

En plus du processus ci-dessus, j'ai également un exemple de "mise en cache de valgrind" en l'installant et en le compilant depuis la source. La taille du cache est désormais d'environ 63 Mo (compressée) et il faut encore installer séparément libcquel type de but échoue .


Références:

smac89
la source
Oh, je vois, c'est ingénieux. Je ne savais pas que vous pouviez prendre tous les fichiers installés en toute sécurité et les déplacer dans un autre répertoire sans casser quelque chose. Je ne suis pas sûr que cela fonctionne. J'ai exécuté le flux de travail 3 fois et j'y vais toujours Cache not found for input keys: ***.. J'ai ajouté le VALGRIND_VERSIONsecret dans Paramètres> Secrets, n'est-ce pas?
natiiix
J'ai réussi à obtenir un accès au cache maintenant, mais je reçois l'erreur suivante de valgrind:--2906-- Reading syms from /lib/x86_64-linux-gnu/ld-2.27.so --2906-- Considering /lib/x86_64-linux-gnu/ld-2.27.so .. --2906-- .. CRC mismatch (computed 1b7c895e wanted 2943108a) --2906-- object doesn't have a symbol table
natiiix
@natiiix il est possible que la mise valgrinden cache ait fait en sorte que la libcdépendance ne soit pas installée lorsque le cache est récupéré. Je ne suis pas près d'un moniteur maintenant, mais j'ai recherché votre erreur et il semble que ce soit un bug avec valgrind. Vous pouvez également essayer d'installer libc version 6 et voir si cela aide. Je
mettrai à
Oui, il semble que oui. Si j'ajoute sudo apt-get install -y libc6-dbg, cela fonctionne bien, mais je suis aussi là où j'ai commencé, car l'installation de ce package prend 30 secondes de plus.
natiiix
@natiiix Il semble que la mise en cache de valgrind peut être plus de travail que prévu, mais au moins cela montre comment la mise en cache peut être effectuée sur ubuntu. En regardant les dépendances de valgrind, il y a au moins 6 dépendances, et je pense qu'elles ont probablement toutes besoin d'être mises en cache pour que cela fonctionne.
smac89
4

Vous pouvez créer une image docker avec valgrindpréinstallé et exécuter votre flux de travail à ce sujet.

Créez un Dockerfileavec quelque chose comme:

FROM ubuntu

RUN apt-get install -y valgrind

Construisez-le et poussez-le sur dockerhub:

docker build -t natiiix/valgrind .
docker push natiiix/valgrind

Utilisez ensuite quelque chose comme ce qui suit comme flux de travail:

name: C Workflow

on: [push, pull_request]

jobs:
  build:
    container: natiiix/valgrind

    steps:
    - uses: actions/checkout@v1

    - name: make
      run: make

    - name: valgrind
      run: valgrind -v --leak-check=full --show-leak-kinds=all ./bin

Complètement non testé, mais vous avez l'idée.

diviser
la source
C'est une idée très intéressante, mais elle sape en quelque sorte le principe de laisser les actions GitHub mettre en cache l'environnement / les artefacts pour les futures exécutions et nécessite à la place un effort supplémentaire de ma part. D'un autre côté, une fois cela fait, cela pourrait probablement être réutilisé assez facilement.
natiiix
1
C'est à vous de décider ce qui vous convient le mieux ou ce qui nécessite le plus d'offort de votre part ¯_ (ツ) _ / ¯
divivid