fix: resolve 10 bugs across scripts
- manage_runner.sh: fix RUNNER_DEFAULT_IMAGE clobbering by renaming per-runner var to RUNNER_SECTION_IMAGE; .env fallback now works - manage_runner.sh: render native runner config.yaml before registration so act_runner can read it during --config flag - manage_runner.sh: add SSH credential validation for remote hosts (fail early with clear error instead of cryptic SSH failure) - phase1/phase2: add UNRAID_DB_IP/FEDORA_DB_IP to conditional require_vars when DB_TYPE != sqlite3 - cleanup.sh: only clear manifest when all actions for host succeeded; failed actions are preserved for retry - phase8_cutover.sh: strip empty environment: block from Caddy docker-compose when TLS_MODE=existing - phase5_migrate_pipelines.sh, phase5_teardown.sh, phase9_teardown.sh: wrap cd+git in subshells so working directory is always restored - phase3_post_check.sh: handle both string and numeric runner status from Gitea API (offline vs 2) - configure_env.sh: fix TOTAL_PROMPTS base count (63->64) and move DB/repo count adjustments before their prompts are shown Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -40,7 +40,7 @@ EOF
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Parse a runner entry from runners.conf (INI format) by section name.
|
# Parse a runner entry from runners.conf (INI format) by section name.
|
||||||
# Sets globals: RUNNER_NAME, RUNNER_HOST, RUNNER_TYPE, RUNNER_DATA_PATH,
|
# Sets globals: RUNNER_NAME, RUNNER_HOST, RUNNER_TYPE, RUNNER_DATA_PATH,
|
||||||
# RUNNER_LABELS, RUNNER_DEFAULT_IMAGE, RUNNER_REPOS, RUNNER_CAPACITY,
|
# RUNNER_LABELS, RUNNER_SECTION_IMAGE, RUNNER_REPOS, RUNNER_CAPACITY,
|
||||||
# RUNNER_CPU, RUNNER_MEMORY, RUNNER_BOOT
|
# RUNNER_CPU, RUNNER_MEMORY, RUNNER_BOOT
|
||||||
# Also resolves: RUNNER_SSH_HOST, RUNNER_SSH_USER, RUNNER_SSH_PORT,
|
# Also resolves: RUNNER_SSH_HOST, RUNNER_SSH_USER, RUNNER_SSH_PORT,
|
||||||
# RUNNER_SSH_KEY (from .env or custom section keys)
|
# RUNNER_SSH_KEY (from .env or custom section keys)
|
||||||
@@ -65,7 +65,7 @@ parse_runner_entry() {
|
|||||||
RUNNER_TYPE=$(ini_get "$RUNNERS_CONF" "$target_name" "type" "")
|
RUNNER_TYPE=$(ini_get "$RUNNERS_CONF" "$target_name" "type" "")
|
||||||
RUNNER_DATA_PATH=$(ini_get "$RUNNERS_CONF" "$target_name" "data_path" "")
|
RUNNER_DATA_PATH=$(ini_get "$RUNNERS_CONF" "$target_name" "data_path" "")
|
||||||
RUNNER_LABELS=$(ini_get "$RUNNERS_CONF" "$target_name" "labels" "")
|
RUNNER_LABELS=$(ini_get "$RUNNERS_CONF" "$target_name" "labels" "")
|
||||||
RUNNER_DEFAULT_IMAGE=$(ini_get "$RUNNERS_CONF" "$target_name" "default_image" "")
|
RUNNER_SECTION_IMAGE=$(ini_get "$RUNNERS_CONF" "$target_name" "default_image" "")
|
||||||
RUNNER_REPOS=$(ini_get "$RUNNERS_CONF" "$target_name" "repos" "all")
|
RUNNER_REPOS=$(ini_get "$RUNNERS_CONF" "$target_name" "repos" "all")
|
||||||
RUNNER_CAPACITY=$(ini_get "$RUNNERS_CONF" "$target_name" "capacity" "1")
|
RUNNER_CAPACITY=$(ini_get "$RUNNERS_CONF" "$target_name" "capacity" "1")
|
||||||
RUNNER_CPU=$(ini_get "$RUNNERS_CONF" "$target_name" "cpu" "")
|
RUNNER_CPU=$(ini_get "$RUNNERS_CONF" "$target_name" "cpu" "")
|
||||||
@@ -107,6 +107,18 @@ parse_runner_entry() {
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# --- Validate SSH credentials for remote hosts ---
|
||||||
|
if [[ "$RUNNER_SSH_HOST" != "local" ]]; then
|
||||||
|
if [[ -z "$RUNNER_SSH_HOST" ]]; then
|
||||||
|
log_error "Runner '$target_name': SSH host is empty (check .env for ${RUNNER_HOST^^}_IP)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [[ -z "$RUNNER_SSH_USER" ]]; then
|
||||||
|
log_error "Runner '$target_name': SSH user is empty (check .env for ${RUNNER_HOST^^}_SSH_USER)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# --- Validate required fields ---
|
# --- Validate required fields ---
|
||||||
if [[ -z "$RUNNER_TYPE" ]]; then
|
if [[ -z "$RUNNER_TYPE" ]]; then
|
||||||
log_error "Runner '$target_name': type is empty (must be docker or native)"
|
log_error "Runner '$target_name': type is empty (must be docker or native)"
|
||||||
@@ -137,9 +149,10 @@ parse_runner_entry() {
|
|||||||
# Sets RUNNER_RESOLVED_IMAGE.
|
# Sets RUNNER_RESOLVED_IMAGE.
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
resolve_runner_image() {
|
resolve_runner_image() {
|
||||||
local image="${RUNNER_DEFAULT_IMAGE:-}"
|
# Per-runner image from runners.conf takes priority, then .env global, then hardcoded fallback
|
||||||
|
local image="${RUNNER_SECTION_IMAGE:-${RUNNER_DEFAULT_IMAGE:-}}"
|
||||||
if [[ -z "$image" ]] && [[ "$RUNNER_TYPE" == "docker" ]]; then
|
if [[ -z "$image" ]] && [[ "$RUNNER_TYPE" == "docker" ]]; then
|
||||||
image="${RUNNER_DEFAULT_IMAGE:-catthehacker/ubuntu:act-latest}"
|
image="catthehacker/ubuntu:act-latest"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n "$image" ]] && [[ -n "${LOCAL_REGISTRY:-}" ]]; then
|
if [[ -n "$image" ]] && [[ -n "${LOCAL_REGISTRY:-}" ]]; then
|
||||||
@@ -384,6 +397,16 @@ add_native_runner() {
|
|||||||
log_success "act_runner binary downloaded"
|
log_success "act_runner binary downloaded"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Render runner config (must exist before registration — act_runner reads it)
|
||||||
|
local tmpfile
|
||||||
|
tmpfile=$(mktemp)
|
||||||
|
# shellcheck disable=SC2090 # intentional — RUNNER_LABELS_YAML rendered via envsubst
|
||||||
|
export RUNNER_NAME RUNNER_DATA_PATH RUNNER_LABELS_YAML RUNNER_CAPACITY
|
||||||
|
render_template "${SCRIPT_DIR}/templates/runner-config.yaml.tpl" "$tmpfile" \
|
||||||
|
"\${RUNNER_NAME} \${RUNNER_LABELS_YAML} \${RUNNER_CAPACITY}"
|
||||||
|
cp "$tmpfile" "${RUNNER_DATA_PATH}/config.yaml"
|
||||||
|
rm -f "$tmpfile"
|
||||||
|
|
||||||
# Register the runner with Gitea
|
# Register the runner with Gitea
|
||||||
if [[ ! -f "${RUNNER_DATA_PATH}/.runner" ]]; then
|
if [[ ! -f "${RUNNER_DATA_PATH}/.runner" ]]; then
|
||||||
log_info "Registering runner with Gitea..."
|
log_info "Registering runner with Gitea..."
|
||||||
@@ -397,16 +420,6 @@ add_native_runner() {
|
|||||||
log_success "Runner registered"
|
log_success "Runner registered"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Render runner config
|
|
||||||
local tmpfile
|
|
||||||
tmpfile=$(mktemp)
|
|
||||||
# shellcheck disable=SC2090 # intentional — RUNNER_LABELS_YAML rendered via envsubst
|
|
||||||
export RUNNER_NAME RUNNER_DATA_PATH RUNNER_LABELS_YAML RUNNER_CAPACITY
|
|
||||||
render_template "${SCRIPT_DIR}/templates/runner-config.yaml.tpl" "$tmpfile" \
|
|
||||||
"\${RUNNER_NAME} \${RUNNER_LABELS_YAML} \${RUNNER_CAPACITY}"
|
|
||||||
cp "$tmpfile" "${RUNNER_DATA_PATH}/config.yaml"
|
|
||||||
rm -f "$tmpfile"
|
|
||||||
|
|
||||||
# Render launchd plist.
|
# Render launchd plist.
|
||||||
# When boot=true, insert a <key>UserName</key> entry so the daemon runs as
|
# When boot=true, insert a <key>UserName</key> entry so the daemon runs as
|
||||||
# the deploying user instead of root (LaunchDaemons default to root).
|
# the deploying user instead of root (LaunchDaemons default to root).
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ require_vars UNRAID_IP UNRAID_SSH_USER UNRAID_SSH_PORT UNRAID_GITEA_DATA_PATH \
|
|||||||
GITEA_INTERNAL_URL GITEA_DOMAIN
|
GITEA_INTERNAL_URL GITEA_DOMAIN
|
||||||
|
|
||||||
if [[ "${GITEA_DB_TYPE}" != "sqlite3" ]]; then
|
if [[ "${GITEA_DB_TYPE}" != "sqlite3" ]]; then
|
||||||
require_vars GITEA_DB_HOST GITEA_DB_PORT GITEA_DB_NAME GITEA_DB_USER GITEA_DB_PASSWD
|
require_vars GITEA_DB_HOST GITEA_DB_PORT GITEA_DB_NAME GITEA_DB_USER GITEA_DB_PASSWD \
|
||||||
|
UNRAID_DB_IP
|
||||||
fi
|
fi
|
||||||
|
|
||||||
phase_header 1 "Gitea on Unraid"
|
phase_header 1 "Gitea on Unraid"
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ require_vars FEDORA_IP FEDORA_SSH_USER FEDORA_SSH_PORT FEDORA_GITEA_DATA_PATH \
|
|||||||
GITEA_BACKUP_INTERNAL_URL
|
GITEA_BACKUP_INTERNAL_URL
|
||||||
|
|
||||||
if [[ "${GITEA_DB_TYPE}" != "sqlite3" ]]; then
|
if [[ "${GITEA_DB_TYPE}" != "sqlite3" ]]; then
|
||||||
require_vars GITEA_DB_HOST GITEA_DB_PORT GITEA_DB_NAME GITEA_DB_USER GITEA_DB_PASSWD
|
require_vars GITEA_DB_HOST GITEA_DB_PORT GITEA_DB_NAME GITEA_DB_USER GITEA_DB_PASSWD \
|
||||||
|
FEDORA_DB_IP
|
||||||
fi
|
fi
|
||||||
|
|
||||||
phase_header 2 "Gitea on Fedora (Backup)"
|
phase_header 2 "Gitea on Fedora (Backup)"
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ while IFS= read -r name; do
|
|||||||
if [[ -z "$local_status" ]]; then
|
if [[ -z "$local_status" ]]; then
|
||||||
log_error "FAIL: Runner '${name}' not found in Gitea admin"
|
log_error "FAIL: Runner '${name}' not found in Gitea admin"
|
||||||
FAIL=$((FAIL + 1))
|
FAIL=$((FAIL + 1))
|
||||||
elif [[ "$local_status" == "offline" ]]; then
|
elif [[ "$local_status" == "offline" ]] || [[ "$local_status" == "2" ]]; then
|
||||||
log_error "FAIL: Runner '${name}' is registered but offline"
|
log_error "FAIL: Runner '${name}' is registered but offline"
|
||||||
FAIL=$((FAIL + 1))
|
FAIL=$((FAIL + 1))
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -158,13 +158,14 @@ for repo in "${REPOS[@]}"; do
|
|||||||
# Step 5: Commit and push
|
# Step 5: Commit and push
|
||||||
# Configure git user for the commit (required for fresh clones)
|
# Configure git user for the commit (required for fresh clones)
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
cd "$CLONE_DIR"
|
(
|
||||||
git config user.name "Gitea Migration"
|
cd "$CLONE_DIR"
|
||||||
git config user.email "migration@gitea.local"
|
git config user.name "Gitea Migration"
|
||||||
git add .gitea/
|
git config user.email "migration@gitea.local"
|
||||||
git commit -q -m "Migrate workflows to Gitea Actions"
|
git add .gitea/
|
||||||
git_with_auth git push -q origin HEAD
|
git commit -q -m "Migrate workflows to Gitea Actions"
|
||||||
cd "$SCRIPT_DIR"
|
git_with_auth git push -q origin HEAD
|
||||||
|
)
|
||||||
|
|
||||||
log_success "Workflows migrated for ${repo}"
|
log_success "Workflows migrated for ${repo}"
|
||||||
SUCCESS=$((SUCCESS + 1))
|
SUCCESS=$((SUCCESS + 1))
|
||||||
|
|||||||
@@ -78,13 +78,14 @@ for repo in "${REPOS[@]}"; do
|
|||||||
|
|
||||||
if [[ -d "${CLONE_DIR}/.gitea/workflows" ]]; then
|
if [[ -d "${CLONE_DIR}/.gitea/workflows" ]]; then
|
||||||
rm -rf "${CLONE_DIR}/.gitea/workflows"
|
rm -rf "${CLONE_DIR}/.gitea/workflows"
|
||||||
cd "$CLONE_DIR"
|
(
|
||||||
git config user.name "Gitea Migration"
|
cd "$CLONE_DIR"
|
||||||
git config user.email "migration@gitea.local"
|
git config user.name "Gitea Migration"
|
||||||
git add -A
|
git config user.email "migration@gitea.local"
|
||||||
git commit -q -m "Remove Gitea Actions workflows (teardown)"
|
git add -A
|
||||||
git_with_auth git push -q origin HEAD
|
git commit -q -m "Remove Gitea Actions workflows (teardown)"
|
||||||
cd "$SCRIPT_DIR"
|
git_with_auth git push -q origin HEAD
|
||||||
|
)
|
||||||
log_success "Removed .gitea/workflows/ from ${repo}"
|
log_success "Removed .gitea/workflows/ from ${repo}"
|
||||||
else
|
else
|
||||||
log_info ".gitea/workflows/ not found in clone — already clean"
|
log_info ".gitea/workflows/ not found in clone — already clean"
|
||||||
|
|||||||
@@ -188,6 +188,16 @@ else
|
|||||||
|
|
||||||
render_template "${SCRIPT_DIR}/templates/docker-compose-caddy.yml.tpl" "$TMPFILE" \
|
render_template "${SCRIPT_DIR}/templates/docker-compose-caddy.yml.tpl" "$TMPFILE" \
|
||||||
"\${CADDY_DATA_PATH} \${CADDY_CONTAINER_IP} \${CADDY_ENV_VARS} \${CADDY_EXTRA_VOLUMES}"
|
"\${CADDY_DATA_PATH} \${CADDY_CONTAINER_IP} \${CADDY_ENV_VARS} \${CADDY_EXTRA_VOLUMES}"
|
||||||
|
# Strip empty YAML blocks left when optional vars are blank
|
||||||
|
if [[ -z "$CADDY_ENV_VARS" ]]; then
|
||||||
|
sed -i.bak '/^[[:space:]]*environment:$/d' "$TMPFILE"
|
||||||
|
rm -f "${TMPFILE}.bak"
|
||||||
|
fi
|
||||||
|
if [[ -z "$CADDY_EXTRA_VOLUMES" ]]; then
|
||||||
|
# Remove trailing blank lines after the volumes block
|
||||||
|
sed -i.bak -e :a -e '/^\n*$/{$d;N;ba' -e '}' "$TMPFILE"
|
||||||
|
rm -f "${TMPFILE}.bak"
|
||||||
|
fi
|
||||||
scp_to UNRAID "$TMPFILE" "${CADDY_DATA_PATH}/docker-compose.yml"
|
scp_to UNRAID "$TMPFILE" "${CADDY_DATA_PATH}/docker-compose.yml"
|
||||||
rm -f "$TMPFILE"
|
rm -f "$TMPFILE"
|
||||||
log_success "Caddy docker-compose.yml deployed"
|
log_success "Caddy docker-compose.yml deployed"
|
||||||
|
|||||||
@@ -79,13 +79,14 @@ for repo in "${REPOS[@]}"; do
|
|||||||
|
|
||||||
if [[ -f "${CLONE_DIR}/.gitea/workflows/security-scan.yml" ]]; then
|
if [[ -f "${CLONE_DIR}/.gitea/workflows/security-scan.yml" ]]; then
|
||||||
rm -f "${CLONE_DIR}/.gitea/workflows/security-scan.yml"
|
rm -f "${CLONE_DIR}/.gitea/workflows/security-scan.yml"
|
||||||
cd "$CLONE_DIR"
|
(
|
||||||
git config user.name "Gitea Migration"
|
cd "$CLONE_DIR"
|
||||||
git config user.email "migration@gitea.local"
|
git config user.name "Gitea Migration"
|
||||||
git add -A
|
git config user.email "migration@gitea.local"
|
||||||
git commit -q -m "Remove security scanning workflow (teardown)"
|
git add -A
|
||||||
git_with_auth git push -q origin HEAD
|
git commit -q -m "Remove security scanning workflow (teardown)"
|
||||||
cd "$SCRIPT_DIR"
|
git_with_auth git push -q origin HEAD
|
||||||
|
)
|
||||||
log_success "Removed security-scan.yml from ${repo}"
|
log_success "Removed security-scan.yml from ${repo}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -214,6 +214,7 @@ for host in "${HOSTS[@]}"; do
|
|||||||
log_info "=== Cleaning up: ${host} ==="
|
log_info "=== Cleaning up: ${host} ==="
|
||||||
|
|
||||||
ssh_key=$(host_to_ssh_key "$host")
|
ssh_key=$(host_to_ssh_key "$host")
|
||||||
|
HOST_FAILED=0
|
||||||
|
|
||||||
# Read entries into array, then reverse (bash 3.2 compatible — no mapfile)
|
# Read entries into array, then reverse (bash 3.2 compatible — no mapfile)
|
||||||
entries=()
|
entries=()
|
||||||
@@ -237,99 +238,102 @@ for host in "${HOSTS[@]}"; do
|
|||||||
if cleanup_brew_pkg "$target"; then
|
if cleanup_brew_pkg "$target"; then
|
||||||
CLEANED=$((CLEANED + 1))
|
CLEANED=$((CLEANED + 1))
|
||||||
else
|
else
|
||||||
FAILED=$((FAILED + 1))
|
FAILED=$((FAILED + 1)); HOST_FAILED=$((HOST_FAILED + 1))
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
dnf_pkg)
|
dnf_pkg)
|
||||||
if [[ -z "$ssh_key" ]]; then
|
if [[ -z "$ssh_key" ]]; then
|
||||||
log_warn "Cannot clean up dnf_pkg '$target' — no SSH key for host '$host'"
|
log_warn "Cannot clean up dnf_pkg '$target' — no SSH key for host '$host'"
|
||||||
FAILED=$((FAILED + 1))
|
FAILED=$((FAILED + 1)); HOST_FAILED=$((HOST_FAILED + 1))
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
if cleanup_dnf_pkg "$ssh_key" "$target"; then
|
if cleanup_dnf_pkg "$ssh_key" "$target"; then
|
||||||
CLEANED=$((CLEANED + 1))
|
CLEANED=$((CLEANED + 1))
|
||||||
else
|
else
|
||||||
FAILED=$((FAILED + 1))
|
FAILED=$((FAILED + 1)); HOST_FAILED=$((HOST_FAILED + 1))
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
static_bin)
|
static_bin)
|
||||||
if [[ -z "$ssh_key" ]]; then
|
if [[ -z "$ssh_key" ]]; then
|
||||||
log_warn "Cannot clean up static_bin '$target' — no SSH key for host '$host'"
|
log_warn "Cannot clean up static_bin '$target' — no SSH key for host '$host'"
|
||||||
FAILED=$((FAILED + 1))
|
FAILED=$((FAILED + 1)); HOST_FAILED=$((HOST_FAILED + 1))
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
if cleanup_static_bin "$ssh_key" "$target"; then
|
if cleanup_static_bin "$ssh_key" "$target"; then
|
||||||
CLEANED=$((CLEANED + 1))
|
CLEANED=$((CLEANED + 1))
|
||||||
else
|
else
|
||||||
FAILED=$((FAILED + 1))
|
FAILED=$((FAILED + 1)); HOST_FAILED=$((HOST_FAILED + 1))
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
docker_group)
|
docker_group)
|
||||||
if [[ -z "$ssh_key" ]]; then
|
if [[ -z "$ssh_key" ]]; then
|
||||||
log_warn "Cannot clean up docker_group '$target' — no SSH key for host '$host'"
|
log_warn "Cannot clean up docker_group '$target' — no SSH key for host '$host'"
|
||||||
FAILED=$((FAILED + 1))
|
FAILED=$((FAILED + 1)); HOST_FAILED=$((HOST_FAILED + 1))
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
if cleanup_docker_group "$ssh_key" "$target"; then
|
if cleanup_docker_group "$ssh_key" "$target"; then
|
||||||
CLEANED=$((CLEANED + 1))
|
CLEANED=$((CLEANED + 1))
|
||||||
else
|
else
|
||||||
FAILED=$((FAILED + 1))
|
FAILED=$((FAILED + 1)); HOST_FAILED=$((HOST_FAILED + 1))
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
systemd_svc)
|
systemd_svc)
|
||||||
if [[ -z "$ssh_key" ]]; then
|
if [[ -z "$ssh_key" ]]; then
|
||||||
log_warn "Cannot clean up systemd_svc '$target' — no SSH key for host '$host'"
|
log_warn "Cannot clean up systemd_svc '$target' — no SSH key for host '$host'"
|
||||||
FAILED=$((FAILED + 1))
|
FAILED=$((FAILED + 1)); HOST_FAILED=$((HOST_FAILED + 1))
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
if cleanup_systemd_svc "$ssh_key" "$target"; then
|
if cleanup_systemd_svc "$ssh_key" "$target"; then
|
||||||
CLEANED=$((CLEANED + 1))
|
CLEANED=$((CLEANED + 1))
|
||||||
else
|
else
|
||||||
FAILED=$((FAILED + 1))
|
FAILED=$((FAILED + 1)); HOST_FAILED=$((HOST_FAILED + 1))
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
xcode_cli)
|
xcode_cli)
|
||||||
if cleanup_xcode_cli; then
|
if cleanup_xcode_cli; then
|
||||||
CLEANED=$((CLEANED + 1))
|
CLEANED=$((CLEANED + 1))
|
||||||
else
|
else
|
||||||
FAILED=$((FAILED + 1))
|
FAILED=$((FAILED + 1)); HOST_FAILED=$((HOST_FAILED + 1))
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
ssh_key)
|
ssh_key)
|
||||||
if [[ -z "$ssh_key" ]]; then
|
if [[ -z "$ssh_key" ]]; then
|
||||||
log_warn "Cannot clean up ssh_key '$target' — no SSH key for host '$host'"
|
log_warn "Cannot clean up ssh_key '$target' — no SSH key for host '$host'"
|
||||||
FAILED=$((FAILED + 1))
|
FAILED=$((FAILED + 1)); HOST_FAILED=$((HOST_FAILED + 1))
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
if cleanup_ssh_key "$ssh_key" "$target"; then
|
if cleanup_ssh_key "$ssh_key" "$target"; then
|
||||||
CLEANED=$((CLEANED + 1))
|
CLEANED=$((CLEANED + 1))
|
||||||
else
|
else
|
||||||
FAILED=$((FAILED + 1))
|
FAILED=$((FAILED + 1)); HOST_FAILED=$((HOST_FAILED + 1))
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
authorized_key)
|
authorized_key)
|
||||||
if [[ -z "$ssh_key" ]]; then
|
if [[ -z "$ssh_key" ]]; then
|
||||||
log_warn "Cannot clean up authorized_key '$target' — no SSH key for host '$host'"
|
log_warn "Cannot clean up authorized_key '$target' — no SSH key for host '$host'"
|
||||||
FAILED=$((FAILED + 1))
|
FAILED=$((FAILED + 1)); HOST_FAILED=$((HOST_FAILED + 1))
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
if cleanup_authorized_key "$ssh_key" "$target"; then
|
if cleanup_authorized_key "$ssh_key" "$target"; then
|
||||||
CLEANED=$((CLEANED + 1))
|
CLEANED=$((CLEANED + 1))
|
||||||
else
|
else
|
||||||
FAILED=$((FAILED + 1))
|
FAILED=$((FAILED + 1)); HOST_FAILED=$((HOST_FAILED + 1))
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
log_warn "Unknown action type '${action_type}' for target '${target}' — skipping"
|
log_warn "Unknown action type '${action_type}' for target '${target}' — skipping"
|
||||||
FAILED=$((FAILED + 1))
|
FAILED=$((FAILED + 1)); HOST_FAILED=$((HOST_FAILED + 1))
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
# Clear the manifest after successful cleanup (unless dry run)
|
# Only clear the manifest if all actions for this host succeeded.
|
||||||
if [[ "$DRY_RUN" == "false" ]]; then
|
# Failed actions remain in the manifest so they can be retried.
|
||||||
|
if [[ "$DRY_RUN" == "false" ]] && [[ "$HOST_FAILED" -eq 0 ]]; then
|
||||||
manifest_clear "$host"
|
manifest_clear "$host"
|
||||||
log_success "Manifest cleared for ${host}"
|
log_success "Manifest cleared for ${host}"
|
||||||
|
elif [[ "$DRY_RUN" == "false" ]] && [[ "$HOST_FAILED" -gt 0 ]]; then
|
||||||
|
log_warn "Manifest preserved for ${host} — ${HOST_FAILED} action(s) failed"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ get_env_val() {
|
|||||||
# Prompt function
|
# Prompt function
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Base prompt count (fixed prompts + TLS conditional slots — repo/DB prompts added dynamically)
|
# Base prompt count (fixed prompts + TLS conditional slots — repo/DB prompts added dynamically)
|
||||||
TOTAL_PROMPTS=63
|
TOTAL_PROMPTS=64
|
||||||
CURRENT_PROMPT=0
|
CURRENT_PROMPT=0
|
||||||
LAST_SECTION=""
|
LAST_SECTION=""
|
||||||
|
|
||||||
@@ -267,6 +267,8 @@ prompt_var "GITEA_DB_TYPE" "Database type (sqlite3, mysql, postgres, ms
|
|||||||
COLLECTED_DB_TYPE=$(get_env_val "GITEA_DB_TYPE" "sqlite3")
|
COLLECTED_DB_TYPE=$(get_env_val "GITEA_DB_TYPE" "sqlite3")
|
||||||
|
|
||||||
if [[ "$COLLECTED_DB_TYPE" != "sqlite3" ]]; then
|
if [[ "$COLLECTED_DB_TYPE" != "sqlite3" ]]; then
|
||||||
|
# Update total BEFORE showing DB prompts so progress counter is accurate
|
||||||
|
TOTAL_PROMPTS=$((TOTAL_PROMPTS + 5))
|
||||||
# Determine default port based on DB type
|
# Determine default port based on DB type
|
||||||
case "$COLLECTED_DB_TYPE" in
|
case "$COLLECTED_DB_TYPE" in
|
||||||
mysql) db_port_default="3306" ;;
|
mysql) db_port_default="3306" ;;
|
||||||
@@ -279,8 +281,6 @@ if [[ "$COLLECTED_DB_TYPE" != "sqlite3" ]]; then
|
|||||||
prompt_var "GITEA_DB_NAME" "Database name" nonempty "gitea" "DATABASE"
|
prompt_var "GITEA_DB_NAME" "Database name" nonempty "gitea" "DATABASE"
|
||||||
prompt_var "GITEA_DB_USER" "Database user" nonempty "gitea" "DATABASE"
|
prompt_var "GITEA_DB_USER" "Database user" nonempty "gitea" "DATABASE"
|
||||||
prompt_var "GITEA_DB_PASSWD" "Database password (min 8 chars)" password "" "DATABASE"
|
prompt_var "GITEA_DB_PASSWD" "Database password (min 8 chars)" password "" "DATABASE"
|
||||||
# Update total for the 5 DB prompts
|
|
||||||
TOTAL_PROMPTS=$((TOTAL_PROMPTS + 5))
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
prompt_var "GITEA_VERSION" "Gitea Docker image tag" nonempty "1.25" "GITEA SHARED CREDENTIALS"
|
prompt_var "GITEA_VERSION" "Gitea Docker image tag" nonempty "1.25" "GITEA SHARED CREDENTIALS"
|
||||||
@@ -312,6 +312,8 @@ if [[ -n "$EXISTING_REPOS" ]]; then
|
|||||||
EXISTING_COUNT=$#
|
EXISTING_COUNT=$#
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Account for the "how many" prompt itself
|
||||||
|
TOTAL_PROMPTS=$((TOTAL_PROMPTS + 1))
|
||||||
CURRENT_PROMPT=$((CURRENT_PROMPT + 1))
|
CURRENT_PROMPT=$((CURRENT_PROMPT + 1))
|
||||||
printf '%b[%d/~%d]%b How many repos to migrate? %b[%s]%b: ' "$C_DIM" "$CURRENT_PROMPT" "$TOTAL_PROMPTS" "$C_RESET" "$C_YELLOW" "${EXISTING_COUNT:-3}" "$C_RESET"
|
printf '%b[%d/~%d]%b How many repos to migrate? %b[%s]%b: ' "$C_DIM" "$CURRENT_PROMPT" "$TOTAL_PROMPTS" "$C_RESET" "$C_YELLOW" "${EXISTING_COUNT:-3}" "$C_RESET"
|
||||||
read -r REPO_COUNT
|
read -r REPO_COUNT
|
||||||
@@ -321,8 +323,8 @@ while ! [[ "$REPO_COUNT" =~ ^[1-9][0-9]*$ ]]; do
|
|||||||
printf 'How many repos to migrate? '
|
printf 'How many repos to migrate? '
|
||||||
read -r REPO_COUNT
|
read -r REPO_COUNT
|
||||||
done
|
done
|
||||||
# Update total now that we know how many repos
|
# Now that we know repo count, add them to total
|
||||||
TOTAL_PROMPTS=$((TOTAL_PROMPTS + 1 + REPO_COUNT))
|
TOTAL_PROMPTS=$((TOTAL_PROMPTS + REPO_COUNT))
|
||||||
|
|
||||||
# Collect repo names
|
# Collect repo names
|
||||||
COLLECTED_REPOS=""
|
COLLECTED_REPOS=""
|
||||||
|
|||||||
Reference in New Issue
Block a user