diff --git a/nix/buildvm.sh b/nix/buildvm.sh deleted file mode 100755 index efeb4f36..00000000 --- a/nix/buildvm.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -if [ "$1" = "-f" ]; then - echo "Deleting current state image..." - rm *.qcow2 -fi - -nixos-rebuild build-vm \ - -I nixos-config=./configuration-test.nix \ - -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/nixos-21.11.tar.gz diff --git a/nix/configuration-test.nix b/nix/checks/configuration-test.nix similarity index 73% rename from nix/configuration-test.nix rename to nix/checks/configuration-test.nix index f3e44c52..a95edb83 100644 --- a/nix/configuration-test.nix +++ b/nix/checks/configuration-test.nix @@ -1,6 +1,5 @@ { config, pkgs, ... }: let - docspell = import ./release.nix; full-text-search = { enabled = true; solr.url = "http://localhost:${toString config.services.solr.port}/solr/docspell"; @@ -12,7 +11,6 @@ let }; in { - imports = docspell.modules ++ [ ./solr.nix ]; i18n = { defaultLocale = "en_US.UTF-8"; @@ -23,17 +21,6 @@ in password = "root"; }; - nixpkgs = { - config = { - packageOverrides = pkgs: - let - callPackage = pkgs.lib.callPackageWith(custom // pkgs); - custom = { - docspell = callPackage docspell.currentPkg {}; - }; - in custom; - }; - }; services.docspell-joex = { enable = true; @@ -57,7 +44,8 @@ in }; }; openid = [ - { enabled = true; + { + enabled = true; display = "Local"; provider = { provider-id = "local"; @@ -73,10 +61,9 @@ in }; environment.systemPackages = - [ pkgs.docspell.server - pkgs.docspell.joex + [ pkgs.jq - pkgs.telnet + pkgs.inetutils pkgs.htop pkgs.openjdk ]; @@ -88,9 +75,9 @@ in networking = { hostName = "docspelltest"; - firewall.allowedTCPPorts = [7880]; + firewall.allowedTCPPorts = [ 7880 ]; }; - system.stateVersion = "21.05"; + system.stateVersion = "22.05"; } diff --git a/nix/checks/default.nix b/nix/checks/default.nix new file mode 100644 index 00000000..35d43699 --- /dev/null +++ b/nix/checks/default.nix @@ -0,0 +1,7 @@ +{ ... }: +{ + imports = [ + ./configuration-test.nix + ./solr.nix + ]; +} diff --git a/nix/solr.nix b/nix/checks/solr.nix similarity index 59% rename from nix/solr.nix rename to nix/checks/solr.nix index b7d73cfb..10150a42 100644 --- a/nix/solr.nix +++ b/nix/checks/solr.nix @@ -1,8 +1,15 @@ -{ config, pkgs, ... }: +{ config, pkgs, lib, ... }: # This module sets up solr with one core. It is a bit tedious…. If you # know a better solution, please let me know. { + nixpkgs.config = { + permittedInsecurePackages = [ + "solr-8.6.3" + # NOTE: Qtwebkit is a dep for wkhtmltopdf, this line is needed until #201765 is fixed in nixpkgs + "qtwebkit-5.212.0-alpha4" + ]; + }; services.solr = { enable = true; @@ -15,7 +22,7 @@ solrPort = toString config.services.solr.port; initSolr = '' if [ ! -f ${config.services.solr.stateDir}/docspell_core ]; then - while ! echo "" | ${pkgs.telnet}/bin/telnet localhost ${solrPort} + while ! echo "" | ${pkgs.inetutils}/bin/telnet localhost ${solrPort} do echo "Waiting for SOLR become ready..." sleep 1.5 @@ -25,11 +32,12 @@ fi ''; in - { script = initSolr; - after = [ "solr.target" ]; - wantedBy = [ "multi-user.target" ]; - requires = [ "solr.target" ]; - description = "Create a core at solr"; - }; + { + script = initSolr; + after = [ "solr.target" ]; + wantedBy = [ "multi-user.target" ]; + requires = [ "solr.target" ]; + description = "Create a core at solr"; + }; } diff --git a/nix/checks/testScript.py b/nix/checks/testScript.py new file mode 100644 index 00000000..ae5fa1a7 --- /dev/null +++ b/nix/checks/testScript.py @@ -0,0 +1,3 @@ +with subtest("services are up"): + machine.wait_for_unit("docspell-restserver") + machine.wait_for_unit("docspell-joex") diff --git a/nix/flake.lock b/nix/flake.lock new file mode 100644 index 00000000..521f5f2b --- /dev/null +++ b/nix/flake.lock @@ -0,0 +1,26 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1669735802, + "narHash": "sha256-qtG/o/i5ZWZLmXw108N2aPiVsxOcidpHJYNkT45ry9Q=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "731cc710aeebecbf45a258e977e8b68350549522", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-22.11", + "type": "indirect" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/nix/flake.nix b/nix/flake.nix new file mode 100644 index 00000000..633f3cd3 --- /dev/null +++ b/nix/flake.nix @@ -0,0 +1,119 @@ +{ + description = "Docspell flake"; + inputs = { + nixpkgs.url = "nixpkgs/nixos-22.11"; + }; + + outputs = { self, nixpkgs }: + let + supportedSystems = [ "x86_64-linux" "aarch64-linux" ]; + forAllSystems = nixpkgs.lib.genAttrs supportedSystems; + nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; }); + # Version config + cfg = { + v0_39_0 = rec { + version = "0.39.0"; + server = { + url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-restserver-${version}.zip"; + sha256 = "sha256-YZzYOqJzp2J5ioTT8H7qpRA3mHDRjJYNA7fUOEQWSfY="; + }; + joex = { + url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-joex-${version}.zip"; + sha256 = "sha256-6Vcuk9+JDkNAdTQd+sRLARfE+y9cbtGE8hWTTcxZk3E="; + }; + }; + }; + current_version = cfg.v0_39_0; + inherit (current_version) version; + in + rec + { + overlays.default = final: prev: { + docspell-server = with final; stdenv.mkDerivation { + inherit version; + pname = "docspell-server"; + + src = fetchzip current_version.server; + buildInputs = [ jdk11 ]; + buildPhase = "true"; + + installPhase = '' + mkdir -p $out/{bin,docspell-restserver-${version}} + cp -R * $out/docspell-restserver-${version}/ + cat > $out/bin/docspell-restserver <<-EOF + #!${bash}/bin/bash + $out/docspell-restserver-${version}/bin/docspell-restserver -java-home ${jdk11} "\$@" + EOF + chmod 755 $out/bin/docspell-restserver + ''; + }; + docspell-joex = with final; stdenv.mkDerivation rec { + inherit version; + + pname = "docspell-joex"; + + src = fetchzip current_version.joex; + + buildInputs = [ jdk11 ]; + + buildPhase = "true"; + + installPhase = '' + mkdir -p $out/{bin,docspell-joex-${version}} + cp -R * $out/docspell-joex-${version}/ + cat > $out/bin/docspell-joex <<-EOF + #!${bash}/bin/bash + $out/docspell-joex-${version}/bin/docspell-joex -java-home ${jdk11} "\$@" + EOF + chmod 755 $out/bin/docspell-joex + ''; + }; + + }; + + packages = forAllSystems (system: + { + default = (import nixpkgs { + inherit system; + overlays = [ self.overlays.default ]; + }).docspell-server; + }); + + checks = forAllSystems + (system: { + build = self.packages.${system}.default; + + test = + with import (nixpkgs + "/nixos/lib/testing-python.nix") + { + inherit system; + }; + + makeTest { + name = "docspell"; + nodes = { + machine = { ... }: { + imports = [ + self.nixosModules.default + ./checks + ]; + }; + }; + + testScript = builtins.readFile ./checks/testScript.py; + }; + }); + + nixosModules = { + default = { ... }: { + imports = [ + ((import ./modules/server.nix) self.overlays.default) + ((import ./modules/joex.nix) self.overlays.default) + ]; + }; + server = ((import ./modules/server.nix) self.overlays.default); + joex = ((import ./modules/joex.nix) self.overlays.default); + }; + + }; +} diff --git a/nix/module-joex.nix b/nix/modules/joex.nix similarity index 93% rename from nix/module-joex.nix rename to nix/modules/joex.nix index 386a108a..e6d5dcce 100644 --- a/nix/module-joex.nix +++ b/nix/modules/joex.nix @@ -1,13 +1,13 @@ -{config, lib, pkgs, ...}: +overlay: { config, lib, pkgs, ... }: with lib; let cfg = config.services.docspell-joex; user = if cfg.runAs == null then "docspell" else cfg.runAs; configFile = pkgs.writeText "docspell-joex.conf" '' - {"docspell": { "joex": - ${builtins.toJSON cfg} - }} + {"docspell": { "joex": + ${builtins.toJSON cfg} + }} ''; defaults = { app-id = "joex1"; @@ -83,20 +83,20 @@ let schedule = "Sun *-*-* 00:00:00 UTC"; sender-account = ""; smtp-id = ""; - recipients = []; + recipients = [ ]; subject = "Docspell {{ latestVersion }} is available"; body = '' -Hello, + Hello, -You are currently running Docspell {{ currentVersion }}. Version *{{ latestVersion }}* -is now available, which was released on {{ releasedAt }}. Check the release page at: + You are currently running Docspell {{ currentVersion }}. Version *{{ latestVersion }}* + is now available, which was released on {{ releasedAt }}. Check the release page at: - + -Have a nice day! + Have a nice day! -Docpell Update Check -''; + Docpell Update Check + ''; }; extraction = { pdf = { @@ -110,7 +110,7 @@ Docpell Update Check page-range = { begin = 10; }; - ghostscript = { + ghostscript = { working-dir = "/tmp/docspell-extraction"; command = { program = "${pkgs.ghostscript}/bin/gs"; @@ -126,9 +126,9 @@ Docpell Update Check }; }; tesseract = { - command= { + command = { program = "${pkgs.tesseract4}/bin/tesseract"; - args = ["{{file}}" "stdout" "-l" "{{lang}}" ]; + args = [ "{{file}}" "stdout" "-l" "{{lang}}" ]; timeout = "5 minutes"; }; }; @@ -149,7 +149,8 @@ Docpell Update Check enabled = true; item-count = 600; classifiers = [ - { "useSplitWords" = "true"; + { + "useSplitWords" = "true"; "splitWordsTokenizerRegexp" = ''[\p{L}][\p{L}0-9]*|(?:\$ ?)?[0-9]+(?:\.[0-9]{2})?%?|\s+|.''; "splitWordsIgnoreRegexp" = ''\s+''; "useSplitPrefixSuffixNGrams" = "true"; @@ -169,14 +170,14 @@ Docpell Update Check markdown = { internal-css = '' - body { padding: 2em 5em; } - ''; + body { padding: 2em 5em; } + ''; }; wkhtmlpdf = { command = { program = "${pkgs.wkhtmltopdf}/bin/wkhtmltopdf"; - args = ["-s" "A4" "--encoding" "UTF-8" "-" "{{outfile}}"]; + args = [ "-s" "A4" "--encoding" "UTF-8" "-" "{{outfile}}" ]; timeout = "2 minutes"; }; working-dir = "/tmp/docspell-convert"; @@ -185,7 +186,7 @@ Docpell Update Check tesseract = { command = { program = "${pkgs.tesseract4}/bin/tesseract"; - args = ["{{infile}}" "out" "-l" "{{lang}}" "pdf" "txt"]; + args = [ "{{infile}}" "out" "-l" "{{lang}}" "pdf" "txt" ]; timeout = "5 minutes"; }; working-dir = "/tmp/docspell-convert"; @@ -194,7 +195,7 @@ Docpell Update Check unoconv = { command = { program = "${pkgs.unoconv}/bin/unoconv"; - args = ["-f" "pdf" "-o" "{{outfile}}" "{{infile}}"]; + args = [ "-f" "pdf" "-o" "{{outfile}}" "{{infile}}" ]; timeout = "2 minutes"; }; working-dir = "/tmp/docspell-convert"; @@ -205,12 +206,14 @@ Docpell Update Check command = { program = "${pkgs.ocrmypdf}/bin/ocrmypdf"; args = [ - "-l" "{{lang}}" - "--skip-text" - "--deskew" - "-j" "1" - "{{infile}}" - "{{outfile}}" + "-l" + "{{lang}}" + "--skip-text" + "--deskew" + "-j" + "1" + "{{infile}}" + "{{outfile}}" ]; timeout = "5 minutes"; }; @@ -219,7 +222,7 @@ Docpell Update Check }; files = { chunk-size = 524288; - valid-mime-types = []; + valid-mime-types = [ ]; }; full-text-search = { enabled = false; @@ -238,7 +241,7 @@ Docpell Update Check user = "pguser"; password = ""; }; - pg-config = {}; + pg-config = { }; pg-query-parser = "websearch_to_tsquery"; pg-rank-normalization = [ 4 ]; }; @@ -260,7 +263,7 @@ Docpell Update Check fail-fast = true; run-timeout = "15 minutes"; nix-runner = { - nix-binary = "${pkgs.nixFlakes}/bin/nix"; + nix-binary = "${pkgs.nix}/bin/nix"; build-timeout = "15 minutes"; }; docker-runner = { @@ -270,7 +273,8 @@ Docpell Update Check }; }; }; -in { +in +{ ## interface options = { @@ -299,7 +303,7 @@ in { }; jvmArgs = mkOption { type = types.listOf types.str; - default = []; + default = [ ]; example = [ "-J-Xmx1G" ]; description = "The options passed to the executable for setting jvm arguments."; }; @@ -318,7 +322,7 @@ in { }; bind = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { address = mkOption { type = types.str; @@ -337,7 +341,7 @@ in { }; logging = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { minimum-level = mkOption { type = types.str; @@ -364,10 +368,10 @@ in { type = types.bool; default = defaults.mail-debug; description = '' - Enable or disable debugging for e-mail related functionality. This - applies to both sending and receiving mails. For security reasons - logging is not very extensive on authentication failures. Setting - this to true, results in a lot of data printed to stdout. + Enable or disable debugging for e-mail related functionality. This + applies to both sending and receiving mails. For security reasons + logging is not very extensive on authentication failures. Setting + this to true, results in a lot of data printed to stdout. ''; }; @@ -405,7 +409,7 @@ in { }; send-mail = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { list-id = mkOption { type = types.str; @@ -429,7 +433,7 @@ in { }; scheduler = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { pool-size = mkOption { type = types.int; @@ -485,7 +489,7 @@ in { }; periodic-scheduler = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { wakeup-period = mkOption { type = types.str; @@ -506,10 +510,10 @@ in { }; user-tasks = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { scan-mailbox = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { max-folders = mkOption { type = types.int; @@ -534,12 +538,12 @@ in { type = types.int; default = defaults.user-tasks.scan-mailbox.max-mails; description = '' - A limit on how many mails to process in one job run. This is - meant to avoid too heavy resource allocation to one - user/collective. + A limit on how many mails to process in one job run. This is + meant to avoid too heavy resource allocation to one + user/collective. - If more than this number of mails is encountered, a warning is - logged. + If more than this number of mails is encountered, a warning is + logged. ''; }; }; @@ -554,7 +558,7 @@ in { }; house-keeping = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { schedule = mkOption { type = types.str; @@ -565,7 +569,7 @@ in { ''; }; cleanup-invites = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { enabled = mkOption { type = types.bool; @@ -587,7 +591,7 @@ in { ''; }; cleanup-jobs = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { enabled = mkOption { type = types.bool; @@ -622,7 +626,7 @@ in { ''; }; cleanup-remember-me = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { enabled = mkOption { type = types.bool; @@ -641,7 +645,7 @@ in { }; cleanup-downloads = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { enabled = mkOption { type = types.bool; @@ -660,7 +664,7 @@ in { }; check-nodes = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { enabled = mkOption { type = types.bool; @@ -687,7 +691,7 @@ in { }; update-check = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { enabled = mkOption { type = types.bool; @@ -769,10 +773,10 @@ in { }; extraction = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { pdf = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { min-text-len = mkOption { type = types.int; @@ -791,7 +795,7 @@ in { description = "Settings for PDF extraction"; }; preview = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { dpi = mkOption { type = types.int; @@ -813,7 +817,7 @@ in { description = ""; }; ocr = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { max-image-size = mkOption { type = types.int; @@ -824,7 +828,7 @@ in { ''; }; page-range = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { begin = mkOption { type = types.int; @@ -849,7 +853,7 @@ in { ''; }; ghostscript = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { working-dir = mkOption { type = types.str; @@ -857,7 +861,7 @@ in { description = "Directory where the extraction processes can put their temp files"; }; command = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { program = mkOption { type = types.str; @@ -885,10 +889,10 @@ in { description = "The ghostscript command."; }; unpaper = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { command = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { program = mkOption { type = types.str; @@ -916,10 +920,10 @@ in { description = "The unpaper command."; }; tesseract = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { command = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { program = mkOption { type = types.str; @@ -968,7 +972,7 @@ in { }; text-analysis = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { max-length = mkOption { type = types.int; @@ -993,7 +997,7 @@ in { }; nlp = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { mode = mkOption { type = types.str; @@ -1051,7 +1055,7 @@ in { }; regex-ner = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { max-entries = mkOption { type = types.int; @@ -1093,7 +1097,7 @@ in { }; classification = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { enabled = mkOption { type = types.bool; @@ -1151,7 +1155,7 @@ in { }; convert = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { chunk-size = mkOption { type = types.int; @@ -1180,7 +1184,7 @@ in { ''; }; markdown = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { internal-css = mkOption { type = types.str; @@ -1202,7 +1206,7 @@ in { ''; }; wkhtmlpdf = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { working-dir = mkOption { type = types.str; @@ -1210,7 +1214,7 @@ in { description = "Directory where the conversion processes can put their temp files"; }; command = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { program = mkOption { type = types.str; @@ -1241,7 +1245,7 @@ in { ''; }; tesseract = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { working-dir = mkOption { type = types.str; @@ -1249,7 +1253,7 @@ in { description = "Directory where the conversion processes can put their temp files"; }; command = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { program = mkOption { type = types.str; @@ -1280,7 +1284,7 @@ in { ''; }; unoconv = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { working-dir = mkOption { type = types.str; @@ -1288,7 +1292,7 @@ in { description = "Directory where the conversion processes can put their temp files"; }; command = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { program = mkOption { type = types.str; @@ -1326,7 +1330,7 @@ in { }; ocrmypdf = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { enabled = mkOption { type = types.bool; @@ -1339,7 +1343,7 @@ in { description = "Directory where the conversion processes can put their temp files"; }; command = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { program = mkOption { type = types.str; @@ -1396,7 +1400,7 @@ in { ''; }; files = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { chunk-size = mkOption { type = types.int; @@ -1425,10 +1429,10 @@ in { }; }); default = defaults.files; - description= "Settings for how files are stored."; + description = "Settings for how files are stored."; }; full-text-search = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { enabled = mkOption { type = types.bool; @@ -1448,7 +1452,7 @@ in { }; solr = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { url = mkOption { type = types.str; @@ -1486,7 +1490,7 @@ in { }; postgresql = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { use-default-connection = mkOption { type = types.bool; @@ -1540,7 +1544,7 @@ in { }; migration = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { index-all-chunk = mkOption { type = types.int; @@ -1562,7 +1566,7 @@ in { description = "Configuration for full-text search."; }; addons = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { working-dir = mkOption { type = types.str; @@ -1575,7 +1579,7 @@ in { description = "Cache directory"; }; executor-config = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { runner = mkOption { type = types.str; @@ -1593,7 +1597,7 @@ in { description = ""; }; nspawn = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { enabled = mkOption { type = types.bool; @@ -1621,7 +1625,7 @@ in { description = ""; }; nix-runner = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { nix-binary = mkOption { type = types.str; @@ -1639,7 +1643,7 @@ in { description = ""; }; docker-runner = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { docker-binary = mkOption { type = types.str; @@ -1672,6 +1676,8 @@ in { ## implementation config = mkIf config.services.docspell-joex.enable { + nixpkgs.overlays = [ overlay ]; + users.users."${user}" = mkIf (cfg.runAs == null) { name = user; isSystemUser = true; @@ -1680,44 +1686,43 @@ in { description = "Docspell user"; group = user; }; - users.groups."${user}" = mkIf (cfg.runAs == null) { - }; + users.groups."${user}" = mkIf (cfg.runAs == null) { }; # Setting up a unoconv listener to improve conversion performance systemd.services.unoconv = let cmd = "${pkgs.unoconv}/bin/unoconv --listener -v"; in - { - description = "Unoconv Listener"; - after = [ "networking.target" ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - Restart = "always"; - }; - script = - "${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${user} -c \"${cmd}\""; + { + description = "Unoconv Listener"; + after = [ "networking.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Restart = "always"; }; + script = + "${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${user} -c \"${cmd}\""; + }; systemd.services.docspell-joex = let args = builtins.concatStringsSep " " cfg.jvmArgs; - cmd = "${pkgs.docspell.joex}/bin/docspell-joex ${args} -- ${configFile}"; + cmd = "${pkgs.docspell-joex}/bin/docspell-joex ${args} -- ${configFile}"; waitTarget = if cfg.waitForTarget != null then [ cfg.waitForTarget ] else - []; + [ ]; in - { - description = "Docspell Joex"; - after = ([ "networking.target" ] ++ waitTarget); - wantedBy = [ "multi-user.target" ]; - path = [ pkgs.gawk ]; + { + description = "Docspell Joex"; + after = ([ "networking.target" ] ++ waitTarget); + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.gawk ]; - script = - "${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${user} -c \"${cmd}\""; - }; + script = + "${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${user} -c \"${cmd}\""; + }; }; } diff --git a/nix/module-server.nix b/nix/modules/server.nix similarity index 94% rename from nix/module-server.nix rename to nix/modules/server.nix index 16748173..33e3aaa7 100644 --- a/nix/module-server.nix +++ b/nix/modules/server.nix @@ -1,4 +1,4 @@ -{config, lib, pkgs, ...}: +overlay: { config, lib, pkgs, ... }: with lib; let @@ -76,7 +76,7 @@ let user = "pguser"; password = ""; }; - pg-config = {}; + pg-config = { }; pg-query-parser = "websearch_to_tsquery"; pg-rank-normalization = [ 4 ]; }; @@ -124,17 +124,18 @@ let }; files = { chunk-size = 524288; - valid-mime-types = []; + valid-mime-types = [ ]; }; addons = { enabled = false; allow-impure = true; - allowed-urls = ["*"]; - denied-urls = []; + allowed-urls = [ "*" ]; + denied-urls = [ ]; }; }; }; -in { +in +{ ## interface options = { @@ -153,7 +154,7 @@ in { }; jvmArgs = mkOption { type = types.listOf types.str; - default = []; + default = [ ]; example = [ "-J-Xmx1G" ]; description = "The options passed to the executable for setting jvm arguments."; }; @@ -229,7 +230,7 @@ in { }; bind = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { address = mkOption { type = types.str; @@ -248,7 +249,7 @@ in { }; server-options = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { enable-http-2 = mkOption { type = types.bool; @@ -272,7 +273,7 @@ in { }; logging = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { minimum-level = mkOption { type = types.str; @@ -296,7 +297,7 @@ in { }; auth = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { server-secret = mkOption { type = types.str; @@ -317,7 +318,7 @@ in { ''; }; remember-me = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { enabled = mkOption { type = types.bool; @@ -341,7 +342,7 @@ in { }; download-all = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { max-files = mkOption { type = types.int; @@ -439,12 +440,12 @@ in { }; }; }); - default = []; + default = [ ]; description = "A list of OIDC provider configurations."; }; integration-endpoint = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { enabled = mkOption { type = types.bool; @@ -464,7 +465,7 @@ in { ''; }; allowed-ips = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { enabled = mkOption { type = types.bool; @@ -488,7 +489,7 @@ in { ''; }; http-basic = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { enabled = mkOption { type = types.bool; @@ -518,7 +519,7 @@ in { ''; }; http-header = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { enabled = mkOption { type = types.bool; @@ -563,7 +564,7 @@ in { }; admin-endpoint = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { secret = mkOption { type = types.str; @@ -577,7 +578,7 @@ in { }; full-text-search = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { enabled = mkOption { type = types.bool; @@ -594,7 +595,7 @@ in { description = "The backend to use, either solr or postgresql"; }; solr = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { url = mkOption { type = types.str; @@ -632,7 +633,7 @@ in { }; postgresql = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { use-default-connection = mkOption { type = types.bool; @@ -691,16 +692,16 @@ in { }; backend = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { mail-debug = mkOption { type = types.bool; default = defaults.backend.mail-debug; description = '' - Enable or disable debugging for e-mail related functionality. This - applies to both sending and receiving mails. For security reasons - logging is not very extensive on authentication failures. Setting - this to true, results in a lot of data printed to stdout. + Enable or disable debugging for e-mail related functionality. This + applies to both sending and receiving mails. For security reasons + logging is not very extensive on authentication failures. Setting + this to true, results in a lot of data printed to stdout. ''; }; jdbc = mkOption { @@ -774,7 +775,7 @@ in { description = "Registration settings"; }; files = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { chunk-size = mkOption { type = types.int; @@ -803,10 +804,10 @@ in { }; }); default = defaults.backend.files; - description= "Settings for how files are stored."; + description = "Settings for how files are stored."; }; addons = mkOption { - type = types.submodule({ + type = types.submodule ({ options = { enabled = mkOption { type = types.bool; @@ -844,6 +845,7 @@ in { ## implementation config = mkIf config.services.docspell-restserver.enable { + nixpkgs.overlays = [ overlay ]; users.users."${user}" = mkIf (cfg.runAs == null) { name = user; isSystemUser = true; @@ -852,25 +854,24 @@ in { description = "Docspell user"; group = user; }; - users.groups."${user}" = mkIf (cfg.runAs == null) { - }; + users.groups."${user}" = mkIf (cfg.runAs == null) { }; systemd.services.docspell-restserver = - let - args = builtins.concatStringsSep " " cfg.jvmArgs; - cmd = "${pkgs.docspell.server}/bin/docspell-restserver ${args} -- ${configFile}"; - in - { - description = "Docspell Rest Server"; - after = [ "networking.target" ]; - wantedBy = [ "multi-user.target" ]; - path = [ pkgs.gawk ]; - preStart = '' + let + args = builtins.concatStringsSep " " cfg.jvmArgs; + cmd = "${pkgs.docspell-server}/bin/docspell-restserver ${args} -- ${configFile}"; + in + { + description = "Docspell Rest Server"; + after = [ "networking.target" ]; + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.gawk ]; + preStart = '' ''; - script = - "${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${user} -c \"${cmd}\""; - }; + script = + "${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${user} -c \"${cmd}\""; + }; }; } diff --git a/nix/pkg.nix b/nix/pkg.nix deleted file mode 100644 index 9ad108be..00000000 --- a/nix/pkg.nix +++ /dev/null @@ -1,54 +0,0 @@ -cfg: {stdenv, lib, fetchzip, file, curl, inotifyTools, fetchurl, jdk11, bash, jq, sqlite}: -let - meta = with lib; { - description = "Docspell helps to organize and archive your paper documents."; - homepage = https://github.com/eikek/docspell; - license = licenses.gpl3; - maintainers = [ maintainers.eikek ]; - }; -in -{ server = stdenv.mkDerivation rec { - name = "docspell-server-${cfg.version}"; - - src = fetchzip cfg.server; - - buildInputs = [ jdk11 ]; - - buildPhase = "true"; - - installPhase = '' - mkdir -p $out/{bin,docspell-restserver-${cfg.version}} - cp -R * $out/docspell-restserver-${cfg.version}/ - cat > $out/bin/docspell-restserver <<-EOF - #!${bash}/bin/bash - $out/docspell-restserver-${cfg.version}/bin/docspell-restserver -java-home ${jdk11} "\$@" - EOF - chmod 755 $out/bin/docspell-restserver - ''; - - inherit meta; - }; - - joex = stdenv.mkDerivation rec { - name = "docspell-joex-${cfg.version}"; - - src = fetchzip cfg.joex; - - buildInputs = [ jdk11 ]; - - buildPhase = "true"; - - installPhase = '' - mkdir -p $out/{bin,docspell-joex-${cfg.version}} - cp -R * $out/docspell-joex-${cfg.version}/ - cat > $out/bin/docspell-joex <<-EOF - #!${bash}/bin/bash - $out/docspell-joex-${cfg.version}/bin/docspell-joex -java-home ${jdk11} "\$@" - EOF - chmod 755 $out/bin/docspell-joex - ''; - - inherit meta; - }; - -} diff --git a/nix/release.nix b/nix/release.nix deleted file mode 100644 index f6f65741..00000000 --- a/nix/release.nix +++ /dev/null @@ -1,140 +0,0 @@ -rec { - cfg = { - v0_39_0 = rec { - version = "0.39.0"; - server = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-restserver-${version}.zip"; - sha256 = "sha256-YZzYOqJzp2J5ioTT8H7qpRA3mHDRjJYNA7fUOEQWSfY="; - }; - joex = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-joex-${version}.zip"; - sha256 = "sha256-6Vcuk9+JDkNAdTQd+sRLARfE+y9cbtGE8hWTTcxZk3E="; - }; - }; - v0_38_0 = rec { - version = "0.38.0"; - server = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-restserver-${version}.zip"; - sha256 = "sha256-KufKnkg+YXIktWRQ/pUrXVKLLBOb1i/G3u60Y3GwMAw="; - }; - joex = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-joex-${version}.zip"; - sha256 = "sha256-Z85SfJfuCZZ24B5TJM0Mpx8NefaLdQpWs7ftkVCiohM="; - }; - }; - v0_37_0 = rec { - version = "0.37.0"; - server = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-restserver-${version}.zip"; - sha256 = "sha256-Emi4lynYsNIZh2B0c6l1LexxDgrnax2Uy19VoPW1Exo="; - }; - joex = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-joex-${version}.zip"; - sha256 = "sha256-fWYBTphEtkFCdKun4U7fEQkTLnum/qtLBJs8Y9AqD54="; - }; - }; - v0_36_0 = rec { - version = "0.36.0"; - server = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-restserver-${version}.zip"; - sha256 = "sha256-0qDsvEN5ohv/xvkHywonfMtf3p871VdegJqrg7DaAak="; - }; - joex = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-joex-${version}.zip"; - sha256 = "sha256-ovNSdjEKY1oaQruTQN23sGK4lHuBoYgTLVocVNYIt9Y="; - }; - }; - v0_35_0 = rec { - version = "0.35.0"; - server = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-restserver-${version}.zip"; - sha256 = "sha256-WnZME2qyxwWZmArH0TDSZLmxZgM/mQCvgeYOFtsIZNs="; - }; - joex = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-joex-${version}.zip"; - sha256 = "sha256-hBBXthKeS8petmRscSr9kUOphkipxvltHkfg7yvN/Ok="; - }; - }; - v0_34_0 = rec { - version = "0.34.0"; - server = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-restserver-${version}.zip"; - sha256 = "0gri5g6mhz8ghqbpzg191mxjacia7dz36j9y90ndns32pzx2w7z3"; - }; - joex = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-joex-${version}.zip"; - sha256 = "0i485q762afajim3iq4ax9a3snih041s9fvrzh9i68ixk1qrvwz4"; - }; - }; - v0_33_0 = rec { - version = "0.33.0"; - server = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-restserver-${version}.zip"; - sha256 = "1nnf5iwycyq8ddc2b0fks5xjqrj921d50b9lw488zs5j387sjmm1"; - }; - joex = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-joex-${version}.zip"; - sha256 = "07ip74awhilyxyksrq6qb6jbiiiqfxlw5in461n93aggpa5r6ccy"; - }; - }; - v0_32_0 = rec { - version = "0.32.0"; - server = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-restserver-${version}.zip"; - sha256 = "0095i9p7ikx8a64137iq95ilj8aiz8rzwxvqz8qkv2ia15g8q65p"; - }; - joex = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-joex-${version}.zip"; - sha256 = "0k0bvzvdksw2bd33cfdpxw229rpx4g4xnm5qkk2pga35g7k5kgf7"; - }; - }; - v0_31_0 = rec { - version = "0.31.0"; - server = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-restserver-${version}.zip"; - sha256 = "17qkq71lqf5yh6p23rhjliwqrid70c6x5iq20msliqzghv6zjn97"; - }; - joex = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-joex-${version}.zip"; - sha256 = "0ani309kcrn7rslr7qnx9n2z09ba2v8dwnzjkabj9d2kd05mkz7r"; - }; - }; - v0_22_0 = rec { - version = "0.22.0"; - server = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-restserver-${version}.zip"; - sha256 = "1lysbqc62c2ijqg948wh882b6609mhal9n4ab9y4xjs788lfvd7h"; - }; - joex = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-joex-${version}.zip"; - sha256 = "0g5ajkrsnbdig0hw5nz1g75ghvds6f2389zy2ccs4zfjws6xp1nr"; - }; - tools = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-tools-${version}.zip"; - sha256 = "00n9z2z06hr431xascpxmb6vn5lc2a3hz4p2ap3zc1nbkkdwmkh2"; - }; - }; - v0_1_0 = rec { - version = "0.1.0"; - server = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-restserver-${version}.zip"; - sha256 = "19bmvrk07s4gsw4dszbilfv7jns7bp20lfr0ia73xdmn5w8kdhq0"; - }; - joex = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-joex-${version}.zip"; - sha256 = "175yz0lxra0qv63xjl90hh32idm13c1k1aah2hqc0ncpx22scp5v"; - }; - tools = { - url = "https://github.com/eikek/docspell/releases/download/v${version}/docspell-tools-${version}.zip"; - sha256 = "03w5cxylk2yfkah15qrx5cl21gfly0vwa0czglb1swsri3808rdb"; - }; - }; - }; - pkg = v: import ./pkg.nix v; - currentPkg = pkg cfg.v0_39_0; - module-joex = ./module-joex.nix; - module-restserver = ./module-server.nix; - modules = [ module-joex - module-restserver - ]; -} diff --git a/website/site/content/docs/install/nix.md b/website/site/content/docs/install/nix.md index 677ef786..343b4e0c 100644 --- a/website/site/content/docs/install/nix.md +++ b/website/site/content/docs/install/nix.md @@ -10,59 +10,7 @@ weight = 24 Docspell can be installed via the [nix](https://nixos.org/nix) package manager, which is available for Linux and OSX. Docspell is currently not part of the [nixpkgs collection](https://nixos.org/nixpkgs/), but you -can use the derivation from this repository. This is sometimes -referred to as [import from -derivation](https://nixos.wiki/wiki/Import_From_Derivation). - -For example, the `builtins.fetchTarball` function can be used to -retrieve the files; then import the `release.nix` file: - -``` nix -let - docspellsrc = builtins.fetchTarball "https://github.com/eikek/docspell/archive/master.tar.gz"; -in -import "${docspellsrc}/nix/release.nix"; -``` - -This creates a set containing a function for creating a derivation for -docspell. This then needs to be called like other custom packages. For -example, in your `~/.nixpkgs/config.nix` you could write this: - -``` nix -let - docspellsrc = builtins.fetchTarball "https://github.com/eikek/docspell/archive/master.tar.gz"; - docspell = import "${docspellsrc}/nix/release.nix"; -in -{ packageOverrides = pkgs: - let - callPackage = pkgs.lib.callPackageWith(custom // pkgs); - custom = { - docspell = callPackage docspell.currentPkg {}; - }; - in custom; -} -``` - -The `docspell` custom package is again a set that contains derivations -for all 3 installable docspell programs: the restserver, joex and the -tools. - -Then you can install docspell via `nix-shell` or `nix-env`, for example: - -``` bash -$ nix-env -iA nixpkgs.docspell.server nixpkgs.docspell.joex nixpkgs.docspell.tools -``` - -You may need to replace `nixpkgs` with `nixos` when you're on NixOS. - -The expression `docspell.currentPkg` refers to the most current -release of Docspell. So even if you use the tarball of the current -master branch, the `release.nix` file only contains derivations for -releases. The expression `docspell.currentPkg` is a shortcut for -selecting the most current release. For example it translates to -`docspell.pkg docspell.cfg.v{{ pversion() }}` – if the current version -is `{{version()}}`. - +can use the flake from this repository. ## Upgrading @@ -71,9 +19,6 @@ it is recommended to backup your database before upgrading. Should something not work as expected, restore the database backup and go back to the previous version. -When using the provided nix setup, the `currentPkg` always points to -the latest release. Thus it is enough to run `nix-build`. - # Docspell on NixOS {#nixos} If you are running [NixOS](https://nixos.org), there is a module @@ -83,59 +28,22 @@ There are the following modules provided: - restserver - joex -- consumedir - -The `consumedir` module defines a systemd unit that starts the `dsc -watch` command to watch one or more directories for new files. - -You need to import the `release.nix` file as described above in your -`configuration.nix` and then append the docspell module to your list of -modules. Here is an example: ```nix -{ config, pkgs, ... }: -let - docspellsrc = builtins.fetchTarball "https://github.com/eikek/docspell/archive/master.tar.gz"; - docspell = import "${docspellsrc}/nix/release.nix"; -in -{ - imports = [ mymodule1 mymodule2 ] ++ docspell.modules; +# flake.nix +inputs.docspell.url = "github:eikek/docspell?dir=nix/"; - nixpkgs = { - config = { - packageOverrides = pkgs: - let - callPackage = pkgs.lib.callPackageWith(custom // pkgs); - custom = { - docspell = callPackage docspell.currentPkg {}; - }; - in custom; - }; - }; - - services.docspell-restserver = { - enable = true; - base-url = "http://docspelltest:7880"; - # ... more settings here - }; - services.docspell-joex = { - enable = true; - base-url = "http://docspelltexst:7878"; - # ... more settings here - }; - services.docspell-consumedir = { - enable = true; - watchDirs = ["/tmp/test"]; - source-id = "the-source-id"; - }; - - ... -} +# in modules +imports = [ + docspell.nixosModules.default +] +services.docspell-joex = { ... } +services.docspell-restserver = { ... } ``` -Please see the `nix/module-server.nix` and `nix/module-joex.nix` files -for the set of options. The nixos options are modelled after the +Please see the `nix/modules/server.nix` and `nix/modules/joex.nix` files +for the set of options. The nixos options are modeled after the default configuration file. The modules files are only applicable to the newest version of @@ -149,25 +57,13 @@ postgres database. This snippet can be used to create a vm (using `nixos-rebuild build-vm` as shown above) or a container, for example. ``` nix -{ config, pkgs, ... }: -let - docspellsrc = builtins.fetchTarball "https://github.com/eikek/docspell/archive/master.tar.gz"; - docspell = import "${docspellsrc}/nix/release.nix"; -in -{ - imports = docspell.modules; +# flake.nix +inputs.docspell.url = "github:eikek/docspell?dir=nix/"; - nixpkgs = { - config = { - packageOverrides = pkgs: - let - callPackage = pkgs.lib.callPackageWith(custom // pkgs); - custom = { - docspell = callPackage docspell.currentPkg {}; - }; - in custom; - }; - }; +# module.nix +{ config, pkgs, docspell, ... }: +{ + imports = docspell.nixosModules.default; ##### just for the example… users.users.root = { diff --git a/website/site/content/docs/install/quickstart.md b/website/site/content/docs/install/quickstart.md index 6740c76e..fa02b4e1 100644 --- a/website/site/content/docs/install/quickstart.md +++ b/website/site/content/docs/install/quickstart.md @@ -21,8 +21,9 @@ To get started, here are some quick links: from the [release page](https://github.com/eikek/docspell/releases/latest). - via the [nix package manager](@/docs/install/nix.md) and/or as a - [NixOS module](@/docs/install/nix.md#nixos). If you use nix/nixos, - you know what to do. The linked page contains some examples. + [NixOS module](@/docs/install/nix.md#nixos) through a flake. + If you use nix/nixos, you know what to do. The linked page contains + some examples. - [Unraid](https://www.unraid.net/): There are user provided [notes and unraid templates](https://github.com/vakilando/unraid-docker-templates)