Build and test FreeIPA containers #927
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build and test FreeIPA containers | |
on: | |
push: | |
pull_request: | |
workflow_dispatch: | |
schedule: | |
- cron: '15 4 * * 1,3,5' | |
jobs: | |
build: | |
name: Build image | |
runs-on: ubuntu-22.04 | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [ fedora-rawhide, fedora-40, fedora-39, centos-9-stream, rocky-9, rocky-8, almalinux-9, almalinux-8 ] | |
docker: [ docker ] | |
include: | |
- os: rhel-9 | |
docker: podman | |
- os: rhel-8 | |
docker: podman | |
timeout-minutes: 15 | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Install podman 4.* | |
uses: ./.github/actions/install-podman-4 | |
if: matrix.docker == 'podman' | |
- name: Separate git work tree with just the files needed for build | |
run: git worktree add --no-checkout ../minimize-for-build | |
- name: Populate with the Dockerfile | |
run: cd ../minimize-for-build && git checkout HEAD Dockerfile.${{ matrix.os }} | |
- name: Populate with files referenced from the Dockerfile | |
run: cd ../minimize-for-build && awk '/^(ADD|COPY)/ { for (i = 2; i < NF; i++) print $i }' Dockerfile.${{ matrix.os }} | while read f ; do git checkout HEAD $f ; done | |
- name: For RHEL builds, use entitlements | |
if: ${{ startsWith(matrix.os, 'rhel-') }} | |
uses: ./.github/actions/podman-entitlement | |
with: | |
org: ${{ secrets.REDHAT_ORG }} | |
activationkey: ${{ secrets.REDHAT_ACTIVATIONKEY }} | |
- name: Ensure docker images sees the named parent image | |
run: awk '$1 == "FROM" { print $2 ; exit }' ../minimize-for-build/Dockerfile.${{ matrix.os }} | xargs ${{ matrix.docker }} pull | |
- name: Build image | |
run: ${{ matrix.docker }} build -t localhost/freeipa-server:${{ matrix.os }} -f Dockerfile.${{ matrix.os }} ../minimize-for-build | |
- name: Label the built image | |
run: docker="${{ matrix.docker }}" ./ci/label-image.sh Dockerfile.${{ matrix.os }} localhost/freeipa-server:${{ matrix.os }} $( cd ../minimize-for-build && git write-tree ) "${{ github.server_url }}/${{ github.repository }}" "actions/runs/${{ github.run_id }}" | |
- name: File issue if building image failed | |
if: ${{ failure() && github.event_name == 'schedule' }} | |
run: | | |
curl -s '${{ github.api_url }}/repos/${{ github.repository }}/issues?labels=image-build-fail' | jq -r '.[0].state' | grep open \ | |
|| curl -s -X POST \ | |
--url ${{ github.api_url }}/repos/${{ github.repository }}/issues \ | |
-H 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \ | |
-H 'Accept: application/vnd.github.v3+json' \ | |
-d '{ | |
"title": "Image build for ${{ matrix.os }} failed on '$( date -I )'", | |
"body": "This issue was automatically created by GitHub Action\n\n${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}.\n", | |
"labels": ["image-build-fail" ] | |
}' | |
- name: Check resulting labels | |
run: | | |
skopeo inspect docker-daemon:localhost/freeipa-server:${{ matrix.os }} | jq '.Labels' | |
diff -u <( skopeo inspect docker://quay.io/freeipa/freeipa-server:${{ matrix.os }} | jq '.Labels' ) <( skopeo inspect docker-daemon:localhost/freeipa-server:${{ matrix.os }} | jq '.Labels' ) || true | |
if: matrix.docker != 'podman' | |
- name: Check resulting labels | |
run: | | |
skopeo inspect containers-storage:localhost/freeipa-server:${{ matrix.os }} | jq '.Labels' | |
diff -u <( skopeo inspect docker://quay.io/freeipa/freeipa-server:${{ matrix.os }} | jq '.Labels' ) <( skopeo inspect containers-storage:localhost/freeipa-server:${{ matrix.os }} | jq '.Labels' ) || true | |
if: matrix.docker == 'podman' | |
- name: Create directory for artifacts | |
run: mkdir freeipa-server-${{ matrix.os }} | |
- name: Save image | |
run: ${{ matrix.docker }} save localhost/freeipa-server:${{ matrix.os }} | gzip > freeipa-server-${{ matrix.os }}/freeipa-server-${{ matrix.os }}.tar.gz | |
- name: For RHEL builds, encrypt the artifacts | |
uses: ./.github/actions/encrypt-file | |
if: ${{ startsWith(matrix.os, 'rhel-') }} | |
with: | |
file: freeipa-server-${{ matrix.os }}/freeipa-server-${{ matrix.os }}.tar.gz | |
secret: ${{ secrets.UPLOAD_SECRET }} | |
- uses: actions/upload-artifact@v4 | |
with: | |
name: freeipa-server-${{ matrix.os }} | |
path: freeipa-server-${{ matrix.os }} | |
retention-days: 1 | |
test-docker: | |
name: Run with docker | |
runs-on: ubuntu-22.04 | |
needs: [ build ] | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- os: fedora-40 | |
- os: fedora-40 | |
readonly: --read-only | |
- os: fedora-40 | |
readonly: --read-only | |
ca: --external-ca | |
- os: fedora-rawhide | |
- os: centos-9-stream | |
- os: centos-9-stream | |
readonly: --read-only | |
- os: centos-9-stream | |
readonly: --read-only | |
ca: --external-ca | |
os: [ fedora-39, rhel-9, rhel-8, almalinux-9 ] | |
timeout-minutes: 30 | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: ./.github/actions/docker-cgroups-ubuntu-22 | |
- uses: actions/download-artifact@v4 | |
with: | |
name: freeipa-server-${{ matrix.os }} | |
- name: Decrypt artifacts that were encrypted after build | |
uses: ./.github/actions/decrypt-file | |
if: ${{ startsWith(matrix.os, 'rhel-') }} | |
with: | |
file: freeipa-server-${{ matrix.os }}.tar.gz | |
secret: ${{ secrets.UPLOAD_SECRET }} | |
- name: Load image | |
run: gunzip < freeipa-server-${{ matrix.os }}.tar.gz | docker load | |
- name: Run master and replica | |
run: readonly=${{ matrix.readonly }} ca=${{ matrix.ca }} seccomp=${{ matrix.seccomp }} replica=${{ matrix.replica }} tests/run-master-and-replica.sh localhost/freeipa-server:${{ matrix.os }} | |
- name: Run partial tests | |
if: ${{ failure() }} | |
run: tests/run-partial-tests.sh Dockerfile.${{ matrix.os }} | |
test-rootless-docker: | |
name: Run with rootless docker | |
runs-on: ubuntu-22.04 | |
needs: [ build ] | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [ fedora-rawhide, fedora-40, rocky-9, almalinux-9 ] | |
readonly: [ --read-only ] | |
timeout-minutes: 30 | |
steps: | |
- uses: actions/checkout@v4 | |
- run: sudo systemctl disable --now docker.service docker.socket | |
- run: curl -fsSL https://get.docker.com/rootless | FORCE_ROOTLESS_INSTALL=1 sh | |
- uses: actions/download-artifact@v4 | |
with: | |
name: freeipa-server-${{ matrix.os }} | |
- name: Decrypt artifacts that were encrypted after build | |
uses: ./.github/actions/decrypt-file | |
if: ${{ startsWith(matrix.os, 'rhel-') }} | |
with: | |
file: freeipa-server-${{ matrix.os }}.tar.gz | |
secret: ${{ secrets.UPLOAD_SECRET }} | |
- name: Load image | |
run: gunzip < freeipa-server-${{ matrix.os }}.tar.gz | docker load | |
- name: Run master and replica | |
run: readonly=${{ matrix.readonly }} ca=${{ matrix.ca }} seccomp=${{ matrix.seccomp }} replica=${{ matrix.replica }} tests/run-master-and-replica.sh localhost/freeipa-server:${{ matrix.os }} | |
- name: Run partial tests | |
if: ${{ failure() }} | |
run: tests/run-partial-tests.sh Dockerfile.${{ matrix.os }} | |
test-docker-20-04: | |
name: Run with docker on Ubuntu 20.04 with hybrid cgroups | |
runs-on: ubuntu-20.04 | |
needs: [ build ] | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- os: fedora-40 | |
readonly: --read-only | |
- os: centos-9-stream | |
readonly: --read-only | |
timeout-minutes: 30 | |
steps: | |
- run: ls -la /sys/fs/cgroup/unified | |
- uses: actions/checkout@v4 | |
- uses: actions/download-artifact@v4 | |
with: | |
name: freeipa-server-${{ matrix.os }} | |
- name: Decrypt artifacts that were encrypted after build | |
uses: ./.github/actions/decrypt-file | |
if: ${{ startsWith(matrix.os, 'rhel-') }} | |
with: | |
file: freeipa-server-${{ matrix.os }}.tar.gz | |
secret: ${{ secrets.UPLOAD_SECRET }} | |
- name: Load image | |
run: gunzip < freeipa-server-${{ matrix.os }}.tar.gz | docker load | |
- name: Disable fs.protected_regular | |
if: ${{ matrix.protected_regular == 'unset' }} | |
run: sudo sysctl fs.protected_regular=0 | |
- name: Run master and replica | |
run: readonly=${{ matrix.readonly }} ca=${{ matrix.ca }} seccomp=${{ matrix.seccomp }} replica=${{ matrix.replica }} tests/run-master-and-replica.sh localhost/freeipa-server:${{ matrix.os }} | |
- name: Run partial tests | |
if: ${{ failure() }} | |
run: tests/run-partial-tests.sh Dockerfile.${{ matrix.os }} | |
test-podman: | |
name: Run with sudo podman 4 | |
runs-on: ubuntu-22.04 | |
needs: [ build ] | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [ fedora-40, centos-9-stream ] | |
timeout-minutes: 30 | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Install podman 4.* | |
uses: ./.github/actions/install-podman-4 | |
- uses: actions/download-artifact@v4 | |
with: | |
name: freeipa-server-${{ matrix.os }} | |
- name: Decrypt artifacts that were encrypted after build | |
uses: ./.github/actions/decrypt-file | |
if: ${{ startsWith(matrix.os, 'rhel-') }} | |
with: | |
file: freeipa-server-${{ matrix.os }}.tar.gz | |
secret: ${{ secrets.UPLOAD_SECRET }} | |
- name: Load image | |
run: gunzip < freeipa-server-${{ matrix.os }}.tar.gz | sudo podman load | |
- name: Run master and replica | |
run: docker='sudo podman' tests/run-master-and-replica.sh localhost/freeipa-server:${{ matrix.os }} | |
- name: Run partial tests | |
if: ${{ failure() }} | |
run: docker='sudo podman' tests/run-partial-tests.sh Dockerfile.${{ matrix.os }} | |
test-rootless-podman: | |
name: Run with rootless podman 4 | |
runs-on: ubuntu-22.04 | |
needs: [ build ] | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [ fedora-40, rhel-9, rhel-8, centos-9-stream, rocky-9, rocky-8, almalinux-8 ] | |
timeout-minutes: 30 | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Install podman 4.* | |
uses: ./.github/actions/install-podman-4 | |
- uses: actions/download-artifact@v4 | |
with: | |
name: freeipa-server-${{ matrix.os }} | |
- name: Decrypt artifacts that were encrypted after build | |
uses: ./.github/actions/decrypt-file | |
if: ${{ startsWith(matrix.os, 'rhel-') }} | |
with: | |
file: freeipa-server-${{ matrix.os }}.tar.gz | |
secret: ${{ secrets.UPLOAD_SECRET }} | |
- name: Load image | |
run: gunzip < freeipa-server-${{ matrix.os }}.tar.gz | podman load | |
- name: Run master | |
run: docker=podman tests/run-master-and-replica.sh localhost/freeipa-server:${{ matrix.os }} && podman pod ls -q | xargs podman pod rm -f | |
- name: Run partial tests | |
if: ${{ failure() }} | |
run: docker=podman tests/run-partial-tests.sh Dockerfile.${{ matrix.os }} | |
test-upgrade: | |
name: Upgrade from older version or build | |
runs-on: ubuntu-22.04 | |
needs: [ build ] | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- os: fedora-40 | |
data-from: fedora-39 | |
- os: fedora-40 | |
data-from: fedora-38 | |
- os: rhel-8 | |
data-from: centos-8 | |
- os: rocky-8 | |
data-from: centos-8 | |
- os: almalinux-8 | |
data-from: centos-8 | |
timeout-minutes: 20 | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: ./.github/actions/docker-cgroups-ubuntu-22 | |
- uses: actions/download-artifact@v4 | |
with: | |
name: freeipa-server-${{ matrix.os }} | |
- name: Decrypt artifacts that were encrypted after build | |
uses: ./.github/actions/decrypt-file | |
if: ${{ startsWith(matrix.os, 'rhel-') }} | |
with: | |
file: freeipa-server-${{ matrix.os }}.tar.gz | |
secret: ${{ secrets.UPLOAD_SECRET }} | |
- name: Load image | |
run: gunzip < freeipa-server-${{ matrix.os }}.tar.gz | docker load | |
- name: Populate volume with data | |
run: docker volume create loaded-data && docker create --name loaded-data -v loaded-data:/data:z quay.io/freeipa/freeipa-server:data-${{ matrix.data-from }} noop && mkdir /tmp/freeipa-data && docker run --security-opt label=disable --volumes-from loaded-data -v /tmp/freeipa-data:/data-out:z --rm docker.io/library/busybox sh -c 'cd /data && cp -a . /data-out' | |
- name: Run master and replica | |
run: VOLUME=/tmp/freeipa-data replica=none tests/run-master-and-replica.sh localhost/freeipa-server:${{ matrix.os }} | |
test-upgrade-podman: | |
name: Upgrade from older version with podman 4 | |
runs-on: ubuntu-22.04 | |
needs: [ build ] | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- os: fedora-40 | |
data-from: fedora-39 | |
timeout-minutes: 20 | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Install podman 4.* | |
uses: ./.github/actions/install-podman-4 | |
- uses: actions/download-artifact@v4 | |
with: | |
name: freeipa-server-${{ matrix.os }} | |
- name: Decrypt artifacts that were encrypted after build | |
uses: ./.github/actions/decrypt-file | |
if: ${{ startsWith(matrix.os, 'rhel-') }} | |
with: | |
file: freeipa-server-${{ matrix.os }}.tar.gz | |
secret: ${{ secrets.UPLOAD_SECRET }} | |
- name: Load image | |
run: gunzip < freeipa-server-${{ matrix.os }}.tar.gz | podman load | |
- name: Populate volume with data | |
run: podman volume create loaded-data && podman run --name loaded-data -v loaded-data:/data:z quay.io/freeipa/freeipa-server:data-${{ matrix.data-from }} noop || true | |
- name: Copy the content of the volume to directory | |
run: mkdir /tmp/freeipa-data && podman run --volumes-from loaded-data -v /tmp/freeipa-data:/data-out:z --rm docker.io/library/busybox sh -c 'cd /data && cp -a . /data-out' | |
- name: Run master and replica | |
run: docker=podman VOLUME=/tmp/freeipa-data replica=none tests/run-master-and-replica.sh localhost/freeipa-server:${{ matrix.os }} | |
test-upgrade-20-04: | |
name: Upgrade from older version or build on Ubuntu 20.04 | |
runs-on: ubuntu-20.04 | |
needs: [ build ] | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- os: fedora-40 | |
data-from: fedora-39 | |
timeout-minutes: 20 | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions/download-artifact@v4 | |
with: | |
name: freeipa-server-${{ matrix.os }} | |
- name: Decrypt artifacts that were encrypted after build | |
uses: ./.github/actions/decrypt-file | |
if: ${{ startsWith(matrix.os, 'rhel-') }} | |
with: | |
file: freeipa-server-${{ matrix.os }}.tar.gz | |
secret: ${{ secrets.UPLOAD_SECRET }} | |
- name: Load image | |
run: gunzip < freeipa-server-${{ matrix.os }}.tar.gz | docker load | |
- name: Populate volume with data | |
run: docker volume create loaded-data && docker create --name loaded-data -v loaded-data:/data:z quay.io/freeipa/freeipa-server:data-${{ matrix.data-from }} noop && mkdir /tmp/freeipa-data && docker run --security-opt label=disable --volumes-from loaded-data -v /tmp/freeipa-data:/data-out:z --rm docker.io/library/busybox sh -c 'cd /data && cp -a . /data-out' | |
- name: Run master and replica | |
run: VOLUME=/tmp/freeipa-data replica=none tests/run-master-and-replica.sh localhost/freeipa-server:${{ matrix.os }} | |
test-k3s: | |
name: Run with K3s with docker | |
runs-on: ubuntu-22.04 | |
needs: [ build ] | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [ fedora-rawhide, fedora-40, rhel-9, rhel-8, centos-9-stream ] | |
timeout-minutes: 30 | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: ./.github/actions/docker-cgroups-ubuntu-22 | |
- uses: actions/download-artifact@v4 | |
with: | |
name: freeipa-server-${{ matrix.os }} | |
- name: Decrypt artifacts that were encrypted after build | |
uses: ./.github/actions/decrypt-file | |
if: ${{ startsWith(matrix.os, 'rhel-') }} | |
with: | |
file: freeipa-server-${{ matrix.os }}.tar.gz | |
secret: ${{ secrets.UPLOAD_SECRET }} | |
- name: Download latest cri-dockerd | |
run: curl -s ${{ github.api_url }}/repos/Mirantis/cri-dockerd/releases/latest | jq -r '.assets[].browser_download_url' | grep jammy_amd64.deb | tee /dev/stderr | xargs curl -LO | |
- name: Install cri-dockerd | |
run: sudo apt install -y ./cri-dockerd_*.deb | |
- name: Unset network-plugin | |
run: | | |
sudo mkdir /etc/systemd/system/cri-docker.service.d | |
( echo '[Service]' ; echo 'ExecStart=' ; sed 's/ExecStart=.*/& --network-plugin=/;t;d' /lib/systemd/system/cri-docker.service ) | sudo tee /etc/systemd/system/cri-docker.service.d/network-plugin.conf | |
sudo systemctl daemon-reload | |
sudo systemctl restart cri-docker | |
- name: Load image | |
run: gunzip < freeipa-server-${{ matrix.os }}.tar.gz | docker load | |
- name: Run K3s and master in it | |
run: tests/run-master-in-k3s.sh localhost/freeipa-server:${{ matrix.os }} | |
push-after-success: | |
name: Push images to registries | |
runs-on: ubuntu-22.04 | |
needs: [ test-docker, test-rootless-docker, test-docker-20-04, test-podman, test-rootless-podman, test-upgrade, test-upgrade-20-04, test-k3s ] | |
if: github.event_name != 'pull_request' && github.repository == 'freeipa/freeipa-container' && github.ref == 'refs/heads/master' | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [ fedora-rawhide, fedora-40, fedora-39, centos-9-stream, rocky-9, rocky-8, almalinux-9, almalinux-8 ] | |
timeout-minutes: 30 | |
steps: | |
- uses: actions/download-artifact@v4 | |
with: | |
name: freeipa-server-${{ matrix.os }} | |
- name: Prepare authentication file | |
run: | | |
cat > auth.json << 'EOF' | |
${{ secrets.REGISTRY_CREDENTIALS_FILE }} | |
EOF | |
- name: Copy ${{ matrix.os }} to registries | |
run: | | |
set -e | |
f=docker-archive:freeipa-server-${{ matrix.os }}.tar.gz | |
while read r ; do | |
if cmp \ | |
<( skopeo inspect $r:${{ matrix.os }} \ | |
| jq -r '.Labels."org.opencontainers.image.base.digest", .Labels."org.opencontainers.image.version"' ) \ | |
<( skopeo inspect $f \ | |
| jq -r '.Labels."org.opencontainers.image.base.digest", .Labels."org.opencontainers.image.version"' ) ; then | |
echo Built freeipa-server:${{ matrix.os }} is the same as image at ${r#docker://}, not pushing | |
continue | |
fi | |
echo Copying freeipa-server:${{ matrix.os }} to ${r#docker://} | |
skopeo copy --authfile=auth.json $f $r:${{ matrix.os }} | |
VERSION=$( skopeo inspect --format='{{index .Labels "org.opencontainers.image.version"}}' $f | sed 's/-.*//' ) | |
test -n "$VERSION" | |
skopeo copy --authfile=auth.json $r:${{ matrix.os }} $r:${{ matrix.os }}-$VERSION | |
echo Tagged as ${{ matrix.os }}-$VERSION as well | |
done << 'EOF' | |
${{ secrets.REGISTRY_TARGET_LIST }} | |
EOF | |