Skip to content

desktops: flip netplan renderer to NetworkManager on live install#880

Merged
igorpecovnik merged 1 commit intomainfrom
desktop-install-networking
Apr 20, 2026
Merged

desktops: flip netplan renderer to NetworkManager on live install#880
igorpecovnik merged 1 commit intomainfrom
desktop-install-networking

Conversation

@igorpecovnik
Copy link
Copy Markdown
Member

Summary

When a desktop is installed on top of a minimal Armbian image, the image's networking baseline is netplan.io driving systemd-networkd. The desktop's NM-applet / GNOME Quick Settings / Plasma plasma-nm all talk to NetworkManager, and with NM not actually driving the link the Wi-Fi/Wired tile stays in "disconnected" state even though the machine is online. Worse, if the user clicks Connect in the tile, NM and networkd race for the interface.

armbian/build's extensions/network/net-network-manager.sh already does this flip at image-assembly time for image-built desktop variants. This PR runs the equivalent transition at runtime for the install-on-minimal path so the two paths converge on the same end state.

What happens during install

After module_desktop_branding copies branding assets, a new helper _module_desktops_configure_networking runs:

  1. Removes /etc/netplan/10-dhcp-all-interfaces.yaml (the networkd drop-in that minimal images ship).
  2. Installs /etc/netplan/00-default-use-network-manager.yaml (renderer: NetworkManager).
  3. Installs three /etc/NetworkManager/conf.d/ drop-ins that match build's extension exactly: readme stub, wifi MAC randomisation, wifi powersave disable.
  4. Disables NetworkManager-wait-online.service (otherwise boots hang 90s waiting for carrier on every managed interface).
  5. Keeps systemd-resolved enabled (NM uses it as DNS cache when /etc/resolv.conf points at the stub).
  6. netplan generate && netplan apply — unless mode=build (deferred to first-boot) or we're in a container (no real network to flip).

Idempotent: safe to re-run on a system already on NetworkManager.

YAML change

common.yaml's minimal tier now pulls in network-manager + netplan.io directly. Previous coverage was inconsistent — gnome/mate/cinnamon/kde-plasma/i3-wm/xmonad had the daemon in their per-DE yamls, xfce/enlightenment/budgie/deepin/kde-neon didn't, so the first group would have had NM installed while the second group's transition would have failed at the command -v NetworkManager gate. Moving it to common closes that hole.

Per-DE applets (network-manager-gnome for GTK DEs, KDE's plasma-nm via kde-plasma-desktop metapackage) stay in the per-DE yamls — only the DEs that need them pull them.

Files

  • tools/modules/desktops/networking/netplan/00-default-use-network-manager.yaml — mirrors build's config-nm/netplan/00-default-use-network-manager.yaml
  • tools/modules/desktops/networking/NetworkManager/00-armbian-readme.conf
  • tools/modules/desktops/networking/NetworkManager/zz-10-override-wifi-random-mac-disable.conf
  • tools/modules/desktops/networking/NetworkManager/zz-20-override-wifi-powersave-disable.conf
  • tools/modules/desktops/module_desktops.sh — new helper + install-path call
  • tools/modules/desktops/yaml/common.yaml — minimal tier gets network-manager + netplan.io

Test plan

  • Parser sanity: every DE now emits network-manager + netplan.io in DESKTOP_PACKAGES at the minimal tier (verified via parse_desktop_yaml.py).
  • Parser dedup: gnome.yaml still declares network-manager in its minimal tier alongside common's; parser emits it once.
  • bash -n module_desktops.sh passes.
  • Fresh install of any DE on a minimal Ubuntu/Debian image: Wi-Fi tile in the DE controls the link after the install completes.
  • /etc/netplan/ ends up with only 00-default-use-network-manager.yaml, 10-dhcp-all-interfaces.yaml is gone.
  • systemctl is-enabled NetworkManager-wait-online.service reports masked or disabled.
  • mode=build path lays the netplan + conf.d files but doesn't try to netplan apply.
  • CI unit-test matrix (container): helper runs, writes files, skips netplan apply cleanly.

When a desktop is installed on top of a minimal Armbian image, the
image's networking baseline is netplan.io driving systemd-networkd
(armbian/build's extensions/network/net-systemd-networkd.sh lays
/etc/netplan/10-dhcp-all-interfaces.yaml with 'renderer: networkd').
The desktop's NM-applet / GNOME Quick Settings / Plasma plasma-nm
talk to NetworkManager, and with NM not actually driving the link
the Wi-Fi/Wired tile stays in 'disconnected' state even though the
machine is online. Worse, if the user clicks 'Connect' in the tile,
NM and networkd race for the interface.

Image-built desktop images use armbian/build's
extensions/network/net-network-manager.sh to do the flip at image
assembly time. This change runs the equivalent transition at runtime
for the install-on-minimal path so the two converge on the same
end state.

The transition:

  - Remove /etc/netplan/10-dhcp-all-interfaces.yaml (the networkd
    renderer drop-in the minimal image shipped).
  - Install /etc/netplan/00-default-use-network-manager.yaml with
    renderer: NetworkManager.
  - Install the three NetworkManager conf.d drop-ins that
    armbian/build's net-network-manager.sh ships: readme stub,
    wifi MAC randomisation, wifi powersave disable.
  - Disable NetworkManager-wait-online.service (90s boot hang
    waiting for carrier on every managed interface otherwise).
  - Keep systemd-resolved enabled (NM uses it as DNS cache when
    /etc/resolv.conf points at the stub).
  - netplan generate + netplan apply to switch the live system,
    unless mode=build (deferred to first-boot) or inside a
    container/CI (no real network to flip).

common.yaml's minimal tier now declares network-manager and
netplan.io directly so every DE picks them up instead of each
per-DE yaml declaring them piecemeal — current coverage was
inconsistent (gnome/mate/cinnamon/kde-plasma/i3/xmonad had them,
xfce/enlightenment/budgie/deepin/kde-neon didn't). Per-DE applet
packages (network-manager-gnome for GTK DEs, plasma-nm for KDE)
stay in the per-DE yamls since they're only pulled on the DEs
that need them.

Network assets live under tools/modules/desktops/networking/ so
the layout mirrors branding/, greeters/, skel/ — a dedicated
subdirectory per install-time concern. The function is wired into
the install pipeline after module_desktop_branding, before the
per-user group/DM work, so it runs once per install in both
build-time and runtime paths.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 20, 2026

Walkthrough

This change introduces desktop networking configuration support by adding a new helper function that switches the system's network renderer from systemd-networkd to NetworkManager. The implementation includes three new NetworkManager configuration fragments and a Netplan configuration file that establishes NetworkManager as the renderer with DHCP device management. The helper function includes conditional logic to skip runtime changes in build mode and container environments. Two networking packages (network-manager and netplan.io) are added to the minimal desktop package tier.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: converting netplan's renderer from systemd-networkd to NetworkManager during desktop installation on minimal images.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, detailing the networking transition logic, YAML modifications, affected files, and a thorough test plan.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch desktop-install-networking

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added size/medium PR with more then 50 and less then 250 lines 05 Milestone: Second quarter release labels Apr 20, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
tools/modules/desktops/networking/netplan/00-default-use-network-manager.yaml (1)

12-18: Minor: comment attributes DHCP-on-carrier to this YAML, but it's NM that provides it.

The YAML declares only the renderer; it has no ethernets/wifis/dhcp4 blocks, so the "come up with DHCP once carrier is detected" behavior is actually NetworkManager's default policy (its auto-generated "Wired connection 1"-style profiles), not something netplan emits from this file. Consider tweaking the wording to make clear this is NM's default once control has been passed over. Non-blocking.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@tools/modules/desktops/networking/netplan/00-default-use-network-manager.yaml`
around lines 12 - 18, The comment incorrectly attributes DHCP-on-carrier
behavior to this netplan YAML; update the comment to state that this file only
hands control to NetworkManager (network with renderer: NetworkManager) and that
NetworkManager provides the default auto-generated DHCP-on-carrier profiles
(e.g., "Wired connection 1") rather than netplan emitting dhcp4/ethernets/wifis
settings; keep the existing YAML (network / version: 2 / renderer:
NetworkManager) but rephrase the top comment to reflect that nuance.
tools/modules/desktops/module_desktops.sh (1)

190-204: Enable/start NetworkManager.service before netplan apply, not after.

Current order:

  1. netplan generate && netplan apply (lines 195‑196)
  2. srv_enable + srv_start NetworkManager.service (lines 203‑204)

netplan apply with renderer: NetworkManager writes keyfiles to /run/NetworkManager/system-connections/ and then expects NM to pick them up. If NM is disabled/masked at this point (e.g., installed into a partially-booted system, or a distro where the postinst's dh_installsystemd hook didn't enable it because policy-rc.d denied it), the apply effectively no-ops the hand-off and the link is down until the next boot — the exact "orphaned network" the binary-presence guard at line 138 is trying to prevent.

Enabling + starting NM first is cheap, idempotent, and removes the ordering dependency on netplan apply's ability to start its backend:

♻️ Proposed reordering
+	# Make sure NM is enabled + running before netplan hands off
+	# to it. On a freshly-installed NM the postinst usually enables
+	# the unit, but we can't rely on that in chroot-style installs
+	# where policy-rc.d blocked postinst activation.
+	srv_enable NetworkManager.service 2>/dev/null || true
+	srv_start  NetworkManager.service 2>/dev/null || true
+
 	# Live install. Regenerate netplan output and apply it. netplan
 	# apply stops systemd-networkd.service on interfaces it hands
 	# over to NetworkManager, so the user's current SSH session over
 	# those interfaces can stall briefly — that's expected.
 	if command -v netplan > /dev/null 2>&1; then
 		netplan generate 2>&1 || echo "Warning: netplan generate failed" >&2
 		netplan apply    2>&1 || echo "Warning: netplan apply failed" >&2
 	fi
-
-	# Make sure NM is enabled + started. On a minimal image the
-	# service was installed a moment ago and masked/not enabled by
-	# default on some distros; enabling + starting here is
-	# idempotent.
-	srv_enable NetworkManager.service 2>/dev/null || true
-	srv_start  NetworkManager.service 2>/dev/null || true
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tools/modules/desktops/module_desktops.sh` around lines 190 - 204, The
netplan apply step can no-op if NetworkManager is disabled/masked; move the
NetworkManager startup before running netplan so keyfiles are picked up
immediately: call srv_enable and srv_start for NetworkManager.service (the
existing srv_enable NetworkManager.service 2>/dev/null || true and srv_start
NetworkManager.service 2>/dev/null || true invocations) before invoking netplan
generate and netplan apply, preserving the same redirections and idempotent
behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tools/modules/desktops/module_desktops.sh`:
- Around line 190-204: The netplan apply step can no-op if NetworkManager is
disabled/masked; move the NetworkManager startup before running netplan so
keyfiles are picked up immediately: call srv_enable and srv_start for
NetworkManager.service (the existing srv_enable NetworkManager.service
2>/dev/null || true and srv_start NetworkManager.service 2>/dev/null || true
invocations) before invoking netplan generate and netplan apply, preserving the
same redirections and idempotent behavior.

In
`@tools/modules/desktops/networking/netplan/00-default-use-network-manager.yaml`:
- Around line 12-18: The comment incorrectly attributes DHCP-on-carrier behavior
to this netplan YAML; update the comment to state that this file only hands
control to NetworkManager (network with renderer: NetworkManager) and that
NetworkManager provides the default auto-generated DHCP-on-carrier profiles
(e.g., "Wired connection 1") rather than netplan emitting dhcp4/ethernets/wifis
settings; keep the existing YAML (network / version: 2 / renderer:
NetworkManager) but rephrase the top comment to reflect that nuance.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 77718780-bce4-41e0-a462-16800e743445

📥 Commits

Reviewing files that changed from the base of the PR and between 8269c1a and 4bac6d3.

📒 Files selected for processing (6)
  • tools/modules/desktops/module_desktops.sh
  • tools/modules/desktops/networking/NetworkManager/00-armbian-readme.conf
  • tools/modules/desktops/networking/NetworkManager/zz-10-override-wifi-random-mac-disable.conf
  • tools/modules/desktops/networking/NetworkManager/zz-20-override-wifi-powersave-disable.conf
  • tools/modules/desktops/networking/netplan/00-default-use-network-manager.yaml
  • tools/modules/desktops/yaml/common.yaml

@igorpecovnik igorpecovnik merged commit 882a7bc into main Apr 20, 2026
199 of 221 checks passed
@igorpecovnik igorpecovnik deleted the desktop-install-networking branch April 20, 2026 07:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

05 Milestone: Second quarter release size/medium PR with more then 50 and less then 250 lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant