summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authordanbst <abcz2.uprola@gmail.com>2019-07-22 02:57:16 +0300
committerdanbst <abcz2.uprola@gmail.com>2019-07-23 21:56:26 +0300
commit92a015d35d0450708438f68466027707b18188bd (patch)
tree2244bb45863a8c40b9c411c9194a32699eb41739 /nixos
parent104f8a0e1a17a894b320f86add409d9aebb36fe4 (diff)
downloadnixpkgs-92a015d35d0450708438f68466027707b18188bd.tar
nixpkgs-92a015d35d0450708438f68466027707b18188bd.tar.gz
nixpkgs-92a015d35d0450708438f68466027707b18188bd.tar.bz2
nixpkgs-92a015d35d0450708438f68466027707b18188bd.tar.lz
nixpkgs-92a015d35d0450708438f68466027707b18188bd.tar.xz
nixpkgs-92a015d35d0450708438f68466027707b18188bd.tar.zst
nixpkgs-92a015d35d0450708438f68466027707b18188bd.zip
nixos/postgresql: support 0750 for data directory
This is rework of part of https://github.com/NixOS/nixpkgs/pull/46670.
My usecase was to be able to inspect PG datadir as wheel user.

PG11 now allows starting server with 0750 mask for data dir.
`groupAccess = true` now does this automatically. The only thing you have to do
is to set group ownership.

For PG10 and below, I've described a hack how this can be done. Before this PR
hack was impossible. The hack isn't ideal, because there is short
period of time when dir mode is 0700, so I didn't want to make it official.

Test/example is present too.
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/services/databases/postgresql.nix40
-rw-r--r--nixos/tests/postgresql.nix66
2 files changed, 101 insertions, 5 deletions
diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix
index bc47e7e1e0d..7dddebfc28d 100644
--- a/nixos/modules/services/databases/postgresql.nix
+++ b/nixos/modules/services/databases/postgresql.nix
@@ -38,6 +38,8 @@ let
       ${cfg.extraConfig}
     '';
 
+    dirMode = if cfg.groupAccess then "0750" else "0700";
+
 in
 
 {
@@ -80,6 +82,23 @@ in
         '';
       };
 
+      groupAccess = mkOption {
+        type = types.bool;
+        default = false;
+        example = true;
+        description = ''
+          Allow read access for group (0750 mask for data directory).
+          Supported only for PostgreSQL 11+. PostgreSQL 10 and lower doesn't
+          support starting server with 0750 mask, but a workaround like
+          <programlisting>
+          systemd.services.postgresql.postStart = lib.mkAfter '''
+            chmod 750 ''${config.services.postgresql.dataDir}
+          ''';
+          </programlisting>
+          may be used instead.
+        '';
+      };
+
       authentication = mkOption {
         type = types.lines;
         default = "";
@@ -240,6 +259,14 @@ in
 
   config = mkIf config.services.postgresql.enable {
 
+    assertions = [
+      { assertion = cfg.groupAccess -> builtins.compareVersions cfg.package.version "11.0" >= 0;
+        message = ''
+          'groupAccess' is not available for PostgreSQL < 11.
+        '';
+      }
+    ];
+
     services.postgresql.package =
       # Note: when changing the default, make it conditional on
       # ‘system.stateVersion’ to maintain compatibility with existing
@@ -287,9 +314,9 @@ in
           ''
             # Create data directory.
             if ! test -e ${cfg.dataDir}/PG_VERSION; then
-              mkdir -m 0700 -p ${cfg.dataDir}
+              mkdir -m ${dirMode} -p ${cfg.dataDir}
               rm -f ${cfg.dataDir}/*.conf
-              chown -R postgres:postgres ${cfg.dataDir}
+              chown -R postgres ${cfg.dataDir}
             fi
           ''; # */
 
@@ -297,7 +324,9 @@ in
           ''
             # Initialise the database.
             if ! test -e ${cfg.dataDir}/PG_VERSION; then
-              initdb -U ${cfg.superUser}
+              initdb -U ${cfg.superUser} ${
+                lib.optionalString cfg.groupAccess "--allow-group-access"
+              }
               # See postStart!
               touch "${cfg.dataDir}/.first_startup"
             fi
@@ -306,8 +335,9 @@ in
               ln -sfn "${pkgs.writeText "recovery.conf" cfg.recoveryConfig}" \
                 "${cfg.dataDir}/recovery.conf"
             ''}
+            chmod ${dirMode} "${cfg.dataDir}"
 
-             exec postgres
+            exec postgres
           '';
 
         serviceConfig =
@@ -365,5 +395,5 @@ in
   };
 
   meta.doc = ./postgresql.xml;
-  meta.maintainers = with lib.maintainers; [ thoughtpolice ];
+  meta.maintainers = with lib.maintainers; [ thoughtpolice danbst ];
 }
diff --git a/nixos/tests/postgresql.nix b/nixos/tests/postgresql.nix
index ae5d6d095ea..81ec4d698b6 100644
--- a/nixos/tests/postgresql.nix
+++ b/nixos/tests/postgresql.nix
@@ -69,5 +69,71 @@ let
 in
   (mapAttrs' (name: package: { inherit name; value=make-postgresql-test name package false;}) postgresql-versions) // {
     postgresql_11-backup-all = make-postgresql-test "postgresql_11-backup-all" postgresql-versions.postgresql_11 true;
+
+    postgresql_dirmode_change =
+      let dataDir = "/db";
+    in makeTest {
+      name = "postgresql_dirmode_change";
+      meta = with pkgs.stdenv.lib.maintainers; {
+        maintainers = [ danbst ];
+      };
+
+      machine = { config, ...}:
+        {
+          services.postgresql.enable = true;
+          services.postgresql.package = pkgs.postgresql_11;
+          services.postgresql.dataDir = dataDir;
+
+          # users.groups.backup = {};
+          users.users.backup.isNormalUser = true;
+          users.users.backup.group = "wheel";
+
+          systemd.tmpfiles.rules = [
+            "d ${dataDir} 0750 postgres wheel -"
+          ];
+
+          nesting.clone = [
+            {
+              services.postgresql.groupAccess = true;
+            }
+
+            ({ config, lib, ... }: {
+              services.postgresql.package = lib.mkForce pkgs.postgresql_10;
+              services.postgresql.dataDir = lib.mkForce (dataDir + "_10");
+              systemd.tmpfiles.rules = [
+                "d ${dataDir}_10 0750 postgres wheel -"
+              ];
+              systemd.services.postgresql.postStart = lib.mkAfter ''
+                chmod 750 ${config.services.postgresql.dataDir}
+              '';
+            })
+          ];
+        };
+    testScript = { nodes, ... }: let
+      c1 = "${nodes.machine.config.system.build.toplevel}/fine-tune/child-1";
+      c2 = "${nodes.machine.config.system.build.toplevel}/fine-tune/child-2";
+    in ''
+      $machine->start;
+      $machine->waitForUnit("postgresql");
+      $machine->succeed("echo select 1 | sudo -u postgres psql");
+
+      # by default, mode is 0700
+      $machine->fail("sudo -u backup ls ${dataDir}");
+
+      $machine->succeed("${c1}/bin/switch-to-configuration test >&2");
+      $machine->succeed("journalctl -u postgresql | grep -q -i stopped"); # was restarted
+      $machine->succeed("echo select 1 | sudo -u postgres psql"); # works after restart
+      $machine->succeed("sudo -u backup ls ${dataDir}");
+
+      # This tests a hack for PG <11: restore permissions to 0700 just before PG starts
+      # and put it back to 0750 after PG had started
+      $machine->succeed("${c2}/bin/switch-to-configuration test >&2");
+      $machine->succeed("systemctl restart postgresql");
+      $machine->waitForUnit("postgresql");   # works after restart
+      $machine->succeed("sudo -u backup ls ${dataDir}_10");
+
+      $machine->shutdown;
+    '';
+    };
   }