285 lines
7.2 KiB
Bash
285 lines
7.2 KiB
Bash
#!/bin/bash
|
|
|
|
INSTALL_PATH="/data/bin/act_runner"
|
|
SYSTEM_PATH="/usr/local/bin/act_runner"
|
|
RUNNER_INDEX_URL="${RUNNER_INDEX_URL:-https://dl.gitea.com/act_runner/}"
|
|
|
|
print_usage() {
|
|
cat <<'EOF'
|
|
Usage: /data/upgrade.sh [options]
|
|
|
|
Upgrade act_runner without re-registering existing runners.
|
|
|
|
Options:
|
|
--version <version> Upgrade to a specific version instead of auto-detecting latest
|
|
--arch <arch> Override detected architecture: amd64, arm64, arm-7
|
|
--runner <name> Restart only the specified runner (can be used multiple times)
|
|
-y, --yes Skip confirmation prompt
|
|
-h, --help Show this help message
|
|
EOF
|
|
}
|
|
|
|
log() {
|
|
echo "$@"
|
|
}
|
|
|
|
fail() {
|
|
echo "✗ $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
extract_version_number() {
|
|
sed -nE 's/.*version[[:space:]]+([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' | head -n 1
|
|
}
|
|
|
|
extract_versions_from_listing() {
|
|
grep -oE '/act_runner/[0-9]+\.[0-9]+\.[0-9]+/' | \
|
|
sed -E 's#^/act_runner/([0-9]+\.[0-9]+\.[0-9]+)/$#\1#' | \
|
|
awk '!seen[$0]++'
|
|
}
|
|
|
|
pick_latest_version() {
|
|
awk 'NF' | sort -V | tail -n 1
|
|
}
|
|
|
|
fetch_latest_version() {
|
|
curl -fsSL "${RUNNER_INDEX_URL}" | extract_versions_from_listing | pick_latest_version
|
|
}
|
|
|
|
resolve_latest_version_or_fallback() {
|
|
local fallback_version=$1
|
|
local fetcher_cmd=${2:-fetch_latest_version}
|
|
local detected_version=""
|
|
|
|
if command -v "${fetcher_cmd}" >/dev/null 2>&1; then
|
|
detected_version=$("${fetcher_cmd}" 2>/dev/null || true)
|
|
fi
|
|
|
|
if [ -n "${detected_version}" ] && validate_version "${detected_version}"; then
|
|
echo "${detected_version}"
|
|
else
|
|
echo "${fallback_version}"
|
|
fi
|
|
}
|
|
|
|
validate_version() {
|
|
local version=$1
|
|
|
|
[[ "${version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]
|
|
}
|
|
|
|
detect_runner_arch() {
|
|
local arch
|
|
arch=$(uname -m)
|
|
|
|
case "${arch}" in
|
|
x86_64)
|
|
echo "amd64"
|
|
;;
|
|
aarch64|arm64)
|
|
echo "arm64"
|
|
;;
|
|
armv7l)
|
|
echo "arm-7"
|
|
;;
|
|
*)
|
|
fail "Unsupported architecture: ${arch}"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
get_installed_version() {
|
|
local output=""
|
|
|
|
if [ -x "${INSTALL_PATH}" ]; then
|
|
output=$("${INSTALL_PATH}" --version 2>/dev/null || true)
|
|
elif command -v act_runner >/dev/null 2>&1; then
|
|
output=$(act_runner --version 2>/dev/null || true)
|
|
fi
|
|
|
|
if [ -n "${output}" ]; then
|
|
extract_version_number <<<"${output}"
|
|
fi
|
|
}
|
|
|
|
list_registered_runners() {
|
|
local runner_dir
|
|
|
|
if [ ! -d "/data/runners" ]; then
|
|
return 0
|
|
fi
|
|
|
|
for runner_dir in /data/runners/*/; do
|
|
if [ -d "${runner_dir}" ] && [ -f "${runner_dir}/.runner" ]; then
|
|
basename "${runner_dir}"
|
|
fi
|
|
done
|
|
}
|
|
|
|
build_download_url() {
|
|
local version=$1
|
|
local arch=$2
|
|
|
|
echo "https://dl.gitea.com/act_runner/${version}/act_runner-${version}-linux-${arch}"
|
|
}
|
|
|
|
confirm_or_exit() {
|
|
local auto_confirm=$1
|
|
|
|
if [ "${auto_confirm}" = "true" ]; then
|
|
return 0
|
|
fi
|
|
|
|
read -p "Proceed with upgrade? (y/N): " -n 1 -r
|
|
echo
|
|
if [[ ! "${REPLY}" =~ ^[Yy]$ ]]; then
|
|
echo "Upgrade cancelled."
|
|
exit 0
|
|
fi
|
|
}
|
|
|
|
download_and_install() {
|
|
local version=$1
|
|
local arch=$2
|
|
local url
|
|
local tmp_path
|
|
local downloaded_version
|
|
|
|
mkdir -p "$(dirname "${INSTALL_PATH}")"
|
|
url=$(build_download_url "${version}" "${arch}")
|
|
tmp_path=$(mktemp "${INSTALL_PATH}.tmp.XXXXXX")
|
|
|
|
trap 'rm -f "${tmp_path}"' EXIT
|
|
|
|
log "Downloading ${url}"
|
|
curl -fL "${url}" -o "${tmp_path}"
|
|
chmod +x "${tmp_path}"
|
|
|
|
downloaded_version=$("${tmp_path}" --version 2>/dev/null | extract_version_number)
|
|
if [ "${downloaded_version}" != "${version}" ]; then
|
|
fail "Downloaded binary version mismatch: expected ${version}, got ${downloaded_version:-unknown}"
|
|
fi
|
|
|
|
mv "${tmp_path}" "${INSTALL_PATH}"
|
|
ln -sf "${INSTALL_PATH}" "${SYSTEM_PATH}"
|
|
trap - EXIT
|
|
}
|
|
|
|
restart_runner_process() {
|
|
local runner_name=$1
|
|
|
|
if ! command -v supervisorctl >/dev/null 2>&1; then
|
|
log "⚠ supervisorctl not found, please restart the container manually."
|
|
return 1
|
|
fi
|
|
|
|
log "Restarting runner '${runner_name}'..."
|
|
supervisorctl restart "runner-${runner_name}"
|
|
}
|
|
|
|
restart_selected_runners() {
|
|
local requested_runners=("$@")
|
|
local runner_names=()
|
|
local runner_name
|
|
|
|
if [ "${#requested_runners[@]}" -gt 0 ]; then
|
|
runner_names=("${requested_runners[@]}")
|
|
else
|
|
while IFS= read -r runner_name; do
|
|
[ -n "${runner_name}" ] && runner_names+=("${runner_name}")
|
|
done < <(list_registered_runners)
|
|
fi
|
|
|
|
if [ "${#runner_names[@]}" -eq 0 ]; then
|
|
log "No registered runners found. Binary upgraded, no process restart needed."
|
|
return 0
|
|
fi
|
|
|
|
for runner_name in "${runner_names[@]}"; do
|
|
restart_runner_process "${runner_name}"
|
|
done
|
|
}
|
|
|
|
main() {
|
|
local target_version=""
|
|
local target_arch=""
|
|
local auto_confirm="false"
|
|
local current_version=""
|
|
local runner_names=()
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--version)
|
|
[ $# -ge 2 ] || fail "--version requires a value"
|
|
target_version=$2
|
|
shift 2
|
|
;;
|
|
--arch)
|
|
[ $# -ge 2 ] || fail "--arch requires a value"
|
|
target_arch=$2
|
|
shift 2
|
|
;;
|
|
--runner)
|
|
[ $# -ge 2 ] || fail "--runner requires a value"
|
|
runner_names+=("$2")
|
|
shift 2
|
|
;;
|
|
-y|--yes)
|
|
auto_confirm="true"
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
print_usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
fail "Unknown option: $1"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
current_version=$(get_installed_version || true)
|
|
|
|
if [ -z "${target_version}" ]; then
|
|
log "Fetching latest act_runner version from ${RUNNER_INDEX_URL}"
|
|
target_version=$(fetch_latest_version)
|
|
[ -n "${target_version}" ] || fail "Unable to detect the latest act_runner version"
|
|
fi
|
|
|
|
validate_version "${target_version}" || fail "Invalid version: ${target_version}"
|
|
|
|
if [ -z "${target_arch}" ]; then
|
|
target_arch=$(detect_runner_arch)
|
|
fi
|
|
|
|
if [ -n "${current_version}" ] && [ "${current_version}" = "${target_version}" ]; then
|
|
log "act_runner is already at the latest version: ${current_version}"
|
|
exit 0
|
|
fi
|
|
|
|
log "Upgrade summary:"
|
|
log " Current version: ${current_version:-not installed}"
|
|
log " Target version: ${target_version}"
|
|
log " Architecture: ${target_arch}"
|
|
log " Install path: ${INSTALL_PATH}"
|
|
if [ "${#runner_names[@]}" -gt 0 ]; then
|
|
log " Restart target: ${runner_names[*]}"
|
|
else
|
|
log " Restart target: all registered runners"
|
|
fi
|
|
echo
|
|
|
|
confirm_or_exit "${auto_confirm}"
|
|
download_and_install "${target_version}" "${target_arch}"
|
|
restart_selected_runners "${runner_names[@]}"
|
|
|
|
log
|
|
log "✓ act_runner upgraded successfully"
|
|
log " Installed version: $(get_installed_version || echo unknown)"
|
|
}
|
|
|
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
set -euo pipefail
|
|
main "$@"
|
|
fi
|