self: { config, lib, pkgs, ... }: let cfg = config.services.nix-ota-server; inherit (lib) mkEnableOption mkOption mkIf types; in { options.services.nix-ota-server = { enable = mkEnableOption "nix-ota control server"; package = mkOption { type = types.package; default = self.packages.${pkgs.system}.nix-ota-server; }; listen = mkOption { type = types.str; default = "0.0.0.0:8080"; }; dataDir = mkOption { type = types.path; default = "/var/lib/nix-ota-server"; }; publishTokenFile = mkOption { type = types.nullOr types.path; default = null; description = "Path to a file containing the bearer token for /publish."; }; openFirewall = mkOption { type = types.bool; default = false; }; }; config = mkIf cfg.enable { users.users.nix-ota = { isSystemUser = true; group = "nix-ota"; home = cfg.dataDir; createHome = true; }; users.groups.nix-ota = {}; systemd.services.nix-ota-server = { description = "nix-ota control server"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { User = "nix-ota"; Group = "nix-ota"; WorkingDirectory = cfg.dataDir; Restart = "on-failure"; StateDirectory = "nix-ota-server"; }; script = '' ${lib.optionalString (cfg.publishTokenFile != null) '' export NIX_OTA_PUBLISH_TOKEN="$(cat ${cfg.publishTokenFile})" ''} exec ${cfg.package}/bin/nix-ota-server \ --listen ${cfg.listen} \ --db ${cfg.dataDir}/nix-ota.db ''; }; networking.firewall = mkIf cfg.openFirewall { allowedTCPPorts = [ (lib.toInt (lib.last (lib.splitString ":" cfg.listen))) ]; }; }; }