nixos/postgresql: don't create postgresql-setup if no setup is needed
Also add postgresql replication test Fixes #469859
This commit is contained in:
@@ -911,6 +911,12 @@ in
|
||||
|
||||
# Wait for PostgreSQL to be ready to accept connections.
|
||||
script = ''
|
||||
# If we're in standby mode, don't perform any setup
|
||||
if [[ -f "${cfg.dataDir}/standby.signal" ]]; then
|
||||
echo "Skipping setup because PostgreSQL is in standby mode"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
check-connection() {
|
||||
psql -d postgres -v ON_ERROR_STOP=1 <<-' EOF'
|
||||
SELECT pg_is_in_recovery() \gset
|
||||
|
||||
@@ -31,6 +31,7 @@ in
|
||||
# postgresql
|
||||
postgresql = importWithArgs ./postgresql.nix;
|
||||
postgresql-jit = importWithArgs ./postgresql-jit.nix;
|
||||
postgresql-replication = importWithArgs ./postgresql-replication.nix;
|
||||
postgresql-wal-receiver = importWithArgs ./postgresql-wal-receiver.nix;
|
||||
postgresql-tls-client-cert = importWithArgs ./postgresql-tls-client-cert.nix;
|
||||
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
{
|
||||
pkgs,
|
||||
makeTest,
|
||||
genTests,
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
|
||||
makeTestFor =
|
||||
package:
|
||||
makeTest {
|
||||
name = "postgresql-replication-${package.name}";
|
||||
meta.maintainers = with lib.maintainers; [ bouk ];
|
||||
|
||||
nodes = {
|
||||
primary =
|
||||
{ ... }:
|
||||
{
|
||||
services.postgresql = {
|
||||
inherit package;
|
||||
enable = true;
|
||||
enableTCPIP = true;
|
||||
settings = {
|
||||
wal_level = "replica";
|
||||
max_wal_senders = 10;
|
||||
max_replication_slots = 10;
|
||||
};
|
||||
authentication = ''
|
||||
local replication postgres peer
|
||||
host replication replication all trust
|
||||
'';
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "replication";
|
||||
ensureClauses.replication = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 5432 ];
|
||||
};
|
||||
|
||||
replica =
|
||||
{ nodes, ... }:
|
||||
{
|
||||
services.postgresql = {
|
||||
inherit package;
|
||||
enable = true;
|
||||
settings = {
|
||||
hot_standby = "on";
|
||||
primary_conninfo = "host=${nodes.primary.networking.primaryIPAddress} user=replication";
|
||||
primary_slot_name = "replica_slot";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
primary.wait_for_unit("postgresql.target")
|
||||
|
||||
primary.succeed(
|
||||
"sudo -u postgres psql -c \"SELECT * FROM pg_create_physical_replication_slot('replica_slot');\""
|
||||
)
|
||||
|
||||
primary.succeed(
|
||||
"sudo -u postgres pg_basebackup -D /tmp/basebackup -S replica_slot -X stream"
|
||||
)
|
||||
primary.succeed("tar -C /tmp -cf /tmp/shared/basebackup.tar basebackup")
|
||||
|
||||
replica.wait_for_unit("postgresql.target")
|
||||
replica.succeed("systemctl stop postgresql")
|
||||
|
||||
replica_data_dir = "/var/lib/postgresql/${package.psqlSchema}"
|
||||
replica.succeed(f"rm -rf {replica_data_dir}")
|
||||
replica.succeed(f"mkdir -p {replica_data_dir}")
|
||||
replica.succeed(f"tar -C {replica_data_dir} --strip-components=1 -xf /tmp/shared/basebackup.tar")
|
||||
replica.succeed(f"touch {replica_data_dir}/standby.signal")
|
||||
replica.succeed(f"chown -R postgres:postgres {replica_data_dir}")
|
||||
replica.succeed(f"chmod 700 {replica_data_dir}")
|
||||
|
||||
replica.succeed("systemctl start postgresql")
|
||||
replica.wait_for_unit("postgresql.target")
|
||||
|
||||
replica.wait_until_succeeds(
|
||||
"sudo -u postgres psql -tAc 'SELECT pg_is_in_recovery();' | grep t"
|
||||
)
|
||||
|
||||
primary.succeed(
|
||||
"sudo -u postgres psql -c 'CREATE TABLE test_replication (id serial PRIMARY KEY, data text);'"
|
||||
)
|
||||
primary.succeed(
|
||||
"sudo -u postgres psql -c \"INSERT INTO test_replication (data) VALUES ('hello');\""
|
||||
)
|
||||
|
||||
replica.wait_until_succeeds(
|
||||
"sudo -u postgres psql -c 'SELECT * FROM test_replication;' | grep hello",
|
||||
timeout=30
|
||||
)
|
||||
|
||||
with subtest("Verify replica is in recovery mode"):
|
||||
result = replica.succeed("sudo -u postgres psql -tAc 'SELECT pg_is_in_recovery();'")
|
||||
t.assertEqual(result.strip(), "t")
|
||||
|
||||
with subtest("Verify replication slot is active"):
|
||||
result = primary.succeed(
|
||||
"sudo -u postgres psql -tAc \"SELECT active FROM pg_replication_slots WHERE slot_name = 'replica_slot';\""
|
||||
)
|
||||
t.assertEqual(result.strip(), "t")
|
||||
|
||||
with subtest("Insert more data and verify replication"):
|
||||
primary.succeed(
|
||||
"sudo -u postgres psql -c \"INSERT INTO test_replication (data) VALUES ('world');\""
|
||||
)
|
||||
replica.wait_until_succeeds(
|
||||
"sudo -u postgres psql -c 'SELECT * FROM test_replication;' | grep world",
|
||||
timeout=30
|
||||
)
|
||||
|
||||
primary.shutdown()
|
||||
replica.shutdown()
|
||||
'';
|
||||
};
|
||||
in
|
||||
genTests { inherit makeTestFor; }
|
||||
@@ -612,6 +612,7 @@ let
|
||||
|
||||
tests = {
|
||||
postgresql = nixosTests.postgresql.postgresql.passthru.override finalAttrs.finalPackage;
|
||||
postgresql-replication = nixosTests.postgresql.postgresql-replication.passthru.override finalAttrs.finalPackage;
|
||||
postgresql-tls-client-cert = nixosTests.postgresql.postgresql-tls-client-cert.passthru.override finalAttrs.finalPackage;
|
||||
postgresql-wal-receiver = nixosTests.postgresql.postgresql-wal-receiver.passthru.override finalAttrs.finalPackage;
|
||||
pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage;
|
||||
|
||||
Reference in New Issue
Block a user