server profile: fix desktop assumptions that abort headless/Cloud runs - #32
Open
edmondscommerce wants to merge 2 commits into
Open
Conversation
Proving provisioning_profile=server on a minimal Fedora 44 Cloud Base VM surfaced five scope:general plays that assume a desktop (hardware, firmware, a GUI XDG dir, or a local firewalld) and hard-fail under any_errors_fatal on a server/VM. The GNOME/GUI profile guard already works (the ~35 desktop plays skip); these are the remaining gaps. Every change is a pure addition — the desktop path is unchanged, so there is zero regression risk to existing desktop users. All proven end-to-end on a real Cloud VM (green through ccy + claude-code + markless + VPN). 1. play-AB-dnf-upgrade.yml (CRITICAL): the kernel half-install cleanup enumerates `rpm -q kernel-modules`. A minimal Cloud/Server image legitimately ships kernel-core + kernel-modules-core and NO full kernel-modules. On server this either hard-fails on `rpm -q kernel-modules` (rc 1) or, if made tolerant, treats EVERY kernel as half-installed and dnf-removes kernel-core + kernel-modules-core -> unbootable. Fix: default half_installed_kernels to [] then gate the enumerate/identify tasks on provisioning_profile != 'server'. 2. play-basic-configs.yml: the fwupd firmware task runs fwupdmgr, absent on a minimal Cloud image (rc 127). Fix: a `command -v fwupdmgr` presence-check gate, so bare-metal servers with fwupd still get firmware updates while VMs skip. 3. play-podman.yml: podman-compose uses the pip module but a minimal Cloud image has no pip3. Fix: add python3-pip to the engine dnf install list. 4. play-markless.yml: the install shell does `cd ~/Downloads`, a desktop XDG dir absent on minimal Cloud. Fix: `mkdir -p ~/Downloads` before cd (no-op on desktop). 5. play-vpn.yml: "Allow OpenVPN Through Firewall" uses the firewalld module, which needs python3-firewall (absent on minimal Cloud). The play already keeps the VPN CLI packages and already server-guards its GNOME applet task. Fix: the same `when: provisioning_profile != 'server'` guard on the firewall-rule task. play-lxc-install-config.yml (also firewalld, plus a hard Docker + GitHub-SSH dependency) is a desktop/dev-workstation play and is intentionally left out — LXC-on-server needs its own decision, not a forced-green here.
…(bug 3) play-lxc-install-config.yml is desktop/dev-workstation tooling: it hard-requires the container engine to be present, uses the firewalld module (python3-firewall, absent on a minimal Cloud image), and clones "LXC Bash" over a GitHub SSH url. None of that applies to a headless dev/prod server (podman is the runtime there), and under any_errors_fatal the firewalld import aborts the whole run. Classify it as desktop-only, exactly like firefox/vscode/browsers/comms/ terminal-emulators (all scope: gnome): set scope: gnome and add the standard two-task scope guard so the play cleanly end_play's on provisioning_profile=server. Proven: the full server run now skips LXC and continues to podman + ccy.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Server profile: fix desktop assumptions that abort headless/Cloud runs
Proving the
provisioning_profile=serverpath on a minimal Fedora 44 Cloud Base VMsurfaced six plays that assume a desktop (hardware, firmware, GUI XDG dirs, a local
firewalld, or desktop-only tooling) and therefore hard-fail under
any_errors_fatal: trueon a server/VM. The GNOME/GUI profile guard already works correctly (the ~35 desktop plays
skip); these are the remaining gaps.
Every change is a pure addition — the desktop path is unchanged, so there is zero
regression risk to existing desktop users. All proven end-to-end on a real Cloud VM (green
through podman + ccy + claude-code).
1.
play-AB-dnf-upgrade.yml— kernel half-install cleanup (CRITICAL: would brick a VM)The kernel half-install cleanup enumerates
rpm -q kernel-modules. A minimal Cloud/Serverimage legitimately ships
kernel-core+kernel-modules-coreand no fullkernel-modules— a valid minimal kernel, not a half-install. On a server this either(a) hard-fails on
rpm -q kernel-modules(rc 1) underany_errors_fatal, or (b) ifmade tolerant, computes
half_installed_kernels= every kernel and the removaldnftask would remove
kernel-core+kernel-modules-corefor all of them → an unbootablebox.
Fix: default
half_installed_kernels: []first, then gate the enumerate/identify taskson
provisioning_profile != 'server'.2.
play-basic-configs.yml— fwupd firmware updates"Check and Apply Firmware Updates via fwupd" runs
fwupdmgr, absent on a minimal Cloud/VMimage → rc 127 aborts the run.
Fix: a
command -v fwupdmgrpresence-check gate — bare-metal servers with fwupd stillget firmware updates while VMs/minimal images skip.
3.
play-podman.yml— podman-compose needs pip3"Install podman-compose" uses the
pipmodule, which fails with "Unable to find any of pip3to use" — a minimal Cloud image has no
python3-pip.Fix: add
python3-pipto the play's "Install Podman" dnf list.4.
play-markless.yml— assumes~/DownloadsexistsThe install shell does
cd ~/Downloads, a desktop XDG dir absent on minimal Cloud →cdaborts the run.
Fix:
mkdir -p ~/Downloadsbeforecd(no-op on desktop).5.
play-vpn.yml— OpenVPN firewalld rule needs python3-firewall"Allow OpenVPN Through Firewall" uses the
firewalldmodule, which needspython3-firewall(absent on a minimal Cloud image). The play already keeps the VPN CLI packages and already
server-guards its GNOME applet task.
Fix: the same
when: provisioning_profile != 'server'guard on the firewall-rule task.A headless server is firewalled at the network edge and runs no local firewalld.
6.
play-lxc-install-config.yml— desktop-only; server-skip itThis play is desktop/dev-workstation tooling: it hard-requires the container engine, uses
the
firewalldmodule (python3-firewall, absent on minimal Cloud), and clones "LXC Bash"over a GitHub SSH url. None of that applies to a headless server (podman is the runtime
there), and the firewalld import aborts the run.
Fix: classify it as desktop-only like
firefox/vscode/browsers/comms/terminal-emulators(allscope: gnome): setscope: gnomeand add the standard two-taskscope guard so it cleanly
end_plays on the server profile.Proven end-to-end
With these fixes,
ansible-playbook playbooks/playbook-main.yml -e provisioning_profile=serverruns green on a Fedora 44 Cloud VM through dnf-upgrade → basic-configs → GitHub CLI → RPM
Fusion → podman → python → claude-yolo (ccy) image build → claude-code → markless →
VPN → repo-cleanup, with the GNOME/GUI/desktop plays (LXC included) skipping. The ccy
container image builds and
podman image inspect claude-yolo:latestverifies; theclaude-code CLI installs and runs.
🤖 Generated with Claude Code