From db57818eb3237212fc79b71a131e91e94c2fcc09 Mon Sep 17 00:00:00 2001 From: Florian Wilde Date: Fri, 23 Oct 2026 15:08:05 +0200 Subject: [PATCH] fix(adapter): Benutzer anlegen, auch wenn die Gruppe schon existiert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ubuntu 22.04 bringt eine Gruppe „admin“ mit; heißt der Gast-Benutzer so, brach useradd mit Code 9 ab (gefunden im Feldtest auf pve-demo). Der Container-Test legt jetzt diese Lage nach und lief seit pnpm 12 nicht mehr (pnpm -s gibt es dort nicht). Refs #020 Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 2 ++ scripts/profil-rendern.ts | 9 ++++++--- src/engine/adapter/debian.ts | 4 +++- tests/container/im-gast-pruefen.sh | 6 ++++-- tests/container/profile-pruefen.sh | 2 +- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfc5671..0e370b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/). ### Geändert ### Behoben +- Gast-Benutzer, der wie eine vorhandene Gruppe heißt (z. B. „admin“ auf Ubuntu 22.04), ließ die Provisionierung mit Code 9 abbrechen; die Gruppe wird jetzt Primärgruppe (#020) +- `pnpm test:container` lief seit pnpm 12 nicht mehr (`pnpm -s` gibt es dort nicht) (#020) - Auf ausgelasteten Nodes brachen Aufträge beim ersten Verbindungswackler ab („Broken pipe“, „other side closed“, Zeitüberschreitung). Lesende Proxmox-Aufrufe werden jetzt bis zu dreimal wiederholt, schreibende nur, wenn die Anfrage sicher nicht ankam; Schreibaufrufe dürfen 120 s dauern; Wiederholungen stehen im Detail-Log (#020) - `proxdeploy batch --dry-run --quiet` gab Leerzeilen für erfolgreiche Einträge aus (#020) - Übersicht am Handy breiter als der Bildschirm (lange Auftragszeilen); der Browser zoomte heraus und die Navigation verdeckte „Abmelden“ (#023) diff --git a/scripts/profil-rendern.ts b/scripts/profil-rendern.ts index af62f96..babd52f 100644 --- a/scripts/profil-rendern.ts +++ b/scripts/profil-rendern.ts @@ -7,6 +7,9 @@ import { katalogLaden } from "@/engine/katalog/laden"; import { profileAufloesen } from "@/engine/profile/aufloesen"; import { profileRendern } from "@/engine/profile/rendern"; +/** Gast-Benutzer; „admin“ prüft den Fall „Gruppe gibt es schon“ (Ubuntu 22.04). */ +const BENUTZER = process.env["PD_BENUTZER"] ?? "florian"; + const [distroId = "debian-13", auswahl = "base", ...zuweisungen] = process.argv.slice(2); const katalog = await katalogLaden("catalog"); const distro = katalog.distributionen.find((d) => d.eintrag.id === distroId)?.eintrag; @@ -29,12 +32,12 @@ const { skript } = profileRendern( adapter, { os: distro.os, - gast: { name: "testgast", benutzer: "florian" }, + gast: { name: "testgast", benutzer: BENUTZER }, }, [ adapter.benutzerAnlegen({ - name: "florian", - sshSchluessel: ["ssh-ed25519 AAAAtest florian@test"], + name: BENUTZER, + sshSchluessel: [`ssh-ed25519 AAAAtest ${BENUTZER}@test`], sudo: true, }), ], diff --git a/src/engine/adapter/debian.ts b/src/engine/adapter/debian.ts index 70a812f..a3dd45b 100644 --- a/src/engine/adapter/debian.ts +++ b/src/engine/adapter/debian.ts @@ -119,7 +119,9 @@ setupcon --save-only >/dev/null 2>&1 || true const name = q(b.name); const schluessel = b.sshSchluessel.join("\n") + "\n"; const zeilen = [ - `id -u ${name} >/dev/null 2>&1 || useradd -m -s /bin/bash ${name}`, + // Gibt es schon eine gleichnamige Gruppe (Ubuntu 22.04 bringt „admin“ mit), wird sie die + // Primärgruppe – sonst bricht useradd mit Code 9 ab. + `id -u ${name} >/dev/null 2>&1 || { if getent group ${name} >/dev/null; then useradd -m -s /bin/bash -g ${name} ${name}; else useradd -m -s /bin/bash ${name}; fi; }`, `pd_home="$(getent passwd ${name} | cut -d: -f6)"`, `install -d -m 0700 -o ${name} -g ${name} "$pd_home/.ssh"`, // Schlüssel ergänzen statt ersetzen: cloud-init hat sie bei VMs vielleicht schon eingetragen. diff --git a/tests/container/im-gast-pruefen.sh b/tests/container/im-gast-pruefen.sh index 455672b..9252331 100755 --- a/tests/container/im-gast-pruefen.sh +++ b/tests/container/im-gast-pruefen.sh @@ -1,6 +1,8 @@ #!/bin/bash # Läuft im Container: systemctl-Stub, Skript ausführen, Ergebnis prüfen. printf '#!/bin/sh\necho "[systemctl] $*" >> /tmp/systemctl.log\n' > /usr/local/bin/systemctl && chmod +x /usr/local/bin/systemctl +# Wie im Ubuntu-22.04-Cloud-Image: eine Gruppe „admin“ gibt es schon, der Benutzer heißt genauso. +getent group admin >/dev/null || groupadd admin bash "$1" > /tmp/lauf.log 2>&1; code=$? grep '::proxdeploy::' /tmp/lauf.log echo "exit=$code" @@ -10,7 +12,7 @@ docker --version; docker compose version zabbix_agent2 -V | head -1; cat /etc/zabbix/zabbix_agent2.d/proxdeploy.conf cat /etc/timezone; readlink /etc/localtime; grep LANG /etc/default/locale; locale -a | grep -i de_de grep XKBLAYOUT /etc/default/keyboard -id florian; cat /etc/sudoers.d/90-proxdeploy-florian; cat ~florian/.ssh/authorized_keys +id admin; cat /etc/sudoers.d/90-proxdeploy-admin; cat ~admin/.ssh/authorized_keys cat /etc/apt/apt.conf.d/20auto-upgrades; dpkg -l fail2ban chrony qemu-guest-agent | grep ^ii | awk '{print $2}' cat /tmp/systemctl.log | sort -u | tr '\n' ' '; echo -echo "--- Zweiter Lauf (Idempotenz)"; bash "$1" > /tmp/lauf2.log 2>&1; echo "exit2=$?"; grep -c florian ~florian/.ssh/authorized_keys +echo "--- Zweiter Lauf (Idempotenz)"; bash "$1" > /tmp/lauf2.log 2>&1; echo "exit2=$?"; grep -c admin ~admin/.ssh/authorized_keys diff --git a/tests/container/profile-pruefen.sh b/tests/container/profile-pruefen.sh index 922c0bb..83fc7cd 100755 --- a/tests/container/profile-pruefen.sh +++ b/tests/container/profile-pruefen.sh @@ -16,7 +16,7 @@ arbeit="$(mktemp -d)"; trap 'rm -rf "$arbeit"' EXIT cp tests/container/im-gast-pruefen.sh "$arbeit/" fehler=0 for distro in ${ziele[*]}; do - pnpm -s exec tsx scripts/profil-rendern.ts "$distro" docker,zabbix-agent server=zbx.example fail2ban=true > "$arbeit/$distro.sh" + PD_BENUTZER=admin pnpm exec tsx scripts/profil-rendern.ts "$distro" docker,zabbix-agent server=zbx.example fail2ban=true > "$arbeit/$distro.sh" echo "=== $distro (${IMAGES[$distro]})" if docker run --rm -v "$arbeit:/s:ro" "${IMAGES[$distro]}" bash /s/im-gast-pruefen.sh "/s/$distro.sh" > "$arbeit/$distro.log" 2>&1 \ && grep -q '^exit=0$' "$arbeit/$distro.log" && grep -q '^exit2=0$' "$arbeit/$distro.log"; then