diff --git a/nixos/doc/manual/release-notes/rl-2511.section.md b/nixos/doc/manual/release-notes/rl-2511.section.md
index a155ca4340e4..27af8355cfb2 100644
--- a/nixos/doc/manual/release-notes/rl-2511.section.md
+++ b/nixos/doc/manual/release-notes/rl-2511.section.md
@@ -126,6 +126,10 @@
- The Pocket ID module ([`services.pocket-id`][#opt-services.pocket-id.enable]) and package (`pocket-id`) has been updated to 1.0.0. Some environment variables have been changed or removed, see the [migration guide](https://pocket-id.org/docs/setup/migrate-to-v1/).
+- `services.seafile` has been removed, as it is unmaintained and outdated.
+ See [the manual](https://manual.seafile.com/13.0/upgrade/upgrade_notes_for_13.0.x/#important-release-changes)
+ for details and next steps.
+
- The `zigbee2mqtt` package was updated to version 2.x, which contains breaking changes. See the [discussion](https://github.com/Koenkk/zigbee2mqtt/discussions/24198) for further information.
- []{#sec-release-25.11-incompatibilities-sourcehut-removed} The `services.sourcehut` module and corresponding `sourcehut` packages were removed due to being broken and unmaintained.
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 3931662eaff8..d65241265b31 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -1325,7 +1325,6 @@
./services/networking/scion/scion-ip-gateway.nix
./services/networking/scion/scion-router.nix
./services/networking/scion/scion.nix
- ./services/networking/seafile.nix
./services/networking/searx.nix
./services/networking/shadowsocks.nix
./services/networking/shairport-sync.nix
diff --git a/nixos/modules/services/networking/seafile.nix b/nixos/modules/services/networking/seafile.nix
deleted file mode 100644
index 2129af18ed76..000000000000
--- a/nixos/modules/services/networking/seafile.nix
+++ /dev/null
@@ -1,547 +0,0 @@
-{
- config,
- lib,
- pkgs,
- ...
-}:
-let
- cfg = config.services.seafile;
- settingsFormat = pkgs.formats.ini { };
-
- 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" (
- 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.mysql',
- 'NAME' : 'seahub_db',
- 'HOST' : '/var/run/mysqld/mysqld.sock',
- }
- }
- MEDIA_ROOT = '${seahubDir}/media/'
- THUMBNAIL_ROOT = '${seahubDir}/thumbnail/'
-
- 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";
- ccnetDir = "${seafRoot}/ccnet";
- seahubDir = "${seafRoot}/seahub";
- defaultUser = "seafile";
-
-in
-{
-
- ###### Interface
-
- options.services.seafile = with lib; {
- enable = mkEnableOption "Seafile server";
-
- ccnetSettings = mkOption {
- type = types.submodule {
- freeformType = settingsFormat.type;
-
- options = {
- General = {
- SERVICE_URL = mkOption {
- type = types.singleLineStr;
- example = "https://www.example.com";
- description = ''
- Seahub public URL.
- '';
- };
- };
- };
- };
- default = { };
- description = ''
- Configuration for ccnet, see
-
- 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.singleLineStr;
- default = "ipv4:127.0.0.1";
- example = "unix:/run/seafile/server.sock";
- description = ''
- The bind address used by seafile fileserver.
-
- The addr can be defined as one of the following:
- - ipv6: for binding to an IPv6 address.
- - unix: for binding to a unix named socket
- - ipv4: for binding to an ipv4 address
- Otherwise the addr is assumed to be ipv4.
- '';
- };
- };
- };
- };
- default = { };
- description = ''
- Configuration for seafile-server, see
-
- for supported values.
- '';
- };
-
- 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;
- example = 10;
- description = ''
- The number of gunicorn worker processes for handling requests.
- '';
- };
-
- adminEmail = mkOption {
- example = "john@example.com";
- type = types.singleLineStr;
- description = ''
- Seafile Seahub Admin Account Email.
- '';
- };
-
- initialAdminPassword = mkOption {
- example = "someStrongPass";
- type = types.singleLineStr;
- description = ''
- Seafile Seahub Admin Account initial password.
- Should be changed via Seahub web front-end.
- '';
- };
-
- seahubPackage = mkPackageOption pkgs "seahub" { };
-
- user = mkOption {
- type = types.singleLineStr;
- default = defaultUser;
- description = "User account under which seafile runs.";
- };
-
- group = mkOption {
- type = types.singleLineStr;
- default = defaultUser;
- description = "Group under which seafile runs.";
- };
-
- dataDir = mkOption {
- type = types.path;
- default = "${seafRoot}/data";
- description = "Path in which to store user data";
- };
-
- 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.
- Refer to
- for all available options.
- '';
- };
- };
-
- ###### Implementation
-
- 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;
- environment.etc."seafile/seahub_settings.py".source = seahubSettings;
-
- users.users = lib.optionalAttrs (cfg.user == defaultUser) {
- "${defaultUser}" = {
- group = cfg.group;
- isSystemUser = true;
- };
- };
-
- users.groups = lib.optionalAttrs (cfg.group == defaultUser) { "${defaultUser}" = { }; };
-
- systemd.targets.seafile = {
- wantedBy = [ "multi-user.target" ];
- description = "Seafile components";
- };
-
- systemd.services =
- let
- serviceOptions = {
- ProtectHome = true;
- PrivateUsers = true;
- PrivateDevices = true;
- PrivateTmp = true;
- ProtectSystem = "strict";
- ProtectClock = true;
- ProtectHostname = true;
- ProtectProc = "invisible";
- ProtectKernelModules = true;
- ProtectKernelTunables = true;
- ProtectKernelLogs = true;
- ProtectControlGroups = true;
- RestrictNamespaces = true;
- RemoveIPC = true;
- LockPersonality = true;
- RestrictRealtime = true;
- RestrictSUIDSGID = true;
- NoNewPrivileges = true;
- MemoryDenyWriteExecute = true;
- SystemCallArchitectures = "native";
- 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;
- };
- in
- {
- seaf-server = {
- description = "Seafile server";
- partOf = [ "seafile.target" ];
- 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
- ];
- serviceConfig = serviceOptions // {
- ExecStart = ''
- ${lib.getExe cfg.seahubPackage.seafile-server} \
- --foreground \
- -F /etc/seafile \
- -c ${ccnetDir} \
- -d ${cfg.dataDir} \
- -l /var/log/seafile/server.log \
- -P /run/seafile/server.pid \
- -p /run/seafile
- '';
- };
- preStart = ''
- if [ ! -f "${seafRoot}/server-setup" ]; then
- 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.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 == 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: $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" ];
- 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 = "${cfg.seahubPackage.pythonPath}:${cfg.seahubPackage}/thirdpart:${cfg.seahubPackage}";
- DJANGO_SETTINGS_MODULE = "seahub.settings";
- CCNET_CONF_DIR = ccnetDir;
- SEAFILE_CONF_DIR = cfg.dataDir;
- SEAFILE_CENTRAL_CONF_DIR = "/etc/seafile";
- SEAFILE_RPC_PIPE_PATH = "/run/seafile";
- SEAHUB_LOG_DIR = "/var/log/seafile";
- };
- serviceConfig = serviceOptions // {
- RuntimeDirectory = "seahub";
- ExecStart = ''
- ${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 ${cfg.seahubAddress}
- '';
- };
- preStart = ''
- mkdir -p ${seahubDir}/media
- # Link all media except avatars
- for m in `find ${cfg.seahubPackage}/media/ -maxdepth 1 -not -name "avatars"`; do
- ln -sf $m ${seahubDir}/media/
- done
- if [ ! -e "${seafRoot}/.seahubSecret" ]; then
- (
- 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/ ${cfg.seahubPackage}/media/avatars/default.png
- install -D -t ${seahubDir}/media/avatars/groups ${cfg.seahubPackage}/media/avatars/groups/default.png
- # init database
- ${cfg.seahubPackage}/manage.py migrate
- # create admin account
- ${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
- # 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 = 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 = ''
- if [ ! -f "${seafRoot}/server-setup" ]; then
- echo "Server not setup yet, GC not needed" >&2
- exit
- fi
-
- # 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.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
- exit
- fi
-
- # Clean up user-deleted blocks and libraries
- ${cfg.seahubPackage.seafile-server}/bin/seafserv-gc \
- -F /etc/seafile \
- -c ${ccnetDir} \
- -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 lib.maintainers; [
- schmittlauch
- ];
-}
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 526f5a7edce8..e4f1fb1614f9 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -1330,7 +1330,6 @@ in
scx = runTest ./scx/default.nix;
sddm = import ./sddm.nix { inherit runTest; };
sdl3 = runTest ./sdl3.nix;
- seafile = runTest ./seafile.nix;
searx = runTest ./searx.nix;
seatd = runTest ./seatd.nix;
send = runTest ./send.nix;
diff --git a/nixos/tests/seafile.nix b/nixos/tests/seafile.nix
deleted file mode 100644
index c82c5cac3de8..000000000000
--- a/nixos/tests/seafile.nix
+++ /dev/null
@@ -1,128 +0,0 @@
-{ pkgs, ... }:
-let
- client =
- { config, pkgs, ... }:
- {
- environment.systemPackages = [
- pkgs.seafile-shared
- pkgs.curl
- ];
- };
-in
-{
- name = "seafile";
- meta = with pkgs.lib.maintainers; {
- maintainers = [
- kampfschlaefer
- ];
- };
-
- nodes = {
- server =
- { config, 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";
- };
- services.nginx = {
- enable = true;
- virtualHosts."server" = {
- locations."/".proxyPass = "http://unix:/run/seahub/gunicorn.sock";
- locations."/seafhttp" = {
- proxyPass = "http://unix:/run/seafile/server.sock";
- 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.wait_until_succeeds("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.wait_until_succeeds("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.wait_until_succeeds("seaf-cli status |grep synchronized >&2")
-
- client2.succeed("ls -la test01 >&2")
-
- client2.succeed('[ `cat test01/first_file` = "bla" ]')
- '';
-}
diff --git a/pkgs/by-name/se/seafile-server/libevhtp.nix b/pkgs/by-name/se/seafile-server/libevhtp.nix
deleted file mode 100644
index 07f0df1cd8f6..000000000000
--- a/pkgs/by-name/se/seafile-server/libevhtp.nix
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- stdenv,
- lib,
- fetchFromGitHub,
- cmake,
- libevent,
-}:
-
-stdenv.mkDerivation {
- 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; [
- schmittlauch
- melvyn2
- ];
- };
-}
diff --git a/pkgs/by-name/se/seafile-server/package.nix b/pkgs/by-name/se/seafile-server/package.nix
deleted file mode 100644
index f6a0b61af28b..000000000000
--- a/pkgs/by-name/se/seafile-server/package.nix
+++ /dev/null
@@ -1,101 +0,0 @@
-{
- stdenv,
- lib,
- fetchFromGitHub,
- fetchpatch,
- pkg-config,
- python3,
- autoreconfHook,
- libuuid,
- libmysqlclient,
- sqlite,
- glib,
- libevent,
- libsearpc,
- openssl,
- fuse,
- libarchive,
- libjwt,
- curl,
- which,
- vala,
- cmake,
- oniguruma,
- nixosTests,
-}:
-
-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 {
- pname = "seafile-server";
- version = "11.0.12"; # Doc links match Seafile 11.0 in seafile.nix – update if version changes.
- src = fetchFromGitHub {
- owner = "haiwen";
- repo = "seafile-server";
- rev = "5e6c0974e6abe5d92b8ba1db41c6ddbc1029f2d5"; # using a fixed revision because upstream may re-tag releases :/
- hash = "sha256-BVa4QZiHPkqRB5FvDlCSbEVxdnyxVy2KuCDb2orRMuI=";
- };
-
- nativeBuildInputs = [
- autoreconfHook
- pkg-config
- python3
- libsearpc # searpc-codegen.py
- vala # valac
- which
- ];
-
- buildInputs = [
- libuuid
- libmysqlclient
- sqlite
- glib
- libsearpc
- libevent
- python3
- fuse
- libarchive
- libjwt
- libevhtp
- oniguruma
- ];
-
- patches = [
- # https://github.com/haiwen/seafile-server/pull/658
- (fetchpatch {
- url = "https://github.com/haiwen/seafile-server/commit/8029a11a731bfe142af43f230f47b93811ebaaaa.patch";
- hash = "sha256-AWNDXIyrKXgqgq3p0m8+s3YH8dKxWnf7uEMYzSsjmX4=";
- })
- ];
-
- postInstall = ''
- mkdir -p $out/share/seafile/sql
- cp -r scripts/sql $out/share/seafile
- '';
-
- passthru.tests = {
- inherit (nixosTests) 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; [
- melvyn2
- ];
- mainProgram = "seaf-server";
- };
-}
diff --git a/pkgs/by-name/se/seahub/package.nix b/pkgs/by-name/se/seahub/package.nix
deleted file mode 100644
index b3c8baf90114..000000000000
--- a/pkgs/by-name/se/seahub/package.nix
+++ /dev/null
@@ -1,87 +0,0 @@
-{
- lib,
- fetchFromGitHub,
- python3,
- makeWrapper,
- nixosTests,
- seafile-server,
-}:
-python3.pkgs.buildPythonApplication rec {
- pname = "seahub";
- version = "11.0.12";
- pyproject = false;
-
- src = fetchFromGitHub {
- owner = "haiwen";
- repo = "seahub";
- rev = "d998361dd890cac3f6d6ebec3af47a589e0332bc"; # using a fixed revision because upstream may re-tag releases :/
- hash = "sha256-n56sRZ9TVb37JA0+12ZoF2Mt7dADjaYk7V0PmdBY0EU=";
- };
-
- dontBuild = true;
-
- doCheck = false; # disabled because it requires a ccnet environment
-
- nativeBuildInputs = [ makeWrapper ];
-
- propagatedBuildInputs = with python3.pkgs; [
- django
- django-compressor
- django-statici18n
- django-webpack-loader
- django-simple-captcha
- django-picklefield
- django-formtools
- djangosaml2
- mysqlclient
- pillow
- python-dateutil
- djangorestframework
- openpyxl
- requests
- requests-oauthlib
- chardet
- pyjwt
- pycryptodome
- pyopenssl
- python-ldap
- qrcode
- pysearpc
- gunicorn
- markdown
- bleach
-
- (python3.pkgs.toPythonModule (seafile-server.override { inherit python3; }))
- ];
-
- postPatch = ''
- substituteInPlace seahub/settings.py --replace-fail "SEAFILE_VERSION = '6.3.3'" "SEAFILE_VERSION = '${version}'"
- substituteInPlace thirdpart/constance/management/commands/constance.py --replace-fail \
- "from __future__ import unicode_literals" ""
- '';
-
- installPhase = ''
- cp -dr --no-preserve='ownership' . $out/
- wrapProgram $out/manage.py \
- --prefix PYTHONPATH : "$PYTHONPATH:$out/thirdpart:"
- '';
-
- passthru = {
- inherit python3;
- pythonPath = python3.pkgs.makePythonPath propagatedBuildInputs;
- tests = {
- inherit (nixosTests) seafile;
- };
- inherit seafile-server;
- };
-
- meta = {
- description = "Web end of seafile server";
- homepage = "https://github.com/haiwen/seahub";
- license = lib.licenses.asl20;
- maintainers = with lib.maintainers; [
- melvyn2
- ];
- platforms = lib.platforms.linux;
- };
-}
diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix
index c47470549d1e..9db4c9956d5b 100644
--- a/pkgs/top-level/aliases.nix
+++ b/pkgs/top-level/aliases.nix
@@ -2105,6 +2105,8 @@ mapAliases {
scitoken-cpp = scitokens-cpp; # Added 2024-02-12
scry = throw "'scry' has been removed as it was archived upstream. Use 'crystalline' instead"; # Added 2025-02-12
scudcloud = throw "'scudcloud' has been removed as it was archived by upstream"; # Added 2025-07-24
+ seafile-server = throw "'seafile-server' has been removed as it is unmaintained"; # Added 2025-08-21
+ seahub = throw "'seahub' has been removed as it is unmaintained"; # Added 2025-08-21
semeru-bin-16 = throw "Semeru 16 has been removed as it has reached its end of life"; # Added 2024-08-01
semeru-jre-bin-16 = throw "Semeru 16 has been removed as it has reached its end of life"; # Added 2024-08-01
sensu = throw "sensu has been removed as the upstream project is deprecated. Consider using `sensu-go`"; # Added 2024-10-28
diff --git a/pkgs/top-level/python-aliases.nix b/pkgs/top-level/python-aliases.nix
index 074304ed4eaf..869086c0154a 100644
--- a/pkgs/top-level/python-aliases.nix
+++ b/pkgs/top-level/python-aliases.nix
@@ -743,6 +743,7 @@ mapAliases ({
scikitlearn = scikit-learn; # added 2021-07-21
scikit-optimize = throw "scikit-optimize has been removed because it is abandoned"; # added 2024-09-30
scikits-samplerate = throw "scikits-samplerate has been removed, it was unsed and unmaintained since 2015"; # added 2024-05-23
+ seaserv = throw "seaserv has been removed as it is unmaintained"; # Added 2025-08-21
selectors2 = throw "selectors2 has been removed: archived by upstream."; # added 2024-07-27
selectors34 = throw "selectors34 has been removed: functionality provided by Python itself; archived by upstream."; # added 2021-06-10
sentry-sdk_2 = sentry-sdk; # added 2025-04-20
diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix
index 9f6c63cfba6f..40c1e29a051a 100644
--- a/pkgs/top-level/python-packages.nix
+++ b/pkgs/top-level/python-packages.nix
@@ -16401,8 +16401,6 @@ self: super: with self; {
seabreeze = callPackage ../development/python-modules/seabreeze { };
- seaserv = toPythonModule (pkgs.seafile-server.override { python3 = self.python; });
-
seasonal = callPackage ../development/python-modules/seasonal { };
seatconnect = callPackage ../development/python-modules/seatconnect { };