From fb748c217c336d0610a6659a16f649a90660d15c Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Tue, 16 Jun 2026 17:08:41 +0100 Subject: [PATCH] feat(services): opt-in Tailscale + Syncthing (nomarchy.services.*) Start the opt-in services surface: nomarchy.services.{tailscale,syncthing}, off by default, in modules/nixos/services.nix. Tailscale ships the daemon (authenticate with `sudo tailscale up`); Syncthing runs as the login user with its GUI on 127.0.0.1:8384 (overrideDevices/Folders off so GUI-managed folders survive rebuilds). username is read lazily, only when Syncthing is on. Commented examples in the downstream system.nix template per the opt-in convention. Co-Authored-By: Claude Opus 4.8 --- README.md | 2 ++ docs/ROADMAP.md | 19 ++++++++++------ modules/nixos/default.nix | 2 +- modules/nixos/services.nix | 40 +++++++++++++++++++++++++++++++++ templates/downstream/system.nix | 3 +++ 5 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 modules/nixos/services.nix diff --git a/README.md b/README.md index a27ef5a..b243e28 100644 --- a/README.md +++ b/README.md @@ -219,6 +219,8 @@ examples: **[docs/OVERRIDES.md](docs/OVERRIDES.md)**. | `nomarchy.system.power.laptop` | `false` | Marks a laptop, gating battery-only features; the installer sets it when a battery is present | | `nomarchy.system.power.thermal.enable` | `false` | thermald (Intel-only); the installer enables it on a GenuineIntel CPU | | `nomarchy.system.power.batteryChargeLimit` | `null` | Stop charging at this % (e.g. `80`) where the hardware supports it; needs `power.laptop` | +| `nomarchy.services.tailscale.enable` | `false` | Opt-in: Tailscale mesh VPN (then `sudo tailscale up`) | +| `nomarchy.services.syncthing.enable` | `false` | Opt-in: Syncthing file sync as the login user (GUI at `127.0.0.1:8384`) | Beyond the `nomarchy.*` surface, the system layer turns on the usual desktop services with `lib.mkDefault` (override natively). One worth diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index c6ad23f..eaef340 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -261,22 +261,27 @@ how to override it. Items marked ✓ are shipped. application suite above — heavier or more personal integrations shipped **off by default**, each a `nomarchy.services..enable` toggle a downstream flips on in one line. Keeps the base lean while making common - additions trivial. Candidates by area: - - **cloud/sync:** Nextcloud client; Syncthing (`services.syncthing`) + additions trivial. **✓ First two shipped** — `nomarchy.services.tailscale` + and `nomarchy.services.syncthing` (`modules/nixos/services.nix`, system-side; + Syncthing runs as the login user with its GUI on 127.0.0.1:8384), with + commented examples in the downstream `system.nix` template. More candidates + by area: + - ✓ **cloud/sync:** Syncthing (`services.syncthing`); Nextcloud client (todo) - **local AI:** LM Studio (`lmstudio`); Ollama (`services.ollama`, optional GPU accel) — pairs with the menu's Ask-Claude philosophy - **containers/VMs:** Docker/Podman; libvirt + virt-manager - - **networking:** Tailscale (`services.tailscale`); WireGuard + - ✓ **networking:** Tailscale (`services.tailscale`); WireGuard (todo) - **gaming/media:** Steam (`programs.steam`); OBS Studio - **devices:** printing (CUPS + Avahi); KDE Connect / phone integration; OpenRGB - **backup:** restic/borg (`services.restic`) - **escape hatch:** Flatpak (`services.flatpak`) for apps outside nixpkgs - Decisions: the curated set; whether system services and GUI apps share one - surface or split (`nomarchy.services.*` system-side vs home-side packages); - and how it relates to `nomarchy.apps.*` (opt-out suite). Unfree entries are - already covered (`allowUnfree = true`). + Surface decided: `nomarchy.services.*`, system-side for system services + (home-side ones can extend the same prefix later). Remaining: curate the + rest (Ollama, containers, Steam/OBS, printing, backups, Flatpak …) and + decide how it relates to `nomarchy.apps.*` (opt-out suite). Unfree entries + are already covered (`allowUnfree = true`). - ✓ **Display / monitor management:** declarative `nomarchy.monitors` (a per-output schema — name/resolution/position/scale/transform/mirror/ bitdepth/vrr/disable) generates Hyprland `monitor` rules, keeping the diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix index 37358db..391fea9 100644 --- a/modules/nixos/default.nix +++ b/modules/nixos/default.nix @@ -22,7 +22,7 @@ let ''; in { - imports = [ ./options.nix ./plymouth.nix ./file-manager.nix ./power.nix ]; + imports = [ ./options.nix ./plymouth.nix ./file-manager.nix ./power.nix ./services.nix ]; config = { # The safe half of distro branding: distroName flows into diff --git a/modules/nixos/services.nix b/modules/nixos/services.nix new file mode 100644 index 0000000..739dcdf --- /dev/null +++ b/modules/nixos/services.nix @@ -0,0 +1,40 @@ +# Opt-in services & integrations — off by default, one toggle each, enabled +# in system.nix (see the commented examples in the downstream template). +# These are system services: Tailscale is system-only, and Syncthing runs as +# the login user. Their own `nomarchy.services.*` namespace, distinct from the +# distro's core `nomarchy.system.*` toggles. `username` (from specialArgs) is +# read lazily, only when Syncthing is enabled. +{ config, lib, ... }@args: + +let + cfg = config.nomarchy.services; +in +{ + options.nomarchy.services = { + tailscale.enable = lib.mkEnableOption '' + Tailscale, the mesh VPN — ships the daemon; authenticate once with + `sudo tailscale up`''; + + syncthing.enable = lib.mkEnableOption '' + Syncthing continuous file sync, running as the login user — add + folders and devices in the web UI at http://127.0.0.1:8384''; + }; + + config = lib.mkMerge [ + (lib.mkIf cfg.tailscale.enable { + services.tailscale.enable = true; + }) + + (lib.mkIf cfg.syncthing.enable { + services.syncthing = { + enable = true; + user = args.username; + # Manage folders/devices in the GUI; don't let the (empty) declarative + # config wipe them on a rebuild. + overrideDevices = false; + overrideFolders = false; + guiAddress = "127.0.0.1:8384"; + }; + }) + ]; +} diff --git a/templates/downstream/system.nix b/templates/downstream/system.nix index c0a57a2..04206cf 100644 --- a/templates/downstream/system.nix +++ b/templates/downstream/system.nix @@ -30,6 +30,9 @@ # batteryChargeLimit = 80; # cap charging for longevity # thermal.enable = true; # thermald (Intel CPUs) # }; + # + # nomarchy.services.tailscale.enable = true; # mesh VPN — then `sudo tailscale up` + # nomarchy.services.syncthing.enable = true; # file sync — GUI at http://127.0.0.1:8384 system.stateVersion = "26.05"; }