about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorLuca Bruno <lethalman88@gmail.com>2015-11-29 16:50:26 +0100
committerLuca Bruno <lethalman88@gmail.com>2015-11-29 16:50:26 +0100
commit920b1d3591431837f4522ccff52fb65b241200cf (patch)
treea63a1acebbee20444f4b3e9e2695ec712ba7aae3 /nixos
parent07a0204282224891492e7e1cfe72830a1fc32355 (diff)
parenta9056371a0a62da46ff88183a6535635ed085dec (diff)
downloadnixlib-920b1d3591431837f4522ccff52fb65b241200cf.tar
nixlib-920b1d3591431837f4522ccff52fb65b241200cf.tar.gz
nixlib-920b1d3591431837f4522ccff52fb65b241200cf.tar.bz2
nixlib-920b1d3591431837f4522ccff52fb65b241200cf.tar.lz
nixlib-920b1d3591431837f4522ccff52fb65b241200cf.tar.xz
nixlib-920b1d3591431837f4522ccff52fb65b241200cf.tar.zst
nixlib-920b1d3591431837f4522ccff52fb65b241200cf.zip
Merge branch 'master' into closure-size
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/release-notes/rl-unstable.xml15
-rw-r--r--nixos/lib/make-iso9660-image.sh6
-rw-r--r--nixos/modules/misc/ids.nix2
-rw-r--r--nixos/modules/programs/zsh/zsh.nix2
-rw-r--r--nixos/modules/security/pam.nix26
-rw-r--r--nixos/modules/services/misc/disnix.nix12
-rw-r--r--nixos/modules/services/monitoring/graphite.nix29
-rw-r--r--nixos/modules/services/monitoring/statsd.nix31
-rw-r--r--nixos/modules/services/networking/chrony.nix69
-rw-r--r--nixos/modules/services/networking/syncthing.nix15
-rw-r--r--nixos/modules/services/web-servers/apache-httpd/wordpress.nix2
-rw-r--r--nixos/modules/tasks/encrypted-devices.nix2
-rw-r--r--nixos/modules/virtualisation/containers.nix54
13 files changed, 207 insertions, 58 deletions
diff --git a/nixos/doc/manual/release-notes/rl-unstable.xml b/nixos/doc/manual/release-notes/rl-unstable.xml
index 97ac03a770f6..c9b31afdfcf8 100644
--- a/nixos/doc/manual/release-notes/rl-unstable.xml
+++ b/nixos/doc/manual/release-notes/rl-unstable.xml
@@ -26,6 +26,13 @@ nixos.path = ./nixpkgs-unstable-2015-12-06/nixos;
 
 </itemizedlist>
 
+<para>The following new services were added since the last release:
+
+  <itemizedlist>
+    <listitem><para><literal>services/monitoring/longview.nix</literal></para></listitem>
+  </itemizedlist>
+</para>
+
 <para>When upgrading from a previous release, please be aware of the
 following incompatible changes:</para>
 
@@ -89,6 +96,14 @@ nginx.override {
     </para>
   </listitem>
 
+  <listitem>
+    <para><literal>tidy-html5</literal> package is removed.
+    Upstream only provided <literal>(lib)tidy5</literal> during development,
+    and now they went back to <literal>(lib)tidy</literal> to work as a drop-in
+    replacement of the original package that has been unmaintained for years.
+    You can (still) use the <literal>html-tidy</literal> package, which got updated
+    to a stable release from this new upstream.</para>
+  </listitem>
 </itemizedlist>
 
 </section>
diff --git a/nixos/lib/make-iso9660-image.sh b/nixos/lib/make-iso9660-image.sh
index c9a373794692..31bfe23d3d4a 100644
--- a/nixos/lib/make-iso9660-image.sh
+++ b/nixos/lib/make-iso9660-image.sh
@@ -119,7 +119,11 @@ $xorriso -output $out/iso/$isoName
 
 if test -n "$usbBootable"; then
     echo "Making image hybrid..."
-    isohybrid --uefi $out/iso/$isoName
+    if test -n "$efiBootable"; then
+        isohybrid --uefi $out/iso/$isoName
+    else
+        isohybrid $out/iso/$isoName
+    fi
 fi
 
 if test -n "$compressImage"; then
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index c9810b6fccb1..2b40120641a0 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -305,7 +305,7 @@
       nslcd = 58;
       scanner = 59;
       nginx = 60;
-      #chrony = 61; # unused
+      chrony = 61;
       systemd-journal = 62;
       smtpd = 63;
       smtpq = 64;
diff --git a/nixos/modules/programs/zsh/zsh.nix b/nixos/modules/programs/zsh/zsh.nix
index 9f7596a21e72..dae7e446b4cf 100644
--- a/nixos/modules/programs/zsh/zsh.nix
+++ b/nixos/modules/programs/zsh/zsh.nix
@@ -179,6 +179,8 @@ in
     environment.systemPackages = [ pkgs.zsh ]
       ++ optional cfg.enableCompletion pkgs.nix-zsh-completions;
 
+    environment.pathsToLink = optional cfg.enableCompletion "/share/zsh";
+
     #users.defaultUserShell = mkDefault "/run/current-system/sw/bin/zsh";
 
     environment.shells =
diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix
index 88760574cbc6..2ee8a803d2fe 100644
--- a/nixos/modules/security/pam.nix
+++ b/nixos/modules/security/pam.nix
@@ -218,7 +218,7 @@ let
       # Samba stuff to the Samba module.  This requires that the PAM
       # module provides the right hooks.
       text = mkDefault
-        ''
+        (''
           # Account management.
           account sufficient pam_unix.so
           ${optionalString config.users.ldap.enable
@@ -241,12 +241,22 @@ let
               "auth sufficient ${pkgs.pam_u2f}/lib/security/pam_u2f.so"}
           ${optionalString cfg.usbAuth
               "auth sufficient ${pkgs.pam_usb}/lib/security/pam_usb.so"}
+        '' +
+          # Modules in this block require having the password set in PAM_AUTHTOK.
+          # pam_unix is marked as 'sufficient' on NixOS which means nothing will run
+          # after it succeeds. Certain modules need to run after pam_unix
+          # prompts the user for password so we run it once with 'required' at an
+          # earlier point and it will run again with 'sufficient' further down.
+          # We use try_first_pass the second time to avoid prompting password twice
+          (optionalString (cfg.unixAuth && (config.security.pam.enableEcryptfs || cfg.pamMount)) ''
+              auth required pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} likeauth
+              ${optionalString config.security.pam.enableEcryptfs
+                "auth optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap"}
+              ${optionalString cfg.pamMount
+                "auth optional ${pkgs.pam_mount}/lib/security/pam_mount.so"}
+            '') + ''
           ${optionalString cfg.unixAuth
-              "auth ${if (config.security.pam.enableEcryptfs || cfg.pamMount) then "required" else "sufficient"} pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} likeauth"}
-          ${optionalString cfg.pamMount
-              "auth optional ${pkgs.pam_mount}/lib/security/pam_mount.so"}
-          ${optionalString config.security.pam.enableEcryptfs
-              "auth required ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap"}
+              "auth sufficient pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} likeauth try_first_pass"}
           ${optionalString cfg.otpwAuth
               "auth sufficient ${pkgs.otpw}/lib/security/pam_otpw.so"}
           ${optionalString cfg.oathAuth
@@ -258,7 +268,7 @@ let
             auth [default=die success=done] ${pam_ccreds}/lib/security/pam_ccreds.so action=validate use_first_pass
             auth sufficient ${pam_ccreds}/lib/security/pam_ccreds.so action=store use_first_pass
           ''}
-          ${optionalString (!(config.security.pam.enableEcryptfs || cfg.pamMount)) "auth required pam_deny.so"}
+          auth required pam_deny.so
 
           # Password management.
           password requisite pam_unix.so nullok sha512
@@ -306,7 +316,7 @@ let
               "session optional ${pkgs.pam_mount}/lib/security/pam_mount.so"}
           ${optionalString (cfg.enableAppArmor && config.security.apparmor.enable)
               "session optional ${pkgs.apparmor-pam}/lib/security/pam_apparmor.so order=user,group,default debug"}
-        '';
+        '');
     };
 
   };
diff --git a/nixos/modules/services/misc/disnix.nix b/nixos/modules/services/misc/disnix.nix
index c439efe9f8e7..0534c4fc942d 100644
--- a/nixos/modules/services/misc/disnix.nix
+++ b/nixos/modules/services/misc/disnix.nix
@@ -121,6 +121,7 @@ in
       disnix =
         { description = "Disnix server";
         
+          wants = [ "dysnomia.target" ];
           wantedBy = [ "multi-user.target" ];
           after = [ "dbus.service" ]
             ++ optional config.services.httpd.enable "httpd.service"
@@ -137,6 +138,17 @@ in
           environment = {
             HOME = "/root";
           };
+          
+          preStart = ''
+            mkdir -p /etc/systemd-mutable/system
+            if [ ! -f /etc/systemd-mutable/system/dysnomia.target ]
+            then
+                ( echo "[Unit]"
+                  echo "Description=Services that are activated and deactivated by Dysnomia"
+                  echo "After=final.target"
+                ) > /etc/systemd-mutable/system/dysnomia.target
+            fi
+          '';
 
           exec = "disnix-service";
         };
diff --git a/nixos/modules/services/monitoring/graphite.nix b/nixos/modules/services/monitoring/graphite.nix
index ac0fba597a04..57abb959fdb7 100644
--- a/nixos/modules/services/monitoring/graphite.nix
+++ b/nixos/modules/services/monitoring/graphite.nix
@@ -41,8 +41,15 @@ let
   };
 
   carbonOpts = name: with config.ids; ''
-    --nodaemon --syslog --prefix=${name} --pidfile ${dataDir}/${name}.pid ${name}
+    --nodaemon --syslog --prefix=${name} --pidfile /run/${name}/${name}.pid ${name}
   '';
+
+  mkPidFileDir = name: ''
+    mkdir -p /run/${name}
+    chmod 0700 /run/${name}
+    chown -R graphite:graphite /run/${name}
+  '';
+
   carbonEnv = {
     PYTHONPATH = "${pkgs.python27Packages.carbon}/lib/python2.7/site-packages";
     GRAPHITE_ROOT = dataDir;
@@ -370,18 +377,20 @@ in {
 
   config = mkMerge [
     (mkIf cfg.carbon.enableCache {
-      systemd.services.carbonCache = {
+      systemd.services.carbonCache = let name = "carbon-cache"; in {
         description = "Graphite Data Storage Backend";
         wantedBy = [ "multi-user.target" ];
         after = [ "network-interfaces.target" ];
         environment = carbonEnv;
         serviceConfig = {
-          ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts "carbon-cache"}";
+          ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts name}";
           User = "graphite";
           Group = "graphite";
           PermissionsStartOnly = true;
+          PIDFile="/run/${name}/${name}.pid";
         };
-        preStart = ''
+        preStart = mkPidFileDir name + ''
+
           mkdir -p ${cfg.dataDir}/whisper
           chmod 0700 ${cfg.dataDir}/whisper
           chown -R graphite:graphite ${cfg.dataDir}
@@ -390,31 +399,35 @@ in {
     })
 
     (mkIf cfg.carbon.enableAggregator {
-      systemd.services.carbonAggregator = {
+      systemd.services.carbonAggregator = let name = "carbon-aggregator"; in {
         enable = cfg.carbon.enableAggregator;
         description = "Carbon Data Aggregator";
         wantedBy = [ "multi-user.target" ];
         after = [ "network-interfaces.target" ];
         environment = carbonEnv;
         serviceConfig = {
-          ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts "carbon-aggregator"}";
+          ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts name}";
           User = "graphite";
           Group = "graphite";
+          PIDFile="/run/${name}/${name}.pid";
         };
+        preStart = mkPidFileDir name;
       };
     })
 
     (mkIf cfg.carbon.enableRelay {
-      systemd.services.carbonRelay = {
+      systemd.services.carbonRelay = let name = "carbon-relay"; in {
         description = "Carbon Data Relay";
         wantedBy = [ "multi-user.target" ];
         after = [ "network-interfaces.target" ];
         environment = carbonEnv;
         serviceConfig = {
-          ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts "carbon-relay"}";
+          ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts name}";
           User = "graphite";
           Group = "graphite";
+          PIDFile="/run/${name}/${name}.pid";
         };
+        preStart = mkPidFileDir name;
       };
     })
 
diff --git a/nixos/modules/services/monitoring/statsd.nix b/nixos/modules/services/monitoring/statsd.nix
index d9e0b83e2389..39fabc27d6c8 100644
--- a/nixos/modules/services/monitoring/statsd.nix
+++ b/nixos/modules/services/monitoring/statsd.nix
@@ -6,13 +6,21 @@ let
 
   cfg = config.services.statsd;
 
+  isBuiltinBackend = name:
+    builtins.elem name [ "graphite" "console" "repeater" ];
+
   configFile = pkgs.writeText "statsd.conf" ''
     {
       address: "${cfg.host}",
       port: "${toString cfg.port}",
       mgmt_address: "${cfg.mgmt_address}",
       mgmt_port: "${toString cfg.mgmt_port}",
-      backends: [${concatMapStringsSep "," (el: if (nixType el) == "string" then ''"./backends/${el}"'' else ''"${head el.names}"'') cfg.backends}],
+      backends: [${
+        concatMapStringsSep "," (name:
+          if (isBuiltinBackend name)
+          then ''"./backends/${name}"''
+          else ''"${name}"''
+        ) cfg.backends}],
       ${optionalString (cfg.graphiteHost!=null) ''graphiteHost: "${cfg.graphiteHost}",''}
       ${optionalString (cfg.graphitePort!=null) ''graphitePort: "${toString cfg.graphitePort}",''}
       console: {
@@ -66,9 +74,16 @@ in
 
     backends = mkOption {
       description = "List of backends statsd will use for data persistence";
-      default = ["graphite"];
-      example = ["graphite" pkgs.nodePackages."statsd-influxdb-backend"];
-      type = types.listOf (types.either types.str types.package);
+      default = [];
+      example = [
+        "graphite"
+        "console"
+        "repeater"
+        "statsd-librato-backend"
+        "stackdriver-statsd-backend"
+        "statsd-influxdb-backend"
+      ];
+      type = types.listOf types.str;
     };
 
     graphiteHost = mkOption {
@@ -105,15 +120,17 @@ in
       description = "Statsd Server";
       wantedBy = [ "multi-user.target" ];
       environment = {
-        NODE_PATH=concatMapStringsSep ":" (el: "${el}/lib/node_modules") (filter (el: (nixType el) != "string") cfg.backends);
+        NODE_PATH=concatMapStringsSep ":"
+          (pkg: "${builtins.getAttr pkg pkgs.statsd.nodePackages}/lib/node_modules")
+          (filter (name: !isBuiltinBackend name) cfg.backends);
       };
       serviceConfig = {
-        ExecStart = "${pkgs.nodePackages.statsd}/bin/statsd ${configFile}";
+        ExecStart = "${pkgs.statsd}/bin/statsd ${configFile}";
         User = "statsd";
       };
     };
 
-    environment.systemPackages = [pkgs.nodePackages.statsd];
+    environment.systemPackages = [ pkgs.statsd ];
 
   };
 
diff --git a/nixos/modules/services/networking/chrony.nix b/nixos/modules/services/networking/chrony.nix
index fe062b30e4b7..1cd678e7c621 100644
--- a/nixos/modules/services/networking/chrony.nix
+++ b/nixos/modules/services/networking/chrony.nix
@@ -8,26 +8,10 @@ let
 
   stateDir = "/var/lib/chrony";
 
-  chronyUser = "chrony";
+  keyFile = "/etc/chrony.keys";
 
   cfg = config.services.chrony;
 
-  configFile = pkgs.writeText "chrony.conf" ''
-    ${toString (map (server: "server " + server + "\n") cfg.servers)}
-
-    ${optionalString cfg.initstepslew.enabled ''
-      initstepslew ${toString cfg.initstepslew.threshold} ${toString (map (server: server + " ") cfg.initstepslew.servers)}
-    ''}
-
-    driftfile ${stateDir}/chrony.drift
-
-    ${optionalString (!config.time.hardwareClockInLocalTime) "rtconutc"}
-
-    ${cfg.extraConfig}
-  '';
-
-  chronyFlags = "-m -f ${configFile} -u ${chronyUser}";
-
 in
 
 {
@@ -47,12 +31,7 @@ in
       };
 
       servers = mkOption {
-        default = [
-          "0.nixos.pool.ntp.org"
-          "1.nixos.pool.ntp.org"
-          "2.nixos.pool.ntp.org"
-          "3.nixos.pool.ntp.org"
-        ];
+        default = config.services.ntp.servers;
         description = ''
           The set of NTP servers from which to synchronise.
         '';
@@ -90,28 +69,60 @@ in
     # Make chronyc available in the system path
     environment.systemPackages = [ pkgs.chrony ];
 
+    environment.etc."chrony.conf".text =
+      ''
+        ${concatMapStringsSep "\n" (server: "server " + server) cfg.servers}
+
+        ${optionalString
+          cfg.initstepslew.enabled
+          "initstepslew ${toString cfg.initstepslew.threshold} ${concatStringsSep " " cfg.initstepslew.servers}"
+        }
+
+        driftfile ${stateDir}/chrony.drift
+
+        keyfile ${keyFile}
+        generatecommandkey
+
+        ${optionalString (!config.time.hardwareClockInLocalTime) "rtconutc"}
+
+        ${cfg.extraConfig}
+      '';
+
+    users.extraGroups = singleton
+      { name = "chrony";
+        gid = config.ids.gids.chrony;
+      };
+
     users.extraUsers = singleton
-      { name = chronyUser;
+      { name = "chrony";
         uid = config.ids.uids.chrony;
+        group = "chrony";
         description = "chrony daemon user";
         home = stateDir;
       };
 
-    jobs.chronyd =
-      { description = "chrony daemon";
+    systemd.services.ntpd.enable = false;
+
+    systemd.services.chronyd =
+      { description = "chrony NTP daemon";
 
         wantedBy = [ "multi-user.target" ];
         after = [ "network.target" ];
+        conflicts = [ "ntpd.service" "systemd-timesyncd.service" ];
 
-        path = [ chrony ];
+        path = [ pkgs.chrony ];
 
         preStart =
           ''
             mkdir -m 0755 -p ${stateDir}
-            chown ${chronyUser} ${stateDir}
+            touch ${keyFile}
+            chmod 0640 ${keyFile}
+            chown chrony:chrony ${stateDir} ${keyFile}
           '';
 
-        exec = "chronyd -n ${chronyFlags}";
+        serviceConfig =
+          { ExecStart = "${pkgs.chrony}/bin/chronyd -n -m -u chrony";
+          };
       };
 
   };
diff --git a/nixos/modules/services/networking/syncthing.nix b/nixos/modules/services/networking/syncthing.nix
index 4eb32b1cf306..56c384731c61 100644
--- a/nixos/modules/services/networking/syncthing.nix
+++ b/nixos/modules/services/networking/syncthing.nix
@@ -21,7 +21,7 @@ in
         description = ''
           Whether to enable the Syncthing, self-hosted open-source alternative
           to Dropbox and BittorrentSync. Initial interface will be
-          available on http://127.0.0.1:8080/.
+          available on http://127.0.0.1:8384/.
         '';
       };
 
@@ -40,6 +40,17 @@ in
         '';
       };
 
+      package = mkOption {
+        type = types.package;
+        default = pkgs.syncthing;
+        example = literalExample "pkgs.syncthing";
+        description = ''
+          Syncthing package to use.
+        '';
+      };
+
+
+
     };
 
   };
@@ -66,7 +77,7 @@ in
         };
       };
 
-    environment.systemPackages = [ pkgs.syncthing ];
+    environment.systemPackages = [ cfg.package ];
 
   };
 
diff --git a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
index 7a0314027a3d..a28c8567f9ff 100644
--- a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
+++ b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
@@ -248,7 +248,7 @@ in
     if [ ! -d ${serverInfo.fullConfig.services.mysql.dataDir}/${config.dbName} ]; then
       echo "Need to create the database '${config.dbName}' and grant permissions to user named '${config.dbUser}'."
       # Wait until MySQL is up
-      while [ ! -e /var/run/mysql/mysqld.pid ]; do
+      while [ ! -e ${serverInfo.fullConfig.services.mysql.pidDir}/mysqld.pid ]; do
         sleep 1
       done
       ${pkgs.mysql}/bin/mysql -e 'CREATE DATABASE ${config.dbName};'
diff --git a/nixos/modules/tasks/encrypted-devices.nix b/nixos/modules/tasks/encrypted-devices.nix
index 331531cee151..457b86e95ab5 100644
--- a/nixos/modules/tasks/encrypted-devices.nix
+++ b/nixos/modules/tasks/encrypted-devices.nix
@@ -30,7 +30,7 @@ let
       label = mkOption {
         default = null;
         example = "rootfs";
-        type = types.uniq (types.nullOr types.str);
+        type = types.nullOr types.str;
         description = "Label of the unlocked encrypted device. Set <literal>fileSystems.&lt;name?&gt;.device</literal> to <literal>/dev/mapper/&lt;label&gt;</literal> to mount the unlocked device.";
       };
 
diff --git a/nixos/modules/virtualisation/containers.nix b/nixos/modules/virtualisation/containers.nix
index 02cf1fe46a55..121ecbc9bf2c 100644
--- a/nixos/modules/virtualisation/containers.nix
+++ b/nixos/modules/virtualisation/containers.nix
@@ -47,6 +47,41 @@ let
 
   system = config.nixpkgs.system;
 
+  bindMountOpts = { name, config, ... }: {
+  
+    options = {
+      mountPoint = mkOption {
+        example = "/mnt/usb";
+        type = types.str;
+        description = "Mount point on the container file system.";
+      };
+      hostPath = mkOption {
+        default = null;
+        example = "/home/alice";
+        type = types.nullOr types.str;
+        description = "Location of the host path to be mounted.";
+      };
+      isReadOnly = mkOption {
+        default = true;
+        example = true;
+        type = types.bool;
+        description = "Determine whether the mounted path will be accessed in read-only mode.";
+      };
+    };
+    
+    config = {
+      mountPoint = mkDefault name;
+    };
+    
+  };
+  
+  mkBindFlag = d:
+               let flagPrefix = if d.isReadOnly then " --bind-ro=" else " --bind=";
+                   mountstr = if d.hostPath != null then "${d.hostPath}:${d.mountPoint}" else "${d.mountPoint}";
+               in flagPrefix + mountstr ;
+
+  mkBindFlags = bs: concatMapStrings mkBindFlag (lib.attrValues bs);
+
 in
 
 {
@@ -142,6 +177,21 @@ in
                 Wether the container is automatically started at boot-time.
               '';
             };
+
+            bindMounts = mkOption {
+              type = types.loaOf types.optionSet;
+              options = [ bindMountOpts ];
+              default = {};
+              example = { "/home" = { hostPath = "/home/alice";
+                                      isReadOnly = false; };
+                        };
+                        
+              description =
+                ''
+                  An extra list of directories that is bound to the container.
+                '';
+            };
+
           };
 
           config = mkMerge
@@ -249,12 +299,15 @@ in
               fi
             ''}
 
+
+
             # Run systemd-nspawn without startup notification (we'll
             # wait for the container systemd to signal readiness).
             EXIT_ON_REBOOT=1 NOTIFY_SOCKET= \
             exec ${config.systemd.package}/bin/systemd-nspawn \
               --keep-unit \
               -M "$INSTANCE" -D "$root" $extraFlags \
+              $EXTRA_NSPAWN_FLAGS \
               --bind-ro=/nix/store \
               --bind-ro=/nix/var/nix/db \
               --bind-ro=/nix/var/nix/daemon-socket \
@@ -354,6 +407,7 @@ in
            ${optionalString cfg.autoStart ''
              AUTO_START=1
            ''}
+           EXTRA_NSPAWN_FLAGS="${mkBindFlags cfg.bindMounts}"
           '';
       }) config.containers;