Merge pull request #119719 from greizgh/seafile
This commit is contained in:
@@ -373,6 +373,14 @@
|
|||||||
<link linkend="opt-services.multipath.enable">services.multipath</link>.
|
<link linkend="opt-services.multipath.enable">services.multipath</link>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://www.seafile.com/en/home/">seafile</link>,
|
||||||
|
an open source file syncing & sharing software. Available
|
||||||
|
as
|
||||||
|
<link xlink:href="options.html#opt-services.seafile.enable">services.seafile</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="sec-release-21.11-incompatibilities">
|
<section xml:id="sec-release-21.11-incompatibilities">
|
||||||
|
|||||||
@@ -114,6 +114,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||||||
|
|
||||||
- [multipath](https://github.com/opensvc/multipath-tools), the device mapper multipath (DM-MP) daemon. Available as [services.multipath](#opt-services.multipath.enable).
|
- [multipath](https://github.com/opensvc/multipath-tools), the device mapper multipath (DM-MP) daemon. Available as [services.multipath](#opt-services.multipath.enable).
|
||||||
|
|
||||||
|
- [seafile](https://www.seafile.com/en/home/), an open source file syncing & sharing software. Available as [services.seafile](options.html#opt-services.seafile.enable).
|
||||||
|
|
||||||
## Backward Incompatibilities {#sec-release-21.11-incompatibilities}
|
## Backward Incompatibilities {#sec-release-21.11-incompatibilities}
|
||||||
|
|
||||||
- The `services.wakeonlan` option was removed, and replaced with `networking.interfaces.<name>.wakeOnLan`.
|
- The `services.wakeonlan` option was removed, and replaced with `networking.interfaces.<name>.wakeOnLan`.
|
||||||
|
|||||||
@@ -838,6 +838,7 @@
|
|||||||
./services/networking/rpcbind.nix
|
./services/networking/rpcbind.nix
|
||||||
./services/networking/rxe.nix
|
./services/networking/rxe.nix
|
||||||
./services/networking/sabnzbd.nix
|
./services/networking/sabnzbd.nix
|
||||||
|
./services/networking/seafile.nix
|
||||||
./services/networking/searx.nix
|
./services/networking/searx.nix
|
||||||
./services/networking/skydns.nix
|
./services/networking/skydns.nix
|
||||||
./services/networking/shadowsocks.nix
|
./services/networking/shadowsocks.nix
|
||||||
|
|||||||
290
nixos/modules/services/networking/seafile.nix
Normal file
290
nixos/modules/services/networking/seafile.nix
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
python = pkgs.python3Packages.python;
|
||||||
|
cfg = config.services.seafile;
|
||||||
|
settingsFormat = pkgs.formats.ini { };
|
||||||
|
|
||||||
|
ccnetConf = settingsFormat.generate "ccnet.conf" cfg.ccnetSettings;
|
||||||
|
|
||||||
|
seafileConf = settingsFormat.generate "seafile.conf" 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',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MEDIA_ROOT = '${seahubDir}/media/'
|
||||||
|
THUMBNAIL_ROOT = '${seahubDir}/thumbnail/'
|
||||||
|
|
||||||
|
with open('${seafRoot}/.seahubSecret') as f:
|
||||||
|
SECRET_KEY = f.readline().rstrip()
|
||||||
|
|
||||||
|
${cfg.seahubExtraConf}
|
||||||
|
'';
|
||||||
|
|
||||||
|
seafRoot = "/var/lib/seafile"; # hardcode it due to dynamicuser
|
||||||
|
ccnetDir = "${seafRoot}/ccnet";
|
||||||
|
dataDir = "${seafRoot}/data";
|
||||||
|
seahubDir = "${seafRoot}/seahub";
|
||||||
|
|
||||||
|
in {
|
||||||
|
|
||||||
|
###### Interface
|
||||||
|
|
||||||
|
options.services.seafile = {
|
||||||
|
enable = mkEnableOption "Seafile server";
|
||||||
|
|
||||||
|
ccnetSettings = mkOption {
|
||||||
|
type = types.submodule {
|
||||||
|
freeformType = settingsFormat.type;
|
||||||
|
|
||||||
|
options = {
|
||||||
|
General = {
|
||||||
|
SERVICE_URL = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "https://www.example.com";
|
||||||
|
description = ''
|
||||||
|
Seahub public URL.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Configuration for ccnet, see
|
||||||
|
<link xlink:href="https://manual.seafile.com/config/ccnet-conf/"/>
|
||||||
|
for supported values.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
seafileSettings = mkOption {
|
||||||
|
type = types.submodule {
|
||||||
|
freeformType = settingsFormat.type;
|
||||||
|
|
||||||
|
options = {
|
||||||
|
fileserver = {
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 8082;
|
||||||
|
description = ''
|
||||||
|
The tcp port used by seafile fileserver.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
host = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "127.0.0.1";
|
||||||
|
example = "0.0.0.0";
|
||||||
|
description = ''
|
||||||
|
The binding address used by seafile fileserver.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Configuration for seafile-server, see
|
||||||
|
<link xlink:href="https://manual.seafile.com/config/seafile-conf/"/>
|
||||||
|
for supported values.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
workers = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 4;
|
||||||
|
example = 10;
|
||||||
|
description = ''
|
||||||
|
The number of gunicorn worker processes for handling requests.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
adminEmail = mkOption {
|
||||||
|
example = "john@example.com";
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
Seafile Seahub Admin Account Email.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
initialAdminPassword = mkOption {
|
||||||
|
example = "someStrongPass";
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
Seafile Seahub Admin Account initial password.
|
||||||
|
Should be change via Seahub web front-end.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
seafilePackage = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
description = "Which package to use for the seafile server.";
|
||||||
|
default = pkgs.seafile-server;
|
||||||
|
};
|
||||||
|
|
||||||
|
seahubExtraConf = mkOption {
|
||||||
|
default = "";
|
||||||
|
type = types.lines;
|
||||||
|
description = ''
|
||||||
|
Extra config to append to `seahub_settings.py` file.
|
||||||
|
Refer to <link xlink:href="https://manual.seafile.com/config/seahub_settings_py/" />
|
||||||
|
for all available options.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
###### Implementation
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
environment.etc."seafile/ccnet.conf".source = ccnetConf;
|
||||||
|
environment.etc."seafile/seafile.conf".source = seafileConf;
|
||||||
|
environment.etc."seafile/seahub_settings.py".source = seahubSettings;
|
||||||
|
|
||||||
|
systemd.targets.seafile = {
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
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 ];
|
||||||
|
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}
|
||||||
|
${pkgs.sqlite}/bin/sqlite3 ${ccnetDir}/GroupMgr/groupmgr.db ".read ${cfg.seafilePackage}/share/seafile/sql/sqlite/groupmgr.sql"
|
||||||
|
${pkgs.sqlite}/bin/sqlite3 ${ccnetDir}/misc/config.db ".read ${cfg.seafilePackage}/share/seafile/sql/sqlite/config.sql"
|
||||||
|
${pkgs.sqlite}/bin/sqlite3 ${ccnetDir}/OrgMgr/orgmgr.db ".read ${cfg.seafilePackage}/share/seafile/sql/sqlite/org.sql"
|
||||||
|
${pkgs.sqlite}/bin/sqlite3 ${ccnetDir}/PeerMgr/usermgr.db ".read ${cfg.seafilePackage}/share/seafile/sql/sqlite/user.sql"
|
||||||
|
${pkgs.sqlite}/bin/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
|
||||||
|
echo "Unsupported upgrade" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
seahub = let
|
||||||
|
penv = (pkgs.python3.withPackages (ps: with ps; [ gunicorn seahub ]));
|
||||||
|
in {
|
||||||
|
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.python3Packages.seahub}/thirdpart:${pkgs.python3Packages.seahub}:${penv}/${python.sitePackages}";
|
||||||
|
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 = ''
|
||||||
|
${penv}/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.python3Packages.seahub}/media/ -maxdepth 1 -not -name "avatars"`; do
|
||||||
|
ln -sf $m ${seahubDir}/media/
|
||||||
|
done
|
||||||
|
if [ ! -e "${seafRoot}/.seahubSecret" ]; then
|
||||||
|
${penv}/bin/python ${pkgs.python3Packages.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.python3Packages.seahub}/media/avatars/default.png
|
||||||
|
install -D -t ${seahubDir}/media/avatars/groups ${pkgs.python3Packages.seahub}/media/avatars/groups/default.png
|
||||||
|
# init database
|
||||||
|
${pkgs.python3Packages.seahub}/manage.py migrate
|
||||||
|
# create admin account
|
||||||
|
${pkgs.expect}/bin/expect -c 'spawn ${pkgs.python3Packages.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.python3Packages.seahub.version}-sqlite" > "${seafRoot}/seahub-setup"
|
||||||
|
fi
|
||||||
|
if [ $(cat "${seafRoot}/seahub-setup" | cut -d"-" -f1) != "${pkgs.python3Packages.seahub.version}" ]; then
|
||||||
|
# update database
|
||||||
|
${pkgs.python3Packages.seahub}/manage.py migrate
|
||||||
|
echo "${pkgs.python3Packages.seahub.version}-sqlite" > "${seafRoot}/seahub-setup"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
123
nixos/tests/seafile.nix
Normal file
123
nixos/tests/seafile.nix
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
import ./make-test-python.nix ({ pkgs, ... }:
|
||||||
|
let
|
||||||
|
client = { config, pkgs, ... }: {
|
||||||
|
virtualisation.memorySize = 256;
|
||||||
|
environment.systemPackages = [ pkgs.seafile-shared pkgs.curl ];
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
name = "seafile";
|
||||||
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
|
maintainers = [ kampfschlaefer schmittlauch ];
|
||||||
|
};
|
||||||
|
|
||||||
|
nodes = {
|
||||||
|
server = { config, pkgs, ... }: {
|
||||||
|
virtualisation.memorySize = 512;
|
||||||
|
services.seafile = {
|
||||||
|
enable = true;
|
||||||
|
ccnetSettings.General.SERVICE_URL = "http://server";
|
||||||
|
adminEmail = "admin@example.com";
|
||||||
|
initialAdminPassword = "seafile_password";
|
||||||
|
};
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts."server" = {
|
||||||
|
locations."/".proxyPass = "http://unix:/run/seahub/gunicorn.sock";
|
||||||
|
locations."/seafhttp" = {
|
||||||
|
proxyPass = "http://127.0.0.1:8082";
|
||||||
|
extraConfig = ''
|
||||||
|
rewrite ^/seafhttp(.*)$ $1 break;
|
||||||
|
client_max_body_size 0;
|
||||||
|
proxy_connect_timeout 36000s;
|
||||||
|
proxy_read_timeout 36000s;
|
||||||
|
proxy_send_timeout 36000s;
|
||||||
|
send_timeout 36000s;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
networking.firewall = { allowedTCPPorts = [ 80 ]; };
|
||||||
|
};
|
||||||
|
client1 = client pkgs;
|
||||||
|
client2 = client pkgs;
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
start_all()
|
||||||
|
|
||||||
|
with subtest("start seaf-server"):
|
||||||
|
server.wait_for_unit("seaf-server.service")
|
||||||
|
server.wait_for_file("/run/seafile/seafile.sock")
|
||||||
|
|
||||||
|
with subtest("start seahub"):
|
||||||
|
server.wait_for_unit("seahub.service")
|
||||||
|
server.wait_for_unit("nginx.service")
|
||||||
|
server.wait_for_file("/run/seahub/gunicorn.sock")
|
||||||
|
|
||||||
|
with subtest("client1 fetch seahub page"):
|
||||||
|
client1.succeed("curl -L http://server | grep 'Log In' >&2")
|
||||||
|
|
||||||
|
with subtest("client1 connect"):
|
||||||
|
client1.wait_for_unit("default.target")
|
||||||
|
client1.succeed("seaf-cli init -d . >&2")
|
||||||
|
client1.succeed("seaf-cli start >&2")
|
||||||
|
client1.succeed(
|
||||||
|
"seaf-cli list-remote -s http://server -u admin\@example.com -p seafile_password >&2"
|
||||||
|
)
|
||||||
|
|
||||||
|
libid = client1.succeed(
|
||||||
|
'seaf-cli create -s http://server -n test01 -u admin\@example.com -p seafile_password -t "first test library"'
|
||||||
|
).strip()
|
||||||
|
|
||||||
|
client1.succeed(
|
||||||
|
"seaf-cli list-remote -s http://server -u admin\@example.com -p seafile_password |grep test01"
|
||||||
|
)
|
||||||
|
client1.fail(
|
||||||
|
"seaf-cli list-remote -s http://server -u admin\@example.com -p seafile_password |grep test02"
|
||||||
|
)
|
||||||
|
|
||||||
|
client1.succeed(
|
||||||
|
f"seaf-cli download -l {libid} -s http://server -u admin\@example.com -p seafile_password -d . >&2"
|
||||||
|
)
|
||||||
|
|
||||||
|
client1.sleep(3)
|
||||||
|
|
||||||
|
client1.succeed("seaf-cli status |grep synchronized >&2")
|
||||||
|
|
||||||
|
client1.succeed("ls -la >&2")
|
||||||
|
client1.succeed("ls -la test01 >&2")
|
||||||
|
|
||||||
|
client1.execute("echo bla > test01/first_file")
|
||||||
|
|
||||||
|
client1.sleep(2)
|
||||||
|
|
||||||
|
client1.succeed("seaf-cli status |grep synchronized >&2")
|
||||||
|
|
||||||
|
with subtest("client2 sync"):
|
||||||
|
client2.wait_for_unit("default.target")
|
||||||
|
|
||||||
|
client2.succeed("seaf-cli init -d . >&2")
|
||||||
|
client2.succeed("seaf-cli start >&2")
|
||||||
|
|
||||||
|
client2.succeed(
|
||||||
|
"seaf-cli list-remote -s http://server -u admin\@example.com -p seafile_password >&2"
|
||||||
|
)
|
||||||
|
|
||||||
|
libid = client2.succeed(
|
||||||
|
"seaf-cli list-remote -s http://server -u admin\@example.com -p seafile_password |grep test01 |cut -d' ' -f 2"
|
||||||
|
).strip()
|
||||||
|
|
||||||
|
client2.succeed(
|
||||||
|
f"seaf-cli download -l {libid} -s http://server -u admin\@example.com -p seafile_password -d . >&2"
|
||||||
|
)
|
||||||
|
|
||||||
|
client2.sleep(3)
|
||||||
|
|
||||||
|
client2.succeed("seaf-cli status |grep synchronized >&2")
|
||||||
|
|
||||||
|
client2.succeed("ls -la test01 >&2")
|
||||||
|
|
||||||
|
client2.succeed('[ `cat test01/first_file` = "bla" ]')
|
||||||
|
'';
|
||||||
|
})
|
||||||
@@ -12,6 +12,7 @@ stdenv.mkDerivation rec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [ autoreconfHook ];
|
nativeBuildInputs = [ autoreconfHook ];
|
||||||
|
configureFlags = [ "--enable-posix-api=yes" ];
|
||||||
|
|
||||||
meta = with lib; {
|
meta = with lib; {
|
||||||
homepage = "https://github.com/kkos/oniguruma";
|
homepage = "https://github.com/kkos/oniguruma";
|
||||||
|
|||||||
23
pkgs/development/python-modules/django-formtools/default.nix
Normal file
23
pkgs/development/python-modules/django-formtools/default.nix
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{ stdenv, lib, buildPythonPackage, fetchPypi, django, python }:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "django-formtools";
|
||||||
|
version = "2.2";
|
||||||
|
|
||||||
|
src = fetchPypi {
|
||||||
|
inherit pname version;
|
||||||
|
sha256 = "1chkbl188yj6hvhh1wgjpfgql553k6hrfwxzb8vv4lfdq41jq9y5";
|
||||||
|
};
|
||||||
|
|
||||||
|
propagatedBuildInputs = [ django ];
|
||||||
|
checkPhase = ''
|
||||||
|
${python.interpreter} -m django test --settings=tests.settings
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "A set of high-level abstractions for Django forms";
|
||||||
|
homepage = "https://github.com/jazzband/django-formtools";
|
||||||
|
license = licenses.bsd3;
|
||||||
|
maintainers = with maintainers; [ greizgh schmittlauch ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{ stdenv, lib, buildPythonPackage, fetchPypi, django, django_appconf }:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "django-statici18n";
|
||||||
|
version = "2.0.1";
|
||||||
|
|
||||||
|
src = fetchPypi {
|
||||||
|
inherit pname version;
|
||||||
|
sha256 = "0cqwfirzjbanibq3mfz9lcwqnc8655zpysf9hk9g3lbwj2m478sp";
|
||||||
|
};
|
||||||
|
|
||||||
|
propagatedBuildInputs = [ django django_appconf ];
|
||||||
|
|
||||||
|
# pypi package does not contains test harness
|
||||||
|
# source tarball requires setting up a config
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Helper for generating Javascript catalog to static files";
|
||||||
|
homepage = "https://github.com/zyegfryed/django-statici18n";
|
||||||
|
license = licenses.bsd3;
|
||||||
|
maintainers = with maintainers; [ greizgh schmittlauch ];
|
||||||
|
};
|
||||||
|
}
|
||||||
56
pkgs/development/python-modules/seahub/default.nix
Normal file
56
pkgs/development/python-modules/seahub/default.nix
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
{ stdenv, lib, fetchFromGitHub, python3Packages, makeWrapper }:
|
||||||
|
|
||||||
|
python3Packages.buildPythonPackage rec {
|
||||||
|
pname = "seahub";
|
||||||
|
version = "8.0.7";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "haiwen";
|
||||||
|
repo = "seahub";
|
||||||
|
rev = "4f7bb3f617dd847cf0a6b33c0bfb567b44c06059"; # using a fixed revision because upstream may re-tag releases :/
|
||||||
|
sha256 = "09d05sxly1bljxxzm77limhwsbg8c4b54fzv3kmaih59pjnjyr03";
|
||||||
|
};
|
||||||
|
|
||||||
|
dontBuild = true;
|
||||||
|
doCheck = false; # disabled because it requires a ccnet environment
|
||||||
|
|
||||||
|
nativeBuildInputs = [ makeWrapper ];
|
||||||
|
|
||||||
|
propagatedBuildInputs = with python3Packages; [
|
||||||
|
django
|
||||||
|
future
|
||||||
|
django-statici18n
|
||||||
|
django-webpack-loader
|
||||||
|
django-simple-captcha
|
||||||
|
django-picklefield
|
||||||
|
django-formtools
|
||||||
|
mysqlclient
|
||||||
|
pillow
|
||||||
|
python-dateutil
|
||||||
|
django_compressor
|
||||||
|
djangorestframework
|
||||||
|
openpyxl
|
||||||
|
requests
|
||||||
|
requests_oauthlib
|
||||||
|
pyjwt
|
||||||
|
pycryptodome
|
||||||
|
qrcode
|
||||||
|
pysearpc
|
||||||
|
seaserv
|
||||||
|
];
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
cp -dr --no-preserve='ownership' . $out/
|
||||||
|
wrapProgram $out/manage.py \
|
||||||
|
--prefix PYTHONPATH : "$PYTHONPATH:$out/thirdpart:" \
|
||||||
|
--prefix PATH : "${python3Packages.python}/bin"
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
homepage = "https://github.com/haiwen/seahub";
|
||||||
|
description = "The web end of seafile server";
|
||||||
|
license = licenses.asl20;
|
||||||
|
platforms = platforms.linux;
|
||||||
|
maintainers = with maintainers; [ greizgh schmittlauch ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -18,8 +18,8 @@ stdenv.mkDerivation rec {
|
|||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "haiwen";
|
owner = "haiwen";
|
||||||
repo = "seafile";
|
repo = "seafile";
|
||||||
rev = "v${version}";
|
rev = "0fdc14d5175979919b7c741f6bb97bfaaacbbfbe";
|
||||||
sha256 = "QflLh3fj+jOq/8etr9aG8LGrvtIlB/htVkWbdO+GIbM=";
|
sha256 = "1cr1hvpp96s5arnzh1r5sazapcghhvbazbf7zym37yp3fy3lpya1";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
@@ -40,12 +40,12 @@ stdenv.mkDerivation rec {
|
|||||||
|
|
||||||
configureFlags = [
|
configureFlags = [
|
||||||
"--disable-server"
|
"--disable-server"
|
||||||
"--disable-console"
|
|
||||||
"--with-python3"
|
"--with-python3"
|
||||||
];
|
];
|
||||||
|
|
||||||
pythonPath = with python3.pkgs; [
|
pythonPath = with python3.pkgs; [
|
||||||
libsearpc
|
future
|
||||||
|
pysearpc
|
||||||
];
|
];
|
||||||
|
|
||||||
postFixup = ''
|
postFixup = ''
|
||||||
@@ -55,8 +55,8 @@ stdenv.mkDerivation rec {
|
|||||||
meta = with lib; {
|
meta = with lib; {
|
||||||
homepage = "https://github.com/haiwen/seafile";
|
homepage = "https://github.com/haiwen/seafile";
|
||||||
description = "Shared components of Seafile: seafile-daemon, libseafile, libseafile python bindings, manuals, and icons";
|
description = "Shared components of Seafile: seafile-daemon, libseafile, libseafile python bindings, manuals, and icons";
|
||||||
license = licenses.gpl3;
|
license = licenses.gpl2Plus;
|
||||||
platforms = platforms.linux;
|
platforms = platforms.linux;
|
||||||
maintainers = [ ];
|
maintainers = with maintainers; [ greizgh schmittlauch ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
52
pkgs/servers/seafile-server/default.nix
Normal file
52
pkgs/servers/seafile-server/default.nix
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
{ stdenv, lib, fetchFromGitHub, pkg-config, python3Packages, autoreconfHook
|
||||||
|
, libuuid, sqlite, glib, libevent, libsearpc, openssl, fuse, libarchive, which
|
||||||
|
, vala, cmake, oniguruma }:
|
||||||
|
|
||||||
|
let
|
||||||
|
# seafile-server relies on a specific version of libevhtp.
|
||||||
|
# It contains non upstreamed patches and is forked off an outdated version.
|
||||||
|
libevhtp = import ./libevhtp.nix {
|
||||||
|
inherit stdenv lib fetchFromGitHub cmake libevent;
|
||||||
|
};
|
||||||
|
in stdenv.mkDerivation rec {
|
||||||
|
pname = "seafile-server";
|
||||||
|
version = "8.0.7";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "haiwen";
|
||||||
|
repo = "seafile-server";
|
||||||
|
rev = "27dac89bb3a81c5acc3f764ce92134eb357ea64b";
|
||||||
|
sha256 = "1h2hxvv0l5m9nbkdyjpznb7ddk8hb8hhwj8b2lx6aqbvp8gll9q7";
|
||||||
|
};
|
||||||
|
|
||||||
|
nativeBuildInputs = [ autoreconfHook pkg-config ];
|
||||||
|
|
||||||
|
buildInputs = [
|
||||||
|
libuuid
|
||||||
|
sqlite
|
||||||
|
openssl
|
||||||
|
glib
|
||||||
|
libsearpc
|
||||||
|
libevent
|
||||||
|
python3Packages.python
|
||||||
|
fuse
|
||||||
|
libarchive
|
||||||
|
which
|
||||||
|
vala
|
||||||
|
libevhtp
|
||||||
|
oniguruma
|
||||||
|
];
|
||||||
|
|
||||||
|
postInstall = ''
|
||||||
|
mkdir -p $out/share/seafile/sql
|
||||||
|
cp -r scripts/sql $out/share/seafile
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "File syncing and sharing software with file encryption and group sharing, emphasis on reliability and high performance";
|
||||||
|
homepage = "https://github.com/haiwen/seafile-server";
|
||||||
|
license = licenses.agpl3Plus;
|
||||||
|
platforms = platforms.linux;
|
||||||
|
maintainers = with maintainers; [ greizgh schmittlauch ];
|
||||||
|
};
|
||||||
|
}
|
||||||
29
pkgs/servers/seafile-server/libevhtp.nix
Normal file
29
pkgs/servers/seafile-server/libevhtp.nix
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{ stdenv, lib, fetchFromGitHub, cmake, libevent }:
|
||||||
|
|
||||||
|
stdenv.mkDerivation rec {
|
||||||
|
pname = "libevhtp";
|
||||||
|
version = "unstable-2021-04-28";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "haiwen";
|
||||||
|
repo = "libevhtp";
|
||||||
|
rev = "18c649203f009ef1d77d6f8301eba09af3777adf";
|
||||||
|
sha256 = "1rf0jcy2lf8jbzpkhfgv289hc8zdy5zs6sn36k4vlqvilginxiid";
|
||||||
|
};
|
||||||
|
|
||||||
|
nativeBuildInputs = [ cmake ];
|
||||||
|
|
||||||
|
buildInputs = [ libevent ];
|
||||||
|
|
||||||
|
cmakeFlags = [
|
||||||
|
"-DEVHTP_DISABLE_SSL=ON"
|
||||||
|
"-DEVHTP_BUILD_SHARED=ON"
|
||||||
|
];
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Create extremely-fast and secure embedded HTTP servers with ease";
|
||||||
|
homepage = "https://github.com/criticalstack/libevhtp";
|
||||||
|
license = licenses.bsd3;
|
||||||
|
maintainers = with maintainers; [ greizgh schmittlauch ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -32676,6 +32676,8 @@ with pkgs;
|
|||||||
thrift = thrift-0_10;
|
thrift = thrift-0_10;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
seafile-server = callPackage ../servers/seafile-server { };
|
||||||
|
|
||||||
seafile-shared = callPackage ../misc/seafile-shared { };
|
seafile-shared = callPackage ../misc/seafile-shared { };
|
||||||
|
|
||||||
ser2net = callPackage ../servers/ser2net {};
|
ser2net = callPackage ../servers/ser2net {};
|
||||||
|
|||||||
@@ -2110,6 +2110,8 @@ in {
|
|||||||
|
|
||||||
django-filter = callPackage ../development/python-modules/django-filter { };
|
django-filter = callPackage ../development/python-modules/django-filter { };
|
||||||
|
|
||||||
|
django-formtools = callPackage ../development/python-modules/django-formtools { };
|
||||||
|
|
||||||
django-gravatar2 = callPackage ../development/python-modules/django-gravatar2 { };
|
django-gravatar2 = callPackage ../development/python-modules/django-gravatar2 { };
|
||||||
|
|
||||||
django_guardian = callPackage ../development/python-modules/django_guardian { };
|
django_guardian = callPackage ../development/python-modules/django_guardian { };
|
||||||
@@ -2179,6 +2181,8 @@ in {
|
|||||||
|
|
||||||
django-sr = callPackage ../development/python-modules/django-sr { };
|
django-sr = callPackage ../development/python-modules/django-sr { };
|
||||||
|
|
||||||
|
django-statici18n = callPackage ../development/python-modules/django-statici18n { };
|
||||||
|
|
||||||
django-storages = callPackage ../development/python-modules/django-storages { };
|
django-storages = callPackage ../development/python-modules/django-storages { };
|
||||||
|
|
||||||
django_tagging = callPackage ../development/python-modules/django_tagging { };
|
django_tagging = callPackage ../development/python-modules/django_tagging { };
|
||||||
@@ -6956,6 +6960,8 @@ in {
|
|||||||
|
|
||||||
pysdl2 = callPackage ../development/python-modules/pysdl2 { };
|
pysdl2 = callPackage ../development/python-modules/pysdl2 { };
|
||||||
|
|
||||||
|
pysearpc = toPythonModule pkgs.libsearpc;
|
||||||
|
|
||||||
pysendfile = callPackage ../development/python-modules/pysendfile { };
|
pysendfile = callPackage ../development/python-modules/pysendfile { };
|
||||||
|
|
||||||
pysensors = callPackage ../development/python-modules/pysensors { };
|
pysensors = callPackage ../development/python-modules/pysensors { };
|
||||||
@@ -8319,6 +8325,10 @@ in {
|
|||||||
|
|
||||||
seabreeze = callPackage ../development/python-modules/seabreeze { };
|
seabreeze = callPackage ../development/python-modules/seabreeze { };
|
||||||
|
|
||||||
|
seahub = callPackage ../development/python-modules/seahub { };
|
||||||
|
|
||||||
|
seaserv = toPythonModule pkgs.seafile-server;
|
||||||
|
|
||||||
seccomp = callPackage ../development/python-modules/seccomp { };
|
seccomp = callPackage ../development/python-modules/seccomp { };
|
||||||
|
|
||||||
secp256k1 = callPackage ../development/python-modules/secp256k1 {
|
secp256k1 = callPackage ../development/python-modules/secp256k1 {
|
||||||
|
|||||||
Reference in New Issue
Block a user