- 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
wip/yesman
Sander van der Burg 14 years ago
parent f6bc3d61cf
commit 9c722e474d
  1. 4
      lib/build-vms.nix
  2. 16
      modules/installer/tools/nixos-build-vms/build-vms.nix
  3. 66
      modules/installer/tools/nixos-build-vms/nixos-build-vms.sh
  4. 1
      modules/installer/tools/nixos-deploy-network/nixos-deploy-network.sh
  5. 8
      modules/installer/tools/tools.nix
  6. 29
      modules/virtualisation/qemu-vm.nix

@ -1,4 +1,4 @@
{ nixpkgs, services, system }:
{ nixpkgs, services, system, useBackdoor ? false }:
let pkgs = import nixpkgs { config = {}; inherit system; }; in
@ -58,7 +58,7 @@ rec {
modules = configurations ++
[ ../modules/virtualisation/qemu-vm.nix
../modules/testing/test-instrumentation.nix # !!! should only get added for automated test runs
{ key = "no-manual"; services.nixosManual.enable = false; }
{ key = "no-manual"; services.nixosManual.enable = false; virtualisation.useBackdoor = useBackdoor; }
];
extraArgs = { inherit nodes; };
};

@ -0,0 +1,16 @@
{ nixos
, nixpkgs
, services ? "/etc/nixos/services"
, system ? builtins.currentSystem
, networkExpr
, useBackdoor ? false
}:
let nodes = import networkExpr;
in
(import "${nixos}/lib/build-vms.nix" {
inherit nixpkgs services system useBackdoor;
})
.buildVirtualNetwork {
inherit nodes;
}

@ -0,0 +1,66 @@
#! @shell@ -e
# Shows the usage of this command to the user
showUsage()
{
echo "Usage: $0 -n network_expr -i infrastructure_expr"
echo "Options:"
echo
echo "-n,--network Network Nix expression which captures properties of machines in the network"
echo "--use-backdoor Indicates that the backdoor must be enabled so that the VMs can be accessed through a UNIX domain socket"
echo "--show-trace Shows the output trace"
echo "-h,--help Shows the usage of this command"
}
# Parse valid argument options
PARAMS=`getopt -n $0 -o n:h -l network:,use-backdoor,show-trace,help -- "$@"`
if [ $? != 0 ]
then
showUsage
exit 1
fi
eval set -- "$PARAMS"
# Evaluate valid options
while [ "$1" != "--" ]
do
case "$1" in
-n|--network)
networkExpr=`readlink -f $2`
;;
--use-backdoor)
useBackdoorArg="--arg useBackdoor true"
;;
--show-trace)
showTraceArg="--show-trace"
;;
-h|--help)
showUsage
exit 0
;;
esac
shift
done
# Validate the given options
if [ "$networkExpr" = "" ]
then
echo "ERROR: A network expression must be specified!" >&2
exit 1
fi
if [ -z "$NIXOS" ]
then
NIXOS=/etc/nixos/nixos
fi
# Build a network of VMs
nix-build $NIXOS/modules/installer/tools/nixos-build-vms/build-vms.nix --argstr networkExpr $networkExpr --argstr nixos $NIXOS --argstr nixpkgs $NIXPKGS_ALL $useBackdoorArg $showTraceArg

@ -9,6 +9,7 @@ showUsage()
echo
echo "-n,--network Network Nix expression which captures properties of machines in the network"
echo "-i,--infrastructure Infrastructure Nix expression which captures properties of machines in the network"
echo "--show-trace Shows an output trace"
echo "-h,--help Shows the usage of this command"
}

@ -11,6 +11,11 @@ let
isExecutable = true;
});
nixosBuildVMS = makeProg {
name = "nixos-build-vms";
src = ./nixos-build-vms/nixos-build-vms.sh;
};
nixosDeployNetwork = makeProg {
name = "nixos-deploy-network";
src = ./nixos-deploy-network/nixos-deploy-network.sh;
@ -131,7 +136,8 @@ in
config = {
environment.systemPackages =
[ nixosDeployNetwork
[ nixosBuildVMS
nixosDeployNetwork
nixosInstall
nixosRebuild
nixosHardwareScan

@ -111,6 +111,17 @@ let
description = "Options passed to QEMU.";
};
virtualisation.useBackdoor =
mkOption {
default = false;
description =
''
If enabled, the virtual machine makes a connection through TCP port 23
to a daemon running on the host system acting as a proxy.
This option makes it possible to connect to a VM through a socket file.
'';
};
virtualisation.useBootLoader =
mkOption {
default = false;
@ -145,6 +156,11 @@ let
${toString config.virtualisation.diskSize}M || exit 1
fi
${pkgs.lib.optionalString cfg.useBackdoor ''
# Remember the current working directory
WORKDIR=$(pwd)
''}
# Start Samba (which wants to put its socket and config files in TMPDIR).
if [ -z "$TMPDIR" -o -z "$USE_TMPDIR" ]; then
TMPDIR=$(mktemp -d nix-vm-smbd.XXXXXXXXXX --tmpdir)
@ -153,13 +169,24 @@ let
${pkgs.vmTools.startSamba}
${pkgs.lib.optionalString cfg.useBackdoor ''
# Create a shell socket file to which the VM can connect and create in the
# current working directory a socket file which can be used to remotely access
# the VM through the shell interface
${pkgs.socat}/bin/socat UNIX-LISTEN:./shell UNIX-LISTEN:$WORKDIR/${vmName}.socket,fork &
while [ ! -e ./shell ]; do sleep 0.1; done # Wait until the socket file is there
''}
# Start QEMU.
exec ${pkgs.qemu_kvm}/bin/qemu-system-x86_64 \
-name ${vmName} \
-m ${toString config.virtualisation.memorySize} \
-net nic,vlan=0,model=virtio \
-chardev socket,id=samba,path=./samba \
-net user,vlan=0,guestfwd=tcp:10.0.2.4:139-chardev:samba''${QEMU_NET_OPTS:+,$QEMU_NET_OPTS} \
-net user,vlan=0,guestfwd=tcp:10.0.2.4:139-chardev:samba${if cfg.useBackdoor then ",guestfwd=tcp:10.0.2.6:23-chardev:shell" else ""}''${QEMU_NET_OPTS:+,$QEMU_NET_OPTS} \
${if cfg.useBackdoor then "-chardev socket,id=shell,path=./shell" else ""} \
${if cfg.useBootLoader then ''
-drive index=0,file=$NIX_DISK_IMAGE,if=virtio,cache=writeback,werror=report \
-drive index=1,file=${bootDisk}/disk.img,if=virtio,boot=on \

Loading…
Cancel
Save