diff --git a/backends/fedora/backend.sh b/backends/fedora/backend.sh index 93ea909..440fe85 100755 --- a/backends/fedora/backend.sh +++ b/backends/fedora/backend.sh @@ -67,6 +67,7 @@ backend_validate() { backend_generate_config() { local hostname + local device_id local disk_encryption local partitioning local secure_boot_required @@ -80,6 +81,10 @@ backend_generate_config() { [[ -n "${hostname}" ]] || { backend_fatal "Kein Hostname in der Serverantwort gefunden."; return 1; } + device_id="$(jq --raw-output '.device.id // empty' "${SERVER_RESPONSE_FILE}")" + [[ -n "${device_id}" ]] || + { backend_fatal "Keine Geräte-ID in der Serverantwort gefunden."; return 1; } + disk_encryption="$(jq --raw-output '.runtime_blueprint.installation_directives.disk_encryption' "${RUNTIME_BLUEPRINT_FILE}")" partitioning="$(jq --raw-output '.runtime_blueprint.installation_directives.partitioning' "${RUNTIME_BLUEPRINT_FILE}")" secure_boot_required="$(jq --raw-output '.runtime_blueprint.installation_directives.secure_boot_required' "${RUNTIME_BLUEPRINT_FILE}")" @@ -105,9 +110,10 @@ backend_generate_config() { blueprints_json="$(jq --compact-output '.runtime_blueprint.blueprints' "${RUNTIME_BLUEPRINT_FILE}")" TUXFLOTTE_HOSTNAME="${hostname}" \ + TUXFLOTTE_DEVICE_ID="${device_id}" \ TUXFLOTTE_PARTITIONING_COMMAND="${partitioning_command}" \ TUXFLOTTE_BLUEPRINTS_JSON="${blueprints_json}" \ - envsubst '${TUXFLOTTE_HOSTNAME} ${TUXFLOTTE_PARTITIONING_COMMAND} ${TUXFLOTTE_BLUEPRINTS_JSON}' \ + envsubst '${TUXFLOTTE_HOSTNAME} ${TUXFLOTTE_DEVICE_ID} ${TUXFLOTTE_PARTITIONING_COMMAND} ${TUXFLOTTE_BLUEPRINTS_JSON}' \ <"${KICKSTART_TEMPLATE}" >"${CONFIG_FILE}" chmod 0600 "${CONFIG_FILE}" @@ -129,5 +135,5 @@ backend_launch() { } backend_postinstall() { - backend_log "Phase 1: Vorbereitung des Provisioning-Agent erfolgt bereits im %post-Abschnitt der Kickstart-Konfiguration." + backend_log "Provisioning-Agent-Einrichtung erfolgt im %post-Abschnitt der Kickstart-Konfiguration (Agent-Abruf, Bootstrap-Registrierung, systemd-Aktivierung)." } diff --git a/backends/fedora/kickstart.tpl b/backends/fedora/kickstart.tpl index f10f3cc..9796996 100644 --- a/backends/fedora/kickstart.tpl +++ b/backends/fedora/kickstart.tpl @@ -28,10 +28,11 @@ bootloader --location=mbr vim curl git +jq ansible-core %end -%post +%post --erroronfail --interpreter=/bin/bash cat > /etc/motd <<'EOF' Provisioned by tuxflotte @@ -42,14 +43,64 @@ localectl set-locale LANG=de_DE.UTF-8 localectl set-keymap de localectl set-x11-keymap de -mkdir -p /etc/tuxflotte +install -d -m 0700 /etc/tuxflotte cat > /etc/tuxflotte/runtime_blueprint.json <<'RUNTIME_BLUEPRINT_EOF' ${TUXFLOTTE_BLUEPRINTS_JSON} RUNTIME_BLUEPRINT_EOF -# Der Provisioning Agent existiert noch nicht als Build-Artefakt. -# Anwendung der obigen Blueprints per Ansible-Pull erfolgt erst nach dessen Implementierung. +# Provisioning Agent einrichten (backend_postinstall). Vorbereitung vor dem +# ersten Reboot: Agent-Code holen, beim Provisioning-Server registrieren und +# den Dienst für den ersten Boot aktivieren. Gestartet wird er erst danach, +# durch systemd selbst (siehe provisioning-agent/README.md). +# +# Bewusst ohne globales `set -e`: vorangehende Schritte wie +# `localectl set-x11-keymap` schlagen in der %post-Chroot best-effort fehl +# (kein laufendes systemd/D-Bus) und sollen die Installation nicht abbrechen. +# Der Agent-Block unten prüft deshalb jeden kritischen Schritt einzeln. +tuxflotte_agent_fatal() { + echo "tuxflotte: Provisioning-Agent-Einrichtung fehlgeschlagen: $*" >> /var/log/tuxflotte-postinstall.log + exit 1 +} + +ANODE_URL="https://anode.tuxflotte.de" +AGENT_REPO_RAW="https://git.tuxflotte.de/admin/provisioning-agent/raw/branch/main" + +install -d /opt/tuxflotte/agent || + tuxflotte_agent_fatal "Verzeichnis /opt/tuxflotte/agent konnte nicht angelegt werden." + +curl --silent --show-error --fail --location \ + --output /opt/tuxflotte/agent/agent.py \ + "${AGENT_REPO_RAW}/agent.py" || + tuxflotte_agent_fatal "agent.py konnte nicht von ${AGENT_REPO_RAW} geladen werden." + +curl --silent --show-error --fail --location \ + --output /etc/systemd/system/tuxflotte-agent.service \ + "${AGENT_REPO_RAW}/tuxflotte-agent.service" || + tuxflotte_agent_fatal "tuxflotte-agent.service konnte nicht von ${AGENT_REPO_RAW} geladen werden." + +AGENT_BOOTSTRAP_RESPONSE="$( + curl --silent --show-error --fail --location \ + --header 'Content-Type: application/json' \ + --data-binary "{\"device_id\": \"${TUXFLOTTE_DEVICE_ID}\"}" \ + "${ANODE_URL}/api/v1/agent/bootstrap" +)" || + tuxflotte_agent_fatal "Bootstrap-Aufruf gegen ${ANODE_URL} ist fehlgeschlagen." + +jq --exit-status '.success == true' <<<"${AGENT_BOOTSTRAP_RESPONSE}" >/dev/null || + tuxflotte_agent_fatal "Server hat den Bootstrap abgelehnt: ${AGENT_BOOTSTRAP_RESPONSE}" + +jq --null-input \ + --arg device_id "${TUXFLOTTE_DEVICE_ID}" \ + --argjson response "${AGENT_BOOTSTRAP_RESPONSE}" \ + '{device_id: $device_id, agent_secret: $response.agent_secret}' \ + > /etc/tuxflotte/agent.credentials || + tuxflotte_agent_fatal "Credentials-Datei konnte nicht erzeugt werden." +chmod 0600 /etc/tuxflotte/agent.credentials + +systemctl enable tuxflotte-agent.service || + tuxflotte_agent_fatal "systemd-Dienst tuxflotte-agent konnte nicht aktiviert werden." + echo "tuxflotte: Runtime Blueprint unter /etc/tuxflotte/runtime_blueprint.json hinterlegt." >> /var/log/tuxflotte-postinstall.log -echo "tuxflotte: Provisioning-Agent-Installation ist noch nicht implementiert (Phase 1)." >> /var/log/tuxflotte-postinstall.log +echo "tuxflotte: Provisioning-Agent installiert, registriert und für den ersten Boot aktiviert." >> /var/log/tuxflotte-postinstall.log %end