From da77a6437f63c98132135f158970cac7b295f3f3 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 19 Jun 2009 15:19:56 +0000 Subject: [PATCH] * qemu-vm.nix: automatically create and initialise the disk image if it doesn't already exist. Also set up some ad hoc port forwarding from the host to the guest. svn path=/nixos/branches/modular-nixos/; revision=16012 --- modules/system/boot/stage-1.nix | 12 +++++ modules/virtualisation/qemu-vm.nix | 75 ++++++++++++++++++++++++------ 2 files changed, 73 insertions(+), 14 deletions(-) diff --git a/modules/system/boot/stage-1.nix b/modules/system/boot/stage-1.nix index 3ff69ac12da..c91c4d93333 100644 --- a/modules/system/boot/stage-1.nix +++ b/modules/system/boot/stage-1.nix @@ -81,6 +81,16 @@ let ''; }; + boot.initrd.extraUtilsCommands = mkOption { + default = ""; + merge = pkgs.lib.mergeStringOption; + description = '' + Shell commands to be executed in the builder of the + extra-utils derivation. This can be used to provide + additional utilities in the initial ramdisk. + ''; + }; + fileSystems = mkOption { options.neededForBoot = mkOption { default = false; @@ -167,6 +177,8 @@ let cp ${pkgs.bash}/bin/bash $out/bin ln -s bash $out/bin/sh + ${config.boot.initrd.extraUtilsCommands} + # Run patchelf to make the programs refer to the copied libraries. for i in $out/bin/* $out/lib/*; do if ! test -L $i; then nuke-refs $i; fi; done diff --git a/modules/virtualisation/qemu-vm.nix b/modules/virtualisation/qemu-vm.nix index d532208378e..db12c2c9bb4 100644 --- a/modules/virtualisation/qemu-vm.nix +++ b/modules/virtualisation/qemu-vm.nix @@ -9,16 +9,75 @@ {config, pkgs, ...}: +let + + options = { + + virtualisation.diskImage = + pkgs.lib.mkOption { + default = "./${config.networking.hostName}.qcow2"; + description = + '' + Path to the disk image containing the root filesystem. + The image will be created on startup if it does not + exist. + ''; + }; + + }; + + + # Shell script to start the VM. + startVM = + '' + #! ${pkgs.stdenv.shell} + + export PATH=${pkgs.samba}/sbin:$PATH + + NIX_DISK_IMAGE=''${NIX_DISK_IMAGE:-${config.virtualisation.diskImage}} + + if ! test -e "$NIX_DISK_IMAGE"; then + ${pkgs.kvm}/bin/qemu-img create -f qcow2 "$NIX_DISK_IMAGE" 512M || exit 1 + fi + + ${pkgs.kvm}/bin/qemu-system-x86_64 \ + -net nic,model=virtio -net user -smb / \ + -drive file=$NIX_DISK_IMAGE,if=virtio,boot=on \ + -kernel ${config.system.build.system}/kernel \ + -initrd ${config.system.build.system}/initrd \ + -redir tcp:8080::80 \ + -redir tcp:8022::22 \ + -append "$(cat ${config.system.build.system}/kernel-params) init=${config.system.build.bootStage2} systemConfig=${config.system.build.system}" + ''; + +in + { + require = options; + # All the modules the initrd needs to mount the host filesystem via # CIFS. Also use paravirtualised network and block devices for # performance. boot.initrd.extraKernelModules = ["cifs" "virtio_net" "virtio_pci" "virtio_blk" "virtio_balloon" "nls_utf8"]; + boot.initrd.extraUtilsCommands = + '' + # We need mke2fs in the initrd. + cp ${pkgs.e2fsprogs}/sbin/mke2fs $out/bin + ''; + boot.initrd.postDeviceCommands = '' + # Set up networking. Needed for CIFS mounting. ipconfig 10.0.2.15:::::eth0:none + + # If the disk image appears to be empty (fstype "unknown"; + # hacky!!!), run mke2fs to initialise. + eval $(fstype /dev/vda) + if test "$FSTYPE" = unknown; then + mke2fs -t ext3 /dev/vda + fi ''; # Mount the host filesystem via CIFS, and bind-mount the Nix store @@ -46,21 +105,9 @@ system.build.vm = pkgs.runCommand "nixos-vm" {} '' - ensureDir $out - ln -s ${config.system.build.system} $out/system - ensureDir $out/bin - cat > $out/bin/run-nixos-vm <