This commit is contained in:
@@ -0,0 +1,284 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user