Files
dotfiles/system-config/modules/host_system.py
T
alex ed063ab1fe feat(desktop): consolidate declarative workstation profile
Capture desktop-specific system, session, Noctalia, and Pi integration alongside shared laptop support. Retire obsolete X11 configuration and make package ownership explicit for repeatable Decman deployments.
2026-08-24 20:20:58 +02:00

295 lines
11 KiB
Python

"""System files and concern-scoped unit enablement for machine profiles."""
from __future__ import annotations
from pathlib import Path
import decman
from decman.plugins import systemd
ROOT = Path(__file__).resolve().parents[1]
MANIFESTS = ROOT / "manifests"
def _units(*names: str) -> set[str]:
units: set[str] = set()
for name in names:
units |= {
line.strip()
for line in (MANIFESTS / name).read_text(encoding="utf-8").splitlines()
if line.strip()
}
return units
class UserConfigConcern(decman.Module):
"""Home-directory configuration owned by a named local user."""
def __init__(
self,
name: str,
files: dict[str, str | tuple[str, int]] | None = None,
directories: dict[str, str] | None = None,
user: str = "alex",
) -> None:
super().__init__(f"user:{name}")
self._files = files or {}
self._directories = directories or {}
self.user = user
def files(self) -> dict[str, decman.File]:
return {
target: decman.File(
source_file=str(
ROOT / (source[0] if isinstance(source, tuple) else source)
),
owner=self.user,
permissions=source[1] if isinstance(source, tuple) else 0o644,
)
for target, source in self._files.items()
}
def directories(self) -> dict[str, decman.Directory]:
return {
target: decman.Directory(
source_directory=str(ROOT / source),
bin_files=True,
owner=self.user,
permissions=0o644,
)
for target, source in self._directories.items()
}
class SystemConcern(decman.Module):
"""One host/system concern with explicit files and unit manifests."""
def __init__(
self,
name: str,
files: dict[str, str | tuple[str, int]] | None = None,
system_manifests: tuple[str, ...] = (),
user_manifests: tuple[str, ...] = (),
user: str = "alex",
) -> None:
super().__init__(f"system:{name}")
self._files = files or {}
self._system_manifests = system_manifests
self._user_manifests = user_manifests
self.user = user
def files(self) -> dict[str, decman.File]:
return {
target: decman.File(
source_file=str(
ROOT / (source[0] if isinstance(source, tuple) else source)
),
permissions=source[1] if isinstance(source, tuple) else 0o644,
)
for target, source in self._files.items()
}
def on_change(self, store: decman.Store) -> None:
if self.name == "system:locale":
decman.prg(["locale-gen"])
if self.name == "system:boot":
decman.prg(["mkinitcpio", "-P"])
@systemd.units
def system_units(self) -> set[str]:
return _units(*self._system_manifests)
@systemd.user_units
def user_units(self) -> dict[str, set[str]]:
return {self.user: _units(*self._user_manifests)}
def common_user_config() -> list[UserConfigConcern]:
return [
UserConfigConcern(
"common-config",
{
"/home/alex/.config/environment.d/pi-status-bridge.conf": (
"config/user/common/environment.d/pi-status-bridge.conf"
),
"/home/alex/.config/fish/config.fish": "config/user/common/fish/config.fish",
"/home/alex/.config/hypr/hypridle.conf": "config/user/common/hypr/hypridle.conf",
"/home/alex/.config/hypr/hyprland.lua": "config/user/common/hypr/hyprland.lua",
"/home/alex/.config/hypr/hyprlock.conf": "config/user/common/hypr/hyprlock.conf",
"/home/alex/.config/kitty/kitty.conf": "config/user/common/kitty/kitty.conf",
"/home/alex/.config/mimeapps.list": "config/user/common/mime/mimeapps.list",
"/home/alex/.config/noctalia/10-base.toml": "config/user/common/noctalia/10-base.toml",
"/home/alex/.config/noctalia/palettes/Ember OLED.json": (
"config/user/common/noctalia/palettes/Ember OLED.json"
),
"/home/alex/.config/systemd/user/idle-inhibitor-monitor.service": (
"config/user/common/systemd/user/idle-inhibitor-monitor.service"
),
"/home/alex/.config/systemd/user/pi-status-bridge.service": (
"config/user/common/systemd/user/pi-status-bridge.service"
),
"/home/alex/.config/systemd/user/ssh-agent.service": (
"config/user/common/systemd/user/ssh-agent.service"
),
"/home/alex/.config/user-dirs.dirs": "config/user/common/user-dirs/user-dirs.dirs",
"/home/alex/.local/bin/idle-inhibitor-monitor": (
"config/user/common/bin/idle-inhibitor-monitor",
0o755,
),
"/home/alex/.local/bin/pi-status-ui": (
"config/user/common/bin/pi-status-ui",
0o755,
),
"/home/alex/.local/bin/wayshell-blanker": (
"config/user/common/bin/wayshell-blanker",
0o755,
),
},
{
"/home/alex/.config/alacritty": "config/user/common/alacritty",
"/home/alex/.config/yazi": "config/user/common/yazi",
"/home/alex/.local/share/noctalia/plugins/knowledge-lookup": (
"config/user/common/noctalia/plugins/knowledge-lookup"
),
"/home/alex/.local/share/noctalia/plugins/pi-status-bridge": (
"config/user/common/noctalia/plugins/pi-status-bridge"
),
"/home/alex/.local/share/noctalia/plugins/system-status": (
"config/user/common/noctalia/plugins/system-status"
),
},
)
]
def laptop_user_config() -> list[UserConfigConcern]:
return [
UserConfigConcern(
"laptop-config",
{
"/home/alex/.config/hypr/machine.lua": "config/user/laptop/hypr/machine.lua",
"/home/alex/.config/noctalia/90-machine.toml": (
"config/user/laptop/noctalia/90-machine.toml"
),
"/home/alex/.config/noctalia/99-extend.toml": (
"config/user/laptop/noctalia/99-extend.toml"
),
},
)
]
def desktop_user_config() -> list[UserConfigConcern]:
return [
UserConfigConcern(
"desktop-config",
{
"/home/alex/.config/hypr/machine.lua": "config/user/desktop/hypr/machine.lua",
"/home/alex/.config/noctalia/90-machine.toml": (
"config/user/desktop/noctalia/90-machine.toml"
),
},
)
]
def common_system() -> list[SystemConcern | UserConfigConcern]:
return [
SystemConcern(
"package-policy",
{
"/etc/pacman.conf": "config/system/common/pacman/pacman.conf",
"/etc/makepkg.conf": "config/system/common/makepkg/makepkg.conf",
},
),
SystemConcern(
"locale",
{
"/etc/locale.conf": "config/system/common/locale/locale.conf",
"/etc/locale.gen": "config/system/common/locale/locale.gen",
},
),
SystemConcern(
"keyboard",
{
"/etc/vconsole.conf": "config/system/common/keyboard/vconsole.conf",
"/etc/X11/xorg.conf.d/00-keyboard.conf": "config/system/common/keyboard/x11.conf",
},
),
SystemConcern("base", system_manifests=("common/base-system.txt",)),
SystemConcern("network", system_manifests=("common/network-system.txt",)),
SystemConcern("desktop", user_manifests=("common/desktop-user.txt",)),
SystemConcern("local", user_manifests=("common/local-user.txt",)),
SystemConcern(
"network-services", system_manifests=("common/network-services-system.txt",)
),
SystemConcern(
"development", system_manifests=("common/development-system.txt",)
),
SystemConcern("privacy", system_manifests=("common/privacy-system.txt",)),
*common_user_config(),
]
def laptop_system() -> list[SystemConcern | UserConfigConcern]:
return [
*common_system(),
SystemConcern(
"laptop",
{
"/etc/keyd/default.conf": "config/system/common/keyd.conf",
"/etc/NetworkManager/conf.d/wifi-powersave.conf": "config/system/laptop/wifi-powersave.conf",
"/etc/modprobe.d/iwlwifi.conf": "config/system/laptop/iwlwifi.conf",
"/etc/X11/xorg.conf.d/30-touchpad.conf": "config/system/laptop/touchpad.conf",
"/etc/tlp.conf": "config/system/laptop/power/tlp.conf",
"/etc/systemd/sleep.conf.d/90-laptop.conf": "config/system/laptop/sleep.conf.d/90-laptop.conf",
"/etc/systemd/logind.conf.d/90-noctalia-battery-idle.conf": "config/system/laptop/systemd/90-noctalia-battery-idle.conf",
"/boot/EFI/refind/refind.conf": (
"config/system/laptop/refind/refind.conf",
0o755,
),
"/boot/refind_linux.conf": (
"config/system/laptop/refind/refind_linux.conf",
0o755,
),
},
system_manifests=("laptop/hardware-system.txt",),
),
SystemConcern(
"boot",
{"/etc/mkinitcpio.conf": "config/system/laptop/boot/mkinitcpio.conf"},
),
*laptop_user_config(),
]
def desktop_system() -> list[SystemConcern | UserConfigConcern]:
"""Desktop: shared policy plus this host's boot, GPU, input, and session state."""
return [
*common_system(),
SystemConcern(
"desktop-host",
{
"/etc/fstab": "config/system/desktop/storage/fstab",
"/etc/hostname": "config/system/desktop/identity/hostname",
"/etc/keyd/default.conf": "config/system/desktop/input/keyd.conf",
"/etc/modprobe.d/nvidia-pm.conf": "config/system/desktop/nvidia/nvidia-pm.conf",
"/etc/NetworkManager/NetworkManager.conf": (
"config/system/desktop/network/NetworkManager.conf"
),
"/etc/sddm.conf.d/10-theme.conf": "config/system/desktop/sddm/10-theme.conf",
"/etc/udev/rules.d/50-zsa.rules": "config/system/desktop/input/50-zsa.rules",
},
system_manifests=("desktop/hardware-system.txt",),
),
SystemConcern(
"boot",
{
"/boot/EFI/refind/refind.conf": "config/system/desktop/boot/refind.conf",
"/boot/refind_linux.conf": "config/system/desktop/boot/refind_linux.conf",
"/etc/mkinitcpio.conf": "config/system/desktop/boot/mkinitcpio.conf",
},
),
*desktop_user_config(),
]