nixos/paperless: add module options for automated exports
Paperless includes a document exporter that can be used for e.g. backups. This change extends the module to provide a way to enable and configure a timer, export settings, pre- and post-processing scripts (e.g. to ship the backup somewhere else, clean up, ...). It works out of the box when just enabling it but can be customized. Includes suitable tests.
This commit is contained in:
parent
14f4013165
commit
865ab91155
@ -308,6 +308,9 @@
|
|||||||
|
|
||||||
- `bind.cacheNetworks` now only controls access for recursive queries, where it previously controlled access for all queries.
|
- `bind.cacheNetworks` now only controls access for recursive queries, where it previously controlled access for all queries.
|
||||||
|
|
||||||
|
- The paperless module now has an option for regular automatic export of
|
||||||
|
documents data using the integrated document exporter.
|
||||||
|
|
||||||
- Caddy can now be built with plugins by using `caddy.withPlugins`, a `passthru` function that accepts an attribute set as a parameter. The `plugins` argument represents a list of Caddy plugins, with each Caddy plugin being a versioned module. The `hash` argument represents the `vendorHash` of the resulting Caddy source code with the plugins added.
|
- Caddy can now be built with plugins by using `caddy.withPlugins`, a `passthru` function that accepts an attribute set as a parameter. The `plugins` argument represents a list of Caddy plugins, with each Caddy plugin being a versioned module. The `hash` argument represents the `vendorHash` of the resulting Caddy source code with the plugins added.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ config, options, pkgs, lib, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.services.paperless;
|
cfg = config.services.paperless;
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ let
|
|||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
meta.maintainers = with lib.maintainers; [ leona SuperSandro2000 erikarvstedt ];
|
meta.maintainers = with lib.maintainers; [ leona SuperSandro2000 erikarvstedt atemu theuni ];
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
(lib.mkRenamedOptionModule [ "services" "paperless-ng" ] [ "services" "paperless" ])
|
(lib.mkRenamedOptionModule [ "services" "paperless-ng" ] [ "services" "paperless" ])
|
||||||
@ -252,9 +252,42 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exporter = {
|
||||||
|
enable = lib.mkEnableOption "regular automatic document exports";
|
||||||
|
|
||||||
|
directory = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = cfg.dataDir + "/export";
|
||||||
|
defaultText = "\${dataDir}/export";
|
||||||
|
description = "Directory to store export.";
|
||||||
|
};
|
||||||
|
|
||||||
|
onCalendar = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = "01:30:00";
|
||||||
|
description = ''
|
||||||
|
When to run the exporter. See {manpage}`systemd.time(7)`.
|
||||||
|
|
||||||
|
`null` disables the timer; allowing you to run the
|
||||||
|
`paperless-exporter` service through other means.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = lib.mkOption {
|
||||||
|
type = with lib.types; attrsOf anything;
|
||||||
|
default = {
|
||||||
|
"no-progress-bar" = true;
|
||||||
|
"no-color" = true;
|
||||||
|
"compare-checksums" = true;
|
||||||
|
"delete" = true;
|
||||||
|
};
|
||||||
|
description = "Settings to pass to the document exporter as CLI arguments.";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable (lib.mkMerge [ {
|
||||||
services.redis.servers.paperless.enable = lib.mkIf enableRedis true;
|
services.redis.servers.paperless.enable = lib.mkIf enableRedis true;
|
||||||
|
|
||||||
services.postgresql = lib.mkIf cfg.database.createLocally {
|
services.postgresql = lib.mkIf cfg.database.createLocally {
|
||||||
@ -439,5 +472,40 @@ in
|
|||||||
gid = config.ids.gids.paperless;
|
gid = config.ids.gids.paperless;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
|
(lib.mkIf cfg.exporter.enable {
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d '${cfg.exporter.directory}' - ${cfg.user} ${config.users.users.${cfg.user}.group} - -"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.paperless.exporter.settings = options.services.paperless.exporter.settings.default;
|
||||||
|
|
||||||
|
systemd.services.paperless-exporter = {
|
||||||
|
startAt = lib.defaultTo [] cfg.exporter.onCalendar;
|
||||||
|
serviceConfig = {
|
||||||
|
User = cfg.user;
|
||||||
|
WorkingDirectory = cfg.dataDir;
|
||||||
|
};
|
||||||
|
unitConfig = let
|
||||||
|
services = [
|
||||||
|
"paperless-consumer.service"
|
||||||
|
"paperless-scheduler.service"
|
||||||
|
"paperless-task-queue.service"
|
||||||
|
"paperless-web.service" ];
|
||||||
|
in {
|
||||||
|
# Shut down the paperless services while the exporter runs
|
||||||
|
Conflicts = services;
|
||||||
|
After = services;
|
||||||
|
# Bring them back up afterwards, regardless of pass/fail
|
||||||
|
OnFailure = services;
|
||||||
|
OnSuccess = services;
|
||||||
|
};
|
||||||
|
enableStrictShellChecks = true;
|
||||||
|
script = ''
|
||||||
|
./paperless-manage document_exporter ${cfg.exporter.directory} ${lib.cli.toGNUCommandLineShell {} cfg.exporter.settings}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
})
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,15 @@ import ./make-test-python.nix ({ lib, ... }: {
|
|||||||
services.paperless = {
|
services.paperless = {
|
||||||
enable = true;
|
enable = true;
|
||||||
passwordFile = builtins.toFile "password" "admin";
|
passwordFile = builtins.toFile "password" "admin";
|
||||||
|
|
||||||
|
exporter = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
"no-color" = lib.mkForce false; # override a default option
|
||||||
|
"no-thumbnail" = true; # add a new option
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
postgres = { config, pkgs, ... }: {
|
postgres = { config, pkgs, ... }: {
|
||||||
@ -73,6 +82,25 @@ import ./make-test-python.nix ({ lib, ... }: {
|
|||||||
metadata = json.loads(node.succeed("curl -u admin:admin -fs localhost:28981/api/documents/3/metadata/"))
|
metadata = json.loads(node.succeed("curl -u admin:admin -fs localhost:28981/api/documents/3/metadata/"))
|
||||||
assert "original_checksum" in metadata
|
assert "original_checksum" in metadata
|
||||||
|
|
||||||
|
with subtest("Exporter"):
|
||||||
|
node.succeed("systemctl start --wait paperless-exporter")
|
||||||
|
node.wait_for_unit("paperless-web.service")
|
||||||
|
node.wait_for_unit("paperless-consumer.service")
|
||||||
|
node.wait_for_unit("paperless-scheduler.service")
|
||||||
|
node.wait_for_unit("paperless-task-queue.service")
|
||||||
|
|
||||||
|
node.succeed("ls -lah /var/lib/paperless/export/manifest.json")
|
||||||
|
|
||||||
|
timers = node.succeed("systemctl list-timers paperless-exporter")
|
||||||
|
print(timers)
|
||||||
|
assert "paperless-exporter.timer paperless-exporter.service" in timers, "missing timer"
|
||||||
|
assert "1 timers listed." in timers, "incorrect number of timers"
|
||||||
|
|
||||||
|
# Double check that our attrset option override works as expected
|
||||||
|
cmdline = node.succeed("grep 'paperless-manage' $(systemctl cat paperless-exporter | grep ExecStart | cut -f 2 -d=)")
|
||||||
|
print(f"Exporter command line {cmdline!r}")
|
||||||
|
assert cmdline.strip() == "./paperless-manage document_exporter /var/lib/paperless/export --compare-checksums --delete --no-progress-bar --no-thumbnail", "Unexpected exporter command line"
|
||||||
|
|
||||||
test_paperless(simple)
|
test_paperless(simple)
|
||||||
simple.send_monitor_command("quit")
|
simple.send_monitor_command("quit")
|
||||||
simple.wait_for_shutdown()
|
simple.wait_for_shutdown()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user