Caching paket APT di alur kerja Tindakan GitHub

9

Saya menggunakan alur kerja Tindakan Github berikut untuk proyek C saya. Alur kerja selesai dalam ~ 40 detik, tetapi lebih dari setengah dari waktu itu dihabiskan dengan menginstal valgrindpaket dan dependensinya.

Saya percaya caching dapat membantu saya mempercepat alur kerja. Saya tidak keberatan menunggu beberapa detik tambahan, tapi ini sepertinya membuang-buang sumber daya GitHub yang tidak ada gunanya.

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

Menjalankan sudo apt-get install -y valgrindmenginstal paket-paket berikut:

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

Saya tahu Actions mendukung caching direktori tertentu (dan sudah ada beberapa pertanyaan dan artikel SO yang dijawab tentang ini), tetapi saya tidak yakin di mana semua paket berbeda yang diinstal oleh apt berakhir. Saya berasumsi /bin/atau /usr/bin/bukan satu-satunya direktori yang terpengaruh oleh menginstal paket.

Apakah ada cara yang elegan untuk menembolok paket sistem yang diinstal untuk menjalankan alur kerja di masa depan?

natiiix
sumber

Jawaban:

5

Tujuan dari jawaban ini adalah untuk menunjukkan bagaimana caching dapat dilakukan dengan tindakan github. Tidak harus menunjukkan cara cache valgrind, yang ditampilkan, tetapi juga untuk menunjukkan bahwa tidak semuanya bisa / harus di-cache, dan timbal balik dari cache dan memulihkan cache vs menginstal ulang ketergantungan perlu diperhitungkan.


Anda akan menggunakan actions/cachetindakan untuk melakukan ini.

Tambahkan sebagai langkah (sebelum Anda perlu menggunakan valgrind):

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

Langkah selanjutnya harus mencoba untuk menginstal versi yang di-cache jika ada atau menginstal dari repositori:

- 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

Penjelasan

Set VALGRIND_VERSION rahasia untuk menjadi hasil dari:

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

ini akan memungkinkan Anda untuk membatalkan cache ketika versi baru dirilis hanya dengan mengubah nilai rahasianya.

dpkg -L valgrinddigunakan untuk membuat daftar semua file yang diinstal saat menggunakan sudo apt-get install valgrind.

Apa yang sekarang dapat kita lakukan dengan perintah ini adalah menyalin semua dependensi ke folder cache kita:

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

Selanjutnya

Selain menyalin semua komponen valgrind, mungkin juga perlu menyalin dependensi (seperti libcdalam kasus ini), tetapi saya tidak menyarankan melanjutkan sepanjang jalur ini karena rantai ketergantungan hanya tumbuh dari sana. Tepatnya, dependensi yang diperlukan untuk menyalin untuk akhirnya memiliki lingkungan yang cocok untuk dijalankan valgrind adalah sebagai berikut:

  • libc6
  • libgcc1
  • gcc-8-base

Untuk menyalin semua dependensi ini, Anda dapat menggunakan sintaks yang sama seperti di atas:

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

Apakah semua pekerjaan ini benar-benar layak masalah ketika semua yang diperlukan untuk menginstal valgrinddi tempat pertama adalah menjalankannya sudo apt-get install valgrind? Jika tujuan Anda adalah untuk mempercepat proses pembuatan, maka Anda juga harus mempertimbangkan jumlah waktu yang diperlukan untuk memulihkan (mengunduh, dan mengekstrak) cache vs. hanya menjalankan perintah lagi untuk menginstal valgrind.


Dan akhirnya untuk mengembalikan cache, dengan anggapan disimpan /tmp/valgrind, Anda dapat menggunakan perintah:

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

Yang pada dasarnya akan menyalin semua file dari cache ke partisi root.

Selain proses di atas, saya juga punya contoh "caching valgrind" dengan menginstal dan mengkompilasinya dari sumber. Cache sekarang sekitar 63MB (terkompresi) dalam ukuran dan satu masih perlu menginstal secara terpisah libcjenis yang mengalahkan tujuannya.


Referensi:

smac89
sumber
Oh, begitu, itu cerdik. Saya tidak tahu Anda bisa dengan aman mengambil semua file yang diinstal dan hanya memindahkannya ke direktori lain tanpa merusak sesuatu. Saya tidak yakin itu berhasil. Saya menjalankan alur kerja 3 kali dan selalu pergi Cache not found for input keys: ***.. Saya menambahkan VALGRIND_VERSIONrahasia di Pengaturan> Rahasia, benarkah itu?
natiiix
Saya sudah berhasil mendapatkan cache hit sekarang, tapi saya mendapatkan kesalahan berikut dari 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 ada kemungkinan caching valgrinddibuat sehingga libcketergantungan tidak diinstal ketika cache diambil. Saya tidak berada di dekat monitor sekarang, tetapi saya mencari kesalahan Anda dan sepertinya itu adalah bug dengan valgrind. Anda dapat mencoba juga menginstal libc versi 6 dan melihat apakah itu membantu. Saya akan memperbarui jawabannya hari ini
smac89
Ya, sepertinya begitu. Jika saya tambahkan sudo apt-get install -y libc6-dbg, maka itu berfungsi dengan baik, tapi kemudian saya juga di mana saya mulai karena instalasi paket itu membutuhkan waktu 30 detik lebih.
natiiix
@natiiix Tampaknya caching valgrind mungkin lebih berfungsi daripada yang diantisipasi, tetapi setidaknya ini menunjukkan bagaimana caching dapat dilakukan di ubuntu. Melihat dependensi valgrind, ada setidaknya 6 dependensi, dan saya pikir mereka semua mungkin perlu di-cache jika ini berfungsi.
smac89
4

Anda bisa membuat gambar buruh pelabuhan dengan valgrindpra - instal dan menjalankan alur kerja Anda di situ.

Buat Dockerfiledengan sesuatu seperti:

FROM ubuntu

RUN apt-get install -y valgrind

Bangun dan dorong ke dockerhub:

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

Kemudian gunakan sesuatu seperti berikut ini sebagai alur kerja Anda:

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

Benar-benar belum diuji, tetapi Anda mendapatkan idenya.

terpecah belah
sumber
Ini adalah ide yang sangat menarik, tetapi agak merusak seluruh prinsip membiarkan Tindakan GitHub melakukan cache lingkungan / artefak untuk menjalankan masa depan dan sebagai gantinya memerlukan beberapa upaya tambahan dari pihak saya. Di sisi lain, setelah selesai, ini mungkin dapat digunakan kembali dengan cukup mudah.
natiiix
1
Terserah Anda untuk memutuskan mana yang paling cocok untuk Anda, atau apa yang paling membutuhkan pengorbanan dari pihak Anda ¯_ (ツ) _ / ¯
bagilah