diff options
Diffstat (limited to 'scripts/install-image')
-rwxr-xr-x | scripts/install-image | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/scripts/install-image b/scripts/install-image new file mode 100755 index 00000000..201500e3 --- /dev/null +++ b/scripts/install-image @@ -0,0 +1,168 @@ +#!/bin/bash + +# this script installs a new release image into a running "union-installed" +# system to the new release. the specified image is a release ISO image. +# the script sets up a new union mount for the new release. a reboot is +# then required to boot into the newly installed release. + +NEW_ISO=$1 + +PI_ROOT='' +SQUASH_MOUNT='' +ISO_MOUNT='' +TMP_DIR='' + +vyatta_sysconfdir=/opt/vyatta/etc + +failure_exit () { + echo "$*" + exit 1 +} + +clean_up () { + if [ -n "$PI_ROOT" ] && [ -d "$PI_ROOT" ]; then + umount $PI_ROOT >&/dev/null || true + fi + if [ -n "$SQUASH_MOUNT" ] && [ -d "$SQUASH_MOUNT" ]; then + umount $SQUASH_MOUNT >&/dev/null || true + fi + if [ -n "$ISO_MOUNT" ] && [ -d "$ISO_MOUNT" ]; then + umount $ISO_MOUNT >&/dev/null || true + fi + if [ -n "$TMP_DIR" ] && [ -d "$TMP_DIR" ]; then + rm -rf $TMP_DIR + fi + PI_ROOT='' + SQUASH_MOUNT='' + ISO_MOUNT='' + TMP_DIR='' +} + +sig_handler () { + echo "ERROR: Signal received. Exiting..." + clean_up + echo "Done" + trap - EXIT + exit 1 +} + +exit_handler () { + echo "Exiting..." + clean_up + echo "Done" +} + +trap sig_handler INT KILL +trap exit_handler EXIT + +if [ `whoami` != 'root' ] ; then + failure_exit 'This script must be run with root privileges.' +fi + +# make sure it's a union-installed system +CURVER=$(sed -n 's/^Version \+: \+\([^ ]\+\)$/\1/p' \ + ${vyatta_sysconfdir}/version 2>/dev/null) +if [ -z "$CURVER" ]; then + failure_exit 'Cannot find current version.' +fi +if [ ! -d "/live/image/boot/$CURVER" ] \ + || ! grep -q ' /live/image ' /proc/mounts \ + || grep -q ' /live/image iso9660 ' /proc/mounts \ + || ! grep -q " /$CURVER.squashfs " /proc/mounts; then + failure_exit 'This script can only be used on a "union-installed" system.' +fi + +# check the ISO +if [ ! -f "$NEW_ISO" ] || ! (file $NEW_ISO | grep -q 9660); then + failure_exit "\"$NEW_ISO\" is not a valid ISO image file." +fi +TMP_DIR=$(mktemp -d /tmp/install-image.XXXXXX) \ + || failure_exit 'Failed to create temporary directory.' +ISO_MOUNT=$TMP_DIR/iso-mount +if ! mkdir $ISO_MOUNT || ! mount -o loop,ro "$NEW_ISO" $ISO_MOUNT; then + failure_exit 'Failed to mount ISO image.' +fi + +# check the squashfs image +SQUASH_FILE=$ISO_MOUNT/live/filesystem.squashfs +if [ ! -f "$SQUASH_FILE" ] || ! (file $SQUASH_FILE | grep -q Squashfs) \ + || ! grep -q '^ii vyatta-version ' $ISO_MOUNT/live/packages.txt; then + failure_exit "\"$NEW_ISO\" is not a Vyatta ISO image file." +fi +SQUASH_MOUNT=$TMP_DIR/squash-mount +if ! mkdir $SQUASH_MOUNT \ + || ! mount -o loop,ro "$SQUASH_FILE" $SQUASH_MOUNT; then + failure_exit 'Failed to mount squashfs image.' +fi + +# get version string +NEWVER=$(grep '^Version ' ${SQUASH_MOUNT}${vyatta_sysconfdir}/version \ + | tr -s ' ' | cut -d ' ' -f 3) +if [ -z "$NEWVER" ]; then + failure_exit 'Cannot find new release version.' +fi +if [ "$CURVER" == "$NEWVER" ]; then + failure_exit "Cannot install the same release version \"$NEWVER\"." +fi + +# start the install +echo "Installing \"$NEWVER\" release." + +# create the new release directories +REL_ROOT="/live/image/boot/$NEWVER" +RW_DIR="$REL_ROOT/live-rw" +if ! mkdir -p "$RW_DIR"; then + failure_exit 'Cannot create directory for new release.' +fi + +# copy the squashfs image and boot files +echo -n "Copying new release files..." +cp -p $SQUASH_FILE $REL_ROOT/$NEWVER.squashfs >&/dev/null +cp -p $SQUASH_MOUNT/boot/* $REL_ROOT/ >&/dev/null +echo " Done" + +# mount copied squashfs +umount $SQUASH_MOUNT +SQUASH_FILE=$REL_ROOT/$NEWVER.squashfs +if ! mount -o loop,ro "$SQUASH_FILE" $SQUASH_MOUNT; then + failure_exit 'Failed to mount new squashfs image.' +fi + +# set up root for postinst +PI_ROOT=$TMP_DIR/pi_root +if ! mkdir $PI_ROOT \ + || ! mount -t unionfs -o noatime,dirs=$RW_DIR=rw:$SQUASH_MOUNT=ro unionfs \ + $PI_ROOT; then + failure_exit 'Failed to set up root directory for postinst.' +fi + +# set up /var/run fstab entry +PI_FSTAB=$PI_ROOT/etc/fstab +if ! grep -q 'tmpfs /var/run ' $PI_FSTAB >&/dev/null; then + # replace the fstab. the default one has header that will cause + # it to be wiped out on live boot. + echo 'tmpfs /var/run tmpfs nosuid,nodev 0 0' >$PI_FSTAB +fi + +# postinst hook +PI_SCRIPT=${PI_ROOT}${vyatta_sysconfdir}/install-image/postinst +if [ -e "$PI_SCRIPT" ]; then + echo "running post-install script" + $PI_SCRIPT $PI_ROOT +fi + +# set up grub entry (if provided) +DEF_GRUB=${PI_ROOT}${vyatta_sysconfdir}/grub/default-union-grub-entry +if [ -e "$DEF_GRUB" ]; then + old_grub_cfg=/live/image/boot/grub/grub.cfg + new_grub_cfg=$TMP_DIR/grub.cfg + sed -n '/^menuentry/q;p' $old_grub_cfg >$new_grub_cfg + cat $DEF_GRUB >>$new_grub_cfg + sed -n '/^menuentry/,${p}' $old_grub_cfg >>$new_grub_cfg + sed -i 's/^set default=[0-9]\+$/set default=0/' $new_grub_cfg + mv $new_grub_cfg $old_grub_cfg +fi + +# done +exit 0 + |