Skip to content

Commit

Permalink
ci: build and publish ARM64 images (experimental)
Browse files Browse the repository at this point in the history
This commit modifies the CI code (`ci.yaml`) to use the new docker build
infrastructure (`Makefile`) in `docker/` to build linux/arm64 images in addition
to linux/amd64.

Several considerations:

* The original step 3 is split in:
  - 3.1: where the basic (local) build for the host arch and the docker-compose
         smoke test is run. This is to mimic what a user would do locally.
  - 3.2: where the multi-platform images are built, smoke tested (host arch only
         and published.
* Due to the limitations of `docker buildx` (see previous commit and
  `docker/README.md`), a temporary build docker registry is spawned as part of
  step 3.2.
* docker image publishing is moved to step of 3.2 (`docker-build-test-publish`),
  which allows PRs to execute most of the sections of 3.1/3.2 and skip the
  publishing step only.

ARM64 generation is slow. Building and - especially - pushing multi-platform
images is much easier than _trying_ to do that across jobs. There isn't much
to optimize on the ARM side of things (just a byproduct of cross-compiling).
However, stage 3.2 could start in parallel with stage 1/2, but gate publishing
to dockerhub until stage 1,2 and 3.1 have successfully completed (e.g. using
artifacts to pass status). This is out of scope of this commit.

Signed-off-by: Marc Sune <[email protected]>
  • Loading branch information
msune committed Jan 2, 2025
1 parent a7edfea commit 641ef03
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 75 deletions.
130 changes: 64 additions & 66 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,40 +107,21 @@ jobs:
docker exec -i $CONTAINER_ID ./ci/script.sh
docker stop $CONTAINER_ID
### Step 3: official docker image generation
pmacct-docker:
### Step 3.1: test that local single-platform builds work fine
docker-build-test-local:
runs-on: ubuntu-22.04
steps:
- name: Checkout pmacct
uses: actions/checkout@v4
uses: actions/checkout@v1 #Don't use v2 messes everything
with:
path: pmacct
fetch-depth: 0
fetch-tags: 1

- name: Check DAEMONS env. variable...
- name: Build single-platform
run: |
#Sanity, avoid regression #816
N_DAEMONS="$(echo $DAEMONS | wc --words)"
if [[ "${N_DAEMONS}" != "7" ]]; then
echo "ERROR: invalid number of DAEMONS: ${N_DAEMONS}"
exit 1
fi
- name: Build containers
uses: ./pmacct/.github/actions/build_containers/
with:
daemons: ${{env.DAEMONS}}

- name: Docker save images
run: |
echo "Saving images as artifacts..."
mkdir -p /tmp/docker/
docker save -o /tmp/docker/pmacct_docker_images.tar base:_build $(for DAEMON in ${DAEMONS};do echo "${DAEMON}:_build "; done)
cd docker && V=1 make
- name: Docker (compose) smoke test
run: |
cd pmacct
echo "Running smoke test using docker compose..."
TAG=_build docker compose -f ci/smoke-test/docker-compose.yml up -d
sleep 10
Expand All @@ -151,51 +132,31 @@ jobs:
echo "Stopping containers..."
TAG=_build docker compose -f ci/smoke-test/docker-compose.yml down
- name: Export pmacct docker images as an artifact
uses: actions/upload-artifact@v4
with:
name: pmacct_docker_images
retention-days: 1
path: /tmp/docker

### Step 4: Upload images to dockerhub (bleeding-edge, latest and releases)
publish-dockerhub:
needs: [pmacct-docker, build-and-test]
### Step 3.2: Build test and publish (bleeding-edge, latest and releases)
docker-multiplatform-build-test-publish:
runs-on: ubuntu-22.04
if: github.event_name != 'pull_request' && vars.SKIP_DOCKERHUB_PUBLISH != 'true'
needs: [build-and-test, docker-build-test-local]
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
PLATFORMS: linux/amd64,linux/arm64
steps:
- uses: actions/download-artifact@v4
with:
name: pmacct_docker_images
path: /tmp/docker

- name: Import pmacct docker images in the local registry
run: |
docker load -i /tmp/docker/pmacct_docker_images.tar
- name: Checkout pmacct
uses: actions/checkout@v1 #Don't use v2 messes everything
with:
path: pmacct

- name: Build and upload containers
- name: Deduce PMACCT version and tags
run: |
echo "Fix mess with tags in actions/checkout..."
git fetch -f && git fetch -f --tags
echo "Deducing PMACCT_VERSION..."
PMACCT_VERSION=$(git describe --abbrev=0 --match="v*")
echo "PMACCT_VERSION=$PMACCT_VERSION"
echo "Uploading to dockerhub ...";
echo ${DOCKER_PASSWORD} | docker login -u ${DOCKER_USERNAME} --password-stdin;
#Always push bleeding-edge when pushed to master
GIT_IS_BLEEDING_EDGE=$( (git branch --all --contains HEAD | grep master ) || echo "")
echo "GIT_IS_BLEEDING_EDGE=$GIT_IS_BLEEDING_EDGE"
if [ "$GIT_IS_BLEEDING_EDGE" != "" ]; then
echo "Tagging and uploading 'bleeding-edge'..."
TAGS="$TAGS bleeding-edge"
else
echo "NOT uploading 'bleeding-edge'... Not HEAD of master"
fi
Expand All @@ -205,32 +166,69 @@ jobs:
if [ "$GIT_RELEASE_TAG" != "" ]; then
echo "GIT_RELEASE_TAG=$GIT_RELEASE_TAG"
echo "Tagging and uploading release '$GIT_RELEASE_TAG'..."
TAGS="$TAGS $GIT_RELEASE_TAG"
#Latest tag
GIT_LAST_TAG=$(git tag --sort=v:refname | tail -n 1);
echo "GIT_LAST_TAG=$GIT_LAST_TAG"
if [ "$GIT_RELEASE_TAG" == "$GIT_LAST_TAG" ]; then
echo "Tagging and uploading 'latest'..."
TAGS="$TAGS latest"
else
echo "NOT uploading 'latest'..."
fi
else
echo "NOT uploading '$GIT_RELEASE_TAG' nor 'latest'. Not a release!"
fi
#Let's do it!
EXT_DAEMONS="base ${DAEMONS}"
for DAEMON in ${EXT_DAEMONS}; do
if [ "$GIT_IS_BLEEDING_EDGE" != "" ]; then
docker tag ${DAEMON}:_build ${DOCKER_USERNAME}/${DAEMON}:bleeding-edge;
docker push ${DOCKER_USERNAME}/${DAEMON}:bleeding-edge;
fi
if [ "$GIT_RELEASE_TAG" != "" ]; then
docker tag ${DAEMON}:_build ${DOCKER_USERNAME}/${DAEMON}:${PMACCT_VERSION};
docker push ${DOCKER_USERNAME}/${DAEMON}:${PMACCT_VERSION};
if [ "$GIT_RELEASE_TAG" == "$GIT_LAST_TAG" ]; then
docker tag ${DAEMON}:_build ${DOCKER_USERNAME}/${DAEMON}:latest;
docker push ${DOCKER_USERNAME}/${DAEMON}:latest;
fi
fi
done
#Summarize deduced tags
echo "Deduced tags: $TAGS"
echo "TAGS=$TAGS" >> $GITHUB_ENV
- name: Get Runner's IP Address
run: |
RUNNER_IP=$(hostname -I | awk '{print $1}')
echo "RUNNER_IP=$RUNNER_IP" >> $GITHUB_ENV
echo "Deduced RUNNER_IP: $RUNNER_IP"
- name: Spawn docker registry
run: |
echo "Instruct dockerd to trust $RUNNER_IP:5000 as an insecure registry..."
sudo mkdir -p /etc/docker
echo "{
\"insecure-registries\": [\"http://$RUNNER_IP:5000\"]
}" | sudo tee /etc/docker/daemon.json > /dev/null
sudo systemctl restart docker
echo "Starting temporary docker registry..."
docker run -d -p 5000:5000 --name registry registry:2
- name: Build for platforms
run: |
echo "Building platforms: ${{ env.PLATFORMS }}..."
echo "Got tags from previous step: $TAGS"
cd docker && BUILD_REGISTRY=$RUNNER_IP:5000 PLATFORMS="${{env.PLATFORMS}}" V=1 make
- name: Docker (compose) smoke test
run: |
echo "Running smoke test using docker compose..."
export DOCKER_OPTS="--insecure-registry $RUNNER_IP:5000"
TAG=_build REPO=$RUNNER_IP:5000/ docker compose -f ci/smoke-test/docker-compose.yml up -d
sleep 10
echo "Check that all containers are up and running, without restarts ..."
if [[ "$(docker inspect `docker ps -aq` | grep RestartCount | grep -v '\"RestartCount\": 0')" != "" ]]; then
echo "Some containers restarted!" && docker inspect `docker ps -aq` && /bin/false
fi
echo "Stopping containers..."
TAG=_build docker compose -f ci/smoke-test/docker-compose.yml down
- name: Tag and push to dockerhub
if: ${{ github.event_name != 'pull_request' && vars.SKIP_DOCKERHUB_PUBLISH != 'true' && env.TAGS != '' }}
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
run: |
echo "Logging in...";
echo ${DOCKER_PASSWORD} | docker login -u ${DOCKER_USERNAME} --password-stdin
echo "Publishing platforms(archs): ${{ env.PLATFORMS }}..."
echo "Got tags from previous step: $TAGS"
cd docker && BUILD_REGISTRY=$RUNNER_IP:5000 PUSH=${{secrets.DOCKER_USERNAME}} TAGS="${TAGS}" PLATFORMS="${{env.PLATFORMS}}" V=1 make
16 changes: 7 additions & 9 deletions ci/smoke-test/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,44 +1,42 @@
version: "3"

services:
nfacctd:
image: nfacctd:${TAG}
image: ${REPO:-}nfacctd:${TAG}
volumes:
- ./etc/pmacct:/etc/pmacct
restart: on-failure

pmacctd:
image: pmacctd:${TAG}
image: ${REPO:-}pmacctd:${TAG}
volumes:
- ./etc/pmacct:/etc/pmacct
restart: on-failure

pmbgpd:
image: pmbgpd:${TAG}
image: ${REPO:-}pmbgpd:${TAG}
volumes:
- ./etc/pmacct:/etc/pmacct
restart: on-failure

pmbmpd:
image: pmbmpd:${TAG}
image: ${REPO:-}pmbmpd:${TAG}
volumes:
- ./etc/pmacct:/etc/pmacct
restart: on-failure

pmtelemetryd:
image: pmtelemetryd:${TAG}
image: ${REPO:-}pmtelemetryd:${TAG}
volumes:
- ./etc/pmacct:/etc/pmacct
restart: on-failure

sfacctd:
image: sfacctd:${TAG}
image: ${REPO:-}sfacctd:${TAG}
volumes:
- ./etc/pmacct:/etc/pmacct
restart: on-failure

uacctd:
image: uacctd:${TAG}
image: ${REPO:-}uacctd:${TAG}
volumes:
- ./etc/pmacct:/etc/pmacct
restart: on-failure
Expand Down

0 comments on commit 641ef03

Please sign in to comment.