forked from mirrors/nixpkgs
* 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
13
default.nix
13
default.nix
|
@ -11,11 +11,22 @@ let
|
|||
|
||||
inherit (eval) config pkgs;
|
||||
|
||||
# This is for `nixos-rebuild build-vm'.
|
||||
vmConfig = (import ./lib/eval-config.nix {
|
||||
inherit system;
|
||||
modules = [ configuration ./modules/virtualisation/qemu-vm.nix ];
|
||||
}).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
|
||||
|
||||
{
|
||||
|
@ -25,6 +36,8 @@ in
|
|||
|
||||
vm = vmConfig.system.build.vm;
|
||||
|
||||
vmWithBootLoader = vmWithBootLoaderConfig.system.build.vm;
|
||||
|
||||
# The following are used by nixos-rebuild.
|
||||
nixFallback = pkgs.nixUnstable;
|
||||
manifests = config.installer.manifests;
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
<arg choice='plain'><option>build</option></arg>
|
||||
<arg choice='plain'><option>dry-run</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>
|
||||
<sbr />
|
||||
<arg><option>--install-grub</option></arg>
|
||||
|
@ -151,6 +153,35 @@ $ ./result/bin/run-*-vm
|
|||
</listitem>
|
||||
</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>
|
||||
|
||||
</para>
|
||||
|
|
|
@ -22,6 +22,8 @@ The operation is one of the following:
|
|||
activate it
|
||||
build-vm: build a virtual machine containing the configuration
|
||||
(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
|
||||
pull: just pull the Nixpkgs channel manifest and exit
|
||||
|
||||
|
@ -64,7 +66,7 @@ while test "$#" -gt 0; do
|
|||
--help)
|
||||
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"
|
||||
;;
|
||||
--install-grub)
|
||||
|
@ -171,9 +173,12 @@ if test -z "$rollback"; then
|
|||
elif test "$action" = test -o "$action" = build -o "$action" = dry-run; then
|
||||
nix-build $NIXOS -A system -K -k $extraBuildFlags > /dev/null
|
||||
pathToConfig=./result
|
||||
elif test "$action" = build-vm; then
|
||||
elif [ "$action" = build-vm ]; then
|
||||
nix-build $NIXOS -A vm -K -k $extraBuildFlags > /dev/null
|
||||
pathToConfig=./result
|
||||
elif [ "$action" = build-vm-with-bootloader ]; then
|
||||
nix-build $NIXOS -A vmWithBootLoader -K -k $extraBuildFlags > /dev/null
|
||||
pathToConfig=./result
|
||||
else
|
||||
showSyntax
|
||||
fi
|
||||
|
|
|
@ -38,7 +38,7 @@ if [ "$action" = "switch" -o "$action" = "boot" ]; then
|
|||
|
||||
if [ "$NIXOS_INSTALL_GRUB" = 1 -o "$oldGrubVersion" != "$newGrubVersion" ]; then
|
||||
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
|
||||
fi
|
||||
fi
|
||||
|
|
|
@ -111,6 +111,23 @@ let
|
|||
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;
|
||||
|
@ -146,12 +163,17 @@ let
|
|||
-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} \
|
||||
${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 \
|
||||
'' 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} \
|
||||
$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}
|
||||
'';
|
||||
|
||||
|
@ -165,11 +187,54 @@ let
|
|||
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
|
||||
|
||||
{
|
||||
require = options;
|
||||
|
||||
boot.loader.grub.device = mkOverride 50 "/dev/vda";
|
||||
|
||||
# All the modules the initrd needs to mount the host filesystem via
|
||||
# CIFS. Also use paravirtualised network and block devices for
|
||||
# performance.
|
||||
|
@ -207,6 +272,7 @@ in
|
|||
|
||||
boot.initrd.postMountCommands =
|
||||
''
|
||||
mkdir -p $targetRoot/boot
|
||||
mount -o remount,ro $targetRoot/nix/store
|
||||
${optionalString cfg.writableStore ''
|
||||
mkdir /mnt-store-tmpfs
|
||||
|
@ -225,7 +291,9 @@ in
|
|||
boot.postBootCommands =
|
||||
''
|
||||
( source /proc/cmdline
|
||||
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
|
||||
# disregarded for the purpose of building a VM test image (since
|
||||
# those filesystems don't exist in the VM).
|
||||
fileSystems = mkOverride 50
|
||||
fileSystems = mkOverride 50 (
|
||||
[ { mountPoint = "/";
|
||||
device = "/dev/vda";
|
||||
}
|
||||
|
@ -253,7 +321,15 @@ in
|
|||
options = "bind";
|
||||
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
|
||||
# host filesystem and thus deadlocks the system.
|
||||
|
|
Loading…
Reference in a new issue