pyload-ng: drop (#502033)
This commit is contained in:
@@ -164,7 +164,7 @@ The pre-existing `services.ankisyncd` has been marked deprecated and will be dro
|
||||
|
||||
- [prometheus-nats-exporter](https://github.com/nats-io/prometheus-nats-exporter), a Prometheus exporter for NATS. Available as [services.prometheus.exporters.nats](#opt-services.prometheus.exporters.nats.enable).
|
||||
|
||||
- [pyLoad](https://pyload.net/), a FOSS download manager written in Python. Available as [services.pyload](#opt-services.pyload.enable).
|
||||
- [pyLoad](https://pyload.net/), a FOSS download manager written in Python. Available as `services.pyload`.
|
||||
|
||||
- [Python Matter Server](https://github.com/home-assistant-libs/python-matter-server), a
|
||||
Matter Controller Server exposing websocket connections for use with other services, notably Home Assistant.
|
||||
|
||||
@@ -129,6 +129,8 @@
|
||||
|
||||
- `services.statsd` has been removed because the packages it relies on do not exist anymore in nixpkgs.
|
||||
|
||||
- `services.pyload` has been removed because the package it relies on does not exist anymore in nixpkgs due to vulnerabilities and being unmaintained.
|
||||
|
||||
- `services.tandoor-recipes` now uses a sub-directory for media files by default starting with `26.05`. Existing setups should move media files out of the data directory and adjust `services.tandoor-recipes.extraConfig.MEDIA_ROOT` accordingly. See [Migrating media files for pre 26.05 installations](#module-services-tandoor-recipes-migrating-media).
|
||||
|
||||
- `rustic` was upgraded to `0.11.x`, which contains breaking [changes to command-line parameters and configuration file](https://rustic.cli.rs/docs/breaking_changes.html#0110).
|
||||
|
||||
@@ -1347,7 +1347,6 @@
|
||||
./services/networking/pptpd.nix
|
||||
./services/networking/privoxy.nix
|
||||
./services/networking/prosody.nix
|
||||
./services/networking/pyload.nix
|
||||
./services/networking/quassel.nix
|
||||
./services/networking/quicktun.nix
|
||||
./services/networking/r53-ddns.nix
|
||||
|
||||
@@ -486,6 +486,9 @@ in
|
||||
(mkRemovedOptionModule [ "programs" "spacefm" ] ''
|
||||
spacefm has been removed since it was unmaintained upstream.
|
||||
'')
|
||||
(mkRemovedOptionModule [ "services" "pyload" ] ''
|
||||
services.pyload has been removed since the pyload-ng package had vulnerabilities and was unmaintained in nixpkgs.
|
||||
'')
|
||||
# Do NOT add any option renames here, see top of the file
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
utils,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.services.pyload;
|
||||
|
||||
stateDir = "/var/lib/pyload";
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ ambroisie ];
|
||||
|
||||
options = with lib; {
|
||||
services.pyload = {
|
||||
enable = mkEnableOption "pyLoad download manager";
|
||||
|
||||
package = mkPackageOption pkgs "pyLoad" { default = [ "pyload-ng" ]; };
|
||||
|
||||
listenAddress = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
example = "0.0.0.0";
|
||||
description = "Address to listen on for the web UI.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 8000;
|
||||
example = 9876;
|
||||
description = "Port to listen on for the web UI.";
|
||||
};
|
||||
|
||||
downloadDirectory = mkOption {
|
||||
type = types.path;
|
||||
default = "${stateDir}/downloads";
|
||||
example = "/mnt/downloads";
|
||||
description = "Directory to store downloads.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "pyload";
|
||||
description = "User under which pyLoad runs, and which owns the download directory.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "pyload";
|
||||
description = "Group under which pyLoad runs, and which owns the download directory.";
|
||||
};
|
||||
|
||||
credentialsFile = mkOption {
|
||||
type = with types; nullOr path;
|
||||
default = null;
|
||||
example = "/run/secrets/pyload-credentials.env";
|
||||
description = ''
|
||||
File containing {env}`PYLOAD_DEFAULT_USERNAME` and
|
||||
{env}`PYLOAD_DEFAULT_PASSWORD` in the format of an `EnvironmentFile=`,
|
||||
as described by {manpage}`systemd.exec(5)`.
|
||||
|
||||
If not given, they default to the username/password combo of
|
||||
pyload/pyload.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.tmpfiles.settings.pyload = {
|
||||
${cfg.downloadDirectory}.d = { inherit (cfg) user group; };
|
||||
};
|
||||
|
||||
systemd.services.pyload = {
|
||||
description = "pyLoad download manager";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
# NOTE: unlike what the documentation says, it looks like `HOME` is not
|
||||
# defined with this service definition...
|
||||
# Since pyload tries to do the equivalent of `cd ~`, it needs to be able
|
||||
# to resolve $HOME, which fails when `RootDirectory` is set.
|
||||
# FIXME: check if `SetLoginEnvironment` fixes this issue in version 255
|
||||
environment = {
|
||||
HOME = stateDir;
|
||||
PYLOAD__WEBUI__HOST = cfg.listenAddress;
|
||||
PYLOAD__WEBUI__PORT = toString cfg.port;
|
||||
};
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = utils.escapeSystemdExecArgs [
|
||||
(lib.getExe cfg.package)
|
||||
"--userdir"
|
||||
"${stateDir}/config"
|
||||
"--storagedir"
|
||||
cfg.downloadDirectory
|
||||
];
|
||||
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
|
||||
EnvironmentFile = lib.optional (cfg.credentialsFile != null) cfg.credentialsFile;
|
||||
|
||||
StateDirectory = "pyload";
|
||||
WorkingDirectory = stateDir;
|
||||
RuntimeDirectory = "pyload";
|
||||
RuntimeDirectoryMode = "0700";
|
||||
RootDirectory = "/run/pyload";
|
||||
BindReadOnlyPaths = [
|
||||
builtins.storeDir # Needed to run the python interpreter
|
||||
];
|
||||
BindPaths = [
|
||||
cfg.downloadDirectory
|
||||
];
|
||||
|
||||
# Hardening options
|
||||
LockPersonality = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateMounts = true;
|
||||
PrivateTmp = true;
|
||||
PrivateUsers = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProtectSystem = "strict";
|
||||
RemoveIPC = true;
|
||||
RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX";
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
"~@resources"
|
||||
"~@privileged"
|
||||
];
|
||||
UMask = "0002";
|
||||
CapabilityBoundingSet = [
|
||||
"~CAP_BLOCK_SUSPEND"
|
||||
"~CAP_BPF"
|
||||
"~CAP_CHOWN"
|
||||
"~CAP_IPC_LOCK"
|
||||
"~CAP_KILL"
|
||||
"~CAP_LEASE"
|
||||
"~CAP_LINUX_IMMUTABLE"
|
||||
"~CAP_NET_ADMIN"
|
||||
"~CAP_SYS_ADMIN"
|
||||
"~CAP_SYS_BOOT"
|
||||
"~CAP_SYS_CHROOT"
|
||||
"~CAP_SYS_NICE"
|
||||
"~CAP_SYS_PACCT"
|
||||
"~CAP_SYS_PTRACE"
|
||||
"~CAP_SYS_RESOURCE"
|
||||
"~CAP_SYS_TTY_CONFIG"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
users.users.pyload = lib.mkIf (cfg.user == "pyload") {
|
||||
isSystemUser = true;
|
||||
group = cfg.group;
|
||||
home = stateDir;
|
||||
};
|
||||
|
||||
users.groups.pyload = lib.mkIf (cfg.group == "pyload") { };
|
||||
};
|
||||
}
|
||||
@@ -1348,7 +1348,6 @@ in
|
||||
pulseaudio = discoverTests (import ./pulseaudio.nix);
|
||||
pulseaudio-tcp = runTest ./pulseaudio-tcp.nix;
|
||||
pykms = runTest ./pykms.nix;
|
||||
pyload = runTest ./pyload.nix;
|
||||
qbittorrent = runTest ./qbittorrent.nix;
|
||||
qboot = handleTestOn [ "x86_64-linux" "i686-linux" ] ./qboot.nix { };
|
||||
qemu-vm-credentials-fwcfg = runTest {
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
name = "pyload";
|
||||
meta.maintainers = with lib.maintainers; [ ambroisie ];
|
||||
|
||||
nodes = {
|
||||
machine =
|
||||
{ ... }:
|
||||
{
|
||||
services.pyload = {
|
||||
enable = true;
|
||||
|
||||
listenAddress = "0.0.0.0";
|
||||
port = 9876;
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 9876 ];
|
||||
};
|
||||
|
||||
client = { };
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
|
||||
machine.wait_for_unit("pyload.service")
|
||||
|
||||
with subtest("Web interface accessible locally"):
|
||||
machine.wait_until_succeeds("curl -fs localhost:9876")
|
||||
|
||||
client.wait_for_unit("network.target")
|
||||
|
||||
with subtest("Web interface accessible from a different machine"):
|
||||
client.wait_until_succeeds("curl -fs machine:9876")
|
||||
'';
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
diff --git a/src/pyload/core/__init__.py b/src/pyload/core/__init__.py
|
||||
index 4324fc700..f7fcd66ec 100644
|
||||
--- a/src/pyload/core/__init__.py
|
||||
+++ b/src/pyload/core/__init__.py
|
||||
@@ -46,8 +46,8 @@ class Exit(Exception):
|
||||
# improve external scripts
|
||||
class Core:
|
||||
LOCALE_DOMAIN = APPID
|
||||
- DEFAULT_USERNAME = APPID
|
||||
- DEFAULT_PASSWORD = APPID
|
||||
+ DEFAULT_USERNAME = os.getenv("PYLOAD_DEFAULT_USERNAME", APPID)
|
||||
+ DEFAULT_PASSWORD = os.getenv("PYLOAD_DEFAULT_PASSWORD", APPID)
|
||||
DEFAULT_DATADIR = os.path.join(
|
||||
os.getenv("APPDATA") or USERHOMEDIR, "pyLoad" if os.name == "nt" else ".pyload"
|
||||
)
|
||||
@@ -1,18 +0,0 @@
|
||||
diff --git a/src/pyload/core/__init__.py b/src/pyload/core/__init__.py
|
||||
index 4324fc700..5d915a85e 100644
|
||||
--- a/src/pyload/core/__init__.py
|
||||
+++ b/src/pyload/core/__init__.py
|
||||
@@ -128,6 +128,13 @@ class Core:
|
||||
else:
|
||||
self._debug = max(0, int(debug))
|
||||
|
||||
+ # Allow setting any option declaratively, for the NixOS module
|
||||
+ for env, value in os.environ.items():
|
||||
+ if not env.startswith("PYLOAD__"):
|
||||
+ continue
|
||||
+ section, opt = env.removeprefix("PYLOAD__").lower().split("__")
|
||||
+ self.config.set(section, opt, value)
|
||||
+
|
||||
# If no argument set, read storage dir from config file,
|
||||
# otherwise save setting to config dir
|
||||
if storagedir is None:
|
||||
@@ -1,72 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
fetchPypi,
|
||||
nixosTests,
|
||||
python3,
|
||||
}:
|
||||
|
||||
python3.pkgs.buildPythonApplication (finalAttrs: {
|
||||
version = "0.5.0b3.dev88";
|
||||
pname = "pyload-ng";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchPypi {
|
||||
inherit (finalAttrs) version;
|
||||
# The uploaded tarball uses an underscore in recent releases
|
||||
pname = "pyload_ng";
|
||||
hash = "sha256-6YVYXiYxUkpQmDG/aGEgBlJy2oUGCNDkIsUt0TRcaro=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
# Makes it possible to change the default username/password in the module
|
||||
./declarative-default-user.patch
|
||||
# Makes it possible to change the configuration through environment variables
|
||||
# in the NixOS module (aimed mostly at listen address/port)
|
||||
./declarative-env-config.patch
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
# relax version bounds
|
||||
sed -i -E 's/([A-z0-9]*)~=[^;]*(.*)/\1\2/' setup.cfg
|
||||
'';
|
||||
|
||||
dependencies = with python3.pkgs; [
|
||||
bitmath
|
||||
certifi
|
||||
cheroot
|
||||
cryptography
|
||||
dukpy
|
||||
filetype
|
||||
flask
|
||||
flask-babel
|
||||
flask-caching
|
||||
flask-compress
|
||||
flask-session
|
||||
flask-themes2
|
||||
pycurl
|
||||
semver
|
||||
setuptools
|
||||
];
|
||||
|
||||
optional-dependencies = {
|
||||
plugins = with python3.pkgs; [
|
||||
beautifulsoup4 # for some plugins
|
||||
colorlog # colorful console logging
|
||||
pillow # for some CAPTCHA plugin
|
||||
send2trash # send some files to trash instead of deleting them
|
||||
slixmpp # XMPP plugin
|
||||
];
|
||||
};
|
||||
|
||||
passthru.tests = {
|
||||
inherit (nixosTests) pyload;
|
||||
};
|
||||
|
||||
meta = {
|
||||
description = "Free and open-source download manager with support for 1-click-hosting sites";
|
||||
homepage = "https://github.com/pyload/pyload";
|
||||
license = lib.licenses.agpl3Plus;
|
||||
maintainers = with lib.maintainers; [ ruby0b ];
|
||||
mainProgram = "pyload";
|
||||
};
|
||||
})
|
||||
@@ -1,64 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
buildPythonPackage,
|
||||
setuptools,
|
||||
mutf8,
|
||||
webassets,
|
||||
pytestCheckHook,
|
||||
mock,
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "dukpy";
|
||||
version = "0.5.1";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "amol-";
|
||||
repo = "dukpy";
|
||||
tag = version;
|
||||
hash = "sha256-ZoBkCpilqPwDy0njwXqUIVgKt16jDCdnbDk7EfxzWOM=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
substituteInPlace tests/test_webassets_filter.py \
|
||||
--replace-fail "class PyTestTemp" "class _Temp" \
|
||||
--replace-fail "PyTestTemp" "Temp"
|
||||
'';
|
||||
|
||||
build-system = [ setuptools ];
|
||||
|
||||
dependencies = [ mutf8 ];
|
||||
|
||||
optional-dependencies = {
|
||||
webassets = [ webassets ];
|
||||
};
|
||||
|
||||
nativeCheckInputs = [
|
||||
pytestCheckHook
|
||||
mock
|
||||
]
|
||||
++ optional-dependencies.webassets;
|
||||
|
||||
disabledTests = [ "test_installer" ];
|
||||
|
||||
preCheck = ''
|
||||
rm -r dukpy
|
||||
'';
|
||||
|
||||
pythonImportsCheck = [ "dukpy" ];
|
||||
|
||||
meta = {
|
||||
description = "Simple JavaScript interpreter for Python";
|
||||
homepage = "https://github.com/amol-/dukpy";
|
||||
changelog = "https://github.com/amol-/dukpy/releases/tag/${src.tag}";
|
||||
license = lib.licenses.mit;
|
||||
maintainers = with lib.maintainers; [ ruby0b ];
|
||||
mainProgram = "dukpy";
|
||||
# error: 'TARGET_OS_BRIDGE' is not defined, evaluates to 0 [-Werror,-Wundef-prefix=TARGET_OS_]
|
||||
# https://github.com/amol-/dukpy/issues/82
|
||||
broken = stdenv.cc.isClang;
|
||||
};
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
buildPythonPackage,
|
||||
fetchPypi,
|
||||
setuptools,
|
||||
flask,
|
||||
pytestCheckHook,
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "flask-themes2";
|
||||
version = "1.0.1";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchPypi {
|
||||
pname = "Flask-Themes2";
|
||||
inherit version;
|
||||
hash = "sha256-gsMgQQXjhDfQRhm7H0kBy8jKxd75WY+PhHR6Rk/PUPs=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ setuptools ];
|
||||
|
||||
propagatedBuildInputs = [ flask ];
|
||||
|
||||
nativeCheckInputs = [ pytestCheckHook ];
|
||||
|
||||
meta = {
|
||||
description = "Easily theme your Flask app";
|
||||
homepage = "https://github.com/sysr-q/flask-themes2";
|
||||
license = lib.licenses.mit;
|
||||
maintainers = with lib.maintainers; [ ruby0b ];
|
||||
};
|
||||
}
|
||||
@@ -1675,6 +1675,7 @@ mapAliases {
|
||||
purple-vk-plugin = throw "'purple-vk-plugin' has been removed as upstream repository was deleted and no active forks are found."; # Added 2025-09-17
|
||||
purple-xmpp-http-upload = throw "'purple-xmpp-http-upload' has been renamed to/replaced by 'pidginPackages.purple-xmpp-http-upload'"; # Converted to throw 2025-10-27
|
||||
pyCA = warnAlias "'pyCA' was renamed to 'pyca'" pyca; # Added 2026-02-12
|
||||
pyload-ng = throw "'pyload-ng' has been removed due to vulnerabilities and being unmaintained"; # Added 2026-03-21
|
||||
pyo3-pack = throw "'pyo3-pack' has been renamed to/replaced by 'maturin'"; # Converted to throw 2025-10-27
|
||||
pypolicyd-spf = throw "'pypolicyd-spf' has been renamed to/replaced by 'spf-engine'"; # Converted to throw 2025-10-27
|
||||
python3Full = throw "python3Full has been removed. Bluetooth support is now enabled by default. The tkinter package is available within the package set."; # Added 2025-08-30
|
||||
|
||||
@@ -181,6 +181,7 @@ mapAliases {
|
||||
docker_pycreds = throw "'docker_pycreds' has been renamed to/replaced by 'docker-pycreds'"; # Converted to throw 2025-10-29
|
||||
dogpile_cache = throw "'dogpile_cache' has been renamed to/replaced by 'dogpile-cache'"; # Converted to throw 2025-10-29
|
||||
duckduckgo-search = throw "duckduckgo-search was renamed to ddgs, use ddgs instead"; # added 2025-10-20
|
||||
dukpy = throw "'dukpy' was removed as the only consumer pyload-ng was removed"; # added 2026-03-21
|
||||
easyeda2ato = throw "easyeda2ato as been removed in favor of atopile-easyda2kicad"; # added 2025-06-08
|
||||
EasyProcess = throw "'EasyProcess' has been renamed to/replaced by 'easyprocess'"; # Converted to throw 2025-10-29
|
||||
editdistance-s = throw "editdistance-s has been removed since it was added solely for the identity package, which has moved on to ukkonen"; # added 2025-08-04
|
||||
@@ -204,6 +205,7 @@ mapAliases {
|
||||
filesplit = throw "filesplit has been removed, since it is unmaintained"; # added 2025-08-20
|
||||
flask-security-too = throw "'flask-security-too' has been renamed to/replaced by 'flask-security'"; # Converted to throw 2025-10-29
|
||||
flask-silk = throw "flask-silk was removed, as it is unmaintained since 2018."; # added 2025-05-25
|
||||
flask-themes2 = throw "'flask-themes2' was removed as the only consumer pyload-ng was removed"; # added 2026-03-21
|
||||
flask_assets = throw "'flask_assets' has been renamed to/replaced by 'flask-assets'"; # Converted to throw 2025-10-29
|
||||
flask_elastic = throw "'flask_elastic' has been renamed to/replaced by 'flask-elastic'"; # Converted to throw 2025-10-29
|
||||
flask_login = throw "'flask_login' has been renamed to/replaced by 'flask-login'"; # Converted to throw 2025-10-29
|
||||
|
||||
@@ -4763,8 +4763,6 @@ self: super: with self; {
|
||||
|
||||
dufte = callPackage ../development/python-modules/dufte { };
|
||||
|
||||
dukpy = callPackage ../development/python-modules/dukpy { };
|
||||
|
||||
dulwich = callPackage ../development/python-modules/dulwich { inherit (pkgs) gnupg; };
|
||||
|
||||
dunamai = callPackage ../development/python-modules/dunamai { };
|
||||
@@ -5727,8 +5725,6 @@ self: super: with self; {
|
||||
|
||||
flask-themer = callPackage ../development/python-modules/flask-themer { };
|
||||
|
||||
flask-themes2 = callPackage ../development/python-modules/flask-themes2 { };
|
||||
|
||||
flask-unsign = callPackage ../development/python-modules/flask-unsign { };
|
||||
|
||||
flask-versioned = callPackage ../development/python-modules/flask-versioned { };
|
||||
|
||||
Reference in New Issue
Block a user