forked from actions/runner
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Sample scripts to automate scaleable runners (actions#427)
- Loading branch information
1 parent
e1a3c1d
commit 147eb82
Showing
4 changed files
with
351 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Automate Configuring Self-Hosted Runners | ||
|
||
|
||
## Export PAT | ||
|
||
Before running any of these sample scripts, create a GitHub PAT and export it before running the script | ||
|
||
```bash | ||
export RUNNER_CFG_PAT=yourPAT | ||
``` | ||
|
||
## Create running as a service | ||
|
||
**Scenario**: Run on a machine or VM (not container) which automates: | ||
|
||
- Resolving latest released runner | ||
- Download and extract latest | ||
- Acquire a registration token | ||
- Configure the runner | ||
- Run as a systemd (linux) or Launchd (osx) service | ||
|
||
:point_right: [Sample script here](../scripts/create-latest-svc.sh) :point_left: | ||
|
||
Run as a one-liner. NOTE: replace with yourorg/yourrepo (repo level) or just yourorg (org level) | ||
```bash | ||
curl -s https://raw.githubusercontent.com/actions/runner/automate/scripts/create-latest-svc.sh | bash -s yourorg/yourrepo | ||
``` | ||
|
||
## Uninstall running as service | ||
|
||
**Scenario**: Run on a machine or VM (not container) which automates: | ||
|
||
- Stops and uninstalls the systemd (linux) or Launchd (osx) service | ||
- Acquires a removal token | ||
- Removes the runner | ||
|
||
:point_right: [Sample script here](../scripts/remove-svc.sh) :point_left: | ||
|
||
Repo level one liner. NOTE: replace with yourorg/yourrepo (repo level) or just yourorg (org level) | ||
```bash | ||
curl -s https://raw.githubusercontent.com/actions/runner/automate/scripts/remove-svc.sh | bash -s yourorg/yourrepo | ||
``` | ||
|
||
### Delete an offline runner | ||
|
||
**Scenario**: Deletes a registered runner that is offline: | ||
|
||
- Ensures the runner is offline | ||
- Resolves id from name | ||
- Deletes the runner | ||
|
||
:point_right: [Sample script here](../scripts/delete.sh) :point_left: | ||
|
||
Repo level one-liner. NOTE: replace with yourorg/yourrepo (repo level) or just yourorg (org level) and replace runnername | ||
```bash | ||
curl -s https://raw.githubusercontent.com/actions/runner/automate/scripts/delete.sh | bash -s yourorg/yourrepo runnername | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
#/bin/bash | ||
|
||
set -e | ||
|
||
# | ||
# Downloads latest releases (not pre-release) runner | ||
# Configures as a service | ||
# | ||
# Examples: | ||
# RUNNER_CFG_PAT=<yourPAT> ./create-latest-svc.sh myuser/myrepo | ||
# RUNNER_CFG_PAT=<yourPAT> ./create-latest-svc.sh myorg | ||
# | ||
# Usage: | ||
# export RUNNER_CFG_PAT=<yourPAT> | ||
# ./create-latest-svc scope [name] [user] | ||
# | ||
# scope required repo (:owner/:repo) or org (:organization) | ||
# name optional defaults to hostname | ||
# user optional user svc will run as. defaults to current | ||
# | ||
# Notes: | ||
# PATS over envvars are more secure | ||
# Should be used on VMs and not containers | ||
# Works on OSX and Linux | ||
# Assumes x64 arch | ||
# | ||
|
||
runner_scope=${1} | ||
runner_name=${2:-$(hostname)} | ||
svc_user=${3:-$USER} | ||
|
||
echo "Configuring runner @ ${runner_scope}" | ||
sudo echo | ||
|
||
#--------------------------------------- | ||
# Validate Environment | ||
#--------------------------------------- | ||
runner_plat=linux | ||
[ ! -z "$(which sw_vers)" ] && runner_plat=osx; | ||
|
||
function fatal() | ||
{ | ||
echo "error: $1" >&2 | ||
exit 1 | ||
} | ||
|
||
if [ -z "${runner_scope}" ]; then fatal "supply scope as argument 1"; fi | ||
if [ -z "${RUNNER_CFG_PAT}" ]; then fatal "RUNNER_CFG_PAT must be set before calling"; fi | ||
|
||
which curl || fatal "curl required. Please install in PATH with apt-get, brew, etc" | ||
which jq || fatal "jq required. Please install in PATH with apt-get, brew, etc" | ||
|
||
# bail early if there's already a runner there. also sudo early | ||
if [ -d ./runner ]; then | ||
fatal "Runner already exists. Use a different directory or delete ./runner" | ||
fi | ||
|
||
sudo -u ${svc_user} mkdir runner | ||
|
||
# TODO: validate not in a container | ||
# TODO: validate systemd or osx svc installer | ||
|
||
#-------------------------------------- | ||
# Get a config token | ||
#-------------------------------------- | ||
echo | ||
echo "Generating a registration token..." | ||
|
||
# if the scope has a slash, it's an repo runner | ||
base_api_url="https://api.github.com/orgs" | ||
if [[ "$runner_scope" == *\/* ]]; then | ||
base_api_url="https://api.github.com/repos" | ||
fi | ||
|
||
export RUNNER_TOKEN=$(curl -s -X POST ${base_api_url}/${runner_scope}/actions/runners/registration-token -H "accept: application/vnd.github.everest-preview+json" -H "authorization: token ${RUNNER_CFG_PAT}" | jq -r '.token') | ||
|
||
if [ -z "$RUNNER_TOKEN" ]; then fatal "Failed to get a token"; fi | ||
|
||
#--------------------------------------- | ||
# Download latest released and extract | ||
#--------------------------------------- | ||
echo | ||
echo "Downloading latest runner ..." | ||
|
||
latest_version_label=$(curl -s -X GET 'https://api.github.com/repos/actions/runner/releases/latest' | jq -r '.tag_name') | ||
latest_version=$(echo ${latest_version_label:1}) | ||
runner_file="actions-runner-${runner_plat}-x64-${latest_version}.tar.gz" | ||
|
||
if [ -f "${runner_file}" ]; then | ||
echo "${runner_file} exists. skipping download." | ||
else | ||
runner_url="https://github.com/actions/runner/releases/download/${latest_version_label}/${runner_file}" | ||
|
||
echo "Downloading ${latest_version_label} for ${runner_plat} ..." | ||
echo $runner_url | ||
|
||
curl -O -L ${runner_url} | ||
fi | ||
|
||
ls -la *.tar.gz | ||
|
||
#--------------------------------------------------- | ||
# extract to runner directory in this directory | ||
#--------------------------------------------------- | ||
echo | ||
echo "Extracting ${runner_file} to ./runner" | ||
|
||
tar xzf "./${runner_file}" -C runner | ||
|
||
# export of pass | ||
sudo chown -R $svc_user ./runner | ||
|
||
pushd ./runner | ||
|
||
#--------------------------------------- | ||
# Unattend config | ||
#--------------------------------------- | ||
runner_url="https://github.com/${runner_scope}" | ||
echo | ||
echo "Configuring ${runner_name} @ $runner_url" | ||
echo "./config.sh --unattended --url $runner_url --token *** --name $runner_name" | ||
sudo -E -u ${svc_user} ./config.sh --unattended --url $runner_url --token $RUNNER_TOKEN --name $runner_name | ||
|
||
#--------------------------------------- | ||
# Configuring as a service | ||
#--------------------------------------- | ||
echo | ||
echo "Configuring as a service ..." | ||
prefix="" | ||
if [ "${runner_plat}" == "linux" ]; then | ||
prefix="sudo " | ||
fi | ||
|
||
${prefix}./svc.sh install ${svc_user} | ||
${prefix}./svc.sh start |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#/bin/bash | ||
|
||
set -e | ||
|
||
# | ||
# Force deletes a runner from the service | ||
# The caller should have already ensured the runner is gone and/or stopped | ||
# | ||
# Examples: | ||
# RUNNER_CFG_PAT=<yourPAT> ./delete.sh myuser/myrepo myname | ||
# RUNNER_CFG_PAT=<yourPAT> ./delete.sh myorg | ||
# | ||
# Usage: | ||
# export RUNNER_CFG_PAT=<yourPAT> | ||
# ./delete.sh scope name | ||
# | ||
# scope required repo (:owner/:repo) or org (:organization) | ||
# name optional defaults to hostname. name to delete | ||
# | ||
# Notes: | ||
# PATS over envvars are more secure | ||
# Works on OSX and Linux | ||
# Assumes x64 arch | ||
# | ||
|
||
runner_scope=${1} | ||
runner_name=${2} | ||
|
||
echo "Deleting runner ${runner_name} @ ${runner_scope}" | ||
|
||
function fatal() | ||
{ | ||
echo "error: $1" >&2 | ||
exit 1 | ||
} | ||
|
||
if [ -z "${runner_scope}" ]; then fatal "supply scope as argument 1"; fi | ||
if [ -z "${runner_name}" ]; then fatal "supply name as argument 2"; fi | ||
if [ -z "${RUNNER_CFG_PAT}" ]; then fatal "RUNNER_CFG_PAT must be set before calling"; fi | ||
|
||
which curl || fatal "curl required. Please install in PATH with apt-get, brew, etc" | ||
which jq || fatal "jq required. Please install in PATH with apt-get, brew, etc" | ||
|
||
base_api_url="https://api.github.com/orgs" | ||
if [[ "$runner_scope" == *\/* ]]; then | ||
base_api_url="https://api.github.com/repos" | ||
fi | ||
|
||
|
||
#-------------------------------------- | ||
# Ensure offline | ||
#-------------------------------------- | ||
runner_status=$(curl -s -X GET ${base_api_url}/${runner_scope}/actions/runners?per_page=100 -H "accept: application/vnd.github.everest-preview+json" -H "authorization: token ${RUNNER_CFG_PAT}" \ | ||
| jq -M -j ".runners | .[] | [select(.name == \"${runner_name}\")] | .[0].status") | ||
|
||
if [ -z "${runner_status}" ]; then | ||
fatal "Could not find runner with name ${runner_name}" | ||
fi | ||
|
||
echo "Status: ${runner_status}" | ||
|
||
if [ "${runner_status}" != "offline" ]; then | ||
fatal "Runner should be offline before removing" | ||
fi | ||
|
||
#-------------------------------------- | ||
# Get id of runner to remove | ||
#-------------------------------------- | ||
runner_id=$(curl -s -X GET ${base_api_url}/${runner_scope}/actions/runners?per_page=100 -H "accept: application/vnd.github.everest-preview+json" -H "authorization: token ${RUNNER_CFG_PAT}" \ | ||
| jq -M -j ".runners | .[] | [select(.name == \"${runner_name}\")] | .[0].id") | ||
|
||
if [ -z "${runner_id}" ]; then | ||
fatal "Could not find runner with name ${runner_name}" | ||
fi | ||
|
||
echo "Removing id ${runner_id}" | ||
|
||
#-------------------------------------- | ||
# Remove the runner | ||
#-------------------------------------- | ||
curl -s -X DELETE ${base_api_url}/${runner_scope}/actions/runners/${runner_id} -H "authorization: token ${RUNNER_CFG_PAT}" | ||
|
||
echo "Done." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#/bin/bash | ||
|
||
set -e | ||
|
||
# | ||
# Removes a runner running as a service | ||
# Must be run on the machine where the service is run | ||
# | ||
# Examples: | ||
# RUNNER_CFG_PAT=<yourPAT> ./remove-svc.sh myuser/myrepo | ||
# RUNNER_CFG_PAT=<yourPAT> ./remove-svc.sh myorg | ||
# | ||
# Usage: | ||
# export RUNNER_CFG_PAT=<yourPAT> | ||
# ./remove-svc scope name | ||
# | ||
# scope required repo (:owner/:repo) or org (:organization) | ||
# name optional defaults to hostname. name to uninstall and remove | ||
# | ||
# Notes: | ||
# PATS over envvars are more secure | ||
# Should be used on VMs and not containers | ||
# Works on OSX and Linux | ||
# Assumes x64 arch | ||
# | ||
|
||
runner_scope=${1} | ||
runner_name=${2:-$(hostname)} | ||
|
||
echo "Uninstalling runner ${runner_name} @ ${runner_scope}" | ||
sudo echo | ||
|
||
function fatal() | ||
{ | ||
echo "error: $1" >&2 | ||
exit 1 | ||
} | ||
|
||
if [ -z "${runner_scope}" ]; then fatal "supply scope as argument 1"; fi | ||
if [ -z "${RUNNER_CFG_PAT}" ]; then fatal "RUNNER_CFG_PAT must be set before calling"; fi | ||
|
||
which curl || fatal "curl required. Please install in PATH with apt-get, brew, etc" | ||
which jq || fatal "jq required. Please install in PATH with apt-get, brew, etc" | ||
|
||
runner_plat=linux | ||
[ ! -z "$(which sw_vers)" ] && runner_plat=osx; | ||
|
||
#-------------------------------------- | ||
# Get a remove token | ||
#-------------------------------------- | ||
echo | ||
echo "Generating a removal token..." | ||
|
||
# if the scope has a slash, it's an repo runner | ||
base_api_url="https://api.github.com/orgs" | ||
if [[ "$runner_scope" == *\/* ]]; then | ||
base_api_url="https://api.github.com/repos" | ||
fi | ||
|
||
export REMOVE_TOKEN=$(curl -s -X POST ${base_api_url}/${runner_scope}/actions/runners/remove-token -H "accept: application/vnd.github.everest-preview+json" -H "authorization: token ${RUNNER_CFG_PAT}" | jq -r '.token') | ||
|
||
if [ -z "$REMOVE_TOKEN" ]; then fatal "Failed to get a token"; fi | ||
|
||
#--------------------------------------- | ||
# Stop and uninstall the service | ||
#--------------------------------------- | ||
echo | ||
echo "Uninstall the service ..." | ||
pushd ./runner | ||
prefix="" | ||
if [ "${runner_plat}" == "linux" ]; then | ||
prefix="sudo " | ||
fi | ||
${prefix}./svc.sh stop | ||
${prefix}./svc.sh uninstall | ||
${prefix}./config.sh remove --token $REMOVE_TOKEN |