diff --git a/Dockerfile b/Dockerfile index d6d4668..e2405e3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,8 @@ ARG INSTALL_VERSION=latest ARG INSTALL_NAMESPACE=/opt/gh-runner-krunvm COPY runner/*.sh ${INSTALL_NAMESPACE}/bin/ +# Redundant, but this makes this image more standalone. +COPY lib/*.sh ${INSTALL_NAMESPACE}/lib/ RUN chmod a+x ${INSTALL_NAMESPACE}/bin/*.sh \ && "${INSTALL_NAMESPACE}/bin/install.sh" -v -l /dev/stdout diff --git a/Dockerfile.base b/Dockerfile.base index 983d9b8..0b361cf 100644 --- a/Dockerfile.base +++ b/Dockerfile.base @@ -5,6 +5,7 @@ FROM fedora:${FEDORA_VERSION} ARG INSTALL_NAMESPACE=/opt/gh-runner-krunvm COPY base/*.sh ${INSTALL_NAMESPACE}/bin/ +COPY lib/*.sh ${INSTALL_NAMESPACE}/lib/ RUN chmod a+x "${INSTALL_NAMESPACE}/bin/base.sh" \ && "${INSTALL_NAMESPACE}/bin/base.sh" -dv -l /dev/stdout COPY base/root/ / diff --git a/base/base.sh b/base/base.sh index 0ec3de7..d693be6 100755 --- a/base/base.sh +++ b/base/base.sh @@ -41,23 +41,20 @@ BASE_UID=${BASE_UID:-1001} BASE_GROUP=${BASE_GROUP:-runner} BASE_GID=${BASE_GID:-121} -# Name of the "sudo" group +# Name of the "sudo" group - wheel on Fedora, sudo on Ubuntu BASE_SUDO=${BASE_SUDO:-"wheel"} # Resolve the root directory hosting this script to an absolute path, symbolic # links resolved. BASE_ROOTDIR=$( cd -P -- "$(dirname -- "$(command -v -- "$(abspath "$0")")")" && pwd -P ) + BASE_DOCKER_WRAPPER=${BASE_DOCKER_WRAPPER:-$BASE_ROOTDIR/docker.sh} -usage() { - # This uses the comments behind the options to show the help. Not extremly - # correct, but effective and simple. - echo "$0 installs a base GitHub runner environment in Fedora" && \ - grep "[[:space:]].)\ #" "$0" | - sed 's/#//' | - sed -r 's/([a-z-])\)/-\1/' - exit "${1:-0}" -} +# shellcheck source=../lib/common.sh +. "$BASE_ROOTDIR/../lib/common.sh" + +# shellcheck disable=SC2034 # Used in sourced scripts +KRUNVM_RUNNER_MAIN="Install a base GitHub runner environment in Fedora" while getopts "dl:vh-" opt; do case "$opt" in @@ -77,36 +74,10 @@ while getopts "dl:vh-" opt; do done shift $((OPTIND-1)) -# PML: Poor Man's Logging -_log() { - printf '[%s] [%s] [%s] %s\n' \ - "$(basename "$0")" \ - "${2:-LOG}" \ - "$(date +'%Y%m%d-%H%M%S')" \ - "${1:-}" \ - >&"$BASE_LOG" -} -trace() { if [ "${BASE_VERBOSE:-0}" -ge "3" ]; then _log "$1" TRC; fi; } -debug() { if [ "${BASE_VERBOSE:-0}" -ge "2" ]; then _log "$1" DBG; fi; } -verbose() { if [ "${BASE_VERBOSE:-0}" -ge "1" ]; then _log "$1" NFO; fi; } -warn() { _log "$1" WRN; } -error() { _log "$1" ERR && exit 1; } - -# Find the executable passed as an argument in the PATH variable and print it. -find_exec() { - while IFS= read -r dir; do - if [ -n "${dir}" ] && [ -d "${dir}" ]; then - if [ -x "${dir%/}/$1" ] && [ "${dir%/}/$1" != "$(abspath "$0")" ]; then - printf %s\\n "${dir%/}/$1" - break - fi - fi - done <&"$KRUNVM_RUNNER_LOG" +} +trace() { if [ "${KRUNVM_RUNNER_VERBOSE:-0}" -ge "3" ]; then _log "$1" TRC; fi; } +debug() { if [ "${KRUNVM_RUNNER_VERBOSE:-0}" -ge "2" ]; then _log "$1" DBG; fi; } +verbose() { if [ "${KRUNVM_RUNNER_VERBOSE:-0}" -ge "1" ]; then _log "$1" NFO; fi; } +info() { if [ "${KRUNVM_RUNNER_VERBOSE:-0}" -ge "1" ]; then _log "$1" NFO; fi; } +warn() { _log "$1" WRN; } +error() { _log "$1" ERR && exit 1; } + diff --git a/runner/install.sh b/runner/install.sh index c2b5697..7dab8c2 100755 --- a/runner/install.sh +++ b/runner/install.sh @@ -3,6 +3,28 @@ # Shell sanity. Stop on errors and undefined variables. set -eu +# This is a readlink -f implementation so this script can (perhaps) run on MacOS +abspath() { + is_abspath() { + case "$1" in + /* | ~*) true;; + *) false;; + esac + } + + if [ -d "$1" ]; then + ( cd -P -- "$1" && pwd -P ) + elif [ -L "$1" ]; then + if is_abspath "$(readlink "$1")"; then + abspath "$(readlink "$1")" + else + abspath "$(dirname "$1")/$(readlink "$1")" + fi + else + printf %s\\n "$(abspath "$(dirname "$1")")/$(basename "$1")" + fi +} + # Level of verbosity, the higher the more verbose. All messages are sent to the # stderr. INSTALL_VERBOSE=${INSTALL_VERBOSE:-0} @@ -24,15 +46,15 @@ INSTALL_DIRECTORIES=${INSTALL_DIRECTORIES:-"/_work $INSTALL_TOOL_CACHE $INSTALL_ # User to change ownership of directories to INSTALL_USER=${INSTALL_USER:-runner} -usage() { - # This uses the comments behind the options to show the help. Not extremly - # correct, but effective and simple. - echo "$0 install the GitHub runner" && \ - grep "[[:space:]].)\ #" "$0" | - sed 's/#//' | - sed -r 's/([a-z-])\)/-\1/' - exit "${1:-0}" -} +# Resolve the root directory hosting this script to an absolute path, symbolic +# links resolved. +INSTALL_ROOTDIR=$( cd -P -- "$(dirname -- "$(command -v -- "$(abspath "$0")")")" && pwd -P ) + +# shellcheck source=../lib/common.sh +. "$INSTALL_ROOTDIR/../lib/common.sh" + +# shellcheck disable=SC2034 # Used in sourced scripts +KRUNVM_RUNNER_MAIN="Install the GitHub runner" while getopts "l:u:vh-" opt; do case "$opt" in @@ -52,20 +74,9 @@ while getopts "l:u:vh-" opt; do done shift $((OPTIND-1)) -# PML: Poor Man's Logging -_log() { - printf '[%s] [%s] [%s] %s\n' \ - "$(basename "$0")" \ - "${2:-LOG}" \ - "$(date +'%Y%m%d-%H%M%S')" \ - "${1:-}" \ - >&"$INSTALL_LOG" -} -trace() { if [ "${INSTALL_VERBOSE:-0}" -ge "3" ]; then _log "$1" TRC; fi; } -debug() { if [ "${INSTALL_VERBOSE:-0}" -ge "2" ]; then _log "$1" DBG; fi; } -verbose() { if [ "${INSTALL_VERBOSE:-0}" -ge "1" ]; then _log "$1" NFO; fi; } -warn() { _log "$1" WRN; } -error() { _log "$1" ERR && exit 1; } +# Pass logging configuration and level to imported scripts +KRUNVM_RUNNER_LOG=$INSTALL_LOG +KRUNVM_RUNNER_VERBOSE=$INSTALL_VERBOSE # Collect the version to install from the environment or the first argument. INSTALL_VERSION=${INSTALL_VERSION:-${1:-latest}} diff --git a/runner/runner.sh b/runner/runner.sh index bf2a20e..6d0661a 100755 --- a/runner/runner.sh +++ b/runner/runner.sh @@ -26,11 +26,6 @@ abspath() { fi } -# shellcheck disable=SC2120 # Function has good default. -random_string() { - LC_ALL=C tr -dc 'a-zA-Z0-9' < /dev/urandom | head -c "${1:-12}" -} - # Resolve the root directory hosting this script to an absolute path, symbolic # links resolved. RUNNER_ROOTDIR=$( cd -P -- "$(dirname -- "$(command -v -- "$(abspath "$0")")")" && pwd -P ) @@ -57,7 +52,7 @@ RUNNER_LABELS=${RUNNER_LABELS:-""} # Name of the user to run the runner as, defaults to root. User must exist. RUNNER_USER=${RUNNER_USER:-"root"} -# One of repo, org or enterprise +# Scope of the runner, one of: repo, org or enterprise RUNNER_SCOPE=${RUNNER_SCOPE:-"repo"} # Name of organisation, enterprise or repo to attach the runner to, when @@ -84,19 +79,14 @@ RUNNER_INSTALL=${RUNNER_INSTALL:-"/opt/actions-runner"} # Should the runner auto-update RUNNER_UPDATE=${RUNNER_UPDATE:-"0"} - RUNNER_TOOL_CACHE=${RUNNER_TOOL_CACHE:-"${AGENT_TOOLSDIRECTORY:-"/opt/hostedtoolcache"}"} +# shellcheck source=../lib/common.sh +. "$RUNNER_ROOTDIR/../lib/common.sh" + +# shellcheck disable=SC2034 # Used in sourced scripts +KRUNVM_RUNNER_MAIN="Configure and run the installed GitHub runner" -usage() { - # This uses the comments behind the options to show the help. Not extremly - # correct, but effective and simple. - echo "$0 configure and run the installed GitHub runner" && \ - grep "[[:space:]].) #" "$0" | - sed 's/#//' | - sed -r 's/([a-zA-Z-])\)/-\1/' - exit "${1:-0}" -} while getopts "eg:G:l:L:n:p:s:t:T:u:Uvh-" opt; do case "$opt" in @@ -136,36 +126,9 @@ while getopts "eg:G:l:L:n:p:s:t:T:u:Uvh-" opt; do done shift $((OPTIND-1)) -# PML: Poor Man's Logging -_log() { - printf '[%s] [%s] [%s] %s\n' \ - "$(basename "$0")" \ - "${2:-LOG}" \ - "$(date +'%Y%m%d-%H%M%S')" \ - "${1:-}" \ - >&"$RUNNER_LOG" -} -trace() { if [ "${RUNNER_VERBOSE:-0}" -ge "3" ]; then _log "$1" TRC; fi; } -debug() { if [ "${RUNNER_VERBOSE:-0}" -ge "2" ]; then _log "$1" DBG; fi; } -verbose() { if [ "${RUNNER_VERBOSE:-0}" -ge "1" ]; then _log "$1" NFO; fi; } -warn() { _log "$1" WRN; } -error() { _log "$1" ERR && exit 1; } - -# shellcheck disable=SC2120 # Take none or one argument -to_lower() { - if [ -z "${1:-}" ]; then - tr '[:upper:]' '[:lower:]' - else - printf %s\\n "$1" | to_lower - fi -} - -is_true() { - case "$(to_lower "${1:-}")" in - 1 | true | yes | y | on | t) return 0;; - *) return 1;; - esac -} +# Pass logging configuration and level to imported scripts +KRUNVM_RUNNER_LOG=$RUNNER_LOG +KRUNVM_RUNNER_VERBOSE=$RUNNER_VERBOSE configure() { verbose "Registering $RUNNER_SCOPE runner '$RUNNER_NAME' for $RUNNER_URL" @@ -231,20 +194,6 @@ unregister() { } -# Find the executable passed as an argument in the PATH variable and print it. -find_exec() { - while IFS= read -r dir; do - if [ -n "${dir}" ] && [ -d "${dir}" ]; then - if [ -x "${dir%/}/$1" ] && [ "${dir%/}/$1" != "$(abspath "$0")" ]; then - printf %s\\n "${dir%/}/$1" - break - fi - fi - done </dev/null 2>&1; then diff --git a/runner/token.sh b/runner/token.sh index 8ca17b9..d783c48 100755 --- a/runner/token.sh +++ b/runner/token.sh @@ -3,6 +3,32 @@ # Shell sanity. Stop on errors and undefined variables. set -eu +# This is a readlink -f implementation so this script can (perhaps) run on MacOS +abspath() { + is_abspath() { + case "$1" in + /* | ~*) true;; + *) false;; + esac + } + + if [ -d "$1" ]; then + ( cd -P -- "$1" && pwd -P ) + elif [ -L "$1" ]; then + if is_abspath "$(readlink "$1")"; then + abspath "$(readlink "$1")" + else + abspath "$(dirname "$1")/$(readlink "$1")" + fi + else + printf %s\\n "$(abspath "$(dirname "$1")")/$(basename "$1")" + fi +} + +# Resolve the root directory hosting this script to an absolute path, symbolic +# links resolved. +TOKEN_ROOTDIR=$( cd -P -- "$(dirname -- "$(command -v -- "$(abspath "$0")")")" && pwd -P ) + # Level of verbosity, the higher the more verbose. All messages are sent to the # stderr. TOKEN_VERBOSE=${TOKEN_VERBOSE:-0} @@ -10,27 +36,27 @@ TOKEN_VERBOSE=${TOKEN_VERBOSE:-0} # Where to send logs TOKEN_LOG=${TOKEN_LOG:-2} +# GitHub host, e.g. github.com or github.example.com TOKEN_GITHUB=${TOKEN_GITHUB:-"github.com"} +# Version of the GitHub API to use TOKEN_API_VERSION=${TOKEN_API_VERSION:-"v3"} +# PAT to acquire the runner token with TOKEN_PAT=${TOKEN_PAT:-""} +# Scope of the runner, one of: repo, org or enterprise TOKEN_SCOPE=${TOKEN_SCOPE:-"repo"} # Name of organisation, enterprise or repo to attach the runner to, when # relevant scope. TOKEN_PRINCIPAL=${TOKEN_PRINCIPAL:-""} -usage() { - # This uses the comments behind the options to show the help. Not extremly - # correct, but effective and simple. - echo "$0 install the GitHub runner" && \ - grep "[[:space:]].) #" "$0" | - sed 's/#//' | - sed -r 's/([a-zA-Z-])\)/-\1/' - exit "${1:-0}" -} +# shellcheck source=../lib/common.sh +. "$TOKEN_ROOTDIR/../lib/common.sh" + +# shellcheck disable=SC2034 # Used in sourced scripts +KRUNVM_RUNNER_MAIN="Acquire a runner token from GitHub API" while getopts "g:l:p:s:T:vh-" opt; do case "$opt" in @@ -56,20 +82,9 @@ while getopts "g:l:p:s:T:vh-" opt; do done shift $((OPTIND-1)) -# PML: Poor Man's Logging -_log() { - printf '[%s] [%s] [%s] %s\n' \ - "$(basename "$0")" \ - "${2:-LOG}" \ - "$(date +'%Y%m%d-%H%M%S')" \ - "${1:-}" \ - >&"$TOKEN_LOG" -} -trace() { if [ "${TOKEN_VERBOSE:-0}" -ge "3" ]; then _log "$1" TRC; fi; } -debug() { if [ "${TOKEN_VERBOSE:-0}" -ge "2" ]; then _log "$1" DBG; fi; } -verbose() { if [ "${TOKEN_VERBOSE:-0}" -ge "1" ]; then _log "$1" NFO; fi; } -warn() { _log "$1" WRN; } -error() { _log "$1" ERR && exit 1; } +# Pass logging configuration and level to imported scripts +KRUNVM_RUNNER_LOG=$TOKEN_LOG +KRUNVM_RUNNER_VERBOSE=$TOKEN_VERBOSE if [ -z "$TOKEN_PRINCIPAL" ]; then error "Principal must be set to name of repo, org or enterprise"