Files
sp-config/postgresql/postgresql.nix

130 lines
3.8 KiB
Nix

{
config,
lib,
pkgs,
...
}:
let
sp = config.selfprivacy;
pleroma_location =
if
lib.attrsets.hasAttr "pleroma" sp.modules && lib.attrsets.hasAttr "location" sp.modules.pleroma
then
sp.modules.pleroma.location
else
null;
postgres_location =
if lib.attrsets.hasAttr "postgresql" sp && lib.attrsets.hasAttr "location" sp.postgresql then
sp.postgresql.location
else
null;
# Priority: postgresql > pleroma
location = if postgres_location != null then postgres_location else pleroma_location;
# Active if there is a location
enable = location != null;
pleroma_enabled =
if
lib.attrsets.hasAttr "pleroma" sp.modules && lib.attrsets.hasAttr "enable" sp.modules.pleroma
then
sp.modules.pleroma.enable
else
false;
in
{
imports = [
./upgrade12to16.nix
];
fileSystems = lib.mkIf enable {
"/var/lib/postgresql" = {
device = "/volumes/${location}/postgresql";
options = [
"bind"
"x-systemd.required-by=postgresql.service"
"x-systemd.required-by=postgresql-upgrade12to16.service"
"x-systemd.before=postgresql.service"
"x-systemd.before=postgresql-upgrade12to16.service"
];
};
"/var/lib/postgresql-dumps" = {
device = "/volumes/${location}/postgresql-dumps";
options = [ "bind" ];
};
};
services = {
postgresql = {
enable = enable;
package = pkgs.postgresql_16;
# Change to selfpirvacy-api user when API migrates to rootless daemon
authentication = ''
local all postgres peer map=selfprivacy-api
'';
identMap = ''
selfprivacy-api root postgres
selfprivacy-api postgres postgres
'';
};
postgresqlUpgrade12to16 = {
enable = false;
pleromaEnabled = pleroma_enabled;
};
};
systemd = {
services.postgresql = {
serviceConfig.Slice = "postgresql.slice";
serviceConfig.ExecStartPost = pkgs.writeShellScript "update-pg-collation" ''
export PATH="${config.services.postgresql.package}/bin:$PATH"
GLIBC_VERSION="${pkgs.glibc.version}"
check_mismatches() {
local query="
SELECT datname, datcollversion
FROM pg_database
WHERE datcollversion IS NOT NULL
AND datcollversion != '$GLIBC_VERSION'
AND datallowconn = true
AND datname NOT IN ('template0')
ORDER BY datname;
"
psql -c "$query" 2>/dev/null | grep -v '^$' || true
}
get_mismatched_databases() {
check_mismatches | while IFS='|' read -r dbname version; do
dbname=$(echo "$dbname" | xargs)
version=$(echo "$version" | xargs)
if [ "datname" != "$dbname" ] && [ -n "$dbname" ] && [ -n "$version" ]; then
echo "$dbname"
fi
done
}
fix_database() {
local dbname=$1
local current_version
current_version=$(psql --csv -c "SELECT datcollversion FROM pg_database WHERE datname = '$dbname';" | xargs)
if psql -d "$dbname" -c "REINDEX DATABASE \"$dbname\";" 2>/dev/null && psql -d "$dbname" -c "ALTER DATABASE \"$dbname\" REFRESH COLLATION VERSION;" 2>/dev/null; then
echo "update-collation: Successfully updated collation on DB $dbname ($current_version -> $GLIBC_VERSION)"
return 0
else
echo "update-collation: Failed to update collation on DB $dbname"
return 1
fi
}
dbs=$(get_mismatched_databases)
for dbname in $dbs; do
echo "update-collation: Updating $dbname"
fix_database $dbname
done
'';
};
slices.postgresql = {
description = "PostgreSQL slice";
};
};
}