Memorizzazione nella cache dei pacchetti APT nel flusso di lavoro Azioni GitHub


9

Uso il seguente flusso di lavoro di azioni Github per il mio progetto C. Il flusso di lavoro termina in ~ 40 secondi, ma più della metà del tempo viene impiegato per l'installazione del valgrindpacchetto e delle sue dipendenze.

Credo che la cache possa aiutarmi ad accelerare il flusso di lavoro. Non mi dispiace aspettare un paio di secondi in più, ma questo sembra solo uno spreco inutile delle risorse di 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'esecuzione sudo apt-get install -y valgrindinstalla i seguenti pacchetti:

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

So che le azioni supportano la memorizzazione nella cache di una directory specifica (e ci sono già molte domande e articoli SO su questo con risposta), ma non sono sicuro di dove finiscano tutti i diversi pacchetti installati da apt. Presumo /bin/o /usr/bin/non sono le uniche directory interessate dall'installazione dei pacchetti.

Esiste un modo elegante per memorizzare nella cache i pacchetti di sistema installati per future esecuzioni del flusso di lavoro?

Risposte:


5

Lo scopo di questa risposta è mostrare come è possibile eseguire la memorizzazione nella cache con le azioni github. Non necessariamente per mostrare come memorizzare nella cache valgrind, cosa che mostra, ma anche per mostrare che non tutto può / dovrebbe essere memorizzato nella cache, e devono essere presi in considerazione i compromessi della memorizzazione nella cache e del ripristino di una cache rispetto alla reinstallazione della dipendenza.


Farai uso actions/cachedell'azione per fare questo.

Aggiungilo come passaggio (prima di utilizzare valgrind):

- name: Cache valgrind
  uses: actions/cache@v1.0.3
  id: cache-valgrind
  with:
      path: "~/valgrind"
      key: ${{secrets.VALGRIND_VERSION}}

Il passaggio successivo dovrebbe tentare di installare la versione cache se presente o installare dai repository:

- 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

Spiegazione

Imposta il VALGRIND_VERSIONsegreto come output di:

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

questo ti permetterà di invalidare la cache quando viene rilasciata una nuova versione semplicemente modificando il valore del segreto.

dpkg -L valgrindviene utilizzato per elencare tutti i file installati durante l'utilizzo sudo apt-get install valgrind.

Ciò che ora possiamo fare con questo comando è copiare tutte le dipendenze nella nostra cartella 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/

inoltre

Oltre a copiare tutti i componenti di valgrind, potrebbe anche essere necessario copiare le dipendenze (come libcin questo caso), ma non consiglio di continuare lungo questo percorso perché la catena delle dipendenze cresce da lì. Per essere precisi, le dipendenze necessarie per copiare per avere finalmente un ambiente adatto a valgrind per funzionare sono le seguenti:

  • libc6
  • libgcc1
  • gcc-8-base

Per copiare tutte queste dipendenze, è possibile utilizzare la stessa sintassi di cui sopra:

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

Tutto questo lavoro vale davvero la pena quando valgrindin primo luogo tutto ciò che è necessario per installare è semplicemente eseguire sudo apt-get install valgrind? Se il tuo obiettivo è velocizzare il processo di compilazione, devi anche prendere in considerazione la quantità di tempo necessaria per ripristinare (scaricare ed estrarre) la cache e semplicemente eseguire nuovamente il comando per installare valgrind.


E infine per ripristinare la cache, supponendo che sia archiviata in /tmp/valgrind, è possibile utilizzare il comando:

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

Il che sostanzialmente copierà tutti i file dalla cache alla partizione root.

Oltre al processo sopra, ho anche un esempio di "memorizzazione nella cache di valgrind" installandolo e compilandolo dal sorgente. La cache ora ha una dimensione di circa 63 MB (compressa) e si deve ancora installare separatamente libcquale tipo di sconfigge lo scopo.


Riferimenti:


Oh, capisco, è geniale. Non avevo idea che avresti potuto tranquillamente prendere tutti i file installati e spostarli in un'altra directory senza rompere qualcosa. Non sono sicuro che funzioni però. Ho eseguito il flusso di lavoro 3 volte e vado sempre Cache not found for input keys: ***.. Ho aggiunto il VALGRIND_VERSIONsegreto in Impostazioni> Segreti, giusto?
natiiix,

Sono riuscito a ottenere un hit della cache ora, ma sto ottenendo il seguente errore da 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 esiste la possibilità che la memorizzazione nella cache valgrindabbia consentito di libcnon installare la dipendenza al momento del recupero della cache. Ora non sono vicino a un monitor, ma ho cercato il tuo errore e sembra che sia un bug con valgrind. Puoi anche provare a installare libc versione 6 e vedere se questo aiuta. Aggiornerò la risposta più tardi oggi
smac89,

Sì, sembra di si. Se aggiungo sudo apt-get install -y libc6-dbg, allora funziona benissimo, ma poi sono anche da dove ho iniziato perché l'installazione di quel pacchetto richiede altri 30 secondi.
natiiix,

@natiiix Sembra che la memorizzazione nella cache di valgrind possa essere più impegnativa del previsto, ma almeno questo mostra come è possibile eseguire la memorizzazione nella cache su Ubuntu. Osservando le dipendenze di valgrind, ci sono almeno 6 dipendenze e penso che probabilmente tutte avranno bisogno di essere memorizzate nella cache per funzionare.
smac89,

4

È possibile creare un'immagine docker con valgrindpreinstallato ed eseguirne il flusso di lavoro.

Crea un Dockerfilecon qualcosa come:

FROM ubuntu

RUN apt-get install -y valgrind

Costruiscilo e spingilo su dockerhub:

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

Quindi utilizzare qualcosa di simile al seguente come flusso di lavoro:

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

Completamente non testato, ma hai l'idea.


Questa è un'idea molto interessante, ma in qualche modo mina l'intero principio di lasciare che GitHub Actions memorizzi nella cache l'ambiente / artefatti per le esecuzioni future e invece richiede un ulteriore sforzo da parte mia. D'altra parte, una volta fatto, questo potrebbe probabilmente essere riutilizzato abbastanza facilmente.
natiiix

1
Sta a te decidere cosa funziona meglio per te o cosa richiede più offesa dalla tua parte ¯_ (ツ) _ / ¯
deivid
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.