{ pkgs, config, lib, ... }: let cfg = config.services.syncyomi; defaultUser = "syncyomi"; defaultGroup = defaultUser; defaultStateDir = "/var/lib/syncyomi"; settingsFormat = pkgs.formats.toml { }; in { options.services.syncyomi = { enable = lib.mkEnableOption null; package = lib.mkPackageOption pkgs "syncyomi" {}; user = lib.mkOption { type = lib.types.str; default = defaultUser; }; group = lib.mkOption { type = lib.types.str; default = defaultGroup; }; stateDir = lib.mkOption { type = lib.types.str; default = defaultStateDir; }; settings = lib.mkOption { type = settingsFormat.type; default = { }; }; }; config = lib.mkIf cfg.enable { services.syncyomi.settings = { host = lib.mkDefault "127.0.0.1"; port = lib.mkDefault 8282; checkForUpdates = lib.mkDefault false; }; users = { users = lib.mkIf (cfg.user == defaultUser) { ${defaultUser} = { home = cfg.stateDir; group = cfg.group; isSystemUser = true; description = "Syncyomi daemon user"; }; }; groups = lib.mkIf (cfg.group == defaultGroup) { ${defaultGroup} = { }; }; }; systemd.services.syncyomi = { description = "Syncyomi service"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Restart = "on-failure"; User = cfg.user; Group = cfg.group; ExecStart = "${cfg.package}/bin/syncyomi --config ${cfg.stateDir}"; ReadWritePaths = [ cfg.stateDir ]; ProcSubset = "pid"; ProtectProc = "invisible"; CapabilityBoundingSet = ""; NoNewPrivileges = true; ProtectSystem = "strict"; ProtectHome = true; PrivateTmp = true; PrivateDevices = true; PrivateUsers = true; PrivateMounts = true; ProtectHostname = true; ProtectClock = true; ProtectKernelTunables = true; ProtectKernelModules = true; ProtectKernelLogs = true; ProtectControlGroups = true; RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ]; RestrictNamespaces = true; LockPersonality = true; MemoryDenyWriteExecute = true; RestrictRealtime = true; RestrictSUIDSGID = true; RemoveIPC = true; SystemCallArchitectures = "native"; SystemCallFilter = [ "@system-service" "~@keyring @privileged @resources" "setrlimit" ]; }; }; systemd.tmpfiles.rules = let configToml = settingsFormat.generate "config.toml" cfg.settings; in [ "d '${cfg.stateDir}' 0750 ${cfg.user} ${cfg.group} - -" "z '${cfg.stateDir}' 0750 ${cfg.user} ${cfg.group} - -" "L+ '${cfg.stateDir}/config.toml' - - - - ${configToml}" ]; }; }