cp "\$SSH_KEY" "${JENKINS_GIT_KEY_FILE}"
chmod 600 "${JENKINS_GIT_KEY_FILE}"
+ # Set GIT_SSH_COMMAND to use the per-node Jenkins git key during prepare_env
+
export GIT_SSH_COMMAND="ssh -i ${JENKINS_GIT_KEY_FILE} -o StrictHostKeyChecking=no"
bash builder-reimage/build/prepare_env.sh \
passwordVariable: 'JOB_BUILDER_PASS'
)
]) {
+
+ // If Ansible SSH/connectivity failed after reimage, do not restore
+ // the Jenkins node state. The node may be unreachable or only
+ // partially configured, so keep it offline for manual investigation.
+
withEnv([
"SYNC_MACHINE=${machine}",
"SYNC_TARGET_FQDN=${TARGET_FQDN}",
- "SYNC_STATE_FILE=${JENKINS_NODE_STATE_FILE}"
+ "SYNC_STATE_FILE=${JENKINS_NODE_STATE_FILE}",
+ "SYNC_CONNECTIVITY_FAILED_FILE=${WORK_DIR}/ansible-connectivity-failed"
]) {
sh '''#!/bin/bash
set +e
+ if [ -f "$SYNC_CONNECTIVITY_FAILED_FILE" ]; then
+ echo "[WARN] Skipping Jenkins node restore for $SYNC_MACHINE because Ansible connectivity failed after reimage"
+ echo "[WARN] Keeping node offline for manual investigation"
+ exit 0
+ fi
+
echo "[INFO] Restoring Jenkins node state for $SYNC_MACHINE"
python3 builder-reimage/build/jenkins_node_control.py \
mkdir -p "${LOG_DIR}"
+CONNECTIVITY_FAILED_FILE="${WORK_DIR}/ansible-connectivity-failed"
+CONNECTIVITY_LOG="${LOG_DIR}/${TARGET_FQDN}-wait-online.log"
+
+rm -f "${CONNECTIVITY_FAILED_FILE}"
+
# Activate virtualenv if present
if [[ -f "${WORK_DIR}/${VENV_DIR}/bin/activate" ]]; then
echo "[ansible_runner] Activating venv: ${WORK_DIR}/${VENV_DIR}"
echo "[ansible_runner] Using inventory = ${INVENTORY_PATH}"
echo "[ansible_runner] Using secrets = ${SECRETS_PATH}"
+# Wait until the reimaged node is reachable by Ansible.
+# MAAS may mark the node as deployed before SSH/cloud-init is fully ready.
+# This prevents playbooks from starting too early and failing with connection errors.
+wait_for_ansible_connectivity() {
+ local attempts=0
+ local max_attempts=40
+ local interval=15
+
+ echo "[ansible_runner] Waiting for SSH/Ansible connectivity on ${TARGET_FQDN}"
+
+ until [[ $attempts -ge $max_attempts ]]; do
+ attempts=$((attempts + 1))
+
+ # Use Ansible ping to confirm SSH access and remote Python readiness.
+ ANSIBLE_HOST_KEY_CHECKING=False ansible all \
+ -i "${INVENTORY_PATH}" \
+ --limit "${TARGET_FQDN}" \
+ -m ping \
+ -e "ansible_ssh_user=${SSH_USER}" \
+ > "${CONNECTIVITY_LOG}" 2>&1
+
+ rc=$?
+
+ if [[ $rc -eq 0 ]]; then
+ echo "[ansible_runner] ${TARGET_FQDN} is reachable by Ansible"
+ return 0
+ fi
+
+ # Node is deployed but not ready yet, retry after a short wait.
+ echo "[ansible_runner] ${TARGET_FQDN} not ready yet, attempt ${attempts}/${max_attempts}"
+ tail -n 10 "${CONNECTIVITY_LOG}" || true
+
+ sleep "${interval}"
+ done
+
+ # Fail clearly if the node never becomes reachable after deployment.
+ echo "[ansible_runner] ERROR: ${TARGET_FQDN} did not become reachable by Ansible"
+ echo "[ansible_runner] Last connectivity check output:"
+ cat "${CONNECTIVITY_LOG}" || true
+
+ touch "${CONNECTIVITY_FAILED_FILE}"
+ return 1
+}
+
# Admin user JSON builder
ADMIN_USERS=(
"akraitma"
done
}
+# Ensure the node is actually reachable before running post-reimage playbooks.
+if ! wait_for_ansible_connectivity; then
+ FAILED_PLAYBOOKS+=("precheck-ansible-connectivity")
+ FAILED_LOGS+=("${CONNECTIVITY_LOG}")
+else
+
##############################################
# PLAYBOOK 1 — ansible_managed.yml
##############################################
FAILED_LOGS+=("${LOG_DIR}/${TARGET_FQDN}-play6-main-builder.log")
fi
+fi
+
echo "========================================"
echo "[ansible_runner] FINAL EXECUTION SUMMARY"
echo "========================================"