From 24f8cf08cc897f0b3c2ff4118fe30c38eed85aa6 Mon Sep 17 00:00:00 2001 From: obadz Date: Tue, 16 Aug 2016 04:02:20 +0100 Subject: [PATCH] nixos/lib/make-disk-image: refactor to use nixos-install MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 '' -A tests.installer.simple passes Also tried generating an image with: nix-build -E 'let pkgs = import {}; lib = pkgs.lib; nixos = import { 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 { 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. --- nixos/lib/make-disk-image.nix | 45 ++++++------------- .../modules/installer/tools/nixos-install.sh | 17 +++---- nixos/modules/installer/tools/tools.nix | 1 + 3 files changed, 21 insertions(+), 42 deletions(-) diff --git a/nixos/lib/make-disk-image.nix b/nixos/lib/make-disk-image.nix index 9f8ec419256..58d0cb38d75 100644 --- a/nixos/lib/make-disk-image.nix +++ b/nixos/lib/make-disk-image.nix @@ -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. diff --git a/nixos/modules/installer/tools/nixos-install.sh b/nixos/modules/installer/tools/nixos-install.sh index 758f0cdb9d3..0c14e51336e 100644 --- a/nixos/modules/installer/tools/nixos-install.sh +++ b/nixos/modules/installer/tools/nixos-install.sh @@ -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. diff --git a/nixos/modules/installer/tools/tools.nix b/nixos/modules/installer/tools/tools.nix index 687a3142fa4..fc39a653abd 100644 --- a/nixos/modules/installer/tools/tools.nix +++ b/nixos/modules/installer/tools/tools.nix @@ -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"