Files
local-ci-cd-system/scripts/install-vmware-host-services.sh
T
Simone 19186981a5 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.
2026-07-19 19:47:16 +02:00

91 lines
4.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# install-vmware-host-services.sh — install the native systemd units that bring
# up the VMware Workstation host stack at boot on the Linux CI host.
#
# Why this exists: VMware Workstation on Linux ships NO native systemd unit,
# does NOT register vmmon/vmnet with DKMS, and installs NO kernel postinst hook.
# Two failure modes follow, both of which stop build VMs from starting:
# 1. After a kernel upgrade the vmmon/vmnet .ko are unbuilt until
# vmware-modconfig runs (vmrun start => "Error: The operation was
# canceled").
# 2. The LSB-generated sysv `vmware.service` has proven unreliable to generate
# at early boot ("systemd-sysv-generator: Cannot find unit vmware.service"),
# so vmmon stays unloaded and vmnet1/vmnet8 (DHCP/NAT) never come up.
#
# This installs two native systemd units built on VMware's own tools:
# - vmware-modules-rebuild.service : rebuilds vmmon/vmnet via vmware-modconfig
# if the .ko for the running kernel is missing (build-if-missing guard).
# - vmware-host.service : runs `/etc/init.d/vmware start` to load
# the modules and bring up vmnet networking; ordered After the guard.
# The flaky sysv `vmware.service` is masked so vmware-host.service is the sole
# owner of the host stack.
#
# Usage:
# sudo ./scripts/install-vmware-host-services.sh # install + enable + start
# sudo ./scripts/install-vmware-host-services.sh --uninstall
#
# Idempotent: re-running overwrites the units in place and re-enables them.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_DIR="$(dirname "$SCRIPT_DIR")"
SRC="$REPO_DIR/deploy/systemd"
ACTION="install"
log() { printf '[install-vmware-host-services] %s\n' "$*"; }
warn() { printf '[install-vmware-host-services] WARN: %s\n' "$*" >&2; }
die() { printf '[install-vmware-host-services] ERROR: %s\n' "$*" >&2; exit 1; }
while [ $# -gt 0 ]; do
case "$1" in
--uninstall) ACTION="uninstall"; shift ;;
-h|--help) sed -n '2,29p' "$0"; exit 0 ;;
*) die "unknown argument: $1 (use --uninstall)" ;;
esac
done
[ "$(id -u)" -eq 0 ] || die "run as root: sudo bash $0"
if [ "$ACTION" = "uninstall" ]; then
systemctl disable --now vmware-host.service 2>/dev/null || true
systemctl disable --now vmware-modules-rebuild.service 2>/dev/null || true
rm -f /etc/systemd/system/vmware-host.service \
/etc/systemd/system/vmware-modules-rebuild.service \
/usr/local/sbin/vmware-modules-rebuild.sh
systemctl unmask vmware.service 2>/dev/null || true
systemctl daemon-reload
log "uninstalled (units removed, vmware.service unmasked)"
exit 0
fi
[ -d "$SRC" ] || die "source dir not found: $SRC (clone the repo first)"
command -v vmware-modconfig >/dev/null 2>&1 || warn "vmware-modconfig not found — is VMware Workstation installed?"
[ -x /etc/init.d/vmware ] || warn "/etc/init.d/vmware not found — is VMware Workstation installed?"
# 1. rebuild guard script + units
install -m 0755 -o root -g root "$SRC/vmware-modules-rebuild.sh" /usr/local/sbin/vmware-modules-rebuild.sh
install -m 0644 -o root -g root "$SRC/vmware-modules-rebuild.service" /etc/systemd/system/vmware-modules-rebuild.service
install -m 0644 -o root -g root "$SRC/vmware-host.service" /etc/systemd/system/vmware-host.service
log "installed rebuild script + 2 systemd units"
# 2. mask the flaky sysv vmware.service so the native unit is the sole owner
if [ "$(systemctl is-enabled vmware.service 2>/dev/null || true)" = "masked" ]; then
log "vmware.service already masked"
else
systemctl mask vmware.service && log "masked sysv vmware.service" || warn "could not mask vmware.service"
fi
# 3. reload + enable + start (start is idempotent — init script start is re-runnable)
systemctl daemon-reload
systemctl enable vmware-modules-rebuild.service
systemctl enable vmware-host.service
log "enabled vmware-modules-rebuild.service + vmware-host.service"
if systemctl start vmware-host.service; then
log "vmware-host.service started"
else
warn "vmware-host.service start failed — check: journalctl -u vmware-host.service"
fi
log "done — verify: lsmod | grep -E 'vmmon|vmnet'; ip -o link show | grep vmnet"