diff options
author | aszlig <aszlig@redmoonstudios.org> | 2014-02-15 23:23:47 +0100 |
---|---|---|
committer | aszlig <aszlig@redmoonstudios.org> | 2014-02-26 04:51:56 +0100 |
commit | c731467e2c83f3df0b59c44575616e6241a63c7d (patch) | |
tree | d86cba504d645898458142bd425980c8d7ebafb3 /pkgs/build-support/vm/windows/default.nix | |
parent | 5105e7f0bfc3a9131df5a8f3bf4d899a01b0106b (diff) | |
download | nixpkgs-c731467e2c83f3df0b59c44575616e6241a63c7d.tar nixpkgs-c731467e2c83f3df0b59c44575616e6241a63c7d.tar.gz nixpkgs-c731467e2c83f3df0b59c44575616e6241a63c7d.tar.bz2 nixpkgs-c731467e2c83f3df0b59c44575616e6241a63c7d.tar.lz nixpkgs-c731467e2c83f3df0b59c44575616e6241a63c7d.tar.xz nixpkgs-c731467e2c83f3df0b59c44575616e6241a63c7d.tar.zst nixpkgs-c731467e2c83f3df0b59c44575616e6241a63c7d.zip |
vm/windows: Split install into several stages.
These stages are in particular: * Install of the bare Windows VM with Cygwin and shut down. * Boot up the same VM again without the installation media and dump the VMs memory to state.gz. * Resume from state.gz and build whatever we want to build. Every single stage involves a new "controller", which is more like an abstraction on the Nix side that constructs the madness described in 276b72fb93d60ae0e59088ea0e0029da87e6f31c. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Diffstat (limited to 'pkgs/build-support/vm/windows/default.nix')
-rw-r--r-- | pkgs/build-support/vm/windows/default.nix | 175 |
1 files changed, 32 insertions, 143 deletions
diff --git a/pkgs/build-support/vm/windows/default.nix b/pkgs/build-support/vm/windows/default.nix index 470fac0437d..2ecadbae7cf 100644 --- a/pkgs/build-support/vm/windows/default.nix +++ b/pkgs/build-support/vm/windows/default.nix @@ -1,160 +1,49 @@ -with import <nixpkgs> {}; - -with import <nixpkgs/nixos/lib/build-vms.nix> { - inherit system; - minimal = false; -}; - let + inherit (import <nixpkgs> {}) lib stdenv requireFile writeText qemu; + winISO = /path/to/iso/XXX; - base = import ./install { + installedVM = import ./install { isoFile = winISO; productKey = "XXX"; }; - maybeKvm64 = lib.optional (stdenv.system == "x86_64-linux") "-cpu kvm64"; - - cygwinQemuArgs = lib.concatStringsSep " " (maybeKvm64 ++ [ - "-monitor unix:$MONITOR_SOCKET,server,nowait" - "-nographic" - "-boot order=c,once=d" - "-drive file=${base.floppy},readonly,index=0,if=floppy" - "-drive file=winvm.img,index=0,media=disk" - "-drive file=${winISO},index=1,media=cdrom" - "-drive file=${base.iso}/iso/cd.iso,index=2,media=cdrom" - "-net nic,vlan=0,macaddr=52:54:00:12:01:01" - "-net vde,vlan=0,sock=$QEMU_VDE_SOCKET" - "-rtc base=2010-01-01,clock=vm" - ]); - - modulesClosure = lib.overrideDerivation vmTools.modulesClosure (o: { - rootModules = o.rootModules ++ lib.singleton "virtio_net"; + runInVM = img: attrs: import ./controller (attrs // { + inherit (installedVM) sshKey; + qemuArgs = attrs.qemuArgs or [] ++ [ + "-boot order=c" + "-drive file=${img},index=0,media=disk" + ]; }); - controllerQemuArgs = cmd: let - preInitScript = writeScript "preinit.sh" '' - #!${vmTools.initrdUtils}/bin/ash -e - export PATH=${vmTools.initrdUtils}/bin - mount -t proc none /proc - mount -t sysfs none /sys - for arg in $(cat /proc/cmdline); do - if [ "x''${arg#command=}" != "x$arg" ]; then - command="''${arg#command=}" - fi - done - - for i in $(cat ${modulesClosure}/insmod-list); do - insmod $i - done - - mkdir -p /tmp /dev - mknod /dev/null c 1 3 - mknod /dev/zero c 1 5 - mknod /dev/random c 1 8 - mknod /dev/urandom c 1 9 - mknod /dev/tty c 5 0 - - ifconfig lo up - ifconfig eth0 up 192.168.0.2 - - mkdir -p /nix/store /etc /var/run /var/log - - cat > /etc/passwd <<PASSWD - root:x:0:0::/root:/bin/false - nobody:x:65534:65534::/var/empty:/bin/false - PASSWD - - mount -t 9p \ - -o trans=virtio,version=9p2000.L,msize=262144,cache=loose \ - store /nix/store - - exec "$command" - ''; - initrd = makeInitrd { - contents = lib.singleton { - object = preInitScript; - symlink = "/init"; - }; - }; - initScript = writeScript "init.sh" '' - #!${stdenv.shell} - ${coreutils}/bin/mkdir -p /etc/samba /etc/samba/private /var/lib/samba - ${coreutils}/bin/cat > /etc/samba/smb.conf <<CONFIG - [global] - security = user - map to guest = Bad User - workgroup = cygwin - netbios name = controller - server string = %h - log level = 1 - max log size = 1000 - log file = /var/log/samba.log - - [nixstore] - path = /nix/store - read only = no - guest ok = yes - CONFIG - - ${samba}/sbin/nmbd -D - ${samba}/sbin/smbd -D - ${coreutils}/bin/cp -L "${base.sshKey}" /ssh.key - ${coreutils}/bin/chmod 600 /ssh.key - - echo -n "Waiting for Windows VM to become ready" - while ! ${netcat}/bin/netcat -z 192.168.0.1 22; do - echo -n . - ${coreutils}/bin/sleep 1 - done - echo " ready." - - ${openssh}/bin/ssh \ - -o UserKnownHostsFile=/dev/null \ - -o StrictHostKeyChecking=no \ - -i /ssh.key \ - -l Administrator \ - 192.168.0.1 -- "${cmd}" + runAndSuspend = runInVM "winvm.img" { + suspendTo = "state.gz"; + }; - ${busybox}/sbin/poweroff -f + suspendedVM = stdenv.mkDerivation { + name = "cygwin-suspended-vm"; + buildCommand = '' + ${qemu}/bin/qemu-img create \ + -b "${installedVM}/disk.img" \ + -f qcow2 winvm.img + ${runAndSuspend} + ensureDir "$out" + cp winvm.img "$out/disk.img" + cp state.gz "$out/state.gz" ''; - kernelAppend = lib.concatStringsSep " " [ - "panic=1" - "loglevel=4" - "console=tty1" - "console=ttyS0" - "command=${initScript}" - ]; - in lib.concatStringsSep " " (maybeKvm64 ++ [ - "-nographic" - "-no-reboot" - "-virtfs local,path=/nix/store,security_model=none,mount_tag=store" - "-kernel ${modulesClosure.kernel}/bzImage" - "-initrd ${initrd}/initrd" - "-append \"${kernelAppend}\"" - "-net nic,vlan=0,macaddr=52:54:00:12:01:02,model=virtio" - "-net vde,vlan=0,sock=$QEMU_VDE_SOCKET" - ]); + }; - bootstrap = stdenv.mkDerivation { - name = "windown-vm"; + resumeAndRun = command: runInVM "${suspendedVM}/disk.img" { + resumeFrom = "${suspendedVM}/state.gz"; + qemuArgs = lib.singleton "-snapshot"; + inherit command; + }; + runFromSuspended = command: stdenv.mkDerivation { + name = "cygwin-vm-run"; buildCommand = '' - ${qemu}/bin/qemu-img create -f qcow2 winvm.img 2G - QEMU_VDE_SOCKET="$(pwd)/vde.ctl" - MONITOR_SOCKET="$(pwd)/monitor" - ${vde2}/bin/vde_switch -s "$QEMU_VDE_SOCKET" & - ${vmTools.qemuProg} ${cygwinQemuArgs} & - ${vmTools.qemuProg} ${controllerQemuArgs "sync"} - - ensureDir "$out" - ${socat}/bin/socat - UNIX-CONNECT:$MONITOR_SOCKET <<CMD - stop - migrate_set_speed 4095m - migrate "exec:${gzip}/bin/gzip -c > '$out/state.gz'" - CMD - cp winvm.img "$out/disk.img" + ${resumeAndRun command} ''; }; -in bootstrap +in runFromSuspended "uname -a" |