about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonas Heinrich <onny@project-insanity.org>2023-05-01 20:04:20 +0200
committerGitHub <noreply@github.com>2023-05-01 20:04:20 +0200
commitfcf6662fb579a0cfc0867296960a7c2eade3e3c4 (patch)
treee7ebd481f77ea1aa15ba9953727d18b20ce63548
parent1a0c498ee1f81fd06fdab35fd19639c860721b35 (diff)
parentfddf531c6fa3c769f70a4a0dfc4d886216f0107e (diff)
downloadnixlib-fcf6662fb579a0cfc0867296960a7c2eade3e3c4.tar
nixlib-fcf6662fb579a0cfc0867296960a7c2eade3e3c4.tar.gz
nixlib-fcf6662fb579a0cfc0867296960a7c2eade3e3c4.tar.bz2
nixlib-fcf6662fb579a0cfc0867296960a7c2eade3e3c4.tar.lz
nixlib-fcf6662fb579a0cfc0867296960a7c2eade3e3c4.tar.xz
nixlib-fcf6662fb579a0cfc0867296960a7c2eade3e3c4.tar.zst
nixlib-fcf6662fb579a0cfc0867296960a7c2eade3e3c4.zip
Merge pull request #229159 from Misterio77/refactor-nextcloud-createlocally
nixos/nextcloud: refactor database.createLocally
-rw-r--r--nixos/doc/manual/release-notes/rl-2305.section.md5
-rw-r--r--nixos/modules/services/web-apps/nextcloud.md34
-rw-r--r--nixos/modules/services/web-apps/nextcloud.nix63
-rw-r--r--nixos/tests/nextcloud/with-declarative-redis-and-secrets.nix43
-rw-r--r--nixos/tests/nextcloud/with-mysql-and-memcached.nix11
-rw-r--r--nixos/tests/nextcloud/with-postgresql-and-redis.nix20
6 files changed, 80 insertions, 96 deletions
diff --git a/nixos/doc/manual/release-notes/rl-2305.section.md b/nixos/doc/manual/release-notes/rl-2305.section.md
index 86e643f424f7..da4453b43e17 100644
--- a/nixos/doc/manual/release-notes/rl-2305.section.md
+++ b/nixos/doc/manual/release-notes/rl-2305.section.md
@@ -217,6 +217,11 @@ In addition to numerous new and upgraded packages, this release has the followin
 
 - The [services.wordpress.sites.&lt;name&gt;.plugins](#opt-services.wordpress.sites._name_.plugins) and [services.wordpress.sites.&lt;name&gt;.themes](#opt-services.wordpress.sites._name_.themes) options have been converted from sets to attribute sets to allow for consumers to specify explicit install paths via attribute name.
 
+- [`services.nextcloud.database.createLocally`](#opt-services.nextcloud.database.createLocally) now uses socket authentication and is no longer compatible with password authentication.
+  - If you want the module to manage the database for you, unset [`services.nextcloud.config.dbpassFile`](#opt-services.nextcloud.config.dbpassFile) (and [`services.nextcloud.config.dbhost`](#opt-services.nextcloud.config.dbhost), if it's set).
+  - If your database is external, simply set [`services.nextcloud.database.createLocally`](#opt-services.nextcloud.database.createLocally) to `false`.
+  - If you want to use password authentication **and** create the database locally, you will have to use [`services.mysql`](#opt-services.mysql.enable) to set it up.
+
 - `protonmail-bridge` package has been updated to major version 3.
 
 - Nebula now runs as a system user and group created for each nebula network, using the `CAP_NET_ADMIN` ambient capability on launch rather than starting as root. Ensure that any files each Nebula instance needs to access are owned by the correct user and group, by default `nebula-${networkName}`.
diff --git a/nixos/modules/services/web-apps/nextcloud.md b/nixos/modules/services/web-apps/nextcloud.md
index 15c1f2da2724..6ecfc6ca7e47 100644
--- a/nixos/modules/services/web-apps/nextcloud.md
+++ b/nixos/modules/services/web-apps/nextcloud.md
@@ -12,10 +12,16 @@ major version available.
 
 Nextcloud is a PHP-based application which requires an HTTP server
 ([`services.nextcloud`](#opt-services.nextcloud.enable)
-optionally supports
-[`services.nginx`](#opt-services.nginx.enable))
-and a database (it's recommended to use
-[`services.postgresql`](#opt-services.postgresql.enable)).
+and optionally supports
+[`services.nginx`](#opt-services.nginx.enable)).
+
+For the database, you can set
+[`services.nextcloud.config.dbtype`](#opt-services.nextcloud.config.dbtype) to
+either `sqlite` (the default), `mysql`, or `pgsql`. For the last two, by
+default, a local database will be created and nextcloud will connect to it via
+socket; this can be disabled by setting
+[`services.nextcloud.database.createLocally`](#opt-services.nextcloud.database.createLocally)
+to `false`.
 
 A very basic configuration may look like this:
 ```
@@ -26,30 +32,10 @@ A very basic configuration may look like this:
     hostName = "nextcloud.tld";
     config = {
       dbtype = "pgsql";
-      dbuser = "nextcloud";
-      dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself
-      dbname = "nextcloud";
       adminpassFile = "/path/to/admin-pass-file";
-      adminuser = "root";
     };
   };
 
-  services.postgresql = {
-    enable = true;
-    ensureDatabases = [ "nextcloud" ];
-    ensureUsers = [
-     { name = "nextcloud";
-       ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES";
-     }
-    ];
-  };
-
-  # ensure that postgres is running *before* running the setup
-  systemd.services."nextcloud-setup" = {
-    requires = ["postgresql.service"];
-    after = ["postgresql.service"];
-  };
-
   networking.firewall.allowedTCPPorts = [ 80 443 ];
 }
 ```
diff --git a/nixos/modules/services/web-apps/nextcloud.nix b/nixos/modules/services/web-apps/nextcloud.nix
index 2824b7ee2456..8edf270c8899 100644
--- a/nixos/modules/services/web-apps/nextcloud.nix
+++ b/nixos/modules/services/web-apps/nextcloud.nix
@@ -57,6 +57,9 @@ let
 
   inherit (config.system) stateVersion;
 
+  mysqlLocal = cfg.database.createLocally && cfg.config.dbtype == "mysql";
+  pgsqlLocal = cfg.database.createLocally && cfg.config.dbtype == "pgsql";
+
 in {
 
   imports = [
@@ -314,13 +317,9 @@ in {
 
       createLocally = mkOption {
         type = types.bool;
-        default = false;
+        default = true;
         description = lib.mdDoc ''
-          Create the database and database user locally. Only available for
-          mysql database.
-          Note that this option will use the latest version of MariaDB which
-          is not officially supported by Nextcloud. As for now a workaround
-          is used to also support MariaDB version >= 10.6.
+          Create the database and database user locally.
         '';
       };
 
@@ -352,12 +351,15 @@ in {
       };
       dbhost = mkOption {
         type = types.nullOr types.str;
-        default = "localhost";
+        default =
+          if pgsqlLocal then "/run/postgresql"
+          else if mysqlLocal then "localhost:/run/mysqld/mysqld.sock"
+          else "localhost";
+        defaultText = "localhost";
         description = lib.mdDoc ''
-          Database host.
-
-          Note: for using Unix authentication with PostgreSQL, this should be
-          set to `/run/postgresql`.
+          Database host or socket path. Defaults to the correct unix socket
+          instead if `services.nextcloud.database.createLocally` is true and
+          `services.nextcloud.config.dbtype` is either `pgsql` or `mysql`.
         '';
       };
       dbport = mkOption {
@@ -737,8 +739,22 @@ in {
     }
 
     { assertions = [
-      { assertion = cfg.database.createLocally -> cfg.config.dbtype == "mysql";
-        message = ''services.nextcloud.config.dbtype must be set to mysql if services.nextcloud.database.createLocally is set to true.'';
+      { assertion = cfg.database.createLocally -> cfg.config.dbpassFile == null;
+        message = ''
+          Using `services.nextcloud.database.createLocally` (that now defaults
+          to true) with database password authentication is no longer
+          supported.
+
+          If you use an external database (or want to use password auth for any
+          other reason), set `services.nextcloud.database.createLocally` to
+          `false`. The database won't be managed for you (use `services.mysql`
+          if you want to set it up).
+
+          If you want this module to manage your nextcloud database for you,
+          unset `services.nextcloud.config.dbpassFile` and
+          `services.nextcloud.config.dbhost` to use socket authentication
+          instead of password.
+        '';
       }
     ]; }
 
@@ -902,6 +918,8 @@ in {
         in {
           wantedBy = [ "multi-user.target" ];
           before = [ "phpfpm-nextcloud.service" ];
+          after = optional mysqlLocal "mysql.service" ++ optional pgsqlLocal "postgresql.service";
+          requires = optional mysqlLocal "mysql.service" ++ optional pgsqlLocal "postgresql.service";
           path = [ occ ];
           script = ''
             ${optionalString (c.dbpassFile != null) ''
@@ -1007,7 +1025,7 @@ in {
 
       environment.systemPackages = [ occ ];
 
-      services.mysql = lib.mkIf cfg.database.createLocally {
+      services.mysql = lib.mkIf mysqlLocal {
         enable = true;
         package = lib.mkDefault pkgs.mariadb;
         ensureDatabases = [ cfg.config.dbname ];
@@ -1015,14 +1033,15 @@ in {
           name = cfg.config.dbuser;
           ensurePermissions = { "${cfg.config.dbname}.*" = "ALL PRIVILEGES"; };
         }];
-        initialScript = pkgs.writeText "mysql-init" ''
-          CREATE USER '${cfg.config.dbname}'@'localhost' IDENTIFIED BY '${builtins.readFile( cfg.config.dbpassFile )}';
-          CREATE DATABASE IF NOT EXISTS ${cfg.config.dbname};
-          GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER,
-            CREATE TEMPORARY TABLES ON ${cfg.config.dbname}.* TO '${cfg.config.dbuser}'@'localhost'
-            IDENTIFIED BY '${builtins.readFile( cfg.config.dbpassFile )}';
-          FLUSH privileges;
-        '';
+      };
+
+      services.postgresql = mkIf pgsqlLocal {
+        enable = true;
+        ensureDatabases = [ cfg.config.dbname ];
+        ensureUsers = [{
+          name = cfg.config.dbuser;
+          ensurePermissions = { "DATABASE ${cfg.config.dbname}" = "ALL PRIVILEGES"; };
+        }];
       };
 
       services.nginx.enable = mkDefault true;
diff --git a/nixos/tests/nextcloud/with-declarative-redis-and-secrets.nix b/nixos/tests/nextcloud/with-declarative-redis-and-secrets.nix
index 93e655c3056b..ce0019e9da4a 100644
--- a/nixos/tests/nextcloud/with-declarative-redis-and-secrets.nix
+++ b/nixos/tests/nextcloud/with-declarative-redis-and-secrets.nix
@@ -1,6 +1,11 @@
 import ../make-test-python.nix ({ pkgs, ...}: let
-  adminpass = "hunter2";
-  adminuser = "custom-admin-username";
+  username = "custom_admin_username";
+  # This will be used both for redis and postgresql
+  pass = "hunter2";
+  # Don't do this at home, use a file outside of the nix store instead
+  passFile = toString (pkgs.writeText "pass-file" ''
+    ${pass}
+  '');
 in {
   name = "nextcloud-with-declarative-redis";
   meta = with pkgs.lib.maintainers; {
@@ -22,15 +27,15 @@ in {
           redis = true;
           memcached = false;
         };
+        # This test also validates that we can use an "external" database
+        database.createLocally = false;
         config = {
           dbtype = "pgsql";
           dbname = "nextcloud";
-          dbuser = "nextcloud";
-          dbhost = "/run/postgresql";
-          inherit adminuser;
-          adminpassFile = toString (pkgs.writeText "admin-pass-file" ''
-            ${adminpass}
-          '');
+          dbuser = username;
+          dbpassFile = passFile;
+          adminuser = username;
+          adminpassFile = passFile;
         };
         secretFile = "/etc/nextcloud-secrets.json";
 
@@ -52,20 +57,20 @@ in {
 
       systemd.services.nextcloud-setup= {
         requires = ["postgresql.service"];
-        after = [
-          "postgresql.service"
-        ];
+        after = [ "postgresql.service" ];
       };
 
       services.postgresql = {
         enable = true;
-        ensureDatabases = [ "nextcloud" ];
-        ensureUsers = [
-          { name = "nextcloud";
-            ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES";
-          }
-        ];
       };
+      systemd.services.postgresql.postStart = pkgs.lib.mkAfter ''
+        password=$(cat ${passFile})
+        ${config.services.postgresql.package}/bin/psql <<EOF
+          CREATE ROLE ${username} WITH LOGIN PASSWORD '$password' CREATEDB;
+          CREATE DATABASE nextcloud;
+          GRANT ALL PRIVILEGES ON DATABASE nextcloud TO ${username};
+        EOF
+      '';
 
       # This file is meant to contain secret options which should
       # not go into the nix store. Here it is just used to set the
@@ -86,8 +91,8 @@ in {
       export RCLONE_CONFIG_NEXTCLOUD_TYPE=webdav
       export RCLONE_CONFIG_NEXTCLOUD_URL="http://nextcloud/remote.php/webdav/"
       export RCLONE_CONFIG_NEXTCLOUD_VENDOR="nextcloud"
-      export RCLONE_CONFIG_NEXTCLOUD_USER="${adminuser}"
-      export RCLONE_CONFIG_NEXTCLOUD_PASS="$(${pkgs.rclone}/bin/rclone obscure ${adminpass})"
+      export RCLONE_CONFIG_NEXTCLOUD_USER="${username}"
+      export RCLONE_CONFIG_NEXTCLOUD_PASS="$(${pkgs.rclone}/bin/rclone obscure ${pass})"
       "''${@}"
     '';
     copySharedFile = pkgs.writeScript "copy-shared-file" ''
diff --git a/nixos/tests/nextcloud/with-mysql-and-memcached.nix b/nixos/tests/nextcloud/with-mysql-and-memcached.nix
index 63e0e2c59639..f673e5e75d3b 100644
--- a/nixos/tests/nextcloud/with-mysql-and-memcached.nix
+++ b/nixos/tests/nextcloud/with-mysql-and-memcached.nix
@@ -26,24 +26,13 @@ in {
           redis = false;
           memcached = true;
         };
-        database.createLocally = true;
         config = {
           dbtype = "mysql";
-          dbname = "nextcloud";
-          dbuser = "nextcloud";
-          dbhost = "127.0.0.1";
-          dbport = 3306;
-          dbpassFile = "${pkgs.writeText "dbpass" "hunter2" }";
           # Don't inherit adminuser since "root" is supposed to be the default
           adminpassFile = "${pkgs.writeText "adminpass" adminpass}"; # Don't try this at home!
         };
       };
 
-      systemd.services.nextcloud-setup= {
-        requires = ["mysql.service"];
-        after = ["mysql.service"];
-      };
-
       services.memcached.enable = true;
     };
   };
diff --git a/nixos/tests/nextcloud/with-postgresql-and-redis.nix b/nixos/tests/nextcloud/with-postgresql-and-redis.nix
index d28c1bdfd6e1..43892d39e9f0 100644
--- a/nixos/tests/nextcloud/with-postgresql-and-redis.nix
+++ b/nixos/tests/nextcloud/with-postgresql-and-redis.nix
@@ -27,9 +27,6 @@ in {
         };
         config = {
           dbtype = "pgsql";
-          dbname = "nextcloud";
-          dbuser = "nextcloud";
-          dbhost = "/run/postgresql";
           inherit adminuser;
           adminpassFile = toString (pkgs.writeText "admin-pass-file" ''
             ${adminpass}
@@ -48,23 +45,6 @@ in {
 
       services.redis.servers."nextcloud".enable = true;
       services.redis.servers."nextcloud".port = 6379;
-
-      systemd.services.nextcloud-setup= {
-        requires = ["postgresql.service"];
-        after = [
-          "postgresql.service"
-        ];
-      };
-
-      services.postgresql = {
-        enable = true;
-        ensureDatabases = [ "nextcloud" ];
-        ensureUsers = [
-          { name = "nextcloud";
-            ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES";
-          }
-        ];
-      };
     };
   };