{ sshKey , qemuArgs ? [] , command ? "sync" , suspendTo ? null , resumeFrom ? null , installMode ? false }: let inherit (import {}) lib stdenv writeScript vmTools makeInitrd; inherit (import {}) samba vde2 openssh socat netcat coreutils gzip; 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 = lib.singleton { object = preInitScript; symlink = "/init"; }; }; shellEscape = x: "'${lib.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 < '${suspendTo}'" quit CMD wait %- ''; in writeScript "run-cygwin-vm.sh" '' #!${stdenv.shell} -e ${preVM} ${vmExec} ''