Кешування пакетів APT у робочому процесі GitHub Actions


9

Я використовую наступний робочий процес Github Actions для мого проекту C. Робочий процес закінчується за ~ 40 секунд, але більше половини цього часу витрачається на встановлення valgrindпакета та його залежностей.

Я вважаю, що кешування може допомогти мені прискорити робочий процес. Я не проти чекати пару зайвих секунд, але це просто здається безглуздим витрачанням ресурсів 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

Запуск sudo apt-get install -y valgrindвстановлює такі пакети:

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

Я знаю, що Action підтримують кешування певного каталогу (і вже є кілька відповідей на такі питання та статті щодо цього), але я не впевнений, де закінчуються всі різні пакунки, встановлені apt. Я вважаю , /bin/або /usr/bin/не тільки каталоги , які постраждали від установки пакетів.

Чи є елегантний спосіб кешування встановлених системних пакетів для майбутніх робочих процесів?

Відповіді:


5

Мета цієї відповіді - показати, як кешування можна виконати з діями github. Не обов’язково показувати, як кешувати valgrind, що він показує, але також показувати, що не все можна / слід кешувати, а компроміси кешування та відновлення кешу та перевстановлення залежності потрібно враховувати.


Для цього ви скористаєтесь actions/cacheдіями.

Додайте його як крок (перед тим, як використовувати valgrind):

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

Наступним кроком слід спробувати встановити кешовану версію, якщо така є, або встановити з сховищ:

- 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

Пояснення

Встановіть VALGRIND_VERSIONсекрет як вихід:

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

це дозволить вам визнати недійсним кеш, коли випущена нова версія, просто змінивши значення секрету.

dpkg -L valgrindвикористовується для списку всіх встановлених файлів при використанні sudo apt-get install valgrind.

Тепер ми можемо скористатися цією командою - скопіювати всі залежності в нашу папку кешу:

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

Крім того

На додаток до копіювання всіх компонентів valgrind, можливо, також буде потрібно копіювати залежності (наприклад, libcу цьому випадку), але я не рекомендую продовжувати цей шлях, оскільки ланцюг залежностей просто зростає звідти. Якщо бути точним, залежності, необхідні для копіювання, щоб нарешті створити середовище, придатне для запуску valgrind, є таким:

  • libc6
  • libgcc1
  • gcc-8-основа

Щоб скопіювати всі ці залежності, ви можете використовувати той же синтаксис, що і вище:

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

Чи справді ця робота вартує клопоту, коли все, що потрібно встановити valgrindв першу чергу - це просто запустити sudo apt-get install valgrind? Якщо ваша мета - прискорити процес збирання, то вам також доведеться враховувати кількість часу, необхідного для відновлення (завантаження та вилучення) кешу, а також просто запустити команду знову для встановлення valgrind.


І нарешті, щоб відновити кеш, припускаючи, що він зберігається в /tmp/valgrind, ви можете використовувати команду:

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

Що в основному буде копіювати всі файли з кеша до кореневого розділу.

Окрім вищезазначеного процесу, я також маю приклад "кешування вальгринду" шляхом встановлення та компіляції з джерела. Зараз кеш має розмір приблизно 63 Мб (стислий), і все одно потрібно окремо встановити, libcякий тип перемагає призначення.


Список літератури:


О, я бачу, це геніально. Я не мав уявлення, що ти можеш сміливо взяти всі встановлені файли і просто перенести їх в інший каталог, нічого не порушивши. Я не впевнений, що це працює. Я пробіг робочий процес 3 рази і завжди йду Cache not found for input keys: ***.. Я додав VALGRIND_VERSIONсекрет у Налаштуваннях> Секрети, правда?
natiiix

Зараз мені вдалося отримати кеш-хіт, але я отримую таку помилку від 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 є ймовірність, що кешування valgrindзробило це таким чином, що libcзалежність не встановлюється під час отримання кешу. Зараз я не біля монітора, але я перевірив вашу помилку і, здається, це помилка з valgrind. Ви також можете спробувати встановити libc версії 6 і подивитися, чи це допомагає. Відповідь я
оновлю

Так, здається, так. Якщо я додаю sudo apt-get install -y libc6-dbg, то це працює добре, але тоді я теж з того, з чого почав, тому що установка цього пакета займає ще 30 секунд.
natiiix

@natiiix Схоже, що кешування valgrind може бути більшою роботою, ніж передбачалося, але принаймні це показує, як кешування можна виконати на ubuntu. Дивлячись на залежність валлінджу, існує як мінімум 6 залежностей, і я думаю, що їх, мабуть, потрібно кешувати, якщо це спрацює.
smac89

4

Ви можете створити зображення докера із valgrindпопередньо встановленою програмою та запустити на цьому робочий процес.

Створіть Dockerfileщось із:

FROM ubuntu

RUN apt-get install -y valgrind

Створіть його та натисніть на dockerhub:

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

Тоді в якості робочого процесу використовуйте щось подібне:

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

Цілком неперевірений, але ви отримуєте ідею.


Це дуже цікава ідея, але вона начебто підриває весь принцип дозволу GitHub Actions кешувати середовище / артефакти для майбутніх запусків, а натомість потребує додаткових зусиль з мого боку. З іншого боку, щойно зроблено, це, ймовірно, можна повторно використати.
natiiix

1
Ви вирішуєте, що для вас найкраще чи що вимагає найбільше комфорту з вашого боку ¯_ (ツ) _ / ¯
квітня
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.