nixos/davis: fix several outstanding bugs (#409068)

This commit is contained in:
Ulrik Strid 2025-05-21 15:36:41 +02:00 committed by GitHub
commit fbbba999f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 70 additions and 23 deletions

View file

@ -24,9 +24,10 @@ After that, `davis` can be deployed like this:
adminLogin = "admin"; adminLogin = "admin";
adminPasswordFile = "/run/secrets/davis-admin-password"; adminPasswordFile = "/run/secrets/davis-admin-password";
appSecretFile = "/run/secrets/davis-app-secret"; appSecretFile = "/run/secrets/davis-app-secret";
nginx = {};
}; };
} }
``` ```
This deploys Davis using a sqlite database running out of `/var/lib/davis`. This deploys Davis using a sqlite database running out of `/var/lib/davis`.
Logs can be found in `/var/lib/davis/var/log/`.

View file

@ -220,10 +220,13 @@ in
}; };
nginx = lib.mkOption { nginx = lib.mkOption {
type = lib.types.submodule ( type = lib.types.nullOr (
lib.recursiveUpdate (import ../web-servers/nginx/vhost-options.nix { inherit config lib; }) { } lib.types.submodule (
lib.recursiveUpdate (import ../web-servers/nginx/vhost-options.nix { inherit config lib; }) {
}
)
); );
default = null; default = { };
example = '' example = ''
{ {
serverAliases = [ serverAliases = [
@ -235,7 +238,7 @@ in
} }
''; '';
description = '' description = ''
With this option, you can customize the nginx virtualHost settings. Use this option to customize an nginx virtual host. To disable the nginx set this to null.
''; '';
}; };
@ -308,18 +311,16 @@ in
message = "One of services.davis.database.urlFile or services.davis.database.createLocally must be set."; message = "One of services.davis.database.urlFile or services.davis.database.createLocally must be set.";
} }
{ {
assertion = (mail.dsn != null) != (mail.dsnFile != null); assertion = !(mail.dsn != null && mail.dsnFile != null);
message = "One of (and only one of) services.davis.mail.dsn or services.davis.mail.dsnFile must be set."; message = "services.davis.mail.dsn and services.davis.mail.dsnFile cannot both be set.";
} }
]; ];
services.davis.config = services.davis.config =
{ {
APP_ENV = "prod"; APP_ENV = "prod";
APP_CACHE_DIR = "${cfg.dataDir}/var/cache"; APP_CACHE_DIR = "${cfg.dataDir}/var/cache";
# note: we do not need the log dir (we log to stdout/journald), by davis/symfony will try to create it, and the default value is one in the nix-store
# so we set it to a path under dataDir to avoid something like: Unable to create the "logs" directory (/nix/store/5cfskz0ybbx37s1161gjn5klwb5si1zg-davis-4.4.1/var/log).
APP_LOG_DIR = "${cfg.dataDir}/var/log"; APP_LOG_DIR = "${cfg.dataDir}/var/log";
LOG_FILE_PATH = "/dev/stdout"; LOG_FILE_PATH = "%kernel.logs_dir%/%kernel.environment%.log";
DATABASE_DRIVER = db.driver; DATABASE_DRIVER = db.driver;
INVITE_FROM_ADDRESS = mail.inviteFromAddress; INVITE_FROM_ADDRESS = mail.inviteFromAddress;
APP_SECRET._secret = cfg.appSecretFile; APP_SECRET._secret = cfg.appSecretFile;
@ -330,7 +331,14 @@ in
CALDAV_ENABLED = true; CALDAV_ENABLED = true;
CARDDAV_ENABLED = true; CARDDAV_ENABLED = true;
} }
// (if mail.dsn != null then { MAILER_DSN = mail.dsn; } else { MAILER_DSN._secret = mail.dsnFile; }) // (
if mail.dsn != null then
{ MAILER_DSN = mail.dsn; }
else if mail.dsnFile != null then
{ MAILER_DSN._secret = mail.dsnFile; }
else
{ }
)
// ( // (
if db.createLocally then if db.createLocally then
{ {

View file

@ -1,10 +1,14 @@
{ pkgs, ... }: {
pkgs,
config,
...
}:
{ {
name = "davis"; name = "davis";
meta.maintainers = pkgs.davis.meta.maintainers; meta.maintainers = pkgs.davis.meta.maintainers;
nodes.machine = nodes.machine1 =
{ config, ... }: { config, ... }:
{ {
virtualisation = { virtualisation = {
@ -24,33 +28,67 @@
adminLogin = "admin"; adminLogin = "admin";
appSecretFile = "${pkgs.writeText "davisAppSecret" "52882ef142066e09ab99ce816ba72522e789505caba224"}"; appSecretFile = "${pkgs.writeText "davisAppSecret" "52882ef142066e09ab99ce816ba72522e789505caba224"}";
adminPasswordFile = "${pkgs.writeText "davisAdminPass" "nixos"}"; adminPasswordFile = "${pkgs.writeText "davisAdminPass" "nixos"}";
nginx = { }; };
};
nodes.machine2 =
{ nodes, config, ... }:
{
virtualisation = {
memorySize = 512;
};
environment.systemPackages = [ pkgs.fcgi ];
# no nginx, and no mail dsn
services.davis = {
enable = true;
hostname = "davis.example.com";
database = {
driver = "postgresql";
};
adminLogin = "admin";
appSecretFile = "${pkgs.writeText "davisAppSecret" "52882ef142066e09ab99ce816ba72522e789505caba224"}";
adminPasswordFile = "${pkgs.writeText "davisAdminPass" "nixos"}";
nginx = null;
}; };
}; };
testScript = '' testScript = ''
start_all() start_all()
machine.wait_for_unit("postgresql.service")
machine.wait_for_unit("davis-env-setup.service") machine1.wait_for_unit("postgresql.service")
machine.wait_for_unit("davis-db-migrate.service") machine1.wait_for_unit("davis-env-setup.service")
machine.wait_for_unit("nginx.service") machine1.wait_for_unit("davis-db-migrate.service")
machine.wait_for_unit("phpfpm-davis.service") machine1.wait_for_unit("phpfpm-davis.service")
with subtest("welcome screen loads"): with subtest("welcome screen loads"):
machine.succeed( machine1.succeed(
"curl -sSfL --resolve davis.example.com:80:127.0.0.1 http://davis.example.com/ | grep '<title>Davis</title>'" "curl -sSfL --resolve davis.example.com:80:127.0.0.1 http://davis.example.com/ | grep '<title>Davis</title>'"
) )
with subtest("login works"): with subtest("login works"):
csrf_token = machine.succeed( csrf_token = machine1.succeed(
"curl -c /tmp/cookies -sSfL --resolve davis.example.com:80:127.0.0.1 http://davis.example.com/login | grep '_csrf_token' | sed -E 's,.*value=\"(.*)\".*,\\1,g'" "curl -c /tmp/cookies -sSfL --resolve davis.example.com:80:127.0.0.1 http://davis.example.com/login | grep '_csrf_token' | sed -E 's,.*value=\"(.*)\".*,\\1,g'"
) )
r = machine.succeed( r = machine1.succeed(
f"curl -b /tmp/cookies --resolve davis.example.com:80:127.0.0.1 http://davis.example.com/login -X POST -F _username=admin -F _password=nixos -F _csrf_token={csrf_token.strip()} -D headers" f"curl -b /tmp/cookies --resolve davis.example.com:80:127.0.0.1 http://davis.example.com/login -X POST -F _username=admin -F _password=nixos -F _csrf_token={csrf_token.strip()} -D headers"
) )
print(r) print(r)
machine.succeed( machine1.succeed(
"[[ $(grep -i 'location: ' headers | cut -d: -f2- | xargs echo) == /dashboard* ]]" "[[ $(grep -i 'location: ' headers | cut -d: -f2- | xargs echo) == /dashboard* ]]"
) )
machine2.wait_for_unit("davis-env-setup.service")
machine2.wait_for_unit("davis-db-migrate.service")
machine2.wait_for_unit("phpfpm-davis.service")
r = machine2.succeed(
"find /var/lib/davis/var/log"
)
print(r)
env = (
"SCRIPT_NAME=/index.php",
"SCRIPT_FILENAME=${config.nodes.machine2.services.davis.package}/public/index.php",
"REMOTE_ADDR=127.0.0.1",
"REQUEST_METHOD=GET",
);
page = machine2.succeed(f"{' '.join(env)} ${pkgs.fcgi}/bin/cgi-fcgi -bind -connect ${config.nodes.machine2.services.phpfpm.pools.davis.socket}")
''; '';
} }