about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/from_md/release-notes/rl-2111.section.xml20
-rw-r--r--nixos/doc/manual/from_md/release-notes/rl-2205.section.xml9
-rw-r--r--nixos/doc/manual/release-notes/rl-2111.section.md12
-rw-r--r--nixos/doc/manual/release-notes/rl-2205.section.md6
-rw-r--r--nixos/modules/services/networking/lxd-image-server.nix3
-rw-r--r--nixos/modules/services/networking/shairport-sync.nix31
-rw-r--r--nixos/modules/services/security/step-ca.nix4
-rw-r--r--nixos/modules/services/x11/display-managers/lightdm.nix2
-rw-r--r--nixos/modules/virtualisation/amazon-ec2-amis.nix40
-rw-r--r--nixos/modules/virtualisation/waydroid.nix9
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/custom-ca.nix9
-rw-r--r--nixos/tests/docker-tools.nix20
-rw-r--r--nixos/tests/step-ca.nix76
14 files changed, 213 insertions, 29 deletions
diff --git a/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml
index fb98b6a4b01c0..96cb5187889fa 100644
--- a/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml
+++ b/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml
@@ -1,9 +1,5 @@
 <section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-release-21.11">
   <title>Release 21.11 (“Porcupine”, 2021/11/30)</title>
-  <para>
-    In addition to numerous new and upgraded packages, this release has
-    the following highlights:
-  </para>
   <itemizedlist spacing="compact">
     <listitem>
       <para>
@@ -14,6 +10,10 @@
   </itemizedlist>
   <section xml:id="sec-release-21.11-highlights">
     <title>Highlights</title>
+    <para>
+      In addition to numerous new and upgraded packages, this release
+      has the following highlights:
+    </para>
     <itemizedlist>
       <listitem>
         <para>
@@ -255,14 +255,14 @@
         <para>
           <link xlink:href="https://www.isc.org/kea/">Kea</link>, ISCs
           2nd generation DHCP and DDNS server suite. Available at
-          <link xlink:href="options.html#opt-services.kea">services.kea</link>.
+          <link xlink:href="options.html#opt-services.kea.dhcp4">services.kea</link>.
         </para>
       </listitem>
       <listitem>
         <para>
           <link xlink:href="https://owncast.online/">owncast</link>,
           self-hosted video live streaming solution. Available at
-          <link xlink:href="options.html#opt-services.owncast">services.owncast</link>.
+          <link xlink:href="options.html#opt-services.owncast.enable">services.owncast</link>.
         </para>
       </listitem>
       <listitem>
@@ -270,7 +270,7 @@
           <link xlink:href="https://joinpeertube.org/">PeerTube</link>,
           developed by Framasoft, is the free and decentralized
           alternative to video platforms. Available at
-          <link xlink:href="options.html#opt-services.peertube">services.peertube</link>.
+          <link xlink:href="options.html#opt-services.peertube.enable">services.peertube</link>.
         </para>
       </listitem>
       <listitem>
@@ -2023,6 +2023,12 @@ Superuser created successfully.
           hydrus manual</link>.
         </para>
       </listitem>
+      <listitem>
+        <para>
+          More jdk and jre versions are now exposed via
+          <literal>java-packages.compiler</literal>.
+        </para>
+      </listitem>
     </itemizedlist>
   </section>
 </section>
diff --git a/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
index 4752cad6c7b09..bb8c24ec4d1fb 100644
--- a/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
+++ b/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
@@ -57,6 +57,15 @@
           new versions will release.
         </para>
       </listitem>
+      <listitem>
+        <para>
+          The <literal>wafHook</literal> hook now honors
+          <literal>NIX_BUILD_CORES</literal> when
+          <literal>enableParallelBuilding</literal> is not set
+          explicitly. Packages can restore the old behaviour by setting
+          <literal>enableParallelBuilding=false</literal>.
+        </para>
+      </listitem>
     </itemizedlist>
   </section>
   <section xml:id="sec-release-22.05-notable-changes">
diff --git a/nixos/doc/manual/release-notes/rl-2111.section.md b/nixos/doc/manual/release-notes/rl-2111.section.md
index 5abfa6beb1061..584bde952a2af 100644
--- a/nixos/doc/manual/release-notes/rl-2111.section.md
+++ b/nixos/doc/manual/release-notes/rl-2111.section.md
@@ -1,11 +1,11 @@
 # Release 21.11 (“Porcupine”, 2021/11/30) {#sec-release-21.11}
 
-In addition to numerous new and upgraded packages, this release has the following highlights:
-
 - Support is planned until the end of June 2022, handing over to 22.05.
 
 ## Highlights {#sec-release-21.11-highlights}
 
+In addition to numerous new and upgraded packages, this release has the following highlights:
+
 - Nix has been updated to version 2.4, reference its [release notes](https://discourse.nixos.org/t/nix-2-4-released/15822) for more information on what has changed. The previous version of Nix, 2.3.16, remains available for the time being in the `nix_2_3` package.
 
 - `iptables` now uses `nf_tables` backend.
@@ -68,11 +68,11 @@ In addition to numerous new and upgraded packages, this release has the followin
 
 - [Jibri](https://github.com/jitsi/jibri), a service for recording or streaming a Jitsi Meet conference. Available as [services.jibri](options.html#opt-services.jibri.enable).
 
-- [Kea](https://www.isc.org/kea/), ISCs 2nd generation DHCP and DDNS server suite. Available at [services.kea](options.html#opt-services.kea).
+- [Kea](https://www.isc.org/kea/), ISCs 2nd generation DHCP and DDNS server suite. Available at [services.kea](options.html#opt-services.kea.dhcp4).
 
-- [owncast](https://owncast.online/), self-hosted video live streaming solution. Available at [services.owncast](options.html#opt-services.owncast).
+- [owncast](https://owncast.online/), self-hosted video live streaming solution. Available at [services.owncast](options.html#opt-services.owncast.enable).
 
-- [PeerTube](https://joinpeertube.org/), developed by Framasoft, is the free and decentralized alternative to video platforms. Available at [services.peertube](options.html#opt-services.peertube).
+- [PeerTube](https://joinpeertube.org/), developed by Framasoft, is the free and decentralized alternative to video platforms. Available at [services.peertube](options.html#opt-services.peertube.enable).
 
 - [sourcehut](https://sr.ht), a collection of tools useful for software development. Available as [services.sourcehut](options.html#opt-services.sourcehut.enable).
 
@@ -549,3 +549,5 @@ In addition to numerous new and upgraded packages, this release has the followin
 - RetroArch has been upgraded from version `1.8.5` to `1.9.13.2`. Since the previous release was quite old, if you're having issues after the upgrade, please delete your `$XDG_CONFIG_HOME/retroarch/retroarch.cfg` file.
 
 - hydrus has been upgraded from version `438` to `463`. Since upgrading between releases this old is advised against, be sure to have a backup of your data before upgrading. For details, see [the hydrus manual](https://hydrusnetwork.github.io/hydrus/help/getting_started_installing.html#big_updates).
+
+- More jdk and jre versions are now exposed via `java-packages.compiler`.
diff --git a/nixos/doc/manual/release-notes/rl-2205.section.md b/nixos/doc/manual/release-notes/rl-2205.section.md
index b0526a1fb3b49..579bcda9ec4ff 100644
--- a/nixos/doc/manual/release-notes/rl-2205.section.md
+++ b/nixos/doc/manual/release-notes/rl-2205.section.md
@@ -10,7 +10,7 @@ In addition to numerous new and upgraded packages, this release has the followin
 
 ## Backward Incompatibilities {#sec-release-22.05-incompatibilities}
 
-* `pkgs.ghc` now refers to `pkgs.targetPackages.haskellPackages.ghc`.
+- `pkgs.ghc` now refers to `pkgs.targetPackages.haskellPackages.ghc`.
   This *only* makes a difference if you are cross-compiling and will
   ensure that `pkgs.ghc` always runs on the host platform and compiles
   for the target platform (similar to `pkgs.gcc` for example).
@@ -22,9 +22,11 @@ In addition to numerous new and upgraded packages, this release has the followin
   instead to ensure cross compilation keeps working (or switch to
   `haskellPackages.callPackage`).
 
-* `pkgs.emacsPackages.orgPackages` is removed because org elpa is deprecated.
+- `pkgs.emacsPackages.orgPackages` is removed because org elpa is deprecated.
   The packages in the top level of `pkgs.emacsPackages`, such as org and
   org-contrib, refer to the ones in `pkgs.emacsPackages.elpaPackages` and
   `pkgs.emacsPackages.nongnuPackages` where the new versions will release.
 
+- The `wafHook` hook now honors `NIX_BUILD_CORES` when `enableParallelBuilding` is not set explicitly. Packages can restore the old behaviour by setting `enableParallelBuilding=false`.
+
 ## Other Notable Changes {#sec-release-22.05-notable-changes}
diff --git a/nixos/modules/services/networking/lxd-image-server.nix b/nixos/modules/services/networking/lxd-image-server.nix
index 5ec6cacffa497..b119ba8acf634 100644
--- a/nixos/modules/services/networking/lxd-image-server.nix
+++ b/nixos/modules/services/networking/lxd-image-server.nix
@@ -55,9 +55,8 @@ in
         path = "/var/log/lxd-image-server/lxd-image-server.log";
         frequency = "daily";
         keep = 21;
-        user = "lxd-image-server";
-        group = cfg.group;
         extraConfig = ''
+          create 755 lxd-image-server ${cfg.group}
           missingok
           compress
           delaycompress
diff --git a/nixos/modules/services/networking/shairport-sync.nix b/nixos/modules/services/networking/shairport-sync.nix
index ac526c0e9f6f4..eb61663e4d922 100644
--- a/nixos/modules/services/networking/shairport-sync.nix
+++ b/nixos/modules/services/networking/shairport-sync.nix
@@ -36,6 +36,14 @@ in
         '';
       };
 
+      openFirewall = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to automatically open ports in the firewall.
+        '';
+      };
+
       user = mkOption {
         type = types.str;
         default = "shairport";
@@ -45,6 +53,15 @@ in
         '';
       };
 
+      group = mkOption {
+        type = types.str;
+        default = "shairport";
+        description = ''
+          Group account name under which to run shairport-sync. The account
+          will be created.
+        '';
+      };
+
     };
 
   };
@@ -58,13 +75,22 @@ in
     services.avahi.publish.enable = true;
     services.avahi.publish.userServices = true;
 
-    users.users.${cfg.user} =
-      { description = "Shairport user";
+    users = {
+      users.${cfg.user} = {
+        description = "Shairport user";
         isSystemUser = true;
         createHome = true;
         home = "/var/lib/shairport-sync";
+        group = cfg.group;
         extraGroups = [ "audio" ] ++ optional config.hardware.pulseaudio.enable "pulse";
       };
+      groups.${cfg.group} = {};
+    };
+
+    networking.firewall = mkIf cfg.openFirewall {
+      allowedTCPPorts = [ 5000 ];
+      allowedUDPPortRanges = [ { from = 6001; to = 6011; } ];
+    };
 
     systemd.services.shairport-sync =
       {
@@ -73,6 +99,7 @@ in
         wantedBy = [ "multi-user.target" ];
         serviceConfig = {
           User = cfg.user;
+          Group = cfg.group;
           ExecStart = "${pkgs.shairport-sync}/bin/shairport-sync ${cfg.arguments}";
           RuntimeDirectory = "shairport-sync";
         };
diff --git a/nixos/modules/services/security/step-ca.nix b/nixos/modules/services/security/step-ca.nix
index db7f81acd2a39..27b2ceed1a430 100644
--- a/nixos/modules/services/security/step-ca.nix
+++ b/nixos/modules/services/security/step-ca.nix
@@ -1,4 +1,4 @@
-{ config, lib, pkgs, ... }:
+{ config, lib, pkgs, nixosTests, ... }:
 let
   cfg = config.services.step-ca;
   settingsFormat = (pkgs.formats.json { });
@@ -82,6 +82,8 @@ in
       });
     in
     {
+      passthru.tests.step-ca = nixosTests.step-ca;
+
       assertions =
         [
           {
diff --git a/nixos/modules/services/x11/display-managers/lightdm.nix b/nixos/modules/services/x11/display-managers/lightdm.nix
index 9a7532b476415..84b75c83aeab4 100644
--- a/nixos/modules/services/x11/display-managers/lightdm.nix
+++ b/nixos/modules/services/x11/display-managers/lightdm.nix
@@ -312,7 +312,7 @@ in
     };
 
     systemd.tmpfiles.rules = [
-      "d /run/lightdm 0711 lightdm lightdm 0"
+      "d /run/lightdm 0711 lightdm lightdm -"
       "d /var/cache/lightdm 0711 root lightdm -"
       "d /var/lib/lightdm 1770 lightdm lightdm -"
       "d /var/lib/lightdm-data 1775 lightdm lightdm -"
diff --git a/nixos/modules/virtualisation/amazon-ec2-amis.nix b/nixos/modules/virtualisation/amazon-ec2-amis.nix
index b3459ba3d650f..91b5237e3371d 100644
--- a/nixos/modules/virtualisation/amazon-ec2-amis.nix
+++ b/nixos/modules/virtualisation/amazon-ec2-amis.nix
@@ -402,5 +402,43 @@ let self = {
   "21.05".ap-east-1.x86_64-linux.hvm-ebs = "ami-06dc98082bc55c1fc";
   "21.05".sa-east-1.x86_64-linux.hvm-ebs = "ami-04737dd49b98936c6";
 
-  latest = self."21.05";
+  # 21.11.333823.96b4157790f-x86_64-linux
+  "21.11".eu-west-1.x86_64-linux.hvm-ebs = "ami-01d0304a712f2f3f0";
+  "21.11".eu-west-2.x86_64-linux.hvm-ebs = "ami-00e828bfc1e5d09ac";
+  "21.11".eu-west-3.x86_64-linux.hvm-ebs = "ami-0e1ea64430d8103f2";
+  "21.11".eu-central-1.x86_64-linux.hvm-ebs = "ami-0fcf28c07e86142c5";
+  "21.11".eu-north-1.x86_64-linux.hvm-ebs = "ami-0ee83a3c6590fd6b1";
+  "21.11".us-east-1.x86_64-linux.hvm-ebs = "ami-099756bfda4540da0";
+  "21.11".us-east-2.x86_64-linux.hvm-ebs = "ami-0b20a80b82052d23f";
+  "21.11".us-west-1.x86_64-linux.hvm-ebs = "ami-088ea590004b01752";
+  "21.11".us-west-2.x86_64-linux.hvm-ebs = "ami-0025b9d4831b911a7";
+  "21.11".ca-central-1.x86_64-linux.hvm-ebs = "ami-0e67089f898e74443";
+  "21.11".ap-southeast-1.x86_64-linux.hvm-ebs = "ami-0dc8d718279d3402d";
+  "21.11".ap-southeast-2.x86_64-linux.hvm-ebs = "ami-0155e842329970187";
+  "21.11".ap-northeast-1.x86_64-linux.hvm-ebs = "ami-07c95eda953bf5435";
+  "21.11".ap-northeast-2.x86_64-linux.hvm-ebs = "ami-04167df3cd952b3bd";
+  "21.11".ap-south-1.x86_64-linux.hvm-ebs = "ami-0680e05531b3db677";
+  "21.11".ap-east-1.x86_64-linux.hvm-ebs = "ami-0835a3e481dc240f9";
+  "21.11".sa-east-1.x86_64-linux.hvm-ebs = "ami-0f7c354c421348e51";
+
+  # 21.11.333823.96b4157790f-aarch64-linux
+  "21.11".eu-west-1.aarch64-linux.hvm-ebs = "ami-048f3eea6a12c4b3b";
+  "21.11".eu-west-2.aarch64-linux.hvm-ebs = "ami-0e6f18f2009806add";
+  "21.11".eu-west-3.aarch64-linux.hvm-ebs = "ami-0a28d593f5e938d80";
+  "21.11".eu-central-1.aarch64-linux.hvm-ebs = "ami-0b9c95d926ab9474c";
+  "21.11".eu-north-1.aarch64-linux.hvm-ebs = "ami-0f2d400b4a2368a1a";
+  "21.11".us-east-1.aarch64-linux.hvm-ebs = "ami-05afb75585567d386";
+  "21.11".us-east-2.aarch64-linux.hvm-ebs = "ami-07f360673c2fccf8d";
+  "21.11".us-west-1.aarch64-linux.hvm-ebs = "ami-0a6892c61d85774db";
+  "21.11".us-west-2.aarch64-linux.hvm-ebs = "ami-04eaf20283432e852";
+  "21.11".ca-central-1.aarch64-linux.hvm-ebs = "ami-036b69828502e7fdf";
+  "21.11".ap-southeast-1.aarch64-linux.hvm-ebs = "ami-0d52e51e68b6954ef";
+  "21.11".ap-southeast-2.aarch64-linux.hvm-ebs = "ami-000a3019e003f4fb9";
+  "21.11".ap-northeast-1.aarch64-linux.hvm-ebs = "ami-09b0c7928780e25b6";
+  "21.11".ap-northeast-2.aarch64-linux.hvm-ebs = "ami-05f80f3c83083ff62";
+  "21.11".ap-south-1.aarch64-linux.hvm-ebs = "ami-05b2a3ff8489c3f59";
+  "21.11".ap-east-1.aarch64-linux.hvm-ebs = "ami-0aa3b50a4f2822a00";
+  "21.11".sa-east-1.aarch64-linux.hvm-ebs = "ami-00f68eff453d3fe69";
+
+  latest = self."21.11";
 }; in self
diff --git a/nixos/modules/virtualisation/waydroid.nix b/nixos/modules/virtualisation/waydroid.nix
index 854ab056dbb84..4fc798ff39f89 100644
--- a/nixos/modules/virtualisation/waydroid.nix
+++ b/nixos/modules/virtualisation/waydroid.nix
@@ -18,7 +18,8 @@ let
     /dev/hwbinder = hidl
   '';
 
-in {
+in
+{
 
   options.virtualisation.waydroid = {
     enable = mkEnableOption "Waydroid";
@@ -36,6 +37,12 @@ in {
       (isEnabled "ASHMEM")
     ];
 
+    /* NOTE: we always enable this flag even if CONFIG_PSI_DEFAULT_DISABLED is not on
+      as reading the kernel config is not always possible and on kernels where it's
+      already on it will be no-op
+    */
+    boot.kernelParams = [ "psi=1" ];
+
     environment.etc."gbinder.d/waydroid.conf".source = waydroidGbinderConf;
 
     environment.systemPackages = with pkgs; [ waydroid ];
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 4f04771e2533a..1ff1b8d586422 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -432,6 +432,7 @@ in
   sslh = handleTest ./sslh.nix {};
   sssd = handleTestOn ["x86_64-linux"] ./sssd.nix {};
   sssd-ldap = handleTestOn ["x86_64-linux"] ./sssd-ldap.nix {};
+  step-ca = handleTestOn ["x86_64-linux"] ./step-ca.nix {};
   strongswan-swanctl = handleTest ./strongswan-swanctl.nix {};
   sudo = handleTest ./sudo.nix {};
   sway = handleTest ./sway.nix {};
diff --git a/nixos/tests/custom-ca.nix b/nixos/tests/custom-ca.nix
index 0ab49f3b34306..a55449a397a7c 100644
--- a/nixos/tests/custom-ca.nix
+++ b/nixos/tests/custom-ca.nix
@@ -82,6 +82,9 @@ in
       # chromium-based browsers refuse to run as root
       test-support.displayManager.auto.user = "alice";
 
+      # browsers may hang with the default memory
+      virtualisation.memorySize = 600;
+
       networking.hosts."127.0.0.1" = [ "good.example.com" "bad.example.com" ];
       security.pki.certificateFiles = [ "${example-good-cert}/ca.crt" ];
 
@@ -160,7 +163,7 @@ in
         browser = command.split()[0]
         with subtest("Good certificate is trusted in " + browser):
             execute_as(
-                "alice", f"env P11_KIT_DEBUG=trust {command} https://good.example.com & >&2"
+                "alice", f"{command} https://good.example.com >&2 &"
             )
             wait_for_window_as("alice", browser)
             machine.wait_for_text("It works!")
@@ -168,9 +171,9 @@ in
             execute_as("alice", "xdotool key ctrl+w")  # close tab
 
         with subtest("Unknown CA is untrusted in " + browser):
-            execute_as("alice", f"{command} https://bad.example.com & >&2")
+            execute_as("alice", f"{command} https://bad.example.com >&2 &")
             machine.wait_for_text(error)
             machine.screenshot("bad" + browser)
-            machine.succeed("pkill " + browser)
+            machine.succeed("pkill -f " + browser)
   '';
 })
diff --git a/nixos/tests/docker-tools.nix b/nixos/tests/docker-tools.nix
index 7110187e8d764..f3858b8bd81e8 100644
--- a/nixos/tests/docker-tools.nix
+++ b/nixos/tests/docker-tools.nix
@@ -276,15 +276,22 @@ import ./make-test-python.nix ({ pkgs, ... }: {
         # Ensure the image has the correct number of layers
         assert len(set_of_layers("layered-bulk-layer")) == 4
 
-    with subtest("Ensure correct behavior when no store is needed"):
+    with subtest("Ensure only minimal paths are added to the store"):
+        # TODO: make an example that has no store paths, for example by making
+        #       busybox non-self-referential.
+
         # This check tests that buildLayeredImage can build images that don't need a store.
         docker.succeed(
             "docker load --input='${pkgs.dockerTools.examples.no-store-paths}'"
         )
 
-        # This check may be loosened to allow an *empty* store rather than *no* store.
-        docker.succeed("docker run --rm no-store-paths ls /")
-        docker.fail("docker run --rm no-store-paths ls /nix/store")
+        docker.succeed("docker run --rm no-store-paths ls / >/dev/console")
+
+        # If busybox isn't self-referential, we need this line
+        #   docker.fail("docker run --rm no-store-paths ls /nix/store >/dev/console")
+        # However, it currently is self-referential, so we check that it is the
+        # only store path.
+        docker.succeed("diff <(docker run --rm no-store-paths ls /nix/store) <(basename ${pkgs.pkgsStatic.busybox}) >/dev/console")
 
     with subtest("Ensure buildLayeredImage does not change store path contents."):
         docker.succeed(
@@ -379,6 +386,11 @@ import ./make-test-python.nix ({ pkgs, ... }: {
             "docker run --rm ${examples.layeredImageWithFakeRootCommands.imageName} sh -c 'stat -c '%u' /home/jane | grep -E ^1000$'"
         )
 
+    with subtest("The image contains store paths referenced by the fakeRootCommands output"):
+        docker.succeed(
+            "docker run --rm ${examples.layeredImageWithFakeRootCommands.imageName} /hello/bin/layeredImageWithFakeRootCommands-hello"
+        )
+
     with subtest("exportImage produces a valid tarball"):
         docker.succeed(
             "tar -tf ${examples.exportBash} | grep '\./bin/bash' > /dev/null"
diff --git a/nixos/tests/step-ca.nix b/nixos/tests/step-ca.nix
new file mode 100644
index 0000000000000..b22bcb060f2bf
--- /dev/null
+++ b/nixos/tests/step-ca.nix
@@ -0,0 +1,76 @@
+import ./make-test-python.nix ({ pkgs, ... }:
+  let
+    test-certificates = pkgs.runCommandLocal "test-certificates" { } ''
+      mkdir -p $out
+      echo insecure-root-password > $out/root-password-file
+      echo insecure-intermediate-password > $out/intermediate-password-file
+      ${pkgs.step-cli}/bin/step certificate create "Example Root CA" $out/root_ca.crt $out/root_ca.key --password-file=$out/root-password-file --profile root-ca
+      ${pkgs.step-cli}/bin/step certificate create "Example Intermediate CA 1" $out/intermediate_ca.crt $out/intermediate_ca.key --password-file=$out/intermediate-password-file --ca-password-file=$out/root-password-file --profile intermediate-ca --ca $out/root_ca.crt --ca-key $out/root_ca.key
+    '';
+  in
+  {
+    nodes =
+      {
+        caserver =
+          { config, pkgs, ... }: {
+            services.step-ca = {
+              enable = true;
+              address = "0.0.0.0";
+              port = 8443;
+              openFirewall = true;
+              intermediatePasswordFile = "${test-certificates}/intermediate-password-file";
+              settings = {
+                dnsNames = [ "caserver" ];
+                root = "${test-certificates}/root_ca.crt";
+                crt = "${test-certificates}/intermediate_ca.crt";
+                key = "${test-certificates}/intermediate_ca.key";
+                db = {
+                  type = "badger";
+                  dataSource = "/var/lib/step-ca/db";
+                };
+                authority = {
+                  provisioners = [
+                    {
+                      type = "ACME";
+                      name = "acme";
+                    }
+                  ];
+                };
+              };
+            };
+          };
+
+        caclient =
+          { config, pkgs, ... }: {
+            security.acme.server = "https://caserver:8443/acme/acme/directory";
+            security.acme.email = "root@example.org";
+            security.acme.acceptTerms = true;
+
+            security.pki.certificateFiles = [ "${test-certificates}/root_ca.crt" ];
+
+            networking.firewall.allowedTCPPorts = [ 80 443 ];
+
+            services.nginx = {
+              enable = true;
+              virtualHosts = {
+                "caclient" = {
+                  forceSSL = true;
+                  enableACME = true;
+                };
+              };
+            };
+          };
+
+        catester = { config, pkgs, ... }: {
+          security.pki.certificateFiles = [ "${test-certificates}/root_ca.crt" ];
+        };
+      };
+
+    testScript =
+      ''
+        catester.start()
+        caserver.wait_for_unit("step-ca.service")
+        caclient.wait_for_unit("acme-finished-caclient.target")
+        catester.succeed("curl https://caclient/ | grep \"Welcome to nginx!\"")
+      '';
+  })