From 1ee3a01447469d613124ecc8ac5680699d767b7f Mon Sep 17 00:00:00 2001 From: Robert Collins Date: Mon, 11 Feb 2013 17:01:36 +1300 Subject: [PATCH] Move initial root contents into a hook. This is a necessary but not complete step towards supporting Fedora and Suse distributions. Further work is needed (e.g. to quiesce daemons on installation). Change-Id: If3ea6093d41a21de755db52328226b84b5a3ede6 --- .gitignore | 1 + README.md | 14 +++++++++-- bin/disk-image-create | 5 +--- elements/ubuntu/README.md | 1 + .../ubuntu/root.d/10-cache-ubuntu-tarball | 22 ++++++++++++++++ elements/vm/install.d/51-grub | 1 - lib/img-defaults | 4 --- lib/img-functions | 25 ++++++++++--------- 8 files changed, 50 insertions(+), 23 deletions(-) create mode 100644 elements/ubuntu/README.md create mode 100755 elements/ubuntu/root.d/10-cache-ubuntu-tarball diff --git a/.gitignore b/.gitignore index 4a919ea97..c66683a36 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .tox *.egg-info dist +*.qcow2 diff --git a/README.md b/README.md index 1f4b41480..5cd1de76e 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,16 @@ Writing an element Make as many of the following subdirectories as you need, depending on what part of the process you need to customise: +* root.d: Create or adapt the initial root filesystem content. This is where + alternative distribution support is added, or customisations such as + building on an existing image. If no element configures a root, the ubuntu + element will be automatically invoked to obtain an Ubuntu image. + Runs outside the chroot on the host environment, so should cleanup after + itself using the root-finished.d hook. + NB: Only one element can use this at a time. + + * inputs: $ARCH=i386|amd64 $TARGET\_ROOT=/path/to/target/workarea + * block-device-size.d: Alter the size (in GB) of the disk image. This is useful when a particular element will require a certain minimum (or maximum) size. You can either error and stop the build, or adjust the size to match. @@ -94,8 +104,8 @@ part of the process you need to customise: so this should be used rarely - only one element in a mix can reliably set a size. - * outputs: $IMAGE\_SIZE={size_in_GB} - * inputs: $IMAGE_SIZE={size_in_GB} + * outputs: $IMAGE\_SIZE={size\_in\_GB} + * inputs: $IMAGE\_SIZE={size\_in\_GB} * block-device.d: customise the block device that the image will be made on (e.g. to make partitions). diff --git a/bin/disk-image-create b/bin/disk-image-create index a73e55e7b..29cbae89b 100755 --- a/bin/disk-image-create +++ b/bin/disk-image-create @@ -41,7 +41,6 @@ INSTALL_PACKAGES="" COMPRESS_IMAGE="true" TEMP=`getopt -o a:ho:xucp: -n $SCRIPTNAME -- "$@"` if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi -echo "XXX $TEMP" # Note the quotes around `$TEMP': they are essential! eval set -- "$TEMP" @@ -76,13 +75,11 @@ IMAGE_ELEMENT=$($SCRIPT_HOME/element-info --expand-dependencies $IMAGE_ELEMENT) echo "Building elements: $IMAGE_ELEMENT" echo "If prompted for sudo, install sudoers.d/img-build-sudoers into /etc/sudoers.d and restart the build." -mkdir -p $IMG_PATH -# TODO: make an element. +# TODO: make into an element. ensure_nbd mk_build_dir -ensure_base_available eval_run_d block-device-size "IMAGE_SIZE=" qemu-img create -f qcow2 -o preallocation=metadata $TMP_IMAGE_PATH ${IMAGE_SIZE}G diff --git a/elements/ubuntu/README.md b/elements/ubuntu/README.md new file mode 100644 index 000000000..6c6e90b4a --- /dev/null +++ b/elements/ubuntu/README.md @@ -0,0 +1 @@ +Use Ubuntu cloud images as the baseline for built disk images. diff --git a/elements/ubuntu/root.d/10-cache-ubuntu-tarball b/elements/ubuntu/root.d/10-cache-ubuntu-tarball new file mode 100755 index 000000000..686fcf711 --- /dev/null +++ b/elements/ubuntu/root.d/10-cache-ubuntu-tarball @@ -0,0 +1,22 @@ +#!/bin/bash +# These are useful, or at worst not harmful, for all images we build. + +set -e + +[ -n "$ARCH" ] +[ -n "$TARGET_ROOT" ] + +IMG_PATH=~/.cache/image-create +CLOUD_IMAGES=${CLOUD_IMAGES:-http://cloud-images.ubuntu.com/} +RELEASE=${RELEASE:-quantal} +BASE_IMAGE_FILE=${BASE_IMAGE_FILE:-$RELEASE-server-cloudimg-$ARCH-root.tar.gz} + +mkdir -p $IMG_PATH +# TODO: don't cache -current forever. +if [ ! -f $IMG_PATH/$BASE_IMAGE_FILE ] ; then + echo "Fetching Base Image" + wget $CLOUD_IMAGES/$RELEASE/current/$BASE_IMAGE_FILE -O $IMG_PATH/$BASE_IMAGE_FILE.tmp + mv $IMG_PATH/$BASE_IMAGE_FILE.tmp $IMG_PATH/$BASE_IMAGE_FILE +fi +# Extract the base image +sudo tar -C $TARGET_ROOT -xzf $IMG_PATH/$BASE_IMAGE_FILE diff --git a/elements/vm/install.d/51-grub b/elements/vm/install.d/51-grub index 482c4d0b3..e8d687281 100755 --- a/elements/vm/install.d/51-grub +++ b/elements/vm/install.d/51-grub @@ -3,7 +3,6 @@ set -e -set -o xtrace # XXX: grub-probe on the nbd0 device returns nothing - workaround, manually # specify modules. https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1073731 diff --git a/lib/img-defaults b/lib/img-defaults index 496660a91..273dd9d04 100644 --- a/lib/img-defaults +++ b/lib/img-defaults @@ -15,9 +15,6 @@ # options for create-baremetal-image.sh ARCH=${ARCH:-$(dpkg --print-architecture)} -RELEASE=${RELEASE:-quantal} -BASE_IMAGE_FILE=${BASE_IMAGE_FILE:-$RELEASE-server-cloudimg-$ARCH-root.tar.gz} -CLOUD_IMAGES=${CLOUD_IMAGES:-http://cloud-images.ubuntu.com/} FS_TYPE=${FS_TYPE:-ext4} # Used to set the file extension only at this stage. IMAGE_TYPE=${IMAGE_TYPE:-qcow2} @@ -25,5 +22,4 @@ IMAGE_NAME=${IMAGE_NAME:-image} export IMAGE_SIZE=${IMAGE_SIZE:-2} # N.B. This size is in GB # Set via the CLI normally. # IMAGE_ELEMENT= -IMG_PATH=~/.cache/image-create export ELEMENTS_DIR=$(dirname $0)/../elements diff --git a/lib/img-functions b/lib/img-functions index 2dee2fb84..fba3bf48f 100644 --- a/lib/img-functions +++ b/lib/img-functions @@ -48,15 +48,6 @@ function ensure_nbd () { (lsmod | grep '^nbd ') || sudo modprobe nbd max_part=16 } -function ensure_base_available () { - # TODO: don't cache -current forever. - if [ ! -f $IMG_PATH/$BASE_IMAGE_FILE ] ; then - echo "Fetching Base Image" - wget $CLOUD_IMAGES/$RELEASE/current/$BASE_IMAGE_FILE -O $IMG_PATH/$BASE_IMAGE_FILE.tmp - mv $IMG_PATH/$BASE_IMAGE_FILE.tmp $IMG_PATH/$BASE_IMAGE_FILE - fi -} - function ensure_sudo () { sudo echo "Ensuring sudo is available" } @@ -69,8 +60,17 @@ function mount_tmp_image () { } function create_base () { - # Extract the base image - sudo tar -C $TMP_MOUNT_PATH -xzf $IMG_PATH/$BASE_IMAGE_FILE + # Copy data in to the root. + TARGET_ROOT=$TMP_MOUNT_PATH run_d root + + if [ -z "$(ls /tmp/foo)" ] ; then + # Nothing copied in, use Ubuntu. + echo "Adding ubuntu element as / had no contents" + IMAGE_ELEMENT=$($SCRIPT_HOME/element-info --expand-dependencies $IMAGE_ELEMENT ubuntu) + generate_hooks + echo "Now building: $IMAGE_ELEMENT" + TARGET_ROOT=$TMP_MOUNT_PATH run_d root + fi # Configure Image # Setup resolv.conf so we can chroot to install some packages @@ -242,4 +242,5 @@ function do_extra_package_install () { function copy_elements_lib () { sudo mkdir -p $TMP_MOUNT_PATH/lib/diskimage-builder sudo cp -t $TMP_MOUNT_PATH/lib/diskimage-builder $_LIB/elements-functions -} \ No newline at end of file +} +