src/brand/common.ksh
changeset 1483 2276b6786711
parent 1327 6c5e04bdd8b2
child 1493 625950c12e71
--- a/src/brand/common.ksh	Tue Nov 10 15:49:19 2009 +0000
+++ b/src/brand/common.ksh	Tue Nov 10 14:40:37 2009 -0700
@@ -23,27 +23,41 @@
 # Use is subject to license terms.
 #
 
-ZONE_SUBPROC_OK=0
-ZONE_SUBPROC_USAGE=253
-ZONE_SUBPROC_INCOMPLETE=254
-ZONE_SUBPROC_FATAL=255
+unset LD_LIBRARY_PATH
+PATH=/usr/bin:/usr/sbin
+export PATH
+
+. /usr/lib/brand/shared/common.ksh
 
 PROP_PARENT="org.opensolaris.libbe:parentbe"
 PROP_ACTIVE="org.opensolaris.libbe:active"
 
+f_incompat_options=$(gettext "cannot specify both %s and %s options")
+f_sanity_detail=$(gettext  "Missing %s at %s")
+f_sanity_sparse=$(gettext  "Is this a sparse zone image?  The image must be whole-root.")
+sanity_ok=$(gettext     "  Sanity Check: Passed.  Looks like an OpenSolaris system.")
+sanity_fail=$(gettext   "  Sanity Check: FAILED (see log for details).")
+sanity_fail_vers=$(gettext  "  Sanity Check: the Solaris image (release %s) is not an OpenSolaris image and cannot be installed in this type of branded zone.")
+install_fail=$(gettext  "        Result: *** Installation FAILED ***")
 f_zfs_in_root=$(gettext "Installing a zone in the ROOT pool is unsupported.")
 f_zfs_create=$(gettext "Unable to create the zone's ZFS dataset.")
 f_root_create=$(gettext "Unable to create the zone's ZFS dataset mountpoint.")
-f_no_gzbe=$(gettext "Error: unable to determine global zone boot environment.")
-f_no_ds=$(gettext "Error: no zonepath dataset.")
-f_multiple_ds=$(gettext "Error: multiple active datasets.")
-f_no_active_ds=$(gettext "Error: no active dataset.")
+f_no_gzbe=$(gettext "unable to determine global zone boot environment.")
+f_no_ds=$(gettext "the zonepath must be a ZFS dataset.\nThe parent directory of the zonepath must be a ZFS dataset so that the\nzonepath ZFS dataset can be created properly.")
+f_multiple_ds=$(gettext "multiple active datasets.")
+f_no_active_ds=$(gettext "no active dataset.")
 f_zfs_mount=$(gettext "Unable to mount the zone's ZFS dataset.")
 
 f_safedir=$(gettext "Expected %s to be a directory.")
 f_cp=$(gettext "Failed to cp %s %s.")
 f_cp_unsafe=$(gettext "Failed to safely copy %s to %s.")
 
+m_brnd_usage=$(gettext "brand-specific usage: ")
+
+m_complete=$(gettext    "        Done: Installation completed in %s seconds.")
+m_postnote=$(gettext    "  Next Steps: Boot the zone, then log into the zone console (zlogin -C)")
+m_postnote2=$(gettext "              to complete the configuration process.")
+
 fail_incomplete() {
 	printf "ERROR: " 1>&2
 	printf "$@" 1>&2
@@ -51,16 +65,59 @@
 	exit $ZONE_SUBPROC_INCOMPLETE
 }
 
-fail_fatal() {
-	printf "ERROR: " 1>&2
+fail_usage() {
 	printf "$@" 1>&2
 	printf "\n" 1>&2
-	exit $ZONE_SUBPROC_FATAL
+	printf "$m_brnd_usage" 1>&2
+	printf "$m_usage\n" 1>&2
+	exit $ZONE_SUBPROC_USAGE
 }
 
-fail_usage() {
-	print "Usage: $1"
-	exit $ZONE_SUBPROC_USAGE
+sanity_check()
+{
+	typeset dir="$1"
+	shift
+	res=0
+
+	#
+	# Check for some required directories and make sure this isn't a
+	# sparse zone image from SXCE.
+	#
+	checks="etc etc/svc var var/svc"
+	for x in $checks; do
+		if [[ ! -e $dir/$x ]]; then
+			log "$f_sanity_detail" "$x" "$dir"
+			res=1
+		fi
+	done
+	if (( $res != 0 )); then
+		log "$f_sanity_sparse"
+		log "$sanity_fail"
+		fatal "$install_fail" "$ZONENAME"
+        fi
+
+	# Check for existence of pkg command.
+	if [[ ! -x $dir/usr/bin/pkg ]]; then
+		log "$f_sanity_detail" "usr/bin/pkg" "$dir"
+		log "$sanity_fail"
+		fatal "$install_fail" "$ZONENAME"
+	fi
+
+	#
+	# XXX There should be a better way to do this.
+	# Check image release.  We only work on the same minor release as the
+	# system is running.  The INST_RELEASE file doesn't exist with IPS on
+	# OpenSolaris, so its presence means we have an earlier Solaris
+	# (i.e. non-OpenSolaris) image.
+	#
+	if [[ -f "$dir/var/sadm/system/admin/INST_RELEASE" ]]; then
+		image_vers=$(nawk -F= '{if ($1 == "VERSION") print $2}' \
+		    $dir/var/sadm/system/admin/INST_RELEASE)
+		vlog "$sanity_fail_vers" "$image_vers"
+		fatal "$install_fail" "$ZONENAME"
+	fi
+	
+	vlog "$sanity_ok"
 }
 
 get_current_gzbe() {
@@ -85,19 +142,6 @@
 	fi
 }
 
-# Find the dataset mounted on the zonepath.
-get_zonepath_ds() {
-	ZONEPATH_DS=`/usr/sbin/zfs list -H -t filesystem -o name,mountpoint | \
-	    /usr/bin/nawk -v zonepath=$1 '{
-		if ($2 == zonepath)
-			print $1
-	}'`
-
-	if [ -z "$ZONEPATH_DS" ]; then
-		fail_fatal "$f_no_ds"
-	fi
-}
-
 # Find the active dataset under the zonepath dataset to mount on zonepath/root.
 # $1 CURRENT_GZBE
 # $2 ZONEPATH_DS
@@ -136,6 +180,66 @@
 }
 
 #
+# Set up ZFS dataset hierarchy for the zone root dataset.
+#
+create_active_ds() {
+	get_current_gzbe
+
+	#
+	# Find the zone's current dataset.  This should have been created by
+	# zoneadm.
+	#
+	get_zonepath_ds $zonepath
+
+	# Check that zone is not in the ROOT dataset.
+	fail_zonepath_in_rootds $ZONEPATH_DS
+
+	#
+	# From here on, errors should cause the zone to be incomplete.
+	#
+	int_code=$ZONE_SUBPROC_FATAL
+
+	#
+	# We need to tolerate errors while creating the datasets and making the
+	# mountpoint, since these could already exist from some other BE.
+	#
+
+	/usr/sbin/zfs list -H -o name $ZONEPATH_DS/ROOT >/dev/null 2>&1
+	if (( $? != 0 )); then
+		/usr/sbin/zfs create -o mountpoint=legacy \
+		    -o zoned=on $ZONEPATH_DS/ROOT
+		if (( $? != 0 )); then
+			fail_fatal "$f_zfs_create"
+		fi
+	fi
+
+	BENAME=zbe
+	BENUM=0
+	# Try 100 different names before giving up.
+	while [ $BENUM -lt 100 ]; do
+       		/usr/sbin/zfs create -o $PROP_ACTIVE=on \
+		    -o $PROP_PARENT=$CURRENT_GZBE \
+		    -o canmount=noauto $ZONEPATH_DS/ROOT/$BENAME >/dev/null 2>&1
+		if (( $? == 0 )); then
+			break
+		fi
+		BENUM=`expr $BENUM + 1`
+		BENAME="zbe-$BENUM"
+	done
+
+	if [ $BENUM -ge 100 ]; then
+		fail_fatal "$f_zfs_create"
+	fi
+
+	if [ ! -d $ZONEROOT ]; then
+		/usr/bin/mkdir $ZONEROOT
+	fi
+
+	/usr/sbin/mount -F zfs $ZONEPATH_DS/ROOT/$BENAME $ZONEROOT || \
+	    fail_incomplete "$f_zfs_mount"
+}
+
+#
 # Emits to stdout the entire incorporation for this image,
 # stripped of publisher name and other junk.
 #
@@ -172,26 +276,3 @@
 	    nawk -F': ' '/SSL Cert/ {print $2; exit 0}')
 	print $key $cert
 }
-
-# Validate that the directory is safe.
-# n.b.: this is diverged from the shared/common.ksh version.
-safe_dir()
-{
-	typeset dir="$1"
-
-	[[ -h $dir || ! -d $dir ]] && fail_fatal "$f_safedir"
-}
-
-# Make a copy even if the destination already exists.
-# n.b.: this is diverged from the shared/common.ksh version.
-safe_copy()
-{
-	typeset src="$1"
-	typeset dst="$2"
-
-	if [[ ! -h $src && ! -h $dst && ! -d $dst ]]; then
-		/usr/bin/cp -p $src $dst || fail_fatal "$f_cp" "$src" "$dst"
-	else
-		fail_fatal "$f_cp_unsafe" "$src" "$dst"
-	fi
-}