diff options
author | An-Cheng Huang <ancheng@vyatta.com> | 2009-10-30 18:42:30 -0700 |
---|---|---|
committer | An-Cheng Huang <ancheng@vyatta.com> | 2009-10-30 18:42:30 -0700 |
commit | 1f5174a65f21d1280827d7fb911232f4bfc56eb7 (patch) | |
tree | 389ce51f25870f0fb9b273951853ce79abd649d7 /scripts | |
parent | c758197af1f11727cb01188b14d0a4801448cfcd (diff) | |
download | vyatta-cfg-quagga-1f5174a65f21d1280827d7fb911232f4bfc56eb7.tar.gz vyatta-cfg-quagga-1f5174a65f21d1280827d7fb911232f4bfc56eb7.zip |
add unified install-image
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/install/install-functions | 329 | ||||
-rwxr-xr-x | scripts/install/install-get-partition | 808 | ||||
-rwxr-xr-x | scripts/install/install-image | 170 | ||||
-rwxr-xr-x | scripts/install/install-image-existing | 133 | ||||
-rwxr-xr-x | scripts/install/install-image-new | 76 | ||||
-rwxr-xr-x | scripts/install/install-postinst-new | 201 |
6 files changed, 1717 insertions, 0 deletions
diff --git a/scripts/install/install-functions b/scripts/install/install-functions new file mode 100755 index 00000000..3bdc1fde --- /dev/null +++ b/scripts/install/install-functions @@ -0,0 +1,329 @@ +# this provides environment and functions needed by install scripts. +# must be sourced by the scripts. + +if [ -e /etc/default/vyatta ] ; then + . /etc/default/vyatta +fi + +: ${vyatta_prefix:=/opt/vyatta} +: ${vyatta_exec_prefix:=$vyatta_prefix} +: ${vyatta_bindir:=${vyatta_exec_prefix}/bin} +: ${vyatta_sysconfdir:=${vyatta_prefix}/etc} + +# trap signals so we can kill runaway progress indicators +trap 'progress_indicator stop; exit 1' 1 +trap 'progress_indicator stop; exit 1' 2 + +# mount point for the install root. +# for union install, this is a r/w union mount. +# for non-union install, this is the root partition mount. +INST_ROOT=/mnt/inst_root + +# mount point for the writable root, i.e., the root partition. +# this is only used for union install. +WRITE_ROOT=/mnt/wroot + +# mount point for the readonly squashfs mount. +# this is only used for union install. +READ_ROOT=/mnt/squashfs + +# mount point for the ISO image. +# this is only used when installing with an ISO image file +# (instead of from a live CD boot). +CD_ROOT=/mnt/cdrom + +# mount point for the squashfs image in the ISO image. +# this is only used when installing with an ISO image file +# (instead of from a live CD boot). +CD_SQUASH_ROOT=/mnt/cdsquash + +# the vyatta config dir +VYATTA_CFG_DIR=${vyatta_sysconfdir}/config + +# the floppy config dir +FD_CFG_DIR=/media/floppy/config + +# Process ID for progress_indicator +SPID=$$ + +progress_indicator () { + case "$1" in + start) + $vyatta_bindir/progress-indicator $SPID & + ;; + *) + if ! rm /tmp/pi.$SPID 2>/dev/null; then + sleep 1 + rm /tmp/pi.$SPID 2>/dev/null + fi + sleep 1 + echo -n -e "\b" + ;; + esac +} + +# echo to log. uses INSTALL_LOG if set. +lecho () +{ + local log=$INSTALL_LOG + if [ -z "$log" ]; then + log=/tmp/install-$$.log + fi + echo -e "$*" >>$log +} + +# echo to both. +becho () +{ + lecho "$*" + echo -e "$*" +} + +# Validates a user response. Returns the response if valid. +# Returns the default is the user just hits enter. +# Returns nothing if not valid. Default parameter is $1. +# Options are in $2. If options are defined return must be a member +# of the enum. +get_response () { + ldefault=$(echo "$1" | tr [:upper:] [:lower:]) + loptions=$(echo "$2" | tr [:upper:] [:lower:]) + + # get the response from the user + read myresponse + myresponse=$(echo "$myresponse" | tr [:upper:] [:lower:]) + + # Check to see if the user accepts the default + if [ -z "$myresponse" ]; then + echo -n $ldefault + elif [ -n "$loptions" ]; then + # make sure response is a valid option + for token in $loptions + do + if [ "$token" == "$myresponse" ]; then + echo -n "$myresponse" + return 0 + fi + done + return 1 + else + echo -n "$myresponse" + fi + + return 0 +} + +# turn off any mounted swap partitions +turnoffswap () { + if [ -f "/proc/swaps" ]; then + myresponse=$(cat /proc/swaps) + if [ -n "$myresponse" ]; then + lecho "turning off swaps..." + swapoff -a + fi + fi +} + +# Return the size of the drive in MB +get_drive_size () { + ldrive=$1 + + # Make sure you can print disk info using parted + parted /dev/$ldrive p >/dev/null 2>&1 + + # If unable to read disk, it's likely it needs a disklabel + if [ "$?" != "0" ]; then + lecho "Creating a new disklabel on $ldrive" + lecho "parted /dev/$ldrive mklabel msdos" + output=$(parted /dev/$ldrive mklabel msdos) + + # Get the drive size from parted + lsize=$(parted /dev/$ldrive p | grep "^Disk" | awk '{ print $3 }') + + if [ $(echo $lsize | grep error) ]; then + echo "Unable to read disk label. Exiting." + exit 1 + fi + fi + + # Get the drive size from parted + lsize=$(parted /dev/$ldrive p | grep "^Disk" | awk '{ print $3 }') + # Get the reported units (mB, GB, kB) + lmodifier=$(echo $lsize | sed 's/[0-9\.]//g') + # remove the modifier + lsize=$(echo $lsize | sed 's/[a-z,A-Z]//g') + # Remove any fractions + lsize=$(echo $lsize | cut -f1 -d'.') + # Translate our size into mB if not there already + if [ $lmodifier = "GB" ]; then + lsize=$(($lsize * 1000)) + elif [ $lmodifier = "kB" ]; then + lsize=$(($lsize / 1000)) + fi + + echo $lsize +} + +# Probe hardrives not shown in /proc/partitions by default +probe_drives () { + # Find drives that may not be in /proc/partitions since not mounted + drive=$(ls /sys/block | grep '[hsv]d.') + + # now exclude all drives that are read-only + for drive in $drive; do + if [ $(cat /sys/block/$drive/ro) -ne 0 ]; then + output=$(mount | grep $drive) + if [ -z "$output" ]; then + output=$(parted /dev/$drive p) + fi + fi + done +} + +# Display text $1 before choice. +# Sets the variable named by $2. +# Note that select_drive should be wrapped +# in the verification loop, not the included get_response. +select_drive () { + local msg=$1 + local outvar=$2 + local drv='' + # list the drives in /proc/partitions. Remove partitions and empty lines. + # the first grep pattern looks for devices named c0d0, hda, and sda. + drives=$(cat /proc/partitions | \ + awk '{ if ($4!="name") { print $4 } }' | \ + egrep "c[0-9]d[0-9]$|[hsv]d[a-z]$" | \ + egrep -v "^$") + + # take the first drive as the default + drv=$(echo $drives | /usr/bin/awk '{ print $1 }') + + # Add the drive sizes to the display to help the user decide + display='' + for drive in $drives; do + size=$(get_drive_size $drive) + display="$display $drive\t$size"MB"\n" + done + + while true; do + # Display the drives and ask the user which one to install to + echo -e "$display" + echo + echo -n "$1 [$drv]:" + response=$(get_response "$drv" "$drives") && break + done + eval "$outvar=$response" + + echo +} + +# $1: user name +# $2: encrypted password +# $3: config file +set_encrypted_password () { + sed -i -e \ + "/ user $1 {/,/}/s/encrypted-password.*\$/encrypted-password \"$2\"/" $3 +} + +# interactively prompt user to change password for the specified account in +# the specified config file +# $1: account name +# $2: config file +change_password() { + local user=$1 + local config=$2 + local pwd1="1" + local pwd2="2" + + until [ "$pwd1" == "$pwd2" ]; do + read -p "Enter $user password:" -r -s pwd1 <>/dev/tty 2>&0 + echo + read -p "Retype $user password:" -r -s pwd2 <>/dev/tty 2>&0 + echo + + if [ "$pwd1" != "$pwd2" ]; then + echo "Passwords do not match" + fi + done + + # escape any slashes in resulting password + local epwd=$(mkpasswd -H md5 "$pwd1" | sed 's:/:\\/:g') + set_encrypted_password "$user" "$epwd" "$config" +} + +# returns true if it's a live cd boot +is_live_cd_boot () +{ + if grep -q ' /live/image [^ ]\+ ro' /proc/mounts; then + return 0 + else + return 1 + fi +} + +# returns true if it's a union-install boot +is_union_install () +{ + if is_live_cd_boot; then + return 1 + fi + if grep -q ' /live/image [^ ]\+ rw' /proc/mounts \ + && grep -q 'unionfs / unionfs ' /proc/mounts; then + return 0 + else + return 1 + fi +} + +# outputs the version string of the current running version. +get_cur_version () +{ + local ver_file=/opt/vyatta/etc/version + if [ -f "$ver_file" ]; then + grep '^Version' $ver_file | awk '{ print $3 }' + return + fi +} + +# outputs the version string of the new version, i.e., the version that is +# being installed. this can be from live CD boot or from a ISO image file. +get_new_version () +{ + ver_path=/opt/vyatta/etc/version + ver_file=${CD_SQUASH_ROOT}${ver_path} + if [ -f "$ver_file" ]; then + # CD_SQUASH_ROOT is set up => we are installing with a specified ISO + # image file. use the version string from there. + grep '^Version' $ver_file | awk '{ print $3 }' + return + fi + + ver_file=${ver_path} + if is_live_cd_boot && [ -f "$ver_file" ]; then + # we are installing from a live CD boot + grep '^Version' $ver_file | awk '{ print $3 }' + return + fi + + # couldn't find it +} + +# try to mount. log any errors and return the appropriate status. +# $1: arguments for mount +try_mount () +{ + args="$*" + output=$(eval "mount $args 2>&1") + status=$? + if [ $status == 0 ]; then + return 0 + fi + # error + cat <<EOF +Error trying to mount a partition/directory. +Please see $INSTALL_LOG for details. +EOF + lecho 'Error trying to mount a partition/directory.' + lecho "mount $args\n$output" + return 1 +} + diff --git a/scripts/install/install-get-partition b/scripts/install/install-get-partition new file mode 100755 index 00000000..30316724 --- /dev/null +++ b/scripts/install/install-get-partition @@ -0,0 +1,808 @@ +#!/bin/bash + +if [ `whoami` != 'root' ] ; then + echo "This script must be run with root privileges." + exit 1 +fi + +# this script will write the partition type, selected partition, and selected +# drive into the specified file +OUTFILE=$1 + +if [ ! -f "$OUTFILE" ]; then + echo "Output file does not exist. Exiting..." + exit 1 +fi + +# source in the functions +source /opt/vyatta/sbin/install-functions + +# the INSTALL_LOG env var should be exported by the "caller". +# it will be used to log messages. + +# Absolute minimum root partition size in MB. Below this, we won't let +# you install. +ROOT_MIN=1000 +# the base install drive e.g. sda +INSTALL_DRIVE='' +# the install partition e.g. sda1 +ROOT_PARTITION='' +# the type of the install partition: "union", "old", or "new" +ROOT_PARTITION_TYPE='' +# global holding variable used in the select_partition sub +PARTITION='' +# default file system type +ROOT_FSTYPE='ext3' + +warn_of_dire_consequences () { + # Give the user a requisite warning that we are about to nuke their drive + response='' + while [ -z $response ]; do + echo "This will destroy all data on /dev/$INSTALL_DRIVE." + echo -n "Continue? (Yes/No) [No]: " + response=$(get_response "No" "Yes No Y N") + + if [ "$response" == "no" ] || [ "$response" == "n" ]; then + echo "Ok then. Exiting..." + exit 1 + fi + done +} + +check_for_old_raid () { + # First, trigger construction of previously configured RAID groups + echo -n "Looking for pre-existing RAID groups..." + raid_config=`mdadm --examine --scan` + if [ -z "$raid_config" ]; then + echo "none found." + return + fi + + echo "found some." + echo "Trying to configure pre-existing RAID groups..." + mdadm --assemble --scan --auto=yes --symlink=no + + # Identify physical drives + raid_drives=$(cat /proc/partitions | awk '{ if ($4!="name") { print $4 } }' \ + | grep "md" | egrep -v "^$") + if [ -z "$raid_drives" ]; then + echo "Unable to configure any RAID groups." + return + fi + + numraids=`echo $raid_drives | wc -w` + if [ $numraids -eq 1 ]; then + echo "The following RAID group is now configured:" + else + echo "The following RAID groups are now configured:" + fi + + for drive in $raid_drives; do + cat /proc/mdstat | grep --after-context 2 ^$drive | sed -e 's/^/\t/' + done + + if [ $numraids -eq 1 ]; then + echo -n "Would you like to use this one? (Yes/No) [Yes]:" + else + echo -n "Would you like to use one of these? (Yes/No) [Yes]:" + fi + + response=$(get_response "Yes" "Yes No Y N") + if [ "$response" == "no" ] || [ "$response" == "n" ]; then + echo + echo "Ok. Not using existing RAID groups." + echo + + # pick the first RAID group to be broken + raid_drive=$(echo $raid_drives | /usr/bin/awk '{ print $1 }') + + echo "Would you like to break RAID group $raid_drive so that its" + echo "members can be re-used for a new installation, understanding" + echo -n "that doing so will destroy all data on it? (Yes/No) [No]:" + destroy_raid=$(get_response "No" "Yes No Y N") + echo + + if [ "${destroy_raid:0:1}" = "y" ]; then + echo "OK. Breaking the RAID group $raid_drive." + + members=`ls /sys/block/$raid_drive/slaves` + + echo "First, stopping all existing RAID groups:" + mdadm --stop --scan + + for member in $members ; do + drive=${member:0:3} + part=${member:3:1} + echo "Re-setting partition ID for RAID group $raid_drive member /dev/${member}:" + sfdisk --change-id /dev/$drive $part 0x83 + echo "Clearing RAID superblock from RAID group $raid_drive member /dev/${member}." + mdadm --zero-superblock /dev/$member + done + else + echo "OK. Stopping, but not breaking, existing RAID groups:" + mdadm --stop --scan + fi + + echo + return + fi + + if [ $numraids -eq 1 ]; then + INSTALL_DRIVE=$raid_drives + else + # take the first drive as the default + INSTALL_DRIVE=$(echo $raid_drives | /usr/bin/awk '{ print $1 }') + echo -n "Which one would you like to use? ($raid_drives) [$INSTALL_DRIVE]: " + INSTALL_DRIVE=$(get_response "$INSTALL_DRIVE" "$drives") + fi + + echo "Using RAID partition $INSTALL_DRIVE" + + raid_degraded=`cat /sys/block/$INSTALL_DRIVE/md/degraded` + raid_sync_action=`cat /sys/block/$INSTALL_DRIVE/md/sync_action` + + if [ "$raid_degraded" = "1" ]; then + echo + if [ "$raid_sync_action" = "recover" ]; then + echo "Error: This RAID set is degraded and is in the process of" + echo "rebuilding. It is not safe to install onto it while the" + echo "rebuild is in progress. Please wait for the rebuild to" + echo "complete and then re-start the installation. You may" + echo "monitor the progress of the RAID rebuild with the" + echo "command:" + echo + echo " show raid $INSTALL_DRIVE" + echo + exit 1 + fi + echo "Warning: This RAID set is degraded, but is not in the" + echo "process of rebuilding. It is safe to perform the installation" + echo "onto a degraded RAID set that is not in the process of" + echo "rebuilding. You may stop the installation now and rebuild the" + echo "RAID set, or continue installing onto it. If you continue" + echo "installing, do not attempt to rebuild the RAID set until the" + echo "installation has completed and you have rebooted the system." + echo + fi + + warn_of_dire_consequences + + ROOT_PARTITION=$INSTALL_DRIVE + + # make sure we aren't working on a mounted part + unmount "$INSTALL_DRIVE" + + # check for an old config on the partition + check_config_partition "$ROOT_PARTITION" + + # create the filesystem on the part + make_filesystem "$ROOT_PARTITION" +} + +check_for_new_raid () { + # Identify physical drives + drives=$(cat /proc/partitions | awk '{ if ($4!="name") { print $4 } }' \ + | egrep -v "[0-9]$" | egrep -v "^$") + + numdrives=`echo $drives | wc -w` + + # Need at least two drives for RAID-1. We don't yet have the code + # to handle selection of two from a set of 3 or more, so for now, we + # only support two drives. + # + if [ $numdrives -ne 2 ]; then + return + fi + + drive1=`echo $drives | awk '{ print $1 }'` + drive2=`echo $drives | awk '{ print $2 }'` + + drivesize1=$(get_drive_size $drive1) + drivesize2=$(get_drive_size $drive2) + + # Both drives must have enough space to hold our minimum root filesystem + # + if [ $drivesize1 -lt $ROOT_MIN -o $drivesize2 -lt $ROOT_MIN ]; then + return + fi + + echo "You have two disk drives:" + echo -e "\t$drive1 \t$drivesize1 MB" + echo -e "\t$drive2 \t$drivesize2 MB" + + echo -n "Would you like to configure RAID-1 mirroring on them? (Yes/No) [Yes]:" + response=$(get_response "Yes" "Yes No Y N") + if [ "$response" == "no" ] || [ "$response" == "n" ]; then + echo "Ok. Not configuring RAID-1." + return + fi + + if [ $drivesize1 -ne $drivesize2 ]; then + echo "Since the disks are not the same size, we will use the smaller" + echo "of the two sizes in configuring the RAID-1 set. This will" + echo "waste some space on the larger drive." + echo "" + fi + + # Configure RAID-1 + echo "This process will erase all data on both drives." + echo -n "Are you sure you want to do this? (Yes/No) [No]: " + response=$(get_response "Yes" "Yes No Y N") + if [ "$response" == "no" ] || [ "$response" == "n" ]; then + echo "Ok. Not configuring RAID-1." + return + fi + + for drive in $drives; do + echo "Deleting old partitions on drive $drive" + # remove any existing partitions on that drive + delete_partitions "$drive" + done + + # Need to leave space on both disks between the MBR and the start + # of the first partition for grub. Grub needs to embed a large + # boot image there when booting off RAID devices. + # + # Partition creation variables are in units of megabytes. + part_start_offset=2 + part_diag_size=60 + + if [ $drivesize1 -lt $drivesize2 ]; then + root_size=$drivesize1 + else + root_size=$drivesize2 + fi + + let min_size_with_diag=${MIN_ROOT}+${part_diag_size} + if [ $root_size -ge $min_size_with_diag ]; then + echo "Would you like me to create a $part_diag_size MB partition for diagnostics?" + echo -n "(Yes/No) [No]: " + diag_response=$(get_response "No" "Yes No Y N") + if [ "$diag_response" == "yes" ] || [ "$diag_response" == "y" ]; then + for drive in $drives; do + echo "Creating diag partition on drive $drive" + create_partitions "$drive" $part_diag_size $part_start_offset "no" + sfdisk --change-id /dev/$drive 1 0x6 + done + data_dev=2 + let part_start_offset+=$part_diag_size + else + data_dev=1 + fi + fi + + let root_size-=$part_start_offset + + for drive in $drives; do + echo "Creating data partition: /dev/${drive}${data_dev}" + create_partitions "$drive" $root_size $part_start_offset "no" + sfdisk --change-id /dev/$drive $data_dev 0xfd + # mark data partition as bootable + lecho "Marking /dev/$drive partition $data_dev bootable" + output=$(parted /dev/$drive set $data_dev boot on 2>&1) + lecho "$output" + done + + # Must give partition device time to settle + sleep 5 + echo + + for drive in $drives; do + echo "Erasing any previous RAID metadata that may exist on /dev/${drive}${data_dev}" + mdadm --zero-superblock /dev/${drive}${data_dev} + done + + echo "Creating RAID-1 group on partitions: /dev/${drive1}${data_dev} /dev/${drive2}${data_dev}" + + raid_dev=md0 + mdadm --create /dev/$raid_dev --level=1 --raid-disks=2 \ + /dev/${drive1}${data_dev} /dev/${drive2}${data_dev} + + if [ $? = 0 -a -e /dev/$raid_dev ]; then + echo "RAID-1 group created successfully:" + cat /proc/mdstat | grep --after-context 2 ^$raid_dev | sed -e 's/^/\t/' + else + echo "Unable to create RAID-1 group!" + return + fi + + INSTALL_DRIVE=$raid_dev + ROOT_PARTITION=$INSTALL_DRIVE + ROOT_PARTITION_TYPE=new + + # Give device time to settle... + sleep 5 + + # create the filesystem on the part + make_filesystem "$ROOT_PARTITION" +} + +# Allow the user to select a partition to work with +# sets the global PARTITION +# $1 is the text to display before prompt +select_partition () { + minsize=$1 + text=$2 + exclude=$3 + + echo -n "Looking for appropriate partitions: " + progress_indicator start + + # initialize out global var. using globals in this way is bad form. I know. + PARTITION='' + + # list only the partitions in /proc/partitions. + parts=$(cat /proc/partitions | awk '{ if ($4!="name") { print $4 " "} }' \ + | egrep "[0-9]" | egrep -v "loop" | tr -d '\n') + + # remove any partitions we have already previously used + if [ -n "$exclude" ]; then + for part in $parts; do + temp=$(echo $part | egrep -v $exclude) + parts_temp="$parts_temp $temp" + done + parts=$parts_temp + fi + + # Get the partition sizes for display + # only show linux partitions that have sizes, i.e. remove loops + display='' + myparts='' + for part in $parts; do + if [ ${part:0:2} = "md" ]; then + parttype="RAID" + else + rootdev=$(echo $part | sed 's/[0-9]//g') + parttype=$(fdisk -l /dev/$rootdev | grep $part | grep Linux) + fi + if [ -n "$parttype" ]; then + lsize=$(get_drive_size $part) + if [ "$lsize" -a $lsize -ge $minsize ]; then + display="$display $part\t\t$lsize"MB"\n" + myparts="$myparts $part" + fi + fi + done + + progress_indicator stop + echo "OK" + + if [ -n "$myparts" ]; then + lpartition='' + while [ -z "$lpartition" ]; do + # take the first partition as the default + lpartition=$(echo $myparts | /usr/bin/awk '{ print $1 }') + + echo "I found the following partitions suitable for the Vyatta image:" + echo -e "Partition\tSize" + echo -e "$display" + echo + echo -n "$text [$lpartition]: " + + lpartition=$(get_response "$lpartition" "$myparts") + echo + done + else + becho "No suitable partition sizes found. Exiting..." + exit 1 + fi + PARTITION=$lpartition +} + +rename_old_config() { + files=$(find /mnt/config -mindepth 1 -type f | grep -v pre-glendale) + for f in $files; do + if grep -q '/\*XORP Configuration File, v1.0\*/' $f >&/dev/null; then + CURTIME=$(date +%F-%H%M%S) + mv $f $f.pre-glendale.$CURTIME + fi + done +} + +## check_config_partition +# look to see if this partition contains a config file +# and back it up +check_config_partition() { + lpart=$1 + + # Cleanup from possible partial last run + rm -fr /mnt/config + + # Look to see if this is a config partition + mkdir -p /mnt/tmp + output=$(mount /dev/$lpart /mnt/tmp 2>&1) + if [ $? != 0 ]; then + lecho "Cannot mount /dev/$lpart"."\nmount /dev/$ldrive$part /mnt/tmp\nExiting..." + lecho "$output" + else + # Look to see if there is a config partition there + if [ -f /mnt/tmp/opt/vyatta/etc/config/.vyatta_config ] \ + || [ -f /mnt/tmp/.vyatta_config ]; then + response='' + while [ -z "$response" ]; do + echo "/dev/$lpart has an old configuration directory!" + echo -ne "Would you like me to save the data on it\nbefore I delete it? (Yes/No) [Yes]: " + response=$(get_response "Yes" "Yes No Y N") + if [ "$response" == "yes" ] || [ "$response" == "y" ]; then + mkdir -p /mnt/config + if [ -d /mnt/tmp/opt/vyatta/etc/config ]; then + output=$(cp -pR /mnt/tmp/opt/vyatta/etc/config/* /mnt/config) + else + output=$(cp -pR /mnt/tmp/* /mnt/config) + fi + if [ -n "$output" ]; then + echo -e "Warning: error in copying the old config partition.\nSee $INSTALL_LOG for more details." + lecho "Warning: error in copying the old config partition.\ncp -pR /mnt/tmp/* /mnt/config\n$output\n" + fi + rename_old_config + fi + done + fi + umount /mnt/tmp + fi +} + +# Delete all existing partitions for an automated install +# $1 is the drive to delete partitions from +delete_partitions () { + ldrive=$1 + + # get the partitions on the drive + # in the first grep below we add the optional [p] in order to + # accomdate cciss drives + partitions=$(cat /proc/partitions | grep $ldrive[p]*[0-9] \ + | awk '{ print $4 }' | sed 's/\(.*\)\([0-9]$\)/\2/g' \ + | grep -v "^$") + + # now for each part, blow it away + for part in $partitions; do + # Look to see if this is a config partition + check_config_partition "$ldrive$part" + + lecho "Removing partition $part on /dev/$ldrive" + output=$(parted /dev/$ldrive rm $part) + status=$? + if [ "$status" != 0 ]; then + echo -e "Warning: cannot delete partition $part on $ldrive.\nPlease see $INSTALL_LOG for more details." + lecho "Warning: cannot delete partition $part on $ldrive.\nparted /dev/$ldrive rm $part\n$output" + fi + + # We add a bogus sleep here because the loop needs to wait for udev + sleep 5 + done +} + +# make a filesystem on the drive +# $1 is the drive to format +make_filesystem () { + ldrive=$1 + + echo -n "Creating filesystem on /dev/$ldrive: " + lecho "Creating filesystem on /dev/$ldrive..." + + progress_indicator start + output=$(mkfs -t $ROOT_FSTYPE /dev/$ldrive 2>&1) + status=$? + if [ "$status" != 0 ]; then + echo -e "Error: couldn't create the root filesystem.\nSee $INSTALL_LOG for further details.\nExiting..." + lecho "Error: couldn't create the root filesystem.\n/sbin/mke2fs -j /dev/$ldrive\n$output" + exit 1 + fi + progress_indicator stop + echo "OK" +} + +# create the root partition +# $1 is the install drive e.g. sda +# $2 is the partition size e.g. 512 +# This will set the global ROOT_PARTITION +create_partitions() { + ldrive=$1 + root_part_size=$2 + start_offset=$3 + initialize_fs=$4 + + # Make sure there is enough space on drive + size=$(get_drive_size "$ldrive") + if [ "$root_part_size" -gt "$size" ]; then + echo "Error: $ldrive is only $size"MB" large. Desired root is $root_part_size" + exit 1 + fi + + lecho "Creating root partition on /dev/$ldrive" + + # make the root partition + output=$(parted /dev/$ldrive mkpart primary $start_offset $root_part_size) + status=$? + if [ "$status" != 0 ]; then + echo -e "Error creating primary partition on $ldrive.\nPlease see $INSTALL_LOG for more details.\nExiting..." + lecho "Error creating primary partition on $ldrive.\nparted /dev/$ldrive mkpart primary 0 $root_part_size\n$output" + exit 1 + fi + + # set the partition number on the device. + if [ -n "$( echo $ldrive | grep -E "cciss|ida" )" ]; then + # if this is a cciss + ROOT_PARTITION=$ldrive"p1" + else + # else... the rest of the world + ROOT_PARTITION=$ldrive"1" + fi + # udev takes time to re-add the device file, so wait for it + while [ ! -b "/dev/$ROOT_PARTITION" ]; do + sleep 1 + done + + if [ "$initialize_fs" = "yes" ]; then + # make the root and config file systems. + make_filesystem "$ROOT_PARTITION" + fi +} + +# sets ROOT_FSTYPE based on disk size +set_root_fstype () { + local drv=$1 + local sz=$(get_drive_size "$drv") + # If disk is small, it is probably a CF device or virtual environment + # so avoid the overhead of a journal + if (( $sz < 11000 )); then + ROOT_FSTYPE=ext2 + else + ROOT_FSTYPE=ext3 + fi +} + +# ask for user input on the parted and skip setup methods +# $1 is whether or not to run parted +# sets globals INSTALL_DRIVE, ROOT_PARTITION, CONFIG_PARTITION +setup_method_manual() { + parted=$1 + + echo "The Vyatta install needs a minimum ${ROOT_MIN}MB root" + echo "with partiton type 83 (Linux)." + echo -e "\n\n" + + # if this is parted, let the user create the partitions + if [ "$parted" == 'parted' ]; then + while [ -z "$INSTALL_DRIVE" ]; do + # TODO: right now we only run parted on a single drive + echo -e "\nI found the following drives on your system:" + select_drive 'Which drive would you like to run parted on?' \ + 'INSTALL_DRIVE' + done + + set_root_fstype "$INSTALL_DRIVE" + + # Unmount the install drive if it is mounted + unmount "$INSTALL_DRIVE" + + # Run parted and let the user configure + parted /dev/$INSTALL_DRIVE + fi + + # Ask for the root partition and make sure it's valid + while [ -z "$ROOT_PARTITION" ]; do + select_partition 500 "Which partition should I install the root on?" + # Note that PARTITION is defined in select partition + ROOT_PARTITION=$PARTITION + unmount "$ROOT_PARTITION" + vd=$(grep $ROOT_PARTITION /proc/partitions | awk '{ print $4 }') + + if [ -z "$vd" ]; then + echo + echo "$ROOT_PARTITION is an invalid partition. Please try again." + ROOT_PARTITION="" + fi + done + + # check for an old config on the partition + check_config_partition "$ROOT_PARTITION" + + # create the filesystem on the part + make_filesystem "$ROOT_PARTITION" + + # We need to set the INSTALL_DRIVE if it wasn't set when the user ran parted + # We assume that we will use the boot sector of the same drive that the + # partition is on. + # TODO: Allow different drives to function as the boot device + if [ -z "$INSTALL_DRIVE" ]; then + if [ ${ROOT_PARTITION:0:2} = "md" ]; then + INSTALL_DRIVE=$ROOT_PARTITION + else + INSTALL_DRIVE=$(echo $ROOT_PARTITION | sed 's/[0-9]//g') + fi + fi +} + +# Walk the user through the auto setup method +# sets globals INSTALL_DRIVE, ROOT_PARTITION +setup_method_auto () { + while [ -z "$INSTALL_DRIVE" ]; do + echo "I found the following drives on your system:" + select_drive 'Install the image on?' 'INSTALL_DRIVE' + + # check to make sure the drive is large enough to hold the image + if [ -n "$INSTALL_DRIVE" ]; then + set_root_fstype "$INSTALL_DRIVE" + lsize=$(get_drive_size "$INSTALL_DRIVE") + total=$ROOT_MIN + if [ "$total" -gt "$lsize" ]; then + echo "Unfortunately, Vyatta requires a total of at least $total"MB" to properly install." + echo "$INSTALL_DRIVE is below the minimum required capacity and therefore, cannot be used to" + echo -e "complete the installation.\n" + echo "If other drives are present" + echo -e "Please select another drive...\n" + + INSTALL_DRIVE='' + fi + fi + done + + warn_of_dire_consequences + + echo + + # make sure we aren't working on a mounted part + unmount "$INSTALL_DRIVE" + + # remove any existing partitions on that drive + delete_partitions "$INSTALL_DRIVE" + + # Enforce minimum partition size requirement. + local root_part_size=0 + while [ $ROOT_MIN -gt $root_part_size ]; do + # Get the size of the drive + size=$(get_drive_size $INSTALL_DRIVE) + echo -n "How big of a root partition should I create? ($ROOT_MIN"MB" - $size"MB") [$size]MB: " + response=$(get_response "$size") + # TODO: need to have better error checking on this value + root_part_size=$(echo "$response" | sed 's/[^0-9]//g') + if [ $root_part_size -lt $ROOT_MIN ] \ + || [ $root_part_size -gt $size ]; then + echo "Root partion must be between $ROOT_MIN"MB" and $size"MB"" + echo + root_part_size=0 + fi + done + + echo + + # now take the data and create the partitions + create_partitions "$INSTALL_DRIVE" "$root_part_size" 0 "yes" + # mark data partition as bootable + lecho "Marking /dev/$INSTALL_DRIVE partition 1 as bootable" + output=$(parted /dev/$INSTALL_DRIVE set 1 boot on 2>&1) + lecho "$output" + # Must give partition device time to settle + sleep 5 +} + +unmount () { + # grab the list of mounted drives + # make sure to reverse sort so as to unmount up the tree + mounted=$(mount | grep "$1" | cut -f3 -d' ' | sort -r) + if [ -n "$mounted" ]; then + echo "I need to unmount: " + echo "$mounted" + + response='' + while [ -z $response ]; do + echo -n "Continue (Yes/No) [No]: " + response=$(get_response "No" "Yes No Y N") + if [ "$response" == "no" ] || [ "$response" == "n" ]; then + echo -e "Ok then. Need to unmount to continue.\nExiting..." + exit 1 + fi + done + + for parts in "$mounted"; do + lecho "umount $parts" + output=$(umount $parts) + status=$? + if [ "$status" != 0 ]; then + echo -e "Exiting: error unmounting $parts.\nPlease see $INSTALL_LOG for more details." + lecho "Exiting: error unmounting $parts.\numount $parts\n$output" + exit 1 + fi + done + fi +} + +##### Main +## +# turn off any mounted swap files +turnoffswap + +while true; do + # check if we are in a live CD boot + if ! is_live_cd_boot; then + # running installed system. check boot drive/partition. + if is_union_install; then + # this is a union install + ROOT_PARTITION_TYPE=union + else + # this is an old, non-union install + ROOT_PARTITION_TYPE=old + fi + while [ -z "$response" ]; do + cat <<EOF +You are running an installed system. Do you want to use the current install +EOF + echo -n "partition? (Yes/No) [Yes]: " + response=$(get_response "Yes" "Yes No Y N") + echo + done + if [ "$response" == "no" ] || [ "$response" == "n" ]; then + # for simplicity, require the current install partition if running an + # installed system. + ROOT_PARTITION_TYPE='' + break + else + # flag them as found but we don't actually need them + ROOT_PARTITION=dummy + INSTALL_DRIVE=dummy + fi + fi + if [ -n "$ROOT_PARTITION" ]; then + # got partition. done. + break + fi + + # some drives don't show up in /proc/partitions so we need to bootstrap them + echo -n "Probing drives: " + progress_indicator start + probe_drives + progress_indicator stop + echo "OK" + + # try old raid + check_for_old_raid + if [ -n "$ROOT_PARTITION" ]; then + # got partition. done. + break + fi + + # try new raid + check_for_new_raid + if [ -n "$ROOT_PARTITION" ]; then + # got partition. done. + break + fi + + cat <<EOF +The Vyatta image will require a minimum ${ROOT_MIN}MB root. +Would you like me to try to partition a drive automatically +or would you rather partition it manually with parted? If +you have already setup your partitions, you may skip this step + +EOF + PART_METHOD='' + while [ -z "$PART_METHOD" ]; do + echo -n "Partition (Auto/Parted/Skip) [Auto]: " + PART_METHOD=$(get_response "Auto" "Auto Parted Skip A P S") + done + echo + + # TODO: Note installs assume an LBA BIOS. So no boot partition currently. + # also note that we are not creating a swap partition right now. + ROOT_PARTITION_TYPE=new + if [ "$PART_METHOD" == "parted" ] || [ "$PART_METHOD" == "p" ]; then + setup_method_manual "parted" + elif [ "$PART_METHOD" == "skip" ] || [ "$PART_METHOD" == "s" ]; then + setup_method_manual "skip" + elif [ "$PART_METHOD" == "auto" ] || [ "$PART_METHOD" == "a" ]; then + setup_method_auto + fi + + break +done + +if [ -z "$ROOT_PARTITION" ]; then + echo 'Partition not selected. Exiting...' + exit 1 +fi + +echo "$ROOT_PARTITION_TYPE $ROOT_PARTITION $INSTALL_DRIVE" >$OUTFILE +becho 'Done!' +exit 0 + diff --git a/scripts/install/install-image b/scripts/install/install-image new file mode 100755 index 00000000..0bf31a00 --- /dev/null +++ b/scripts/install/install-image @@ -0,0 +1,170 @@ +#!/bin/bash + +# source in the functions +source /opt/vyatta/sbin/install-functions + +# export INSTALL_LOG for the scripts invoked +export INSTALL_LOG=/tmp/install-$$.log + +# file for get-partition output +PART_FILE='' + +fail_exit () +{ + echo "$*" + echo 'Exiting...' + exit 1 +} + +clean_up () +{ + if [ -n "$PART_FILE" ]; then + rm -f $PART_FILE >&/dev/null + fi + umount $CD_SQUASH_ROOT >&/dev/null || true + umount $CD_ROOT >&/dev/null || true + umount $INST_ROOT >&/dev/null || true + umount $READ_ROOT >&/dev/null || true + umount $WRITE_ROOT >&/dev/null || true +} + +sig_handler () { + echo "ERROR: Signal received. Exiting..." + clean_up + echo "Done" + trap - EXIT + exit 1 +} + +exit_handler () { + clean_up +} + +# set up the specified ISO image for install +set_up_new_iso () +{ + if [ ! -f "$NEW_ISO" ] || ! (file $NEW_ISO | grep -q 9660); then + fail_exit "\"$NEW_ISO\" is not a valid ISO image file." + fi + + # make sure mount points exist + mkdir -p $INST_ROOT $WRITE_ROOT $READ_ROOT $CD_ROOT $CD_SQUASH_ROOT + + # mount ISO + margs="-o loop,ro $NEW_ISO $CD_ROOT" + if ! try_mount "$margs"; then + fail_exit 'Failed to mount the new image.' + fi + + # check squash image + local squash_file=$CD_ROOT/live/filesystem.squashfs + if [ ! -f "$squash_file" ] || ! (file $squash_file | grep -q Squashfs) \ + || ! grep -q '^ii vyatta-version ' $CD_ROOT/live/packages.txt; then + fail_exit "\"$NEW_ISO\" is not a Vyatta ISO image file." + fi + + # mount squash image + margs="-o loop,ro $squash_file $CD_SQUASH_ROOT" + if ! try_mount "$margs"; then + fail_exit 'Failed to mount the squashfs image.' + fi +} + +# install new image into a newly-formatted partition. +# will exit with error if installation fails. +install_new () +{ + local root_part=$1 + local inst_drv=$2 + + if [ ! -e "/dev/$root_part" ] || [ ! -e "/dev/$inst_drv" ]; then + fail_exit "Invalid drive/partition ($inst_drv and $root_part)." + fi + + # install new image + if ! /opt/vyatta/sbin/install-image-new "$root_part"; then + exit 1 + fi + + # postinst operations + if ! /opt/vyatta/sbin/install-postinst-new \ + "$inst_drv" "$root_part" union; then + exit 1 + fi +} + +# install new image into the current boot partition. +# will exit with error if installation fails. +install_existing () +{ + local ctype=$1 + if ! /opt/vyatta/sbin/install-image-existing "$ctype"; then + exit 1 + fi +} + +# the image to be installed. only used if installing from an installed, +# running system. +NEW_ISO=$1 + +if [ `whoami` != 'root' ] ; then + fail_exit 'This script must be run with root privileges.' +fi + +trap sig_handler INT KILL +trap exit_handler EXIT + +if is_live_cd_boot; then + if [ -n "$NEW_ISO" ]; then + fail_exit 'Do not specify an image when installing from a live CD.' + fi +elif [ -z "$NEW_ISO" ]; then + fail_exit 'Must specify an image to install.' +else + # installing on an installed system. set up the new image. + set_up_new_iso +fi + +# check versions +if is_live_cd_boot; then + CURVER=LIVECD +else + CURVER=$(get_cur_version) +fi +NEWVER=$(get_new_version) +if [ -z "$CURVER" ] || [ -z "$NEWVER" ]; then + fail_exit 'Cannot find release version.' +fi +if [ "$CURVER" == "$NEWVER" ]; then + fail_exit "Version \"$NEWVER\" is already installed." +fi + +# get install partition +PART_FILE=$(mktemp /tmp/inst-get-part.XXXXXX) \ + || fail_exit 'Failed to create temporary file' +if ! /opt/vyatta/sbin/install-get-partition $PART_FILE; then + exit 1 +fi + +# get the partition params +root_part_type='' +root_part='' +inst_drv='' +eval "read root_part_type root_part inst_drv <$PART_FILE" >&/dev/null +rm -f $PART_FILE >&/dev/null + +# handle different types +case "$root_part_type" in + new) + install_new "$root_part" "$inst_drv" + exit 0 + ;; + union|old) + install_existing "$root_part_type" + exit 0 + ;; + *) + fail_exit "Unknown partition type \"$root_part_type\"." + ;; +esac + diff --git a/scripts/install/install-image-existing b/scripts/install/install-image-existing new file mode 100755 index 00000000..0b5cba62 --- /dev/null +++ b/scripts/install/install-image-existing @@ -0,0 +1,133 @@ +#!/bin/bash + +# this script installs a new release image into a running system. +# the new ISO image must be already mounted by caller. +# the script sets up a new union mount for the new release. a reboot +# is then required to boot into the newly installed release. + +# the current install type: "union" or "old" +CUR_INSTALL=$1 + +source /opt/vyatta/sbin/install-functions + +failure_exit () { + echo "$*" + exit 1 +} + +if [ `whoami` != 'root' ] ; then + failure_exit 'This script must be run with root privileges.' +fi + +CURVER=$(sed -n 's/^Version \+: \+\([^ ]\+\)$/\1/p' \ + ${vyatta_sysconfdir}/version 2>/dev/null) +if [ -z "$CURVER" ]; then + failure_exit 'Cannot find current version.' +fi + +# get new version string. this is from the squashfs image. +NEWVER=$(grep '^Version ' ${CD_SQUASH_ROOT}${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." + +# this is the default if current install is union +BOOT_DIR=/live/image/boot +if [ "$CUR_INSTALL" == 'old' ]; then + BOOT_DIR=/boot +elif [ "$CUR_INSTALL" != 'union' ]; then + echo 'Invalid current install type. Exiting...' + exit 1 +fi + +# create the new release directories +REL_ROOT=$BOOT_DIR/$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 "Copying new release files..." +squash_img=${CD_ROOT}/live/filesystem.squashfs +boot_dir=${CD_SQUASH_ROOT}/boot +boot_files=$(find $boot_dir -maxdepth 1 -type f -o -type l 2>/dev/null) +if [ ! -f "$squash_img" ] || [ -z "$boot_files" ]; then + becho 'Cannot find the files. Exiting...' + exit 1 +fi +target_squash=$REL_ROOT/$NEWVER.squashfs +cp -p $squash_img $target_squash >&/dev/null +cp -dp $boot_files $REL_ROOT/ >&/dev/null + +# mount copied squashfs +if ! try_mount "-o loop,ro $target_squash $READ_ROOT"; then + failure_exit 'Failed to mount new squashfs image.' +fi + +# set up root for postinst +margs="-t unionfs -o noatime,dirs=$RW_DIR=rw:$READ_ROOT=ro unionfs" +margs="$margs $INST_ROOT" +if ! try_mount "$margs"; then + failure_exit 'Failed to set up root directory for postinst.' +fi + +# set up /var/run fstab entry +PI_FSTAB=$INST_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 + +# save current config if needed +def_cfg="$VYATTA_CFG_DIR/config.boot" +if [ -f "$def_cfg" ]; then + resp='' + while [ -z "$resp" ]; do + echo 'Would you like to use the current configuration' + echo -n 'for the new version? (Yes/No) [Yes]: ' + resp=$(get_response "Yes" "Yes No Y N") + if [ "$resp" == 'yes' ] || [ "$resp" == 'y' ]; then + echo 'Copying current configuration...' + ndir=${INST_ROOT}${VYATTA_CFG_DIR} + mkdir -p $ndir + cp -p $def_cfg $ndir/ + chgrp -R vyattacfg $ndir + chmod -R 775 $ndir + fi + done +fi + +# postinst hook +PI_SCRIPT=${INST_ROOT}${vyatta_sysconfdir}/install-image/postinst +if [ -e "$PI_SCRIPT" ]; then + echo "Running post-install script..." + $PI_SCRIPT $INST_ROOT +fi + +# set up grub entry (if provided) +DEF_GRUB=${INST_ROOT}${vyatta_sysconfdir}/grub/default-union-grub-entry +if [ -e "$DEF_GRUB" ]; then + echo "Setting up grub configuration..." + old_grub_cfg=$BOOT_DIR/grub/grub.cfg + new_grub_cfg=/tmp/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 + +echo 'Done.' + +# done +exit 0 + diff --git a/scripts/install/install-image-new b/scripts/install/install-image-new new file mode 100755 index 00000000..7294fc35 --- /dev/null +++ b/scripts/install/install-image-new @@ -0,0 +1,76 @@ +#!/bin/bash + +if [ `whoami` != 'root' ] ; then + echo "This script must be run with root privileges." + exit 1 +fi + +# source in the functions +source /opt/vyatta/sbin/install-functions + +# the INSTALL_LOG env var should be exported by the "caller". +# it will be used to log messages. + +# the install partition e.g. sda1 +ROOT_PARTITION=$1 + +becho "Mounting /dev/$ROOT_PARTITION..." + +# mount the partition +mkdir -p $WRITE_ROOT +if ! try_mount "/dev/$ROOT_PARTITION $WRITE_ROOT"; then + echo 'Exiting...' + exit 1 +fi + +version=$(get_new_version) +if [ -z "$version" ]; then + echo 'Cannot find new version. Exiting...' + exit 1 +fi + +# make the dir for the new version +mkdir -p $WRITE_ROOT/boot/$version +# make dir for backing store +rw_dir=$WRITE_ROOT/boot/$version/live-rw +mkdir -p $rw_dir + +echo Copying squashfs image... +# these are the defaults if installing from a specified ISO image file. +# in such cases, the ISO image has already been mounted by caller. +squash_img=${CD_ROOT}/live/filesystem.squashfs +boot_dir=${CD_SQUASH_ROOT}/boot +boot_files=$(find $boot_dir -maxdepth 1 -type f -o -type l 2>/dev/null) +if [ ! -f "$squash_img" ] || [ -z "$boot_files" ]; then + # maybe installing from a live CD boot? + squash_img=/live/image/live/filesystem.squashfs + boot_dir=/boot + boot_files=$(find $boot_dir -maxdepth 1 -type f -o -type l 2>/dev/null) + if [ ! -f "$squash_img" ] || [ -z "$boot_files" ]; then + # not a live CD boot either. give up. + becho 'Cannot find the squashfs image. Exiting...' + exit 1 + fi +fi + +target_squash=$WRITE_ROOT/boot/$version/$version.squashfs +cp -p $squash_img $target_squash +echo Copying kernel and initrd images... +cp -dp $boot_files $WRITE_ROOT/boot/$version/ + +# set up union root for postinst +mkdir -p $INST_ROOT $READ_ROOT +if ! try_mount "-o loop,ro -t squashfs $target_squash $READ_ROOT"; then + echo 'Exiting...' + exit 1 +fi +margs="-t unionfs -o noatime,dirs=$rw_dir=rw:$READ_ROOT=ro unionfs $INST_ROOT" +if ! try_mount "$margs"; then + echo 'Exiting...' + exit 1 +fi + +becho "Done!" + +exit 0 + diff --git a/scripts/install/install-postinst-new b/scripts/install/install-postinst-new new file mode 100755 index 00000000..84b96989 --- /dev/null +++ b/scripts/install/install-postinst-new @@ -0,0 +1,201 @@ +#!/bin/bash + +# postinst operations for installation on a "new" partition, i.e., full grub +# setup needed, etc. + +if [ `whoami` != 'root' ] ; then + echo "This script must be run with root privileges." + exit 1 +fi + +# source in the functions +source /opt/vyatta/sbin/install-functions + +# the INSTALL_LOG env var should be exported by the "caller". +# it will be used to log messages. + +# the base install drive e.g. sda +INSTALL_DRIVE=$1 +# the install partition e.g. sda1 +ROOT_PARTITION=$2 +# install type: "union" or "old" +INSTALL_TYPE=$3 + +# copy configuration to the config directory +copy_config () { + local cfg_dir=${INST_ROOT}${VYATTA_CFG_DIR} + + # create the config directory + mkdir -p $cfg_dir + chgrp vyattacfg $cfg_dir + chmod 775 $cfg_dir + + # create our config partition marker + touch $cfg_dir/.vyatta_config + + if [ -d /mnt/config ]; then + echo "Copying old configurations to config partition." + cp -a /mnt/config/* $cfg_dir/ >&/dev/null + else + # Find the config files and give the user the option to copy config files + # TODO: this needs cleaned up + if [ -f "${VYATTA_CFG_DIR}/config.boot" ]; then + config=${VYATTA_CFG_DIR}/config.boot + fi + if [ -f "${FD_CFG_DIR}/config.boot" ]; then + if [ -z "$config" ]; then + config="${FD_CFG_DIR}/config.boot" + else + config="$config ${FD_CFG_DIR}/config.boot" + fi + fi + + if [ -n "$config" ]; then + echo "I found the following configuration files" + for file in $config; do + echo $file + done + + default=$(echo -e $config | awk '{ print $1 }') + + while [ -z "$configfile" ]; do + echo -n "Which one should I copy to $INSTALL_DRIVE? [$default]: " + configfile=$(get_response "$default" "$config") + done + + echo + cp -p $configfile $cfg_dir/ >&/dev/null + if [ $? != 0 ]; then + lecho "Error copying file $configfile to config directory. Exiting..." + exit 1 + fi + fi + fi + + # set the permissions on the new config file + if [ -f "$cfg_dir/config.boot" ]; then + chgrp vyattacfg $cfg_dir/config.boot + chmod 775 $cfg_dir/config.boot + fi +} + +# setup grub on the boot sector of a user selected drive +install_grub () { + grub_inst_drv='' + if [ ${INSTALL_DRIVE:0:2} == "md" ]; then + grub_inst_drv=$INSTALL_DRIVE + fi + + mkdir -p $grub_root/boot/grub + + # Let the user choose the boot sector + while [ -z "$grub_inst_drv" ] + do + echo "I need to install the GRUB boot loader." + echo "I found the following drives on your system:" + select_drive "Which drive should GRUB modify the boot partition on?" \ + 'grub_inst_drv' + done + + echo -n "Setting up grub: " + lecho "Setting up grub..." + + # Install grub in the boot sector of the primary drive + progress_indicator start + output=$(grub-install --no-floppy --recheck --root-directory=$grub_root \ + /dev/$grub_inst_drv 2>&1) + lecho "$output" + progress_indicator stop + + output=$(/opt/vyatta/sbin/vyatta-grub-setup $grub_setup_args \ + "$ROOT_PARTITION" '' $grub_root 2>&1) + ret=$? + lecho "$output" + if [ $ret == 0 ]; then + echo 'OK' + else + echo 'Grub failed to install!' + exit 1 + fi +} + +##### Main + +version=$(get_new_version) +if [ -z "$version" ]; then + echo 'Cannot find new version. Exiting...' + exit 1 +fi + +# these are the defaults for "union" +grub_root=$WRITE_ROOT +grub_setup_args="-u $version" +if [ "$INSTALL_TYPE" == 'old' ]; then + grub_root=$INST_ROOT + grub_setup_args='' +elif [ "$INSTALL_TYPE" != 'union' ]; then + echo 'Invalid install type. Exiting...' + exit 1 +fi + +# Copy the config files saved from earlier steps +copy_config + +# Modify config to match system +# Assume user wants to keep password from old config +if [ ! -d /mnt/config ]; then + # Disable root login + set_encrypted_password root "*" "${INST_ROOT}${VYATTA_CFG_DIR}/config.boot" + + echo "Enter password for administrator account" + change_password vyatta "${INST_ROOT}${VYATTA_CFG_DIR}/config.boot" +fi + +# Install grub +install_grub + +# Fix up PAM configuration for login so that invalid users are prompted +# for password +# XXX is this still needed? can't find this in the files any more. +sed -i 's/requisite[ \t][ \t]*pam_securetty.so/required pam_securetty.so/' \ + ${INST_ROOT}/etc/pam.d/login + +# +# Only start the mdadm daemon if we have the root filesystem running +# on a RAID set. Since this script is the only way that the root filesystem +# ever gets set up, we can do this configuration here. +# +MDADM_CONFIG_FILE=${INST_ROOT}/etc/default/mdadm +if [ -f "$MDADM_CONFIG_FILE" ]; then + if [ "${INSTALL_DRIVE:0:2}" = "md" ]; then + sed -i 's/^START_DAEMON.*$/START_DAEMON=true/' $MDADM_CONFIG_FILE + else + sed -i 's/^START_DAEMON.*$/START_DAEMON=false/' $MDADM_CONFIG_FILE + fi +fi + +if [ "$INSTALL_TYPE" == 'union' ]; then + # make /var/run tmpfs + pi_fstab=$INST_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 +else + # not passing the write root to postinst (only needed for union) + WRITE_ROOT='' +fi + +# postinst hook +if [ -e /opt/vyatta/etc/install-system/postinst ]; then + echo "running post-install script" + output=$(/opt/vyatta/etc/install-system/postinst \ + "$INST_ROOT" "$WRITE_ROOT" 2>&1) + lecho "$output" +fi + +becho "Done!" + +exit 0 + |