nixos/lib/make-disk-image: refactor to use nixos-install

- Replace hand-rolled version of nixos-install in make-disk-image by an
  actual call to nixos-install
- Required a few cleanups of nixos-install
- nixos-install invokes an activation script which the hand-rolled version
  in make-disk-image did not do. We remove /etc/machine-id as that's
  a host-specific, impure, output of the activation script

Testing:

nix-build '<nixpkgs/nixos/release.nix>' -A tests.installer.simple passes

Also tried generating an image with:

nix-build -E 'let
    pkgs = import <nixpkgs> {};
    lib = pkgs.lib;
    nixos = import <nixpkgs/nixos> {
      configuration = {
        fileSystems."/".device = "/dev/disk/by-label/nixos";
        boot.loader.grub.devices = [ "/dev/sda" ];
        boot.loader.grub.extraEntries = '"''"'
          menuentry "Ubuntu" {
             insmod ext2
             search --set=root --label ubuntu
             configfile /boot/grub/grub.cfg
          }
        '"''"';
      };
    };
  in import <nixpkgs/nixos/lib/make-disk-image.nix> {
    inherit pkgs lib;
    config = nixos.config;
    diskSize = 2000;
    partitioned = false;
    installBootLoader = false;
  }'

Then installed the image:
$ sudo df if=./result/nixos.img of=/dev/sdaX bs=1M
$ sudo resize2fs /dev/disk/by-label/nixos
$ sudo mount /dev/disk/by-label/nixos /mnt
$ sudo mount --rbind /proc /mnt/proc
$ sudo mount --rbind /dev /mnt/dev
$ sudo chroot /mnt /nix/var/nix/profiles/system/bin/switch-to-configuration boot

[ … optionally do something about passwords … ]

and successfully rebooted to that image.

Was doing all this from inside a Ubuntu VM with a single user nix install.
This commit is contained in:
obadz 2016-08-16 04:02:20 +01:00
parent 4d1d37014a
commit 24f8cf08cc
3 changed files with 21 additions and 42 deletions

View File

@ -67,40 +67,24 @@ pkgs.vmTools.runInLinuxVM (
mkdir /mnt
mount $rootDisk /mnt
# The initrd expects these directories to exist.
mkdir /mnt/dev /mnt/proc /mnt/sys
mount -o bind /proc /mnt/proc
mount -o bind /dev /mnt/dev
mount -o bind /sys /mnt/sys
# Copy all paths in the closure to the filesystem.
storePaths=$(perl ${pkgs.pathsFromGraph} /tmp/xchg/closure)
mkdir -p /mnt/nix/store
echo "copying everything (will take a while)..."
set -f
cp -prd $storePaths /mnt/nix/store/
# Register the paths in the Nix database.
printRegistration=1 perl ${pkgs.pathsFromGraph} /tmp/xchg/closure | \
chroot /mnt ${config.nix.package.out}/bin/nix-store --load-db --option build-users-group ""
${config.nix.package.out}/bin/nix-store --load-db --option build-users-group ""
# Add missing size/hash fields to the database. FIXME:
# exportReferencesGraph should provide these directly.
chroot /mnt ${config.nix.package.out}/bin/nix-store --verify --check-contents
${config.nix.package.out}/bin/nix-store --verify --check-contents --option build-users-group ""
# Create the system profile to allow nixos-rebuild to work.
chroot /mnt ${config.nix.package.out}/bin/nix-env --option build-users-group "" \
-p /nix/var/nix/profiles/system --set ${config.system.build.toplevel}
# In case the bootloader tries to write to /dev/sda…
ln -s vda /dev/xvda
ln -s vda /dev/sda
# `nixos-rebuild' requires an /etc/NIXOS.
mkdir -p /mnt/etc
touch /mnt/etc/NIXOS
# `switch-to-configuration' requires a /bin/sh
mkdir -p /mnt/bin
ln -s ${config.system.build.binsh}/bin/sh /mnt/bin/sh
# Install the closure onto the image
USER=root ${config.system.build.nixos-install}/bin/nixos-install \
--closure ${config.system.build.toplevel} \
--no-channel-copy \
--no-root-passwd \
${optionalString (!installBootLoader) "--no-bootloader"}
# Install a configuration.nix.
mkdir -p /mnt/etc/nixos
@ -108,12 +92,9 @@ pkgs.vmTools.runInLinuxVM (
cp ${configFile} /mnt/etc/nixos/configuration.nix
''}
# Generate the GRUB menu.
ln -s vda /dev/xvda
ln -s vda /dev/sda
${optionalString installBootLoader "chroot /mnt ${config.system.build.toplevel}/bin/switch-to-configuration boot"}
# Remove /etc/machine-id so that each machine cloning this image will get its own id
rm -f /mnt/etc/machine-id
umount /mnt/proc /mnt/dev /mnt/sys
umount /mnt
# Do a fsck to make sure resize2fs works.

View File

@ -24,6 +24,7 @@ fi
# Parse the command line for the -I flag
extraBuildFlags=()
chrootCommand=(/run/current-system/sw/bin/bash)
buildUsersGroup="nixbld"
while [ "$#" -gt 0 ]; do
i="$1"; shift 1
@ -42,6 +43,7 @@ while [ "$#" -gt 0 ]; do
;;
--closure)
closure="$1"; shift 1
buildUsersGroup=""
;;
--no-channel-copy)
noChannelCopy=1
@ -100,8 +102,8 @@ mount -t tmpfs -o "mode=0755" none $mountPoint/run
mount -t tmpfs -o "mode=0755" none $mountPoint/var/setuid-wrappers
rm -rf $mountPoint/var/run
ln -s /run $mountPoint/var/run
rm -f $mountPoint/etc/{resolv.conf,hosts}
cp -Lf /etc/resolv.conf /etc/hosts $mountPoint/etc/
for f in /etc/resolv.conf /etc/hosts; do rm -f $mountPoint/$f; [ -f "$f" ] && cp -Lf $f $mountPoint/etc/; done
for f in /etc/passwd /etc/group; do touch $mountPoint/$f; [ -f "$f" ] && mount --rbind -o ro $f $mountPoint/$f; done
cp -Lf "@cacert@" "$mountPoint/tmp/ca-cert.crt"
export SSL_CERT_FILE=/tmp/ca-cert.crt
@ -141,7 +143,7 @@ mkdir -m 0755 -p \
$mountPoint/nix/var/log/nix/drvs
mkdir -m 1775 -p $mountPoint/nix/store
chown root:@nixbld_gid@ $mountPoint/nix/store
chown @root_uid@:@nixbld_gid@ $mountPoint/nix/store
# There is no daemon in the chroot.
@ -155,7 +157,7 @@ export LC_TIME=
# Builds will use users that are members of this group
extraBuildFlags+=(--option "build-users-group" "nixbld")
extraBuildFlags+=(--option "build-users-group" "$buildUsersGroup")
# Inherit binary caches from the host
@ -163,11 +165,6 @@ binary_caches="$(@perl@/bin/perl -I @nix@/lib/perl5/site_perl/*/* -e 'use Nix::C
extraBuildFlags+=(--option "binary-caches" "$binary_caches")
touch $mountPoint/etc/passwd $mountPoint/etc/group
mount --bind -o ro /etc/passwd $mountPoint/etc/passwd
mount --bind -o ro /etc/group $mountPoint/etc/group
# Copy Nix to the Nix store on the target device, unless it's already there.
if ! NIX_DB_DIR=$mountPoint/nix/var/nix/db nix-store --check-validity @nix@ 2> /dev/null; then
echo "copying Nix to $mountPoint...."
@ -246,7 +243,7 @@ ln -sfn /nix/var/nix/profiles/per-user/root/channels $mountPoint/root/.nix-defex
# Get rid of the /etc bind mounts.
umount $mountPoint/etc/passwd $mountPoint/etc/group
for f in /etc/passwd /etc/group; do [ -f "$f" ] && umount $mountPoint/$f; done
# Grub needs an mtab.

View File

@ -24,6 +24,7 @@ let
inherit (pkgs) perl pathsFromGraph rsync;
nix = config.nix.package.out;
cacert = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
root_uid = config.ids.uids.root;
nixbld_gid = config.ids.gids.nixbld;
nixClosure = pkgs.runCommand "closure"