From 7c7ba21c90e16aa1c9981122d8d02d6c07b9b8ae Mon Sep 17 00:00:00 2001 From: Dorian Stoll Date: Sat, 22 Jul 2023 20:27:44 +0200 Subject: [PATCH] pkg: fedora: Create containers manually, reclaim space from the runner The GitHub runners usually have about 14 GB of free space. This is not enough to build a full Fedora kernel with debug symbols. Disabling the debug symbols is not an option, because they are needed to generate data for BPF programs, and because it would mean more patches to the spec file which I would like to avoid. The runners contain a bunch of software that is entirely useless for our purposes. For example, a full .NET distribution, the entire Android SDK, and a bunch of cached container images that arent Fedora. However, with GitHubs container directive it is not possible to remove these, because no custom code is ever executed on the runner itself. To execute code on the runner, the container has to be created and used manually. To simplify this, all of the actual logic has been moved to a dedicated script, similar to how the CI on iptsd is set up. --- .github/scripts/container/create.sh | 33 +++++ .github/scripts/container/exec.sh | 46 +++++++ .github/scripts/package/fedora.sh | 76 ++++++++++ .github/scripts/repository/fedora.sh | 72 ++++++++++ .github/workflows/fedora-37.yml | 199 ++++++++++++--------------- .github/workflows/fedora-38.yml | 199 ++++++++++++--------------- 6 files changed, 403 insertions(+), 222 deletions(-) create mode 100644 .github/scripts/container/create.sh create mode 100644 .github/scripts/container/exec.sh create mode 100644 .github/scripts/package/fedora.sh create mode 100644 .github/scripts/repository/fedora.sh diff --git a/.github/scripts/container/create.sh b/.github/scripts/container/create.sh new file mode 100644 index 000000000..cb980b0b1 --- /dev/null +++ b/.github/scripts/container/create.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +if [ -z "${GITHUB_REPOSITORY_ID:-}" ]; then + echo "GITHUB_REPOSITORY_ID is unset!" + exit 1 +fi + +if [ -z "${GITHUB_WORKSPACE:-}" ]; then + echo "GITHUB_WORKSPACE is unset!" + exit 1 +fi + +IMAGE="${1:-}" + +if [ -z "${IMAGE}" ]; then + echo "Container image is unset!" + exit 1 +fi + +if command -v docker &> /dev/null; then + DOCKER="docker" +elif command -v podman &> /dev/null; then + DOCKER="podman" +else + echo "Could not find docker / podman!" + exit 1 +fi + +exec "${DOCKER}" run -d --name "${GITHUB_REPOSITORY_ID}" \ + -v "${GITHUB_WORKSPACE}:/working" --workdir "/working" \ + --entrypoint "tail" "${IMAGE}" -f /dev/null \ No newline at end of file diff --git a/.github/scripts/container/exec.sh b/.github/scripts/container/exec.sh new file mode 100644 index 000000000..41596465b --- /dev/null +++ b/.github/scripts/container/exec.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +if [ -z "${GITHUB_REPOSITORY_ID:-}" ]; then + echo "GITHUB_REPOSITORY_ID is unset!" + exit 1 +fi + +if [ -z "${1:-}" ]; then + echo "Arguments are unset!" + exit 1 +fi + +ENVVARS=() +COMMAND=() + +while (( "${#}" )); do + case "$1" in + -e) + ENVVARS+=("-e") + shift + + ENVVARS+=("$1") + shift + ;; + --) + shift + while (( "${#}" )); do + COMMAND+=("$1") + shift + done + ;; + esac +done + +if command -v docker &> /dev/null; then + DOCKER="docker" +elif command -v podman &> /dev/null; then + DOCKER="podman" +else + echo "Could not find docker / podman!" + exit 1 +fi + +exec "${DOCKER}" exec "${ENVVARS[@]}" "${GITHUB_REPOSITORY_ID}" "${COMMAND[@]}" \ No newline at end of file diff --git a/.github/scripts/package/fedora.sh b/.github/scripts/package/fedora.sh new file mode 100644 index 000000000..aed0360e0 --- /dev/null +++ b/.github/scripts/package/fedora.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +if [ -z "$1" ]; then + $0 setup-builddeps + $0 setup-secureboot + $0 build-packages + $0 sign-packages + exit +fi + +dnf() +{ + command dnf -y "$@" +} + +case "$1" in +setup-builddeps) + # Setup build environment + dnf distro-sync + dnf install @rpm-development-tools git rpm-sign + + # Install build dependencies + dnf builddep kernel + + # Install additional build dependencies + dnf install sbsigntools + ;; +setup-secureboot) + if [ -z "${SB_KEY:-}" ]; then + echo "WARNING: No secureboot key configured, skipping signing." + exit + fi + + # Install the surface secureboot certificate + echo "${SB_KEY}" | base64 -d > pkg/fedora/kernel-surface/secureboot/MOK.key + cp pkg/keys/surface.crt pkg/fedora/kernel-surface/secureboot/MOK.crt + ;; +build-packages) + pushd pkg/fedora/kernel-surface || exit 1 + + # setup git + git config --global user.name "surfacebot" + git config --global user.email "surfacebot@users.noreply.github.com" + + # Build source RPM packages + python3 build-linux-surface.py --mode srpm --ark-dir kernel-ark --outdir srpm + + # Remove the kernel-ark tree to get as much free disk space as possible + rm -rf kernel-ark + + # Build binary RPM packages + find srpm -name '*.src.rpm' -type f -exec rpmbuild -rb \ + --define "_topdir ${PWD}/rpmbuild" --define "_rpmdir ${PWD}/out" {} \; + + popd || exit 1 + ;; +sign-packages) + if [ -z "${GPG_KEY:-}" ] || [ -z "${GPG_KEY_ID:-}" ]; then + echo "WARNING: No GPG key configured, skipping signing." + exit + fi + + pushd pkg/fedora/kernel-surface/out/x86_64 || exit 1 + + # import GPG key + echo "${GPG_KEY}" | base64 -d | gpg --import --no-tty --batch --yes + + # sign packages + find . -name '*.rpm' -type f -exec \ + rpm --resign {} --define "_gpg_name ${GPG_KEY_ID}" \; + + popd || exit 1 + ;; +esac diff --git a/.github/scripts/repository/fedora.sh b/.github/scripts/repository/fedora.sh new file mode 100644 index 000000000..dc62149fa --- /dev/null +++ b/.github/scripts/repository/fedora.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +dnf() +{ + command dnf -y "$@" +} + +if [ -z "${GIT_REF:-}" ]; then + echo "GIT_REF is unset!" + exit 1 +fi + +if [ -z "${GITHUB_REPOSITORY:-}" ]; then + echo "GITHUB_REPOSITORY is unset!" + exit 1 +fi + +if [ -z "${SURFACEBOT_TOKEN:-}" ]; then + echo "SURFACEBOT_TOKEN is unset!" + exit 1 +fi + +if [ -z "${BRANCH_STAGING:-}" ]; then + echo "BRANCH_STAGING is unset!" + exit 1 +fi + +FEDORA="${1:-}" + +if [ -z "${FEDORA}" ]; then + echo "Fedora version is unset!" + exit 1 +fi + +REPONAME="$(echo "${GITHUB_REPOSITORY}" | cut -d'/' -f2)" +REPO="https://surfacebot:${SURFACEBOT_TOKEN}@github.com/linux-surface/repo.git" + +# parse git tag from ref +GIT_TAG="${GIT_REF#refs/tags/}" + +# Install dependencies +dnf install git findutils + +# clone package repository +git clone -b "${BRANCH_STAGING}" "${REPO}" repo + +# copy packages +find "fedora-${FEDORA}-latest" -type f -exec cp {} "repo/fedora/f${FEDORA}" \; +pushd "repo/fedora/f${FEDORA}" || exit 1 + +# convert packages into references +while read -rd $'\n' FILE; do + echo "${REPONAME}:${GIT_TAG}/$(basename "${FILE}")" > "${FILE}.blob" + rm "${FILE}" +done <<< "$(find . -name '*.rpm' -type f)" + +RAND="$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 32 | head -n 1)" +BRANCH="${BRANCH_STAGING}-${RAND}" + +# set git identity +git config --global user.name "surfacebot" +git config --global user.email "surfacebot@users.noreply.github.com" + +# commit and push +git checkout -b "${BRANCH}" +git add . +git commit -m "Update Fedora ${FEDORA} ${REPONAME} package" +git push --set-upstream origin "${BRANCH}" + +popd || exit 1 \ No newline at end of file diff --git a/.github/workflows/fedora-37.yml b/.github/workflows/fedora-37.yml index 6191aca2b..525d178ee 100644 --- a/.github/workflows/fedora-37.yml +++ b/.github/workflows/fedora-37.yml @@ -1,144 +1,121 @@ +name: Fedora 37 + +env: + FEDORA: 37 + GPG_KEY_ID: 56C464BAAC421453 + on: push: tags: - 'fedora-37-*' -name: Fedora 37 - -env: - GPG_KEY_ID: 56C464BAAC421453 - jobs: build: name: Build Kernel runs-on: ubuntu-latest - container: registry.fedoraproject.org/fedora:37 steps: - - name: Checkout code - uses: actions/checkout@v3 + - name: Maximize disk space + uses: easimon/maximize-build-space@master + with: + root-reserve-mb: 5120 + remove-dotnet: true + remove-android: true + remove-docker-images: true - - name: Install build dependencies - run: | - dnf distro-sync -y - dnf install -y git make gcc flex bison bzip2 rpm-build - dnf install -y rpmdevtools rpm-sign 'dnf-command(builddep)' + - name: Checkout code + uses: actions/checkout@v3 - # Install build dependencies - dnf builddep -y kernel + - name: Initialize containers + run: | + bash ./.github/scripts/container/create.sh \ + registry.fedoraproject.org/fedora:${{ env.FEDORA }} - # Install additional build dependencies - dnf install -y sbsigntools + - name: Install build dependencies + run: | + bash ./.github/scripts/container/exec.sh \ + -- \ + bash ./.github/scripts/package/fedora.sh setup-builddeps - - name: Setup secureboot certificate - env: - SB_KEY: ${{ secrets.SURFACE_SB_KEY }} - run: | - # Install the surface secureboot certificate - echo "$SB_KEY" | base64 -d > pkg/fedora/kernel-surface/secureboot/MOK.key - cp pkg/keys/surface.crt pkg/fedora/kernel-surface/secureboot/MOK.crt + - name: Setup secureboot certificate + env: + SB_KEY: ${{ secrets.SURFACE_SB_KEY }} + run: | + bash ./.github/scripts/container/exec.sh \ + -e SB_KEY \ + -- \ + bash ./.github/scripts/package/fedora.sh setup-secureboot - - name: Build packages - run: | - cd pkg/fedora/kernel-surface + - name: Build packages + run: | + bash ./.github/scripts/container/exec.sh \ + -- \ + bash ./.github/scripts/package/fedora.sh build-packages - # setup git - git config --global user.email "surfacebot@users.noreply.github.com" - git config --global user.name "surfacebot" + - name: Sign packages + env: + GPG_KEY: ${{ secrets.LINUX_SURFACE_GPG_KEY }} + run: | + bash ./.github/scripts/container/exec.sh \ + -e GPG_KEY \ + -e GPG_KEY_ID \ + -- \ + bash ./.github/scripts/package/fedora.sh sign-packages - # Build source RPM packages - python3 build-linux-surface.py --mode srpm --ark-dir kernel-ark --outdir srpm - - # Remove the kernel-ark tree to get as much free disk space as possible - rm -rf kernel-ark - - # Build binary RPM packages - rpmbuild -rb --define "_rpmdir $PWD/out" srpm/*.src.rpm - - - name: Sign packages - env: - GPG_KEY: ${{ secrets.LINUX_SURFACE_GPG_KEY }} - run: | - cd pkg/fedora/kernel-surface/out/x86_64 - - # import GPG key - echo "$GPG_KEY" | base64 -d | gpg --import --no-tty --batch --yes - - # sign packages - rpm --resign *.rpm --define "_gpg_name $GPG_KEY_ID" - - - name: Upload artifacts - uses: actions/upload-artifact@v3 - with: - name: fedora-37-latest - path: pkg/fedora/kernel-surface/out/x86_64 + - name: Upload artifacts + uses: actions/upload-artifact@v3 + with: + name: fedora-${{ env.FEDORA }}-latest + path: pkg/fedora/kernel-surface/out/x86_64 release: name: Publish release needs: [build] runs-on: ubuntu-latest steps: - - name: Download artifacts - uses: actions/download-artifact@v3 - with: - name: fedora-37-latest - path: fedora-37-latest + - name: Download artifacts + uses: actions/download-artifact@v3 + with: + name: fedora-${{ env.FEDORA }}-latest + path: fedora-${{ env.FEDORA }}-latest - - name: Upload assets - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.LINUX_SURFACE_BOT_TOKEN }} - file: ./*-latest/* - tag: ${{ github.ref }} - overwrite: true - file_glob: true + - name: Upload assets + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.LINUX_SURFACE_BOT_TOKEN }} + file: ./*-latest/* + tag: ${{ github.ref }} + overwrite: true + file_glob: true repo: name: Update package repository needs: [release] runs-on: ubuntu-latest - container: registry.fedoraproject.org/fedora:37 steps: - - name: Install dependencies - run: | - dnf install -y git findutils + - name: Checkout repository + uses: actions/checkout@v3 - - name: Download artifacts - uses: actions/download-artifact@v3 - with: - name: fedora-37-latest - path: fedora-37-latest + - name: Download artifacts + uses: actions/download-artifact@v3 + with: + name: fedora-${{ env.FEDORA }}-latest + path: fedora-${{ env.FEDORA }}-latest - - name: Update repository - env: - SURFACEBOT_TOKEN: ${{ secrets.LINUX_SURFACE_BOT_TOKEN }} - BRANCH_STAGING: u/staging - GIT_REF: ${{ github.ref }} - run: | - repo="https://surfacebot:${SURFACEBOT_TOKEN}@github.com/linux-surface/repo.git" + - name: Initialize containers + run: | + bash ./.github/scripts/container/create.sh \ + registry.fedoraproject.org/fedora:${{ env.FEDORA }} - # clone package repository - git clone -b "${BRANCH_STAGING}" "${repo}" repo - - # copy packages - cp fedora-37-latest/* repo/fedora/f37 - cd repo/fedora/f37 - - # parse git tag from ref - GIT_TAG=$(echo $GIT_REF | sed 's|^refs/tags/||g') - - # convert packages into references - for pkg in $(find . -name '*.rpm'); do - echo "linux-surface:$GIT_TAG/$(basename $pkg)" > $pkg.blob - rm $pkg - done - - # set git identity - git config --global user.email "surfacebot@users.noreply.github.com" - git config --global user.name "surfacebot" - - # commit and push - update_branch="${BRANCH_STAGING}-$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)" - git checkout -b "${update_branch}" - git add . - git commit -m "Update Fedora 37 kernel" - git push --set-upstream origin "${update_branch}" + - name: Update repository + env: + SURFACEBOT_TOKEN: ${{ secrets.LINUX_SURFACE_BOT_TOKEN }} + GIT_REF: ${{ github.ref }} + BRANCH_STAGING: u/staging + run: | + bash ./.github/scripts/container/exec.sh \ + -e SURFACEBOT_TOKEN \ + -e GIT_REF \ + -e BRANCH_STAGING \ + -e GITHUB_REPOSITORY \ + -- \ + bash ./.github/scripts/repository/fedora.sh ${{ env.FEDORA }} \ No newline at end of file diff --git a/.github/workflows/fedora-38.yml b/.github/workflows/fedora-38.yml index abb0255c1..3396243a8 100644 --- a/.github/workflows/fedora-38.yml +++ b/.github/workflows/fedora-38.yml @@ -1,144 +1,121 @@ +name: Fedora 38 + +env: + FEDORA: 38 + GPG_KEY_ID: 56C464BAAC421453 + on: push: tags: - 'fedora-38-*' -name: Fedora 38 - -env: - GPG_KEY_ID: 56C464BAAC421453 - jobs: build: name: Build Kernel runs-on: ubuntu-latest - container: registry.fedoraproject.org/fedora:38 steps: - - name: Checkout code - uses: actions/checkout@v3 + - name: Maximize disk space + uses: easimon/maximize-build-space@master + with: + root-reserve-mb: 5120 + remove-dotnet: true + remove-android: true + remove-docker-images: true - - name: Install build dependencies - run: | - dnf distro-sync -y - dnf install -y git make gcc flex bison bzip2 rpm-build - dnf install -y rpmdevtools rpm-sign 'dnf-command(builddep)' + - name: Checkout code + uses: actions/checkout@v3 - # Install build dependencies - dnf builddep -y kernel + - name: Initialize containers + run: | + bash ./.github/scripts/container/create.sh \ + registry.fedoraproject.org/fedora:${{ env.FEDORA }} - # Install additional build dependencies - dnf install -y sbsigntools + - name: Install build dependencies + run: | + bash ./.github/scripts/container/exec.sh \ + -- \ + bash ./.github/scripts/package/fedora.sh setup-builddeps - - name: Setup secureboot certificate - env: - SB_KEY: ${{ secrets.SURFACE_SB_KEY }} - run: | - # Install the surface secureboot certificate - echo "$SB_KEY" | base64 -d > pkg/fedora/kernel-surface/secureboot/MOK.key - cp pkg/keys/surface.crt pkg/fedora/kernel-surface/secureboot/MOK.crt + - name: Setup secureboot certificate + env: + SB_KEY: ${{ secrets.SURFACE_SB_KEY }} + run: | + bash ./.github/scripts/container/exec.sh \ + -e SB_KEY \ + -- \ + bash ./.github/scripts/package/fedora.sh setup-secureboot - - name: Build packages - run: | - cd pkg/fedora/kernel-surface + - name: Build packages + run: | + bash ./.github/scripts/container/exec.sh \ + -- \ + bash ./.github/scripts/package/fedora.sh build-packages - # setup git - git config --global user.email "surfacebot@users.noreply.github.com" - git config --global user.name "surfacebot" + - name: Sign packages + env: + GPG_KEY: ${{ secrets.LINUX_SURFACE_GPG_KEY }} + run: | + bash ./.github/scripts/container/exec.sh \ + -e GPG_KEY \ + -e GPG_KEY_ID \ + -- \ + bash ./.github/scripts/package/fedora.sh sign-packages - # Build source RPM packages - python3 build-linux-surface.py --mode srpm --ark-dir kernel-ark --outdir srpm - - # Remove the kernel-ark tree to get as much free disk space as possible - rm -rf kernel-ark - - # Build binary RPM packages - rpmbuild -rb --define "_rpmdir $PWD/out" srpm/*.src.rpm - - - name: Sign packages - env: - GPG_KEY: ${{ secrets.LINUX_SURFACE_GPG_KEY }} - run: | - cd pkg/fedora/kernel-surface/out/x86_64 - - # import GPG key - echo "$GPG_KEY" | base64 -d | gpg --import --no-tty --batch --yes - - # sign packages - rpm --resign *.rpm --define "_gpg_name $GPG_KEY_ID" - - - name: Upload artifacts - uses: actions/upload-artifact@v3 - with: - name: fedora-38-latest - path: pkg/fedora/kernel-surface/out/x86_64 + - name: Upload artifacts + uses: actions/upload-artifact@v3 + with: + name: fedora-${{ env.FEDORA }}-latest + path: pkg/fedora/kernel-surface/out/x86_64 release: name: Publish release needs: [build] runs-on: ubuntu-latest steps: - - name: Download artifacts - uses: actions/download-artifact@v3 - with: - name: fedora-38-latest - path: fedora-38-latest + - name: Download artifacts + uses: actions/download-artifact@v3 + with: + name: fedora-${{ env.FEDORA }}-latest + path: fedora-${{ env.FEDORA }}-latest - - name: Upload assets - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.LINUX_SURFACE_BOT_TOKEN }} - file: ./*-latest/* - tag: ${{ github.ref }} - overwrite: true - file_glob: true + - name: Upload assets + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.LINUX_SURFACE_BOT_TOKEN }} + file: ./*-latest/* + tag: ${{ github.ref }} + overwrite: true + file_glob: true repo: name: Update package repository needs: [release] runs-on: ubuntu-latest - container: registry.fedoraproject.org/fedora:38 steps: - - name: Install dependencies - run: | - dnf install -y git findutils + - name: Checkout repository + uses: actions/checkout@v3 - - name: Download artifacts - uses: actions/download-artifact@v3 - with: - name: fedora-38-latest - path: fedora-38-latest + - name: Download artifacts + uses: actions/download-artifact@v3 + with: + name: fedora-${{ env.FEDORA }}-latest + path: fedora-${{ env.FEDORA }}-latest - - name: Update repository - env: - SURFACEBOT_TOKEN: ${{ secrets.LINUX_SURFACE_BOT_TOKEN }} - BRANCH_STAGING: u/staging - GIT_REF: ${{ github.ref }} - run: | - repo="https://surfacebot:${SURFACEBOT_TOKEN}@github.com/linux-surface/repo.git" + - name: Initialize containers + run: | + bash ./.github/scripts/container/create.sh \ + registry.fedoraproject.org/fedora:${{ env.FEDORA }} - # clone package repository - git clone -b "${BRANCH_STAGING}" "${repo}" repo - - # copy packages - cp fedora-38-latest/* repo/fedora/f38 - cd repo/fedora/f38 - - # parse git tag from ref - GIT_TAG=$(echo $GIT_REF | sed 's|^refs/tags/||g') - - # convert packages into references - for pkg in $(find . -name '*.rpm'); do - echo "linux-surface:$GIT_TAG/$(basename $pkg)" > $pkg.blob - rm $pkg - done - - # set git identity - git config --global user.email "surfacebot@users.noreply.github.com" - git config --global user.name "surfacebot" - - # commit and push - update_branch="${BRANCH_STAGING}-$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)" - git checkout -b "${update_branch}" - git add . - git commit -m "Update Fedora 38 kernel" - git push --set-upstream origin "${update_branch}" + - name: Update repository + env: + SURFACEBOT_TOKEN: ${{ secrets.LINUX_SURFACE_BOT_TOKEN }} + GIT_REF: ${{ github.ref }} + BRANCH_STAGING: u/staging + run: | + bash ./.github/scripts/container/exec.sh \ + -e SURFACEBOT_TOKEN \ + -e GIT_REF \ + -e BRANCH_STAGING \ + -e GITHUB_REPOSITORY \ + -- \ + bash ./.github/scripts/repository/fedora.sh ${{ env.FEDORA }} \ No newline at end of file