lol

Merge pull request #229159 from Misterio77/refactor-nextcloud-createlocally

nixos/nextcloud: refactor database.createLocally

authored by

Jonas Heinrich and committed by
GitHub
fcf6662f 1a0c498e

+80 -96
+5
nixos/doc/manual/release-notes/rl-2305.section.md
··· 217 217 218 218 - The [services.wordpress.sites.<name>.plugins](#opt-services.wordpress.sites._name_.plugins) and [services.wordpress.sites.<name>.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. 219 219 220 + - [`services.nextcloud.database.createLocally`](#opt-services.nextcloud.database.createLocally) now uses socket authentication and is no longer compatible with password authentication. 221 + - 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). 222 + - If your database is external, simply set [`services.nextcloud.database.createLocally`](#opt-services.nextcloud.database.createLocally) to `false`. 223 + - 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. 224 + 220 225 - `protonmail-bridge` package has been updated to major version 3. 221 226 222 227 - 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}`.
+10 -24
nixos/modules/services/web-apps/nextcloud.md
··· 12 12 13 13 Nextcloud is a PHP-based application which requires an HTTP server 14 14 ([`services.nextcloud`](#opt-services.nextcloud.enable) 15 - optionally supports 16 - [`services.nginx`](#opt-services.nginx.enable)) 17 - and a database (it's recommended to use 18 - [`services.postgresql`](#opt-services.postgresql.enable)). 15 + and optionally supports 16 + [`services.nginx`](#opt-services.nginx.enable)). 17 + 18 + For the database, you can set 19 + [`services.nextcloud.config.dbtype`](#opt-services.nextcloud.config.dbtype) to 20 + either `sqlite` (the default), `mysql`, or `pgsql`. For the last two, by 21 + default, a local database will be created and nextcloud will connect to it via 22 + socket; this can be disabled by setting 23 + [`services.nextcloud.database.createLocally`](#opt-services.nextcloud.database.createLocally) 24 + to `false`. 19 25 20 26 A very basic configuration may look like this: 21 27 ``` ··· 26 32 hostName = "nextcloud.tld"; 27 33 config = { 28 34 dbtype = "pgsql"; 29 - dbuser = "nextcloud"; 30 - dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself 31 - dbname = "nextcloud"; 32 35 adminpassFile = "/path/to/admin-pass-file"; 33 - adminuser = "root"; 34 36 }; 35 - }; 36 - 37 - services.postgresql = { 38 - enable = true; 39 - ensureDatabases = [ "nextcloud" ]; 40 - ensureUsers = [ 41 - { name = "nextcloud"; 42 - ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES"; 43 - } 44 - ]; 45 - }; 46 - 47 - # ensure that postgres is running *before* running the setup 48 - systemd.services."nextcloud-setup" = { 49 - requires = ["postgresql.service"]; 50 - after = ["postgresql.service"]; 51 37 }; 52 38 53 39 networking.firewall.allowedTCPPorts = [ 80 443 ];
+41 -22
nixos/modules/services/web-apps/nextcloud.nix
··· 57 57 58 58 inherit (config.system) stateVersion; 59 59 60 + mysqlLocal = cfg.database.createLocally && cfg.config.dbtype == "mysql"; 61 + pgsqlLocal = cfg.database.createLocally && cfg.config.dbtype == "pgsql"; 62 + 60 63 in { 61 64 62 65 imports = [ ··· 314 317 315 318 createLocally = mkOption { 316 319 type = types.bool; 317 - default = false; 320 + default = true; 318 321 description = lib.mdDoc '' 319 - Create the database and database user locally. Only available for 320 - mysql database. 321 - Note that this option will use the latest version of MariaDB which 322 - is not officially supported by Nextcloud. As for now a workaround 323 - is used to also support MariaDB version >= 10.6. 322 + Create the database and database user locally. 324 323 ''; 325 324 }; 326 325 ··· 352 351 }; 353 352 dbhost = mkOption { 354 353 type = types.nullOr types.str; 355 - default = "localhost"; 354 + default = 355 + if pgsqlLocal then "/run/postgresql" 356 + else if mysqlLocal then "localhost:/run/mysqld/mysqld.sock" 357 + else "localhost"; 358 + defaultText = "localhost"; 356 359 description = lib.mdDoc '' 357 - Database host. 358 - 359 - Note: for using Unix authentication with PostgreSQL, this should be 360 - set to `/run/postgresql`. 360 + Database host or socket path. Defaults to the correct unix socket 361 + instead if `services.nextcloud.database.createLocally` is true and 362 + `services.nextcloud.config.dbtype` is either `pgsql` or `mysql`. 361 363 ''; 362 364 }; 363 365 dbport = mkOption { ··· 737 739 } 738 740 739 741 { assertions = [ 740 - { assertion = cfg.database.createLocally -> cfg.config.dbtype == "mysql"; 741 - message = ''services.nextcloud.config.dbtype must be set to mysql if services.nextcloud.database.createLocally is set to true.''; 742 + { assertion = cfg.database.createLocally -> cfg.config.dbpassFile == null; 743 + message = '' 744 + Using `services.nextcloud.database.createLocally` (that now defaults 745 + to true) with database password authentication is no longer 746 + supported. 747 + 748 + If you use an external database (or want to use password auth for any 749 + other reason), set `services.nextcloud.database.createLocally` to 750 + `false`. The database won't be managed for you (use `services.mysql` 751 + if you want to set it up). 752 + 753 + If you want this module to manage your nextcloud database for you, 754 + unset `services.nextcloud.config.dbpassFile` and 755 + `services.nextcloud.config.dbhost` to use socket authentication 756 + instead of password. 757 + ''; 742 758 } 743 759 ]; } 744 760 ··· 902 918 in { 903 919 wantedBy = [ "multi-user.target" ]; 904 920 before = [ "phpfpm-nextcloud.service" ]; 921 + after = optional mysqlLocal "mysql.service" ++ optional pgsqlLocal "postgresql.service"; 922 + requires = optional mysqlLocal "mysql.service" ++ optional pgsqlLocal "postgresql.service"; 905 923 path = [ occ ]; 906 924 script = '' 907 925 ${optionalString (c.dbpassFile != null) '' ··· 1007 1025 1008 1026 environment.systemPackages = [ occ ]; 1009 1027 1010 - services.mysql = lib.mkIf cfg.database.createLocally { 1028 + services.mysql = lib.mkIf mysqlLocal { 1011 1029 enable = true; 1012 1030 package = lib.mkDefault pkgs.mariadb; 1013 1031 ensureDatabases = [ cfg.config.dbname ]; ··· 1015 1033 name = cfg.config.dbuser; 1016 1034 ensurePermissions = { "${cfg.config.dbname}.*" = "ALL PRIVILEGES"; }; 1017 1035 }]; 1018 - initialScript = pkgs.writeText "mysql-init" '' 1019 - CREATE USER '${cfg.config.dbname}'@'localhost' IDENTIFIED BY '${builtins.readFile( cfg.config.dbpassFile )}'; 1020 - CREATE DATABASE IF NOT EXISTS ${cfg.config.dbname}; 1021 - GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, 1022 - CREATE TEMPORARY TABLES ON ${cfg.config.dbname}.* TO '${cfg.config.dbuser}'@'localhost' 1023 - IDENTIFIED BY '${builtins.readFile( cfg.config.dbpassFile )}'; 1024 - FLUSH privileges; 1025 - ''; 1036 + }; 1037 + 1038 + services.postgresql = mkIf pgsqlLocal { 1039 + enable = true; 1040 + ensureDatabases = [ cfg.config.dbname ]; 1041 + ensureUsers = [{ 1042 + name = cfg.config.dbuser; 1043 + ensurePermissions = { "DATABASE ${cfg.config.dbname}" = "ALL PRIVILEGES"; }; 1044 + }]; 1026 1045 }; 1027 1046 1028 1047 services.nginx.enable = mkDefault true;
+24 -19
nixos/tests/nextcloud/with-declarative-redis-and-secrets.nix
··· 1 1 import ../make-test-python.nix ({ pkgs, ...}: let 2 - adminpass = "hunter2"; 3 - adminuser = "custom-admin-username"; 2 + username = "custom_admin_username"; 3 + # This will be used both for redis and postgresql 4 + pass = "hunter2"; 5 + # Don't do this at home, use a file outside of the nix store instead 6 + passFile = toString (pkgs.writeText "pass-file" '' 7 + ${pass} 8 + ''); 4 9 in { 5 10 name = "nextcloud-with-declarative-redis"; 6 11 meta = with pkgs.lib.maintainers; { ··· 22 27 redis = true; 23 28 memcached = false; 24 29 }; 30 + # This test also validates that we can use an "external" database 31 + database.createLocally = false; 25 32 config = { 26 33 dbtype = "pgsql"; 27 34 dbname = "nextcloud"; 28 - dbuser = "nextcloud"; 29 - dbhost = "/run/postgresql"; 30 - inherit adminuser; 31 - adminpassFile = toString (pkgs.writeText "admin-pass-file" '' 32 - ${adminpass} 33 - ''); 35 + dbuser = username; 36 + dbpassFile = passFile; 37 + adminuser = username; 38 + adminpassFile = passFile; 34 39 }; 35 40 secretFile = "/etc/nextcloud-secrets.json"; 36 41 ··· 52 57 53 58 systemd.services.nextcloud-setup= { 54 59 requires = ["postgresql.service"]; 55 - after = [ 56 - "postgresql.service" 57 - ]; 60 + after = [ "postgresql.service" ]; 58 61 }; 59 62 60 63 services.postgresql = { 61 64 enable = true; 62 - ensureDatabases = [ "nextcloud" ]; 63 - ensureUsers = [ 64 - { name = "nextcloud"; 65 - ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES"; 66 - } 67 - ]; 68 65 }; 66 + systemd.services.postgresql.postStart = pkgs.lib.mkAfter '' 67 + password=$(cat ${passFile}) 68 + ${config.services.postgresql.package}/bin/psql <<EOF 69 + CREATE ROLE ${username} WITH LOGIN PASSWORD '$password' CREATEDB; 70 + CREATE DATABASE nextcloud; 71 + GRANT ALL PRIVILEGES ON DATABASE nextcloud TO ${username}; 72 + EOF 73 + ''; 69 74 70 75 # This file is meant to contain secret options which should 71 76 # not go into the nix store. Here it is just used to set the ··· 86 91 export RCLONE_CONFIG_NEXTCLOUD_TYPE=webdav 87 92 export RCLONE_CONFIG_NEXTCLOUD_URL="http://nextcloud/remote.php/webdav/" 88 93 export RCLONE_CONFIG_NEXTCLOUD_VENDOR="nextcloud" 89 - export RCLONE_CONFIG_NEXTCLOUD_USER="${adminuser}" 90 - export RCLONE_CONFIG_NEXTCLOUD_PASS="$(${pkgs.rclone}/bin/rclone obscure ${adminpass})" 94 + export RCLONE_CONFIG_NEXTCLOUD_USER="${username}" 95 + export RCLONE_CONFIG_NEXTCLOUD_PASS="$(${pkgs.rclone}/bin/rclone obscure ${pass})" 91 96 "''${@}" 92 97 ''; 93 98 copySharedFile = pkgs.writeScript "copy-shared-file" ''
-11
nixos/tests/nextcloud/with-mysql-and-memcached.nix
··· 26 26 redis = false; 27 27 memcached = true; 28 28 }; 29 - database.createLocally = true; 30 29 config = { 31 30 dbtype = "mysql"; 32 - dbname = "nextcloud"; 33 - dbuser = "nextcloud"; 34 - dbhost = "127.0.0.1"; 35 - dbport = 3306; 36 - dbpassFile = "${pkgs.writeText "dbpass" "hunter2" }"; 37 31 # Don't inherit adminuser since "root" is supposed to be the default 38 32 adminpassFile = "${pkgs.writeText "adminpass" adminpass}"; # Don't try this at home! 39 33 }; 40 - }; 41 - 42 - systemd.services.nextcloud-setup= { 43 - requires = ["mysql.service"]; 44 - after = ["mysql.service"]; 45 34 }; 46 35 47 36 services.memcached.enable = true;
-20
nixos/tests/nextcloud/with-postgresql-and-redis.nix
··· 27 27 }; 28 28 config = { 29 29 dbtype = "pgsql"; 30 - dbname = "nextcloud"; 31 - dbuser = "nextcloud"; 32 - dbhost = "/run/postgresql"; 33 30 inherit adminuser; 34 31 adminpassFile = toString (pkgs.writeText "admin-pass-file" '' 35 32 ${adminpass} ··· 48 45 49 46 services.redis.servers."nextcloud".enable = true; 50 47 services.redis.servers."nextcloud".port = 6379; 51 - 52 - systemd.services.nextcloud-setup= { 53 - requires = ["postgresql.service"]; 54 - after = [ 55 - "postgresql.service" 56 - ]; 57 - }; 58 - 59 - services.postgresql = { 60 - enable = true; 61 - ensureDatabases = [ "nextcloud" ]; 62 - ensureUsers = [ 63 - { name = "nextcloud"; 64 - ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES"; 65 - } 66 - ]; 67 - }; 68 48 }; 69 49 }; 70 50