* Added a command `nixos-rebuild build-vm-with-bootloader'. This is
like `build-vm', but boots using the regular boot loader (i.e. GRUB 1 or 2) rather than booting directly from the kernel/initrd. Thus it allows testing of GRUB. svn path=/nixos/trunk/; revision=23747
This commit is contained in:
parent
b756a1ee81
commit
c1295661c4
15
default.nix
15
default.nix
|
@ -11,11 +11,22 @@ let
|
||||||
|
|
||||||
inherit (eval) config pkgs;
|
inherit (eval) config pkgs;
|
||||||
|
|
||||||
|
# This is for `nixos-rebuild build-vm'.
|
||||||
vmConfig = (import ./lib/eval-config.nix {
|
vmConfig = (import ./lib/eval-config.nix {
|
||||||
inherit system;
|
inherit system;
|
||||||
modules = [ configuration ./modules/virtualisation/qemu-vm.nix ];
|
modules = [ configuration ./modules/virtualisation/qemu-vm.nix ];
|
||||||
}).config;
|
}).config;
|
||||||
|
|
||||||
|
# This is for `nixos-rebuild build-vm-with-bootloader'.
|
||||||
|
vmWithBootLoaderConfig = (import ./lib/eval-config.nix {
|
||||||
|
inherit system;
|
||||||
|
modules =
|
||||||
|
[ configuration
|
||||||
|
./modules/virtualisation/qemu-vm.nix
|
||||||
|
{ virtualisation.useBootLoader = true; }
|
||||||
|
];
|
||||||
|
}).config;
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -25,6 +36,8 @@ in
|
||||||
|
|
||||||
vm = vmConfig.system.build.vm;
|
vm = vmConfig.system.build.vm;
|
||||||
|
|
||||||
|
vmWithBootLoader = vmWithBootLoaderConfig.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;
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
<arg choice='plain'><option>build</option></arg>
|
<arg choice='plain'><option>build</option></arg>
|
||||||
<arg choice='plain'><option>dry-run</option></arg>
|
<arg choice='plain'><option>dry-run</option></arg>
|
||||||
<arg choice='plain'><option>build-vm</option></arg>
|
<arg choice='plain'><option>build-vm</option></arg>
|
||||||
|
<arg choice='plain'><option>build-vm-with-bootloader</option></arg>
|
||||||
|
<arg choice='plain'><option>pull</option></arg>
|
||||||
</group>
|
</group>
|
||||||
<sbr />
|
<sbr />
|
||||||
<arg><option>--install-grub</option></arg>
|
<arg><option>--install-grub</option></arg>
|
||||||
|
@ -151,6 +153,35 @@ $ ./result/bin/run-*-vm
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>build-vm-with-bootloader</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Like <option>build-vm</option>, but boots using the
|
||||||
|
regular boot loader of your configuration (e.g., GRUB 1 or 2),
|
||||||
|
rather than booting directly into the kernel and initial ramdisk
|
||||||
|
of the system. This allows you to test whether the boot loader
|
||||||
|
works correctly. However, it does not guarantee that your NixOS
|
||||||
|
configuration will boot successfully on the host hardware (i.e.,
|
||||||
|
after running <command>nixos-rebuild switch</command>), because
|
||||||
|
the hardware and boot loader configuration in the VM are
|
||||||
|
different. The boot loader is installed on an automatically
|
||||||
|
generated virtual disk containing a <filename>/boot</filename>
|
||||||
|
partition, which is mounted read-only in the VM.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>pull</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>This operation merely fetches the latest manifest in the
|
||||||
|
Nixpkgs channel to speed up subsequent
|
||||||
|
<command>nix-env</command> operations. This is useful if you
|
||||||
|
are not using <command>nix-channel</command> but still want to
|
||||||
|
use pre-built binary packages. It doesn’t reconfigure the
|
||||||
|
system at all.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
|
@ -22,6 +22,8 @@ The operation is one of the following:
|
||||||
activate it
|
activate it
|
||||||
build-vm: build a virtual machine containing the configuration
|
build-vm: build a virtual machine containing the configuration
|
||||||
(useful for testing)
|
(useful for testing)
|
||||||
|
build-vm-with-bootloader:
|
||||||
|
like build-vm, but include a boot loader in the VM
|
||||||
dry-run: just show what store paths would be built/downloaded
|
dry-run: just show what store paths would be built/downloaded
|
||||||
pull: just pull the Nixpkgs channel manifest and exit
|
pull: just pull the Nixpkgs channel manifest and exit
|
||||||
|
|
||||||
|
@ -64,7 +66,7 @@ while test "$#" -gt 0; do
|
||||||
--help)
|
--help)
|
||||||
showSyntax
|
showSyntax
|
||||||
;;
|
;;
|
||||||
switch|boot|test|build|dry-run|build-vm|pull)
|
switch|boot|test|build|dry-run|build-vm|build-vm-with-bootloader|pull)
|
||||||
action="$i"
|
action="$i"
|
||||||
;;
|
;;
|
||||||
--install-grub)
|
--install-grub)
|
||||||
|
@ -171,9 +173,12 @@ if test -z "$rollback"; 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 > /dev/null
|
nix-build $NIXOS -A system -K -k $extraBuildFlags > /dev/null
|
||||||
pathToConfig=./result
|
pathToConfig=./result
|
||||||
elif test "$action" = build-vm; then
|
elif [ "$action" = build-vm ]; then
|
||||||
nix-build $NIXOS -A vm -K -k $extraBuildFlags > /dev/null
|
nix-build $NIXOS -A vm -K -k $extraBuildFlags > /dev/null
|
||||||
pathToConfig=./result
|
pathToConfig=./result
|
||||||
|
elif [ "$action" = build-vm-with-bootloader ]; then
|
||||||
|
nix-build $NIXOS -A vmWithBootLoader -K -k $extraBuildFlags > /dev/null
|
||||||
|
pathToConfig=./result
|
||||||
else
|
else
|
||||||
showSyntax
|
showSyntax
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -38,7 +38,7 @@ if [ "$action" = "switch" -o "$action" = "boot" ]; then
|
||||||
|
|
||||||
if [ "$NIXOS_INSTALL_GRUB" = 1 -o "$oldGrubVersion" != "$newGrubVersion" ]; then
|
if [ "$NIXOS_INSTALL_GRUB" = 1 -o "$oldGrubVersion" != "$newGrubVersion" ]; then
|
||||||
echo "installing the GRUB bootloader..."
|
echo "installing the GRUB bootloader..."
|
||||||
@grub@/sbin/grub-install "@grubDevice@" --no-floppy --recheck
|
@grub@/sbin/grub-install "@grubDevice@" --no-floppy
|
||||||
echo "$newGrubVersion" > /boot/grub/version
|
echo "$newGrubVersion" > /boot/grub/version
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -110,7 +110,24 @@ let
|
||||||
example = "-vga std";
|
example = "-vga std";
|
||||||
description = "Options passed to QEMU.";
|
description = "Options passed to QEMU.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
virtualisation.useBootLoader =
|
||||||
|
mkOption {
|
||||||
|
default = true;
|
||||||
|
description =
|
||||||
|
''
|
||||||
|
If enabled, the virtual machine will be booted using the
|
||||||
|
regular boot loader (i.e., GRUB 1 or 2). This allows
|
||||||
|
testing of the boot loader. However, it does not
|
||||||
|
guarantee that your NixOS configuration will boot
|
||||||
|
successfully on the host hardware, because the hardware
|
||||||
|
and boot loader configuration in the VM are different. If
|
||||||
|
disabled (the default), the VM directly boots the NixOS
|
||||||
|
kernel and initial ramdisk, bypassing the boot loader
|
||||||
|
altogether.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
cfg = config.virtualisation;
|
cfg = config.virtualisation;
|
||||||
|
@ -146,12 +163,17 @@ let
|
||||||
-net nic,vlan=0,model=virtio \
|
-net nic,vlan=0,model=virtio \
|
||||||
-chardev socket,id=samba,path=./samba \
|
-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''${QEMU_NET_OPTS:+,$QEMU_NET_OPTS} \
|
||||||
-drive file=$NIX_DISK_IMAGE,if=virtio,boot=on,cache=writeback,werror=report \
|
${if cfg.useBootLoader then ''
|
||||||
-kernel ${config.system.build.toplevel}/kernel \
|
-drive index=0,file=$NIX_DISK_IMAGE,if=virtio,cache=writeback,werror=report \
|
||||||
-initrd ${config.system.build.toplevel}/initrd \
|
-drive index=1,file=${bootDisk}/disk.img,if=virtio,boot=on \
|
||||||
|
'' else ''
|
||||||
|
-drive file=$NIX_DISK_IMAGE,if=virtio,boot=on,cache=writeback,werror=report \
|
||||||
|
-kernel ${config.system.build.toplevel}/kernel \
|
||||||
|
-initrd ${config.system.build.toplevel}/initrd \
|
||||||
|
-append "$(cat ${config.system.build.toplevel}/kernel-params) init=${config.system.build.bootStage2} systemConfig=${config.system.build.toplevel} regInfo=${regInfo} ${kernelConsole} $QEMU_KERNEL_PARAMS" \
|
||||||
|
''}
|
||||||
${qemuGraphics} \
|
${qemuGraphics} \
|
||||||
$QEMU_OPTS \
|
$QEMU_OPTS \
|
||||||
-append "$(cat ${config.system.build.toplevel}/kernel-params) init=${config.system.build.bootStage2} systemConfig=${config.system.build.toplevel} regInfo=${regInfo} ${kernelConsole} $QEMU_KERNEL_PARAMS" \
|
|
||||||
${config.virtualisation.qemu.options}
|
${config.virtualisation.qemu.options}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
@ -165,11 +187,54 @@ let
|
||||||
printRegistration=1 perl ${pkgs.pathsFromGraph} closure-* > $out
|
printRegistration=1 perl ${pkgs.pathsFromGraph} closure-* > $out
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
|
||||||
|
# Generate a hard disk image containing a /boot partition and GRUB
|
||||||
|
# in the MBR. Used when the `useBootLoader' option is set.
|
||||||
|
bootDisk =
|
||||||
|
pkgs.vmTools.runInLinuxVM (
|
||||||
|
pkgs.runCommand "nixos-boot-disk"
|
||||||
|
{ preVM =
|
||||||
|
''
|
||||||
|
mkdir $out
|
||||||
|
diskImage=$out/disk.img
|
||||||
|
${pkgs.vmTools.kvm}/bin/qemu-img create -f qcow2 $diskImage "32M"
|
||||||
|
'';
|
||||||
|
buildInputs = [ pkgs.utillinux ];
|
||||||
|
}
|
||||||
|
''
|
||||||
|
# Create a single /boot partition.
|
||||||
|
${pkgs.parted}/sbin/parted /dev/vda mklabel msdos
|
||||||
|
${pkgs.parted}/sbin/parted /dev/vda -- mkpart primary ext2 1M -1s
|
||||||
|
. /sys/class/block/vda1/uevent
|
||||||
|
mknod /dev/vda1 b $MAJOR $MINOR
|
||||||
|
. /sys/class/block/vda/uevent
|
||||||
|
${pkgs.e2fsprogs}/sbin/mkfs.ext3 -L boot /dev/vda1
|
||||||
|
${pkgs.e2fsprogs}/sbin/tune2fs -c 0 -i 0 /dev/vda1
|
||||||
|
|
||||||
|
# Mount /boot.
|
||||||
|
mkdir /boot
|
||||||
|
mount /dev/vda1 /boot
|
||||||
|
|
||||||
|
# This is needed for GRUB 0.97, which doesn't know about virtio devices.
|
||||||
|
mkdir /boot/grub
|
||||||
|
echo '(hd0) /dev/vda' > /boot/grub/device.map
|
||||||
|
|
||||||
|
# Install GRUB and generate the GRUB boot menu.
|
||||||
|
touch /etc/NIXOS
|
||||||
|
mkdir -p /nix/var/nix/profiles
|
||||||
|
${config.system.build.toplevel}/bin/switch-to-configuration boot
|
||||||
|
|
||||||
|
umount /boot
|
||||||
|
''
|
||||||
|
);
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
require = options;
|
require = options;
|
||||||
|
|
||||||
|
boot.loader.grub.device = mkOverride 50 "/dev/vda";
|
||||||
|
|
||||||
# All the modules the initrd needs to mount the host filesystem via
|
# All the modules the initrd needs to mount the host filesystem via
|
||||||
# CIFS. Also use paravirtualised network and block devices for
|
# CIFS. Also use paravirtualised network and block devices for
|
||||||
# performance.
|
# performance.
|
||||||
|
@ -207,6 +272,7 @@ in
|
||||||
|
|
||||||
boot.initrd.postMountCommands =
|
boot.initrd.postMountCommands =
|
||||||
''
|
''
|
||||||
|
mkdir -p $targetRoot/boot
|
||||||
mount -o remount,ro $targetRoot/nix/store
|
mount -o remount,ro $targetRoot/nix/store
|
||||||
${optionalString cfg.writableStore ''
|
${optionalString cfg.writableStore ''
|
||||||
mkdir /mnt-store-tmpfs
|
mkdir /mnt-store-tmpfs
|
||||||
|
@ -225,7 +291,9 @@ in
|
||||||
boot.postBootCommands =
|
boot.postBootCommands =
|
||||||
''
|
''
|
||||||
( source /proc/cmdline
|
( source /proc/cmdline
|
||||||
${config.environment.nix}/bin/nix-store --load-db < $regInfo
|
if [ -n "$regInfo" ]; then
|
||||||
|
${config.environment.nix}/bin/nix-store --load-db < $regInfo
|
||||||
|
fi
|
||||||
)
|
)
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
@ -237,7 +305,7 @@ in
|
||||||
# where the regular value for the `fileSystems' attribute should be
|
# where the regular value for the `fileSystems' attribute should be
|
||||||
# disregarded for the purpose of building a VM test image (since
|
# disregarded for the purpose of building a VM test image (since
|
||||||
# those filesystems don't exist in the VM).
|
# those filesystems don't exist in the VM).
|
||||||
fileSystems = mkOverride 50
|
fileSystems = mkOverride 50 (
|
||||||
[ { mountPoint = "/";
|
[ { mountPoint = "/";
|
||||||
device = "/dev/vda";
|
device = "/dev/vda";
|
||||||
}
|
}
|
||||||
|
@ -253,7 +321,15 @@ in
|
||||||
options = "bind";
|
options = "bind";
|
||||||
neededForBoot = true;
|
neededForBoot = true;
|
||||||
}
|
}
|
||||||
];
|
] ++ optional cfg.useBootLoader
|
||||||
|
{ mountPoint = "/boot";
|
||||||
|
device = "/dev/disk/by-label/boot";
|
||||||
|
fsType = "ext3";
|
||||||
|
options = "ro";
|
||||||
|
noCheck = true; # fsck fails on a r/o filesystem
|
||||||
|
});
|
||||||
|
|
||||||
|
swapDevices = mkOverride 50 [ ];
|
||||||
|
|
||||||
# Starting DHCP brings down eth0, which kills the connection to the
|
# Starting DHCP brings down eth0, which kills the connection to the
|
||||||
# host filesystem and thus deadlocks the system.
|
# host filesystem and thus deadlocks the system.
|
||||||
|
|
Loading…
Reference in New Issue