summary refs log tree commit diff
path: root/nixos/modules/virtualisation
diff options
context:
space:
mode:
authorRob Vermaas <rob.vermaas@gmail.com>2014-05-21 10:55:34 +0200
committerRob Vermaas <rob.vermaas@gmail.com>2014-05-21 16:37:53 +0200
commit3da94435c07d09c792d56d1a4547668422d7c539 (patch)
treea7ac4ed9ec94b2ee2c4d9f77912cf014e74cd356 /nixos/modules/virtualisation
parentd05e832b145485bb754f3aae6097ad75da54744e (diff)
downloadnixlib-3da94435c07d09c792d56d1a4547668422d7c539.tar
nixlib-3da94435c07d09c792d56d1a4547668422d7c539.tar.gz
nixlib-3da94435c07d09c792d56d1a4547668422d7c539.tar.bz2
nixlib-3da94435c07d09c792d56d1a4547668422d7c539.tar.lz
nixlib-3da94435c07d09c792d56d1a4547668422d7c539.tar.xz
nixlib-3da94435c07d09c792d56d1a4547668422d7c539.tar.zst
nixlib-3da94435c07d09c792d56d1a4547668422d7c539.zip
Add option ec2.hvm, to set some boot configuration specific for EC2 HVM instances.
(cherry picked from commit 35c76d917307b7ac405486855cfe63021810dba5)

Conflicts:
	nixos/modules/virtualisation/amazon-image.nix
Diffstat (limited to 'nixos/modules/virtualisation')
-rw-r--r--nixos/modules/virtualisation/amazon-image.nix333
1 files changed, 176 insertions, 157 deletions
diff --git a/nixos/modules/virtualisation/amazon-image.nix b/nixos/modules/virtualisation/amazon-image.nix
index 138047a07db0..9e64327c3abd 100644
--- a/nixos/modules/virtualisation/amazon-image.nix
+++ b/nixos/modules/virtualisation/amazon-image.nix
@@ -1,164 +1,183 @@
 { config, lib, pkgs, ... }:
 
 with lib;
-
+let
+  cfg = config.ec2;
+in
 {
   imports = [ ../profiles/headless.nix ./ec2-data.nix ];
 
-  system.build.amazonImage =
-    pkgs.vmTools.runInLinuxVM (
-      pkgs.runCommand "amazon-image"
-        { preVM =
-            ''
-              mkdir $out
-              diskImage=$out/nixos.img
-              ${pkgs.vmTools.qemu}/bin/qemu-img create -f raw $diskImage "4G"
-              mv closure xchg/
-            '';
-          buildInputs = [ pkgs.utillinux pkgs.perl ];
-          exportReferencesGraph =
-            [ "closure" config.system.build.toplevel ];
-        }
-        ''
-          # Create an empty filesystem and mount it.
-          ${pkgs.e2fsprogs}/sbin/mkfs.ext4 -L nixos /dev/vda
-          ${pkgs.e2fsprogs}/sbin/tune2fs -c 0 -i 0 /dev/vda
-          mkdir /mnt
-          mount /dev/vda /mnt
-
-          # The initrd expects these directories to exist.
-          mkdir /mnt/dev /mnt/proc /mnt/sys
-
-          mount -o bind /proc /mnt/proc
-
-          # Copy all paths in the closure to the filesystem.
-          storePaths=$(perl ${pkgs.pathsFromGraph} /tmp/xchg/closure)
-
-          mkdir -p /mnt/nix/store
-          echo "copying everything (will take a while)..."
-          cp -prd $storePaths /mnt/nix/store/
-
-          # Register the paths in the Nix database.
-          printRegistration=1 perl ${pkgs.pathsFromGraph} /tmp/xchg/closure | \
-              chroot /mnt ${config.nix.package}/bin/nix-store --load-db
-
-          # Create the system profile to allow nixos-rebuild to work.
-          chroot /mnt ${config.nix.package}/bin/nix-env \
-              -p /nix/var/nix/profiles/system --set ${config.system.build.toplevel}
-
-          # `nixos-rebuild' requires an /etc/NIXOS.
-          mkdir -p /mnt/etc
-          touch /mnt/etc/NIXOS
-
-          # `switch-to-configuration' requires a /bin/sh
-          mkdir -p /mnt/bin
-          ln -s ${config.system.build.binsh}/bin/sh /mnt/bin/sh
-
-          # Install a configuration.nix.
-          mkdir -p /mnt/etc/nixos
-          cp ${./amazon-config.nix} /mnt/etc/nixos/configuration.nix
-
-          # Generate the GRUB menu.
-          chroot /mnt ${config.system.build.toplevel}/bin/switch-to-configuration boot
-
-          umount /mnt/proc
-          umount /mnt
-        ''
-    );
-
-  fileSystems."/".device = "/dev/disk/by-label/nixos";
-
-  boot.initrd.kernelModules = [ "xen-blkfront" ];
-  boot.kernelModules = [ "xen-netfront" ];
-  boot.kernelParams = [ "console=ttyS0" ];
-
-  # Generate a GRUB menu.  Amazon's pv-grub uses this to boot our kernel/initrd.
-  boot.loader.grub.version = 1;
-  boot.loader.grub.device = "nodev";
-  boot.loader.grub.timeout = 0;
-  boot.loader.grub.extraPerEntryConfig = "root (hd0)";
-
-  boot.initrd.postDeviceCommands =
-    ''
-      # Force udev to exit to prevent random "Device or resource busy
-      # while trying to open /dev/xvda" errors from fsck.
-      udevadm control --exit || true
-      kill -9 -1
-    '';
-
-  # Mount all formatted ephemeral disks and activate all swap devices.
-  # We cannot do this with the ‘fileSystems’ and ‘swapDevices’ options
-  # because the set of devices is dependent on the instance type
-  # (e.g. "m1.large" has one ephemeral filesystem and one swap device,
-  # while "m1.large" has two ephemeral filesystems and no swap
-  # devices).  Also, put /tmp and /var on /disk0, since it has a lot
-  # more space than the root device.  Similarly, "move" /nix to /disk0
-  # by layering a unionfs-fuse mount on top of it so we have a lot more space for
-  # Nix operations.
-  boot.initrd.postMountCommands =
-    ''
-      diskNr=0
-      diskForUnionfs=
-      for device in /dev/xvd[abcde]*; do
-          if [ "$device" = /dev/xvda -o "$device" = /dev/xvda1 ]; then continue; fi
-          fsType=$(blkid -o value -s TYPE "$device" || true)
-          if [ "$fsType" = swap ]; then
-              echo "activating swap device $device..."
-              swapon "$device" || true
-          elif [ "$fsType" = ext3 ]; then
-              mp="/disk$diskNr"
-              diskNr=$((diskNr + 1))
-              echo "mounting $device on $mp..."
-              if mountFS "$device" "$mp" "" ext3; then
-                  if [ -z "$diskForUnionfs" ]; then diskForUnionfs="$mp"; fi
-              fi
-          else
-              echo "skipping unknown device type $device"
-          fi
-      done
-
-      if [ -n "$diskForUnionfs" ]; then
-          mkdir -m 755 -p $targetRoot/$diskForUnionfs/root
-
-          mkdir -m 1777 -p $targetRoot/$diskForUnionfs/root/tmp $targetRoot/tmp
-          mount --bind $targetRoot/$diskForUnionfs/root/tmp $targetRoot/tmp
-
-          if [ ! -e $targetRoot/.ebs ]; then
-              mkdir -m 755 -p $targetRoot/$diskForUnionfs/root/var $targetRoot/var
-              mount --bind $targetRoot/$diskForUnionfs/root/var $targetRoot/var
-
-              mkdir -p /unionfs-chroot/ro-nix
-              mount --rbind $targetRoot/nix /unionfs-chroot/ro-nix
-
-              mkdir -m 755 -p $targetRoot/$diskForUnionfs/root/nix
-              mkdir -p /unionfs-chroot/rw-nix
-              mount --rbind $targetRoot/$diskForUnionfs/root/nix /unionfs-chroot/rw-nix
-
-              unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot,max_files=32768 /rw-nix=RW:/ro-nix=RO $targetRoot/nix
-          fi
-      fi
-    '';
-
-  boot.initrd.extraUtilsCommands =
-    ''
-      # We need swapon in the initrd.
-      cp ${pkgs.utillinux}/sbin/swapon $out/bin
-    '';
-
-  # Don't put old configurations in the GRUB menu.  The user has no
-  # way to select them anyway.
-  boot.loader.grub.configurationLimit = 0;
-
-  # Allow root logins only using the SSH key that the user specified
-  # at instance creation time.
-  services.openssh.enable = true;
-  services.openssh.permitRootLogin = "without-password";
-
-  # Force getting the hostname from EC2.
-  networking.hostName = mkDefault "";
-
-  # Always include cryptsetup so that Charon can use it.
-  environment.systemPackages = [ pkgs.cryptsetup ];
-
-  boot.initrd.supportedFilesystems = [ "unionfs-fuse" ];
+  options = {
+    ec2 = {
+      hvm = mkOption {
+        default = false;
+        description = ''
+          Whether the EC2 instance is a HVM instance.
+        '';
+      };
+    };
+  };
+
+  config = {
+    system.build.amazonImage =
+      pkgs.vmTools.runInLinuxVM (
+        pkgs.runCommand "amazon-image"
+          { preVM =
+              ''
+                mkdir $out
+                diskImage=$out/nixos.img
+                ${pkgs.vmTools.qemu}/bin/qemu-img create -f raw $diskImage "4G"
+                mv closure xchg/
+              '';
+            buildInputs = [ pkgs.utillinux pkgs.perl ];
+            exportReferencesGraph =
+              [ "closure" config.system.build.toplevel ];
+          }
+          ''
+            # Create an empty filesystem and mount it.
+            ${pkgs.e2fsprogs}/sbin/mkfs.ext4 -L nixos /dev/vda
+            ${pkgs.e2fsprogs}/sbin/tune2fs -c 0 -i 0 /dev/vda
+            mkdir /mnt
+            mount /dev/vda /mnt
+
+            # The initrd expects these directories to exist.
+            mkdir /mnt/dev /mnt/proc /mnt/sys
+
+            mount -o bind /proc /mnt/proc
+
+            # Copy all paths in the closure to the filesystem.
+            storePaths=$(perl ${pkgs.pathsFromGraph} /tmp/xchg/closure)
+
+            mkdir -p /mnt/nix/store
+            echo "copying everything (will take a while)..."
+            cp -prd $storePaths /mnt/nix/store/
+
+            # Register the paths in the Nix database.
+            printRegistration=1 perl ${pkgs.pathsFromGraph} /tmp/xchg/closure | \
+                chroot /mnt ${config.nix.package}/bin/nix-store --load-db
+
+            # Create the system profile to allow nixos-rebuild to work.
+            chroot /mnt ${config.nix.package}/bin/nix-env \
+                -p /nix/var/nix/profiles/system --set ${config.system.build.toplevel}
+
+            # `nixos-rebuild' requires an /etc/NIXOS.
+            mkdir -p /mnt/etc
+            touch /mnt/etc/NIXOS
+
+            # `switch-to-configuration' requires a /bin/sh
+            mkdir -p /mnt/bin
+            ln -s ${config.system.build.binsh}/bin/sh /mnt/bin/sh
+
+            # Install a configuration.nix.
+            mkdir -p /mnt/etc/nixos
+            cp ${./amazon-config.nix} /mnt/etc/nixos/configuration.nix
+
+            # Generate the GRUB menu.
+            chroot /mnt ${config.system.build.toplevel}/bin/switch-to-configuration boot
+
+            umount /mnt/proc
+            umount /mnt
+          ''
+      );
+
+    fileSystems."/".device = "/dev/disk/by-label/nixos";
+
+    boot.initrd.kernelModules = [ "xen-blkfront" ];
+    boot.kernelModules = [ "xen-netfront" ];
+
+    # Generate a GRUB menu.  Amazon's pv-grub uses this to boot our kernel/initrd.
+    boot.loader.grub.version = 1;
+    boot.loader.grub.device = if cfg.hvm then "/dev/xvda" else "nodev";
+    boot.loader.grub.timeout = 0;
+    boot.loader.grub.extraPerEntryConfig = "root (hd0${lib.optionalString cfg.hvm ",0"})";
+
+    boot.initrd.postDeviceCommands =
+      ''
+        # Force udev to exit to prevent random "Device or resource busy
+        # while trying to open /dev/xvda" errors from fsck.
+        udevadm control --exit || true
+        kill -9 -1
+      '';
+
+    # Mount all formatted ephemeral disks and activate all swap devices.
+    # We cannot do this with the ‘fileSystems’ and ‘swapDevices’ options
+    # because the set of devices is dependent on the instance type
+    # (e.g. "m1.large" has one ephemeral filesystem and one swap device,
+    # while "m1.large" has two ephemeral filesystems and no swap
+    # devices).  Also, put /tmp and /var on /disk0, since it has a lot
+    # more space than the root device.  Similarly, "move" /nix to /disk0
+    # by layering a unionfs-fuse mount on top of it so we have a lot more space for
+    # Nix operations.
+    boot.initrd.postMountCommands =
+      ''
+        diskNr=0
+        diskForUnionfs=
+        for device in /dev/xvd[abcde]*; do
+            if [ "$device" = /dev/xvda -o "$device" = /dev/xvda1 ]; then continue; fi
+            fsType=$(blkid -o value -s TYPE "$device" || true)
+            if [ "$fsType" = swap ]; then
+                echo "activating swap device $device..."
+                swapon "$device" || true
+            elif [ "$fsType" = ext3 ]; then
+                mp="/disk$diskNr"
+                diskNr=$((diskNr + 1))
+                echo "mounting $device on $mp..."
+                if mountFS "$device" "$mp" "" ext3; then
+                    if [ -z "$diskForUnionfs" ]; then diskForUnionfs="$mp"; fi
+                fi
+            else
+                echo "skipping unknown device type $device"
+            fi
+        done
+
+        if [ -n "$diskForUnionfs" ]; then
+            mkdir -m 755 -p $targetRoot/$diskForUnionfs/root
+
+            mkdir -m 1777 -p $targetRoot/$diskForUnionfs/root/tmp $targetRoot/tmp
+            mount --bind $targetRoot/$diskForUnionfs/root/tmp $targetRoot/tmp
+
+            if [ ! -e $targetRoot/.ebs ]; then
+                mkdir -m 755 -p $targetRoot/$diskForUnionfs/root/var $targetRoot/var
+                mount --bind $targetRoot/$diskForUnionfs/root/var $targetRoot/var
+
+                mkdir -p /unionfs-chroot/ro-nix
+                mount --rbind $targetRoot/nix /unionfs-chroot/ro-nix
+
+                mkdir -m 755 -p $targetRoot/$diskForUnionfs/root/nix
+                mkdir -p /unionfs-chroot/rw-nix
+                mount --rbind $targetRoot/$diskForUnionfs/root/nix /unionfs-chroot/rw-nix
+
+                unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot,max_files=32768 /rw-nix=RW:/ro-nix=RO $targetRoot/nix
+            fi
+        fi
+      '';
+
+    boot.initrd.extraUtilsCommands =
+      ''
+        # We need swapon in the initrd.
+        cp ${pkgs.utillinux}/sbin/swapon $out/bin
+      '';
+
+    # Don't put old configurations in the GRUB menu.  The user has no
+    # way to select them anyway.
+    boot.loader.grub.configurationLimit = 0;
+
+    # Allow root logins only using the SSH key that the user specified
+    # at instance creation time.
+    services.openssh.enable = true;
+    services.openssh.permitRootLogin = "without-password";
+
+    # Force getting the hostname from EC2.
+    networking.hostName = mkDefault "";
+
+    # Always include cryptsetup so that Charon can use it.
+    environment.systemPackages = [ pkgs.cryptsetup ];
+
+    boot.initrd.supportedFilesystems = [ "unionfs-fuse" ];
+
+    # Prevent logging in as root without a password.  This doesn't really matter,
+    # since the only PAM services that allow logging in with a null
+    # password are local ones that are inaccessible on EC2 machines.
+    security.initialRootPassword = mkDefault "!";
+  };
 }