{ lib, pkgs, config, ... }: with lib; let cfg = config.services.brownpaper; cfgc = config.programs.brownpaper; package = if pkgs ? brownpaper-server && pkgs ? brownpaper then { server = pkgs.brownpaper-server; client = pkgs.brownpaper; } else (pkgs.callPackage ./. { inherit pkgs; src = ./.; }); keyDir = pkgs.runCommand "brownpaper-keys" { } '' mkdir -p $out ${concatStringsSep " && " (builtins.map (key: "cp ${key} $out/") cfg.pgpKeys)} ''; in { options.services.brownpaper = { enable = mkEnableOption "brownpaper service"; listen = mkOption { type = types.str; default = "127.0.0.1"; }; port = mkOption { type = types.int; default = 3000; }; dataDir = mkOption { type = types.path; default = "/var/lib/brownpaper"; }; user = mkOption { type = types.str; default = "brownpaper"; }; pgpKeys = mkOption { type = with types; listOf path; default = [ ]; }; gc = { enable = mkEnableOption "delete old snippets"; dates = mkOption { type = types.str; default = "00:00"; description = '' Specification (in the format described by systemd.time 7) of the time at which the garbage collector will run. ''; }; maxAge = mkOption { type = types.ints.positive; default = 60 * 24 * 30; description = "maximum age in minutes after which snippets will be garbage collected. Defaults to 30 days"; }; }; }; options.programs.brownpaper = { enable = mkEnableOption "brownpaper client"; endpoint = mkOption { type = types.str; default = "http://${cfg.listen}:${toString cfg.port}"; }; }; config = { users.users = mkIf (cfg.enable && cfg.user == "brownpaper") { ${cfg.user} = { isSystemUser = true; group = "brownpaper"; }; }; systemd.services = mkIf cfg.enable { brownpaper-init.script = '' mkdir -p '${cfg.dataDir}' chown ${cfg.user} -R '${cfg.dataDir}' '' + (optionalString (cfg.pgpKeys != [ ]) '' DATADIR='${toString cfg.dataDir}' ([ ! -s "$DATADIR/keys" ] && [ -d "$DATADIR/keys" ]) && mv "$DATADIR/keys" "$DATADIR/keys.bak" [ -s "$DATADIR/keys" ] && rm "$DATADIR/keys" ln -s ${keyDir} "$DATADIR/keys" ''); brownpaper = { wantedBy = [ "multi-user.target" ]; wants = [ "brownpaper-init.service" ]; after = [ "brownpaper-init.service" "network-online.target" ]; path = [ pkgs.coreutils ]; environment.BROWNPAPER_STORAGE_DIR = "${toString cfg.dataDir}"; confinement = { enable = true; packages = with pkgs; [ bash coreutils findutils tzdata keyDir ]; }; script = '' ${package.server}/bin/brownpaper ${cfg.listen}:${toString cfg.port} ''; serviceConfig = { BindPaths = [ cfg.dataDir ] ++ (optional (cfg.pgpKeys != [ ]) keyDir); User = cfg.user; }; }; brownpaper-gc = mkIf cfg.gc.enable { startAt = cfg.gc.dates; script = "${pkgs.findutils}/bin/find ${cfg.dataDir} -maxdepth 1 -type f -mmin +${toString cfg.gc.maxAge} -delete"; }; }; environment.systemPackages = optionals cfgc.enable [ (pkgs.writeShellScriptBin "brownpaper" '' BROWNPAPER_ENDPOINT='${cfgc.endpoint}' ${package.client}/bin/brownpaper "$@" '') ]; }; }