nixos/seafile: add persistent user, configurable storage path, gc service

This commit is contained in:
melvyn 2024-09-27 19:58:34 -04:00
parent 90e07d3e55
commit 073099d0f7
No known key found for this signature in database
GPG Key ID: 25A2B7280CE3AFF6
4 changed files with 284 additions and 116 deletions

View File

@ -529,6 +529,16 @@
- The kubelet configuration file can now be amended with arbitrary additional content using the `services.kubernetes.kubelet.extraConfig` option.
- The `services.seafile` module was updated to major version 11.
- As part of this upgrade, the database backend will be migrated to MySQL.
This process should be automatic, but in case of a botched migration,
old sqlite files are not removed and can be used to manually migrate the database.
- Additionally, the updated CSRF protection may prevent some users from logging in.
Specific origin addresses can be whitelisted using the `services.seafile.seahubExtraConf` option
(e.g. `services.seafile.seahubExtraConf = ''CSRF_TRUSTED_ORIGINS = ["https://example.com"]'';`).
Note that first solution of the [official FAQ answer](https://cloud.seatable.io/dtable/external-links/7b976c85f504491cbe8e/?tid=0000&vid=0000&row-id=BQhH-2HSQs68Nq2EW91DBA)
is not allowed by the `services.nginx` module's config-checker.
- To facilitate dependency injection, the `imgui` package now builds a static archive using vcpkg' CMake rules.
The derivation now installs "impl" headers selectively instead of by a wildcard.
Use `imgui.src` if you just want to access the unpacked sources.

View File

@ -1,19 +1,42 @@
{ config, lib, pkgs, ... }:
with lib;
{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.seafile;
settingsFormat = pkgs.formats.ini { };
ccnetConf = settingsFormat.generate "ccnet.conf" cfg.ccnetSettings;
ccnetConf = settingsFormat.generate "ccnet.conf" (
lib.attrsets.recursiveUpdate {
Database = {
ENGINE = "mysql";
UNIX_SOCKET = "/var/run/mysqld/mysqld.sock";
DB = "ccnet_db";
CONNECTION_CHARSET = "utf8";
};
} cfg.ccnetSettings
);
seafileConf = settingsFormat.generate "seafile.conf" cfg.seafileSettings;
seafileConf = settingsFormat.generate "seafile.conf" (
lib.attrsets.recursiveUpdate {
database = {
type = "mysql";
unix_socket = "/var/run/mysqld/mysqld.sock";
db_name = "seafile_db";
connection_charset = "utf8";
};
} cfg.seafileSettings
);
seahubSettings = pkgs.writeText "seahub_settings.py" ''
FILE_SERVER_ROOT = '${cfg.ccnetSettings.General.SERVICE_URL}/seafhttp'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': '${seahubDir}/seahub.db',
'ENGINE': 'django.db.backends.mysql',
'NAME' : 'seahub_db',
'HOST' : '/var/run/mysqld/mysqld.sock',
}
}
MEDIA_ROOT = '${seahubDir}/media/'
@ -21,13 +44,15 @@ let
SERVICE_URL = '${cfg.ccnetSettings.General.SERVICE_URL}'
CSRF_TRUSTED_ORIGINS = ["${cfg.ccnetSettings.General.SERVICE_URL}"]
with open('${seafRoot}/.seahubSecret') as f:
SECRET_KEY = f.readline().rstrip()
${cfg.seahubExtraConf}
'';
seafRoot = "/var/lib/seafile"; # hardcode it due to dynamicuser
seafRoot = "/var/lib/seafile";
ccnetDir = "${seafRoot}/ccnet";
seahubDir = "${seafRoot}/seahub";
defaultUser = "seafile";
@ -37,7 +62,7 @@ in
###### Interface
options.services.seafile = {
options.services.seafile = with lib; {
enable = mkEnableOption "Seafile server";
ccnetSettings = mkOption {
@ -47,7 +72,7 @@ in
options = {
General = {
SERVICE_URL = mkOption {
type = types.str;
type = types.singleLineStr;
example = "https://www.example.com";
description = ''
Seahub public URL.
@ -78,11 +103,17 @@ in
'';
};
host = mkOption {
type = types.str;
default = "127.0.0.1";
example = "0.0.0.0";
type = types.singleLineStr;
default = "ipv4:127.0.0.1";
example = "unix:/run/seafile/server.sock";
description = ''
The binding address used by seafile fileserver.
The bind address used by seafile fileserver.
The addr can be defined as one of the following:
- ipv6:<ipv6addr> for binding to an IPv6 address.
- unix:<named pipe> for binding to a unix named socket
- ipv4:<ipv4addr> for binding to an ipv4 address
Otherwise the addr is assumed to be ipv4.
'';
};
};
@ -96,6 +127,19 @@ in
'';
};
seahubAddress = mkOption {
type = types.singleLineStr;
default = "unix:/run/seahub/gunicorn.sock";
example = "[::1]:8083";
description = ''
Which address to bind the seahub server to, of the form:
- HOST
- HOST:PORT
- unix:PATH.
IPv6 HOSTs must be wrapped in brackets.
'';
};
workers = mkOption {
type = types.int;
default = 4;
@ -107,7 +151,7 @@ in
adminEmail = mkOption {
example = "john@example.com";
type = types.str;
type = types.singleLineStr;
description = ''
Seafile Seahub Admin Account Email.
'';
@ -115,45 +159,79 @@ in
initialAdminPassword = mkOption {
example = "someStrongPass";
type = types.str;
type = types.singleLineStr;
description = ''
Seafile Seahub Admin Account initial password.
Should be changed via Seahub web front-end.
'';
};
seafilePackage = mkPackageOption pkgs "seafile-server" { };
seahubPackage = mkPackageOption pkgs "seahub" { };
user = mkOption {
type = types.str;
type = types.singleLineStr;
default = defaultUser;
description = "User account under which seafile runs.";
};
group = mkOption {
type = types.str;
type = types.singleLineStr;
default = defaultUser;
description = "Group under which seafile runs.";
};
dataDir = mkOption {
type = types.nullOr types.path;
default = null;
defaultText = "${seafRoot}/data";
type = types.path;
default = "${seafRoot}/data";
description = "Path in which to store user data";
};
gcDates = mkOption {
type = types.listOf types.str;
default = [ ];
example = [ "Sun 03:00:00" ];
description = ''
When to run garbage collection on stored data blocks.
'';
gc = {
enable = mkEnableOption "automatic garbage collection on stored data blocks";
dates = mkOption {
type = types.listOf types.singleLineStr;
default = [ "Sun 03:00:00" ];
description = ''
When to run garbage collection on stored data blocks.
The time format is described in {manpage}`systemd.time(7)`.
'';
};
randomizedDelaySec = mkOption {
default = "0";
type = types.singleLineStr;
example = "45min";
description = ''
Add a randomized delay before each garbage collection.
The delay will be chosen between zero and this value.
This value must be a time span in the format specified by
{manpage}`systemd.time(7)`
'';
};
persistent = mkOption {
default = true;
type = types.bool;
example = false;
description = ''
Takes a boolean argument. If true, the time when the service
unit was last triggered is stored on disk. When the timer is
activated, the service unit is triggered immediately if it
would have been triggered at least once during the time when
the timer was inactive. Such triggering is nonetheless
subject to the delay imposed by RandomizedDelaySec=. This is
useful to catch up on missed runs of the service when the
system was powered down.
'';
};
};
seahubExtraConf = mkOption {
default = "";
example = ''
CSRF_TRUSTED_ORIGINS = ["https://example.com"]
'';
type = types.lines;
description = ''
Extra config to append to `seahub_settings.py` file.
@ -165,7 +243,26 @@ in
###### Implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
services.mysql = {
enable = true;
package = lib.mkDefault pkgs.mariadb;
ensureDatabases = [
"ccnet_db"
"seafile_db"
"seahub_db"
];
ensureUsers = [
{
name = cfg.user;
ensurePermissions = {
"ccnet_db.*" = "ALL PRIVILEGES";
"seafile_db.*" = "ALL PRIVILEGES";
"seahub_db.*" = "ALL PRIVILEGES";
};
}
];
};
environment.etc."seafile/ccnet.conf".source = ccnetConf;
environment.etc."seafile/seafile.conf".source = seafileConf;
@ -178,9 +275,7 @@ in
};
};
users.groups = lib.optionalAttrs (cfg.group == defaultUser) {
"${defaultUser}" = {};
};
users.groups = lib.optionalAttrs (cfg.group == defaultUser) { "${defaultUser}" = { }; };
systemd.targets.seafile = {
wantedBy = [ "multi-user.target" ];
@ -189,7 +284,7 @@ in
systemd.services =
let
securityOptions = {
serviceOptions = {
ProtectHome = true;
PrivateUsers = true;
PrivateDevices = true;
@ -210,34 +305,42 @@ in
NoNewPrivileges = true;
MemoryDenyWriteExecute = true;
SystemCallArchitectures = "native";
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" ];
RestrictAddressFamilies = [
"AF_UNIX"
"AF_INET"
];
User = cfg.user;
Group = cfg.group;
StateDirectory = "seafile";
RuntimeDirectory = "seafile";
LogsDirectory = "seafile";
ConfigurationDirectory = "seafile";
ReadWritePaths = lib.lists.optional (cfg.dataDir != "${seafRoot}/data") cfg.dataDir;
};
dataDir = if (!builtins.isNull cfg.dataDir) then cfg.dataDir else "${seafRoot}/data";
optionalDataDir = lib.lists.optional (!builtins.isNull cfg.dataDir) cfg.dataDir;
in
{
seaf-server = {
description = "Seafile server";
partOf = [ "seafile.target" ];
after = [ "network.target" ];
unitConfig.RequiresMountsFor = optionalDataDir;
unitConfig.RequiresMountsFor = lib.lists.optional (cfg.dataDir != "${seafRoot}/data") cfg.dataDir;
requires = [ "mysql.service" ];
after = [
"network.target"
"mysql.service"
];
wantedBy = [ "seafile.target" ];
restartTriggers = [ ccnetConf seafileConf ];
path = [ pkgs.sqlite ];
serviceConfig = securityOptions // {
User = cfg.user;
Group = cfg.group;
StateDirectory = "seafile";
RuntimeDirectory = "seafile";
LogsDirectory = "seafile";
ConfigurationDirectory = "seafile";
ReadWritePaths = optionalDataDir;
restartTriggers = [
ccnetConf
seafileConf
];
serviceConfig = serviceOptions // {
ExecStart = ''
${cfg.seafilePackage}/bin/seaf-server \
${lib.getExe cfg.seahubPackage.seafile-server} \
--foreground \
-F /etc/seafile \
-c ${ccnetDir} \
-d ${dataDir} \
-d ${cfg.dataDir} \
-l /var/log/seafile/server.log \
-P /run/seafile/server.pid \
-p /run/seafile
@ -245,118 +348,162 @@ in
};
preStart = ''
if [ ! -f "${seafRoot}/server-setup" ]; then
mkdir -p ${dataDir}/library-template
mkdir -p ${ccnetDir}/{GroupMgr,misc,OrgMgr,PeerMgr}
sqlite3 ${ccnetDir}/GroupMgr/groupmgr.db ".read ${cfg.seafilePackage}/share/seafile/sql/sqlite/groupmgr.sql"
sqlite3 ${ccnetDir}/misc/config.db ".read ${cfg.seafilePackage}/share/seafile/sql/sqlite/config.sql"
sqlite3 ${ccnetDir}/OrgMgr/orgmgr.db ".read ${cfg.seafilePackage}/share/seafile/sql/sqlite/org.sql"
sqlite3 ${ccnetDir}/PeerMgr/usermgr.db ".read ${cfg.seafilePackage}/share/seafile/sql/sqlite/user.sql"
sqlite3 ${dataDir}/seafile.db ".read ${cfg.seafilePackage}/share/seafile/sql/sqlite/seafile.sql"
echo "${cfg.seafilePackage.version}-sqlite" > "${seafRoot}"/server-setup
mkdir -p ${cfg.dataDir}/library-template
# Load schema on first install
${pkgs.mariadb.client}/bin/mysql --database=ccnet_db < ${cfg.seahubPackage.seafile-server}/share/seafile/sql/mysql/ccnet.sql
${pkgs.mariadb.client}/bin/mysql --database=seafile_db < ${cfg.seahubPackage.seafile-server}/share/seafile/sql/mysql/seafile.sql
echo "${cfg.seahubPackage.seafile-server.version}-mysql" > "${seafRoot}"/server-setup
echo Loaded MySQL schemas for first install
fi
# checking for upgrades and handling them
installedMajor=$(cat "${seafRoot}/server-setup" | cut -d"-" -f1 | cut -d"." -f1)
installedMinor=$(cat "${seafRoot}/server-setup" | cut -d"-" -f1 | cut -d"." -f2)
pkgMajor=$(echo "${cfg.seafilePackage.version}" | cut -d"." -f1)
pkgMinor=$(echo "${cfg.seafilePackage.version}" | cut -d"." -f2)
pkgMajor=$(echo "${cfg.seahubPackage.seafile-server.version}" | cut -d"." -f1)
pkgMinor=$(echo "${cfg.seahubPackage.seafile-server.version}" | cut -d"." -f2)
if [[ $installedMajor == $pkgMajor && $installedMinor == $pkgMinor ]]; then
:
elif [[ $installedMajor == 8 && $installedMinor == 0 && $pkgMajor == 9 && $pkgMinor == 0 ]]; then
# Upgrade from 8.0 to 9.0
sqlite3 ${dataDir}/seafile.db ".read ${pkgs.seahub}/scripts/upgrade/sql/9.0.0/sqlite3/seafile.sql"
echo "${cfg.seafilePackage.version}-sqlite" > "${seafRoot}"/server-setup
elif [[ $installedMajor == 9 && $installedMinor == 0 && $pkgMajor == 10 && $pkgMinor == 0 ]]; then
# Upgrade from 9.0 to 10.0
sqlite3 ${dataDir}/seafile.db ".read ${pkgs.seahub}/scripts/upgrade/sql/10.0.0/sqlite3/seafile.sql"
echo "${cfg.seafilePackage.version}-sqlite" > "${seafRoot}"/server-setup
elif [[ $installedMajor == 10 && $installedMinor == 0 && $pkgMajor == 11 && $pkgMinor == 0 ]]; then
# Upgrade from 10.0 to 11.0: migrate to mysql
echo Migrating from version 10 to 11
# From https://github.com/haiwen/seahub/blob/e12f941bfef7191795d8c72a7d339c01062964b2/scripts/sqlite2mysql.sh
echo Migrating ccnet database to MySQL
${lib.getExe pkgs.sqlite} ${ccnetDir}/PeerMgr/usermgr.db ".dump" | \
${lib.getExe cfg.seahubPackage.python3} ${cfg.seahubPackage}/scripts/sqlite2mysql.py > ${ccnetDir}/ccnet.sql
${lib.getExe pkgs.sqlite} ${ccnetDir}/GroupMgr/groupmgr.db ".dump" | \
${lib.getExe cfg.seahubPackage.python3} ${cfg.seahubPackage}/scripts/sqlite2mysql.py >> ${ccnetDir}/ccnet.sql
sed 's/ctime INTEGER/ctime BIGINT/g' -i ${ccnetDir}/ccnet.sql
sed 's/email TEXT, role TEXT/email VARCHAR(255), role TEXT/g' -i ${ccnetDir}/ccnet.sql
${pkgs.mariadb.client}/bin/mysql --database=ccnet_db < ${ccnetDir}/ccnet.sql
echo Migrating seafile database to MySQL
${lib.getExe pkgs.sqlite} ${cfg.dataDir}/seafile.db ".dump" | \
${lib.getExe cfg.seahubPackage.python3} ${cfg.seahubPackage}/scripts/sqlite2mysql.py > ${cfg.dataDir}/seafile.sql
sed 's/owner_id TEXT/owner_id VARCHAR(255)/g' -i ${cfg.dataDir}/seafile.sql
sed 's/user_name TEXT/user_name VARCHAR(255)/g' -i ${cfg.dataDir}/seafile.sql
${pkgs.mariadb.client}/bin/mysql --database=seafile_db < ${cfg.dataDir}/seafile.sql
echo Migrating seahub database to MySQL
echo 'SET FOREIGN_KEY_CHECKS=0;' > ${seahubDir}/seahub.sql
${lib.getExe pkgs.sqlite} ${seahubDir}/seahub.db ".dump" | \
${lib.getExe cfg.seahubPackage.python3} ${cfg.seahubPackage}/scripts/sqlite2mysql.py >> ${seahubDir}/seahub.sql
sed 's/`permission` , `reporter` text NOT NULL/`permission` longtext NOT NULL/g' -i ${seahubDir}/seahub.sql
sed 's/varchar(256) NOT NULL UNIQUE/varchar(255) NOT NULL UNIQUE/g' -i ${seahubDir}/seahub.sql
sed 's/, UNIQUE (`user_email`, `contact_email`)//g' -i ${seahubDir}/seahub.sql
sed '/INSERT INTO `base_dirfileslastmodifiedinfo`/d' -i ${seahubDir}/seahub.sql
sed '/INSERT INTO `notifications_usernotification`/d' -i ${seahubDir}/seahub.sql
sed 's/DEFERRABLE INITIALLY DEFERRED//g' -i ${seahubDir}/seahub.sql
${pkgs.mariadb.client}/bin/mysql --database=seahub_db < ${seahubDir}/seahub.sql
echo "${cfg.seahubPackage.seafile-server.version}-mysql" > "${seafRoot}"/server-setup
echo Migration complete
else
echo "Unsupported upgrade" >&2
echo "Unsupported upgrade: $installedMajor.$installedMinor to $pkgMajor.$pkgMinor" >&2
exit 1
fi
'';
# Fix unix socket permissions
postStart = (
lib.strings.optionalString (lib.strings.hasPrefix "unix:" cfg.seafileSettings.fileserver.host) ''
while [[ ! -S "${lib.strings.removePrefix "unix:" cfg.seafileSettings.fileserver.host}" ]]; do
sleep 1
done
chmod 666 "${lib.strings.removePrefix "unix:" cfg.seafileSettings.fileserver.host}"
''
);
};
seahub = {
description = "Seafile Server Web Frontend";
wantedBy = [ "seafile.target" ];
partOf = [ "seafile.target" ];
after = [ "network.target" "seaf-server.service" ];
requires = [ "seaf-server.service" ];
unitConfig.RequiresMountsFor = optionalDataDir;
unitConfig.RequiresMountsFor = lib.lists.optional (cfg.dataDir != "${seafRoot}/data") cfg.dataDir;
requires = [
"mysql.service"
"seaf-server.service"
];
after = [
"network.target"
"mysql.service"
"seaf-server.service"
];
restartTriggers = [ seahubSettings ];
environment = {
PYTHONPATH = "${pkgs.seahub.pythonPath}:${pkgs.seahub}/thirdpart:${pkgs.seahub}";
PYTHONPATH = "${cfg.seahubPackage.pythonPath}:${cfg.seahubPackage}/thirdpart:${cfg.seahubPackage}";
DJANGO_SETTINGS_MODULE = "seahub.settings";
CCNET_CONF_DIR = ccnetDir;
SEAFILE_CONF_DIR = dataDir;
SEAFILE_CONF_DIR = cfg.dataDir;
SEAFILE_CENTRAL_CONF_DIR = "/etc/seafile";
SEAFILE_RPC_PIPE_PATH = "/run/seafile";
SEAHUB_LOG_DIR = "/var/log/seafile";
};
serviceConfig = securityOptions // {
User = cfg.user;
Group = cfg.group;
serviceConfig = serviceOptions // {
RuntimeDirectory = "seahub";
StateDirectory = "seafile";
LogsDirectory = "seafile";
ConfigurationDirectory = "seafile";
ReadWritePaths = optionalDataDir;
ExecStart = ''
${pkgs.seahub.python.pkgs.gunicorn}/bin/gunicorn seahub.wsgi:application \
${lib.getExe cfg.seahubPackage.python3.pkgs.gunicorn} seahub.wsgi:application \
--name seahub \
--workers ${toString cfg.workers} \
--log-level=info \
--preload \
--timeout=1200 \
--limit-request-line=8190 \
--bind unix:/run/seahub/gunicorn.sock
--bind ${cfg.seahubAddress}
'';
};
preStart = ''
mkdir -p ${seahubDir}/media
# Link all media except avatars
for m in `find ${pkgs.seahub}/media/ -maxdepth 1 -not -name "avatars"`; do
for m in `find ${cfg.seahubPackage}/media/ -maxdepth 1 -not -name "avatars"`; do
ln -sf $m ${seahubDir}/media/
done
if [ ! -e "${seafRoot}/.seahubSecret" ]; then
${pkgs.seahub.python}/bin/python ${pkgs.seahub}/tools/secret_key_generator.py > ${seafRoot}/.seahubSecret
chmod 400 ${seafRoot}/.seahubSecret
(
umask 377 &&
${lib.getExe cfg.seahubPackage.python3} ${cfg.seahubPackage}/tools/secret_key_generator.py > ${seafRoot}/.seahubSecret
)
fi
if [ ! -f "${seafRoot}/seahub-setup" ]; then
# avatars directory should be writable
install -D -t ${seahubDir}/media/avatars/ ${pkgs.seahub}/media/avatars/default.png
install -D -t ${seahubDir}/media/avatars/groups ${pkgs.seahub}/media/avatars/groups/default.png
install -D -t ${seahubDir}/media/avatars/ ${cfg.seahubPackage}/media/avatars/default.png
install -D -t ${seahubDir}/media/avatars/groups ${cfg.seahubPackage}/media/avatars/groups/default.png
# init database
${pkgs.seahub}/manage.py migrate
${cfg.seahubPackage}/manage.py migrate
# create admin account
${pkgs.expect}/bin/expect -c 'spawn ${pkgs.seahub}/manage.py createsuperuser --email=${cfg.adminEmail}; expect "Password: "; send "${cfg.initialAdminPassword}\r"; expect "Password (again): "; send "${cfg.initialAdminPassword}\r"; expect "Superuser created successfully."'
echo "${pkgs.seahub.version}-sqlite" > "${seafRoot}/seahub-setup"
${lib.getExe pkgs.expect} -c 'spawn ${cfg.seahubPackage}/manage.py createsuperuser --email=${cfg.adminEmail}; expect "Password: "; send "${cfg.initialAdminPassword}\r"; expect "Password (again): "; send "${cfg.initialAdminPassword}\r"; expect "Superuser created successfully."'
echo "${cfg.seahubPackage.version}-mysql" > "${seafRoot}/seahub-setup"
fi
if [ $(cat "${seafRoot}/seahub-setup" | cut -d"-" -f1) != "${pkgs.seahub.version}" ]; then
# update database
${pkgs.seahub}/manage.py migrate
echo "${pkgs.seahub.version}-sqlite" > "${seafRoot}/seahub-setup"
# run django migrations
${cfg.seahubPackage}/manage.py migrate
echo "${cfg.seahubPackage.version}-mysql" > "${seafRoot}/seahub-setup"
fi
'';
};
seaf-gc = {
description = "Seafile storage garbage collection";
conflicts = [ "seaf-server.service" "seahub.service" ];
after = [ "seaf-server.service" "seahub.service" ];
unitConfig.RequiresMountsFor = optionalDataDir;
onSuccess = [ "seaf-server.service" "seahub.service" ];
onFailure = [ "seaf-server.service" "seahub.service" ];
startAt = cfg.gcDates;
serviceConfig = securityOptions // {
User = cfg.user;
Group = cfg.group;
StateDirectory = "seafile";
RuntimeDirectory = "seafile";
LogsDirectory = "seafile";
ConfigurationDirectory = "seafile";
ReadWritePaths = optionalDataDir;
conflicts = [
"seaf-server.service"
"seahub.service"
];
after = [
"seaf-server.service"
"seahub.service"
];
unitConfig.RequiresMountsFor = lib.lists.optional (cfg.dataDir != "${seafRoot}/data") cfg.dataDir;
onSuccess = [
"seaf-server.service"
"seahub.service"
];
onFailure = [
"seaf-server.service"
"seahub.service"
];
startAt = lib.lists.optionals cfg.gc.enable cfg.gc.dates;
serviceConfig = serviceOptions // {
Type = "oneshot";
};
script = ''
@ -368,8 +515,8 @@ in
# checking for pending upgrades
installedMajor=$(cat "${seafRoot}/server-setup" | cut -d"-" -f1 | cut -d"." -f1)
installedMinor=$(cat "${seafRoot}/server-setup" | cut -d"-" -f1 | cut -d"." -f2)
pkgMajor=$(echo "${cfg.seafilePackage.version}" | cut -d"." -f1)
pkgMinor=$(echo "${cfg.seafilePackage.version}" | cut -d"." -f2)
pkgMajor=$(echo "${cfg.seahubPackage.seafile-server.version}" | cut -d"." -f1)
pkgMinor=$(echo "${cfg.seahubPackage.seafile-server.version}" | cut -d"." -f2)
if [[ $installedMajor != $pkgMajor || $installedMinor != $pkgMinor ]]; then
echo "Server not upgraded yet" >&2
@ -377,15 +524,25 @@ in
fi
# Clean up user-deleted blocks and libraries
${cfg.seafilePackage}/bin/seafserv-gc \
${cfg.seahubPackage.seafile-server}/bin/seafserv-gc \
-F /etc/seafile \
-c ${ccnetDir} \
-d ${dataDir} \
-d ${cfg.dataDir} \
--rm-fs
'';
};
};
systemd.timers.seaf-gc = lib.mkIf cfg.gc.enable {
timerConfig = {
randomizedDelaySec = cfg.gc.randomizedDelaySec;
Persistent = cfg.gc.persistent;
};
};
};
meta.maintainers = with maintainers; [ greizgh schmittlauch ];
meta.maintainers = with lib.maintainers; [
greizgh
schmittlauch
];
}

View File

@ -14,6 +14,7 @@ import ./make-test-python.nix ({ pkgs, ... }:
services.seafile = {
enable = true;
ccnetSettings.General.SERVICE_URL = "http://server";
seafileSettings.fileserver.host = "unix:/run/seafile/server.sock";
adminEmail = "admin@example.com";
initialAdminPassword = "seafile_password";
};
@ -22,7 +23,7 @@ import ./make-test-python.nix ({ pkgs, ... }:
virtualHosts."server" = {
locations."/".proxyPass = "http://unix:/run/seahub/gunicorn.sock";
locations."/seafhttp" = {
proxyPass = "http://127.0.0.1:8082";
proxyPass = "http://unix:/run/seafile/server.sock";
extraConfig = ''
rewrite ^/seafhttp(.*)$ $1 break;
client_max_body_size 0;

View File

@ -52,7 +52,7 @@ python3.pkgs.buildPythonApplication rec {
markdown
bleach
(seafile-server.override { inherit python3; })
(python3.pkgs.toPythonModule (seafile-server.override { inherit python3; }))
];
postPatch = ''
@ -67,7 +67,7 @@ python3.pkgs.buildPythonApplication rec {
passthru = {
inherit python3;
pythonPath = "${python3.pkgs.makePythonPath propagatedBuildInputs}:${seafile-server}/${python3.sitePackages}";
pythonPath = python3.pkgs.makePythonPath propagatedBuildInputs;
tests = {
inherit (nixosTests) seafile;
};