* New nixos-rebuild action: "nixos-rebuild build-vm" builds a virtual

machine containing a replica (minus the state) of the system
  configuration.  This is mostly useful for testing configuration
  changes prior to doing an actual "nixos-rebuild switch" (or even
  "nixos-rebuild test").  The VM can be started as follows:

  $ nixos-rebuild build-vm
  $ ./result/bin/run-*-vm

  which starts a KVM/QEMU instance.  Additional QEMU options can be
  passed through the QEMU_OPTS environment variable
  (e.g. QEMU_OPTS="-redir tcp:8080::80" to forward a host port to the
  guest).  The fileSystem attribute of the regular system
  configuration is ignored (using mkOverride), because obviously we
  can't allow the VM to access the host's block devices.  Instead, at
  startup the VM creates an empty disk image in ./<hostname>.qcow2 to
  store the VM's root filesystem.

  Building a VM in this way is efficient because the VM shares its Nix
  store with the host (through a CIFS mount).  However, because the
  Nix store of the host is mounted read-only in the guest, you cannot
  run Nix build actions inside the VM.  Therefore the VM can only be
  reconfigured by re-running "nixos-rebuild build-vm" on the host and
  restarting the VM.

svn path=/nixos/trunk/; revision=16662
This commit is contained in:
Eelco Dolstra 2009-08-11 01:35:56 +00:00
parent ebd2fbd24f
commit 89ef5c979b
5 changed files with 43 additions and 17 deletions

View File

@ -7,6 +7,11 @@ let
(import ./lib/eval-config.nix {inherit configuration;}) (import ./lib/eval-config.nix {inherit configuration;})
config optionDeclarations pkgs; config optionDeclarations pkgs;
vmConfig = (import ./lib/eval-config.nix {
inherit configuration;
extraModules = [./modules/virtualisation/qemu-vm.nix];
}).config;
in in
{ {
@ -14,6 +19,8 @@ in
system = config.system.build.system; system = config.system.build.system;
vm = vmConfig.system.build.vm;
# The following are used by nixos-rebuild. # The following are used by nixos-rebuild.
nixFallback = pkgs.nixUnstable; nixFallback = pkgs.nixUnstable;
manifests = config.installer.manifests; manifests = config.installer.manifests;

View File

@ -7,6 +7,7 @@
, nixpkgs ? import ./from-env.nix "NIXPKGS" /etc/nixos/nixpkgs , nixpkgs ? import ./from-env.nix "NIXPKGS" /etc/nixos/nixpkgs
, pkgs ? import nixpkgs {inherit system;} , pkgs ? import nixpkgs {inherit system;}
, extraArgs ? {} , extraArgs ? {}
, extraModules ? []
}: }:
let extraArgs_ = extraArgs; in let extraArgs_ = extraArgs; in
@ -14,10 +15,12 @@ let extraArgs_ = extraArgs; in
rec { rec {
inherit nixpkgs pkgs; inherit nixpkgs pkgs;
configComponents = [ configComponents =
configuration [ configuration
./check-config.nix ./check-config.nix
] ++ (import ../modules/module-list.nix); ]
++ extraModules
++ (import ../modules/module-list.nix);
extraArgs = extraArgs_ // { extraArgs = extraArgs_ // {
inherit pkgs; inherit pkgs;

View File

@ -15,12 +15,14 @@ Usage: $0 [OPTIONS...] OPERATION
The operation is one of the following: The operation is one of the following:
switch: make the configuration the boot default and activate now switch: make the configuration the boot default and activate now
boot: make the configuration the boot default boot: make the configuration the boot default
test: activate the configuration, but don't make it the boot default test: activate the configuration, but don't make it the boot default
build: build the configuration, but don't make it the default or build: build the configuration, but don't make it the default or
activate it activate it
dry-run: just show what store paths would be built/downloaded build-vm: build a virtual machine containing the configuration
(useful for testing)
dry-run: just show what store paths would be built/downloaded
Options: Options:
@ -54,7 +56,8 @@ while test "$#" -gt 0; do
i="$1"; shift 1 i="$1"; shift 1
if test "$i" = "--help"; then if test "$i" = "--help"; then
showSyntax showSyntax
elif test "$i" = switch -o "$i" = boot -o "$i" = test -o "$i" = build -o "$i" = dry-run; then elif test "$i" = switch -o "$i" = boot -o "$i" = test -o "$i" = build \
-o "$i" = dry-run -o "$i" = build-vm; then
action="$i" action="$i"
elif test "$i" = --install-grub; then elif test "$i" = --install-grub; then
export NIXOS_INSTALL_GRUB=1 export NIXOS_INSTALL_GRUB=1
@ -129,6 +132,9 @@ if test "$action" = switch -o "$action" = boot; then
elif test "$action" = test -o "$action" = build -o "$action" = dry-run; then elif test "$action" = test -o "$action" = build -o "$action" = dry-run; then
nix-build $NIXOS -A system -K -k $extraBuildFlags nix-build $NIXOS -A system -K -k $extraBuildFlags
pathToConfig=./result pathToConfig=./result
elif test "$action" = build-vm; then
nix-build $NIXOS -A vm -K -k $extraBuildFlags
pathToConfig=./result
else else
showSyntax showSyntax
fi fi
@ -141,7 +147,7 @@ if test "$action" = switch -o "$action" = boot -o "$action" = test; then
fi fi
if test "$action" = "test"; then if test "$action" = test; then
cat >&2 <<EOF cat >&2 <<EOF
Warning: if you remove or overwrite the symlink \`$pathToConfig', the Warning: if you remove or overwrite the symlink \`$pathToConfig', the
@ -149,3 +155,11 @@ active system configuration may be garbage collected! This may render
the system inoperable (though a reboot will fix things). the system inoperable (though a reboot will fix things).
EOF EOF
fi fi
if test "$action" = build-vm; then
cat >&2 <<EOF
Done. The virtual machine can be started by running $(echo $pathToConfig/bin/run-*-vm).
EOF
fi

View File

@ -5,9 +5,7 @@ let
inherit (pkgs.lib) mkOption mkIf; inherit (pkgs.lib) mkOption mkIf;
inherit (pkgs) openssh; inherit (pkgs) openssh;
cfg = (config.services.sshd); cfg = config.services.sshd;
nssModules = config.system.nssModules.list;
nssModulesPath = config.system.nssModules.path; nssModulesPath = config.system.nssModules.path;

View File

@ -85,8 +85,12 @@ in
''; '';
# Mount the host filesystem via CIFS, and bind-mount the Nix store # Mount the host filesystem via CIFS, and bind-mount the Nix store
# of the host into our own filesystem. # of the host into our own filesystem. We use mkOverride to allow
fileSystems = # this module to be applied to "normal" NixOS system configuration,
# where the regular value for the `fileSystems' attribute should be
# disregarded for the purpose of building a VM test image (since
# those filesystems don't exist in the VM).
fileSystems = pkgs.lib.mkOverride 50 {}
[ { mountPoint = "/"; [ { mountPoint = "/";
device = "/dev/vda"; device = "/dev/vda";
} }