nixos/hledger-web: add stateDir, use own user, fix ExecStart
This allows for shared hledger installations, where the web interface is available via network and multiple user share a SSH access to the hledger user. Also added `--serve` to the CLI options, as hledger-web tries to open a webbrowser otherwise: hledger-web: xdg-open: rawSystem: runInteractiveProcess: exec: does not exist (No such file or directory) Co-authored-by: Aaron Andersen <aaron@fosslib.net>
This commit is contained in:
parent
71c55e53d7
commit
569940b9fd
|
@ -34,11 +34,22 @@ in {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
journalFile = mkOption {
|
stateDir = mkOption {
|
||||||
type = types.path;
|
type = types.path;
|
||||||
example = "/home/hledger/.hledger.journal";
|
default = "/var/lib/hledger-web";
|
||||||
description = ''
|
description = ''
|
||||||
Input journal file.
|
Path the service has access to. If left as the default value this
|
||||||
|
directory will automatically be created before the hledger-web server
|
||||||
|
starts, otherwise the sysadmin is responsible for ensuring the
|
||||||
|
directory exists with appropriate ownership and permissions.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
journalFiles = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ".hledger.journal" ];
|
||||||
|
description = ''
|
||||||
|
Paths to journal files relative to <option>services.hledger-web.stateDir</option>.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -50,28 +61,61 @@ in {
|
||||||
Base URL, when sharing over a network.
|
Base URL, when sharing over a network.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extraOptions = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
example = [ "--forecast" ];
|
||||||
|
description = ''
|
||||||
|
Extra command line arguments to pass to hledger-web.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
systemd.services.hledger-web = {
|
|
||||||
|
users.users.hledger = {
|
||||||
|
name = "hledger";
|
||||||
|
group = "hledger";
|
||||||
|
isSystemUser = true;
|
||||||
|
home = cfg.stateDir;
|
||||||
|
useDefaultShell = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups.hledger = {};
|
||||||
|
|
||||||
|
systemd.services.hledger-web = let
|
||||||
|
serverArgs = with cfg; escapeShellArgs ([
|
||||||
|
"--serve"
|
||||||
|
"--host=${host}"
|
||||||
|
"--port=${toString port}"
|
||||||
|
"--capabilities=${capabilityString}"
|
||||||
|
(optionalString (cfg.baseUrl != null) "--base-url=${cfg.baseUrl}")
|
||||||
|
(optionalString (cfg.serveApi) "--serve-api")
|
||||||
|
] ++ (map (f: "--file=${stateDir}/${f}") cfg.journalFiles)
|
||||||
|
++ extraOptions);
|
||||||
|
in {
|
||||||
description = "hledger-web - web-app for the hledger accounting tool.";
|
description = "hledger-web - web-app for the hledger accounting tool.";
|
||||||
documentation = [ https://hledger.org/hledger-web.html ];
|
documentation = [ https://hledger.org/hledger-web.html ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [ "networking.target" ];
|
after = [ "networking.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = mkMerge [
|
||||||
ExecStart = ''
|
{
|
||||||
${pkgs.hledger-web}/bin/hledger-web \
|
ExecStart = "${pkgs.hledger-web}/bin/hledger-web ${serverArgs}";
|
||||||
--host=${cfg.host} \
|
Restart = "always";
|
||||||
--port=${toString cfg.port} \
|
WorkingDirectory = cfg.stateDir;
|
||||||
--file=${cfg.journalFile} \
|
User = "hledger";
|
||||||
"--capabilities=${cfg.capabilities}" \
|
Group = "hledger";
|
||||||
${optionalString (cfg.baseUrl != null) "--base-url=${cfg.baseUrl}"} \
|
PrivateTmp = true;
|
||||||
${optionalString (cfg.serveApi) "--serve-api"}
|
}
|
||||||
'';
|
(mkIf (cfg.stateDir == "/var/lib/hledger-web") {
|
||||||
Restart = "always";
|
StateDirectory = "hledger-web";
|
||||||
};
|
})
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
meta.maintainers = with lib.maintainers; [ marijanp ];
|
meta.maintainers = with lib.maintainers; [ marijanp erictapen ];
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,25 +13,21 @@ rec {
|
||||||
name = "hledger-web";
|
name = "hledger-web";
|
||||||
meta.maintainers = with lib.maintainers; [ marijanp ];
|
meta.maintainers = with lib.maintainers; [ marijanp ];
|
||||||
|
|
||||||
nodes = {
|
nodes = rec {
|
||||||
server = { config, pkgs, ... }: rec {
|
server = { config, pkgs, ... }: {
|
||||||
services.hledger-web = {
|
services.hledger-web = {
|
||||||
host = "127.0.0.1";
|
host = "127.0.0.1";
|
||||||
port = 5000;
|
port = 5000;
|
||||||
enable = true;
|
enable = true;
|
||||||
journalFile = journal;
|
|
||||||
};
|
};
|
||||||
networking.firewall.allowedTCPPorts = [ services.hledger-web.port ];
|
networking.firewall.allowedTCPPorts = [ config.services.hledger-web.port ];
|
||||||
|
systemd.services.hledger-web.preStart = ''
|
||||||
|
ln -s ${journal} /var/lib/hledger-web/.hledger.journal
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
apiserver = { config, pkgs, ... }: rec {
|
apiserver = { ... }: {
|
||||||
services.hledger-web = {
|
imports = [ server ];
|
||||||
host = "127.0.0.1";
|
services.hledger-web.serveApi = true;
|
||||||
port = 5000;
|
|
||||||
enable = true;
|
|
||||||
serveApi = true;
|
|
||||||
journalFile = journal;
|
|
||||||
};
|
|
||||||
networking.firewall.allowedTCPPorts = [ services.hledger-web.port ];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,7 +38,7 @@ rec {
|
||||||
server.wait_for_open_port(5000)
|
server.wait_for_open_port(5000)
|
||||||
with subtest("Check if web UI is accessible"):
|
with subtest("Check if web UI is accessible"):
|
||||||
page = server.succeed("curl -L http://127.0.0.1:5000")
|
page = server.succeed("curl -L http://127.0.0.1:5000")
|
||||||
assert "test.journal" in page
|
assert ".hledger.journal" in page
|
||||||
|
|
||||||
apiserver.wait_for_unit("hledger-web.service")
|
apiserver.wait_for_unit("hledger-web.service")
|
||||||
apiserver.wait_for_open_port(5000)
|
apiserver.wait_for_open_port(5000)
|
||||||
|
|
Loading…
Reference in New Issue