1args@{ nextcloudVersion ? 27, ... }:
2(import ../make-test-python.nix ({ pkgs, ...}: let
3 adminuser = "custom_admin_username";
4 # This will be used both for redis and postgresql
5 pass = "hunter2";
6 # Don't do this at home, use a file outside of the nix store instead
7 passFile = toString (pkgs.writeText "pass-file" ''
8 ${pass}
9 '');
10in {
11 name = "nextcloud-with-declarative-redis";
12 meta = with pkgs.lib.maintainers; {
13 maintainers = [ eqyiel ma27 ];
14 };
15
16 nodes = {
17 # The only thing the client needs to do is download a file.
18 client = { ... }: {};
19
20 nextcloud = { config, pkgs, ... }: {
21 networking.firewall.allowedTCPPorts = [ 80 ];
22
23 services.nextcloud = {
24 enable = true;
25 hostName = "nextcloud";
26 package = pkgs.${"nextcloud" + (toString nextcloudVersion)};
27 caching = {
28 apcu = false;
29 redis = true;
30 memcached = false;
31 };
32 # This test also validates that we can use an "external" database
33 database.createLocally = false;
34 config = {
35 dbtype = "pgsql";
36 dbname = "nextcloud";
37 dbuser = adminuser;
38 dbpassFile = passFile;
39 adminuser = adminuser;
40 adminpassFile = passFile;
41 };
42 secretFile = "/etc/nextcloud-secrets.json";
43
44 extraOptions.redis = {
45 dbindex = 0;
46 timeout = 1.5;
47 # password handled via secretfile below
48 };
49 configureRedis = true;
50 };
51
52 services.redis.servers."nextcloud" = {
53 enable = true;
54 port = 6379;
55 requirePass = "secret";
56 };
57
58 systemd.services.nextcloud-setup= {
59 requires = ["postgresql.service"];
60 after = [ "postgresql.service" ];
61 };
62
63 services.postgresql = {
64 enable = true;
65 };
66 systemd.services.postgresql.postStart = pkgs.lib.mkAfter ''
67 password=$(cat ${passFile})
68 ${config.services.postgresql.package}/bin/psql <<EOF
69 CREATE ROLE ${adminuser} WITH LOGIN PASSWORD '$password' CREATEDB;
70 CREATE DATABASE nextcloud;
71 GRANT ALL PRIVILEGES ON DATABASE nextcloud TO ${adminuser};
72 EOF
73 '';
74
75 # This file is meant to contain secret options which should
76 # not go into the nix store. Here it is just used to set the
77 # redis password.
78 environment.etc."nextcloud-secrets.json".text = ''
79 {
80 "redis": {
81 "password": "secret"
82 }
83 }
84 '';
85 };
86 };
87
88 testScript = let
89 withRcloneEnv = pkgs.writeScript "with-rclone-env" ''
90 #!${pkgs.runtimeShell}
91 export RCLONE_CONFIG_NEXTCLOUD_TYPE=webdav
92 export RCLONE_CONFIG_NEXTCLOUD_URL="http://nextcloud/remote.php/dav/files/${adminuser}"
93 export RCLONE_CONFIG_NEXTCLOUD_VENDOR="nextcloud"
94 export RCLONE_CONFIG_NEXTCLOUD_USER="${adminuser}"
95 export RCLONE_CONFIG_NEXTCLOUD_PASS="$(${pkgs.rclone}/bin/rclone obscure ${pass})"
96 "''${@}"
97 '';
98 copySharedFile = pkgs.writeScript "copy-shared-file" ''
99 #!${pkgs.runtimeShell}
100 echo 'hi' | ${pkgs.rclone}/bin/rclone rcat nextcloud:test-shared-file
101 '';
102
103 diffSharedFile = pkgs.writeScript "diff-shared-file" ''
104 #!${pkgs.runtimeShell}
105 diff <(echo 'hi') <(${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file)
106 '';
107 in ''
108 start_all()
109 nextcloud.wait_for_unit("multi-user.target")
110 nextcloud.succeed("curl -sSf http://nextcloud/login")
111 nextcloud.succeed(
112 "${withRcloneEnv} ${copySharedFile}"
113 )
114 client.wait_for_unit("multi-user.target")
115 client.succeed(
116 "${withRcloneEnv} ${diffSharedFile}"
117 )
118
119 # redis cache should not be empty
120 nextcloud.fail('test "[]" = "$(redis-cli --json KEYS "*")"')
121 '';
122})) args