diff --git a/manage_runner.sh b/manage_runner.sh index a3a80bf..310bf80 100755 --- a/manage_runner.sh +++ b/manage_runner.sh @@ -128,6 +128,14 @@ parse_runner_entry() { log_error "Runner '$target_name': type='$RUNNER_TYPE' (must be docker or native)" return 1 fi + if [[ "$RUNNER_HOST" == "local" ]] && [[ "$RUNNER_TYPE" != "native" ]]; then + log_error "Runner '$target_name': invalid combo host='$RUNNER_HOST' type='$RUNNER_TYPE' (host=local requires type=native)" + return 1 + fi + if [[ "$RUNNER_HOST" != "local" ]] && [[ "$RUNNER_TYPE" != "docker" ]]; then + log_error "Runner '$target_name': invalid combo host='$RUNNER_HOST' type='$RUNNER_TYPE' (host=${RUNNER_HOST} requires type=docker)" + return 1 + fi if [[ -z "$RUNNER_DATA_PATH" ]]; then log_error "Runner '$target_name': data_path is empty" return 1 @@ -475,12 +483,30 @@ remove_docker_runner() { log_info "Removing Docker runner '${RUNNER_NAME}' from ${RUNNER_HOST} (${RUNNER_SSH_HOST})..." if runner_ssh "test -f '${RUNNER_DATA_PATH}/docker-compose.yml'" 2>/dev/null; then - runner_ssh "cd '${RUNNER_DATA_PATH}' && docker compose down 2>/dev/null || docker-compose down" || true - # Remove docker-compose.yml — it contains the registration token in plaintext - runner_ssh "rm -f '${RUNNER_DATA_PATH}/docker-compose.yml'" 2>/dev/null || true - log_success "Docker runner '${RUNNER_NAME}' stopped and compose file removed" + if runner_ssh "cd '${RUNNER_DATA_PATH}' && docker compose down 2>/dev/null || docker-compose down"; then + # Remove docker-compose.yml only after successful stop. + # It contains the registration token in plaintext. + runner_ssh "rm -f '${RUNNER_DATA_PATH}/docker-compose.yml'" 2>/dev/null || true + log_success "Docker runner '${RUNNER_NAME}' stopped and compose file removed" + else + log_error "Failed to stop Docker runner '${RUNNER_NAME}' — preserving compose file for retry" + return 1 + fi else - log_info "No docker-compose.yml found for runner '${RUNNER_NAME}' — already removed" + # Backward-safe cleanup: if compose file was removed manually but the container + # still exists, force-remove the orphaned container by exact name. + local orphan_id + orphan_id=$(runner_ssh "docker ps -a --filter 'name=^/gitea-runner-${RUNNER_NAME}$' --format '{{.ID}}'" 2>/dev/null || true) + if [[ -n "$orphan_id" ]]; then + if runner_ssh "docker rm -f 'gitea-runner-${RUNNER_NAME}'" >/dev/null 2>&1; then + log_warn "docker-compose.yml missing; removed orphaned container gitea-runner-${RUNNER_NAME}" + else + log_error "docker-compose.yml missing and failed to remove orphaned container gitea-runner-${RUNNER_NAME}" + return 1 + fi + else + log_info "No docker-compose.yml found for runner '${RUNNER_NAME}' — already removed" + fi fi }