# 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-side: their own `nomarchy.services.*` namespace, distinct # from the distro's core `nomarchy.system.*` toggles. `username` (from # specialArgs) is read lazily, only where a service needs it. { config, lib, pkgs, ... }@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''; podman.enable = lib.mkEnableOption '' Podman for rootless containers, with `docker` aliased to it and DNS on the default network; the login user gets a subuid/subgid range''; flatpak.enable = lib.mkEnableOption '' Flatpak, with the Flathub remote added system-wide — install apps with `flatpak install flathub `''; pika.enable = lib.mkEnableOption '' Pika Backup, a friendly GUI for scheduled Borg backups (the app; configure repositories and schedules inside it)''; steam.enable = lib.mkEnableOption '' Steam (Valve's game store/launcher) via programs.steam — which wires up the 32-bit graphics libraries, controller udev rules and Remote-Play firewall ports a bare package can't. Unfree''; libvirt.enable = lib.mkEnableOption '' libvirt/KVM virtualisation with the virt-manager GUI — runs the libvirtd daemon and adds the login user to the `libvirtd` group, so VMs can be managed without root''; obs.enable = lib.mkEnableOption '' OBS Studio for screen recording and streaming, plus a v4l2loopback virtual camera — so an OBS scene can be selected as a webcam in Zoom, Teams or a browser (screen capture itself already works over the desktop's PipeWire portal)''; }; 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"; }; }) (lib.mkIf cfg.podman.enable { virtualisation.podman = { enable = true; dockerCompat = lib.mkDefault true; # `docker` → podman (off if you run real docker) defaultNetwork.settings.dns_enabled = true; # DNS for rootless containers }; # Rootless podman needs a subuid/subgid range for the user. users.users.${args.username}.autoSubUidGidRange = lib.mkDefault true; }) (lib.mkIf cfg.flatpak.enable { services.flatpak.enable = true; # Flatpak ships no remotes; add Flathub system-wide. Idempotent # (--if-not-exists), and it reads the .flatpakrepo over the network, so # it waits for connectivity and simply retries next boot if offline. systemd.services.nomarchy-flathub = { description = "Add the Flathub Flatpak remote"; wantedBy = [ "multi-user.target" ]; wants = [ "network-online.target" ]; after = [ "network-online.target" ]; path = [ pkgs.flatpak ]; serviceConfig.Type = "oneshot"; script = '' flatpak remote-add --system --if-not-exists flathub \ https://dl.flathub.org/repo/flathub.flatpakrepo ''; }; }) (lib.mkIf cfg.pika.enable { environment.systemPackages = [ pkgs.pika-backup ]; }) (lib.mkIf cfg.steam.enable { # The Steam package alone misses the system bits a game needs: the # 32-bit graphics stack, controller udev rules, Remote-Play ports. programs.steam.enable = true; }) (lib.mkIf cfg.libvirt.enable { virtualisation.libvirtd.enable = true; programs.virt-manager.enable = true; # Group membership lets the user reach the system libvirtd socket # (manage VMs) without sudo. Merges with the user's other extraGroups. users.users.${args.username}.extraGroups = [ "libvirtd" ]; }) (lib.mkIf cfg.obs.enable { environment.systemPackages = [ pkgs.obs-studio ]; # Virtual camera: OBS streams a scene into a v4l2 loopback device that # Zoom/Teams/browsers then pick up as a webcam. exclusive_caps=1 is the # bit that makes those apps actually list the device. boot.extraModulePackages = [ config.boot.kernelPackages.v4l2loopback ]; boot.kernelModules = [ "v4l2loopback" ]; boot.extraModprobeConfig = '' options v4l2loopback devices=1 video_nr=10 card_label="OBS Virtual Camera" exclusive_caps=1 ''; }) ]; }