Skip to content

Commit

Permalink
feat: add azure devops agent image (#1183)
Browse files Browse the repository at this point in the history
* feat: add azure devops agent image

* fix(review): fixes based on comments from coderabbit

* fix(review): remove docker login

---------

Co-authored-by: tjololo <1145298+tjololo@users.noreply.github.com>
  • Loading branch information
tjololo and tjololo authored Dec 17, 2024
1 parent c784336 commit 17e0429
Show file tree
Hide file tree
Showing 6 changed files with 243 additions and 1 deletion.
41 changes: 41 additions & 0 deletions .github/workflows/azdevops-agent-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Test build azure devops agent

on:
pull_request:
branches:
- main
paths:
- .github/workflows/azdevops-agent-pr.yml
- infrastructure/images/azure-devops-agent/**

permissions:
contents: read
packages: read

jobs:
build:
name: Test build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get version from tags
id: version
run: |
tag=${GITHUB_REF/refs\/tags\//}
echo "version=${tag%-demo}" >> "$GITHUB_OUTPUT"
- name: Get Git commit timestamps
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build
id: docker_build
uses: docker/build-push-action@v6
with:
context: ./infrastructure/images/azure-devops-agent
push: false
platforms: linux/amd64,linux/arm64
tags: ${{ github.repository }}/azure-devops-agent:test
env:
SOURCE_DATE_EPOCH: ${{ env.TIMESTAMP }}
44 changes: 44 additions & 0 deletions .github/workflows/azdevops-agent-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Release azure devops agent

on:
push:
tags:
- "azdevops-agent-*"

permissions:
contents: read
packages: write

jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get variables from tags
id: vars
run: |
tag=${GITHUB_REF/refs\/tags\/azdevops-agent-/}
echo "version=${tag%-demo}" >> "$GITHUB_OUTPUT"
echo "reponame=${GITHUB_REPOSITORY,,}" >> "${GITHUB_OUTPUT}"
- name: Get Git commit timestamps
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
id: docker_build
uses: docker/build-push-action@v6
with:
context: ./infrastructure/images/azure-devops-agent
push: true
platforms: linux/amd64,linux/arm64
tags: ghcr.io/${{ steps.vars.outputs.reponame }}/azure-devops-agent:v${{ steps.vars.outputs.version }}
env:
SOURCE_DATE_EPOCH: ${{ env.TIMESTAMP }}
2 changes: 1 addition & 1 deletion .github/workflows/gh-runner-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ jobs:
platforms: linux/amd64,linux/arm64
tags: ${{ github.repository }}/gh-runner:test
env:
SOURCE_DATE_EPOCH: ${{ env.TIMESTAMP }}
SOURCE_DATE_EPOCH: ${{ env.TIMESTAMP }}
26 changes: 26 additions & 0 deletions infrastructure/images/azure-devops-agent/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FROM ubuntu:22.04
RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y && \
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends \
apt-transport-https \
apt-utils \
ca-certificates \
curl \
git \
iputils-ping \
jq \
lsb-release \
software-properties-common && \
rm -rf /var/lib/apt/lists/*

RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash

# Can be 'linux-x64', 'linux-arm64', 'linux-arm', 'rhel.6-x64'.
ENV TARGETARCH=linux-x64

WORKDIR /azp

COPY scripts/start.sh .
RUN chmod +x start.sh

ENTRYPOINT [ "./start.sh" ]
26 changes: 26 additions & 0 deletions infrastructure/images/azure-devops-agent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Altinn Azure DevOps Agent Image
Default image used for Altinns self-hosted azure devops agents.

This image is base on the example code from [Azure-Samples/container-apps-ci-cd-runner-tutorial](https://github.com/Azure-Samples/container-apps-ci-cd-runner-tutorial)

The image is maintained by the platform team.

The image is meant to be as small and lightweight as possible so we keep the dependencies at a minimum to reduce the maintenance cost.

If any team needs a custom image they are free to roll their own or extend this, but they will be responsible for maintaining this image.

Example Dockerfile for an image that in addition to what is available in the base image installs netcat:

```Dockerfile
FROM ghcr.io/altinn/altinn-platform/azure-devops-agent:1.0.0

+# Switch to root to install additional packages
USER root

+# Install curl and jq while keeping the image size minimal
RUN apt-get update && apt-get install -y curl jq && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

+# Switch back to the runner user for security
USER runner
105 changes: 105 additions & 0 deletions infrastructure/images/azure-devops-agent/scripts/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#!/bin/bash
set -e

if [ -z "$AZP_URL" ]; then
echo 1>&2 "error: missing AZP_URL environment variable"
exit 1
fi

if [ -z "$AZP_TOKEN_FILE" ]; then
if [ -z "$AZP_TOKEN" ]; then
echo 1>&2 "error: missing AZP_TOKEN environment variable"
exit 1
fi

AZP_TOKEN_FILE=/azp/.token
echo -n "$AZP_TOKEN" > "$AZP_TOKEN_FILE"
fi

unset AZP_TOKEN

if [ -n "$AZP_WORK" ]; then
mkdir -p "$AZP_WORK"
fi

export AGENT_ALLOW_RUNASROOT="1"

cleanup() {
# If $AZP_PLACEHOLDER is set, skip cleanup
if [ -n "$AZP_PLACEHOLDER" ]; then
echo 'Running in placeholder mode, skipping cleanup'
return
fi
if [ -e config.sh ]; then
print_header "Cleanup. Removing Azure Pipelines agent..."

# If the agent has some running jobs, the configuration removal process will fail.
# So, give it some time to finish the job.
while true; do
./config.sh remove --unattended --auth PAT --token "$(cat "$AZP_TOKEN_FILE")" && break

echo "Retrying in 30 seconds..."
sleep 30
done
fi
}

print_header() {
lightcyan='\033[1;36m'
nocolor='\033[0m'
echo -e "${lightcyan}$1${nocolor}"
}

# Let the agent ignore the token env variables
export VSO_AGENT_IGNORE=AZP_TOKEN,AZP_TOKEN_FILE

print_header "1. Determining matching Azure Pipelines agent..."

AZP_AGENT_PACKAGES=$(curl -LsS \
-u "user:$(cat "$AZP_TOKEN_FILE")" \
-H 'Accept:application/json;' \
"$AZP_URL/_apis/distributedtask/packages/agent?platform=$TARGETARCH&top=1")

AZP_AGENT_PACKAGE_LATEST_URL=$(echo "$AZP_AGENT_PACKAGES" | jq -r '.value[0].downloadUrl')

if [ -z "$AZP_AGENT_PACKAGE_LATEST_URL" ] || [ "$AZP_AGENT_PACKAGE_LATEST_URL" == "null" ]; then
echo 1>&2 "error: could not determine a matching Azure Pipelines agent"
echo 1>&2 "check that account '$AZP_URL' is correct and the token is valid for that account"
exit 1
fi

print_header "2. Downloading and extracting Azure Pipelines agent..."
echo "Agent package URL: $AZP_AGENT_PACKAGE_LATEST_URL"
curl -LsS $AZP_AGENT_PACKAGE_LATEST_URL | tar -xz & wait $!

source ./env.sh

trap 'cleanup; exit 0' EXIT
trap 'cleanup; exit 130' INT
trap 'cleanup; exit 143' TERM

print_header "3. Configuring Azure Pipelines agent..."

./config.sh --unattended \
--agent "${AZP_AGENT_NAME:-$(hostname)}" \
--url "$AZP_URL" \
--auth PAT \
--token "$(cat "$AZP_TOKEN_FILE")" \
--pool "${AZP_POOL:-Default}" \
--work "${AZP_WORK:-_work}" \
--replace \
--acceptTeeEula & wait $!

print_header "4. Running Azure Pipelines agent..."

chmod +x ./run.sh


# If $AZP_PLACEHOLDER is set, skipping running the agent
if [ -n "$AZP_PLACEHOLDER" ]; then
echo 'Running in placeholder mode, skipping running the agent'
else
# To be aware of TERM and INT signals call run.sh
# Running it with the --once flag at the end will shut down the agent after the build is executed
./run.sh --once & wait $!
fi

0 comments on commit 17e0429

Please sign in to comment.