nix: format all nix files with nixfmt

This commit is contained in:
Tom van Dijk 2025-07-28 12:42:47 +02:00
parent e278316615
commit 4895579c72
No known key found for this signature in database
GPG key ID: 7A984C8207ADBA51
3 changed files with 274 additions and 234 deletions

View file

@ -4,28 +4,31 @@
lib,
...
}:
with lib; let
mkKeyValue = key: value:
if value == true
then
with lib;
let
mkKeyValue =
key: value:
if value == true then
# sets with a true boolean value are coerced to just the key name
key
else if value == false
then
else if value == false then
# or omitted completely when false
""
else (generators.mkKeyValueDefault {inherit mkValueString;} ": " key value);
else
(generators.mkKeyValueDefault { inherit mkValueString; } ": " key value);
mkAttrsString = value: (generators.toKeyValue {inherit mkKeyValue;} value);
mkAttrsString = value: (generators.toKeyValue { inherit mkKeyValue; } value);
mkValueString = value:
if isList value
then (concatStringsSep ", " (map mkValueString value))
else if isAttrs value
then "\n" + (mkAttrsString value)
else (generators.mkValueStringDefault {} value);
mkValueString =
value:
if isList value then
(concatStringsSep ", " (map mkValueString value))
else if isAttrs value then
"\n" + (mkAttrsString value)
else
(generators.mkValueStringDefault { } value);
mkSectionName = value: "[" + (escape ["[" "]"] value) + "]";
mkSectionName = value: "[" + (escape [ "[" "]" ] value) + "]";
mkSection = name: attrs: ''
${mkSectionName name}
@ -57,7 +60,8 @@ with lib; let
externalCacheDir = "/var/cache/copyparty";
externalStateDir = "/var/lib/copyparty";
defaultShareDir = "${externalStateDir}/data";
in {
in
{
options.services.copyparty = {
enable = mkEnableOption "web-based file manager";
@ -128,7 +132,10 @@ in {
};
accounts = mkOption {
type = types.attrsOf (types.submodule ({...}: {
type = types.attrsOf (
types.submodule (
{ ... }:
{
options = {
passwordFile = mkOption {
type = types.str;
@ -139,11 +146,13 @@ in {
example = "/run/keys/copyparty/ed";
};
};
}));
}
)
);
description = ''
A set of copyparty accounts to create.
'';
default = {};
default = { };
example = literalExpression ''
{
ed.passwordFile = "/run/keys/copyparty/ed";
@ -152,7 +161,10 @@ in {
};
volumes = mkOption {
type = types.attrsOf (types.submodule ({...}: {
type = types.attrsOf (
types.submodule (
{ ... }:
{
options = {
path = mkOption {
type = types.path;
@ -211,15 +223,19 @@ in {
nohash = "\.iso$";
};
'';
default = {};
default = { };
};
};
}));
}
)
);
description = "A set of copyparty volumes to create";
default = {
"/" = {
path = defaultShareDir;
access = {r = "*";};
access = {
r = "*";
};
};
};
example = literalExpression ''
@ -238,27 +254,30 @@ in {
};
};
config = mkIf cfg.enable (let
config = mkIf cfg.enable (
let
command = "${getExe cfg.package} -c ${runtimeConfigPath}";
in {
in
{
systemd.services.copyparty = {
description = "http file sharing hub";
wantedBy = ["multi-user.target"];
wantedBy = [ "multi-user.target" ];
environment = {
PYTHONUNBUFFERED = "true";
XDG_CONFIG_HOME = externalStateDir;
};
preStart = let
replaceSecretCommand = name: attrs: "${getExe pkgs.replace-secret} '${
passwordPlaceholder name
}' '${attrs.passwordFile}' ${runtimeConfigPath}";
in ''
preStart =
let
replaceSecretCommand =
name: attrs:
"${getExe pkgs.replace-secret} '${passwordPlaceholder name}' '${attrs.passwordFile}' ${runtimeConfigPath}";
in
''
set -euo pipefail
install -m 600 ${configFile} ${runtimeConfigPath}
${concatStringsSep "\n"
(mapAttrsToList replaceSecretCommand cfg.accounts)}
${concatStringsSep "\n" (mapAttrsToList replaceSecretCommand cfg.accounts)}
'';
serviceConfig = {
@ -267,29 +286,23 @@ in {
# Hardening options
User = cfg.user;
Group = cfg.group;
RuntimeDirectory = ["copyparty"];
RuntimeDirectory = [ "copyparty" ];
RuntimeDirectoryMode = "0700";
StateDirectory = ["copyparty"];
StateDirectory = [ "copyparty" ];
StateDirectoryMode = "0700";
CacheDirectory = lib.mkIf (cfg.settings ? hist) ["copyparty"];
CacheDirectory = lib.mkIf (cfg.settings ? hist) [ "copyparty" ];
CacheDirectoryMode = lib.mkIf (cfg.settings ? hist) "0700";
WorkingDirectory = externalStateDir;
BindReadOnlyPaths =
[
BindReadOnlyPaths = [
"/nix/store"
"-/etc/resolv.conf"
"-/etc/nsswitch.conf"
"-/etc/hosts"
"-/etc/localtime"
]
++ (mapAttrsToList (k: v: "-${v.passwordFile}") cfg.accounts);
] ++ (mapAttrsToList (k: v: "-${v.passwordFile}") cfg.accounts);
BindPaths =
(
if cfg.settings ? hist
then [cfg.settings.hist]
else []
)
++ [externalStateDir]
(if cfg.settings ? hist then [ cfg.settings.hist ] else [ ])
++ [ externalStateDir ]
++ (mapAttrsToList (k: v: v.path) cfg.volumes);
# ProtectSystem = "strict";
# Note that unlike what 'ro' implies,
@ -332,11 +345,10 @@ in {
mode = ":755";
};
}
)
cfg.volumes
) cfg.volumes
);
users.groups.copyparty = lib.mkIf (cfg.user == "copyparty" && cfg.group == "copyparty") {};
users.groups.copyparty = lib.mkIf (cfg.user == "copyparty" && cfg.group == "copyparty") { };
users.users.copyparty = lib.mkIf (cfg.user == "copyparty" && cfg.group == "copyparty") {
description = "Service user for copyparty";
group = "copyparty";
@ -344,9 +356,7 @@ in {
isSystemUser = true;
};
environment.systemPackages = lib.mkIf cfg.mkHashWrapper [
(pkgs.writeShellScriptBin
"copyparty-hash"
''
(pkgs.writeShellScriptBin "copyparty-hash" ''
set -a # automatically export variables
# set same environment variables as the systemd service
${lib.pipe config.systemd.services.copyparty.environment [
@ -359,5 +369,6 @@ in {
exec ${command} --ah-cli
'')
];
});
}
);
}

View file

@ -1,49 +1,67 @@
{ lib, stdenv, makeWrapper, fetchurl, util-linux, python, jinja2, impacket, pyftpdlib, pyopenssl, argon2-cffi, pillow, pyvips, pyzmq, ffmpeg, mutagen,
{
lib,
stdenv,
makeWrapper,
fetchurl,
util-linux,
python,
jinja2,
impacket,
pyftpdlib,
pyopenssl,
argon2-cffi,
pillow,
pyvips,
pyzmq,
ffmpeg,
mutagen,
# use argon2id-hashed passwords in config files (sha2 is always available)
withHashedPasswords ? true,
# use argon2id-hashed passwords in config files (sha2 is always available)
withHashedPasswords ? true,
# generate TLS certificates on startup (pointless when reverse-proxied)
withCertgen ? false,
# generate TLS certificates on startup (pointless when reverse-proxied)
withCertgen ? false,
# create thumbnails with Pillow; faster than FFmpeg / MediaProcessing
withThumbnails ? true,
# create thumbnails with Pillow; faster than FFmpeg / MediaProcessing
withThumbnails ? true,
# create thumbnails with PyVIPS; even faster, uses more memory
# -- can be combined with Pillow to support more filetypes
withFastThumbnails ? false,
# create thumbnails with PyVIPS; even faster, uses more memory
# -- can be combined with Pillow to support more filetypes
withFastThumbnails ? false,
# enable FFmpeg; thumbnails for most filetypes (also video and audio), extract audio metadata, transcode audio to opus
# -- possibly dangerous if you allow anonymous uploads, since FFmpeg has a huge attack surface
# -- can be combined with Thumbnails and/or FastThumbnails, since FFmpeg is slower than both
withMediaProcessing ? true,
# enable FFmpeg; thumbnails for most filetypes (also video and audio), extract audio metadata, transcode audio to opus
# -- possibly dangerous if you allow anonymous uploads, since FFmpeg has a huge attack surface
# -- can be combined with Thumbnails and/or FastThumbnails, since FFmpeg is slower than both
withMediaProcessing ? true,
# if MediaProcessing is not enabled, you probably want this instead (less accurate, but much safer and faster)
withBasicAudioMetadata ? false,
# if MediaProcessing is not enabled, you probably want this instead (less accurate, but much safer and faster)
withBasicAudioMetadata ? false,
# send ZeroMQ messages from event-hooks
withZeroMQ ? true,
# send ZeroMQ messages from event-hooks
withZeroMQ ? true,
# enable FTPS support in the FTP server
withFTPS ? false,
# enable FTPS support in the FTP server
withFTPS ? false,
# samba/cifs server; dangerous and buggy, enable if you really need it
withSMB ? false,
# samba/cifs server; dangerous and buggy, enable if you really need it
withSMB ? false,
# extra packages to add to the PATH
extraPackages ? [ ],
# extra packages to add to the PATH
extraPackages ? [ ],
# function that accepts a python packageset and returns a list of packages to
# be added to the python venv. useful for scripts and such that require
# additional dependencies
extraPythonPackages ? (_p: [ ]),
# function that accepts a python packageset and returns a list of packages to
# be added to the python venv. useful for scripts and such that require
# additional dependencies
extraPythonPackages ? (_p: [ ]),
}:
let
pinData = lib.importJSON ./pin.json;
pyEnv = python.withPackages (ps:
with ps; [
pyEnv = python.withPackages (
ps:
with ps;
[
jinja2
]
++ lib.optional withSMB impacket
@ -57,7 +75,8 @@ let
++ lib.optional withZeroMQ pyzmq
++ (extraPythonPackages ps)
);
in stdenv.mkDerivation {
in
stdenv.mkDerivation {
pname = "copyparty";
version = pinData.version;
src = fetchurl {
@ -70,7 +89,9 @@ in stdenv.mkDerivation {
installPhase = ''
install -Dm755 $src $out/share/copyparty-sfx.py
makeWrapper ${pyEnv.interpreter} $out/bin/copyparty \
--set PATH '${lib.makeBinPath ([ util-linux ] ++ extraPackages ++ lib.optional withMediaProcessing ffmpeg)}:$PATH' \
--set PATH '${
lib.makeBinPath ([ util-linux ] ++ extraPackages ++ lib.optional withMediaProcessing ffmpeg)
}:$PATH' \
--add-flags "$out/share/copyparty-sfx.py"
'';
meta.mainProgram = "copyparty";

View file

@ -4,16 +4,22 @@
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
outputs =
{
self,
nixpkgs,
flake-utils,
}:
{
nixosModules.default = ./contrib/nixos/modules/copyparty.nix;
overlays.default = self: super: {
copyparty =
self.python3.pkgs.callPackage ./contrib/package/nix/copyparty {
copyparty = self.python3.pkgs.callPackage ./contrib/package/nix/copyparty {
ffmpeg = self.ffmpeg-full;
};
};
} // flake-utils.lib.eachDefaultSystem (system:
}
// flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = import nixpkgs {
inherit system;
@ -22,10 +28,12 @@
};
overlays = [ self.overlays.default ];
};
in {
in
{
packages = {
inherit (pkgs) copyparty;
default = self.packages.${system}.copyparty;
};
});
}
);
}