diff --git a/mod-seafile-server.nix b/mod-seafile-server.nix index 3e40535..69f94b4 100644 --- a/mod-seafile-server.nix +++ b/mod-seafile-server.nix @@ -24,17 +24,17 @@ in description = "database backend type"; }; user = mkOption { - type = types.nullOr types.string; + type = types.nullOr types.str; default = "seafile"; description = "Database user name. Not required for sqlite."; }; dbname = mkOption { - type = types.nullOr types.string; + type = types.nullOr types.str; default = "seafile"; description = "Database name. Not required for sqlite."; }; password = mkOption { - type = types.nullOr types.string; + type = types.nullOr types.str; default = null; description = '' Database password. Use passwordFile to avoid this @@ -56,7 +56,7 @@ in }; dbport = mkOption { type = with types; nullOr (either int str); - default = null; + default = 3306; description = "Database port. Not required for sqlite."; }; }; @@ -96,6 +96,12 @@ in description = "listening port for Seafile server"; }; + fileserverPort = mkOption { + type = types.int; + default = 8082; + description = "listening port for Seafile's fileserver component"; + }; + seahubPort = mkOption { type = types.int; default = 443; @@ -117,6 +123,48 @@ in default = true; description = "whether to open up the firewall ports for ccnet, seafile-server and seahub"; }; + + defaultQuota = mkOption { + type = types.nullOr types.int; + default = null; + description = "default quota to be set per user, in GB"; + }; + + trashExpirationTime = mkOption { + type = types.int; + default = 30; + description = "default time for automatic library trash cleanup"; + }; + + fileRevisionHistoryDays = mkOption { + type = types.nullOr types.int; + default = null; + description = "default history length of file revisions to keep in days. null means keeping all revisions."; + }; + + fileserverBindAddress = mkOption { + type = types.str; + default = "0.0.0.0"; + description = "bind address for fileserver, binds to all addresses by default"; + }; + + fileserverWorkers = mkOption { + type = types.int; + default = 10; + description = "number of worker threads to server http requests"; + }; + + fileserverIndexers = mkOption { + type = types.int; + default = 1; + description = "number of threads used to sequentially divide uploaded files into blocks for storage"; + }; + + fileserverBlockSize = mkOption { + type = types.int; + default = 1; + description = "size of blocks that uploaded files are divided into, in MB"; + }; }; @@ -128,6 +176,7 @@ in # state directory permissions managed by systemd tmpfiles.rules = [ "d ${cfg.storagePath} 0750 ${cfg.user} ${cfg.group} -" + "d ${cfg.storagePath}/conf 0750 ${cfg.user} ${cfg.group} -" "d ${cfg.storagePath}/home 0710 ${cfg.user} ${cfg.group} -" ]; services.seafile-server = { @@ -147,14 +196,14 @@ in # ccnet-init must only be run once per installation, as it also generates stateful key and ID # solution: invoke it once, use result as template - if [ ! -e ./conf/mykey.peer ]; then - ${pkgs.seafile-server.ccnet-server}/bin/ccnet-init -c ./conf -n 'TEMPLATENAME' -H 'TEMPLATEHOST' -P 'TEMPLATEPORT' - mv ./conf/ccnet.conf{,.template} + if [ ! -e ./ccnet/mykey.peer ]; then + ${pkgs.seafile-server.ccnet-server}/bin/ccnet-init -c ./ccnet -n 'TEMPLATENAME' -H 'TEMPLATEHOST' -P 'TEMPLATEPORT' + mv ./ccnet/ccnet.conf{,.template} fi # generate actual ccnet config file echo "[General]" > ./conf/ccnet.conf - grep "^ID =" ./conf/ccnet.conf.template >> ./conf/ccnet.conf + grep "^ID =" ./ccnet/ccnet.conf.template >> ./conf/ccnet.conf echo 'USER_NAME = ${cfg.name} NAME = ${cfg.name} # outside URL @@ -163,6 +212,50 @@ in [Network] Port = ${toString cfg.ccnetPort}' >> ./conf/ccnet.conf + # seafile.conf generation + + echo '[library_trash] + expire_days ${toString cfg.trashExpirationTime} + + [fileserver] + host = ${cfg.fileserverBindAddress} + port = ${toString cfg.fileserverPort} + worker_threads = ${toString cfg.fileserverWorkers} + max_indexing_threads = ${toString cfg.fileserverIndexers} + fixed_block_size = ${toString cfg.fileserverIndexers}' > ./conf/seafile.conf + + if [ ${toString (! isNull cfg.defaultQuota)} ]; then + echo '[quota]' >> ./conf/seafile.conf + echo 'default = ${toString cfg.defaultQuota}' >> ./conf/seafile.conf + fi + + if [ ${toString (! isNull cfg.fileRevisionHistoryDays)} ]; then + echo '[history]' >> ./conf/seafile.conf + echo 'keep_days = ${toString cfg.defaultQuota}' >> ./conf/seafile.conf + fi + + # seafile database settings + + if [ ${cfg.db.type} = "mysql" ]; then + echo '[database] + type = mysql + host = ${cfg.db.host} + port = ${toString cfg.db.dbport} + user = ${cfg.db.user} + connection_charset = utf8 + db_name = ${cfg.db.dbname} + max_connections = 100' >> ./conf/seafile.conf + + if [ ${toString (! isNull cfg.db.password)}; then + echo 'password = ${toString cfg.db.password}' >> ./conf/seafile.conf + else + echo "password = $(cat ${toString cfg.db.passwordFile})" >> ./conf/seafile.conf + fi + else + echo '[database] + type = sqlite' >> ./conf/seafile.conf + fi + ln -s ${pkgs.seafile-server} seafile-server ./seafile-server/seafile-server-latest/bin/seafile-admin setup ''}") @@ -187,6 +280,6 @@ in }; users.groups.${cfg.group}.members = [ cfg.user ]; - networking.firewall.allowedTCPPorts = with cfg; if openFirewall then [ ccnetPort seafilePort seahubPort ] else []; + networking.firewall.allowedTCPPorts = with cfg; if openFirewall then [ ccnetPort seafilePort fileserverPort ] else []; }; }