diff --git a/test/vm/nextcloud.nix b/test/vm/nextcloud.nix index 76bc3ec..d2d96a4 100644 --- a/test/vm/nextcloud.nix +++ b/test/vm/nextcloud.nix @@ -4,10 +4,14 @@ let adminUser = "root"; adminPass = "rootpw"; + subdomain = "n"; + domain = "example.com"; + fqdn = "${subdomain}.${domain}"; + commonTestScript = { nodes, ... }: let hasSSL = !(isNull nodes.server.shb.nextcloud.ssl); - fqdn = if hasSSL then "https://n.example.com" else "http://n.example.com"; + proto_fqdn = if hasSSL then "https://${fqdn}" else "http://${fqdn}"; in '' import json @@ -31,14 +35,14 @@ let def curl(target, format, endpoint, succeed=True): return json.loads(target.succeed( "curl --fail-with-body --silent --show-error --output /dev/null --location" - + " --connect-to n.example.com:443:server:443" - + " --connect-to n.example.com:80:server:80" + + " --connect-to ${fqdn}:443:server:443" + + " --connect-to ${fqdn}:80:server:80" + f" --write-out '{format}'" + " " + endpoint )) with subtest("access"): - response = curl(client, """{"code":%{response_code}}""", "${fqdn}") + response = curl(client, """{"code":%{response_code}}""", "${proto_fqdn}") if response['code'] != 200: raise Exception(f"Code is {response['code']}") @@ -63,18 +67,18 @@ let "curl -f -s --location -X PROPFIND" + """ -H "Depth: 1" """ + """ -u ${adminUser}:other """ - + " --connect-to n.example.com:443:server:443" - + " --connect-to n.example.com:80:server:80" - + " ${fqdn}/remote.php/dav/files/${adminUser}/" + + " --connect-to ${fqdn}:443:server:443" + + " --connect-to ${fqdn}:80:server:80" + + " ${proto_fqdn}/remote.php/dav/files/${adminUser}/" ) client.fail( "curl -f -s --location -X PROPFIND" + """ -H "Depth: 1" """ + """ -u root:rootpw """ - + " --connect-to n.example.com:443:server:443" - + " --connect-to n.example.com:80:server:80" - + " ${fqdn}/remote.php/dav/files/other/" + + " --connect-to ${fqdn}:443:server:443" + + " --connect-to ${fqdn}:80:server:80" + + " ${proto_fqdn}/remote.php/dav/files/other/" ) with subtest("fails with incorrect path"): @@ -82,9 +86,9 @@ let "curl -f -s --location -X PROPFIND" + """ -H "Depth: 1" """ + """ -u ${adminUser}:${adminPass} """ - + " --connect-to n.example.com:443:server:443" - + " --connect-to n.example.com:80:server:80" - + " ${fqdn}/remote.php/dav/files/other/" + + " --connect-to ${fqdn}:443:server:443" + + " --connect-to ${fqdn}:80:server:80" + + " ${proto_fqdn}/remote.php/dav/files/other/" ) with subtest("can access webdav"): @@ -92,9 +96,9 @@ let "curl -f -s --location -X PROPFIND" + """ -H "Depth: 1" """ + """ -u ${adminUser}:${adminPass} """ - + " --connect-to n.example.com:443:server:443" - + " --connect-to n.example.com:80:server:80" - + " ${fqdn}/remote.php/dav/files/${adminUser}/" + + " --connect-to ${fqdn}:443:server:443" + + " --connect-to ${fqdn}:80:server:80" + + " ${proto_fqdn}/remote.php/dav/files/${adminUser}/" ) with subtest("can create and retrieve file"): @@ -102,134 +106,154 @@ let "curl -f -s --location -X GET" + """ -H "Depth: 1" """ + """ -u ${adminUser}:${adminPass} """ - + " --connect-to n.example.com:443:server:443" - + " --connect-to n.example.com:80:server:80" + + " --connect-to ${fqdn}:443:server:443" + + " --connect-to ${fqdn}:80:server:80" + """ -T file """ - + " ${fqdn}/remote.php/dav/files/${adminUser}/file" + + " ${proto_fqdn}/remote.php/dav/files/${adminUser}/file" ) client.succeed("echo 'hello' > file") client.succeed( "curl -f -s --location -X PUT" + """ -H "Depth: 1" """ + """ -u ${adminUser}:${adminPass} """ - + " --connect-to n.example.com:443:server:443" - + " --connect-to n.example.com:80:server:80" + + " --connect-to ${fqdn}:443:server:443" + + " --connect-to ${fqdn}:80:server:80" + """ -T file """ - + " ${fqdn}/remote.php/dav/files/${adminUser}/" + + " ${proto_fqdn}/remote.php/dav/files/${adminUser}/" ) content = client.succeed( "curl -f -s --location -X GET" + """ -H "Depth: 1" """ + """ -u ${adminUser}:${adminPass} """ - + " --connect-to n.example.com:443:server:443" - + " --connect-to n.example.com:80:server:80" + + " --connect-to ${fqdn}:443:server:443" + + " --connect-to ${fqdn}:80:server:80" + """ -T file """ - + " ${fqdn}/remote.php/dav/files/${adminUser}/file" + + " ${proto_fqdn}/remote.php/dav/files/${adminUser}/file" ) if content != "hello\n": raise Exception("Got incorrect content for file, expected 'hello\n' but got:\n{}".format(content)) ''; + + base = { + imports = [ + (pkgs'.path + "/nixos/modules/profiles/headless.nix") + (pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix") + { + options = { + shb.backup = lib.mkOption { type = lib.types.anything; }; + }; + } + ../../modules/services/nextcloud-server.nix + ]; + + # Nginx port. + networking.firewall.allowedTCPPorts = [ 80 443 ]; + }; + + certs = { config, ... }: { + imports = [ + ../../modules/blocks/ssl.nix + ]; + + shb.certs = { + cas.selfsigned.myca = { + name = "My CA"; + }; + certs.selfsigned = { + n = { + ca = config.shb.certs.cas.selfsigned.myca; + domain = "*.${domain}"; + group = "nginx"; + }; + }; + }; + + systemd.services.nginx.after = [ config.shb.certs.certs.selfsigned.n.systemdService ]; + systemd.services.nginx.requires = [ config.shb.certs.certs.selfsigned.n.systemdService ]; + }; + + basic = { config, ... }: { + shb.nextcloud = { + enable = true; + inherit domain subdomain; + dataDir = "/var/lib/nextcloud"; + tracing = null; + defaultPhoneRegion = "US"; + + # This option is only needed because we do not access Nextcloud at the default port in the VM. + externalFqdn = "${fqdn}:8080"; + + adminUser = adminUser; + adminPassFile = pkgs.writeText "adminPassFile" adminPass; + debug = true; + }; + }; + + https = { config, ...}: { + shb.nextcloud = { + ssl = config.shb.certs.certs.selfsigned.n; + + externalFqdn = lib.mkForce null; + }; + }; + + previewgenerator = { config, ...}: { + systemd.tmpfiles.rules = [ + "d '/srv/nextcloud' 0750 nextcloud nextcloud - -" + ]; + + shb.nextcloud = { + apps.previewgenerator.enable = true; + }; + }; + + externalstorage = { + systemd.tmpfiles.rules = [ + "d '/srv/nextcloud' 0750 nextcloud nextcloud - -" + ]; + + shb.nextcloud = { + apps.externalStorage = { + enable = true; + userLocalMount.directory = "/srv/nextcloud/$user"; + userLocalMount.mountName = "home"; + }; + }; + }; in { basic = pkgs.testers.runNixOSTest { name = "nextcloud-basic"; - nodes.server = { config, pkgs, ... }: { - imports = [ - (pkgs'.path + "/nixos/modules/profiles/headless.nix") - (pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix") - { - options = { - shb.backup = lib.mkOption { type = lib.types.anything; }; - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ../../modules/services/nextcloud-server.nix - ]; - - shb.nextcloud = { - enable = true; - domain = "example.com"; - subdomain = "n"; - dataDir = "/var/lib/nextcloud"; - tracing = null; - defaultPhoneRegion = "US"; - - # This option is only needed because we do not access Nextcloud at the default port in the VM. - externalFqdn = "n.example.com:8080"; - - adminUser = adminUser; - adminPassFile = pkgs.writeText "adminPassFile" adminPass; - debug = true; - }; - # Nginx port. - networking.firewall.allowedTCPPorts = [ 80 ]; - # VM needs a bit more memory than default. - virtualisation.memorySize = 4096; - }; + nodes.server = lib.mkMerge [ + base + basic + { + options = { + shb.authelia = lib.mkOption { type = lib.types.anything; }; + }; + } + ]; nodes.client = {}; testScript = commonTestScript; }; - cert = pkgs.testers.runNixOSTest { - name = "nextcloud-cert"; + https = pkgs.testers.runNixOSTest { + name = "nextcloud-https"; - nodes.server = { config, pkgs, ... }: { - imports = [ - (pkgs'.path + "/nixos/modules/profiles/headless.nix") - (pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix") - { - options = { - shb.backup = lib.mkOption { type = lib.types.anything; }; - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ../../modules/blocks/nginx.nix - # ../../modules/blocks/postgresql.nix - ../../modules/blocks/ssl.nix - ../../modules/services/nextcloud-server.nix - ]; - - shb.certs = { - cas.selfsigned.myca = { - name = "My CA"; + nodes.server = lib.mkMerge [ + base + certs + basic + https + { + options = { + shb.authelia = lib.mkOption { type = lib.types.anything; }; }; - certs.selfsigned = { - n = { - ca = config.shb.certs.cas.selfsigned.myca; - domain = "*.example.com"; - group = "nginx"; - }; - }; - }; - - systemd.services.nginx.after = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - systemd.services.nginx.requires = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - - shb.nextcloud = { - enable = true; - domain = "example.com"; - subdomain = "n"; - dataDir = "/var/lib/nextcloud"; - tracing = null; - defaultPhoneRegion = "US"; - - ssl = config.shb.certs.certs.selfsigned.n; - - # This option is only needed because we do not access Nextcloud at the default port in the VM. - externalFqdn = "n.example.com:8080"; - - adminUser = adminUser; - adminPassFile = pkgs.writeText "adminPassFile" adminPass; - debug = true; - }; - # Nginx port. - networking.firewall.allowedTCPPorts = [ 80 443 ]; - - shb.nginx.accessLog = true; - }; + } + ]; nodes.client = {}; @@ -240,152 +264,42 @@ in previewGenerator = pkgs.testers.runNixOSTest { name = "nextcloud-previewGenerator"; - nodes.server = { config, pkgs, ... }: { - imports = [ - (pkgs'.path + "/nixos/modules/profiles/headless.nix") - (pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix") - { - options = { - shb.backup = lib.mkOption { type = lib.types.anything; }; - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ../../modules/services/nextcloud-server.nix - ]; - - systemd.tmpfiles.rules = [ - "d '/srv/nextcloud' 0750 nextcloud nextcloud - -" - ]; - - shb.nextcloud = { - enable = true; - domain = "example.com"; - subdomain = "n"; - dataDir = "/var/lib/nextcloud"; - tracing = null; - defaultPhoneRegion = "US"; - - # This option is only needed because we do not access Nextcloud at the default port in the VM. - externalFqdn = "n.example.com:8080"; - - adminUser = adminUser; - adminPassFile = pkgs.writeText "adminPassFile" adminPass; - debug = true; - - apps.previewgenerator.enable = true; - }; - # Nginx port. - networking.firewall.allowedTCPPorts = [ 80 ]; - # VM needs a bit more memory than default. - virtualisation.memorySize = 4096; - }; + nodes.server = lib.mkMerge [ + base + certs + basic + https + previewgenerator + { + options = { + shb.authelia = lib.mkOption { type = lib.types.anything; }; + }; + } + ]; nodes.client = {}; - testScript = { nodes, ... }: - '' - import json - - start_all() - server.wait_for_unit("phpfpm-nextcloud.service") - server.wait_for_unit("nginx.service") - server.wait_for_open_unix_socket("${nodes.server.services.phpfpm.pools.nextcloud.socket}") - - def find_in_logs(unit, text): - return server.systemctl("status {}".format(unit))[1].find(text) != -1 - - def curl(target, format, endpoint, succeed=True): - return json.loads(target.succeed( - "curl --fail-with-body --silent --show-error --output /dev/null --location" - + " --connect-to n.example.com:443:server:443" - + " --connect-to n.example.com:80:server:80" - + f" --write-out '{format}'" - + " " + endpoint - )) - - with subtest("access"): - response = curl(client, """{"code":%{response_code}}""", "http://n.example.com") - - if response['code'] != 200: - raise Exception(f"Code is {response['code']}") - ''; + testScript = commonTestScript; }; externalStorage = pkgs.testers.runNixOSTest { name = "nextcloud-externalStorage"; - nodes.server = { config, pkgs, ... }: { - imports = [ - (pkgs'.path + "/nixos/modules/profiles/headless.nix") - (pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix") - { - options = { - shb.backup = lib.mkOption { type = lib.types.anything; }; - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ../../modules/services/nextcloud-server.nix - ]; - - systemd.tmpfiles.rules = [ - "d '/srv/nextcloud' 0750 nextcloud nextcloud - -" - ]; - - shb.nextcloud = { - enable = true; - domain = "example.com"; - subdomain = "n"; - dataDir = "/var/lib/nextcloud"; - tracing = null; - defaultPhoneRegion = "US"; - - # This option is only needed because we do not access Nextcloud at the default port in the VM. - externalFqdn = "n.example.com:8080"; - - adminUser = adminUser; - adminPassFile = pkgs.writeText "adminPassFile" adminPass; - debug = true; - - apps.externalStorage = { - enable = true; - userLocalMount.directory = "/srv/nextcloud/$user"; - userLocalMount.mountName = "home"; + nodes.server = lib.mkMerge [ + base + certs + basic + https + externalstorage + { + options = { + shb.authelia = lib.mkOption { type = lib.types.anything; }; }; - }; - # Nginx port. - networking.firewall.allowedTCPPorts = [ 80 ]; - # VM needs a bit more memory than default. - virtualisation.memorySize = 4096; - }; + } + ]; nodes.client = {}; - testScript = { nodes, ... }: - '' - import json - - start_all() - server.wait_for_unit("phpfpm-nextcloud.service") - server.wait_for_unit("nginx.service") - server.wait_for_open_unix_socket("${nodes.server.services.phpfpm.pools.nextcloud.socket}") - - def find_in_logs(unit, text): - return server.systemctl("status {}".format(unit))[1].find(text) != -1 - - def curl(target, format, endpoint, succeed=True): - return json.loads(target.succeed( - "curl --fail-with-body --silent --show-error --output /dev/null --location" - + " --connect-to n.example.com:443:server:443" - + " --connect-to n.example.com:80:server:80" - + f" --write-out '{format}'" - + " " + endpoint - )) - - with subtest("access"): - response = curl(client, """{"code":%{response_code}}""", "http://n.example.com") - - if response['code'] != 200: - raise Exception(f"Code is {response['code']}") - ''; + testScript = commonTestScript; }; }