nixpkgs/pkgs/build-support/vm/windows/default.nix

71 lines
1.7 KiB
Nix
Raw Normal View History

vm: Introduce new Windows VM installer for Cygwin. After quite a lot of fighting against Windows and its various limitations, this new is the base architecture for installing and accessing the Windows VM and thus the Cygwin environment inside it: .------------. .---> | vde_switch | | `-[#]----[#]-' | | | ,' .' `---.___ ,' 192.168.0.1 `. | | 192.168.0.2 ,' _____[#]____ | ,' | | ______[#]______ | | Windows VM | | .--' | | |____________| | | | | | /|\ | .-| | | .---------. | | | | | | .-|-| manager |-' | | | | | | | `---------' | | | | | | | | | | | | | | .-------------. | | Samba | | | | BOOTSTRAP | | | | | | | | |-------------| | | | | .------| | `-| spawn VMs |-+--> | | `---| xchg | <-------. | |-------------| | | .---^------| | | | install |---. | `-| nixstore | <----. | | |-------------| | | `----------| | | |---| suspend VM | | | | | | | `------.------' | | Controller VM | | | | | | |_______________| | | | .--' | /|\ VirtIO | | __|__________:____________ | | | \|/ | | `. | | | | .------------. | | : | | | | | REAL BUILD | | | .-------^--------. | | | | |------------| | `-> | serial console | | | | `-| revive VM | | `----------------' | | | |------------| |------------. | | | | build |-->| /nix/store >>>-----------|-' | |------------| |------------| | | | collect |<--| xchg >>>-----------|----' `-----.------' |------------' | | | | \|/ | | | __ ___ | | | |--| | | (__ -|- | F I N I S H E D | | | |__| ___) | | |__________________________| This might look a bit overwhelming, but let me try to explain: We're starting at the base derivation ("BOOTSTRAP" above), where we actually install the Cygwin envirenment. Over there we basically fire up a vde_switch process and two virtual machines: One is the Windows machine, the other is a NixOS machine, which serves as some kind of proxy between the host and the Windows machine. The reason we're doing this, is because we don't have a lot of options for sharing files between a stock Windows machine and the host. In earlier experiments, I've tried to communicate with the Windows guest by using pipes and OpenSSH, but obviously this wasn't a big speed rush (or to say it bluntly: It was fucking slow). Using TCP/IP directly for accessing the guest would have been another option, but it could lead to possible errors when the port or a range of ports are in use at the Host system. Also, we would need to punch a hole into the sandbox of the Nix builder (as it doesn't allow networking), which in turn will possibly undermine deterministic builds/runs (well, at least as deterministic as it can be, we're running Windows, remember?). So, let's continue: The responsibility of the NixOS (controller) VM is to just wait until an SSH port becomes available on the Windows VM, whereas the Windows VM itself is installed using an unattended installation file provided via a virtual floppy image. With the installation of the basic Windows OS, we directly install Cygwin and start up an OpenSSH service. At this point the bootstrapping is almost finished and as soon as the port is available, the controller VM sets up Samba shares and makes it available as drive letters within Windows and as bind mounts (for example /nix/store) within Cygwin. Finally we're making a snapshot of the memory of the Windows VM in order to revive it within a few seconds when we want to build something. Now, the build process itself is fairly straightforward: Revive VM and build based on existing store derivations and collect the result _and_ the exit code from the xchg share/directory. Conclusion: This architecture may sound a bit complicated, but we're trying to achieve deterministic and reproducable builds and/or test runs. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2014-02-15 06:47:57 +04:00
let
inherit (import <nixpkgs> {}) lib stdenv requireFile writeText qemu;
vm: Introduce new Windows VM installer for Cygwin. After quite a lot of fighting against Windows and its various limitations, this new is the base architecture for installing and accessing the Windows VM and thus the Cygwin environment inside it: .------------. .---> | vde_switch | | `-[#]----[#]-' | | | ,' .' `---.___ ,' 192.168.0.1 `. | | 192.168.0.2 ,' _____[#]____ | ,' | | ______[#]______ | | Windows VM | | .--' | | |____________| | | | | | /|\ | .-| | | .---------. | | | | | | .-|-| manager |-' | | | | | | | `---------' | | | | | | | | | | | | | | .-------------. | | Samba | | | | BOOTSTRAP | | | | | | | | |-------------| | | | | .------| | `-| spawn VMs |-+--> | | `---| xchg | <-------. | |-------------| | | .---^------| | | | install |---. | `-| nixstore | <----. | | |-------------| | | `----------| | | |---| suspend VM | | | | | | | `------.------' | | Controller VM | | | | | | |_______________| | | | .--' | /|\ VirtIO | | __|__________:____________ | | | \|/ | | `. | | | | .------------. | | : | | | | | REAL BUILD | | | .-------^--------. | | | | |------------| | `-> | serial console | | | | `-| revive VM | | `----------------' | | | |------------| |------------. | | | | build |-->| /nix/store >>>-----------|-' | |------------| |------------| | | | collect |<--| xchg >>>-----------|----' `-----.------' |------------' | | | | \|/ | | | __ ___ | | | |--| | | (__ -|- | F I N I S H E D | | | |__| ___) | | |__________________________| This might look a bit overwhelming, but let me try to explain: We're starting at the base derivation ("BOOTSTRAP" above), where we actually install the Cygwin envirenment. Over there we basically fire up a vde_switch process and two virtual machines: One is the Windows machine, the other is a NixOS machine, which serves as some kind of proxy between the host and the Windows machine. The reason we're doing this, is because we don't have a lot of options for sharing files between a stock Windows machine and the host. In earlier experiments, I've tried to communicate with the Windows guest by using pipes and OpenSSH, but obviously this wasn't a big speed rush (or to say it bluntly: It was fucking slow). Using TCP/IP directly for accessing the guest would have been another option, but it could lead to possible errors when the port or a range of ports are in use at the Host system. Also, we would need to punch a hole into the sandbox of the Nix builder (as it doesn't allow networking), which in turn will possibly undermine deterministic builds/runs (well, at least as deterministic as it can be, we're running Windows, remember?). So, let's continue: The responsibility of the NixOS (controller) VM is to just wait until an SSH port becomes available on the Windows VM, whereas the Windows VM itself is installed using an unattended installation file provided via a virtual floppy image. With the installation of the basic Windows OS, we directly install Cygwin and start up an OpenSSH service. At this point the bootstrapping is almost finished and as soon as the port is available, the controller VM sets up Samba shares and makes it available as drive letters within Windows and as bind mounts (for example /nix/store) within Cygwin. Finally we're making a snapshot of the memory of the Windows VM in order to revive it within a few seconds when we want to build something. Now, the build process itself is fairly straightforward: Revive VM and build based on existing store derivations and collect the result _and_ the exit code from the xchg share/directory. Conclusion: This architecture may sound a bit complicated, but we're trying to achieve deterministic and reproducable builds and/or test runs. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2014-02-15 06:47:57 +04:00
winISO = /path/to/iso/XXX;
installedVM = import ./install {
isoFile = winISO;
productKey = "XXX";
vm: Introduce new Windows VM installer for Cygwin. After quite a lot of fighting against Windows and its various limitations, this new is the base architecture for installing and accessing the Windows VM and thus the Cygwin environment inside it: .------------. .---> | vde_switch | | `-[#]----[#]-' | | | ,' .' `---.___ ,' 192.168.0.1 `. | | 192.168.0.2 ,' _____[#]____ | ,' | | ______[#]______ | | Windows VM | | .--' | | |____________| | | | | | /|\ | .-| | | .---------. | | | | | | .-|-| manager |-' | | | | | | | `---------' | | | | | | | | | | | | | | .-------------. | | Samba | | | | BOOTSTRAP | | | | | | | | |-------------| | | | | .------| | `-| spawn VMs |-+--> | | `---| xchg | <-------. | |-------------| | | .---^------| | | | install |---. | `-| nixstore | <----. | | |-------------| | | `----------| | | |---| suspend VM | | | | | | | `------.------' | | Controller VM | | | | | | |_______________| | | | .--' | /|\ VirtIO | | __|__________:____________ | | | \|/ | | `. | | | | .------------. | | : | | | | | REAL BUILD | | | .-------^--------. | | | | |------------| | `-> | serial console | | | | `-| revive VM | | `----------------' | | | |------------| |------------. | | | | build |-->| /nix/store >>>-----------|-' | |------------| |------------| | | | collect |<--| xchg >>>-----------|----' `-----.------' |------------' | | | | \|/ | | | __ ___ | | | |--| | | (__ -|- | F I N I S H E D | | | |__| ___) | | |__________________________| This might look a bit overwhelming, but let me try to explain: We're starting at the base derivation ("BOOTSTRAP" above), where we actually install the Cygwin envirenment. Over there we basically fire up a vde_switch process and two virtual machines: One is the Windows machine, the other is a NixOS machine, which serves as some kind of proxy between the host and the Windows machine. The reason we're doing this, is because we don't have a lot of options for sharing files between a stock Windows machine and the host. In earlier experiments, I've tried to communicate with the Windows guest by using pipes and OpenSSH, but obviously this wasn't a big speed rush (or to say it bluntly: It was fucking slow). Using TCP/IP directly for accessing the guest would have been another option, but it could lead to possible errors when the port or a range of ports are in use at the Host system. Also, we would need to punch a hole into the sandbox of the Nix builder (as it doesn't allow networking), which in turn will possibly undermine deterministic builds/runs (well, at least as deterministic as it can be, we're running Windows, remember?). So, let's continue: The responsibility of the NixOS (controller) VM is to just wait until an SSH port becomes available on the Windows VM, whereas the Windows VM itself is installed using an unattended installation file provided via a virtual floppy image. With the installation of the basic Windows OS, we directly install Cygwin and start up an OpenSSH service. At this point the bootstrapping is almost finished and as soon as the port is available, the controller VM sets up Samba shares and makes it available as drive letters within Windows and as bind mounts (for example /nix/store) within Cygwin. Finally we're making a snapshot of the memory of the Windows VM in order to revive it within a few seconds when we want to build something. Now, the build process itself is fairly straightforward: Revive VM and build based on existing store derivations and collect the result _and_ the exit code from the xchg share/directory. Conclusion: This architecture may sound a bit complicated, but we're trying to achieve deterministic and reproducable builds and/or test runs. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2014-02-15 06:47:57 +04:00
};
runInVM = img: attrs: import ./controller (attrs // {
inherit (installedVM) sshKey;
qemuArgs = attrs.qemuArgs or [] ++ [
"-boot order=c"
"-drive file=${img},index=0,media=disk"
];
vm: Introduce new Windows VM installer for Cygwin. After quite a lot of fighting against Windows and its various limitations, this new is the base architecture for installing and accessing the Windows VM and thus the Cygwin environment inside it: .------------. .---> | vde_switch | | `-[#]----[#]-' | | | ,' .' `---.___ ,' 192.168.0.1 `. | | 192.168.0.2 ,' _____[#]____ | ,' | | ______[#]______ | | Windows VM | | .--' | | |____________| | | | | | /|\ | .-| | | .---------. | | | | | | .-|-| manager |-' | | | | | | | `---------' | | | | | | | | | | | | | | .-------------. | | Samba | | | | BOOTSTRAP | | | | | | | | |-------------| | | | | .------| | `-| spawn VMs |-+--> | | `---| xchg | <-------. | |-------------| | | .---^------| | | | install |---. | `-| nixstore | <----. | | |-------------| | | `----------| | | |---| suspend VM | | | | | | | `------.------' | | Controller VM | | | | | | |_______________| | | | .--' | /|\ VirtIO | | __|__________:____________ | | | \|/ | | `. | | | | .------------. | | : | | | | | REAL BUILD | | | .-------^--------. | | | | |------------| | `-> | serial console | | | | `-| revive VM | | `----------------' | | | |------------| |------------. | | | | build |-->| /nix/store >>>-----------|-' | |------------| |------------| | | | collect |<--| xchg >>>-----------|----' `-----.------' |------------' | | | | \|/ | | | __ ___ | | | |--| | | (__ -|- | F I N I S H E D | | | |__| ___) | | |__________________________| This might look a bit overwhelming, but let me try to explain: We're starting at the base derivation ("BOOTSTRAP" above), where we actually install the Cygwin envirenment. Over there we basically fire up a vde_switch process and two virtual machines: One is the Windows machine, the other is a NixOS machine, which serves as some kind of proxy between the host and the Windows machine. The reason we're doing this, is because we don't have a lot of options for sharing files between a stock Windows machine and the host. In earlier experiments, I've tried to communicate with the Windows guest by using pipes and OpenSSH, but obviously this wasn't a big speed rush (or to say it bluntly: It was fucking slow). Using TCP/IP directly for accessing the guest would have been another option, but it could lead to possible errors when the port or a range of ports are in use at the Host system. Also, we would need to punch a hole into the sandbox of the Nix builder (as it doesn't allow networking), which in turn will possibly undermine deterministic builds/runs (well, at least as deterministic as it can be, we're running Windows, remember?). So, let's continue: The responsibility of the NixOS (controller) VM is to just wait until an SSH port becomes available on the Windows VM, whereas the Windows VM itself is installed using an unattended installation file provided via a virtual floppy image. With the installation of the basic Windows OS, we directly install Cygwin and start up an OpenSSH service. At this point the bootstrapping is almost finished and as soon as the port is available, the controller VM sets up Samba shares and makes it available as drive letters within Windows and as bind mounts (for example /nix/store) within Cygwin. Finally we're making a snapshot of the memory of the Windows VM in order to revive it within a few seconds when we want to build something. Now, the build process itself is fairly straightforward: Revive VM and build based on existing store derivations and collect the result _and_ the exit code from the xchg share/directory. Conclusion: This architecture may sound a bit complicated, but we're trying to achieve deterministic and reproducable builds and/or test runs. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2014-02-15 06:47:57 +04:00
});
runAndSuspend = let
drives = {
s = {
source = "nixstore";
target = "/nix/store";
};
x = {
source = "xchg";
target = "/tmp/xchg";
};
};
genDriveCmds = letter: { source, target }: [
"net use ${letter}: '\\\\192.168.0.2\\${source}' /persistent:yes"
"mkdir -p '${target}'"
"mount -o bind '/cygdrive/${letter}' '${target}'"
"echo '/cygdrive/${letter} ${target} none bind 0 0' >> /etc/fstab"
];
in runInVM "winvm.img" {
command = lib.concatStringsSep " && " ([
"net config server /autodisconnect:-1"
] ++ lib.concatLists (lib.mapAttrsToList genDriveCmds drives));
suspendTo = "state.gz";
};
vm: Introduce new Windows VM installer for Cygwin. After quite a lot of fighting against Windows and its various limitations, this new is the base architecture for installing and accessing the Windows VM and thus the Cygwin environment inside it: .------------. .---> | vde_switch | | `-[#]----[#]-' | | | ,' .' `---.___ ,' 192.168.0.1 `. | | 192.168.0.2 ,' _____[#]____ | ,' | | ______[#]______ | | Windows VM | | .--' | | |____________| | | | | | /|\ | .-| | | .---------. | | | | | | .-|-| manager |-' | | | | | | | `---------' | | | | | | | | | | | | | | .-------------. | | Samba | | | | BOOTSTRAP | | | | | | | | |-------------| | | | | .------| | `-| spawn VMs |-+--> | | `---| xchg | <-------. | |-------------| | | .---^------| | | | install |---. | `-| nixstore | <----. | | |-------------| | | `----------| | | |---| suspend VM | | | | | | | `------.------' | | Controller VM | | | | | | |_______________| | | | .--' | /|\ VirtIO | | __|__________:____________ | | | \|/ | | `. | | | | .------------. | | : | | | | | REAL BUILD | | | .-------^--------. | | | | |------------| | `-> | serial console | | | | `-| revive VM | | `----------------' | | | |------------| |------------. | | | | build |-->| /nix/store >>>-----------|-' | |------------| |------------| | | | collect |<--| xchg >>>-----------|----' `-----.------' |------------' | | | | \|/ | | | __ ___ | | | |--| | | (__ -|- | F I N I S H E D | | | |__| ___) | | |__________________________| This might look a bit overwhelming, but let me try to explain: We're starting at the base derivation ("BOOTSTRAP" above), where we actually install the Cygwin envirenment. Over there we basically fire up a vde_switch process and two virtual machines: One is the Windows machine, the other is a NixOS machine, which serves as some kind of proxy between the host and the Windows machine. The reason we're doing this, is because we don't have a lot of options for sharing files between a stock Windows machine and the host. In earlier experiments, I've tried to communicate with the Windows guest by using pipes and OpenSSH, but obviously this wasn't a big speed rush (or to say it bluntly: It was fucking slow). Using TCP/IP directly for accessing the guest would have been another option, but it could lead to possible errors when the port or a range of ports are in use at the Host system. Also, we would need to punch a hole into the sandbox of the Nix builder (as it doesn't allow networking), which in turn will possibly undermine deterministic builds/runs (well, at least as deterministic as it can be, we're running Windows, remember?). So, let's continue: The responsibility of the NixOS (controller) VM is to just wait until an SSH port becomes available on the Windows VM, whereas the Windows VM itself is installed using an unattended installation file provided via a virtual floppy image. With the installation of the basic Windows OS, we directly install Cygwin and start up an OpenSSH service. At this point the bootstrapping is almost finished and as soon as the port is available, the controller VM sets up Samba shares and makes it available as drive letters within Windows and as bind mounts (for example /nix/store) within Cygwin. Finally we're making a snapshot of the memory of the Windows VM in order to revive it within a few seconds when we want to build something. Now, the build process itself is fairly straightforward: Revive VM and build based on existing store derivations and collect the result _and_ the exit code from the xchg share/directory. Conclusion: This architecture may sound a bit complicated, but we're trying to achieve deterministic and reproducable builds and/or test runs. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2014-02-15 06:47:57 +04:00
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"
vm: Introduce new Windows VM installer for Cygwin. After quite a lot of fighting against Windows and its various limitations, this new is the base architecture for installing and accessing the Windows VM and thus the Cygwin environment inside it: .------------. .---> | vde_switch | | `-[#]----[#]-' | | | ,' .' `---.___ ,' 192.168.0.1 `. | | 192.168.0.2 ,' _____[#]____ | ,' | | ______[#]______ | | Windows VM | | .--' | | |____________| | | | | | /|\ | .-| | | .---------. | | | | | | .-|-| manager |-' | | | | | | | `---------' | | | | | | | | | | | | | | .-------------. | | Samba | | | | BOOTSTRAP | | | | | | | | |-------------| | | | | .------| | `-| spawn VMs |-+--> | | `---| xchg | <-------. | |-------------| | | .---^------| | | | install |---. | `-| nixstore | <----. | | |-------------| | | `----------| | | |---| suspend VM | | | | | | | `------.------' | | Controller VM | | | | | | |_______________| | | | .--' | /|\ VirtIO | | __|__________:____________ | | | \|/ | | `. | | | | .------------. | | : | | | | | REAL BUILD | | | .-------^--------. | | | | |------------| | `-> | serial console | | | | `-| revive VM | | `----------------' | | | |------------| |------------. | | | | build |-->| /nix/store >>>-----------|-' | |------------| |------------| | | | collect |<--| xchg >>>-----------|----' `-----.------' |------------' | | | | \|/ | | | __ ___ | | | |--| | | (__ -|- | F I N I S H E D | | | |__| ___) | | |__________________________| This might look a bit overwhelming, but let me try to explain: We're starting at the base derivation ("BOOTSTRAP" above), where we actually install the Cygwin envirenment. Over there we basically fire up a vde_switch process and two virtual machines: One is the Windows machine, the other is a NixOS machine, which serves as some kind of proxy between the host and the Windows machine. The reason we're doing this, is because we don't have a lot of options for sharing files between a stock Windows machine and the host. In earlier experiments, I've tried to communicate with the Windows guest by using pipes and OpenSSH, but obviously this wasn't a big speed rush (or to say it bluntly: It was fucking slow). Using TCP/IP directly for accessing the guest would have been another option, but it could lead to possible errors when the port or a range of ports are in use at the Host system. Also, we would need to punch a hole into the sandbox of the Nix builder (as it doesn't allow networking), which in turn will possibly undermine deterministic builds/runs (well, at least as deterministic as it can be, we're running Windows, remember?). So, let's continue: The responsibility of the NixOS (controller) VM is to just wait until an SSH port becomes available on the Windows VM, whereas the Windows VM itself is installed using an unattended installation file provided via a virtual floppy image. With the installation of the basic Windows OS, we directly install Cygwin and start up an OpenSSH service. At this point the bootstrapping is almost finished and as soon as the port is available, the controller VM sets up Samba shares and makes it available as drive letters within Windows and as bind mounts (for example /nix/store) within Cygwin. Finally we're making a snapshot of the memory of the Windows VM in order to revive it within a few seconds when we want to build something. Now, the build process itself is fairly straightforward: Revive VM and build based on existing store derivations and collect the result _and_ the exit code from the xchg share/directory. Conclusion: This architecture may sound a bit complicated, but we're trying to achieve deterministic and reproducable builds and/or test runs. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2014-02-15 06:47:57 +04:00
'';
};
vm: Introduce new Windows VM installer for Cygwin. After quite a lot of fighting against Windows and its various limitations, this new is the base architecture for installing and accessing the Windows VM and thus the Cygwin environment inside it: .------------. .---> | vde_switch | | `-[#]----[#]-' | | | ,' .' `---.___ ,' 192.168.0.1 `. | | 192.168.0.2 ,' _____[#]____ | ,' | | ______[#]______ | | Windows VM | | .--' | | |____________| | | | | | /|\ | .-| | | .---------. | | | | | | .-|-| manager |-' | | | | | | | `---------' | | | | | | | | | | | | | | .-------------. | | Samba | | | | BOOTSTRAP | | | | | | | | |-------------| | | | | .------| | `-| spawn VMs |-+--> | | `---| xchg | <-------. | |-------------| | | .---^------| | | | install |---. | `-| nixstore | <----. | | |-------------| | | `----------| | | |---| suspend VM | | | | | | | `------.------' | | Controller VM | | | | | | |_______________| | | | .--' | /|\ VirtIO | | __|__________:____________ | | | \|/ | | `. | | | | .------------. | | : | | | | | REAL BUILD | | | .-------^--------. | | | | |------------| | `-> | serial console | | | | `-| revive VM | | `----------------' | | | |------------| |------------. | | | | build |-->| /nix/store >>>-----------|-' | |------------| |------------| | | | collect |<--| xchg >>>-----------|----' `-----.------' |------------' | | | | \|/ | | | __ ___ | | | |--| | | (__ -|- | F I N I S H E D | | | |__| ___) | | |__________________________| This might look a bit overwhelming, but let me try to explain: We're starting at the base derivation ("BOOTSTRAP" above), where we actually install the Cygwin envirenment. Over there we basically fire up a vde_switch process and two virtual machines: One is the Windows machine, the other is a NixOS machine, which serves as some kind of proxy between the host and the Windows machine. The reason we're doing this, is because we don't have a lot of options for sharing files between a stock Windows machine and the host. In earlier experiments, I've tried to communicate with the Windows guest by using pipes and OpenSSH, but obviously this wasn't a big speed rush (or to say it bluntly: It was fucking slow). Using TCP/IP directly for accessing the guest would have been another option, but it could lead to possible errors when the port or a range of ports are in use at the Host system. Also, we would need to punch a hole into the sandbox of the Nix builder (as it doesn't allow networking), which in turn will possibly undermine deterministic builds/runs (well, at least as deterministic as it can be, we're running Windows, remember?). So, let's continue: The responsibility of the NixOS (controller) VM is to just wait until an SSH port becomes available on the Windows VM, whereas the Windows VM itself is installed using an unattended installation file provided via a virtual floppy image. With the installation of the basic Windows OS, we directly install Cygwin and start up an OpenSSH service. At this point the bootstrapping is almost finished and as soon as the port is available, the controller VM sets up Samba shares and makes it available as drive letters within Windows and as bind mounts (for example /nix/store) within Cygwin. Finally we're making a snapshot of the memory of the Windows VM in order to revive it within a few seconds when we want to build something. Now, the build process itself is fairly straightforward: Revive VM and build based on existing store derivations and collect the result _and_ the exit code from the xchg share/directory. Conclusion: This architecture may sound a bit complicated, but we're trying to achieve deterministic and reproducable builds and/or test runs. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2014-02-15 06:47:57 +04:00
resumeAndRun = command: runInVM "${suspendedVM}/disk.img" {
resumeFrom = "${suspendedVM}/state.gz";
qemuArgs = lib.singleton "-snapshot";
inherit command;
};
vm: Introduce new Windows VM installer for Cygwin. After quite a lot of fighting against Windows and its various limitations, this new is the base architecture for installing and accessing the Windows VM and thus the Cygwin environment inside it: .------------. .---> | vde_switch | | `-[#]----[#]-' | | | ,' .' `---.___ ,' 192.168.0.1 `. | | 192.168.0.2 ,' _____[#]____ | ,' | | ______[#]______ | | Windows VM | | .--' | | |____________| | | | | | /|\ | .-| | | .---------. | | | | | | .-|-| manager |-' | | | | | | | `---------' | | | | | | | | | | | | | | .-------------. | | Samba | | | | BOOTSTRAP | | | | | | | | |-------------| | | | | .------| | `-| spawn VMs |-+--> | | `---| xchg | <-------. | |-------------| | | .---^------| | | | install |---. | `-| nixstore | <----. | | |-------------| | | `----------| | | |---| suspend VM | | | | | | | `------.------' | | Controller VM | | | | | | |_______________| | | | .--' | /|\ VirtIO | | __|__________:____________ | | | \|/ | | `. | | | | .------------. | | : | | | | | REAL BUILD | | | .-------^--------. | | | | |------------| | `-> | serial console | | | | `-| revive VM | | `----------------' | | | |------------| |------------. | | | | build |-->| /nix/store >>>-----------|-' | |------------| |------------| | | | collect |<--| xchg >>>-----------|----' `-----.------' |------------' | | | | \|/ | | | __ ___ | | | |--| | | (__ -|- | F I N I S H E D | | | |__| ___) | | |__________________________| This might look a bit overwhelming, but let me try to explain: We're starting at the base derivation ("BOOTSTRAP" above), where we actually install the Cygwin envirenment. Over there we basically fire up a vde_switch process and two virtual machines: One is the Windows machine, the other is a NixOS machine, which serves as some kind of proxy between the host and the Windows machine. The reason we're doing this, is because we don't have a lot of options for sharing files between a stock Windows machine and the host. In earlier experiments, I've tried to communicate with the Windows guest by using pipes and OpenSSH, but obviously this wasn't a big speed rush (or to say it bluntly: It was fucking slow). Using TCP/IP directly for accessing the guest would have been another option, but it could lead to possible errors when the port or a range of ports are in use at the Host system. Also, we would need to punch a hole into the sandbox of the Nix builder (as it doesn't allow networking), which in turn will possibly undermine deterministic builds/runs (well, at least as deterministic as it can be, we're running Windows, remember?). So, let's continue: The responsibility of the NixOS (controller) VM is to just wait until an SSH port becomes available on the Windows VM, whereas the Windows VM itself is installed using an unattended installation file provided via a virtual floppy image. With the installation of the basic Windows OS, we directly install Cygwin and start up an OpenSSH service. At this point the bootstrapping is almost finished and as soon as the port is available, the controller VM sets up Samba shares and makes it available as drive letters within Windows and as bind mounts (for example /nix/store) within Cygwin. Finally we're making a snapshot of the memory of the Windows VM in order to revive it within a few seconds when we want to build something. Now, the build process itself is fairly straightforward: Revive VM and build based on existing store derivations and collect the result _and_ the exit code from the xchg share/directory. Conclusion: This architecture may sound a bit complicated, but we're trying to achieve deterministic and reproducable builds and/or test runs. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2014-02-15 06:47:57 +04:00
runFromSuspended = command: stdenv.mkDerivation {
name = "cygwin-vm-run";
vm: Introduce new Windows VM installer for Cygwin. After quite a lot of fighting against Windows and its various limitations, this new is the base architecture for installing and accessing the Windows VM and thus the Cygwin environment inside it: .------------. .---> | vde_switch | | `-[#]----[#]-' | | | ,' .' `---.___ ,' 192.168.0.1 `. | | 192.168.0.2 ,' _____[#]____ | ,' | | ______[#]______ | | Windows VM | | .--' | | |____________| | | | | | /|\ | .-| | | .---------. | | | | | | .-|-| manager |-' | | | | | | | `---------' | | | | | | | | | | | | | | .-------------. | | Samba | | | | BOOTSTRAP | | | | | | | | |-------------| | | | | .------| | `-| spawn VMs |-+--> | | `---| xchg | <-------. | |-------------| | | .---^------| | | | install |---. | `-| nixstore | <----. | | |-------------| | | `----------| | | |---| suspend VM | | | | | | | `------.------' | | Controller VM | | | | | | |_______________| | | | .--' | /|\ VirtIO | | __|__________:____________ | | | \|/ | | `. | | | | .------------. | | : | | | | | REAL BUILD | | | .-------^--------. | | | | |------------| | `-> | serial console | | | | `-| revive VM | | `----------------' | | | |------------| |------------. | | | | build |-->| /nix/store >>>-----------|-' | |------------| |------------| | | | collect |<--| xchg >>>-----------|----' `-----.------' |------------' | | | | \|/ | | | __ ___ | | | |--| | | (__ -|- | F I N I S H E D | | | |__| ___) | | |__________________________| This might look a bit overwhelming, but let me try to explain: We're starting at the base derivation ("BOOTSTRAP" above), where we actually install the Cygwin envirenment. Over there we basically fire up a vde_switch process and two virtual machines: One is the Windows machine, the other is a NixOS machine, which serves as some kind of proxy between the host and the Windows machine. The reason we're doing this, is because we don't have a lot of options for sharing files between a stock Windows machine and the host. In earlier experiments, I've tried to communicate with the Windows guest by using pipes and OpenSSH, but obviously this wasn't a big speed rush (or to say it bluntly: It was fucking slow). Using TCP/IP directly for accessing the guest would have been another option, but it could lead to possible errors when the port or a range of ports are in use at the Host system. Also, we would need to punch a hole into the sandbox of the Nix builder (as it doesn't allow networking), which in turn will possibly undermine deterministic builds/runs (well, at least as deterministic as it can be, we're running Windows, remember?). So, let's continue: The responsibility of the NixOS (controller) VM is to just wait until an SSH port becomes available on the Windows VM, whereas the Windows VM itself is installed using an unattended installation file provided via a virtual floppy image. With the installation of the basic Windows OS, we directly install Cygwin and start up an OpenSSH service. At this point the bootstrapping is almost finished and as soon as the port is available, the controller VM sets up Samba shares and makes it available as drive letters within Windows and as bind mounts (for example /nix/store) within Cygwin. Finally we're making a snapshot of the memory of the Windows VM in order to revive it within a few seconds when we want to build something. Now, the build process itself is fairly straightforward: Revive VM and build based on existing store derivations and collect the result _and_ the exit code from the xchg share/directory. Conclusion: This architecture may sound a bit complicated, but we're trying to achieve deterministic and reproducable builds and/or test runs. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2014-02-15 06:47:57 +04:00
buildCommand = ''
${resumeAndRun command}
vm: Introduce new Windows VM installer for Cygwin. After quite a lot of fighting against Windows and its various limitations, this new is the base architecture for installing and accessing the Windows VM and thus the Cygwin environment inside it: .------------. .---> | vde_switch | | `-[#]----[#]-' | | | ,' .' `---.___ ,' 192.168.0.1 `. | | 192.168.0.2 ,' _____[#]____ | ,' | | ______[#]______ | | Windows VM | | .--' | | |____________| | | | | | /|\ | .-| | | .---------. | | | | | | .-|-| manager |-' | | | | | | | `---------' | | | | | | | | | | | | | | .-------------. | | Samba | | | | BOOTSTRAP | | | | | | | | |-------------| | | | | .------| | `-| spawn VMs |-+--> | | `---| xchg | <-------. | |-------------| | | .---^------| | | | install |---. | `-| nixstore | <----. | | |-------------| | | `----------| | | |---| suspend VM | | | | | | | `------.------' | | Controller VM | | | | | | |_______________| | | | .--' | /|\ VirtIO | | __|__________:____________ | | | \|/ | | `. | | | | .------------. | | : | | | | | REAL BUILD | | | .-------^--------. | | | | |------------| | `-> | serial console | | | | `-| revive VM | | `----------------' | | | |------------| |------------. | | | | build |-->| /nix/store >>>-----------|-' | |------------| |------------| | | | collect |<--| xchg >>>-----------|----' `-----.------' |------------' | | | | \|/ | | | __ ___ | | | |--| | | (__ -|- | F I N I S H E D | | | |__| ___) | | |__________________________| This might look a bit overwhelming, but let me try to explain: We're starting at the base derivation ("BOOTSTRAP" above), where we actually install the Cygwin envirenment. Over there we basically fire up a vde_switch process and two virtual machines: One is the Windows machine, the other is a NixOS machine, which serves as some kind of proxy between the host and the Windows machine. The reason we're doing this, is because we don't have a lot of options for sharing files between a stock Windows machine and the host. In earlier experiments, I've tried to communicate with the Windows guest by using pipes and OpenSSH, but obviously this wasn't a big speed rush (or to say it bluntly: It was fucking slow). Using TCP/IP directly for accessing the guest would have been another option, but it could lead to possible errors when the port or a range of ports are in use at the Host system. Also, we would need to punch a hole into the sandbox of the Nix builder (as it doesn't allow networking), which in turn will possibly undermine deterministic builds/runs (well, at least as deterministic as it can be, we're running Windows, remember?). So, let's continue: The responsibility of the NixOS (controller) VM is to just wait until an SSH port becomes available on the Windows VM, whereas the Windows VM itself is installed using an unattended installation file provided via a virtual floppy image. With the installation of the basic Windows OS, we directly install Cygwin and start up an OpenSSH service. At this point the bootstrapping is almost finished and as soon as the port is available, the controller VM sets up Samba shares and makes it available as drive letters within Windows and as bind mounts (for example /nix/store) within Cygwin. Finally we're making a snapshot of the memory of the Windows VM in order to revive it within a few seconds when we want to build something. Now, the build process itself is fairly straightforward: Revive VM and build based on existing store derivations and collect the result _and_ the exit code from the xchg share/directory. Conclusion: This architecture may sound a bit complicated, but we're trying to achieve deterministic and reproducable builds and/or test runs. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2014-02-15 06:47:57 +04:00
'';
};
in runFromSuspended "uname -a"