Skip to content

Commit

Permalink
nixos/froide: init
Browse files Browse the repository at this point in the history
  • Loading branch information
onny committed Nov 24, 2024
1 parent 82056ea commit 956ee34
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 0 deletions.
2 changes: 2 additions & 0 deletions nixos/doc/manual/release-notes/rl-2411.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@

- [Soteria](https://github.com/ImVaskel/soteria), a polkit authentication agent to handle elevated prompts for any desktop environment. Normally this should only be used on DEs or WMs that do not provide a graphical polkit frontend on their own. Available as [`security.soteria`](#opt-security.soteria.enable).

- [Froide](https://github.com/okfde/froide), a freedom of information act web application. Available as [services.froide](#opt-services.froide.enable).

- [Flood](https://flood.js.org/), a beautiful WebUI for various torrent clients. Available as [services.flood](options.html#opt-services.flood.enable).

- [Niri](https://github.com/YaLTeR/niri), a scrollable-tiling Wayland compositor. Available as [programs.niri](options.html#opt-programs.niri.enable).
Expand Down
1 change: 1 addition & 0 deletions nixos/modules/module-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -1437,6 +1437,7 @@
./services/web-apps/flarum.nix
./services/web-apps/fluidd.nix
./services/web-apps/freshrss.nix
./services/web-apps/froide.nix
./services/web-apps/galene.nix
./services/web-apps/gancio.nix
./services/web-apps/gerrit.nix
Expand Down
112 changes: 112 additions & 0 deletions nixos/modules/services/web-apps/froide.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
{
config,
lib,
pkgs,
...
}:
let

cfg = config.services.froide;
format = pkgs.formats.toml { };

in
{
options.services.froide = {

enable = lib.mkEnableOption "Gouvernment planer web app Govplan";

settings = lib.mkOption {
default = { };
description = ''
IMAP authentication configuration for rspamd-trainer. For supplying
the IMAP password, use the `secrets` option.
'';
type = lib.types.submodule { freeformType = format.type; };
example = lib.literalExpression ''
{
HOST = "localhost";
USERNAME = "[email protected]";
INBOXPREFIX = "INBOX/";
}
'';
};

secrets = lib.mkOption {
type = with lib.types; listOf path;
description = ''
A list of files containing the various secrets. Should be in the
format expected by systemd's `EnvironmentFile` directory. For the
IMAP account password use `PASSWORD = mypassword`.
'';
default = [ ];
};

};

config = lib.mkIf cfg.enable {

services.postgresql = {
enable = true;
ensureDatabases = [ "froide" ];
ensureUsers = [
{
name = "froide";
ensureDBOwnership = true;
}
];
extraPlugins = ps: with ps; [ postgis ];
authentication = ''
host froide froide localhost trust
'';
initialScript = pkgs.writeText "backend-initScript" ''
ALTER USER froide WITH SUPERUSER;
'';
};

systemd.services = {

postgresql.serviceConfig.ExecStartPost =
let
sqlFile = pkgs.writeText "froide-pgvectors-setup.sql" ''
ALTER USER froide WITH SUPERUSER;
#CREATE EXTENSION IF NOT EXISTS postgis;
#ALTER SCHEMA govplan OWNER TO govplan;
#ALTER EXTENSION govplan UPDATE;
'';
in
[
''
${lib.getExe' config.services.postgresql.package "psql"} -d froide -f "${sqlFile}"
''
];

froide = {
description = "Gouvernment planer Govplan";
serviceConfig = {
ExecStart = "${pkgs.froide}/bin/froide runserver 0.0.0.0:8000";
WorkingDirectory = "/var/lib/froide";
StateDirectory = [ "froide" ];
DynamicUser = true;
EnvironmentFile = [
(format.generate "froide-env" cfg.settings)
cfg.secrets
];
Environment = [ "DJANGO_CONFIGURATION=Production" ];
};
after = [ "postgresql.service" ];
wantedBy = [ "multi-user.target" ];
preStart = ''
# FIXME adapt paperless-ngx check for new versions
${pkgs.froide}/bin/froide collectstatic
${pkgs.froide}/bin/froide migrate
'';
};
};

environment.systemPackages = [ pkgs.froide ];

};

meta.maintainers = with lib.maintainers; [ onny ];

}
90 changes: 90 additions & 0 deletions nixos/tests/froide.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import ./make-test-python.nix ({ lib, ... }: {
name = "paperless";
meta.maintainers = with lib.maintainers; [ leona SuperSandro2000 erikarvstedt ];

nodes = let self = {
simple = { pkgs, ... }: {
environment.systemPackages = with pkgs; [ imagemagick jq ];
services.paperless = {
enable = true;
passwordFile = builtins.toFile "password" "admin";
};
};
postgres = { config, pkgs, ... }: {
imports = [ self.simple ];
services.postgresql = {
enable = true;
ensureDatabases = [ "paperless" ];
ensureUsers = [
{ name = config.services.paperless.user;
ensureDBOwnership = true;
}
];
};
services.paperless.settings = {
PAPERLESS_DBHOST = "/run/postgresql";
PAPERLESS_OCR_LANGUAGE = "deu";
};
};
}; in self;

testScript = ''
import json
def test_paperless(node):
node.wait_for_unit("paperless-consumer.service")
with subtest("Add a document via the file system"):
node.succeed(
"convert -size 400x40 xc:white -font 'DejaVu-Sans' -pointsize 20 -fill black "
"-annotate +5+20 'hello world 16-10-2005' /var/lib/paperless/consume/doc.png"
)
with subtest("Web interface gets ready"):
node.wait_for_unit("paperless-web.service")
# Wait until server accepts connections
node.wait_until_succeeds("curl -fs localhost:28981")
# Required for consuming documents via the web interface
with subtest("Task-queue gets ready"):
node.wait_for_unit("paperless-task-queue.service")
with subtest("Add a png document via the web interface"):
node.succeed(
"convert -size 400x40 xc:white -font 'DejaVu-Sans' -pointsize 20 -fill black "
"-annotate +5+20 'hello web 16-10-2005' /tmp/webdoc.png"
)
node.wait_until_succeeds("curl -u admin:admin -F document=@/tmp/webdoc.png -fs localhost:28981/api/documents/post_document/")
with subtest("Add a txt document via the web interface"):
node.succeed(
"echo 'hello web 16-10-2005' > /tmp/webdoc.txt"
)
node.wait_until_succeeds("curl -u admin:admin -F document=@/tmp/webdoc.txt -fs localhost:28981/api/documents/post_document/")
with subtest("Documents are consumed"):
node.wait_until_succeeds(
"(($(curl -u admin:admin -fs localhost:28981/api/documents/ | jq .count) == 3))"
)
docs = json.loads(node.succeed("curl -u admin:admin -fs localhost:28981/api/documents/"))['results']
assert "2005-10-16" in docs[0]['created']
assert "2005-10-16" in docs[1]['created']
assert "2005-10-16" in docs[2]['created']
# Detects gunicorn issues, see PR #190888
with subtest("Document metadata can be accessed"):
metadata = json.loads(node.succeed("curl -u admin:admin -fs localhost:28981/api/documents/1/metadata/"))
assert "original_checksum" in metadata
metadata = json.loads(node.succeed("curl -u admin:admin -fs localhost:28981/api/documents/2/metadata/"))
assert "original_checksum" in metadata
metadata = json.loads(node.succeed("curl -u admin:admin -fs localhost:28981/api/documents/3/metadata/"))
assert "original_checksum" in metadata
test_paperless(simple)
simple.send_monitor_command("quit")
simple.wait_for_shutdown()
test_paperless(postgres)
'';
})

0 comments on commit 956ee34

Please sign in to comment.