summary refs log tree commit diff
diff options
context:
space:
mode:
authorMaximilian Bosch <maximilian@mbosch.me>2021-10-13 14:26:41 +0200
committerGitHub <noreply@github.com>2021-10-13 14:26:41 +0200
commiteb3a3725e43f7d9b3408555e18a7ecacf07148f0 (patch)
tree307fa0d2e0dbea11c956be62157bdcf5233ccc6d
parentbe5d1c3ca2cd5adc38a63b0c874e04d3ae943c17 (diff)
parent3498c5ff3c7e476298fa6730c90abec4871f0e9a (diff)
downloadnixpkgs-eb3a3725e43f7d9b3408555e18a7ecacf07148f0.tar
nixpkgs-eb3a3725e43f7d9b3408555e18a7ecacf07148f0.tar.gz
nixpkgs-eb3a3725e43f7d9b3408555e18a7ecacf07148f0.tar.bz2
nixpkgs-eb3a3725e43f7d9b3408555e18a7ecacf07148f0.tar.lz
nixpkgs-eb3a3725e43f7d9b3408555e18a7ecacf07148f0.tar.xz
nixpkgs-eb3a3725e43f7d9b3408555e18a7ecacf07148f0.tar.zst
nixpkgs-eb3a3725e43f7d9b3408555e18a7ecacf07148f0.zip
Merge pull request #119638 from beardhatcode/feat/nextcloud-packages
nextcloud: add option to set datadir and extensions
-rw-r--r--nixos/modules/services/web-apps/nextcloud.nix99
-rw-r--r--nixos/modules/services/web-apps/nextcloud.xml6
-rw-r--r--nixos/tests/nextcloud/basic.nix6
-rw-r--r--pkgs/build-support/fetchnextcloudapp/default.nix37
-rw-r--r--pkgs/top-level/all-packages.nix2
5 files changed, 142 insertions, 8 deletions
diff --git a/nixos/modules/services/web-apps/nextcloud.nix b/nixos/modules/services/web-apps/nextcloud.nix
index 4d7f16b1e1a..62ae763b69b 100644
--- a/nixos/modules/services/web-apps/nextcloud.nix
+++ b/nixos/modules/services/web-apps/nextcloud.nix
@@ -6,6 +6,8 @@ let
   cfg = config.services.nextcloud;
   fpm = config.services.phpfpm.pools.nextcloud;
 
+  inherit (cfg) datadir;
+
   phpPackage = cfg.phpPackage.buildEnv {
     extensions = { enabled, all }:
       (with all;
@@ -40,7 +42,7 @@ let
     if [[ "$USER" != nextcloud ]]; then
       sudo='exec /run/wrappers/bin/sudo -u nextcloud --preserve-env=NEXTCLOUD_CONFIG_DIR --preserve-env=OC_PASS'
     fi
-    export NEXTCLOUD_CONFIG_DIR="${cfg.home}/config"
+    export NEXTCLOUD_CONFIG_DIR="${datadir}/config"
     $sudo \
       ${phpPackage}/bin/php \
       occ "$@"
@@ -85,6 +87,59 @@ in {
       default = "/var/lib/nextcloud";
       description = "Storage path of nextcloud.";
     };
+    datadir = mkOption {
+      type = types.str;
+      defaultText = "config.services.nextcloud.home";
+      description = ''
+        Data storage path of nextcloud.  Will be <xref linkend="opt-services.nextcloud.home" /> by default.
+        This folder will be populated with a config.php and data folder which contains the state of the instance (excl the database).";
+      '';
+      example = "/mnt/nextcloud-file";
+    };
+    extraApps = mkOption {
+      type = types.attrsOf types.package;
+      default = { };
+      description = ''
+        Extra apps to install. Should be an attrSet of appid to packages generated by fetchNextcloudApp.
+        The appid must be identical to the "id" value in the apps appinfo/info.xml.
+        Using this will disable the appstore to prevent Nextcloud from updating these apps (see <xref linkend="opt-services.nextcloud.appstoreEnable" />).
+      '';
+      example = literalExpression ''
+        {
+          maps = pkgs.fetchNextcloudApp {
+            name = "maps";
+            sha256 = "007y80idqg6b6zk6kjxg4vgw0z8fsxs9lajnv49vv1zjy6jx2i1i";
+            url = "https://github.com/nextcloud/maps/releases/download/v0.1.9/maps-0.1.9.tar.gz";
+            version = "0.1.9";
+          };
+          phonetrack = pkgs.fetchNextcloudApp {
+            name = "phonetrack";
+            sha256 = "0qf366vbahyl27p9mshfma1as4nvql6w75zy2zk5xwwbp343vsbc";
+            url = "https://gitlab.com/eneiluj/phonetrack-oc/-/wikis/uploads/931aaaf8dca24bf31a7e169a83c17235/phonetrack-0.6.9.tar.gz";
+            version = "0.6.9";
+          };
+        }
+        '';
+    };
+    extraAppsEnable = mkOption {
+      type = types.bool;
+      default = true;
+      description = ''
+        Automatically enable the apps in <xref linkend="opt-services.nextcloud.extraApps" /> every time nextcloud starts.
+        If set to false, apps need to be enabled in the Nextcloud user interface or with nextcloud-occ app:enable.
+      '';
+    };
+    appstoreEnable = mkOption {
+      type = types.nullOr types.bool;
+      default = null;
+      example = true;
+      description = ''
+        Allow the installation of apps and app updates from the store.
+        Enabled by default unless there are packages in <xref linkend="opt-services.nextcloud.extraApps" />.
+        Set to true to force enable the store even if <xref linkend="opt-services.nextcloud.extraApps" /> is used.
+        Set to false to disable the installation of apps from the global appstore. App management is always enabled regardless of this setting.
+      '';
+    };
     logLevel = mkOption {
       type = types.ints.between 0 4;
       default = 2;
@@ -524,6 +579,8 @@ in {
           else nextcloud22
         );
 
+      services.nextcloud.datadir = mkOptionDefault config.services.nextcloud.home;
+
       services.nextcloud.phpPackage =
         if versionOlder cfg.package.version "21" then pkgs.php74
         else pkgs.php80;
@@ -563,6 +620,14 @@ in {
             ]
           '';
 
+          showAppStoreSetting = cfg.appstoreEnable != null || cfg.extraApps != {};
+          renderedAppStoreSetting =
+            let
+              x = cfg.appstoreEnable;
+            in
+              if x == null then "false"
+              else boolToString x;
+
           overrideConfig = pkgs.writeText "nextcloud-config.php" ''
             <?php
             ${optionalString requiresReadSecretFunction ''
@@ -581,10 +646,12 @@ in {
             ''}
             $CONFIG = [
               'apps_paths' => [
+                ${optionalString (cfg.extraApps != { }) "[ 'path' => '${cfg.home}/nix-apps', 'url' => '/nix-apps', 'writable' => false ],"}
                 [ 'path' => '${cfg.home}/apps', 'url' => '/apps', 'writable' => false ],
                 [ 'path' => '${cfg.home}/store-apps', 'url' => '/store-apps', 'writable' => true ],
               ],
-              'datadirectory' => '${cfg.home}/data',
+              ${optionalString (showAppStoreSetting) "'appstoreenabled' => ${renderedAppStoreSetting},"}
+              'datadirectory' => '${datadir}/data',
               'skeletondirectory' => '${cfg.skeletonDirectory}',
               ${optionalString cfg.caching.apcu "'memcache.local' => '\\OC\\Memcache\\APCu',"}
               'log_type' => 'syslog',
@@ -628,7 +695,7 @@ in {
               "--database-pass" = "\$${dbpass.arg}";
               "--admin-user" = ''"${c.adminuser}"'';
               "--admin-pass" = "\$${adminpass.arg}";
-              "--data-dir" = ''"${cfg.home}/data"'';
+              "--data-dir" = ''"${datadir}/data"'';
             });
           in ''
             ${mkExport dbpass}
@@ -670,9 +737,15 @@ in {
 
             ln -sf ${cfg.package}/apps ${cfg.home}/
 
+            # Install extra apps
+            ln -sfT \
+              ${pkgs.linkFarm "nix-apps"
+                (mapAttrsToList (name: path: { inherit name path; }) cfg.extraApps)} \
+              ${cfg.home}/nix-apps
+
             # create nextcloud directories.
             # if the directories exist already with wrong permissions, we fix that
-            for dir in ${cfg.home}/config ${cfg.home}/data ${cfg.home}/store-apps; do
+            for dir in ${datadir}/config ${datadir}/data ${cfg.home}/store-apps ${cfg.home}/nix-apps; do
               if [ ! -e $dir ]; then
                 install -o nextcloud -g nextcloud -d $dir
               elif [ $(stat -c "%G" $dir) != "nextcloud" ]; then
@@ -680,23 +753,29 @@ in {
               fi
             done
 
-            ln -sf ${overrideConfig} ${cfg.home}/config/override.config.php
+            ln -sf ${overrideConfig} ${datadir}/config/override.config.php
 
             # Do not install if already installed
-            if [[ ! -e ${cfg.home}/config/config.php ]]; then
+            if [[ ! -e ${datadir}/config/config.php ]]; then
               ${occInstallCmd}
             fi
 
             ${occ}/bin/nextcloud-occ upgrade
 
             ${occ}/bin/nextcloud-occ config:system:delete trusted_domains
+
+            ${optionalString (cfg.extraAppsEnable && cfg.extraApps != { }) ''
+                # Try to enable apps (don't fail when one of them cannot be enabled , eg. due to incompatible version)
+                ${occ}/bin/nextcloud-occ app:enable ${concatStringsSep " " (attrNames cfg.extraApps)}
+            ''}
+
             ${occSetTrustedDomainsCmd}
           '';
           serviceConfig.Type = "oneshot";
           serviceConfig.User = "nextcloud";
         };
         nextcloud-cron = {
-          environment.NEXTCLOUD_CONFIG_DIR = "${cfg.home}/config";
+          environment.NEXTCLOUD_CONFIG_DIR = "${datadir}/config";
           serviceConfig.Type = "oneshot";
           serviceConfig.User = "nextcloud";
           serviceConfig.ExecStart = "${phpPackage}/bin/php -f ${cfg.package}/cron.php";
@@ -715,7 +794,7 @@ in {
           group = "nextcloud";
           phpPackage = phpPackage;
           phpEnv = {
-            NEXTCLOUD_CONFIG_DIR = "${cfg.home}/config";
+            NEXTCLOUD_CONFIG_DIR = "${datadir}/config";
             PATH = "/run/wrappers/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:/usr/bin:/bin";
           };
           settings = mapAttrs (name: mkDefault) {
@@ -765,6 +844,10 @@ in {
             priority = 201;
             extraConfig = "root ${cfg.home};";
           };
+          "~ ^/nix-apps" = {
+            priority = 201;
+            extraConfig = "root ${cfg.home};";
+          };
           "^~ /.well-known" = {
             priority = 210;
             extraConfig = ''
diff --git a/nixos/modules/services/web-apps/nextcloud.xml b/nixos/modules/services/web-apps/nextcloud.xml
index ed84487d233..9d9cb8dfb3f 100644
--- a/nixos/modules/services/web-apps/nextcloud.xml
+++ b/nixos/modules/services/web-apps/nextcloud.xml
@@ -237,6 +237,12 @@
    Some apps may require extra PHP extensions to be installed.
    This can be configured with the <xref linkend="opt-services.nextcloud.phpExtraExtensions" /> setting.
   </para>
+
+  <para>
+   Alternatively, extra apps can also be declared with the <xref linkend="opt-services.nextcloud.extraApps" /> setting.
+   When using this setting, apps can no longer be managed statefully because this can lead to Nextcloud updating apps
+   that are managed by Nix. If you want automatic updates it is recommended that you use web interface to install apps.
+  </para>
  </section>
 
  <section xml:id="module-services-nextcloud-maintainer-info">
diff --git a/nixos/tests/nextcloud/basic.nix b/nixos/tests/nextcloud/basic.nix
index 1a7b25d5a49..eb37470a4c7 100644
--- a/nixos/tests/nextcloud/basic.nix
+++ b/nixos/tests/nextcloud/basic.nix
@@ -33,8 +33,13 @@ in {
     in {
       networking.firewall.allowedTCPPorts = [ 80 ];
 
+      systemd.tmpfiles.rules = [
+        "d /var/lib/nextcloud-data 0750 nextcloud nginx - -"
+      ];
+
       services.nextcloud = {
         enable = true;
+        datadir = "/var/lib/nextcloud-data";
         hostName = "nextcloud";
         config = {
           # Don't inherit adminuser since "root" is supposed to be the default
@@ -98,6 +103,7 @@ in {
         "${withRcloneEnv} ${copySharedFile}"
     )
     client.wait_for_unit("multi-user.target")
+    nextcloud.succeed("test -f /var/lib/nextcloud-data/data/root/files/test-shared-file")
     client.succeed(
         "${withRcloneEnv} ${diffSharedFile}"
     )
diff --git a/pkgs/build-support/fetchnextcloudapp/default.nix b/pkgs/build-support/fetchnextcloudapp/default.nix
new file mode 100644
index 00000000000..7fe5b35e259
--- /dev/null
+++ b/pkgs/build-support/fetchnextcloudapp/default.nix
@@ -0,0 +1,37 @@
+{ stdenv, gnutar, findutils, fetchurl, ... }:
+{ name
+, url
+, version
+, sha256
+, patches ? [ ]
+}:
+stdenv.mkDerivation {
+  name = "nc-app-${name}";
+  inherit version patches;
+
+  src = fetchurl {
+    inherit url sha256;
+  };
+
+  nativeBuildInputs = [
+    gnutar
+    findutils
+  ];
+
+  unpackPhase = ''
+    tar -xzpf $src
+  '';
+
+  installPhase = ''
+    approot="$(dirname $(dirname $(find -path '*/appinfo/info.xml' | head -n 1)))"
+
+    if [ -d "$approot" ];
+    then
+      mv "$approot/" $out
+      chmod -R a-w $out
+    else
+      echo "Could not find appinfo/info.xml"
+      exit 1;
+    fi
+  '';
+}
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 3087a472984..f3197712d39 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -520,6 +520,8 @@ with pkgs;
       tests = callPackages ../build-support/fetchfirefoxaddon/tests.nix { };
     };
 
+  fetchNextcloudApp = callPackage ../build-support/fetchnextcloudapp {};
+
   # `fetchurl' downloads a file from the network.
   fetchurl = if stdenv.buildPlatform != stdenv.hostPlatform
     then buildPackages.fetchurl # No need to do special overrides twice,