Skip to content

Build and test FreeIPA containers #868

Build and test FreeIPA containers

Build and test FreeIPA containers #868

Workflow file for this run

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, fedora-38, centos-9-stream, centos-8-stream, rocky-9, rocky-8, almalinux-9, almalinux-8, centos-7 ]
docker: [ docker ]
include:
- os: rhel-9
docker: podman
- os: rhel-8
docker: podman
- os: rhel-7
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: centos-8-stream
- os: centos-8-stream
readonly: --read-only
- os: centos-8-stream
readonly: --read-only
ca: --external-ca
os: [ fedora-39, fedora-38, 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, centos-8-stream, 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-8-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-docker-20-04-cgroups-v1:
name: Run with docker on Ubuntu 20.04 with forced cgroups v1
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
- os: centos-8-stream
readonly: --read-only
- os: centos-7
protected_regular: unset
- os: rhel-7
protected_regular: unset
env:
CGROUP_UNIFIED_IGNORE: 1
timeout-minutes: 30
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: 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, centos-8-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, centos-8-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: centos-8-stream
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, centos-8-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, fedora-38, centos-9-stream, centos-8-stream, rocky-9, rocky-8, almalinux-9, almalinux-8, centos-7 ]
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