{ stdenv, writeScript, vmTools, makeInitrd , samba, vde2, openssh, socat, netcat, coreutils, gzip }: { sshKey , qemuArgs ? [] , command ? "sync" , suspendTo ? null , resumeFrom ? null , installMode ? false }: with stdenv.lib; 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 /dev /fs mount -t tmpfs none /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 mount -t tmpfs none /fs mkdir -p /fs/nix/store /fs/xchg /fs/dev /fs/sys /fs/proc /fs/etc /fs/tmp mount -o bind /dev /fs/dev mount -t sysfs none /fs/sys mount -t proc none /fs/proc mount -t 9p \ -o trans=virtio,version=9p2000.L,msize=262144,cache=loose \ store /fs/nix/store mount -t 9p \ -o trans=virtio,version=9p2000.L,msize=262144,cache=loose \ xchg /fs/xchg echo root:x:0:0::/root:/bin/false > /fs/etc/passwd set +e chroot /fs $command $out echo $? > /fs/xchg/in-vm-exit poweroff -f ''; initrd = makeInitrd { contents = singleton { object = preInitScript; symlink = "/init"; }; }; shellEscape = x: "'${replaceChars ["'"] [("'\\'" + "'")] x}'"; loopForever = "while :; do ${coreutils}/bin/sleep 1; done"; initScript = writeScript "init.sh" ('' #!${stdenv.shell} ${coreutils}/bin/cp -L "${sshKey}" /ssh.key ${coreutils}/bin/chmod 600 /ssh.key '' + (if installMode then '' echo -n "Waiting for Windows installation to finish..." while ! ${netcat}/bin/netcat -z 192.168.0.1 22; do echo -n . # Print a dot every 10 seconds only to shorten line length. ${coreutils}/bin/sleep 10 done echo " success." # Loop forever, because this VM is going to be killed. ${loopForever} '' else '' ${coreutils}/bin/mkdir -p /etc/samba /etc/samba/private \ /var/lib/samba /var/log /var/run ${coreutils}/bin/cat > /etc/samba/smb.conf < saved-env XCHG_DIR="$(${coreutils}/bin/mktemp -d nix-vm.XXXXXXXXXX --tmpdir)" ${coreutils}/bin/mv saved-env "$XCHG_DIR/" eval "$preVM" QEMU_VDE_SOCKET="$(pwd)/vde.ctl" MONITOR_SOCKET="$(pwd)/monitor" ${vde2}/bin/vde_switch -s "$QEMU_VDE_SOCKET" & echo 'alive?' | ${socat}/bin/socat - \ UNIX-CONNECT:$QEMU_VDE_SOCKET/ctl,retry=20 ''; bgBoth = optionalString (suspendTo != null) " &"; vmExec = if installMode then '' ${vmTools.qemuProg} ${controllerQemuArgs} & ${vmTools.qemuProg} ${cygwinQemuArgs}${bgBoth} '' else '' ${vmTools.qemuProg} ${cygwinQemuArgs} & ${vmTools.qemuProg} ${controllerQemuArgs}${bgBoth} ''; postVM = if suspendTo != null then '' while ! test -e "$XCHG_DIR/suspend_now"; do sleep 1; done ${socat}/bin/socat - UNIX-CONNECT:$MONITOR_SOCKET < '${suspendTo}'" quit CMD wait %- eval "$postVM" exit 0 '' else if installMode then '' eval "$postVM" exit 0 '' else '' if ! test -e "$XCHG_DIR/in-vm-exit"; then echo "Virtual machine didn't produce an exit code." exit 1 fi eval "$postVM" exit $(< "$XCHG_DIR/in-vm-exit") ''; in writeScript "run-cygwin-vm.sh" '' #!${stdenv.shell} -e ${preVM} ${vmExec} ${postVM} ''