Zwischenspeichern von APT-Paketen im GitHub Actions-Workflow

9

Ich verwende den folgenden Github Actions-Workflow für mein C-Projekt. Der Workflow endet in ~ 40 Sekunden, aber mehr als die Hälfte dieser Zeit wird für die Installation des valgrindPakets und seiner Abhängigkeiten aufgewendet .

Ich glaube, Caching könnte mir helfen, den Workflow zu beschleunigen. Es macht mir nichts aus, ein paar zusätzliche Sekunden zu warten, aber dies scheint nur eine sinnlose Verschwendung der Ressourcen von GitHub zu sein.

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

Beim Ausführen werden sudo apt-get install -y valgrinddie folgenden Pakete installiert:

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

Ich weiß, dass Aktionen das Zwischenspeichern eines bestimmten Verzeichnisses unterstützen (und es gibt bereits mehrere beantwortete SO-Fragen und Artikel dazu), aber ich bin nicht sicher, wo all die verschiedenen von apt installierten Pakete landen. Ich gehe davon aus /bin/oder bin /usr/bin/nicht die einzigen Verzeichnisse, die von der Installation von Paketen betroffen sind.

Gibt es eine elegante Möglichkeit, die installierten Systempakete für zukünftige Workflow-Läufe zwischenzuspeichern?

natiiix
quelle

Antworten:

5

Der Zweck dieser Antwort ist zu zeigen, wie das Caching mit Github-Aktionen durchgeführt werden kann. Nicht unbedingt, um zu zeigen, wie zwischengespeichert wird valgrind, was es zeigt, sondern auch, um zu zeigen, dass nicht alles zwischengespeichert werden kann / sollte, und die Kompromisse zwischen dem Zwischenspeichern und Wiederherstellen eines Caches und dem erneuten Installieren der Abhängigkeit müssen berücksichtigt werden.


Sie werden die actions/cacheAktion nutzen, um dies zu tun.

Fügen Sie es als Schritt hinzu (bevor Sie valgrind verwenden müssen):

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

Im nächsten Schritt sollte versucht werden, die zwischengespeicherte Version zu installieren oder über die Repositorys zu installieren:

- 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

Erläuterung

Setze das VALGRIND_VERSIONGeheimnis als Ausgabe von:

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

Auf diese Weise können Sie den Cache ungültig machen, wenn eine neue Version veröffentlicht wird, indem Sie einfach den Wert des Geheimnisses ändern.

dpkg -L valgrindwird verwendet, um alle bei der Verwendung installierten Dateien aufzulisten sudo apt-get install valgrind.

Mit diesem Befehl können wir jetzt alle Abhängigkeiten in unseren Cache-Ordner kopieren:

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

Außerdem

Zusätzlich zum Kopieren aller Komponenten von valgrindkann es auch erforderlich sein, die Abhängigkeiten zu kopieren (wie libcin diesem Fall). Ich empfehle jedoch nicht, diesen Pfad fortzusetzen, da die Abhängigkeitskette nur von dort aus wächst. Um genau zu sein, müssen folgende Abhängigkeiten kopiert werden, um schließlich eine Umgebung zu erhalten, in der valgrind ausgeführt werden kann:

  • libc6
  • libgcc1
  • gcc-8-Base

Um alle diese Abhängigkeiten zu kopieren, können Sie dieselbe Syntax wie oben verwenden:

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

Ist all diese Arbeit wirklich die Mühe wert, wenn alles, was für die Installation überhaupt erforderlich valgrindist, einfach ausgeführt werden muss sudo apt-get install valgrind? Wenn Sie den Erstellungsprozess beschleunigen möchten, müssen Sie auch die Zeit berücksichtigen, die zum Wiederherstellen (Herunterladen und Extrahieren) des Caches erforderlich ist, anstatt den Befehl zur Installation einfach erneut auszuführen valgrind.


Und schließlich /tmp/valgrindkönnen Sie den Befehl verwenden , um den Cache wiederherzustellen, vorausgesetzt, er ist dort gespeichert :

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

Dadurch werden im Grunde alle Dateien aus dem Cache auf die Root-Partition kopiert.

Zusätzlich zu dem oben beschriebenen Prozess habe ich auch ein Beispiel für das "Zwischenspeichern von Valgrind" durch Installieren und Kompilieren aus dem Quellcode. Der Cache hat jetzt eine Größe von ungefähr 63 MB (komprimiert) und es muss noch separat installiert werden, libcwelche Art von Niederlage den Zweck erfüllt .


Verweise:

smac89
quelle
Oh, ich verstehe, das ist genial. Ich hatte keine Ahnung, dass Sie alle installierten Dateien sicher in ein anderes Verzeichnis verschieben können, ohne etwas zu beschädigen. Ich bin mir nicht sicher, ob es funktioniert. Ich habe den Workflow dreimal ausgeführt und bin immer gegangen Cache not found for input keys: ***.. Ich habe das VALGRIND_VERSIONGeheimnis unter Einstellungen> Geheimnisse hinzugefügt , stimmt das?
Natiiix
Ich habe es jetzt geschafft, einen Cache-Treffer zu bekommen, aber ich --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
erhalte
@natiiix Es besteht die Möglichkeit, dass durch das Caching valgrinddie libcAbhängigkeit nicht installiert wird, wenn der Cache abgerufen wird. Ich bin jetzt nicht in der Nähe eines Monitors, aber ich habe Ihren Fehler nachgeschlagen und es scheint, als wäre es ein Fehler mit Valgrind. Sie können auch versuchen, libc Version 6 zu installieren und prüfen, ob dies hilfreich ist. Ich werde die Antwort später heute aktualisieren
smac89
Ja, es scheint so. Wenn ich hinzufüge sudo apt-get install -y libc6-dbg, funktioniert es gut, aber dann bin ich auch dort, wo ich angefangen habe, weil die Installation dieses Pakets noch 30 Sekunden dauert.
Natiiix
@natiiix Es scheint, dass das Zwischenspeichern von Valgrind mehr Arbeit als erwartet ist, aber zumindest zeigt dies, wie das Zwischenspeichern auf Ubuntu durchgeführt werden kann. Wenn man sich die Abhängigkeiten von valgrind ansieht, gibt es mindestens 6 Abhängigkeiten, und ich denke, dass sie wahrscheinlich alle zwischengespeichert werden müssen, wenn dies funktionieren soll.
smac89
4

Sie können ein Docker-Image mit valgrindvorinstalliertem erstellen und Ihren Workflow darauf ausführen.

Erstellen Sie eine Dockerfilemit so etwas wie:

FROM ubuntu

RUN apt-get install -y valgrind

Erstellen Sie es und schieben Sie es zu Dockerhub:

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

Verwenden Sie dann Folgendes wie Ihren Workflow:

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

Völlig ungetestet, aber Sie bekommen die Idee.

deivid
quelle
Dies ist eine sehr interessante Idee, die jedoch das gesamte Prinzip untergräbt, GitHub Actions die Umgebung / Artefakte für zukünftige Läufe zwischenspeichern zu lassen, und stattdessen einige zusätzliche Anstrengungen von meiner Seite erfordert. Auf der anderen Seite könnte dies, sobald dies erledigt ist, wahrscheinlich recht einfach wiederverwendet werden.
Natiiix
1
Es liegt an Ihnen zu entscheiden, was für Sie am besten funktioniert oder was die größte Abweichung von Ihrer Seite erfordert ¯_ (ツ) _ / ¯
deivid