Initial dockerfile for github-runner
This commit is contained in:
parent
4f907dbb53
commit
91c92a47c8
51
images/github-runner/Dockerfile
Normal file
51
images/github-runner/Dockerfile
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
FROM nestybox/ubuntu-focal-docker
|
||||||
|
|
||||||
|
# Extra deps for GHA Runner
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y \
|
||||||
|
curl \
|
||||||
|
jq \
|
||||||
|
sudo \
|
||||||
|
unzip \
|
||||||
|
wget \
|
||||||
|
zip \
|
||||||
|
git \
|
||||||
|
&& rm -rf /var/lib/apt/list/*
|
||||||
|
|
||||||
|
# Add and config runner user as sudo
|
||||||
|
RUN useradd -m runner \
|
||||||
|
&& usermod -aG sudo runner \
|
||||||
|
&& usermod -aG docker runner \
|
||||||
|
&& echo "%sudo ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers
|
||||||
|
|
||||||
|
# Build args
|
||||||
|
ARG TARGETPLATFORM=x64
|
||||||
|
ARG RUNNER_VERSION=2.301.0
|
||||||
|
WORKDIR /runner
|
||||||
|
|
||||||
|
# Runner download supports amd64 as x64
|
||||||
|
RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \
|
||||||
|
&& if [ "$ARCH" = "amd64" ]; then export ARCH=x64 ; fi \
|
||||||
|
&& curl -Ls -o runner.tar.gz https://github.com/uazo/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-${ARCH}-${RUNNER_VERSION}.tar.gz \
|
||||||
|
&& tar xzf ./runner.tar.gz \
|
||||||
|
&& rm runner.tar.gz \
|
||||||
|
&& ./bin/installdependencies.sh \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Dumb Init
|
||||||
|
#RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \
|
||||||
|
# && curl -Ls -o /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.2/dumb-init_1.2.2_${ARCH} \
|
||||||
|
# && chmod +x /usr/local/bin/dumb-init
|
||||||
|
|
||||||
|
COPY startup.sh .
|
||||||
|
|
||||||
|
# Add patched scripts from GHA runner (svc.sh and RunnerService.js)
|
||||||
|
COPY --chown=runner:runner patched/ ./patched/
|
||||||
|
|
||||||
|
RUN chmod +x ./patched/runsvc.sh ./startup.sh
|
||||||
|
|
||||||
|
USER runner
|
||||||
|
|
||||||
|
#ENTRYPOINT ["/usr/local/bin/dumb-init", "--"]
|
||||||
|
CMD ./startup.sh
|
91
images/github-runner/patched/RunnerService.js
Normal file
91
images/github-runner/patched/RunnerService.js
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
// Copyright (c) GitHub. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
var childProcess = require("child_process");
|
||||||
|
var path = require("path")
|
||||||
|
|
||||||
|
var supported = ['linux', 'darwin']
|
||||||
|
|
||||||
|
if (supported.indexOf(process.platform) == -1) {
|
||||||
|
console.log('Unsupported platform: ' + process.platform);
|
||||||
|
console.log('Supported platforms are: ' + supported.toString());
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var stopping = false;
|
||||||
|
var listener = null;
|
||||||
|
|
||||||
|
var runService = function() {
|
||||||
|
var listenerExePath = path.join(__dirname, '../bin/Runner.Listener');
|
||||||
|
var interactive = process.argv[2] === "interactive";
|
||||||
|
|
||||||
|
if(!stopping) {
|
||||||
|
try {
|
||||||
|
if (interactive) {
|
||||||
|
console.log('Starting Runner listener interactively');
|
||||||
|
listener = childProcess.spawn(listenerExePath, ['run'].concat(process.argv.slice(3)), { env: process.env });
|
||||||
|
} else {
|
||||||
|
console.log('Starting Runner listener with startup type: service');
|
||||||
|
listener = childProcess.spawn(listenerExePath, ['run', '--startuptype', 'service'].concat(process.argv.slice(2)), { env: process.env });
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Started listener process');
|
||||||
|
|
||||||
|
listener.stdout.on('data', (data) => {
|
||||||
|
process.stdout.write(data.toString('utf8'));
|
||||||
|
});
|
||||||
|
|
||||||
|
listener.stderr.on('data', (data) => {
|
||||||
|
process.stdout.write(data.toString('utf8'));
|
||||||
|
});
|
||||||
|
|
||||||
|
listener.on('close', (code) => {
|
||||||
|
console.log(`Runner listener exited with error code ${code}`);
|
||||||
|
|
||||||
|
if (code === 0) {
|
||||||
|
console.log('Runner listener exit with 0 return code, stop the service, no retry needed.');
|
||||||
|
stopping = true;
|
||||||
|
} else if (code === 1) {
|
||||||
|
console.log('Runner listener exit with terminated error, stop the service, no retry needed.');
|
||||||
|
stopping = true;
|
||||||
|
} else if (code === 2) {
|
||||||
|
console.log('Runner listener exit with retryable error, re-launch runner in 5 seconds.');
|
||||||
|
} else if (code === 3) {
|
||||||
|
console.log('Runner listener exit because of updating, re-launch runner in 5 seconds.');
|
||||||
|
} else {
|
||||||
|
console.log('Runner listener exit with undefined return code, re-launch runner in 5 seconds.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!stopping) {
|
||||||
|
setTimeout(runService, 5000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch(ex) {
|
||||||
|
console.log(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runService();
|
||||||
|
console.log('Started running service');
|
||||||
|
|
||||||
|
var gracefulShutdown = function(code) {
|
||||||
|
console.log('Shutting down runner listener');
|
||||||
|
stopping = true;
|
||||||
|
if (listener) {
|
||||||
|
console.log('Sending SIGINT to runner listener to stop');
|
||||||
|
listener.kill('SIGINT');
|
||||||
|
|
||||||
|
// TODO wait for 30 seconds and send a SIGKILL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
process.on('SIGINT', () => {
|
||||||
|
gracefulShutdown(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('SIGTERM', () => {
|
||||||
|
gracefulShutdown(0);
|
||||||
|
});
|
20
images/github-runner/patched/runsvc.sh
Normal file
20
images/github-runner/patched/runsvc.sh
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# convert SIGTERM signal to SIGINT
|
||||||
|
# for more info on how to propagate SIGTERM to a child process see: http://veithen.github.io/2014/11/16/sigterm-propagation.html
|
||||||
|
trap 'kill -INT $PID' TERM INT
|
||||||
|
|
||||||
|
if [ -f ".path" ]; then
|
||||||
|
# configure
|
||||||
|
export PATH=`cat .path`
|
||||||
|
echo ".path=${PATH}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# insert anything to setup env when running as a service
|
||||||
|
|
||||||
|
# run the host process which keep the listener alive
|
||||||
|
./externals/node12/bin/node ./bin/RunnerService.js $* &
|
||||||
|
PID=$!
|
||||||
|
wait $PID
|
||||||
|
trap - TERM INT
|
||||||
|
wait $PID
|
55
images/github-runner/startup.sh
Normal file
55
images/github-runner/startup.sh
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "Starting supervisor (Docker)"
|
||||||
|
sudo service docker start
|
||||||
|
|
||||||
|
if [ -n "${GITHUB_REPOSITORY}" ]
|
||||||
|
then
|
||||||
|
auth_url="https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPOSITORY}/actions/runners/registration-token"
|
||||||
|
registration_url="https://github.com/${GITHUB_OWNER}/${GITHUB_REPOSITORY}"
|
||||||
|
else
|
||||||
|
auth_url="https://api.github.com/orgs/${GITHUB_OWNER}/actions/runners/registration-token"
|
||||||
|
registration_url="https://github.com/${GITHUB_OWNER}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
generate_token() {
|
||||||
|
payload=$(curl -sX POST -H "Authorization: token ${GITHUB_PERSONAL_TOKEN}" "${auth_url}")
|
||||||
|
runner_token=$(echo "${payload}" | jq .token --raw-output)
|
||||||
|
|
||||||
|
if [ "${runner_token}" == "null" ]
|
||||||
|
then
|
||||||
|
echo "${payload}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "${runner_token}"
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_runner() {
|
||||||
|
./config.sh remove --unattended --token "$(generate_token)"
|
||||||
|
}
|
||||||
|
|
||||||
|
service docker status
|
||||||
|
runner_id=${RUNNER_NAME}_$(openssl rand -hex 6)
|
||||||
|
echo "Registering runner ${runner_id}"
|
||||||
|
|
||||||
|
./config.sh \
|
||||||
|
--name "${runner_id}" \
|
||||||
|
--labels "${RUNNER_LABELS}" \
|
||||||
|
--token "$(generate_token)" \
|
||||||
|
--url "${registration_url}" \
|
||||||
|
--allowedauthorslist "${ALLOWEDAUTHORSLIST}" \
|
||||||
|
--unattended \
|
||||||
|
--replace
|
||||||
|
|
||||||
|
trap 'remove_runner; exit 130' SIGINT
|
||||||
|
trap 'remove_runner; exit 143' SIGTERM
|
||||||
|
|
||||||
|
for f in runsvc.sh RunnerService.js; do
|
||||||
|
mv bin/${f}{,.bak}
|
||||||
|
mv {patched,bin}/${f}
|
||||||
|
done
|
||||||
|
|
||||||
|
./bin/runsvc.sh --once "$*"
|
||||||
|
remove_runner
|
Loading…
Reference in New Issue
Block a user