scope sleep to homelab, and port the boot hang fix

Sleep and suspend is homelab only now. The two exclusions are for different
reasons and both are stated in the run rather than left implicit:

  dev — a laptop should sleep; disabling it is a hot bag and a flat battery.

  vps — not merely unnecessary, harmful. A virtual machine has no lid and no
  power button, but the provider's Shut down control works by sending an ACPI
  power button event. HandlePowerKey=ignore makes the VM ignore it, so graceful
  shutdown requests silently do nothing and the instance is hard-killed instead.
  systemd defaults that key to poweroff for exactly this reason.

The boot hang fix is everything except vps, where systemd-networkd genuinely
manages the network and the unit is load-bearing.

Rather than asking whether boot "feels slow" — a question people answer from
memory of the worst time it happened — the step prints what the unit actually
cost on this boot, from systemd's own accounting. On this host that is 14ms,
which ends the discussion. On a NetworkManager desktop it is two minutes, which
also ends it. On dev the wording says outright that a small number here means
there is nothing to do.

The original's live guard is kept and is what actually decides: NetworkManager
active and networkd not. Anything else, including "cannot tell", is left alone,
and the reason is printed. The warning against disabling systemd-networkd
outright is carried across into the library, where the alternative would be
attempted.

Verified all three roles on this host, which is a networkd machine: homelab and
dev both correctly refuse and explain, vps skips as not applicable, and the
timing helper reads 14ms out of systemd-analyze.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-12 18:17:17 +00:00
co-authored by Claude Opus 5
parent c87127ff93
commit 458510a0a8
2 changed files with 123 additions and 3 deletions
+77 -3
View File
@@ -622,8 +622,16 @@ fi
# =============================================================================
step "Sleep and suspend"
# A laptop should sleep. Disabling it on the machine somebody carries around is
# how you get a hot bag and a flat battery, so dev is skipped — visibly.
# Homelab only, and the two exclusions are for different reasons.
#
# dev: a laptop should sleep. Disabling it on the machine somebody carries is how
# you get a hot bag and a flat battery.
#
# vps: not merely unnecessary but harmful. A virtual machine has no lid and no
# power button, but the provider's "Shut down" control works by sending an ACPI
# power button event — HandlePowerKey=ignore makes the VM ignore it, so a
# graceful shutdown request does nothing and the provider hard-kills the instance
# instead. systemd defaults that key to poweroff for exactly this reason.
if ! skip && is_role dev; then
echo ""
info "Sleep and suspend — left alone on a ${MACHINE_ROLE} machine"
@@ -631,6 +639,16 @@ if ! skip && is_role dev; then
echo " to be stopped from it."
SUMMARY+=("Sleep: left alone on ${MACHINE_ROLE}")
step_ok
elif ! skip && is_role vps; then
echo ""
info "Sleep and suspend — left alone on a ${MACHINE_ROLE}"
echo " A virtual machine has no lid and no power button to disable. What it"
echo " does have is the provider's Shut down control, which works by sending"
echo " an ACPI power button event — telling this machine to ignore that would"
echo " mean graceful shutdowns silently do nothing and the instance gets"
echo " hard-killed instead."
SUMMARY+=("Sleep: left alone on ${MACHINE_ROLE} — would break provider shutdown")
step_ok
elif ! skip; then
echo ""
info "Sleep and suspend — stop this machine putting itself to sleep"
@@ -667,13 +685,69 @@ elif ! skip; then
step_ok
fi
# =============================================================================
# 13. Boot hang
# =============================================================================
step "Boot hang"
# Not on a VPS. There the network IS systemd-networkd — cloud-init and netplan
# put it in charge — so the unit below is load-bearing and completes in
# milliseconds. Masking it on that stack is how a box comes up with no network
# and no ssh.
if ! skip && is_role vps; then
echo ""
info "Boot hang — not applicable on a ${MACHINE_ROLE}"
echo " systemd-networkd is what configures the network here, so the unit"
echo " this would mask is doing real work."
SUMMARY+=("Boot hang: not applicable on ${MACHINE_ROLE}")
step_ok
elif ! skip; then
WAIT_ONLINE_TIME="$(wait_online_boot_time)"
echo ""
info "Boot hang — a unit that can add two minutes to every boot"
echo " On a machine where NetworkManager owns the network, systemd-networkd"
echo " runs nothing — but systemd-networkd-wait-online is still enabled, and"
echo " waits for a link that will never come up. It gives up after its full"
echo " timeout, every single boot."
echo ""
echo " network managed by: $(network_manager_name)"
echo " that unit took: ${WAIT_ONLINE_TIME:-it did not run} on this boot"
if ! wait_online_is_spurious; then
echo ""
echo " systemd-networkd is live here, so that unit is doing real work."
echo " Masking it would be how this machine comes up with no network."
SUMMARY+=("Boot hang: nothing to fix — networkd is in charge")
else
echo ""
if is_role dev; then
echo " Only worth doing if you actually feel this — if the machine sits"
echo " there for a couple of minutes before the login screen. The number"
echo " above is the honest answer for this boot; if it is small, there is"
echo " nothing here for you."
fi
echo " This masks systemd-networkd-wait-online.service only. NetworkManager"
echo " keeps configuring the network exactly as it does now."
if confirm "Mask it?"; then
mask_wait_online
ok "systemd-networkd-wait-online masked"
SUMMARY+=("Boot hang: wait-online masked (NetworkManager stack)")
else
warn "skipped by request"
SUMMARY+=("Boot hang: SKIPPED by request")
fi
fi
step_ok
fi
# =============================================================================
# NOT PORTED YET
# =============================================================================
#
# Sections still to move across from scripts/setup-old/setup-ubuntu.sh, in order:
#
# boot-hang fix · user creation ·
# user creation ·
# ssh keys · ssh hardening · dns · static ip · fail2ban · unattended-upgrades ·
# git config · docker · zsh + prompt · tailscale · neovim · js runtimes ·
# dev tools · ufw · zshrc