nixpkgs/lib/build-vms.nix

121 lines
4.1 KiB
Nix
Raw Normal View History

- Added nixos-build-vms command, which builds a virtual network from a network.nix expression (also used by nixos-deploy-network) - Added a backdoor option to the interactive run-vms script. This allows me to intergrate the virtual network approach with Disnix - Small documentation fixes Some explanation: The nixos-build-vms command line tool can be used to build a virtual network of a network.nix specification. For example, a network configuration (network.nix) could look like this: { test1 = {pkgs, config, ...}: { services.openssh.enable = true; ... }; test2 = {pkgs, config, ...}: { services.openssh.enable = true; services.xserver.enable = true; } ; } By typing the following instruction: $ nixos-build-vms -n network.nix a virtual network is built, which can be started by typing: $ ./result/bin/run-vms It is also possible to enable a backdoor. In this case *.socket files are stored in the current directory which can be used by the end-user to invoke remote instruction on a VM in the network through a Unix domain socket. For example by building the network with the following instructions: $ nixos-build-vms -n network.nix --use-backdoor and launching the virtual network: $ ./result/bin/run-vms You can find two socket files in your current directory, namely: test1.socket and test2.socket. These Unix domain sockets can be used to remotely administer the test1 and test2 machine in the virtual network. For example by running: $ socat ./test1.socket stdio ls /root You can retrieve the contents of the /root directory of the virtual machine with identifier test1 svn path=/nixos/trunk/; revision=24410
2010-10-21 22:50:12 +00:00
{ nixpkgs, services, system, useBackdoor ? false }:
* Stuff for automatic and manual testing of NixOS VMs. lib/build-vms.nix contains a function `buildVirtualNetwork' that takes a specification of a network of machines (as an attribute set of NixOS machine configurations) and builds a script that starts each configuration in a separate QEMU/KVM VM and connects them together in a virtual network. This script can be run manually to test the VMs interactively. There is also a function `runTests' that starts and runs the virtual network in a derivation, and then executes a test specification that tells the VMs to do certain things (i.e., letting one VM send an HTTP request to a webserver on another VM). The tests are written in Perl (for now). tests/subversion.nix shows a simple example, namely a network of two machines: a webserver that runs the Subversion subservice, and a client. Apache, Subversion and a few other packages are built with coverage analysis instrumentation. For instance, $ nix-build tests/subversion.nix -A vms $ ./result/bin/run-vms starts two QEMU/KVM instances. When they have finished booting, the webserver can be accessed from the host through http://localhost:8081/. It also has a small test suite: $ nix-build tests/subversion.nix -A report This runs the VMs in a derivation, runs the tests, and then produces a distributed code coverage analysis report (i.e. it shows the combined coverage on both machines). The Perl test driver program is in lib/test-driver. It executes commands on the guest machines by connecting to a root shell running on port 514 (provided by modules/testing/test-instrumentation.nix). The VMs are connected together in a virtual network using QEMU's multicast feature. This isn't very secure. At the very least, other processes on the same machine can listen to or send packets on the virtual network. On the plus side, we don't need to be root to set up a multicast virtual network, so we can do it from a derivation. Maybe we can use VDE instead. (Moved from the vario repository.) svn path=/nixos/trunk/; revision=16899
2009-08-31 14:25:12 +00:00
2009-09-02 23:37:58 +00:00
let pkgs = import nixpkgs { config = {}; inherit system; }; in
* Stuff for automatic and manual testing of NixOS VMs. lib/build-vms.nix contains a function `buildVirtualNetwork' that takes a specification of a network of machines (as an attribute set of NixOS machine configurations) and builds a script that starts each configuration in a separate QEMU/KVM VM and connects them together in a virtual network. This script can be run manually to test the VMs interactively. There is also a function `runTests' that starts and runs the virtual network in a derivation, and then executes a test specification that tells the VMs to do certain things (i.e., letting one VM send an HTTP request to a webserver on another VM). The tests are written in Perl (for now). tests/subversion.nix shows a simple example, namely a network of two machines: a webserver that runs the Subversion subservice, and a client. Apache, Subversion and a few other packages are built with coverage analysis instrumentation. For instance, $ nix-build tests/subversion.nix -A vms $ ./result/bin/run-vms starts two QEMU/KVM instances. When they have finished booting, the webserver can be accessed from the host through http://localhost:8081/. It also has a small test suite: $ nix-build tests/subversion.nix -A report This runs the VMs in a derivation, runs the tests, and then produces a distributed code coverage analysis report (i.e. it shows the combined coverage on both machines). The Perl test driver program is in lib/test-driver. It executes commands on the guest machines by connecting to a root shell running on port 514 (provided by modules/testing/test-instrumentation.nix). The VMs are connected together in a virtual network using QEMU's multicast feature. This isn't very secure. At the very least, other processes on the same machine can listen to or send packets on the virtual network. On the plus side, we don't need to be root to set up a multicast virtual network, so we can do it from a derivation. Maybe we can use VDE instead. (Moved from the vario repository.) svn path=/nixos/trunk/; revision=16899
2009-08-31 14:25:12 +00:00
with pkgs;
with import ../lib/qemu-flags.nix;
* Stuff for automatic and manual testing of NixOS VMs. lib/build-vms.nix contains a function `buildVirtualNetwork' that takes a specification of a network of machines (as an attribute set of NixOS machine configurations) and builds a script that starts each configuration in a separate QEMU/KVM VM and connects them together in a virtual network. This script can be run manually to test the VMs interactively. There is also a function `runTests' that starts and runs the virtual network in a derivation, and then executes a test specification that tells the VMs to do certain things (i.e., letting one VM send an HTTP request to a webserver on another VM). The tests are written in Perl (for now). tests/subversion.nix shows a simple example, namely a network of two machines: a webserver that runs the Subversion subservice, and a client. Apache, Subversion and a few other packages are built with coverage analysis instrumentation. For instance, $ nix-build tests/subversion.nix -A vms $ ./result/bin/run-vms starts two QEMU/KVM instances. When they have finished booting, the webserver can be accessed from the host through http://localhost:8081/. It also has a small test suite: $ nix-build tests/subversion.nix -A report This runs the VMs in a derivation, runs the tests, and then produces a distributed code coverage analysis report (i.e. it shows the combined coverage on both machines). The Perl test driver program is in lib/test-driver. It executes commands on the guest machines by connecting to a root shell running on port 514 (provided by modules/testing/test-instrumentation.nix). The VMs are connected together in a virtual network using QEMU's multicast feature. This isn't very secure. At the very least, other processes on the same machine can listen to or send packets on the virtual network. On the plus side, we don't need to be root to set up a multicast virtual network, so we can do it from a derivation. Maybe we can use VDE instead. (Moved from the vario repository.) svn path=/nixos/trunk/; revision=16899
2009-08-31 14:25:12 +00:00
rec {
inherit pkgs;
# Build a virtual network from an attribute set `{ machine1 =
# config1; ... machineN = configN; }', where `machineX' is the
# hostname and `configX' is a NixOS system configuration. The
# result is a script that starts a QEMU instance for each virtual
# machine. Each machine is given an arbitrary IP address in the
# virtual network.
buildVirtualNetwork =
{ nodes }:
let nodes_ = lib.mapAttrs (n: buildVM nodes_) (assignIPAddresses nodes); in
stdenv.mkDerivation {
name = "vms";
buildCommand =
''
ensureDir $out/vms
${
lib.concatMapStrings (vm:
''
ln -sn ${vm.config.system.build.vm} $out/vms/${vm.config.networking.hostName}
''
) (lib.attrValues nodes_)
}
ensureDir $out/bin
cat > $out/bin/run-vms <<EOF
#! ${stdenv.shell}
port=8080
for i in $out/vms/*; do
port2=\$((port++))
echo "forwarding localhost:\$port2 to \$(basename \$i):80"
QEMU_OPTS="-redir tcp:\$port2::80" \$i/bin/run-*-vm &
* Stuff for automatic and manual testing of NixOS VMs. lib/build-vms.nix contains a function `buildVirtualNetwork' that takes a specification of a network of machines (as an attribute set of NixOS machine configurations) and builds a script that starts each configuration in a separate QEMU/KVM VM and connects them together in a virtual network. This script can be run manually to test the VMs interactively. There is also a function `runTests' that starts and runs the virtual network in a derivation, and then executes a test specification that tells the VMs to do certain things (i.e., letting one VM send an HTTP request to a webserver on another VM). The tests are written in Perl (for now). tests/subversion.nix shows a simple example, namely a network of two machines: a webserver that runs the Subversion subservice, and a client. Apache, Subversion and a few other packages are built with coverage analysis instrumentation. For instance, $ nix-build tests/subversion.nix -A vms $ ./result/bin/run-vms starts two QEMU/KVM instances. When they have finished booting, the webserver can be accessed from the host through http://localhost:8081/. It also has a small test suite: $ nix-build tests/subversion.nix -A report This runs the VMs in a derivation, runs the tests, and then produces a distributed code coverage analysis report (i.e. it shows the combined coverage on both machines). The Perl test driver program is in lib/test-driver. It executes commands on the guest machines by connecting to a root shell running on port 514 (provided by modules/testing/test-instrumentation.nix). The VMs are connected together in a virtual network using QEMU's multicast feature. This isn't very secure. At the very least, other processes on the same machine can listen to or send packets on the virtual network. On the plus side, we don't need to be root to set up a multicast virtual network, so we can do it from a derivation. Maybe we can use VDE instead. (Moved from the vario repository.) svn path=/nixos/trunk/; revision=16899
2009-08-31 14:25:12 +00:00
done
EOF
chmod +x $out/bin/run-vms
''; # */
passthru = { nodes = nodes_; };
* Stuff for automatic and manual testing of NixOS VMs. lib/build-vms.nix contains a function `buildVirtualNetwork' that takes a specification of a network of machines (as an attribute set of NixOS machine configurations) and builds a script that starts each configuration in a separate QEMU/KVM VM and connects them together in a virtual network. This script can be run manually to test the VMs interactively. There is also a function `runTests' that starts and runs the virtual network in a derivation, and then executes a test specification that tells the VMs to do certain things (i.e., letting one VM send an HTTP request to a webserver on another VM). The tests are written in Perl (for now). tests/subversion.nix shows a simple example, namely a network of two machines: a webserver that runs the Subversion subservice, and a client. Apache, Subversion and a few other packages are built with coverage analysis instrumentation. For instance, $ nix-build tests/subversion.nix -A vms $ ./result/bin/run-vms starts two QEMU/KVM instances. When they have finished booting, the webserver can be accessed from the host through http://localhost:8081/. It also has a small test suite: $ nix-build tests/subversion.nix -A report This runs the VMs in a derivation, runs the tests, and then produces a distributed code coverage analysis report (i.e. it shows the combined coverage on both machines). The Perl test driver program is in lib/test-driver. It executes commands on the guest machines by connecting to a root shell running on port 514 (provided by modules/testing/test-instrumentation.nix). The VMs are connected together in a virtual network using QEMU's multicast feature. This isn't very secure. At the very least, other processes on the same machine can listen to or send packets on the virtual network. On the plus side, we don't need to be root to set up a multicast virtual network, so we can do it from a derivation. Maybe we can use VDE instead. (Moved from the vario repository.) svn path=/nixos/trunk/; revision=16899
2009-08-31 14:25:12 +00:00
};
buildVM =
nodes: configurations:
* Stuff for automatic and manual testing of NixOS VMs. lib/build-vms.nix contains a function `buildVirtualNetwork' that takes a specification of a network of machines (as an attribute set of NixOS machine configurations) and builds a script that starts each configuration in a separate QEMU/KVM VM and connects them together in a virtual network. This script can be run manually to test the VMs interactively. There is also a function `runTests' that starts and runs the virtual network in a derivation, and then executes a test specification that tells the VMs to do certain things (i.e., letting one VM send an HTTP request to a webserver on another VM). The tests are written in Perl (for now). tests/subversion.nix shows a simple example, namely a network of two machines: a webserver that runs the Subversion subservice, and a client. Apache, Subversion and a few other packages are built with coverage analysis instrumentation. For instance, $ nix-build tests/subversion.nix -A vms $ ./result/bin/run-vms starts two QEMU/KVM instances. When they have finished booting, the webserver can be accessed from the host through http://localhost:8081/. It also has a small test suite: $ nix-build tests/subversion.nix -A report This runs the VMs in a derivation, runs the tests, and then produces a distributed code coverage analysis report (i.e. it shows the combined coverage on both machines). The Perl test driver program is in lib/test-driver. It executes commands on the guest machines by connecting to a root shell running on port 514 (provided by modules/testing/test-instrumentation.nix). The VMs are connected together in a virtual network using QEMU's multicast feature. This isn't very secure. At the very least, other processes on the same machine can listen to or send packets on the virtual network. On the plus side, we don't need to be root to set up a multicast virtual network, so we can do it from a derivation. Maybe we can use VDE instead. (Moved from the vario repository.) svn path=/nixos/trunk/; revision=16899
2009-08-31 14:25:12 +00:00
import ./eval-config.nix {
inherit nixpkgs services system;
modules = configurations ++
[ ../modules/virtualisation/qemu-vm.nix
../modules/testing/test-instrumentation.nix # !!! should only get added for automated test runs
- Added nixos-build-vms command, which builds a virtual network from a network.nix expression (also used by nixos-deploy-network) - Added a backdoor option to the interactive run-vms script. This allows me to intergrate the virtual network approach with Disnix - Small documentation fixes Some explanation: The nixos-build-vms command line tool can be used to build a virtual network of a network.nix specification. For example, a network configuration (network.nix) could look like this: { test1 = {pkgs, config, ...}: { services.openssh.enable = true; ... }; test2 = {pkgs, config, ...}: { services.openssh.enable = true; services.xserver.enable = true; } ; } By typing the following instruction: $ nixos-build-vms -n network.nix a virtual network is built, which can be started by typing: $ ./result/bin/run-vms It is also possible to enable a backdoor. In this case *.socket files are stored in the current directory which can be used by the end-user to invoke remote instruction on a VM in the network through a Unix domain socket. For example by building the network with the following instructions: $ nixos-build-vms -n network.nix --use-backdoor and launching the virtual network: $ ./result/bin/run-vms You can find two socket files in your current directory, namely: test1.socket and test2.socket. These Unix domain sockets can be used to remotely administer the test1 and test2 machine in the virtual network. For example by running: $ socat ./test1.socket stdio ls /root You can retrieve the contents of the /root directory of the virtual machine with identifier test1 svn path=/nixos/trunk/; revision=24410
2010-10-21 22:50:12 +00:00
{ key = "no-manual"; services.nixosManual.enable = false; virtualisation.useBackdoor = useBackdoor; }
];
* Stuff for automatic and manual testing of NixOS VMs. lib/build-vms.nix contains a function `buildVirtualNetwork' that takes a specification of a network of machines (as an attribute set of NixOS machine configurations) and builds a script that starts each configuration in a separate QEMU/KVM VM and connects them together in a virtual network. This script can be run manually to test the VMs interactively. There is also a function `runTests' that starts and runs the virtual network in a derivation, and then executes a test specification that tells the VMs to do certain things (i.e., letting one VM send an HTTP request to a webserver on another VM). The tests are written in Perl (for now). tests/subversion.nix shows a simple example, namely a network of two machines: a webserver that runs the Subversion subservice, and a client. Apache, Subversion and a few other packages are built with coverage analysis instrumentation. For instance, $ nix-build tests/subversion.nix -A vms $ ./result/bin/run-vms starts two QEMU/KVM instances. When they have finished booting, the webserver can be accessed from the host through http://localhost:8081/. It also has a small test suite: $ nix-build tests/subversion.nix -A report This runs the VMs in a derivation, runs the tests, and then produces a distributed code coverage analysis report (i.e. it shows the combined coverage on both machines). The Perl test driver program is in lib/test-driver. It executes commands on the guest machines by connecting to a root shell running on port 514 (provided by modules/testing/test-instrumentation.nix). The VMs are connected together in a virtual network using QEMU's multicast feature. This isn't very secure. At the very least, other processes on the same machine can listen to or send packets on the virtual network. On the plus side, we don't need to be root to set up a multicast virtual network, so we can do it from a derivation. Maybe we can use VDE instead. (Moved from the vario repository.) svn path=/nixos/trunk/; revision=16899
2009-08-31 14:25:12 +00:00
extraArgs = { inherit nodes; };
};
# Given an attribute set { machine1 = config1; ... machineN =
# configN; }, sequentially assign IP addresses in the 192.168.1.0/24
# range to each machine, and set the hostname to the attribute name.
assignIPAddresses = nodes:
let
machines = lib.attrNames nodes;
machinesNumbered = lib.zipTwoLists machines (lib.range 1 254);
nodes_ = lib.flip map machinesNumbered (m: lib.nameValuePair m.first
[ ( { config, pkgs, nodes, ... }:
let
interfacesNumbered = lib.zipTwoLists config.virtualisation.vlans (lib.range 1 255);
interfaces =
lib.flip map interfacesNumbered ({ first, second }:
{ name = "eth${toString second}";
ipAddress = "192.168.${toString first}.${toString m.second}";
}
);
in
{ key = "ip-address";
config =
{ networking.hostName = m.first;
networking.interfaces = interfaces;
networking.primaryIPAddress =
lib.optionalString (interfaces != []) (lib.head interfaces).ipAddress;
# Put the IP addresses of all VMs in this machine's
# /etc/hosts file. If a machine has multiple
# interfaces, use the IP address corresponding to
# the first interface (i.e. the first network in its
# virtualisation.vlans option).
networking.extraHosts = lib.flip lib.concatMapStrings machines
(m: let config = (lib.getAttr m nodes).config; in
lib.optionalString (config.networking.primaryIPAddress != "")
("${config.networking.primaryIPAddress} " +
"${config.networking.hostName}\n"));
virtualisation.qemu.options =
lib.flip lib.concatMapStrings interfacesNumbered
({ first, second }: qemuNICFlags second first m.second);
};
}
)
(lib.getAttr m.first nodes)
] );
* Stuff for automatic and manual testing of NixOS VMs. lib/build-vms.nix contains a function `buildVirtualNetwork' that takes a specification of a network of machines (as an attribute set of NixOS machine configurations) and builds a script that starts each configuration in a separate QEMU/KVM VM and connects them together in a virtual network. This script can be run manually to test the VMs interactively. There is also a function `runTests' that starts and runs the virtual network in a derivation, and then executes a test specification that tells the VMs to do certain things (i.e., letting one VM send an HTTP request to a webserver on another VM). The tests are written in Perl (for now). tests/subversion.nix shows a simple example, namely a network of two machines: a webserver that runs the Subversion subservice, and a client. Apache, Subversion and a few other packages are built with coverage analysis instrumentation. For instance, $ nix-build tests/subversion.nix -A vms $ ./result/bin/run-vms starts two QEMU/KVM instances. When they have finished booting, the webserver can be accessed from the host through http://localhost:8081/. It also has a small test suite: $ nix-build tests/subversion.nix -A report This runs the VMs in a derivation, runs the tests, and then produces a distributed code coverage analysis report (i.e. it shows the combined coverage on both machines). The Perl test driver program is in lib/test-driver. It executes commands on the guest machines by connecting to a root shell running on port 514 (provided by modules/testing/test-instrumentation.nix). The VMs are connected together in a virtual network using QEMU's multicast feature. This isn't very secure. At the very least, other processes on the same machine can listen to or send packets on the virtual network. On the plus side, we don't need to be root to set up a multicast virtual network, so we can do it from a derivation. Maybe we can use VDE instead. (Moved from the vario repository.) svn path=/nixos/trunk/; revision=16899
2009-08-31 14:25:12 +00:00
in lib.listToAttrs nodes_;
}