{ config, pkgs, lib, ...}: with lib; let cfg = config.services.seafile-server; # fix permissions at start in { options.services.seafile-server = { enable = mkEnableOption "Seafile server"; storagePath = mkOption { type = types.path; default = "/srv/seafile"; description = "where to store uploaded file data"; }; autorun = mkOption { type = types.bool; default = true; description = "enable the seafile-server service to get started automatically"; }; db = { type = mkOption { type = types.enum ["sqlite" "mysql"]; default = "sqlite"; description = "database backend type"; }; user = mkOption { type = types.nullOr types.string; default = "seafile"; description = "Database user name. Not required for sqlite."; }; dbname = mkOption { type = types.nullOr types.string; default = "seafile"; description = "Database name. Not required for sqlite."; }; password = mkOption { type = types.nullOr types.string; default = null; description = '' Database password. Use passwordFile to avoid this being world-readable in the /nix/store. Not required for sqlite.''; }; passwordFile = mkOption { type = types.nullOr types.str; default = null; description = '' The full path to a file that contains the database password. ''; }; host = mkOption { type = types.nullOr types.str; default = "localhost"; description = "Database host."; }; dbport = mkOption { type = with types; nullOr (either int str); default = null; description = "Database port. Not required for sqlite."; }; }; user = mkOption { type = types.str; default = "seafile"; description = "User account under which the Seafile server runs."; }; group = mkOption { type = types.str; default = "seafile"; description = "Group account under which the Seafile server runs."; }; domainName = mkOption { type = types.str; description = "full domain name of the seafile instance"; }; }; config = let directoriesToManage = [ cfg.storagePath ]; in lib.mkIf cfg.enable { systemd = { # state directory permissions managed by systemd tmpfiles.rules = [ "d ${cfg.storagePath} 0750 ${cfg.user} ${cfg.group} -" ]; services.seafile-server = { script = '' ${pkgs.seafile-server.ccnet-server}/bin/ccnet-init ''; serviceConfig = { ExecStartPre = [ ("+${pkgs.writeScript "seafile-server-preStart-privileged" '' #!${pkgs.runtimeShell} # stuff run as root ''}") ("${pkgs.writeShellScript "seafile-server-preStart-unprivileged" '' # stuff run as seafile user ''}") ]; User = cfg.user; Group = cfg.group; Type = "oneshot"; WorkingDirectory = cfg.storagePath; }; enable = cfg.autorun; wantedBy = [ "multi-user.target" ]; }; }; users.users.${cfg.user} = { home = "${cfg.storagePath}/home"; group = cfg.group; # don't make NixOS create the home directory as otherwise the permissions for /srv might be 0700, # making it impossible to cd into the storagePath createHome = false; isNormalUser = false; }; users.groups.${cfg.group}.members = [ cfg.user ]; }; }