|
|
|
@@ -32,7 +32,8 @@ let
|
|
|
|
|
dataDir = "${seafRoot}/data";
|
|
|
|
|
seahubDir = "${seafRoot}/seahub";
|
|
|
|
|
|
|
|
|
|
in {
|
|
|
|
|
in
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
###### Interface
|
|
|
|
|
|
|
|
|
@@ -147,146 +148,151 @@ in {
|
|
|
|
|
description = "Seafile components";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
systemd.services = let
|
|
|
|
|
securityOptions = {
|
|
|
|
|
ProtectHome = true;
|
|
|
|
|
PrivateUsers = true;
|
|
|
|
|
PrivateDevices = true;
|
|
|
|
|
ProtectClock = true;
|
|
|
|
|
ProtectHostname = true;
|
|
|
|
|
ProtectProc = "invisible";
|
|
|
|
|
ProtectKernelModules = true;
|
|
|
|
|
ProtectKernelTunables = true;
|
|
|
|
|
ProtectKernelLogs = true;
|
|
|
|
|
ProtectControlGroups = true;
|
|
|
|
|
RestrictNamespaces = true;
|
|
|
|
|
LockPersonality = true;
|
|
|
|
|
RestrictRealtime = true;
|
|
|
|
|
RestrictSUIDSGID = true;
|
|
|
|
|
MemoryDenyWriteExecute = true;
|
|
|
|
|
SystemCallArchitectures = "native";
|
|
|
|
|
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" ];
|
|
|
|
|
};
|
|
|
|
|
in {
|
|
|
|
|
seaf-server = {
|
|
|
|
|
description = "Seafile server";
|
|
|
|
|
partOf = [ "seafile.target" ];
|
|
|
|
|
after = [ "network.target" ];
|
|
|
|
|
wantedBy = [ "seafile.target" ];
|
|
|
|
|
restartTriggers = [ ccnetConf seafileConf ];
|
|
|
|
|
path = [ pkgs.sqlite ];
|
|
|
|
|
serviceConfig = securityOptions // {
|
|
|
|
|
User = "seafile";
|
|
|
|
|
Group = "seafile";
|
|
|
|
|
DynamicUser = true;
|
|
|
|
|
StateDirectory = "seafile";
|
|
|
|
|
RuntimeDirectory = "seafile";
|
|
|
|
|
LogsDirectory = "seafile";
|
|
|
|
|
ConfigurationDirectory = "seafile";
|
|
|
|
|
ExecStart = ''
|
|
|
|
|
${cfg.seafilePackage}/bin/seaf-server \
|
|
|
|
|
--foreground \
|
|
|
|
|
-F /etc/seafile \
|
|
|
|
|
-c ${ccnetDir} \
|
|
|
|
|
-d ${dataDir} \
|
|
|
|
|
-l /var/log/seafile/server.log \
|
|
|
|
|
-P /run/seafile/server.pid \
|
|
|
|
|
-p /run/seafile
|
|
|
|
|
systemd.services =
|
|
|
|
|
let
|
|
|
|
|
securityOptions = {
|
|
|
|
|
ProtectHome = true;
|
|
|
|
|
PrivateUsers = true;
|
|
|
|
|
PrivateDevices = true;
|
|
|
|
|
ProtectClock = true;
|
|
|
|
|
ProtectHostname = true;
|
|
|
|
|
ProtectProc = "invisible";
|
|
|
|
|
ProtectKernelModules = true;
|
|
|
|
|
ProtectKernelTunables = true;
|
|
|
|
|
ProtectKernelLogs = true;
|
|
|
|
|
ProtectControlGroups = true;
|
|
|
|
|
RestrictNamespaces = true;
|
|
|
|
|
LockPersonality = true;
|
|
|
|
|
RestrictRealtime = true;
|
|
|
|
|
RestrictSUIDSGID = true;
|
|
|
|
|
MemoryDenyWriteExecute = true;
|
|
|
|
|
SystemCallArchitectures = "native";
|
|
|
|
|
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" ];
|
|
|
|
|
};
|
|
|
|
|
in
|
|
|
|
|
{
|
|
|
|
|
seaf-server = {
|
|
|
|
|
description = "Seafile server";
|
|
|
|
|
partOf = [ "seafile.target" ];
|
|
|
|
|
after = [ "network.target" ];
|
|
|
|
|
wantedBy = [ "seafile.target" ];
|
|
|
|
|
restartTriggers = [ ccnetConf seafileConf ];
|
|
|
|
|
path = [ pkgs.sqlite ];
|
|
|
|
|
serviceConfig = securityOptions // {
|
|
|
|
|
User = "seafile";
|
|
|
|
|
Group = "seafile";
|
|
|
|
|
DynamicUser = true;
|
|
|
|
|
StateDirectory = "seafile";
|
|
|
|
|
RuntimeDirectory = "seafile";
|
|
|
|
|
LogsDirectory = "seafile";
|
|
|
|
|
ConfigurationDirectory = "seafile";
|
|
|
|
|
ExecStart = ''
|
|
|
|
|
${cfg.seafilePackage}/bin/seaf-server \
|
|
|
|
|
--foreground \
|
|
|
|
|
-F /etc/seafile \
|
|
|
|
|
-c ${ccnetDir} \
|
|
|
|
|
-d ${dataDir} \
|
|
|
|
|
-l /var/log/seafile/server.log \
|
|
|
|
|
-P /run/seafile/server.pid \
|
|
|
|
|
-p /run/seafile
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
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
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
else
|
|
|
|
|
echo "Unsupported upgrade" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
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
|
|
|
|
|
fi
|
|
|
|
|
# checking for upgrades and handling them
|
|
|
|
|
# WARNING: needs to be extended to actually handle major version migrations
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
else
|
|
|
|
|
echo "Unsupported upgrade" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
seahub = {
|
|
|
|
|
description = "Seafile Server Web Frontend";
|
|
|
|
|
wantedBy = [ "seafile.target" ];
|
|
|
|
|
partOf = [ "seafile.target" ];
|
|
|
|
|
after = [ "network.target" "seaf-server.service" ];
|
|
|
|
|
requires = [ "seaf-server.service" ];
|
|
|
|
|
restartTriggers = [ seahubSettings ];
|
|
|
|
|
environment = {
|
|
|
|
|
PYTHONPATH = "${pkgs.seahub.pythonPath}:${pkgs.seahub}/thirdpart:${pkgs.seahub}";
|
|
|
|
|
DJANGO_SETTINGS_MODULE = "seahub.settings";
|
|
|
|
|
CCNET_CONF_DIR = ccnetDir;
|
|
|
|
|
SEAFILE_CONF_DIR = dataDir;
|
|
|
|
|
SEAFILE_CENTRAL_CONF_DIR = "/etc/seafile";
|
|
|
|
|
SEAFILE_RPC_PIPE_PATH = "/run/seafile";
|
|
|
|
|
SEAHUB_LOG_DIR = "/var/log/seafile";
|
|
|
|
|
};
|
|
|
|
|
serviceConfig = securityOptions // {
|
|
|
|
|
User = "seafile";
|
|
|
|
|
Group = "seafile";
|
|
|
|
|
DynamicUser = true;
|
|
|
|
|
RuntimeDirectory = "seahub";
|
|
|
|
|
StateDirectory = "seafile";
|
|
|
|
|
LogsDirectory = "seafile";
|
|
|
|
|
ConfigurationDirectory = "seafile";
|
|
|
|
|
ExecStart = ''
|
|
|
|
|
${pkgs.seahub.python.pkgs.gunicorn}/bin/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
|
|
|
|
|
seahub = {
|
|
|
|
|
description = "Seafile Server Web Frontend";
|
|
|
|
|
wantedBy = [ "seafile.target" ];
|
|
|
|
|
partOf = [ "seafile.target" ];
|
|
|
|
|
after = [ "network.target" "seaf-server.service" ];
|
|
|
|
|
requires = [ "seaf-server.service" ];
|
|
|
|
|
restartTriggers = [ seahubSettings ];
|
|
|
|
|
environment = {
|
|
|
|
|
PYTHONPATH = "${pkgs.seahub.pythonPath}:${pkgs.seahub}/thirdpart:${pkgs.seahub}";
|
|
|
|
|
DJANGO_SETTINGS_MODULE = "seahub.settings";
|
|
|
|
|
CCNET_CONF_DIR = ccnetDir;
|
|
|
|
|
SEAFILE_CONF_DIR = dataDir;
|
|
|
|
|
SEAFILE_CENTRAL_CONF_DIR = "/etc/seafile";
|
|
|
|
|
SEAFILE_RPC_PIPE_PATH = "/run/seafile";
|
|
|
|
|
SEAHUB_LOG_DIR = "/var/log/seafile";
|
|
|
|
|
};
|
|
|
|
|
serviceConfig = securityOptions // {
|
|
|
|
|
User = "seafile";
|
|
|
|
|
Group = "seafile";
|
|
|
|
|
DynamicUser = true;
|
|
|
|
|
RuntimeDirectory = "seahub";
|
|
|
|
|
StateDirectory = "seafile";
|
|
|
|
|
LogsDirectory = "seafile";
|
|
|
|
|
ConfigurationDirectory = "seafile";
|
|
|
|
|
ExecStart = ''
|
|
|
|
|
${pkgs.seahub.python.pkgs.gunicorn}/bin/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
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
preStart = ''
|
|
|
|
|
mkdir -p ${seahubDir}/media
|
|
|
|
|
# Link all media except avatars
|
|
|
|
|
for m in `find ${pkgs.seahub}/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
|
|
|
|
|
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
|
|
|
|
|
# init database
|
|
|
|
|
${pkgs.seahub}/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"
|
|
|
|
|
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"
|
|
|
|
|
fi
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
preStart = ''
|
|
|
|
|
mkdir -p ${seahubDir}/media
|
|
|
|
|
# Link all media except avatars
|
|
|
|
|
for m in `find ${pkgs.seahub}/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
|
|
|
|
|
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
|
|
|
|
|
# init database
|
|
|
|
|
${pkgs.seahub}/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"
|
|
|
|
|
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"
|
|
|
|
|
fi
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|