fix(host): bring up VMware host stack at boot via native systemd units

Build VMs stopped starting after a reboot into a new kernel: vmmon/vmnet
were left unloaded and vmnet1/vmnet8 (DHCP/NAT) never came up, so
vmware-vmx died (status=237/KEYRING) and clones got no IP. Root cause:
the LSB->systemd sysv-generated vmware.service intermittently fails to
generate at early boot ("systemd-sysv-generator: Cannot find unit
vmware.service"), and the existing module-rebuild guard only builds the
modules -- it never loads them or starts vmnet networking.

Add a native vmware-host.service that runs `/etc/init.d/vmware start`
(loads vmmon/vmci + brings up vmnet), ordered after the rebuild guard,
and mask the flaky sysv vmware.service so the native unit is the sole
owner. Provisioned by scripts/install-vmware-host-services.sh and wired
into setup-host-linux.sh (new step 8/9). VMware ships no native unit and
no kernel postinst hook, so this native wrapper around VMware's own
tools is the reliable boot path.

Verified: linked clone boots and gets a vmnet8 DHCP IP.
This commit is contained in:
2026-07-19 19:47:16 +02:00
parent 92bea69f19
commit 19186981a5
7 changed files with 234 additions and 14 deletions
+29 -13
View File
@@ -14,7 +14,10 @@
# 5. (Opzionale) Clona il repo e installa il package nel venv
# 6. (Opt-in, --with-pwsh) Installa PowerShell Core
# 7. Installa l'alias shell `ci` a livello di sistema (/etc/profile.d/)
# 8. Autorizza ci-runner sulla sessione X del desktop user (xhost persistente)
# 8. Installa i servizi VMware host (unit systemd native): caricano vmmon/vmnet
# e avviano la rete vmnet (DHCP/NAT) a ogni boot, e ricostruiscono i moduli
# dopo un upgrade del kernel. Sostituisce il flaky sysv vmware.service.
# 9. Autorizza ci-runner sulla sessione X del desktop user (xhost persistente)
# così `ci vmware` può aprire la GUI di VMware Workstation.
# L'host Linux NON ha più bisogno di pwsh per il normale funzionamento
# (orchestratore Python). Installalo solo se ti serve per script legacy.
@@ -106,7 +109,7 @@ echo " Utente : $CI_USER"
echo ""
# ── Step 1: utente di servizio ────────────────────────────────────────────────
info "[1/8] Utente di servizio $CI_USER"
info "[1/9] Utente di servizio $CI_USER"
if id "$CI_USER" &>/dev/null; then
warn "Utente $CI_USER esiste già — skip"
else
@@ -115,7 +118,7 @@ else
fi
# ── Step 2: mount partizione CI ───────────────────────────────────────────────
info "[2/8] Mount $CI_DISK → $CI_ROOT"
info "[2/9] Mount $CI_DISK → $CI_ROOT"
if mountpoint -q "$CI_ROOT" 2>/dev/null; then
warn "$CI_ROOT già montato — skip riorganizzazione e fstab"
@@ -173,7 +176,7 @@ else
fi
# ── Step 3: layout directory e permessi ───────────────────────────────────────
info "[3/8] Layout directory e permessi"
info "[3/9] Layout directory e permessi"
# Installa acl se mancante
if ! command -v setfacl &>/dev/null; then
@@ -210,7 +213,7 @@ echo " Layout OK — ACL default su build-vms applicata"
# ── Step 4: Python 3.11+ e venv ──────────────────────────────────────────────
if [[ "$SKIP_PYTHON" == false ]]; then
info "[4/8] Python 3.11+ e venv produzione"
info "[4/9] Python 3.11+ e venv produzione"
# Cerca la prima versione di Python >= 3.11 già installata
PYTHON_BIN=""
@@ -241,12 +244,12 @@ if [[ "$SKIP_PYTHON" == false ]]; then
echo " venv creato in $OPT_CI/venv ($($PYTHON_BIN --version))"
fi
else
info "[4/8] Python/venv — SKIPPED"
info "[4/9] Python/venv — SKIPPED"
fi
# ── Step 5: Clone repo e pip install ─────────────────────────────────────────
if [[ "$SKIP_CLONE" == false ]]; then
info "[5/8] Clone repo e pip install"
info "[5/9] Clone repo e pip install"
REPO_DIR="$OPT_CI/local-ci-cd-system"
if [[ -d "$REPO_DIR/.git" ]]; then
warn "Repo già presente in $REPO_DIR — skip clone (eseguire git pull manualmente)"
@@ -260,12 +263,12 @@ if [[ "$SKIP_CLONE" == false ]]; then
|| die "ci_orchestrator non importabile"
echo " Verifica OK: ${verify_out%%$'\n'*}"
else
info "[5/8] Clone repo — SKIPPED"
info "[5/9] Clone repo — SKIPPED"
fi
# ── Step 6: PowerShell Core (opt-in via --with-pwsh) ──────────────────────────
if [[ "$WITH_PWSH" == true ]]; then
info "[6/8] PowerShell Core"
info "[6/9] PowerShell Core"
if command -v pwsh &>/dev/null; then
warn "pwsh già installato: $(pwsh --version) — skip"
else
@@ -287,11 +290,11 @@ if [[ "$WITH_PWSH" == true ]]; then
echo " Installato: $(pwsh --version)"
fi
else
info "[6/8] PowerShell Core — SKIPPED (opt-in con --with-pwsh)"
info "[6/9] PowerShell Core — SKIPPED (opt-in con --with-pwsh)"
fi
# ── Step 7: alias shell `ci` (system-wide) ────────────────────────────────────
info "[7/8] Alias shell 'ci'"
info "[7/9] Alias shell 'ci'"
ALIAS_SCRIPT="$OPT_CI/local-ci-cd-system/scripts/install-ci-alias.sh"
if [[ -x "$ALIAS_SCRIPT" ]]; then
# Installa /etc/profile.d/ci-alias.sh per tutti gli utenti login.
@@ -303,8 +306,21 @@ else
warn "install-ci-alias.sh non trovato in $ALIAS_SCRIPT — skip (clona il repo, Step 5)"
fi
# ── Step 8: autorizzazione X per la GUI di VMware (xhost persistente) ──────────
info "[8/8] Accesso GUI VMware (xhost ci-runner)"
# ── Step 8: servizi VMware host (moduli + rete al boot) ───────────────────────
info "[8/9] Servizi VMware host (vmmon/vmnet + rete al boot)"
VMSVC_SCRIPT="$OPT_CI/local-ci-cd-system/scripts/install-vmware-host-services.sh"
if [[ -x "$VMSVC_SCRIPT" ]]; then
# Installa le unit systemd native che caricano vmmon/vmnet e avviano la rete
# vmnet (DHCP/NAT) a ogni boot, e ricostruiscono i moduli dopo un upgrade del
# kernel. Sostituisce il flaky sysv vmware.service. Vedi deploy/systemd/.
bash "$VMSVC_SCRIPT"
echo " Servizi VMware host installati — verifica: ip -o link show | grep vmnet"
else
warn "install-vmware-host-services.sh non trovato in $VMSVC_SCRIPT — skip (clona il repo, Step 5)"
fi
# ── Step 9: autorizzazione X per la GUI di VMware (xhost persistente) ──────────
info "[9/9] Accesso GUI VMware (xhost ci-runner)"
GUI_SCRIPT="$OPT_CI/local-ci-cd-system/scripts/install-vmware-gui-access.sh"
if [[ "$SKIP_GUI_ACCESS" == true ]]; then
info " SKIPPED (--skip-gui-access)"