From 9afddcf2669061712a1a9268b890dea315024480 Mon Sep 17 00:00:00 2001 From: Robert Collins Date: Thu, 14 Feb 2013 11:16:00 +1300 Subject: [PATCH] New element that uses a fedora cloud image as the base. Change-Id: I7d83bb2b359e7a8c3858eca04c96e35cf4e1fe9e --- README.md | 4 +- bin/disk-image-create | 2 +- elements/fedora/README.md | 1 + elements/fedora/bin/install-packages | 21 +++++++++ elements/fedora/bin/map-packages | 31 +++++++++++++ elements/fedora/pre-install.d/01-install-bin | 3 ++ .../fedora/pre-install.d/01-override-yum-arch | 17 +++++++ elements/fedora/root.d/10-fedora-cloud-image | 45 +++++++++++++++++++ elements/vm/README.md | 3 ++ elements/vm/install.d/51-grub | 29 ++++++++++-- sudoers.d/img-build-sudoers | 4 ++ 11 files changed, 154 insertions(+), 6 deletions(-) create mode 100644 elements/fedora/README.md create mode 100644 elements/fedora/bin/install-packages create mode 100755 elements/fedora/bin/map-packages create mode 100755 elements/fedora/pre-install.d/01-install-bin create mode 100755 elements/fedora/pre-install.d/01-override-yum-arch create mode 100755 elements/fedora/root.d/10-fedora-cloud-image diff --git a/README.md b/README.md index 577b9919..1e279dfc 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,9 @@ Design Images are built using a chroot and bind mounted /proc /sys and /dev. The goal of the image building process is to produce blank slate machines that have all the necessary bits to fulfill a specific purpose in the running of an Openstack -cloud: e.g. a nova-compute node. +cloud: e.g. a nova-compute node. Images produce either a filesystem image with +a label of cloudimg-rootfs, or can be customised to produce disk images (but +will still contain a filesystem labelled cloudimg-rootfs). An element is a particular set of code that alters how the image is built, or runs within the chroot to prepare the image. E.g. the local-config element diff --git a/bin/disk-image-create b/bin/disk-image-create index dbafb151..9e76a36c 100755 --- a/bin/disk-image-create +++ b/bin/disk-image-create @@ -61,7 +61,7 @@ while true ; do esac done -if [ "$CLEAR_ENV" == "1" -a "$HOME" != "" ]; then +if [ "$CLEAR_ENV" = "1" -a "$HOME" != "" ]; then echo "Re-execing to clear environment." echo "(note this will prevent much of the local_config element from working)" exec -c $0 "$@" diff --git a/elements/fedora/README.md b/elements/fedora/README.md new file mode 100644 index 00000000..4953b447 --- /dev/null +++ b/elements/fedora/README.md @@ -0,0 +1 @@ +Use Fedora cloud images as the baseline for built disk images. diff --git a/elements/fedora/bin/install-packages b/elements/fedora/bin/install-packages new file mode 100644 index 00000000..49d0b364 --- /dev/null +++ b/elements/fedora/bin/install-packages @@ -0,0 +1,21 @@ +#!/bin/sh + +# Copyright 2012 Hewlett-Packard Development Company, L.P. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +set -e + +yum -y install $(map-packages "$@") + diff --git a/elements/fedora/bin/map-packages b/elements/fedora/bin/map-packages new file mode 100755 index 00000000..c08d56cd --- /dev/null +++ b/elements/fedora/bin/map-packages @@ -0,0 +1,31 @@ +#!/bin/env python + +# Copyright 2012 Hewlett-Packard Development Company, L.P. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import sys + +# Manually maintained for brevity; consider making this compiled from +# distromatch or other rich data sources. +# Debian name on the left, Fedora on the right. +package_map = { + 'linux-image-generic': 'kernel', + 'open-iscsi': 'iscsi-initiator-utils', + 'vlan': 'vconfig', + } + +for arg in sys.argv[1:]: + print(package_map.get(arg, arg)) +sys.exit(0) diff --git a/elements/fedora/pre-install.d/01-install-bin b/elements/fedora/pre-install.d/01-install-bin new file mode 100755 index 00000000..555bc782 --- /dev/null +++ b/elements/fedora/pre-install.d/01-install-bin @@ -0,0 +1,3 @@ +#!/bin/sh + +install -m 0755 -o root -g root $(dirname $0)/../bin/* /usr/local/bin diff --git a/elements/fedora/pre-install.d/01-override-yum-arch b/elements/fedora/pre-install.d/01-override-yum-arch new file mode 100755 index 00000000..bf0c6ed8 --- /dev/null +++ b/elements/fedora/pre-install.d/01-override-yum-arch @@ -0,0 +1,17 @@ +#!/bin/sh + +if [ "i386" = "$ARCH" ]; then + basearch=i386 + arch=i686 +elif [ "amd64" = "$ARCH" ]; then + basearch=x86_64 + arch=x86_64 +else + echo "********************" + echo "Unknown arch '$ARCH'" + echo "********************" + exit 1 +fi + +echo $basearch > /etc/yum/vars/basearch +echo $arch > /etc/yum/vars/arch diff --git a/elements/fedora/root.d/10-fedora-cloud-image b/elements/fedora/root.d/10-fedora-cloud-image new file mode 100755 index 00000000..cdfcb17a --- /dev/null +++ b/elements/fedora/root.d/10-fedora-cloud-image @@ -0,0 +1,45 @@ +#!/bin/bash + +set -e + +[ -n "$ARCH" ] +[ -n "$TARGET_ROOT" ] + +if [ 'amd64' = "$ARCH" ] ; then + ARCH="x86_64" +fi + +IMG_PATH=~/.cache/image-create +CLOUD_IMAGES=${CLOUD_IMAGES:-http://mattdm.fedorapeople.org/cloud-images/} +RELEASE=${RELEASE:-Fedora18} +BASE_IMAGE_FILE=${BASE_IMAGE_FILE:-$RELEASE-Cloud-$ARCH-latest.raw.tar.xz} +BASE_IMAGE_TAR=$RELEASE-Cloud-$ARCH-latest.tgz + +mkdir -p $IMG_PATH +# TODO: don't cache forever. +if [ ! -f $IMG_PATH/$BASE_IMAGE_FILE ] ; then + echo "Fetching Base Image" + wget $CLOUD_IMAGES/$BASE_IMAGE_FILE -O $IMG_PATH/$BASE_IMAGE_FILE.tmp + mv $IMG_PATH/$BASE_IMAGE_FILE.tmp $IMG_PATH/$BASE_IMAGE_FILE +fi +if [ ! -f $IMG_PATH/$BASE_IMAGE_TAR ] ; then + echo "Repacking base image as tarball." + WORKING=$(mktemp -d) + EACTION="rm -r $WORKING" + trap "$EACTION" EXIT + echo "Working in $WORKING" + tar -xJC $WORKING -f $IMG_PATH/$BASE_IMAGE_FILE + LOOPDEV=$(sudo losetup --show -r -f $WORKING/*.raw) + EACTION="sudo losetup -d $LOOPDEV;$EACTION" + trap "$EACTION" EXIT + sudo partprobe $LOOPDEV + mkdir $WORKING/mnt + sudo mount ${LOOPDEV}p2 $WORKING/mnt + EACTION="sudo umount -f $WORKING/mnt;$EACTION" + trap "$EACTION" EXIT + # Chroot in so that we get the correct uid/gid + sudo chroot $WORKING/mnt bin/tar -cz . > $WORKING/tmp.tar + mv $WORKING/tmp.tar $IMG_PATH/$BASE_IMAGE_TAR +fi +# Extract the base image +sudo tar -C $TARGET_ROOT -xzf $IMG_PATH/$BASE_IMAGE_TAR diff --git a/elements/vm/README.md b/elements/vm/README.md index ecc8eaf6..5be135b5 100644 --- a/elements/vm/README.md +++ b/elements/vm/README.md @@ -1,2 +1,5 @@ Sets up a partitioned disk (rather than building just one filesystem with no partition table). + +The disk will have grub[2]-install run on it, and that assumes a functional +grub[2] setup. diff --git a/elements/vm/install.d/51-grub b/elements/vm/install.d/51-grub index e8d68728..636246e0 100755 --- a/elements/vm/install.d/51-grub +++ b/elements/vm/install.d/51-grub @@ -1,11 +1,32 @@ #!/bin/bash -# Configure grub +# Configure grub. Note that the various conditionals here are to handle +# different distributions gracefully. set -e # XXX: grub-probe on the nbd0 device returns nothing - workaround, manually # specify modules. https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1073731 -grub-install --modules="biosdisk part_msdos" /dev/nbd0 -# XXX: Undiagnosed, but the LABEL=cloudimg-rootfs isn't being picked up: workaround it. -sed -i 's%/dev/nbd0p1%LABEL=cloudimg-rootfs%' /boot/grub/grub.cfg +GRUBNAME=`which grub-install` || echo "trying grub2-install" +if [ -z "$GRUBNAME" ]; then + GRUBNAME=`which grub2-install` +fi +if [ -z "$GRUBNAME" ]; then + echo "NO grub-install or grub2-install found" + exit 1 +fi +BOOT_DEV=/dev/nbd0 +PART_DEV=/dev/nbd0p1 +$GRUBNAME --modules="biosdisk part_msdos" $BOOT_DEV +# This might be better factored out into a per-distro 'install-bootblock' +# helper. +if [ -f "/boot/grub/grub.cfg" ] ; then + GRUB_CFG=/boot/grub/grub.cfg +elif [ -f "/boot/grub2/grub.cfg" ] ; then + GRUB_CFG=/boot/grub2/grub.cfg +fi +# grub-mkconfig generates a config with the device in it, +# force use of a LABEL: +# NOTE: Updating the grub config by hand once deployed should work, its just +# prepping it in a different environment that needs fiddling. +sed -i "s%$PART_DEV%LABEL=cloudimg-rootfs%" $GRUB_CFG diff --git a/sudoers.d/img-build-sudoers b/sudoers.d/img-build-sudoers index a2739c38..bd65d45e 100644 --- a/sudoers.d/img-build-sudoers +++ b/sudoers.d/img-build-sudoers @@ -43,3 +43,7 @@ ALL ALL=(root) NOPASSWD: /usr/bin/unlink /tmp/*/mnt/* ALL ALL=(root) NOPASSWD: /bin/cp -t /tmp/*/mnt/etc/ -a /tmp/*/hooks/first-boot.d ALL ALL=(root) NOPASSWD: /usr/bin/install -m 0755 -o root -g root -D */dib-run-parts /tmp/*/mnt/usr/local/bin/dib-run-parts ALL ALL=(root) SETENV: NOPASSWD: /usr/sbin/chroot /tmp/*/mnt * +ALL ALL=(root) NOPASSWD: /sbin/losetup --show -r -f /tmp/*/*.raw +ALL ALL=(root) NOPASSWD: /sbin/losetup -d /dev/loop* +ALL ALL=(root) NOPASSWD: /sbin/losetup -d /dev/loop* +ALL ALL=(root) NOPASSWD: /sbin/partprobe /dev/loop*