1#!/bin/ksh -p 2# 3# CDDL HEADER START 4# 5# The contents of this file are subject to the terms of the 6# Common Development and Distribution License (the "License"). 7# You may not use this file except in compliance with the License. 8# 9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10# or http://www.opensolaris.org/os/licensing. 11# See the License for the specific language governing permissions 12# and limitations under the License. 13# 14# When distributing Covered Code, include this CDDL HEADER in each 15# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16# If applicable, add the following below this CDDL HEADER, with the 17# fields enclosed by brackets "[]" replaced with your own identifying 18# information: Portions Copyright [yyyy] [name of copyright owner] 19# 20# CDDL HEADER END 21# 22# Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23# Use is subject to license terms. 24# 25 26. /usr/lib/brand/solaris10/common.ksh 27 28m_usage=$(gettext "solaris10 brand usage:\n\tinstall -u | -p [-v | -s] -a archive | -d directory.\n\tThe -a archive option specifies an archive name which can be a flar,\n\ttar, pax or cpio archive.\n\tThe -d directory option specifies an existing directory.\n\tThe -u option unconfigures the zone, -p preserves the configuration.") 29 30no_install=$(gettext "Could not create install directory '%s'") 31 32product_vers=$(gettext " Product: %s") 33install_vers=$(gettext " Installer: %s") 34install_zone=$(gettext " Zone: %s") 35install_path=$(gettext " Path: %s") 36installing=$(gettext " Installing: This may take several minutes...") 37no_installing=$(gettext " Installing: Using pre-existing data in zonepath") 38install_prog=$(gettext " Installing: %s") 39 40install_fail=$(gettext " Result: *** Installation FAILED ***") 41install_log=$(gettext " Log File: %s") 42 43install_good=$(gettext " Result: Installation completed successfully.") 44 45sanity_ok=$(gettext " Sanity Check: Passed. Looks like a Solaris 10 system.") 46sanity_fail=$(gettext " Sanity Check: FAILED (see log for details).") 47 48 49p2ving=$(gettext "Postprocessing: This may take a while...") 50p2v_prog=$(gettext " Postprocess: ") 51p2v_done=$(gettext " Result: Postprocessing complete.") 52p2v_fail=$(gettext " Result: Postprocessing failed.") 53 54root_full=$(gettext "Zonepath root %s exists and contains data; remove or move aside prior to install.") 55 56media_missing=\ 57$(gettext "you must specify an installation source using '-a', '-d' or '-r'.\n%s") 58 59cfgchoice_missing=\ 60$(gettext "you must specify -u (sys-unconfig) or -p (preserve identity).\n%s") 61 62mount_failed=$(gettext "ERROR: zonecfg(8) 'fs' mount failed") 63 64not_flar=$(gettext "Input is not a flash archive") 65bad_flar=$(gettext "Flash archive is a corrupt") 66unknown_archiver=$(gettext "Archiver %s is not supported") 67 68# Clean up on interrupt 69trap_cleanup() 70{ 71 msg=$(gettext "Installation cancelled due to interrupt.") 72 log "$msg" 73 74 # umount any mounted file systems 75 umnt_fs 76 77 trap_exit 78} 79 80# If the install failed then clean up the ZFS datasets we created. 81trap_exit() 82{ 83 if (( $EXIT_CODE != $ZONE_SUBPROC_OK )); then 84 /usr/lib/brand/solaris10/uninstall $ZONENAME $ZONEPATH -F 85 fi 86 87 exit $EXIT_CODE 88} 89 90# 91# The main body of the script starts here. 92# 93# This script should never be called directly by a user but rather should 94# only be called by zoneadm to install a s10 system image into a zone. 95# 96 97# 98# Exit code to return if install is interrupted or exit code is otherwise 99# unspecified. 100# 101EXIT_CODE=$ZONE_SUBPROC_USAGE 102 103trap trap_cleanup INT 104trap trap_exit EXIT 105 106# If we weren't passed at least two arguments, exit now. 107(( $# < 2 )) && exit $ZONE_SUBPROC_USAGE 108 109ZONENAME="$1" 110ZONEPATH="$2" 111# XXX shared/common script currently uses lower case zonename & zonepath 112zonename="$ZONENAME" 113zonepath="$ZONEPATH" 114 115ZONEROOT="$ZONEPATH/root" 116logdir="$ZONEROOT/var/log" 117 118shift; shift # remove ZONENAME and ZONEPATH from arguments array 119 120unset inst_type 121unset msg 122unset silent_mode 123unset OPT_V 124 125# 126# It is worth noting here that we require the end user to pick one of 127# -u (sys-unconfig) or -p (preserve config). This is because we can't 128# really know in advance which option makes a better default. Forcing 129# the user to pick one or the other means that they will consider their 130# choice and hopefully not be surprised or disappointed with the result. 131# 132unset unconfig_zone 133unset preserve_zone 134unset SANITY_SKIP 135 136while getopts "a:d:Fpr:suv" opt 137do 138 case "$opt" in 139 a) 140 if [[ -n "$inst_type" ]]; then 141 fatal "$incompat_options" "$m_usage" 142 fi 143 inst_type="archive" 144 install_media="$OPTARG" 145 ;; 146 d) 147 if [[ -n "$inst_type" ]]; then 148 fatal "$incompat_options" "$m_usage" 149 fi 150 inst_type="directory" 151 install_media="$OPTARG" 152 ;; 153 F) SANITY_SKIP=1;; 154 p) preserve_zone="-p";; 155 r) 156 if [[ -n "$inst_type" ]]; then 157 fatal "$incompat_options" "$m_usage" 158 fi 159 inst_type="stdin" 160 install_media="$OPTARG" 161 ;; 162 s) silent_mode=1;; 163 u) unconfig_zone="-u";; 164 v) OPT_V="-v";; 165 *) printf "$m_usage\n" 166 exit $ZONE_SUBPROC_USAGE;; 167 esac 168done 169shift OPTIND-1 170 171# The install can't be both verbose AND silent... 172if [[ -n $silent_mode && -n $OPT_V ]]; then 173 fatal "$incompat_options" "$m_usage" 174fi 175 176if [[ -z $install_media ]]; then 177 fatal "$media_missing" "$m_usage" 178fi 179 180# The install can't both preserve and unconfigure 181if [[ -n $unconfig_zone && -n $preserve_zone ]]; then 182 fatal "$incompat_options" "$m_usage" 183fi 184 185# Must pick one or the other. 186if [[ -z $unconfig_zone && -z $preserve_zone ]]; then 187 fatal "$cfgchoice_missing" "$m_usage" 188fi 189 190LOGFILE=$(/usr/bin/mktemp -t -p /var/tmp $ZONENAME.install_log.XXXXXX) 191if [[ -z "$LOGFILE" ]]; then 192 fatal "$e_tmpfile" 193fi 194zone_logfile="${logdir}/$ZONENAME.install$$.log" 195exec 2>>"$LOGFILE" 196log "$install_log" "$LOGFILE" 197 198vlog "Starting pre-installation tasks." 199 200# 201# From here on out, an unspecified exit or interrupt should exit with 202# ZONE_SUBPROC_NOTCOMPLETE, meaning a user will need to do an uninstall before 203# attempting another install, as we've modified the directories we were going 204# to install to in some way. 205# 206EXIT_CODE=$ZONE_SUBPROC_NOTCOMPLETE 207 208create_active_ds 209 210vlog "Installation started for zone \"$ZONENAME\"" 211install_image "$inst_type" "$install_media" 212 213[[ "$SANITY_SKIP" == "1" ]] && touch $ZONEROOT/.sanity_skip 214 215log "$p2ving" 216vlog "running: p2v $OPT_V $unconfig_zone $ZONENAME $ZONEPATH" 217 218# 219# Run p2v. 220# 221# Getting the output to the right places is a little tricky because what 222# we want is for p2v to output in the same way the installer does: verbose 223# messages to the log file always, and verbose messages printed to the 224# user if the user passes -v. This rules out simple redirection. And 225# we can't use tee or other tricks because they cause us to lose the 226# return value from the p2v script due to the way shell pipelines work. 227# 228# The simplest way to do this seems to be to hand off the management of 229# the log file to the p2v script. So we run p2v with -l to tell it where 230# to find the log file and then reopen the log (O_APPEND) when p2v is done. 231# 232/usr/lib/brand/solaris10/p2v -l "$LOGFILE" -m "$p2v_prog" \ 233 $OPT_V $unconfig_zone $ZONENAME $ZONEPATH 234p2v_result=$? 235exec 2>>$LOGFILE 236 237if (( $p2v_result == 0 )); then 238 vlog "$p2v_done" 239else 240 log "$p2v_fail" 241 log "" 242 log "$install_fail" 243 log "$install_log" "$LOGFILE" 244 exit $ZONE_SUBPROC_FATAL 245fi 246 247# Add a service tag for this zone. 248add_svc_tag "$ZONENAME" "install $inst_type `basename $install_media`" 249 250log "" 251log "$install_good" "$ZONENAME" 252 253safe_dir /var 254safe_dir /var/log 255safe_copy $LOGFILE $zone_logfile 256 257log "$install_log" "$zone_logfile" 258rm -f $LOGFILE 259 260# This needs to be set since the exit trap handler is going run. 261EXIT_CODE=$ZONE_SUBPROC_OK 262 263exit $ZONE_SUBPROC_OK 264