feat: implement backend_postinstall() for the Fedora backend
Fetch the provisioning agent from git.tuxflotte.de, register it via POST /api/v1/agent/bootstrap using the device id from the activation response, write /etc/tuxflotte/agent.credentials, and enable the tuxflotte-agent systemd service so it starts on first boot. Verified end to end against a QEMU test VM and the real anode API. The device id is now threaded through backend_generate_config() and substituted into the kickstart template like the existing hostname and blueprint values. %post drops the implicit chroot-wide set -e in favor of per-step error handling, since localectl calls in this section are known to fail best-effort without a running D-Bus. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
05dfacab4a
commit
715658893c
@ -67,6 +67,7 @@ backend_validate() {
|
|||||||
|
|
||||||
backend_generate_config() {
|
backend_generate_config() {
|
||||||
local hostname
|
local hostname
|
||||||
|
local device_id
|
||||||
local disk_encryption
|
local disk_encryption
|
||||||
local partitioning
|
local partitioning
|
||||||
local secure_boot_required
|
local secure_boot_required
|
||||||
@ -80,6 +81,10 @@ backend_generate_config() {
|
|||||||
[[ -n "${hostname}" ]] ||
|
[[ -n "${hostname}" ]] ||
|
||||||
{ backend_fatal "Kein Hostname in der Serverantwort gefunden."; return 1; }
|
{ 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}")"
|
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}")"
|
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}")"
|
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}")"
|
blueprints_json="$(jq --compact-output '.runtime_blueprint.blueprints' "${RUNTIME_BLUEPRINT_FILE}")"
|
||||||
|
|
||||||
TUXFLOTTE_HOSTNAME="${hostname}" \
|
TUXFLOTTE_HOSTNAME="${hostname}" \
|
||||||
|
TUXFLOTTE_DEVICE_ID="${device_id}" \
|
||||||
TUXFLOTTE_PARTITIONING_COMMAND="${partitioning_command}" \
|
TUXFLOTTE_PARTITIONING_COMMAND="${partitioning_command}" \
|
||||||
TUXFLOTTE_BLUEPRINTS_JSON="${blueprints_json}" \
|
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}"
|
<"${KICKSTART_TEMPLATE}" >"${CONFIG_FILE}"
|
||||||
|
|
||||||
chmod 0600 "${CONFIG_FILE}"
|
chmod 0600 "${CONFIG_FILE}"
|
||||||
@ -129,5 +135,5 @@ backend_launch() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
backend_postinstall() {
|
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)."
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,10 +28,11 @@ bootloader --location=mbr
|
|||||||
vim
|
vim
|
||||||
curl
|
curl
|
||||||
git
|
git
|
||||||
|
jq
|
||||||
ansible-core
|
ansible-core
|
||||||
%end
|
%end
|
||||||
|
|
||||||
%post
|
%post --erroronfail --interpreter=/bin/bash
|
||||||
cat > /etc/motd <<'EOF'
|
cat > /etc/motd <<'EOF'
|
||||||
Provisioned by tuxflotte
|
Provisioned by tuxflotte
|
||||||
|
|
||||||
@ -42,14 +43,64 @@ localectl set-locale LANG=de_DE.UTF-8
|
|||||||
localectl set-keymap de
|
localectl set-keymap de
|
||||||
localectl set-x11-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'
|
cat > /etc/tuxflotte/runtime_blueprint.json <<'RUNTIME_BLUEPRINT_EOF'
|
||||||
${TUXFLOTTE_BLUEPRINTS_JSON}
|
${TUXFLOTTE_BLUEPRINTS_JSON}
|
||||||
RUNTIME_BLUEPRINT_EOF
|
RUNTIME_BLUEPRINT_EOF
|
||||||
|
|
||||||
# Der Provisioning Agent existiert noch nicht als Build-Artefakt.
|
# Provisioning Agent einrichten (backend_postinstall). Vorbereitung vor dem
|
||||||
# Anwendung der obigen Blueprints per Ansible-Pull erfolgt erst nach dessen Implementierung.
|
# 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: 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
|
%end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user