diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index aaf7276..64dbbcb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,15 +12,20 @@ concurrency: jobs: vmtest: - runs-on: ubuntu-latest - name: Kernel ${{ matrix.kernel }} + selftests + runs-on: ${{ matrix.runs_on }} + name: Kernel ${{ matrix.kernel }} on ${{ matrix.runs_on }} + selftests strategy: fail-fast: false matrix: include: - kernel: 'LATEST' + runs_on: ubuntu-latest + - kernel: 'LATEST' + runs_on: z15 - kernel: '5.5.0' + runs_on: ubuntu-latest - kernel: '4.9.0' + runs_on: ubuntu-latest steps: - uses: actions/checkout@v2 name: Checkout diff --git a/travis-ci/vmtest/run.sh b/travis-ci/vmtest/run.sh index c6021f2..098b88a 100755 --- a/travis-ci/vmtest/run.sh +++ b/travis-ci/vmtest/run.sh @@ -494,27 +494,31 @@ guestfish --remote exit echo "Starting VM with $(nproc) CPUs..." -if kvm-ok ; then - accel="-cpu kvm64 -enable-kvm" -else - accel="-cpu qemu64 -machine accel=tcg" -fi case "$ARCH" in s390x) qemu="qemu-system-s390x" console="ttyS1" smp=2 + kvm_accel="-enable-kvm" + tcg_accel="-machine accel=tcg" ;; x86_64) qemu="qemu-system-x86_64" console="ttyS0,115200" smp=$(nproc) + kvm_accel="-cpu kvm64 -enable-kvm" + tcg_accel="-cpu qemu64 -machine accel=tcg" ;; *) echo "Unsupported architecture" exit 1 ;; esac +if kvm-ok ; then + accel=$kvm_accel +else + accel=$tcg_accel +fi "$qemu" -nodefaults -display none -serial mon:stdio \ ${accel} -smp "$smp" -m 4G \ -drive file="$IMG",format=raw,index=1,media=disk,if=virtio,cache=none \ diff --git a/travis-ci/vmtest/s390x-self-hosted-builder/README.md b/travis-ci/vmtest/s390x-self-hosted-builder/README.md new file mode 100644 index 0000000..5f173bc --- /dev/null +++ b/travis-ci/vmtest/s390x-self-hosted-builder/README.md @@ -0,0 +1,72 @@ +# IBM Z self-hosted builder + +libbpf CI uses an IBM-provided z15 self-hosted builder. There are no IBM Z +builds of GitHub Actions runner, and stable qemu-user has problems with .NET +apps, so the builder runs the x86_64 runner version with qemu-user built from +the master branch. + +## Configuring the builder. + +### Install prerequisites. + +``` +$ sudo dnf install docker +``` + +### Add services. + +``` +$ sudo cp *.service /etc/systemd/system/ +$ sudo systemctl daemon-reload +``` + +### Create a config file. + +``` +$ sudo tee /etc/actions-runner-libbpf +repo=/ +access_token= +``` + +Access token should have the repo scope, consult +https://docs.github.com/en/rest/reference/actions#create-a-registration-token-for-a-repository +for details. + +### Autostart the x86_64 emulation support. + +``` +$ sudo systemctl enable --now qemu-user-static +``` + +### Autostart the runner. + +``` +$ sudo systemctl enable --now actions-runner-libbpf +``` + +## Rebuilding the image + +In order to update the `iiilinuxibmcom/actions-runner-libbpf` image, e.g. to +get the latest OS security fixes, use the following commands: + +``` +$ sudo docker build \ + --pull \ + -f actions-runner-libbpf.Dockerfile \ + -t iiilinuxibmcom/actions-runner-libbpf +$ sudo systemctl restart actions-runner-libbpf +``` + +## Removing persistent data + +The `actions-runner-libbpf` service stores various temporary data, such as +runner registration information, work directories and logs, in the +`actions-runner-libbpf` volume. In order to remove it and start from scratch, +e.g. when switching the runner to a different repository, use the following +commands: + +``` +$ sudo systemctl stop actions-runner-libbpf +$ sudo docker rm -f actions-runner-libbpf +$ sudo docker volume rm actions-runner-libbpf +``` diff --git a/travis-ci/vmtest/s390x-self-hosted-builder/actions-runner-libbpf.Dockerfile b/travis-ci/vmtest/s390x-self-hosted-builder/actions-runner-libbpf.Dockerfile new file mode 100644 index 0000000..1145ec5 --- /dev/null +++ b/travis-ci/vmtest/s390x-self-hosted-builder/actions-runner-libbpf.Dockerfile @@ -0,0 +1,48 @@ +# Self-Hosted IBM Z Github Actions Runner. + +# Temporary image: amd64 dependencies. +FROM amd64/ubuntu:20.04 as ld-prefix +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get -y install ca-certificates libicu66 libssl1.1 + +# Main image. +FROM s390x/ubuntu:20.04 + +# Packages for libbpf testing that are not installed by .github/actions/setup. +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get -y install \ + bc \ + bison \ + cmake \ + cpu-checker \ + curl \ + flex \ + git \ + jq \ + linux-image-generic \ + qemu-system-s390x \ + rsync \ + software-properties-common \ + sudo \ + tree + +# amd64 dependencies. +COPY --from=ld-prefix / /usr/x86_64-linux-gnu/ +RUN ln -fs ../lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 /usr/x86_64-linux-gnu/lib64/ +RUN ln -fs /etc/resolv.conf /usr/x86_64-linux-gnu/etc/ +ENV QEMU_LD_PREFIX=/usr/x86_64-linux-gnu + +# amd64 Github Actions Runner. +RUN useradd -m actions-runner +RUN echo "actions-runner ALL=(ALL) NOPASSWD: ALL" >>/etc/sudoers +RUN echo "Defaults env_keep += \"DEBIAN_FRONTEND\"" >>/etc/sudoers +USER actions-runner +ENV USER=actions-runner +WORKDIR /home/actions-runner +RUN curl -L https://github.com/actions/runner/releases/download/v2.283.2/actions-runner-linux-x64-2.283.2.tar.gz | tar -xz +VOLUME /home/actions-runner + +# Scripts. +COPY fs/ / +ENTRYPOINT ["/usr/bin/entrypoint"] +CMD ["/usr/bin/actions-runner"] diff --git a/travis-ci/vmtest/s390x-self-hosted-builder/actions-runner-libbpf.service b/travis-ci/vmtest/s390x-self-hosted-builder/actions-runner-libbpf.service new file mode 100644 index 0000000..88e0237 --- /dev/null +++ b/travis-ci/vmtest/s390x-self-hosted-builder/actions-runner-libbpf.service @@ -0,0 +1,24 @@ +[Unit] +Description=Self-Hosted IBM Z Github Actions Runner +Wants=qemu-user-static +After=qemu-user-static +StartLimitIntervalSec=0 + +[Service] +Type=simple +Restart=always +ExecStart=/usr/bin/docker run \ + --device=/dev/kvm \ + --env-file=/etc/actions-runner-libbpf \ + --init \ + --interactive \ + --name=actions-runner-libbpf \ + --rm \ + --volume=actions-runner-libbpf:/home/actions-runner \ + iiilinuxibmcom/actions-runner-libbpf +ExecStop=/bin/sh -c "docker exec actions-runner-libbpf kill -INT -- -1" +ExecStop=/bin/sh -c "docker wait actions-runner-libbpf" +ExecStop=/bin/sh -c "docker rm actions-runner-libbpf" + +[Install] +WantedBy=multi-user.target diff --git a/travis-ci/vmtest/s390x-self-hosted-builder/fs/usr/bin/actions-runner b/travis-ci/vmtest/s390x-self-hosted-builder/fs/usr/bin/actions-runner new file mode 100755 index 0000000..c9d8227 --- /dev/null +++ b/travis-ci/vmtest/s390x-self-hosted-builder/fs/usr/bin/actions-runner @@ -0,0 +1,40 @@ +#!/bin/bash + +# +# Ephemeral runner startup script. +# +# Expects the following environment variables: +# +# - repo=/ +# - access_token= +# + +set -e -u + +# Check the cached registration token. +token_file=registration-token.json +set +e +expires_at=$(jq --raw-output .expires_at "$token_file" 2>/dev/null) +status=$? +set -e +if [[ $status -ne 0 || $(date +%s) -ge $(date -d "$expires_at" +%s) ]]; then + # Refresh the cached registration token. + curl \ + -X POST \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Authorization: token $access_token" \ + "https://api.github.com/repos/$repo/actions/runners/registration-token" \ + -o "$token_file" +fi + +# (Re-)register the runner. +registration_token=$(jq --raw-output .token "$token_file") +./config.sh remove --token "$registration_token" || true +./config.sh \ + --url "https://github.com/$repo" \ + --token "$registration_token" \ + --labels z15 \ + --ephemeral + +# Run one job. +./run.sh diff --git a/travis-ci/vmtest/s390x-self-hosted-builder/fs/usr/bin/entrypoint b/travis-ci/vmtest/s390x-self-hosted-builder/fs/usr/bin/entrypoint new file mode 100755 index 0000000..03cb61c --- /dev/null +++ b/travis-ci/vmtest/s390x-self-hosted-builder/fs/usr/bin/entrypoint @@ -0,0 +1,35 @@ +#!/bin/bash + +# +# Container entrypoint that waits for all spawned processes. +# + +set -e -u + +# /dev/kvm has host permissions, fix it. +if [ -e /dev/kvm ]; then + sudo chown root:kvm /dev/kvm +fi + +# Create a FIFO and start reading from its read end. +tempdir=$(mktemp -d "/tmp/done.XXXXXXXXXX") +trap 'rm -r "$tempdir"' EXIT +done="$tempdir/pipe" +mkfifo "$done" +cat "$done" & waiter=$! + +# Start the workload. Its descendants will inherit the FIFO's write end. +status=0 +if [ "$#" -eq 0 ]; then + bash 9>"$done" || status=$? +else + "$@" 9>"$done" || status=$? +fi + +# When the workload and all of its descendants exit, the FIFO's write end will +# be closed and `cat "$done"` will exit. Wait until it happens. This is needed +# in order to handle SelfUpdater, which the workload may start in background +# before exiting. +wait "$waiter" + +exit "$status" diff --git a/travis-ci/vmtest/s390x-self-hosted-builder/qemu-user-static.service b/travis-ci/vmtest/s390x-self-hosted-builder/qemu-user-static.service new file mode 100644 index 0000000..301f3ed --- /dev/null +++ b/travis-ci/vmtest/s390x-self-hosted-builder/qemu-user-static.service @@ -0,0 +1,11 @@ +[Unit] +Description=Support for transparent execution of non-native binaries with QEMU user emulation + +[Service] +Type=oneshot +# The source code for iiilinuxibmcom/qemu-user-static is at https://github.com/iii-i/qemu-user-static/tree/v6.1.0-1 +# TODO: replace it with multiarch/qemu-user-static once version >6.1 is available +ExecStart=/usr/bin/docker run --rm --interactive --privileged iiilinuxibmcom/qemu-user-static --reset -p yes + +[Install] +WantedBy=multi-user.target