Files
dotfiles/docs/superpowers/specs/2026-05-13-networkmanager-activation-design.md
T
funman300 101accc26b docs: spec for NetworkManager activation with iwd backend
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 14:43:10 -07:00

134 lines
5.3 KiB
Markdown

# NetworkManager Activation Design
**Date:** 2026-05-13
**Status:** Approved
## Summary
Activate NetworkManager (already installed but disabled) and configure it to use `iwd` as its wifi backend. Disables `systemd-networkd` (the current connection manager) to avoid conflicts. Re-enables `nm-applet` and `networkmanager_dmenu` paths that were dead because NM wasn't running.
## Current Behaviour
- `iwd` is running — manages wifi at the protocol level
- `systemd-networkd` is running — handles DHCP and link config
- `NetworkManager.service` is installed but **disabled** (inactive/dead)
- `nm-applet` runs at no-op (no dbus peer to connect to)
- `networkmanager_dmenu` (waybar `network` module's on-click) errors with "NetworkManager is not running"
End result: connectivity works, but the entire NM-based UI ecosystem (applet, dmenu picker, nmcli) is non-functional.
## Target Behaviour
- `iwd` continues running, now as NM's wifi backend
- `NetworkManager` runs as the connection manager
- `systemd-networkd` stopped and disabled
- `nm-applet` shows connection state in the waybar tray (works because the SNI watcher chain works)
- `networkmanager_dmenu` opens a wofi-style picker that lists/connects to known networks
- Existing wifi profiles preserved (NM reads iwd's known-networks via the backend interface)
## Implementation
### Tracked dotfile
**`NetworkManager/conf.d/wifi-backend.conf`** (new file in repo, deployed to `/etc/NetworkManager/conf.d/`):
```ini
[device]
wifi.backend=iwd
```
This is the only file NM needs. It tells NM to delegate wifi to iwd (which is already running) instead of spawning its own `wpa_supplicant`. Modern, well-supported configuration on Arch.
### `install.sh`
Append one block in the existing system-deploy section (after the hibernate `sleep.conf.d` line):
```bash
sudo install -Dm644 "$(pwd)/NetworkManager/conf.d/wifi-backend.conf" \
/etc/NetworkManager/conf.d/wifi-backend.conf
```
`install -Dm644` creates `/etc/NetworkManager/conf.d/` if it doesn't exist (it usually does, since the NM package ships an empty stub) and sets mode 644.
### `packages.txt`
Re-add `network-manager-applet` (removed in commit `4303562` when nm-applet was non-functional). Insertion can go anywhere — alphabetical-ish near the existing `networkmanager`-related lines.
### `niri/config.kdl`
Re-add the spawn-at-startup line (removed in same earlier commit):
```kdl
spawn-at-startup "nm-applet" "--indicator"
```
Position: with the other applet/daemon spawns, alphabetical order doesn't matter.
### One-time service swap (manual, with sudo)
Documented in README, not scripted. Two commands run once:
```bash
sudo systemctl disable --now systemd-networkd
sudo systemctl enable --now NetworkManager
```
Why not script it: systemd unit state is persistent. Once flipped, it stays. Doesn't need to be in `install.sh` (which runs frequently). A one-time README instruction matches the existing pattern for `enable-hibernation.sh`.
### `README.md`
Append a subsection under `## Setup`, alongside the existing "One-time hibernation enablement":
```markdown
### One-time NetworkManager activation
After `install.sh` deploys the NM config, swap from systemd-networkd to NetworkManager (one-time, persistent across reboots):
\`\`\`bash
sudo systemctl disable --now systemd-networkd
sudo systemctl enable --now NetworkManager
\`\`\`
Wifi will drop for a few seconds and reconnect via iwd's stored profiles. If reconnection fails, re-enter the wifi password via `nm-applet` or `networkmanager_dmenu`.
```
## Files Touched
| File | Action |
|---|---|
| `NetworkManager/conf.d/wifi-backend.conf` | created |
| `install.sh` | append one `sudo install -Dm644` line |
| `packages.txt` | re-add `network-manager-applet` |
| `niri/config.kdl` | re-add `spawn-at-startup "nm-applet" "--indicator"` |
| `README.md` | append "One-time NetworkManager activation" subsection |
## Verification
After `install.sh` + the two systemctl commands:
```bash
systemctl is-active NetworkManager # active
systemctl is-active systemd-networkd # inactive
nmcli general status # prints connectivity status
nmcli -f WIFI-PROPERTIES.WPA general status # confirms iwd backend is alive
nmcli connection show --active # shows the wifi connection
busctl --user get-property org.kde.StatusNotifierWatcher \
/StatusNotifierWatcher org.kde.StatusNotifierWatcher RegisteredStatusNotifierItems
# should include nm-applet's tray entry
```
Behavioural checks:
1. Wifi stays connected (after a brief drop during the swap).
2. Click waybar's network widget — `networkmanager_dmenu` opens with available networks.
3. The nm-applet tray icon shows current connection state.
## Out of Scope
- **Migrating iwd profiles to NM-format files** — not needed; NM reads iwd's known-networks via the backend interface.
- **Removing `iwd`** — kept as the wifi backend.
- **Removing the `networkmanager` package** — already installed; we just enable the service.
- **DNS / dispatcher / split-tunnel / VPN config** — beyond scope; default NM behaviour is fine.
- **Wired-only fallback** — out of scope; NM handles ethernet automatically when present.
- **Deleting the obsolete `nm-applet` removal commit from history** — keep history honest.
- **Auto-running the systemctl commands from `install.sh`** — out of scope; service-state changes are one-time and persistent.