Compare commits
	
		
			14 commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 8ecde56247 | |||
| e6fec8642a | |||
| cb44156519 | |||
| d3f1c04e72 | |||
| ce44d19168 | |||
| 3429d2ea63 | |||
| 1f4e3b5c7f | |||
| 8b73ec0585 | |||
| 9dde0d319f | |||
| cb16f19b58 | |||
| bc63307993 | |||
| 65f337bd15 | |||
| 86a300eaec | |||
| 00458bf734 | 
					 4 changed files with 234 additions and 96 deletions
				
			
		| 
						 | 
					@ -2,6 +2,40 @@
 | 
				
			||||||
with lib;
 | 
					with lib;
 | 
				
			||||||
let
 | 
					let
 | 
				
			||||||
  cfg = config.services.seafile-server;
 | 
					  cfg = config.services.seafile-server;
 | 
				
			||||||
 | 
					  seafileConfigFile = pkgs.writeText "seafile.conf"
 | 
				
			||||||
 | 
					    (generators.toINI {} cfg.seafileSettings);
 | 
				
			||||||
 | 
					  ccnetConfigFile = pkgs.writeText "ccnet.conf"
 | 
				
			||||||
 | 
					    (generators.toINI {} cfg.ccnetSettings);
 | 
				
			||||||
 | 
					  gunicornConfigFile = pkgs.writeText "gunicorn.conf.py"
 | 
				
			||||||
 | 
					    ''
 | 
				
			||||||
 | 
					      import os
 | 
				
			||||||
 | 
					      daemon = True
 | 
				
			||||||
 | 
					      workers = 5
 | 
				
			||||||
 | 
					      # default localhost:8000
 | 
				
			||||||
 | 
					      bind = "127.0.0.1:8000"
 | 
				
			||||||
 | 
					      # Pid
 | 
				
			||||||
 | 
					      pids_dir = '${cfg.storagePath}/pids'
 | 
				
			||||||
 | 
					      pidfile = os.path.join(pids_dir, 'seahub.pid')
 | 
				
			||||||
 | 
					      # for file upload, we need a longer timeout value (default is only 30s, too short)
 | 
				
			||||||
 | 
					      timeout = 1200
 | 
				
			||||||
 | 
					      limit_request_line = 8190
 | 
				
			||||||
 | 
					    '';
 | 
				
			||||||
 | 
					  seahubConfigFile = pkgs.writeText "seahub_settings.py"
 | 
				
			||||||
 | 
					    ''
 | 
				
			||||||
 | 
					      SECRET_KEY = #seckey#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      DATABASES = {
 | 
				
			||||||
 | 
					          'default': {
 | 
				
			||||||
 | 
					              'ENGINE': 'django.db.backends.${if cfg.db.type == "mysql" then
 | 
				
			||||||
 | 
					                "mysql" else abort "invalid db type"}',
 | 
				
			||||||
 | 
					              'NAME': '${cfg.db.dbnameSeahub}',
 | 
				
			||||||
 | 
					              'USER': '${cfg.db.user}',
 | 
				
			||||||
 | 
					              'PASSWORD': '#dbpass#',
 | 
				
			||||||
 | 
					              'HOST': '${cfg.db.host}',
 | 
				
			||||||
 | 
					              'PORT': '${toString cfg.db.port}'
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    '';
 | 
				
			||||||
  # fix permissions at start
 | 
					  # fix permissions at start
 | 
				
			||||||
in
 | 
					in
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
| 
						 | 
					@ -12,6 +46,20 @@ in
 | 
				
			||||||
        default = "/srv/seafile";
 | 
					        default = "/srv/seafile";
 | 
				
			||||||
        description = "where to store uploaded file data";
 | 
					        description = "where to store uploaded file data";
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
 | 
					      ccnetSettings = mkOption {
 | 
				
			||||||
 | 
					        type = with types; attrsOf (attrsOf (oneOf [ bool int str ]));
 | 
				
			||||||
 | 
					        default = {};
 | 
				
			||||||
 | 
					        description = ''
 | 
				
			||||||
 | 
					          all possible ccnet.conf settings
 | 
				
			||||||
 | 
					          '';
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      seafileSettings = mkOption {
 | 
				
			||||||
 | 
					        type = with types; attrsOf (attrsOf (oneOf [ bool int str ]));
 | 
				
			||||||
 | 
					        default = {};
 | 
				
			||||||
 | 
					        description = ''
 | 
				
			||||||
 | 
					          all possible seafile.conf settings
 | 
				
			||||||
 | 
					          '';
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
      autorun = mkOption {
 | 
					      autorun = mkOption {
 | 
				
			||||||
        type = types.bool;
 | 
					        type = types.bool;
 | 
				
			||||||
        default = true;
 | 
					        default = true;
 | 
				
			||||||
| 
						 | 
					@ -28,25 +76,27 @@ in
 | 
				
			||||||
          default = "seafile";
 | 
					          default = "seafile";
 | 
				
			||||||
          description = "Database user name. Not required for sqlite.";
 | 
					          description = "Database user name. Not required for sqlite.";
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        dbname = mkOption {
 | 
					        dbnameSeafile = mkOption {
 | 
				
			||||||
          type = types.nullOr types.str;
 | 
					          type = types.nullOr types.str;
 | 
				
			||||||
          default = "seafile";
 | 
					          default = "seafile";
 | 
				
			||||||
          description = "Database name. Not required for sqlite.";
 | 
					          description = "Database name for Seafile server. Not required for sqlite.";
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        password = mkOption {
 | 
					        dbnameCcnet = mkOption {
 | 
				
			||||||
          type = types.nullOr types.str;
 | 
					          type = types.nullOr types.str;
 | 
				
			||||||
          default = null;
 | 
					          default = "seafile";
 | 
				
			||||||
          description = ''
 | 
					          description = "Database name for Ccnet server. Not required for sqlite.";
 | 
				
			||||||
            Database password. Use <literal>passwordFile</literal> to avoid this
 | 
					        };
 | 
				
			||||||
            being world-readable in the <literal>/nix/store</literal>.
 | 
					        dbnameSeahub = mkOption {
 | 
				
			||||||
 | 
					          type = types.nullOr types.str;
 | 
				
			||||||
            Not required for sqlite.'';
 | 
					          default = "seafile";
 | 
				
			||||||
 | 
					          description = "Database name for Seahub web interface. Not required for sqlite.";
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        passwordFile = mkOption {
 | 
					        passwordFile = mkOption {
 | 
				
			||||||
          type = types.nullOr types.str;
 | 
					          type = types.nullOr types.str;
 | 
				
			||||||
          default = null;
 | 
					          default = null;
 | 
				
			||||||
          description = ''
 | 
					          description = ''
 | 
				
			||||||
            The full path to a file that contains the database password.
 | 
					            The full path to a file that contains the database password.
 | 
				
			||||||
 | 
					            Not required for sqlite.
 | 
				
			||||||
          '';
 | 
					          '';
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        host = mkOption {
 | 
					        host = mkOption {
 | 
				
			||||||
| 
						 | 
					@ -54,7 +104,7 @@ in
 | 
				
			||||||
          default = "localhost";
 | 
					          default = "localhost";
 | 
				
			||||||
          description = "Database host.";
 | 
					          description = "Database host.";
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
          dbport = mkOption {
 | 
					        port = mkOption {
 | 
				
			||||||
          type = with types; nullOr (either int str);
 | 
					          type = with types; nullOr (either int str);
 | 
				
			||||||
          default = 3306;
 | 
					          default = 3306;
 | 
				
			||||||
          description = "Database port. Not required for sqlite.";
 | 
					          description = "Database port. Not required for sqlite.";
 | 
				
			||||||
| 
						 | 
					@ -73,11 +123,11 @@ in
 | 
				
			||||||
          description = "Group account under which the Seafile server runs.";
 | 
					          description = "Group account under which the Seafile server runs.";
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#        name = mkOption {
 | 
					        name = mkOption {
 | 
				
			||||||
#          type = types.str;
 | 
					          type = types.str;
 | 
				
			||||||
#          default = "Seafile";
 | 
					          default = "Seafile";
 | 
				
			||||||
#          description = "name of the Seafile instance, will show up in client and web interface";
 | 
					          description = "name of the Seafile instance, will show up in client and web interface";
 | 
				
			||||||
#        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        domainName = mkOption {
 | 
					        domainName = mkOption {
 | 
				
			||||||
          type = types.str;
 | 
					          type = types.str;
 | 
				
			||||||
| 
						 | 
					@ -172,16 +222,68 @@ in
 | 
				
			||||||
        directoriesToManage = [ cfg.storagePath ];
 | 
					        directoriesToManage = [ cfg.storagePath ];
 | 
				
			||||||
      in
 | 
					      in
 | 
				
			||||||
      mkIf cfg.enable {
 | 
					      mkIf cfg.enable {
 | 
				
			||||||
 | 
					        services.seafile-server.ccnetSettings = {
 | 
				
			||||||
 | 
					          # TODO: ID and NAME might be required
 | 
				
			||||||
 | 
					          General.SERVICE_URL="http${if cfg.enableTLS then "s" else ""}://${cfg.domainName}:${toString cfg.externalPort}/";
 | 
				
			||||||
 | 
					          Database = mkMerge [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              ENGINE = cfg.db.type;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            (mkIf (cfg.db.type == "mysql") {
 | 
				
			||||||
 | 
					              HOST = cfg.db.host;
 | 
				
			||||||
 | 
					              PORT = cfg.db.port;
 | 
				
			||||||
 | 
					              USER = cfg.db.user;
 | 
				
			||||||
 | 
					              CONNECTION_CHARSET = "utf8";
 | 
				
			||||||
 | 
					              DB = cfg.db.dbnameCcnet;
 | 
				
			||||||
 | 
					              password = "#dbpass#";
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					          ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        services.seafile-server.seafileSettings = {
 | 
				
			||||||
 | 
					          library_trash.expire_days = cfg.trashExpirationTime;
 | 
				
			||||||
 | 
					          fileserver = {
 | 
				
			||||||
 | 
					            host = cfg.fileserverBindAddress;
 | 
				
			||||||
 | 
					            port = cfg.fileserverPort;
 | 
				
			||||||
 | 
					            worker_threads = cfg.fileserverWorkers;
 | 
				
			||||||
 | 
					            max_indexing_threads = cfg.fileserverIndexers;
 | 
				
			||||||
 | 
					            fixed_block_size = cfg.fileserverBlockSize;
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					          quota = mkIf (! isNull cfg.defaultQuota) {
 | 
				
			||||||
 | 
					            default = cfg.defaultQuota;
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					          history = mkIf (! isNull cfg.fileRevisionHistoryDays) {
 | 
				
			||||||
 | 
					            keep_days = cfg.fileRevisionHistoryDays;
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					          database = mkMerge [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              type = cfg.db.type;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            # while just using the cfg.db set directly might be possible and
 | 
				
			||||||
 | 
					            # save lines of code, I prefer hand-picking options
 | 
				
			||||||
 | 
					            (mkIf (cfg.db.type == "mysql") {
 | 
				
			||||||
 | 
					              host = cfg.db.host;
 | 
				
			||||||
 | 
					              port = cfg.db.port;
 | 
				
			||||||
 | 
					              user = cfg.db.user;
 | 
				
			||||||
 | 
					              connection_charset = "utf8";
 | 
				
			||||||
 | 
					              db_name = cfg.db.dbnameSeafile;
 | 
				
			||||||
 | 
					              max_connections = 100;
 | 
				
			||||||
 | 
					              password = "#dbpass#";
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					          ];
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        systemd = {
 | 
					        systemd = {
 | 
				
			||||||
          # state directory permissions managed by systemd
 | 
					          # state directory permissions managed by systemd
 | 
				
			||||||
          tmpfiles.rules = [
 | 
					          tmpfiles.rules = [
 | 
				
			||||||
            "d ${cfg.storagePath} 0750 ${cfg.user} ${cfg.group} -"
 | 
					            "d ${cfg.storagePath} 0750 ${cfg.user} ${cfg.group} -"
 | 
				
			||||||
            "d ${cfg.storagePath}/conf 0750 ${cfg.user} ${cfg.group} -"
 | 
					            "d ${cfg.storagePath}/conf 0700 ${cfg.user} ${cfg.group} -"
 | 
				
			||||||
            "d ${cfg.storagePath}/home 0710 ${cfg.user} ${cfg.group} -"
 | 
					            "d ${cfg.storagePath}/pids 0710 ${cfg.user} ${cfg.group} -"
 | 
				
			||||||
          ];
 | 
					          ];
 | 
				
			||||||
          services.seafile-server = {
 | 
					          services.seafile-server = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          path = with pkgs; [ seafile-server.ccnet-server seafile-server.seafile-server-core ];
 | 
					          path = with pkgs; [ seafile-server.seafile-server-core ];
 | 
				
			||||||
          script = ''
 | 
					          script = ''
 | 
				
			||||||
            ./seafile-server/seafile-server-latest/bin/seafile-admin start
 | 
					            ./seafile-server/seafile-server-latest/bin/seafile-admin start
 | 
				
			||||||
            '';
 | 
					            '';
 | 
				
			||||||
| 
						 | 
					@ -193,66 +295,46 @@ in
 | 
				
			||||||
              ''}")
 | 
					              ''}")
 | 
				
			||||||
              ("${pkgs.writeShellScript "seafile-server-preStart-unprivileged" ''
 | 
					              ("${pkgs.writeShellScript "seafile-server-preStart-unprivileged" ''
 | 
				
			||||||
                # stuff run as seafile user
 | 
					                # stuff run as seafile user
 | 
				
			||||||
 | 
					                set -ex
 | 
				
			||||||
                # 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 ./ccnet/mykey.peer ]; then
 | 
					 | 
				
			||||||
                  ${pkgs.seafile-server.ccnet-server}/bin/ccnet-init -c ./ccnet -H 'TEMPLATEHOST'
 | 
					 | 
				
			||||||
                  mv ./ccnet/ccnet.conf{,.template}
 | 
					 | 
				
			||||||
                fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                # generate actual ccnet config file
 | 
					 | 
				
			||||||
                echo "[General]" > ./conf/ccnet.conf
 | 
					 | 
				
			||||||
                grep "^ID =" ./ccnet/ccnet.conf.template >> ./conf/ccnet.conf
 | 
					 | 
				
			||||||
                # outside URL
 | 
					 | 
				
			||||||
                SERVICE_URL = http${if cfg.enableTLS then "s" else ""}://${cfg.domainName}:${toString cfg.externalPort}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                # seafile.conf generation
 | 
					                # seafile.conf generation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                echo '[library_trash]
 | 
					                # move config templates from nix store
 | 
				
			||||||
                expire_days ${toString cfg.trashExpirationTime}
 | 
					                ${pkgs.coreutils}/bin/install ${ccnetConfigFile} ./conf/ccnet.conf
 | 
				
			||||||
 | 
					                ${pkgs.coreutils}/bin/install ${seafileConfigFile} ./conf/seafile.conf
 | 
				
			||||||
 | 
					                ${pkgs.coreutils}/bin/install ${gunicornConfigFile} ./conf/gunicorn.conf.py
 | 
				
			||||||
 | 
					                ${pkgs.coreutils}/bin/install ${seahubConfigFile} ./conf/seahub_settings.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                [fileserver]
 | 
					                # seahub secret key
 | 
				
			||||||
                host = ${cfg.fileserverBindAddress}
 | 
					                if [ ! -e .seahubSecret ]; then
 | 
				
			||||||
                port = ${toString cfg.fileserverPort}
 | 
					                    ${pkgs.seafile-server.pythonEnv}/bin/python ${pkgs.seafile-server}/seahub/tools/secret_key_generator.py > .seahubSecret
 | 
				
			||||||
                worker_threads = ${toString cfg.fileserverWorkers}
 | 
					                    chmod 400 .seahubSecret
 | 
				
			||||||
                max_indexing_threads = ${toString cfg.fileserverIndexers}
 | 
					                fi
 | 
				
			||||||
                fixed_block_size = ${toString cfg.fileserverIndexers}' > ./conf/seafile.conf
 | 
					                SEAHUB_SECRET="$(head -n1 .seahubSecret)"
 | 
				
			||||||
 | 
					                # TODO: check for special characters needing to be escaped
 | 
				
			||||||
 | 
					                sed -e "s,#seckey#,$SEAHUB_SECRET,g" -i ./conf/seahub_settings.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if [ ${toString (! isNull cfg.defaultQuota)} ]; then
 | 
					                # replace placeholder secrets with real secret read from file
 | 
				
			||||||
                  echo '[quota]' >> ./conf/seafile.conf
 | 
					                #TODO: unset -x to prevent DBPASS from being leaked in journal
 | 
				
			||||||
                  echo 'default = ${toString cfg.defaultQuota}' >> ./conf/seafile.conf
 | 
					                ${if !(isNull cfg.db.passwordFile) then ''
 | 
				
			||||||
 | 
					                  DBPASS="$(head -n1 ${toString cfg.db.passwordFile})"
 | 
				
			||||||
 | 
					                  sed -e "s,#dbpass#,$DBPASS,g" -i ./conf/seafile.conf ./conf/ccnet.conf ./conf/seahub_settings.py
 | 
				
			||||||
 | 
					                  ''
 | 
				
			||||||
 | 
					                  else ""
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                # initialise db and other things needed at first run
 | 
				
			||||||
 | 
					                if [ -e .initialised ]; then
 | 
				
			||||||
 | 
					                    #TODO: db initialisation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    touch .initialised
 | 
				
			||||||
                fi
 | 
					                fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if [ ${toString (! isNull cfg.fileRevisionHistoryDays)} ]; then
 | 
					                ln -nsf ${pkgs.seafile-server} seafile-server
 | 
				
			||||||
                  echo '[history]' >> ./conf/seafile.conf
 | 
					 | 
				
			||||||
                  echo 'keep_days = ${toString cfg.defaultQuota}' >> ./conf/seafile.conf
 | 
					 | 
				
			||||||
                fi
 | 
					 | 
				
			||||||
               
 | 
					               
 | 
				
			||||||
                # seafile database settings
 | 
					                # for determining update version mismatches
 | 
				
			||||||
 | 
					                ${pkgs.coreutils}/bin/install ${pkgs.seafile-server}/installed_version .
 | 
				
			||||||
                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
 | 
					 | 
				
			||||||
              ''}")
 | 
					              ''}")
 | 
				
			||||||
            ];
 | 
					            ];
 | 
				
			||||||
            User = cfg.user;
 | 
					            User = cfg.user;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,7 @@ import (<nixos-unstable/nixos/tests/make-test-python.nix>) {
 | 
				
			||||||
            (import ./default.nix)
 | 
					            (import ./default.nix)
 | 
				
			||||||
          ];
 | 
					          ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          i18n.consoleKeyMap = "de";
 | 
					          console.keyMap = "de";
 | 
				
			||||||
          users.mutableUsers = false;
 | 
					          users.mutableUsers = false;
 | 
				
			||||||
          users.users.test = {
 | 
					          users.users.test = {
 | 
				
			||||||
            isNormalUser = true;
 | 
					            isNormalUser = true;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,7 @@
 | 
				
			||||||
, python3Packages
 | 
					, python3Packages
 | 
				
			||||||
}:
 | 
					}:
 | 
				
			||||||
let
 | 
					let
 | 
				
			||||||
  version = "8.0.0";
 | 
					  version = "8.0.3";
 | 
				
			||||||
  python = python3;
 | 
					  python = python3;
 | 
				
			||||||
  pythonPackages = python3Packages;
 | 
					  pythonPackages = python3Packages;
 | 
				
			||||||
  django = pythonPackages.django;
 | 
					  django = pythonPackages.django;
 | 
				
			||||||
| 
						 | 
					@ -49,6 +49,8 @@ let
 | 
				
			||||||
    pycryptodome
 | 
					    pycryptodome
 | 
				
			||||||
  ]
 | 
					  ]
 | 
				
			||||||
  ++ map (p: p.override { inherit django; }) djangoModules; # build django modules with required version
 | 
					  ++ map (p: p.override { inherit django; }) djangoModules; # build django modules with required version
 | 
				
			||||||
 | 
					  # defining them here to be able to expose them in a python environment as well
 | 
				
			||||||
 | 
					  pythonEnvDeps = seahubPythonDependencies ++ [ libsearpc ];
 | 
				
			||||||
  seafile-server-core = stdenv.mkDerivation rec {
 | 
					  seafile-server-core = stdenv.mkDerivation rec {
 | 
				
			||||||
    name = "seafile-server-core";
 | 
					    name = "seafile-server-core";
 | 
				
			||||||
    inherit version;
 | 
					    inherit version;
 | 
				
			||||||
| 
						 | 
					@ -56,7 +58,7 @@ let
 | 
				
			||||||
      owner = "haiwen";
 | 
					      owner = "haiwen";
 | 
				
			||||||
      repo = "seafile-server";
 | 
					      repo = "seafile-server";
 | 
				
			||||||
      rev = "v${version}-server";
 | 
					      rev = "v${version}-server";
 | 
				
			||||||
      sha256 = "0pd1zjsw6lkpxd54ln0dz5r9zx9585nib10kvpl1vgzp61g4d223";
 | 
					      sha256 = "1wmbx4smf342b5pars1zm9af2i0yaq7kjj7ry0gr337gdpa4qn3b";
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    # patch to work with latest, non-vulnerable libevhtp
 | 
					    # patch to work with latest, non-vulnerable libevhtp
 | 
				
			||||||
    patches = [
 | 
					    patches = [
 | 
				
			||||||
| 
						 | 
					@ -66,7 +68,14 @@ let
 | 
				
			||||||
    # `which` is called directly from python during buildPhase, so we need the binary
 | 
					    # `which` is called directly from python during buildPhase, so we need the binary
 | 
				
			||||||
    nativeBuildInputs = [ autoconf automake libtool pkgconfig vala autoreconfHook which pythonPackages.wrapPython ];
 | 
					    nativeBuildInputs = [ autoconf automake libtool pkgconfig vala autoreconfHook which pythonPackages.wrapPython ];
 | 
				
			||||||
    buildInputs = [ sqlite glib python libuuid openssl oniguruma fuse libarchive libevent libevhtp ];
 | 
					    buildInputs = [ sqlite glib python libuuid openssl oniguruma fuse libarchive libevent libevhtp ];
 | 
				
			||||||
    propagatedBuildInputs = [ libsearpc ] ++ seahubPythonDependencies;
 | 
					    propagatedBuildInputs = pythonEnvDeps;
 | 
				
			||||||
 | 
					    # copy manual to required location
 | 
				
			||||||
 | 
					    postInstall = ''
 | 
				
			||||||
 | 
					      mkdir $out/doc
 | 
				
			||||||
 | 
					      cp ${src}/doc/*.doc $out/doc/
 | 
				
			||||||
 | 
					      '';
 | 
				
			||||||
 | 
					    # prevent doc directory from being moved to share in fixupPhase
 | 
				
			||||||
 | 
					    forceShare = [ "man" "info" ];
 | 
				
			||||||
    postFixup = ''
 | 
					    postFixup = ''
 | 
				
			||||||
      buildPythonPath $propagatedBuildInputs
 | 
					      buildPythonPath $propagatedBuildInputs
 | 
				
			||||||
      wrapPythonProgramsIn "$out/bin" "$out $pythonPath"
 | 
					      wrapPythonProgramsIn "$out/bin" "$out $pythonPath"
 | 
				
			||||||
| 
						 | 
					@ -85,7 +94,7 @@ let
 | 
				
			||||||
      owner = "haiwen";
 | 
					      owner = "haiwen";
 | 
				
			||||||
      repo = "seahub";
 | 
					      repo = "seahub";
 | 
				
			||||||
      rev = "v${version}-server";
 | 
					      rev = "v${version}-server";
 | 
				
			||||||
      sha256 = "0j7g43j7w1zb00pg4aaacdv5ycva3qf561hj9pbwh4709mbiykip";
 | 
					      sha256 = "0vfkiavsmpjm6wjr5rcnmnpnb3rxr3svwk8fsh5c76zg87ckdz4d";
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    phases = [ "unpackPhase" "installPhase" "fixupPhase" "distPhase" ];
 | 
					    phases = [ "unpackPhase" "installPhase" "fixupPhase" "distPhase" ];
 | 
				
			||||||
    buildInputs = [ python pythonPackages.wrapPython ];
 | 
					    buildInputs = [ python pythonPackages.wrapPython ];
 | 
				
			||||||
| 
						 | 
					@ -120,19 +129,40 @@ stdenv.mkDerivation {
 | 
				
			||||||
  name = "seafile-server";
 | 
					  name = "seafile-server";
 | 
				
			||||||
  inherit version;
 | 
					  inherit version;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  nativeBuildInputs = [ python3Packages.wrapPython  ];
 | 
				
			||||||
  buildInputs = [ seahub seafile-server-core libsearpc ]
 | 
					  buildInputs = [ seahub seafile-server-core libsearpc ]
 | 
				
			||||||
    ++ lib.optional withMysql libmysqlclient;
 | 
					    ++ lib.optional withMysql libmysqlclient;
 | 
				
			||||||
  phases = [ "installPhase" "fixupPhase" "distPhase" ];
 | 
					  phases = [ "installPhase" "fixupPhase" "distPhase" ];
 | 
				
			||||||
  # todo: create data directory in /srv in activation script
 | 
					  # create required directory structure
 | 
				
			||||||
 | 
					  # Which files need to be copied is specified in the function `copy_scripts_and_libs`
 | 
				
			||||||
 | 
					  # of  ${seafile-server-core.src}/scripts/build/build-server.py
 | 
				
			||||||
 | 
					  # The install script below has been hand crafted from that list of files and needs to be updated on new releases.
 | 
				
			||||||
  installPhase = ''
 | 
					  installPhase = ''
 | 
				
			||||||
    mkdir "$out"
 | 
					    mkdir "$out"
 | 
				
			||||||
    cd "$out"
 | 
					    cd "$out"
 | 
				
			||||||
    ln -s ${seahub} seahub
 | 
					    ln -s ${seahub} seahub
 | 
				
			||||||
    ln -s ${seafile-server-core} seafile-server-latest
 | 
					    ln -s ${seafile-server-core} seafile-server
 | 
				
			||||||
 | 
					    # copy general scripts
 | 
				
			||||||
 | 
					    cp ${seafile-server-core.src}/scripts/{setup-seafile.sh,setup-seafile-mysql.sh,setup-seafile-mysql.py,seafile.sh,seahub.sh,reset-admin.sh,seaf-fuse.sh,check_init_admin.py,seaf-gc.sh,seaf-fsck.sh} .
 | 
				
			||||||
 | 
					    # copy update scripts (and their sql)
 | 
				
			||||||
 | 
					    cp -r ${seafile-server-core.src}/scripts/upgrade .
 | 
				
			||||||
 | 
					    cp -r ${seafile-server-core.src}/scripts/sql .
 | 
				
			||||||
 | 
					    # copy_user_manual is already done in the postInstall hook of seafile-server-core
 | 
				
			||||||
 | 
					    # python admin scripts need to be made executable and patched with python path
 | 
				
			||||||
 | 
					    chmod ugo+x *.py
 | 
				
			||||||
 | 
					    buildPythonPath $propagatedBuildInputs
 | 
				
			||||||
 | 
					    wrapPythonProgramsIn "$out/*.py" "$out $pythonPath"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    echo -n "${version}" > installed_version
 | 
				
			||||||
  '';
 | 
					  '';
 | 
				
			||||||
  meta = with lib; {
 | 
					  meta = with lib; {
 | 
				
			||||||
    maintainers = with maintainers; [ schmittlauch ];
 | 
					    maintainers = with maintainers; [ schmittlauch ];
 | 
				
			||||||
    license = licenses.free; # components with different free software licenses are combined
 | 
					    license = licenses.free; # components with different free software licenses are combined
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  inherit seafile-server-core seahub;# for using the path in the NixOS module
 | 
					  inherit seafile-server-core seahub;# for using the path in the NixOS module
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  pythonEnv = python3.buildEnv.override {
 | 
				
			||||||
 | 
					    extraLibs = pythonEnvDeps;
 | 
				
			||||||
 | 
					    ignoreCollisions = true;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,13 +10,13 @@
 | 
				
			||||||
    (import ./default.nix)
 | 
					    (import ./default.nix)
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  i18n.consoleKeyMap = "de";
 | 
					  console.keyMap = "de";
 | 
				
			||||||
  users.mutableUsers = false;
 | 
					  users.mutableUsers = false;
 | 
				
			||||||
  users.users.test = {
 | 
					  users.users.test = {
 | 
				
			||||||
    isNormalUser = true;
 | 
					    isNormalUser = true;
 | 
				
			||||||
    extraGroups = [ "wheel" ];
 | 
					    extraGroups = [ "wheel" ];
 | 
				
			||||||
    #hashedPassword = "$6$SZCzE/xB$Hr9sfsJ7xAcBCoptG39cxxQk8RZfldDjjGpSngOvn9Ufex5dHBEbdncXRZnfrGATsGcYPvLi7m4wIu.f8tY9B.";
 | 
					    #hashedPassword = "$6$SZCzE/xB$Hr9sfsJ7xAcBCoptG39cxxQk8RZfldDjjGpSngOvn9Ufex5dHBEbdncXRZnfrGATsGcYPvLi7m4wIu.f8tY9B.";
 | 
				
			||||||
    password = "";
 | 
					    password = "test";
 | 
				
			||||||
    home = "/home/test";
 | 
					    home = "/home/test";
 | 
				
			||||||
    createHome = true;
 | 
					    createHome = true;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,33 @@
 | 
				
			||||||
  services.seafile-server = {
 | 
					  services.seafile-server = {
 | 
				
			||||||
    enable = true;
 | 
					    enable = true;
 | 
				
			||||||
    #autorun = false;
 | 
					    #autorun = false;
 | 
				
			||||||
    domainName = "localhost";
 | 
					    domainName = "seaf.local";
 | 
				
			||||||
 | 
					    db = {
 | 
				
			||||||
 | 
					      type = "mysql";
 | 
				
			||||||
 | 
					      passwordFile = toString (pkgs.writeText "testPW" "test");
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # db backend
 | 
				
			||||||
 | 
					  services.mysql =
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      enable = true;
 | 
				
			||||||
 | 
					      package = pkgs.mariadb;
 | 
				
			||||||
 | 
					      ensureDatabases = [ "ccnet" "seafile" "seahub" ];
 | 
				
			||||||
 | 
					      ensureUsers = [
 | 
				
			||||||
 | 
					        rec {
 | 
				
			||||||
 | 
					          name = config.services.seafile-server.db.user;
 | 
				
			||||||
 | 
					          ensurePermissions = {
 | 
				
			||||||
 | 
					            "ccnet.*" = "ALL PRIVILEGES";
 | 
				
			||||||
 | 
					            "seafile.*" = "ALL PRIVILEGES";
 | 
				
			||||||
 | 
					            "seahub.*" = "ALL PRIVILEGES";
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      ];
 | 
				
			||||||
 | 
					      # set a password for the seafile user
 | 
				
			||||||
 | 
					      initialScript = pkgs.writeText "mariadb-init.sql" ''
 | 
				
			||||||
 | 
					        CREATE USER ${config.services.seafile-server.db.user}@localhost IDENTIFIED VIA mysql_native_password USING PASSWORD("test");
 | 
				
			||||||
 | 
					      '';
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue