Compare commits
14 commits
Author | SHA1 | Date | |
---|---|---|---|
Trolli Schmittlauch | 8ecde56247 | ||
Trolli Schmittlauch | e6fec8642a | ||
Trolli Schmittlauch | cb44156519 | ||
Trolli Schmittlauch | d3f1c04e72 | ||
Trolli Schmittlauch | ce44d19168 | ||
Trolli Schmittlauch | 3429d2ea63 | ||
Trolli Schmittlauch | 1f4e3b5c7f | ||
Trolli Schmittlauch | 8b73ec0585 | ||
Trolli Schmittlauch | 9dde0d319f | ||
Trolli Schmittlauch | cb16f19b58 | ||
Trolli Schmittlauch | bc63307993 | ||
Trolli Schmittlauch | 65f337bd15 | ||
Trolli Schmittlauch | 86a300eaec | ||
Trolli Schmittlauch | 00458bf734 |
|
@ -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,38 +76,40 @@ 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;
|
||||||
|
default = "seafile";
|
||||||
|
description = "Database name for Ccnet server. Not required for sqlite.";
|
||||||
|
};
|
||||||
|
dbnameSeahub = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = "seafile";
|
||||||
|
description = "Database name for Seahub web interface. Not required for sqlite.";
|
||||||
|
};
|
||||||
|
passwordFile = mkOption {
|
||||||
type = types.nullOr types.str;
|
type = types.nullOr types.str;
|
||||||
default = null;
|
default = null;
|
||||||
description = ''
|
description = ''
|
||||||
Database password. Use <literal>passwordFile</literal> to avoid this
|
The full path to a file that contains the database password.
|
||||||
being world-readable in the <literal>/nix/store</literal>.
|
Not required for sqlite.
|
||||||
|
'';
|
||||||
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 = 3306;
|
|
||||||
description = "Database port. Not required for sqlite.";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
host = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = "localhost";
|
||||||
|
description = "Database host.";
|
||||||
|
};
|
||||||
|
port = mkOption {
|
||||||
|
type = with types; nullOr (either int str);
|
||||||
|
default = 3306;
|
||||||
|
description = "Database port. Not required for sqlite.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
user = mkOption {
|
user = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
@ -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…
Reference in a new issue