Skip to content

Commit

Permalink
nixos/paperless: add backup feature
Browse files Browse the repository at this point in the history
Paperless includes a document exporter that can be used for
backups.

This extends the module to provide a way to enable and configure
a timer, the backup parameters and allow providing a post-processing
script (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.
  • Loading branch information
ctheune committed Sep 10, 2023
1 parent b4f1091 commit 224f1f0
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 2 deletions.
3 changes: 3 additions & 0 deletions nixos/doc/manual/release-notes/rl-2311.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,9 @@ The module update takes care of the new config syntax and the data itself (user

- The `cawbird` package is dropped from nixpkgs, as it got broken by the Twitter API closing down and has been abandoned upstream.

- The paperless module now has options to automatically create regular
backups using the integrated document exporter.

## Nixpkgs internals {#sec-release-23.11-nixpkgs-internals}

- The use of `sourceRoot = "source";`, `sourceRoot = "source/subdir";`, and similar lines in package derivations using the default `unpackPhase` is deprecated as it requires `unpackPhase` to always produce a directory named "source". Use `sourceRoot = src.name`, `sourceRoot = "${src.name}/subdir";`, or `setSourceRoot = "sourceRoot=$(echo */subdir)";` or similar instead.
Expand Down
68 changes: 66 additions & 2 deletions nixos/modules/services/misc/paperless.nix
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,45 @@ in
defaultText = literalExpression "pkgs.paperless-ngx";
description = lib.mdDoc "The Paperless package to use.";
};

exporter = {

enable = mkEnableOption (lib.mdDoc "Enable the paperless document exporter.");

directory = mkOption {
type = types.str;
default = cfg.dataDir + "/exports";
description = lib.mdDoc "Directory to store exports.";
};

calendar = mkOption {
type = types.nullOr types.str;
default = "01:30:00";
description = lib.mdDoc ''
Configured when to run the exporter.
(DayOfWeek Year-Month-Day Hour:Minute:Second).
Set this to `null` to disable the timer and trigger the
`paperless-exporter` service yourself.
'';
};

options = mkOption {
type = types.str;
default = "-c -d";
description = lib.mdDoc "Options to pass to the document exporter.";
};

postScript = mkOption {
type = types.lines;
default = "";
description = lib.mdDoc "Script to run after finishing the export.";
};
};

};

config = mkIf cfg.enable {
config = mkMerge [(mkIf cfg.enable {
services.redis.servers.paperless.enable = mkIf enableRedis true;

systemd.tmpfiles.rules = [
Expand Down Expand Up @@ -392,5 +428,33 @@ in
gid = config.ids.gids.paperless;
};
};
};
}) (mkIf (cfg.enable && cfg.exporter.enable) {

systemd.tmpfiles.rules = [
"d '${cfg.exporter.directory}' - ${cfg.user} ${config.users.users.${cfg.user}.group} - -"
];

systemd.timers.paperless-exporter = lib.mkIf (cfg.exporter.calendar != null) {
description = "paperless exporter timer";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = cfg.exporter.calendar;
AccuracySec = "5m";
};
};

systemd.services.paperless-exporter = {
description = "paperless exporter service";
serviceConfig.User = cfg.user;
script = ''
set -e
cd ${cfg.dataDir}
echo "Exporting documents ..."
./paperless-manage document_exporter ${cfg.exporter.directory} --no-progress-bar --no-color ${cfg.exporter.options}
echo "Running post script ..."
${cfg.exporter.postScript}
'';
};
})];

}
17 changes: 17 additions & 0 deletions nixos/tests/paperless.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import ./make-test-python.nix ({ lib, ... }: {
services.paperless = {
enable = true;
passwordFile = builtins.toFile "password" "admin";

exporter.enable = true;
exporter.postScript = ''
echo "Hello World"
'';
};
};

Expand Down Expand Up @@ -62,5 +67,17 @@ import ./make-test-python.nix ({ lib, ... }: {
metadata = json.loads(machine.succeed("curl -u admin:admin -fs localhost:28981/api/documents/3/metadata/"))
assert "original_checksum" in metadata
# Check exporter config looks good
with subtest("Exporter config is good"):
machine.succeed("systemctl start paperless-exporter")
machine.wait_until_fails("systemctl status paperless-exporter")
output = machine.succeed("journalctl -u paperless-exporter.service")
assert "Hello World" in output
machine.succeed("ls -lah /var/lib/paperless/exports/manifest.json")
timers = machine.succeed("systemctl list-timers paperless-exporter")
assert "paperless-exporter.timer paperless-exporter.service" in timers
assert "1 timers listed." in timers
'';
})

0 comments on commit 224f1f0

Please sign in to comment.