239 lines
8.6 KiB
Python
239 lines
8.6 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] | 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), owner=self.user, permissions=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/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/yazi": "config/user/common/yazi"},
|
|
)
|
|
]
|
|
|
|
|
|
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 desktop-specific home configuration."""
|
|
return [*common_system(), *desktop_user_config()]
|