Skip to content

Commit

Permalink
Add docker publishing logic (actions#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
fgalind1 authored Oct 6, 2021
1 parent 75f5ec8 commit b7d54d8
Show file tree
Hide file tree
Showing 13 changed files with 662 additions and 4 deletions.
12 changes: 12 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Cache
_dotnetsdk
_layout
_downloads

# Dot files
.vscode

# Source
scripts
src
docs
28 changes: 28 additions & 0 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,31 @@ jobs:
run: |
${{ matrix.devScript }} package Release
working-directory: src

# Upload runner package tar.gz/zip as artifact
- name: Publish Artifact
uses: actions/upload-artifact@v1
with:
name: actions-runner-${{ matrix.runtime }}
path: _package

docker:
runs-on: self-hosted
needs:
- build
strategy:
matrix:
runtime: [ linux-x64 ]
include:
- runtime: linux-x64
steps:
- uses: actions/checkout@v1
- name: Set version
run: echo "VERSION=${GITHUB_SHA::7}" >> $GITHUB_ENV
- name: Download Artifact
uses: actions/download-artifact@v1
with:
name: actions-runner-${{ matrix.runtime }}
path: _package
- name: Build Docker Image
run: make docker-build
46 changes: 45 additions & 1 deletion .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,49 @@ jobs:
- name: Publish Artifact
uses: actions/upload-artifact@v1
with:
name: runner-package-${{ matrix.runtime }}
name: actions-runner-${{ matrix.runtime }}
path: _package

docker:
runs-on: self-hosted
needs:
- build
strategy:
matrix:
runtime: [ linux-x64 ]
include:
- runtime: linux-x64
steps:
- uses: actions/checkout@v1
- name: Set version
run: echo "VERSION=${GITHUB_SHA::7}" >> $GITHUB_ENV
- name: Download Artifact
uses: actions/download-artifact@v1
with:
name: actions-runner-${{ matrix.runtime }}
path: _package
- name: Login Docker Harbor CAAS
run: make login-docker
env:
DOCKER_REGISTRY: amr-registry.caas.intel.com
DOCKER_IMAGES_PREFIX: 1source/github-actions
DOCKER_USERNAME: robot\$$actions-runner-controller
DOCKER_PASSWORD: ${{ secrets.PROD_DOCKER_HARBOR_CAAS_PASSWORD }}
- name: Login Docker Azure
run: make login-docker
env:
DOCKER_REGISTRY: intelonesourcedocker.azurecr.io
DOCKER_IMAGES_PREFIX: github-actions
DOCKER_USERNAME: intelonesourcedocker
DOCKER_PASSWORD: ${{ secrets.PROD_DOCKER_AZURE_PASSWORD }}

- name: Build and push Docker Image for Harbor CAAS
run: make docker-build && make docker-push
env:
DOCKER_REGISTRY: amr-registry.caas.intel.com
DOCKER_IMAGES_PREFIX: 1source/github-actions
- name: Build Docker Image for Azure
run: make docker-build && make docker-push
env:
DOCKER_REGISTRY: intelonesourcedocker.azurecr.io
DOCKER_IMAGES_PREFIX: github-actions
27 changes: 24 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
VERSION?=0.0.0-dev
RUNNER_VERSION?=$(shell cat src/runnerversion)
DOCKER_VERSION?=20.10.8

WORKSPACE ?= $(shell pwd)

DOCKER ?= docker
DOCKER_CONFIG?=/tmp/.actions-runner-kubernetes

DOCKER_REGISTRY?=amr-registry.caas.intel.com
DOCKER_IMAGES_PREFIX?=1source/github-actions
Expand All @@ -18,12 +22,29 @@ else
DOCKER_USER_ARGS = --user=$(DOCKER_USER):$(DOCKER_GROUP)
endif

UBUNTU?=$(DOCKER) run -e DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 -e RUNTIME=linux-x64 -v $(WORKSPACE):/workspace -w /workspace/src ubuntu:20.04
DOCKER_BUILD_RUNNER_ARGS=--build-arg TARGETPLATFORM=$(shell arch) --build-arg RUNNER_VERSION=${RUNNER_VERSION} --build-arg DOCKER_VERSION=${DOCKER_VERSION}

UBUNTU?=$(DOCKER) run -t -e DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 -e RUNTIME=linux-x64 -v $(WORKSPACE):/workspace -w /workspace/src ubuntu:20.04

.PHONY: build
build:
$(UBUNTU) bash -c ''' \
./dev.sh dependencies $$RUNTIME && \
./dev.sh layout Release $$RUNTIME && \
./dev.sh test && \
./dev.sh package Release'''
./dev.sh package Release'''

.PHONY: login-docker
login-docker:
$(DOCKER) --config $(DOCKER_CONFIG) login -u $(DOCKER_USERNAME) -p $(DOCKER_PASSWORD) $(DOCKER_REGISTRY)

.PHONY: docker-build
docker-build:
$(DOCKER) build -t ${DOCKER_BASE_IMAGE}-runner:v${RUNNER_VERSION}-ubuntu-20.04-${VERSION} ${DOCKER_BUILD_RUNNER_ARGS} -f docker/Dockerfile .

.PHONY: docker-push
docker-push:
$(DOCKER) tag ${DOCKER_BASE_IMAGE}-runner:v${RUNNER_VERSION}-ubuntu-20.04-${VERSION} ${DOCKER_BASE_IMAGE}-runner:v${RUNNER_VERSION}-ubuntu-20.04
$(DOCKER) tag ${DOCKER_BASE_IMAGE}-runner:v${RUNNER_VERSION}-ubuntu-20.04-${VERSION} ${DOCKER_BASE_IMAGE}-runner:latest
$(DOCKER) --config $(DOCKER_CONFIG) push ${DOCKER_BASE_IMAGE}-runner:v${RUNNER_VERSION}-ubuntu-20.04-${VERSION}
$(DOCKER) --config $(DOCKER_CONFIG) push ${DOCKER_BASE_IMAGE}-runner:v${RUNNER_VERSION}-ubuntu-20.04
$(DOCKER) --config $(DOCKER_CONFIG) push ${DOCKER_BASE_IMAGE}-runner:latest
111 changes: 111 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
FROM ubuntu:20.04

ARG TARGETPLATFORM
ARG RUNNER_VERSION
ARG DOCKER_CHANNEL=stable
ARG DOCKER_VERSION=20.10.8
ARG DUMB_INIT_VERSION=1.2.5

RUN test -n "$TARGETPLATFORM" || (echo "TARGETPLATFORM must be set" && false)

ENV DEBIAN_FRONTEND=noninteractive
RUN apt update -y \
&& apt install -y software-properties-common \
&& add-apt-repository -y ppa:git-core/ppa \
&& apt update -y \
&& apt install -y --no-install-recommends \
build-essential \
curl \
ca-certificates \
dnsutils \
ftp \
git \
iproute2 \
iputils-ping \
jq \
libunwind8 \
locales \
netcat \
openssh-client \
parallel \
python3-pip \
rsync \
shellcheck \
sudo \
telnet \
time \
tzdata \
unzip \
upx \
wget \
zip \
zstd \
&& ln -sf /usr/bin/python3 /usr/bin/python \
&& ln -sf /usr/bin/pip3 /usr/bin/pip \
&& rm -rf /var/lib/apt/lists/*

RUN wget -O /tmp/IntelSHA2RootChain-Base64.zip --no-check-certificate "https://certs.intel.com/crt/IntelSHA2RootChain-Base64.zip" \
&& unzip /tmp/IntelSHA2RootChain-Base64.zip -d /usr/local/share/ca-certificates \
&& rm /tmp/IntelSHA2RootChain-Base64.zip \
&& update-ca-certificates --fresh

# arch command on OS X reports "i386" for Intel CPUs regardless of bitness
RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \
&& if [ "$ARCH" = "arm64" ]; then export ARCH=aarch64 ; fi \
&& if [ "$ARCH" = "amd64" ] || [ "$ARCH" = "i386" ]; then export ARCH=x86_64 ; fi \
&& curl -f -L -o /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v${DUMB_INIT_VERSION}/dumb-init_${DUMB_INIT_VERSION}_${ARCH} \
&& chmod +x /usr/local/bin/dumb-init

# Docker download supports arm64 as aarch64 & amd64 / i386 as x86_64
RUN set -vx; \
export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \
&& if [ "$ARCH" = "arm64" ]; then export ARCH=aarch64 ; fi \
&& if [ "$ARCH" = "amd64" ] || [ "$ARCH" = "i386" ]; then export ARCH=x86_64 ; fi \
&& curl -f -L -o docker.tgz https://download.docker.com/linux/static/${DOCKER_CHANNEL}/${ARCH}/docker-${DOCKER_VERSION}.tgz \
&& tar zxvf docker.tgz \
&& install -o root -g root -m 755 docker/docker /usr/local/bin/docker \
&& rm -rf docker docker.tgz \
&& adduser --disabled-password --gecos "" --uid 1000 runner \
&& groupadd docker \
&& usermod -aG sudo runner \
&& usermod -aG docker runner \
&& echo "%sudo ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers

ENV RUNNER_ASSETS_DIR=/runnertmp
ENV HOME=/home/runner

RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \
&& if [ "$ARCH" = "amd64" ] || [ "$ARCH" = "x86_64" ] || [ "$ARCH" = "i386" ]; then export ARCH=x64 ; fi \
&& mkdir -p "$RUNNER_ASSETS_DIR/packages"

ADD _package/ $RUNNER_ASSETS_DIR/packages/

RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \
&& if [ "$ARCH" = "amd64" ] || [ "$ARCH" = "x86_64" ] || [ "$ARCH" = "i386" ]; then export ARCH=x64 ; fi \
&& cd "$RUNNER_ASSETS_DIR" \
&& tar xzf ./packages/actions-runner-linux-${ARCH}-${RUNNER_VERSION}.tar.gz \
&& rm ./packages/actions-runner-linux-${ARCH}-${RUNNER_VERSION}.tar.gz \
&& rm -rf packages \
&& ./bin/installdependencies.sh \
&& mv ./externals ./externalstmp \
&& apt-get install -y libyaml-dev \
&& rm -rf /var/lib/apt/lists/*

ENV RUNNER_TOOL_CACHE=/opt/hostedtoolcache
RUN mkdir /opt/hostedtoolcache \
&& chgrp docker /opt/hostedtoolcache \
&& chmod g+rwx /opt/hostedtoolcache

COPY docker/entrypoint.sh docker/configure.sh /
RUN chmod 755 /entrypoint.sh
RUN chmod 755 /configure.sh
COPY --chown=runner:docker docker/patched $RUNNER_ASSETS_DIR/patched

# Add the Python "User Script Directory" to the PATH
ENV PATH="${PATH}:${HOME}/.local/bin"
ENV ImageOS=ubuntu20

USER runner

ENTRYPOINT ["/usr/local/bin/dumb-init", "--"]
CMD ["/entrypoint.sh"]
143 changes: 143 additions & 0 deletions docker/configure.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#!/bin/bash

LIGHTGREEN="\e[0;32m"
LIGHTRED="\e[0;31m"
WHITE="\e[0;97m"
RESET="\e[0m"

log(){
printf "${WHITE}${@}${RESET}\n" 1>&2
}

success(){
printf "${LIGHTGREEN}${@}${RESET}\n" 1>&2
}

error(){
printf "${LIGHTRED}${@}${RESET}\n" 1>&2
}

configure(){

result=0

if [ -f .runner ]; then
log "Runner is already configured..."
return
fi

retries_left=10
while [[ ${retries_left} -gt 0 ]]; do
log "Configuring the runner."
./config.sh --unattended --replace \
--name "${RUNNER_NAME}" \
--url "${GITHUB_URL}${ATTACH}" \
--token "${RUNNER_TOKEN}" \
--runnergroup "${RUNNER_GROUPS}" \
--labels "${RUNNER_LABELS}" \
--work "${RUNNER_WORKDIR}" "${config_args[@]}"

if [ -f .runner ]; then
success "Runner successfully configured."
return
fi

error "Configuration failed. Retrying..."
retries_left=$((retries_left - 1))
sleep 3
done

if [ ! -f .runner ]; then
# we couldn't configure and register the runner; no point continuing
error "Configuration failed!"
result=1
return
fi

cat .runner
# Note: the `.runner` file's content should be something like the below:
#
# $ cat /runner/.runner
# {
# "agentId": 117, #=> corresponds to the ID of the runner
# "agentName": "THE_RUNNER_POD_NAME",
# "poolId": 1,
# "poolName": "Default",
# "serverUrl": "https://pipelines.actions.githubusercontent.com/SOME_RANDOM_ID",
# "gitHubUrl": "https://github.com/USER/REPO",
# "workFolder": "/some/work/dir" #=> corresponds to Runner.Spec.WorkDir
# }
#
# Especially `agentId` is important, as other than listing all the runners in the repo,
# this is the only change we could get the exact runnner ID which can be useful for further
# GitHub API call like the below. Note that 171 is the agentId seen above.
# curl \
# -H "Accept: application/vnd.github.v3+json" \
# -H "Authorization: bearer ${GITHUB_TOKEN}"
# https://api.github.com/repos/USER/REPO/actions/runners/171
}

RUNNER_HOME=${RUNNER_HOME:-/runner}

if [ -z "${GITHUB_URL}" ]; then
log "Working with public GitHub"
GITHUB_URL="https://github.com/"
else
length=${#GITHUB_URL}
last_char=${GITHUB_URL:length-1:1}

[[ $last_char != "/" ]] && GITHUB_URL="$GITHUB_URL/"; :
log "Github endpoint URL ${GITHUB_URL}"
fi

if [ -z "${RUNNER_NAME}" ]; then
error "RUNNER_NAME must be set"
exit 1
fi

if [ -n "${RUNNER_ORG}" ] && [ -n "${RUNNER_REPO}" ] && [ -n "${RUNNER_ENTERPRISE}" ]; then
ATTACH="${RUNNER_ORG}/${RUNNER_REPO}"
elif [ -n "${RUNNER_ORG}" ]; then
ATTACH="${RUNNER_ORG}"
elif [ -n "${RUNNER_REPO}" ]; then
ATTACH="${RUNNER_REPO}"
elif [ -n "${RUNNER_ENTERPRISE}" ]; then
ATTACH="enterprises/${RUNNER_ENTERPRISE}"
else
error "At least one of RUNNER_ORG or RUNNER_REPO or RUNNER_ENTERPRISE must be set"
exit 1
fi

if [ -z "${RUNNER_TOKEN}" ]; then
error "RUNNER_TOKEN must be set"
exit 1
fi

if [ -z "${RUNNER_REPO}" ] && [ -n "${RUNNER_GROUP}" ];then
RUNNER_GROUPS=${RUNNER_GROUP}
fi

# Hack due to https://github.com/actions-runner-controller/actions-runner-controller/issues/252#issuecomment-758338483
if [ ! -d "${RUNNER_HOME}" ]; then
error "${RUNNER_HOME} should be an emptyDir mount. Please fix the pod spec."
exit 1
fi

config_args=()
if [ "${RUNNER_FEATURE_FLAG_EPHEMERAL:-}" == "true" -a "${RUNNER_EPHEMERAL}" != "false" ]; then
config_args+=(--ephemeral)
echo "Passing --ephemeral to config.sh to enable the ephemeral runner."
fi

cd ${RUNNER_HOME}
# past that point, it's all relative pathes from /runner

if [[ $1 == "--infinite" ]]; then
while true; do
configure
sleep 60
done
else
configure
exit $result
fi
Loading

0 comments on commit b7d54d8

Please sign in to comment.