feat(services): openrgb + restic toggles; close out the opt-in services item
Finishing the four remaining "opt-in services" candidates — but two of
them aren't service-shaped, so the package-vs-toggle principle applies:
- Nextcloud client → a bare tray app; already in the app-suite menu,
not a service.
- WireGuard → NetworkManager (on distro-wide) imports .conf
tunnels natively, so there's no daemon to "just
enable". Only the wg/wg-quick CLI is missing →
wireguard-tools added to the app-suite menu.
The two that ARE config-backed become nomarchy.services.* toggles:
- openrgb → services.hardware.openrgb (daemon + device udev rules).
- restic → a small scaffolded surface (repository / passwordFile /
paths) over services.restic.backups: daily timer, 7/4/6
retention, --exclude-caches, repo auto-init. Asserts that
repository + passwordFile are set when enabled. passwordFile
is typed `str`, not `path`, so a flake-relative secret can't
be copied into the world-readable store.
README option table and ROADMAP (services now "Seventeen shipped";
cloud-sync / networking / backup / devices areas updated) + the downstream
system.nix examples. Both branches eval-verified; the restic assertions
confirmed firing when repo/password are unset.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -234,6 +234,8 @@ examples: **[docs/OVERRIDES.md](docs/OVERRIDES.md)**.
|
||||
| `nomarchy.services.wireshark.enable` | `false` | Opt-in: Wireshark Qt GUI (user in `wireshark` group, capture without root) |
|
||||
| `nomarchy.services.ollama.enable` | `false` | Opt-in: Ollama local LLM runtime on `127.0.0.1:11434` (CPU; GPU via `services.ollama.acceleration`) |
|
||||
| `nomarchy.services.printing.enable` | `false` | Opt-in: CUPS + Avahi/mDNS network printer discovery |
|
||||
| `nomarchy.services.openrgb.enable` | `false` | Opt-in: OpenRGB daemon for RGB peripheral/motherboard lighting |
|
||||
| `nomarchy.services.restic.enable` | `false` | Opt-in: scheduled daily restic backup (set `.repository` + `.passwordFile`; 7/4/6 retention) |
|
||||
|
||||
Beyond the `nomarchy.*` surface, the system layer turns on the usual
|
||||
desktop services with `lib.mkDefault` (override natively). One worth
|
||||
|
||||
@@ -291,7 +291,7 @@ how to override it. Items marked ✓ are shipped.
|
||||
application suite above — heavier or more personal integrations shipped
|
||||
**off by default**, each a `nomarchy.services.<name>.enable` toggle a
|
||||
downstream flips on in one line. Keeps the base lean while making common
|
||||
additions trivial. **✓ Fifteen shipped** in `modules/nixos/services.nix`
|
||||
additions trivial. **✓ Seventeen shipped** in `modules/nixos/services.nix`
|
||||
(system-side), each with a commented example in the downstream `system.nix`
|
||||
template: `tailscale`, `syncthing` (runs as the login user, GUI on
|
||||
127.0.0.1:8384), `podman` (rootless, `docker` aliased, user subuid/subgid),
|
||||
@@ -302,24 +302,29 @@ how to override it. Items marked ✓ are shipped.
|
||||
usable as a webcam in Zoom/Teams), `docker` (rootful; asserts against the
|
||||
podman docker-compat), `kdeconnect`, `gamemode`, `adb` (android-tools;
|
||||
systemd handles the udev rules), `wireshark` (Qt GUI + the `wireshark`
|
||||
group), `ollama` (local LLM
|
||||
API on 127.0.0.1:11434), and `printing` (CUPS + Avahi mDNS). More
|
||||
candidates by area:
|
||||
- ✓ **cloud/sync:** Syncthing (`services.syncthing`); Nextcloud client (todo)
|
||||
group), `ollama` (local LLM API on 127.0.0.1:11434), `printing` (CUPS +
|
||||
Avahi mDNS), `openrgb` (RGB lighting daemon), and `restic` (scheduled
|
||||
daily backup — a small option surface: `repository`/`passwordFile`/`paths`,
|
||||
7/4/6 retention). More candidates by area:
|
||||
- ✓ **cloud/sync:** Syncthing (`services.syncthing`); Nextcloud client is a
|
||||
bare tray app (in the app-suite menu, not a service)
|
||||
- ✓ **local AI:** Ollama (`nomarchy.services.ollama`, optional GPU accel)
|
||||
ships; LM Studio is a (commented) app-suite package (a bare GUI, no
|
||||
service) — pairs with the menu's Ask-Claude philosophy
|
||||
- ✓ **containers/VMs:** Podman (`virtualisation.podman`); libvirt +
|
||||
virt-manager (`nomarchy.services.libvirt`); Docker (`nomarchy.services.docker`)
|
||||
- ✓ **networking:** Tailscale (`services.tailscale`); WireGuard (todo)
|
||||
- ✓ **networking:** Tailscale (`services.tailscale`); WireGuard needs no
|
||||
toggle — NetworkManager (on by default) imports `.conf` tunnels natively;
|
||||
the `wireguard-tools` CLI is in the app-suite menu
|
||||
- ✓ **gaming/media:** Steam (`nomarchy.services.steam`); OBS Studio
|
||||
(`nomarchy.services.obs`, with the v4l2loopback virtual camera); GameMode
|
||||
(`nomarchy.services.gamemode`)
|
||||
- ✓ **devices:** printing (CUPS + Avahi, `nomarchy.services.printing`); KDE
|
||||
Connect (`nomarchy.services.kdeconnect`); OpenRGB (todo). Plus dev tooling
|
||||
— Android `adb` and `wireshark` toggles
|
||||
- ✓ **backup:** Pika Backup (`pika-backup`, GUI over Borg); restic/borg
|
||||
services (todo)
|
||||
Connect (`nomarchy.services.kdeconnect`); OpenRGB
|
||||
(`nomarchy.services.openrgb`). Plus dev tooling — Android `adb` and
|
||||
`wireshark` toggles
|
||||
- ✓ **backup:** Pika Backup (`pika-backup`, GUI over Borg); scheduled
|
||||
headless restic (`nomarchy.services.restic`)
|
||||
- ✓ **escape hatch:** Flatpak (`services.flatpak`) + Flathub, for apps
|
||||
outside nixpkgs
|
||||
|
||||
|
||||
@@ -76,6 +76,47 @@ in
|
||||
printing.enable = lib.mkEnableOption ''
|
||||
CUPS printing with Avahi/mDNS, so network printers are auto-discovered
|
||||
(add vendor drivers via `services.printing.drivers`)'';
|
||||
|
||||
openrgb.enable = lib.mkEnableOption ''
|
||||
the OpenRGB daemon and GUI for controlling RGB lighting on peripherals
|
||||
and (where supported) motherboards — installs the udev rules for device
|
||||
access. Some motherboard controllers also need `hardware.i2c.enable`'';
|
||||
|
||||
restic = {
|
||||
enable = lib.mkEnableOption ''
|
||||
a scheduled (daily) restic backup — headless, complementing the Pika
|
||||
GUI. Backs up `paths` with sane retention (7 daily / 4 weekly /
|
||||
6 monthly); needs a `repository` and a `passwordFile` (below)'';
|
||||
|
||||
repository = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
example = "/mnt/backup/restic";
|
||||
description = ''
|
||||
The restic repository as a path or URL — e.g. `/mnt/backup/restic`,
|
||||
`sftp:user@host:/srv/restic`, `b2:bucket:/path`. Required when
|
||||
`restic.enable` is set.
|
||||
'';
|
||||
};
|
||||
|
||||
passwordFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "/etc/nomarchy/restic-password";
|
||||
description = ''
|
||||
Path to a file holding the repository password. Give an absolute
|
||||
path that lives ON THE MACHINE — not a `./file` in the flake, which
|
||||
would copy the secret into the world-readable Nix store. Required
|
||||
when `restic.enable` is set.
|
||||
'';
|
||||
};
|
||||
|
||||
paths = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ "/home" ];
|
||||
description = "Paths to include in the backup.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkMerge [
|
||||
@@ -204,5 +245,34 @@ in
|
||||
openFirewall = true;
|
||||
};
|
||||
})
|
||||
|
||||
(lib.mkIf cfg.openrgb.enable {
|
||||
services.hardware.openrgb.enable = true;
|
||||
})
|
||||
|
||||
(lib.mkIf cfg.restic.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.restic.repository != "";
|
||||
message = "nomarchy.services.restic.repository must be set when restic is enabled.";
|
||||
}
|
||||
{
|
||||
assertion = cfg.restic.passwordFile != null;
|
||||
message = "nomarchy.services.restic.passwordFile must be set when restic is enabled.";
|
||||
}
|
||||
];
|
||||
services.restic.backups.nomarchy = {
|
||||
repository = cfg.restic.repository;
|
||||
passwordFile = cfg.restic.passwordFile;
|
||||
paths = cfg.restic.paths;
|
||||
initialize = true; # create the repo on first run if it doesn't exist
|
||||
extraBackupArgs = [ "--exclude-caches" ];
|
||||
pruneOpts = [ "--keep-daily 7" "--keep-weekly 4" "--keep-monthly 6" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "daily";
|
||||
Persistent = true; # catch up a missed run after downtime
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -131,6 +131,7 @@
|
||||
# gnome-disk-utility
|
||||
# gparted
|
||||
# baobab # disk usage
|
||||
# wireguard-tools # WireGuard CLI (NetworkManager imports .conf tunnels natively)
|
||||
|
||||
# Local AI (Ollama is a service toggle in system.nix)
|
||||
# lmstudio # (unfree; large closure)
|
||||
|
||||
@@ -46,6 +46,13 @@
|
||||
# nomarchy.services.wireshark.enable = true; # Wireshark GUI (wireshark group, no root)
|
||||
# nomarchy.services.ollama.enable = true; # local LLM runtime (127.0.0.1:11434)
|
||||
# nomarchy.services.printing.enable = true; # CUPS + Avahi network printer discovery
|
||||
# nomarchy.services.openrgb.enable = true; # RGB peripheral/motherboard lighting daemon
|
||||
# nomarchy.services.restic = { # scheduled (daily) restic backup
|
||||
# enable = true;
|
||||
# repository = "/mnt/backup/restic"; # path or URL (sftp:/b2:/…)
|
||||
# passwordFile = "/etc/nomarchy/restic-password"; # absolute path, NOT in the flake
|
||||
# paths = [ "/home" ];
|
||||
# };
|
||||
|
||||
system.stateVersion = "26.05";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user