From 2e2282bd5e89f019400c264889bf322cf52390ea Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 6 Apr 2011 15:09:34 +0000 Subject: [PATCH] * Added a module to create a disk image for Nova. svn path=/nixos/trunk/; revision=26721 --- modules/virtualisation/amazon-image.nix | 38 +------- modules/virtualisation/ec2-data.nix | 45 +++++++++ modules/virtualisation/nova-image.nix | 123 ++++++++++++++++++++++++ 3 files changed, 170 insertions(+), 36 deletions(-) create mode 100644 modules/virtualisation/ec2-data.nix create mode 100644 modules/virtualisation/nova-image.nix diff --git a/modules/virtualisation/amazon-image.nix b/modules/virtualisation/amazon-image.nix index 4334f04325bc..ca35480240ea 100644 --- a/modules/virtualisation/amazon-image.nix +++ b/modules/virtualisation/amazon-image.nix @@ -3,6 +3,8 @@ with pkgs.lib; { + require = [ ./ec2-data.nix ]; + system.build.amazonImage = pkgs.vmTools.runInLinuxVM ( pkgs.runCommand "amazon-image" @@ -104,40 +106,4 @@ with pkgs.lib; # at instance creation time. services.openssh.enable = true; services.openssh.permitRootLogin = "without-password"; - - # Obtain the SSH key and host name at startup time. - jobs.fetchEC2Data = - { name = "fetch-ec2-data"; - - startOn = "ip-up"; - - task = true; - - script = - '' - echo "obtaining SSH key..." - mkdir -p /root/.ssh - ${pkgs.curl}/bin/curl --retry 3 --retry-delay 0 --fail \ - -o /root/key.pub \ - http://169.254.169.254/1.0/meta-data/public-keys/0/openssh-key - if [ $? -eq 0 -a -e /root/key.pub ]; then - if ! grep -q -f /root/key.pub /root/.ssh/authorized_keys; then - cat /root/key.pub >> /root/.ssh/authorized_keys - echo "new key added to authorized_keys" - fi - chmod 600 /root/.ssh/authorized_keys - rm -f /root/key.pub - fi - - # Print the host public key on the console so that the user - # can obtain it securely by parsing the output of - # ec2-get-console-output. - echo "-----BEGIN SSH HOST KEY FINGERPRINTS-----" > /dev/console - ${pkgs.openssh}/bin/ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub > /dev/console - echo "-----END SSH HOST KEY FINGERPRINTS-----" > /dev/console - - echo "setting host name..." - ${pkgs.nettools}/bin/hostname $(${pkgs.curl}/bin/curl http://169.254.169.254/1.0/meta-data/hostname) - ''; - }; } diff --git a/modules/virtualisation/ec2-data.nix b/modules/virtualisation/ec2-data.nix new file mode 100644 index 000000000000..cd1e3da69bde --- /dev/null +++ b/modules/virtualisation/ec2-data.nix @@ -0,0 +1,45 @@ +# This module defines an Upstart job that obtains the SSH key and host +# name of virtual machines running on Amazon EC2, Eucalyptus and +# OpenStack Compute (Nova). + +{ config, pkgs, ... }: + +{ + + jobs.fetchEC2Data = + { name = "fetch-ec2-data"; + + startOn = "ip-up"; + + task = true; + + script = + '' + echo "setting host name..." + ${pkgs.nettools}/bin/hostname $(${pkgs.curl}/bin/curl http://169.254.169.254/1.0/meta-data/hostname) + + echo "obtaining SSH key..." + mkdir -p /root/.ssh + ${pkgs.curl}/bin/curl --retry 3 --retry-delay 0 --fail \ + -o /root/key.pub \ + http://169.254.169.254/1.0/meta-data/public-keys/0/openssh-key + if [ $? -eq 0 -a -e /root/key.pub ]; then + if ! grep -q -f /root/key.pub /root/.ssh/authorized_keys; then + cat /root/key.pub >> /root/.ssh/authorized_keys + echo "new key added to authorized_keys" + fi + chmod 600 /root/.ssh/authorized_keys + rm -f /root/key.pub + fi + + # Print the host public key on the console so that the user + # can obtain it securely by parsing the output of + # ec2-get-console-output. + echo "-----BEGIN SSH HOST KEY FINGERPRINTS-----" > /dev/console + ${pkgs.openssh}/bin/ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub > /dev/console + echo "-----END SSH HOST KEY FINGERPRINTS-----" > /dev/console + ''; + }; + + +} diff --git a/modules/virtualisation/nova-image.nix b/modules/virtualisation/nova-image.nix new file mode 100644 index 000000000000..3b3fa28d6bbe --- /dev/null +++ b/modules/virtualisation/nova-image.nix @@ -0,0 +1,123 @@ +{ config, pkgs, ... }: + +with pkgs.lib; + +{ + require = [ ../profiles/qemu-guest.nix ./ec2-data.nix ]; + + system.build.novaImage = + pkgs.vmTools.runInLinuxVM ( + pkgs.runCommand "nova-image" + { preVM = + '' + mkdir $out + diskImage=$out/image + ${pkgs.vmTools.kvm}/bin/qemu-img create -f raw $diskImage "4G" + ''; + buildInputs = [ pkgs.utillinux pkgs.perl ]; + exportReferencesGraph = + [ "closure" config.system.build.toplevel ]; + } + '' + # Create a single / partition. + ${pkgs.parted}/sbin/parted /dev/vda mklabel msdos + ${pkgs.parted}/sbin/parted /dev/vda -- mkpart primary ext2 1M -1s + . /sys/class/block/vda1/uevent + mknod /dev/vda1 b $MAJOR $MINOR + + # Create an empty filesystem and mount it. + ${pkgs.e2fsprogs}/sbin/mkfs.ext3 -L nixos /dev/vda1 + ${pkgs.e2fsprogs}/sbin/tune2fs -c 0 -i 0 /dev/vda1 + mkdir /mnt + mount /dev/vda1 /mnt + + # The initrd expects these directories to exist. + mkdir /mnt/dev /mnt/proc /mnt/sys + mount --bind /proc /mnt/proc + mount --bind /dev /mnt/dev + mount --bind /sys /mnt/sys + + # Copy all paths in the closure to the filesystem. + storePaths=$(perl ${pkgs.pathsFromGraph} $ORIG_TMPDIR/closure) + + mkdir -p /mnt/nix/store + ${pkgs.rsync}/bin/rsync -av $storePaths /mnt/nix/store/ + + # Register the paths in the Nix database. + printRegistration=1 perl ${pkgs.pathsFromGraph} $ORIG_TMPDIR/closure | \ + chroot /mnt ${config.environment.nix}/bin/nix-store --load-db + + # Create the system profile to allow nixos-rebuild to work. + chroot /mnt ${config.environment.nix}/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 + + # 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 /mnt/dev /mnt/sys + umount /mnt + '' + ); + + fileSystems = + [ { mountPoint = "/"; + device = "/dev/disk/by-label/nixos"; + } + #{ mountPoint = "/ephemeral0"; + # device = "/dev/xvdc"; + # neededForBoot = true; + #} + ]; + + /* + swapDevices = + [ { device = "/dev/xvdb"; } ]; + */ + + boot.kernelParams = [ "console=ttyS0" ]; + + boot.initrd.kernelModules = [ "aufs" ]; + + boot.extraModulePackages = [ config.boot.kernelPackages.aufs2 ]; + + boot.loader.grub.version = 2; + boot.loader.grub.device = "/dev/vda"; + boot.loader.grub.timeout = 0; + + # Put /tmp and /var on /ephemeral0, which has a lot more space. + # Unfortunately we can't do this with the `fileSystems' option + # because it has no support for creating the source of a bind + # mount. Also, "move" /nix to /ephemeral0 by layering an AUFS + # on top of it so we have a lot more space for Nix operations. + /* + boot.initrd.postMountCommands = + '' + mkdir -m 1777 -p $targetRoot/ephemeral0/tmp + mkdir -m 1777 -p $targetRoot/tmp + mount --bind $targetRoot/ephemeral0/tmp $targetRoot/tmp + + mkdir -m 755 -p $targetRoot/ephemeral0/var + mkdir -m 755 -p $targetRoot/var + mount --bind $targetRoot/ephemeral0/var $targetRoot/var + + mkdir -m 755 -p $targetRoot/ephemeral0/nix + mount -t aufs -o dirs=$targetRoot/ephemeral0/nix=rw:$targetRoot/nix=rr none $targetRoot/nix + ''; + */ + + # There are no virtual consoles. + services.mingetty.ttys = [ ]; + + # 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"; +}