Compare commits

...

5 Commits

Author SHA1 Message Date
cd91a6b393 feat: run installer.sh automatically inside the live session
Uses dracut's official 20-apply-live-updates.sh pre-pivot hook: any
/updates/ directory tree present at the top level of the boot media
gets copied into the live root filesystem before pivoting, verbatim,
no initrd or squashfs/EROFS modification needed. build.sh assembles
this tree from scripts/, backends/, config/ (mapped under
/opt/tuxflotte) plus live-updates/etc/ (an XDG autostart entry that
opens a terminal running installer.sh as root, and a sudoers.d drop-in
granting liveuser passwordless sudo).

xorriso preserves the ownership/permissions recorded at map time, so
-chown_r/-chgrp_r 0 on /updates is enough to make sudoers accept the
drop-in as root-owned without needing local root to build the ISO.

This was tried first as a direct EROFS unpack/repack of
/LiveOS/squashfs.img (that file is actually EROFS despite the name on
current Fedora), but a fresh self-built erofs-utils (Debian's
packaged 1.5-1 can't even read this image's on-disk format) hit a
reproducible bug extracting the packed/fragmented inode into a single
corrupt file instead of a directory tree. The dracut hook sidesteps
that path entirely.

Verified end-to-end: booting either Tuxflotte entry reaches the
Cinnamon live desktop, autostarts a terminal, and installer.sh runs
through every module (network, hardware, enrollment, handshake,
device status, Bereitstellungsvorlage selection, commit point, Runtime
Blueprint resolution against the real server, full Fedora backend
lifecycle, storage detection) to a clean exit.
2026-07-20 14:52:05 +02:00
a8cd66af94 feat: set German console keyboard layout on boot
Adds vconsole.keymap=de to both Tuxflotte GRUB entries.
2026-07-20 14:51:41 +02:00
dd7147aee0 fix: make 20_storage.sh self-contained like every other module
It called log_info/log_warn/error_exit/list_install_disks without
sourcing anything - leftover from before modules were run as
standalone subprocesses via run_module() rather than sourced into
installer.sh. Never noticed because the pipeline never reached this
module in a live run until now. Behavior unchanged: still just lists
disks and warns that partitioning is disabled (Phase 1).
2026-07-20 14:51:28 +02:00
6a48a7c929 fix: tolerate nmcli connection.filename failure for in-memory live connections
export_connection_profile() crashed the whole installer under set -e/
pipefail when the active NetworkManager connection has no backing
keyfile (common for ephemeral live-boot DHCP connections) - nmcli
returned a non-zero exit status even though the guard below already
handles an empty result gracefully. Every other nmcli call in this
function already has this || true safety net; this one was missing it.

Found via a live end-to-end boot test in Proxmox.
2026-07-20 14:51:22 +02:00
1a38f8ef3c fix: set execute bit on Fedora backend and runtime-blueprint/backend modules
These are run as standalone subprocesses via run_module()/source, which
requires the execute bit. Missing since their initial creation - only
noticed because manually chmod'd copies were used for testing on anode,
never the checked-in files. Would have failed on a fresh checkout.
2026-07-20 14:51:12 +02:00
10 changed files with 63 additions and 13 deletions

0
backends/fedora/backend.sh Normal file → Executable file
View File

View File

@ -26,12 +26,12 @@ set color_highlight=white/blue
### BEGIN /etc/grub.d/10_linux ###
menuentry 'Tuxflotte Provisioning (automatisch)' --class fedora --class gnu-linux --class gnu --class os {
linux /boot/x86_64/loader/linux quiet rhgb root=live:CDLABEL=Fedora-Cinn-Live-44 rd.live.image tuxflotte.mode=auto
linux /boot/x86_64/loader/linux quiet rhgb root=live:CDLABEL=Fedora-Cinn-Live-44 rd.live.image vconsole.keymap=de tuxflotte.mode=auto
initrd /boot/x86_64/loader/initrd
}
menuentry 'Tuxflotte Provisioning (interaktiv)' --class fedora --class gnu-linux --class gnu --class os {
linux /boot/x86_64/loader/linux quiet rhgb root=live:CDLABEL=Fedora-Cinn-Live-44 rd.live.image tuxflotte.mode=interactive
linux /boot/x86_64/loader/linux quiet rhgb root=live:CDLABEL=Fedora-Cinn-Live-44 rd.live.image vconsole.keymap=de tuxflotte.mode=interactive
initrd /boot/x86_64/loader/initrd
}

View File

@ -23,12 +23,12 @@ set color_highlight=white/blue
### BEGIN /etc/grub.d/10_linux ###
menuentry 'Tuxflotte Provisioning (automatisch)' --class fedora --class gnu-linux --class gnu --class os {
linux /boot/x86_64/loader/linux quiet rhgb root=live:CDLABEL=Fedora-Cinn-Live-44 rd.live.image tuxflotte.mode=auto
linux /boot/x86_64/loader/linux quiet rhgb root=live:CDLABEL=Fedora-Cinn-Live-44 rd.live.image vconsole.keymap=de tuxflotte.mode=auto
initrd /boot/x86_64/loader/initrd
}
menuentry 'Tuxflotte Provisioning (interaktiv)' --class fedora --class gnu-linux --class gnu --class os {
linux /boot/x86_64/loader/linux quiet rhgb root=live:CDLABEL=Fedora-Cinn-Live-44 rd.live.image tuxflotte.mode=interactive
linux /boot/x86_64/loader/linux quiet rhgb root=live:CDLABEL=Fedora-Cinn-Live-44 rd.live.image vconsole.keymap=de tuxflotte.mode=interactive
initrd /boot/x86_64/loader/initrd
}

View File

@ -0,0 +1 @@
liveuser ALL=(ALL) NOPASSWD: ALL

View File

@ -0,0 +1,6 @@
[Desktop Entry]
Type=Application
Name=Tuxflotte Provisioning
Exec=gnome-terminal --title="Tuxflotte Provisioning" -- bash -c 'sudo /opt/tuxflotte/scripts/installer.sh; rc=$?; echo; echo "--- installer.sh beendet (Exit-Code: $rc) ---"; exec bash'
X-GNOME-Autostart-enabled=true
NoDisplay=true

View File

@ -64,6 +64,22 @@ verify_workdir() {
echo "GRUB verification passed."
}
prepare_updates() {
echo "Assembling live-updates payload..."
local updates_dir="$WORK_DIR/updates"
rm -rf "$updates_dir"
mkdir -p "$updates_dir/opt/tuxflotte"
cp -a "$REPO_DIR/live-updates/etc" "$updates_dir/"
cp -a "$REPO_DIR/scripts" "$updates_dir/opt/tuxflotte/"
cp -a "$REPO_DIR/backends" "$updates_dir/opt/tuxflotte/"
cp -a "$REPO_DIR/config" "$updates_dir/opt/tuxflotte/"
chmod 0440 "$updates_dir/etc/sudoers.d/90-tuxflotte"
}
create_iso() {
echo "Creating Tuxflotte ISO..."
@ -77,6 +93,9 @@ create_iso() {
-compliance no_emul_toc \
-map "$REPO_DIR/grub/EFI-BOOT-grub.cfg" /EFI/BOOT/grub.cfg \
-map "$REPO_DIR/grub/boot-grub2-grub.cfg" /boot/grub2/grub.cfg \
-map "$WORK_DIR/updates" /updates \
-chown_r 0 /updates -- \
-chgrp_r 0 /updates -- \
-boot_image any replay
echo "ISO created: $output_iso"
@ -89,6 +108,7 @@ main() {
extract_iso
patch_grub
verify_workdir
prepare_updates
create_iso
echo

View File

@ -440,7 +440,7 @@ export_connection_profile() {
"${NMCLI}" \
--get-values connection.filename \
connection show "${connection_name}" 2>/dev/null |
head -n 1
head -n 1 || true
)"
if [[ -z "${source_file}" || ! -f "${source_file}" ]]; then

View File

@ -1,14 +1,37 @@
#!/usr/bin/env bash
set -Eeuo pipefail
log_info "Datenträger werden erkannt..."
SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"
readonly SCRIPT_NAME
DISKS="$(list_install_disks || true)"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly SCRIPT_DIR
if [[ -z "$DISKS" ]]; then
error_exit "Keine geeigneten Datenträger erkannt."
fi
# shellcheck source=../lib/checks.sh
source "${SCRIPT_DIR}/../lib/checks.sh"
echo "$DISKS"
log() {
printf '[%s] %s\n' "${SCRIPT_NAME}" "$*"
}
log_warn "Phase 1: Datenträger werden nur angezeigt, nicht verändert."
log_warn "Partitionierung ist noch deaktiviert."
fatal() {
printf '[%s] FEHLER: %s\n' "${SCRIPT_NAME}" "$*" >&2
exit 1
}
main() {
log "Datenträger werden erkannt..."
local disks
disks="$(list_install_disks || true)"
[[ -n "${disks}" ]] ||
fatal "Keine geeigneten Datenträger erkannt."
printf '%s\n' "${disks}"
log "Phase 1: Datenträger werden nur angezeigt, nicht verändert."
log "Partitionierung ist noch deaktiviert."
}
main "$@"

0
scripts/modules/30_runtime_blueprint.sh Normal file → Executable file
View File

0
scripts/modules/40_backend.sh Normal file → Executable file
View File