
Every postgresql testcase essentially does the following things:
* Filter `postgresqlVersions` for server packages
* Filter postgresql server packages for suitable ones (i.e. extensions
must support the given version)
* Generate an attribute-set of testcases
The first item became necessary in
7ab1e88833
given that
`postgresql/default.nix` now exposes JIT and non-JIT servers AND a
`libpq` that is not suitable for the tests here.
This changes restructures this a little bit, i.e.:
* Having an attribute-set that contains a bunch of postgresql servers
and a single client package seems odd (and the sole consumer of
`postgresqlVersions` in nixpkgs, the test suite, has to take that into
account). Hence, postgresql's default.nix now provides `libpq` (the client)
and a `postgresqlVersions` attribute with all supported JIT and non-JIT
variants of postgresql.
* Each test-case gets a third argument, a function called `genTests`:
this function sets `recurseForDerivations = true;` and generates an
attribute-set of tests for each postgresql version given a function
that returns a testcase or multiple test-cases (`makeTestFor`). The
argument to `makeTestFor` is a postgresql server package.
This function also accepts a filter predicate that is passed against
`filterAttrs` to remove postgresql server packages that are not
suitable for the test (e.g. because the version isn't supported by the
extension to test).
I checked by making sure that the `.drv` doesn't change on staging with
this change on top for postgresq, postgresql-jit,
postgresql-wal-receiver, postgresql-tls-client-cert, anonymizer, pgjwt,
pgvecto-rs, timescaledb, tsja and wal2json.
133 lines
4.0 KiB
Nix
133 lines
4.0 KiB
Nix
{
|
|
pkgs,
|
|
makeTest,
|
|
genTests,
|
|
}:
|
|
|
|
let
|
|
inherit (pkgs) lib;
|
|
|
|
runWithOpenSSL =
|
|
file: cmd:
|
|
pkgs.runCommand file {
|
|
buildInputs = [ pkgs.openssl ];
|
|
} cmd;
|
|
caKey = runWithOpenSSL "ca.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out";
|
|
caCert = runWithOpenSSL "ca.crt" ''
|
|
openssl req -new -x509 -sha256 -key ${caKey} -out $out -subj "/CN=test.example" -days 36500
|
|
'';
|
|
serverKey = runWithOpenSSL "server.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out";
|
|
serverKeyPath = "/var/lib/postgresql";
|
|
serverCert = runWithOpenSSL "server.crt" ''
|
|
openssl req -new -sha256 -key ${serverKey} -out server.csr -subj "/CN=db.test.example"
|
|
openssl x509 -req -in server.csr -CA ${caCert} -CAkey ${caKey} \
|
|
-CAcreateserial -out $out -days 36500 -sha256
|
|
'';
|
|
clientKey = runWithOpenSSL "client.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out";
|
|
clientCert = runWithOpenSSL "client.crt" ''
|
|
openssl req -new -sha256 -key ${clientKey} -out client.csr -subj "/CN=test"
|
|
openssl x509 -req -in client.csr -CA ${caCert} -CAkey ${caKey} \
|
|
-CAcreateserial -out $out -days 36500 -sha256
|
|
'';
|
|
clientKeyPath = "/root";
|
|
|
|
makeTestFor =
|
|
package:
|
|
makeTest {
|
|
name = "postgresql-tls-client-cert-${package.name}";
|
|
meta.maintainers = with lib.maintainers; [ erictapen ];
|
|
|
|
nodes.server =
|
|
{ ... }:
|
|
{
|
|
system.activationScripts = {
|
|
keyPlacement.text = ''
|
|
mkdir -p '${serverKeyPath}'
|
|
cp '${serverKey}' '${serverKeyPath}/server.key'
|
|
chown postgres:postgres '${serverKeyPath}/server.key'
|
|
chmod 600 '${serverKeyPath}/server.key'
|
|
'';
|
|
};
|
|
services.postgresql = {
|
|
inherit package;
|
|
enable = true;
|
|
enableJIT = lib.hasInfix "-jit-" package.name;
|
|
enableTCPIP = true;
|
|
ensureUsers = [
|
|
{
|
|
name = "test";
|
|
ensureDBOwnership = true;
|
|
}
|
|
];
|
|
ensureDatabases = [ "test" ];
|
|
settings = {
|
|
ssl = "on";
|
|
ssl_ca_file = toString caCert;
|
|
ssl_cert_file = toString serverCert;
|
|
ssl_key_file = "${serverKeyPath}/server.key";
|
|
};
|
|
authentication = ''
|
|
hostssl test test ::/0 cert clientcert=verify-full
|
|
'';
|
|
};
|
|
networking = {
|
|
interfaces.eth1 = {
|
|
ipv6.addresses = [
|
|
{
|
|
address = "fc00::1";
|
|
prefixLength = 120;
|
|
}
|
|
];
|
|
};
|
|
firewall.allowedTCPPorts = [ 5432 ];
|
|
};
|
|
};
|
|
|
|
nodes.client =
|
|
{ ... }:
|
|
{
|
|
system.activationScripts = {
|
|
keyPlacement.text = ''
|
|
mkdir -p '${clientKeyPath}'
|
|
cp '${clientKey}' '${clientKeyPath}/client.key'
|
|
chown root:root '${clientKeyPath}/client.key'
|
|
chmod 600 '${clientKeyPath}/client.key'
|
|
'';
|
|
};
|
|
environment = {
|
|
variables = {
|
|
PGHOST = "db.test.example";
|
|
PGPORT = "5432";
|
|
PGDATABASE = "test";
|
|
PGUSER = "test";
|
|
PGSSLMODE = "verify-full";
|
|
PGSSLCERT = clientCert;
|
|
PGSSLKEY = "${clientKeyPath}/client.key";
|
|
PGSSLROOTCERT = caCert;
|
|
};
|
|
systemPackages = [ package ];
|
|
};
|
|
networking = {
|
|
interfaces.eth1 = {
|
|
ipv6.addresses = [
|
|
{
|
|
address = "fc00::2";
|
|
prefixLength = 120;
|
|
}
|
|
];
|
|
};
|
|
hosts = {
|
|
"fc00::1" = [ "db.test.example" ];
|
|
};
|
|
};
|
|
};
|
|
|
|
testScript = ''
|
|
server.wait_for_unit("multi-user.target")
|
|
client.wait_for_unit("multi-user.target")
|
|
client.succeed("psql -c \"SELECT 1;\"")
|
|
'';
|
|
};
|
|
in
|
|
genTests { inherit makeTestFor; }
|