Unverified Commit 6355c63f authored by Leona Maroni's avatar Leona Maroni Committed by GitHub
Browse files

Provide NixOS module option to enable the paperless exporter. (#242084)

parents b1101504 865ab911
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -342,6 +342,9 @@

- `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.

  Example:
+72 −4
Original line number Diff line number Diff line
{ config, pkgs, lib, ... }:
{ config, options, pkgs, lib, ... }:
let
  cfg = config.services.paperless;

@@ -82,7 +82,7 @@ let
  };
in
{
  meta.maintainers = with lib.maintainers; [ leona SuperSandro2000 erikarvstedt ];
  meta.maintainers = with lib.maintainers; [ leona SuperSandro2000 erikarvstedt atemu theuni ];

  imports = [
    (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.postgresql = lib.mkIf cfg.database.createLocally {
@@ -439,5 +472,40 @@ in
        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}
      '';
    };
  })
  ]);
}
+28 −0
Original line number Diff line number Diff line
@@ -8,6 +8,15 @@ import ./make-test-python.nix ({ lib, ... }: {
      services.paperless = {
        enable = true;
        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, ... }: {
@@ -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/"))
        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)
    simple.send_monitor_command("quit")
    simple.wait_for_shutdown()