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