# 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. function unmount_image () { # unmount from the chroot # Don't use TMP_MOUNT_PATH here, it might not have been set. sudo umount -f $TMP_BUILD_DIR/mnt/sys || true sudo umount -f $TMP_BUILD_DIR/mnt/proc || true sudo umount -f $TMP_BUILD_DIR/mnt/dev || true sudo umount -f $TMP_BUILD_DIR/mnt/tmp/in_target.d || true # give it a second (ok really 5) to umount XXX - why? should instead track # the mount data / lsof etc. sleep 5 # oh ya don't want to forget to unmount the image sudo umount -f $TMP_BUILD_DIR/mnt || true # having disk corruption issues; one possibility is qemu-nbd not flushing # dirty pages on disconnect? sync if [ -n "$EXTRA_UNMOUNT" ]; then $EXTRA_UNMOUNT fi } function cleanup () { unmount_image cleanup_dirs } function cleanup_dirs () { sudo rm -rf $TMP_BUILD_DIR/built sudo rm -rf $TMP_BUILD_DIR/mnt sudo umount $TMP_BUILD_DIR rm -rf $TMP_BUILD_DIR } function ensure_nbd () { NBD=`which qemu-nbd` || true if [ -z "$NBD" ]; then echo "Need qemu-nbd to build qcow2 files." sudo apt-get install qemu-utils fi # prep nbd for mounting (lsmod | grep '^nbd ') || sudo modprobe nbd max_part=16 } function ensure_sudo () { sudo echo "Ensuring sudo is available" } function create_base () { mkdir $TMP_BUILD_DIR/mnt export TMP_MOUNT_PATH=$TMP_BUILD_DIR/mnt # Copy data in to the root. TARGET_ROOT=$TMP_MOUNT_PATH run_d root if [ -z "$(ls $TMP_MOUNT_PATH | grep -v lost+found)" ] ; 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 # XXXX: Should store the old state rather than unlink; then restore later. if [ -L $TMP_MOUNT_PATH/etc/resolv.conf ] ; then sudo unlink $TMP_MOUNT_PATH/etc/resolv.conf fi if [ -f $TMP_MOUNT_PATH/etc/resolv.conf ] ; then sudo rm -f $TMP_MOUNT_PATH/etc/resolv.conf fi # Recreate resolv.conf sudo touch $TMP_MOUNT_PATH/etc/resolv.conf sudo chmod 777 $TMP_MOUNT_PATH/etc/resolv.conf # use system configured resolv.conf if available to support internal proxy resolving if [ -e /etc/resolv.conf ] then cat /etc/resolv.conf > $TMP_MOUNT_PATH/etc/resolv.conf else echo nameserver 8.8.8.8 > $TMP_MOUNT_PATH/etc/resolv.conf fi mount_proc_dev_sys } function mount_proc_dev_sys () { # supporting kernel file systems sudo mount -t proc none $TMP_MOUNT_PATH/proc sudo mount --bind /dev $TMP_MOUNT_PATH/dev sudo mount -t sysfs none $TMP_MOUNT_PATH/sys } # Helper function to run a command inside the chroot function run_in_target() { # -E to preserve http_proxy sudo -E chroot $TMP_MOUNT_PATH "$@" } # Helper function to run a directory of scripts inside the chroot function run_d_in_target() { check_element # If we can find a directory of hooks to run in the target filesystem, bind # mount it into the target and then execute run-parts in a chroot if [ -d ${TMP_HOOKS_PATH}/$1.d ] ; then sudo mkdir $TMP_MOUNT_PATH/tmp/in_target.d sudo mount --bind ${TMP_HOOKS_PATH} $TMP_MOUNT_PATH/tmp/in_target.d sudo mount -o remount,ro,bind ${TMP_HOOKS_PATH} $TMP_MOUNT_PATH/tmp/in_target.d check_break before-$1 run_in_target bash run_in_target dib-run-parts /tmp/in_target.d/$1.d check_break after-$1 run_in_target bash sudo umount -f $TMP_MOUNT_PATH/tmp/in_target.d sudo rmdir $TMP_MOUNT_PATH/tmp/in_target.d fi } # Run a directory of hooks outside the target. function run_d() { check_element check_break before-$1 bash if [ -d ${TMP_HOOKS_PATH}/$1.d ] ; then run-parts ${TMP_HOOKS_PATH}/$1.d fi check_break after-$1 bash } function prepare_first_boot () { check_break before-first-boot run_in_target bash if [ -d ${TMP_HOOKS_PATH}/first-boot.d ] ; then sudo cp -t $TMP_MOUNT_PATH/etc/ -a $TMP_HOOKS_PATH/first-boot.d run_in_target mv /etc/rc.local /etc/rc.local.REAL sudo dd of=$TMP_MOUNT_PATH/etc/rc.local <> /var/log/first-boot.d.log 2>&1 rm -fr /etc/first-boot.d mv /etc/rc.local.REAL /etc/rc.local exit 0 EOF run_in_target chmod 755 /etc/rc.local fi check_break after-first-boot run_in_target bash } function finalise_base () { TARGET_ROOT=$TMP_MOUNT_PATH run_d cleanup # Now remove the resolv.conf we created above sudo rm -f $TMP_MOUNT_PATH/etc/resolv.conf # The we need to recreate it as a link sudo ln -sf ../run/resolvconf/resolv.conf $TMP_MOUNT_PATH/etc/resolv.conf } function compress_image () { # Recreate our image to throw away unnecessary data test $IMAGE_TYPE != qcow2 && COMPRESS_IMAGE="" qemu-img convert ${COMPRESS_IMAGE:+-c} -f raw $TMP_IMAGE_PATH -O $IMAGE_TYPE $TMP_IMAGE_PATH-new rm $TMP_IMAGE_PATH mv $TMP_IMAGE_PATH-new $TMP_IMAGE_PATH } function do_extra_package_install () { # Install any packages that were requested with the -p command line option if [ "$INSTALL_PACKAGES" != "" ]; then run_in_target install-packages ${INSTALL_PACKAGES[@]} fi } 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 }