From 49641e0de006fdc5edd11292b1e94410c3bb8d79 Mon Sep 17 00:00:00 2001 From: Dan Peebles Date: Wed, 22 Feb 2017 23:47:24 +0000 Subject: [PATCH] make-disk-image.nix: support additional filesystem contents This makes make-disk-image.nix slightly more consistent with other image builders we have. Unfortunately I duplicated some code in doing so, but this is temporary duplication on the path to consolidating everything. See https://github.com/NixOS/nixpkgs/issues/23052 for more details on that. I'm also exposing the option in the amazon-image.nix maintainer module. --- nixos/lib/make-disk-image.nix | 47 ++++++++++++++++++- .../maintainers/scripts/ec2/amazon-image.nix | 23 ++++++++- 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/nixos/lib/make-disk-image.nix b/nixos/lib/make-disk-image.nix index e279803f2ea0..d9d76b5919a5 100644 --- a/nixos/lib/make-disk-image.nix +++ b/nixos/lib/make-disk-image.nix @@ -7,6 +7,12 @@ , # The size of the disk, in megabytes. diskSize + # The files and directories to be placed in the target file system. + # This is a list of attribute sets {source, target} where `source' + # is the file system object (regular file or directory) to be + # grafted in the file system at path `target'. +, contents ? [] + , # Whether the disk should be partitioned (with a single partition # containing the root filesystem) or contain the root filesystem # directly. @@ -45,7 +51,14 @@ pkgs.vmTools.runInLinuxVM ( ${pkgs.vmTools.qemu}/bin/qemu-img create -f ${format} $diskImage "${toString diskSize}M" mv closure xchg/ ''; - buildInputs = [ pkgs.utillinux pkgs.perl pkgs.e2fsprogs pkgs.parted ]; + buildInputs = with pkgs; [ utillinux perl e2fsprogs parted rsync ]; + + # I'm preserving the line below because I'm going to search for it across nixpkgs to consolidate + # image building logic. The comment right below this now appears in 4 different places in nixpkgs :) + # !!! should use XML. + sources = map (x: x.source) contents; + targets = map (x: x.target) contents; + exportReferencesGraph = [ "closure" config.system.build.toplevel ]; inherit postVM; @@ -98,6 +111,38 @@ pkgs.vmTools.runInLinuxVM ( # Remove /etc/machine-id so that each machine cloning this image will get its own id rm -f /mnt/etc/machine-id + # Copy arbitrary other files into the image + # Semi-shamelessly copied from make-etc.sh. I (@copumpkin) shall factor this stuff out as part of + # https://github.com/NixOS/nixpkgs/issues/23052. + set -f + sources_=($sources) + targets_=($targets) + set +f + + for ((i = 0; i < ''${#targets_[@]}; i++)); do + source="''${sources_[$i]}" + target="''${targets_[$i]}" + + if [[ "$source" =~ '*' ]]; then + + # If the source name contains '*', perform globbing. + mkdir -p /mnt/$target + for fn in $source; do + rsync -a --no-o --no-g "$fn" /mnt/$target/ + done + + else + + mkdir -p /mnt/$(dirname $target) + if ! [ -e /mnt/$target ]; then + rsync -a --no-o --no-g $source /mnt/$target + else + echo "duplicate entry $target -> $source" + exit 1 + fi + fi + done + umount /mnt # Make sure resize2fs works diff --git a/nixos/maintainers/scripts/ec2/amazon-image.nix b/nixos/maintainers/scripts/ec2/amazon-image.nix index bfa4f4b3ca59..b4190df8335b 100644 --- a/nixos/maintainers/scripts/ec2/amazon-image.nix +++ b/nixos/maintainers/scripts/ec2/amazon-image.nix @@ -2,15 +2,34 @@ with lib; -{ +let + cfg = config.amazonImage; +in { imports = [ ../../../modules/installer/cd-dvd/channel.nix ../../../modules/virtualisation/amazon-image.nix ]; - system.build.amazonImage = import ../../../lib/make-disk-image.nix { + options.amazonImage = { + contents = mkOption { + example = literalExample '' + [ { source = pkgs.memtest86 + "/memtest.bin"; + target = "boot/memtest.bin"; + } + ] + ''; + default = []; + description = '' + This option lists files to be copied to fixed locations in the + generated image. Glob patterns work. + ''; + }; + }; + + config.system.build.amazonImage = import ../../../lib/make-disk-image.nix { inherit lib config; + inherit (cfg) contents; pkgs = import ../../../.. { inherit (pkgs) system; }; # ensure we use the regular qemu-kvm package partitioned = config.ec2.hvm; diskSize = if config.ec2.hvm then 2048 else 8192;