14684 zone attach incorporation logic needs enhancement
authorGary Pennington <gary.pennington@sun.com>
Mon, 26 Apr 2010 02:19:08 -0700
changeset 1879 7dc50f542f19
parent 1878 badde6b7111b
child 1880 684773e8a373
14684 zone attach incorporation logic needs enhancement
src/brand/attach
src/brand/common.ksh
src/brand/pkgcreatezone
--- a/src/brand/attach	Sat Apr 24 23:40:12 2010 -0400
+++ b/src/brand/attach	Mon Apr 26 02:19:08 2010 -0700
@@ -19,9 +19,9 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
 #
 
 . /usr/lib/brand/ipkg/common.ksh
@@ -30,38 +30,24 @@
 m_zfs=$(gettext "A ZFS file system was created for the zone.")
 m_attaching=$(gettext "Attaching...")
 m_usage=$(gettext  "attach [-a archive] [-d dataset] [-n] [-r zfs-recv] [-u]\n\tThe -a archive option specifies a tar file or cpio archive.\n\tThe -d dataset option specifies an existing dataset.\n\tThe -r zfs-recv option receives the output of a 'zfs send' command\n\tof an existing zone root dataset.\n\tThe -u option indicates that the software should be updated to match\n\tthe current host.")
-m_gzinc=$( gettext "       Global zone version: %s")
-m_zinc=$(  gettext "   Non-Global zone version: %s")
-m_insync=$(gettext "                Evaluation: Packages in %s are in sync with global zone.")
-m_uprev=$(gettext  "                Evaluation: %s is newer than the global zone.")
-m_dnrev=$(gettext  "                Evaluation: %s is downrev of the global zone.")
-m_resetpub=$(gettext  "           Publisher Check: Zone preferred publisher does not contain")
-m_resetpub2=$(gettext "                            %s.")
-m_resetpub3=$(gettext "           Publisher Reset: Copying preferred publisher from global zone.")
-m_pubfine=$(gettext   "           Publisher Check: Looks good.")
-m_cache=$(gettext     "                     Cache: Using %s.")
-m_updating=$(gettext  "  Updating non-global zone: Output follows")
-m_sync_done=$(gettext "  Updating non-global zone: Zone updated to %s")
-m_complete=$(gettext "Attach complete.")
-
+m_gzinc=$(gettext       "       Global zone version: %s")
+m_zinc=$(gettext        "   Non-Global zone version: %s")
+m_need_update=$(gettext "                Evaluation: Packages in zone %s are out of sync with the global zone. To proceed, retry with the -u flag.")
+m_cache=$(gettext       "                     Cache: Using %s.")
+m_updating=$(gettext    "  Updating non-global zone: Output follows")
+m_sync_done=$(gettext   "  Updating non-global zone: Zone updated.")
+m_complete=$(gettext    "                    Result: Attach Succeeded.")
+m_failed=$(gettext      "                    Result: Attach Failed.")
 sanity_fail_global=$(gettext  "  Sanity Check: FAILED, the image is from the global zone.")
-f_downrev=$(gettext "Zone is downrev of global zone.  Specify -u to update it.")
-f_uprev=$(gettext "Zone is uprev of global zone.  Global zone will need to be updated before attach can proceed.")
 f_update=$(gettext "Could not update attaching zone")
-f_gz_entire=$(gettext "Could not find 'entire' incorporation for global zone.")
-f_zone_entire=$(gettext "Could not find 'entire' incorporation for non-global zone.")
-f_fmri_compare=$(gettext "Failed to compare 'entire' FMRIs")
-f_reset_pub=$(gettext "Failed to reset publisher to %s %s")
-f_del_pub=$(gettext "Failed to unset publisher '%s' for zone.")
 f_no_pref_publisher=$(gettext "Unable to get preferred publisher information for zone '%s'.")
-f_get_secinfo=$(gettext "Failed to get key/cert information for publisher %s")
 f_nosuch_key=$(gettext "Failed to find key %s for global zone publisher")
 f_nosuch_cert=$(gettext "Failed to find cert %s for global zone publisher")
 
 # Clean up on interrupt
-trap_cleanup()
-{
-	msg=$(gettext "Installation cancelled due to interrupt.")
+trap_cleanup() {
+	typeset msg=$(gettext "Installation cancelled due to interrupt.")
+
 	log "$msg"
 
 	# umount any mounted file systems
@@ -71,13 +57,12 @@
 }
 
 # If the attach failed then clean up the ZFS datasets we created.
-trap_exit()
-{
+trap_exit() {
 	if [[ $EXIT_CODE == $ZONE_SUBPROC_OK ]]; then
 		# unmount the zoneroot if labeled brand
 		is_brand_labeled
 		(( $? == 1 )) && ( umount $ZONEROOT || \
-		    printf "$f_zfs_unmount" "$ZONEPATH/root" )
+		    log "$f_zfs_unmount" "$ZONEPATH/root" )
 	else
 		if [[ "$install_media" != "-" ]]; then
 			/usr/lib/brand/ipkg/uninstall $ZONENAME $ZONEPATH -F
@@ -91,6 +76,7 @@
 				    >/dev/null 2>&1
 			fi
 		fi
+		log "$m_failed"
 	fi
 
 	exit $EXIT_CODE
@@ -130,10 +116,181 @@
 PKG_IMAGE=$GZ_IMAGE
 export PKG_IMAGE
 
+allow_update=0
 noexecute=0
 
 unset inst_type
 
+# Get publisher information for global zone.  These structures are used
+# to store information about the global zone publishers and
+# incorporations.
+
+typeset -A gz_publishers
+typeset gz_incorporations=""
+
+#
+# Gather the zone publisher details. $1 is the location of the image we
+# are processing and $2 is an associative array used to store publisher
+# details.
+#
+gather_zone_publisher_details() {
+	STORED_IMAGE=$PKG_IMAGE
+	PKG_IMAGE=$1;export PKG_IMAGE
+	typeset -n publishers=$2
+	typeset -li publisher_count=0
+	typeset -li url_count=0
+	typeset line=
+	typeset name=
+	typeset mirror=
+	typeset origin=
+	typeset opublisher=
+
+	#
+	# Store publisher, origin and security details. It is assumed
+	# that mirrors all use the same key as the origins.
+	#
+	for line in $(get_publisher_urls all origin); do
+		print $line | IFS="=" read name origin
+		# When a publisher has multiple origins, the
+		# additional origins don't contain the publisher
+		# name. Correct for this by checking if origin is not
+		# set by get_publisher_urls() and, if so, use the
+		# "name" as the origin and set the name to the value
+		# we have already saved.
+		if [[ -z $origin ]]; then
+			origin=$name
+			name=${publisher.name}
+		fi
+		# Use a compound variable to store all the data
+		# relating to a publisher.
+		if [[ -z ${publishers[$name]} ]]; then
+			typeset -C publisher_$publisher_count
+			typeset -n publisher=publisher_$publisher_count
+			typeset publisher.sticky=""
+			typeset publisher.preferred=""
+			typeset publisher.enabled=""
+			typeset -a publisher.origins=""
+			typeset -a publisher.mirrors=""
+			typeset publisher.name=$name
+			typeset publisher.keyfile=""
+			typeset publisher.certfile=""
+
+			get_publisher_attrs ${publisher.name} origin | \
+			    IFS=" " read publisher.sticky publisher.preferred \
+			    publisher.enabled
+			get_pub_secinfo ${publisher.name} | \
+			    read publisher.keyfile publisher.certfile
+			[[ ${publisher.keyfile} != "None" && \
+			    ! -f ${PKG_IMAGE}/${publisher.keyfile} ]] && \
+			    fail_usage "$f_nosuch_key" ${publisher.keyfile}
+			[[ ${publisher.certfile} != "None" && \
+			    ! -f ${PKG_IMAGE}/${publisher.certfile} ]] && \
+			    fail_usage "$f_nosuch_cert" ${publisher.certfile}
+			publisher_count=publisher_count+1
+			url_count=0
+		fi
+		publisher.origins[$url_count]=$origin
+		publishers[$name]=${publisher}
+		url_count=url_count+1
+	done
+
+	#
+	# Store mirror details
+	#
+	url_count=0
+	for line in $(get_publisher_urls all mirror); do
+		print $line | IFS="=" read name mirror
+		if [[ -z $mirror ]]; then
+			mirror=$name
+			name=${publisher.name}
+		fi
+		if [[ -z $opublisher || $opublisher != $name ]]; then
+			opublisher=$name
+			eval publisher="${publishers[$name]}"
+			url_count=0
+		fi
+		publisher.mirrors[$url_count]=$mirror
+		publishers[$name]=${publisher}
+		url_count=url_count+1
+	done
+	
+	PKG_IMAGE=$STORED_IMAGE;export PKG_IMAGE
+}
+
+#
+# $1 is an associative array of publishers. Search this array and
+# return the preferred publisher.
+#
+get_preferred_publisher() {
+	typeset -n publishers=$1
+	typeset publisher=
+
+	for key in ${!publishers[*]}; do
+		eval publisher="${publishers[$key]}"
+		if [[ ${publisher.preferred}  ==  "true" ]]; then
+			print ${key}
+			return 0
+		fi
+	done
+	return 1
+}
+
+#
+# $1 is an empty string to be populated with a list of incorporation
+# fmris.
+#
+gather_incorporations() {
+	typeset -n incorporations=$1
+	typeset p=
+
+	for p in \
+	    $(LC_ALL=C $PKG search -Hl -o pkg.name \
+	    ':pkg.depend.install-hold:core-os*');do
+		incorporations="$incorporations $(get_pkg_fmri $p)"
+	done
+}
+
+#
+# Print the pkg(1) command which defines a publisher. $1 is an associative 
+# array of publisher details and $2 is the publisher to be printed.
+#
+print_publisher_pkg_defn() {
+	typeset -n publishers=$1
+	typeset pname=$2
+	typeset publisher=
+	typeset args=""
+	typeset origin=
+	typeset mirror=
+
+	eval publisher="${publishers[$pname]}"
+
+	if [[ ${publisher.preferred} == "true" ]]; then
+		args="$args -P"
+	fi
+
+	for origin in ${publisher.origins[*]}; do
+		args="$args -g $origin"
+	done
+
+	for mirror in ${publisher.mirrors[*]}; do
+		args="$args -m $mirror"
+	done
+
+	if [[ ${publisher.sticky} == "true" ]]; then
+		args="$args --sticky"
+	else
+		args="$args --non-sticky"
+	fi
+
+	if [[ ${publisher.enabled} == "true" ]]; then
+		args="$args --enable"
+	else
+		args="$args --disable"
+	fi
+
+	echo "$args"
+}
+
 # Other brand attach options are invalid for this brand.
 while getopts "a:d:nr:u" opt; do
 	case $opt in
@@ -189,6 +346,7 @@
 	fatal "$e_tmpfile"
 fi
 exec 2>>"$LOGFILE"
+
 log "$m_attach_log" "$LOGFILE"
 
 #
@@ -217,8 +375,8 @@
 	#
 	ACTIVE_DS=`mount -p | nawk -v zroot=$ZONEROOT '{
 	    if ($3 == zroot && $4 == "zfs")
-		print $1
-	    }'`
+		    print $1
+	}'`
 
 	[[ -z "$ACTIVE_DS" ]] && fatal "$f_no_active_ds"
 
@@ -247,8 +405,8 @@
 
 	mounted_ds=`mount -p | nawk -v zroot=$ZONEROOT '{
 	    if ($3 == zroot && $4 == "zfs")
-		print $1
-	    }'`
+		    print $1
+	}'`
 
 	if [[ -z $mounted_ds ]]; then
 		mount -F zfs $ACTIVE_DS $ZONEROOT || fatal "$f_zfs_mount"
@@ -296,36 +454,41 @@
 [[ -f $ZONEROOT/var/svc/manifest/system/dumpadm.xml ]] && \
     fatal "$sanity_fail_global"
 
-#
-# Look for the 'entire' incorporation's FMRI in the current image; due to users
-# doing weird machinations with their publishers, we strip off the publisher
-# from the FMRI if it is present.
-#
-gz_entire_fmri=$(get_entire_incorp) || fatal "$f_gz_entire"
+# We would like to ensure that our NGZ publishers are a superset of
+# those in the GZ. We do this by building a list of all publishers in
+# the GZ. We then process this list in the NGZ, first removing (if
+# present) and then installing all publishers in this list. Other
+# publisher, i.e. those not in the GZ list, are left as is.
 
 #
-# Get publisher information for global zone.
+# Gather all the publisher details for the global zone
+#
+gather_zone_publisher_details $PKG_IMAGE gz_publishers
+
+#
+# Get the preferred publisher for the global zone
 # If we were not able to get the zone's preferred publisher, complain.
 #
-
-get_publisher_urls preferred origin |
-    IFS="=" read gz_publisher gz_publisher_origins
+gz_publisher_pref=$(get_preferred_publisher gz_publishers)
 
-[[ -z $gz_publisher ]] && fail_usage "$f_no_pref_publisher" "global"
-[[ -z $gz_publisher_origins ]] && fail_usage "$f_no_pref_publisher" "global"
+if [[ $? -ne 0 ]]; then
+	fail_usage "$f_no_pref_publisher" "global"
+fi
 
-get_publisher_urls preferred mirror |
-    IFS="=" read ignored gz_publisher_mirrors
+log "preferred global publisher: $gz_publisher_pref"
 
-get_pub_secinfo $gz_publisher | read gzkeyfile gzcertfile
-if [[ $? -ne 0 ]]; then
-	fail_usage "$f_get_secinfo" $gz_publisher
+#
+# Try to find the "entire" incorporation's FMRI in the gz.
+#
+gz_entire_fmri=$(get_entire_incorp)
+
+#
+# If entire isn't installed, create an array of global zone core-os
+# incorporations.
+#
+if [[ -z $gz_entire_fmri ]]; then
+	gather_incorporations gz_incorporations
 fi
-[[ $gzkeyfile != "None" && ! -f $gzkeyfile ]] && \
-    fail_usage "$f_nosuch_key" $gzkeyfile
-[[ $gzcertfile != "None" && ! -f $gzcertfile ]] && \
-    fail_usage "$f_nosuch_cert" $gzcertfile
-
 
 #
 # We're done with the global zone: switch images to the non-global
@@ -334,73 +497,57 @@
 PKG_IMAGE="$ZONEROOT"
 
 #
-# Get publisher information for non global zone.
-# If we were not able to get the zone's preferred publisher, complain.
+# Try to find the "entire" incorporation's FMRI in the ngz.
 #
-get_publisher_urls preferred origin |
-    IFS="=" read zone_publisher zone_publisher_origins
+ngz_entire_fmri=$(get_entire_incorp)
 
-[[ -z $zone_publisher ]] && fail_usage "$f_no_pref_publisher" $ZONENAME
-[[ -z $zone_publisher_origins ]] && fail_usage "$f_no_pref_publisher" $ZONENAME
-
-get_publisher_urls preferred mirror |
-    IFS="=" read ignored zone_publisher_mirrors
+[[ -n $gz_entire_fmri ]] && log "$m_gzinc" "$gz_entire_fmri"
+[[ -n $ngz_entire_fmri ]] && log "$m_zinc\n" "$ngz_entire_fmri"
 
 #
-# Get entire incorp for non-global zone
-#
-zone_entire_fmri=$(get_entire_incorp) || fatal "$f_zone_entire"
-
-printf "$m_gzinc\n" $gz_entire_fmri
-printf "$m_zinc\n" $zone_entire_fmri
-# 
-# if the zone entire and the gz entire match, we're good.
+# Create the list of incorporations we wish to install/update in the
+# ngz.
 #
-comp=$(/usr/lib/brand/ipkg/fmri_compare $zone_entire_fmri $gz_entire_fmri)
-if [[ $? -ne 0 ]]; then
-	fatal "$f_fmri_compare"
-fi
-if [[ $comp = "=" ]]; then
-	printf "$m_insync\n" $ZONENAME
-	echo $m_complete
-	EXIT_CODE=$ZONE_SUBPROC_OK
-	exit $ZONE_SUBPROC_OK
-fi
-if [[ $comp = ">" ]]; then
-	printf "$m_uprev\n" $ZONENAME
-	fatal "$f_uprev"
+typeset -n incorp_list
+if [[ -n $gz_entire_fmri ]]; then
+    incorp_list=gz_entire_fmri
+else
+    incorp_list=gz_incorporations
 fi
 
 #
-# If we're here, the zone is downrev of the global zone
+# If there is a cache, use it.
 #
-if [ -z $allow_update ]; then
-	# zone is downrev
-	printf "$m_dnrev\n" $ZONENAME
-	fatal "$f_downrev"
+if [ -d /var/pkg/download ]; then
+	PKG_CACHEDIR=/var/pkg/download
+	export PKG_CACHEDIR
+	log "$m_cache" "$PKG_CACHEDIR"
 fi
 
+log "$m_updating"
+
 #
-# See if the zone knows about the gz entire fmri in question.  If yes,
-# we'll try using that.
-#
-LC_ALL=C $PKG list --no-refresh -a $gz_entire_fmri > /dev/null 2>&1
+# The NGZ publishers must be a superset of the GZ publisher. Process
+# the GZ publishers and make the NGZ publishers match them.
+# You can't remove a preferred publisher, so temporarily create
+# a preferred publisher
+RANDOM=$$
+
+ZNAME=za$RANDOM
 
-#
-# If this doesn't exist, then we reset the preferred pub for
-# the zone to that of the global zone on attach, and try again.
-#
-if [[ $? -ne 0 ]]; then
-	printf "$m_resetpub\n"
-	printf "$m_resetpub2\n" $gz_entire_fmri
-	printf "$m_resetpub3\n"
+LC_ALL=C $PKG set-publisher --no-refresh -P -g http://localhost:10000 $ZNAME
+for key in ${!gz_publishers[*]}; do
+	typeset newlocation=""
 
+	args=$(print_publisher_pkg_defn gz_publishers $key)
+
+	# Copy credentials from global zone.
 	safe_dir var
 	safe_dir var/pkg
 
-	# Copy credentials from global zone.
-	secinfo=""
-	if [[ $gzkeyfile != "None" || $gzcertfile != "None" ]]; then
+	eval publisher="${gz_publishers[$key]}"
+	if [[ ${publisher.keyfile} != "None" || \
+	    ${publisher.certfile} != "None" ]]; then
 		if [[ -e $ZONEROOT/$KEYDIR ]]; then
 			safe_dir $KEYDIR
 		else
@@ -408,106 +555,77 @@
 		fi
 	fi
 
-	if [[ $gzkeyfile != None ]]; then
-		newlocation="$KEYDIR/attach_$(basename $gzkeyfile)"
-		safe_copy $gzkeyfile $ZONEROOT/$newlocation
-		chmod 644 $ZONEROOT/$newkeylocation
-		chown -h root:root $ZONEROOT/$newkeylocation
-		secinfo="$secinfo -k $newlocation"
-	fi
-	if [[ $gzcertfile != None ]]; then
-		newlocation="$KEYDIR/attach_$(basename $gzcertfile)"
-		safe_copy $gzcertfile $ZONEROOT/$newlocation
-		chmod 644 $ZONEROOT/$newkeylocation
-		chown -h root:root $ZONEROOT/$newkeylocation
-		secinfo="$secinfo -c $newlocation"
+	if [[ ${publisher.keyfile} != "None" ]]; then
+		newlocation="$KEYDIR/$(basename ${publisher.keyfile})"
+		safe_copy ${publisher.keyfile} $newlocation
+		chmod 644 $newlocation
+		chown -h root:root $newlocation
+		args="$args -k $newlocation"
 	fi
-
-	# Note that we do cause a refresh here--at some point we need the
-	# catalog to be updated.
-
-	# Be certain that the global zone preferred publisher exists in
-	# the non-global zone.  If it doesn't, all of these comparisons
-	# are not valid.
-	del_ngz_pub=0
-	if [[ -n "$zone_publisher" && "$zone_publisher" != "$gz_publisher" ]];
-	then
-		zone_publisher_origins=""
-		zone_publisher_mirrors=""
-		del_ngz_pub=1
+	if [[ ${publisher.certfile} != "None" ]]; then
+		newlocation="$KEYDIR/$(basename ${publisher.certfile})"
+		safe_copy ${publisher.certfile} $newlocation
+		chmod 644 $newlocation
+		chown -h root:root $newlocation
+		args="$args -c $newlocation"
 	fi
-
-	# Add any origins not found in zone configuration.
-	origins=""
-	src="$(echo $zone_publisher_origins | sed 's/ /|/g')"
-	for u in $gz_publisher_origins; do
-		[[ -z "$u" ]] && continue
-		case $u in
-			$src)   ;; # Already in zone config.
-			*)      origins="${origins}-g $u ";; # Add.
-		esac
-	done
+	LC_ALL=C $PKG unset-publisher $key >/dev/null 2>&1
+	LC_ALL=C $PKG set-publisher $args $key
+	
+done
 
-	# Remove any origins not found in global configuration.
-	src="$(echo $gz_publisher_origins | sed 's/ /|/g')"
-	for u in $zone_publisher_origins; do
-		[[ -z "$u" ]] && continue
-		case $u in
-			$src)   ;; # In global config.
-			*)      origins="${origins}-G $u ";; # Remove.
-		esac
-	done
-
-	# Add any mirrors not found in zone configuration.
-	mirrors=""
-	src="$(echo $zone_publisher_mirrors | sed 's/ /|/g')"
-	for u in $gz_publisher_mirrors; do
-		case $u in
-			$src)   ;; # Already in zone config.
-			*)      mirrors="${mirrors}-m $u ";; # Add.
-		esac
-	done
+#
+# Now remove our temporary publisher
+#
+LC_ALL=C $PKG unset-publisher $ZNAME
 
-	# Remove any mirrors not found in global configuration.
-	src="$(echo $gz_publisher_mirrors | sed 's/ /|/g')"
-	for u in $zone_publisher_mirrors; do
-		case $u in
-			$src)   ;; # In global config.
-			*)      mirrors="${mirrors}-M $u ";; # Remove.
-		esac
-	done
-
-	$PKG set-publisher -P $origins $mirrors $secinfo $gz_publisher
-	if [[ $? -ne 0 ]]; then
-		fatal "$f_reset_pub" $gz_publisher \
-		    "$gz_publisher_origins $gz_publisher_mirrors"
-	fi
-
-	# If the original preferred non-global zone publisher has the 
-	# same URI as the global zone publisher we just stuck into the zone,
-	# then we now need to delete the old ngz publisher.
-	(( $del_ngz_pub == 1 )) && ( $PKG unset-publisher $zone_publisher || \
-	    fatal "$f_del_pub" $zone_publisher )
-
-	zone_publisher=$gz_publisher
-	zone_publisher_origins=$gz_publisher_origins
-	zone_publisher_mirrors=$gz_publisher_mirrors
-else
-	printf "$m_pubfine\n"
+#
+# Bring the ngz entire incorporation into sync with the gz as follows:
+# - First compare the existence of entire in both global and non-global
+#   zone and update the non-global zone accordingly.
+# - Then, if updates aren't allowed check if we can attach because no
+#   updates are required. If we can, then we are finished.
+# - Finally, we know we can do updates and they are required, so update
+#   all the non-global zone incorporations using the list we gathered
+#   from the global zone earlier.
+#
+if [[ -z $gz_entire_fmri && -n $ngz_entire_fmri ]]; then
+	if [[ $allow_update == 1 ]]; then
+		LC_ALL=C $PKG uninstall entire || pkg_err_check "$f_update"
+	else
+		log "$m_need_update" "$ZONENAME"
+		EXIT_CODE=$ZONE_SUBPROC_NOTCOMPLETE
+		exit $EXIT_CODE
+    fi
 fi
 
-if [ -d /var/pkg/download ]; then
-	PKG_CACHEDIR=/var/pkg/download
-	export PKG_CACHEDIR
-	printf "$m_cache\n" $PKG_CACHEDIR
+if [[ $allow_update == 0 ]]; then
+	LC_ALL=C $PKG install --no-refresh -n $incorp_list
+	if [[ $? == 4 ]]; then
+		log "$m_complete"
+		EXIT_CODE=$ZONE_SUBPROC_OK
+		exit $EXIT_CODE
+	else
+		log "$m_need_update" "$ZONENAME"
+		EXIT_CODE=$ZONE_SUBPROC_NOTCOMPLETE
+		exit $EXIT_CODE
+	fi
 fi
 
-printf "$m_updating\n"
+#
+# If the NGZ doesn't have entire, but the GZ does, then we have to install
+# entire twice. First time we don't specify a version and let constraining
+# incorporations determine the version. Second time, we try to install the
+# same version as we have in the GZ.
+#
+if [[ -n $gz_entire_fmri && -z $ngz_entire_fmri ]]; then
+	LC_ALL=C $PKG install --no-refresh entire  || pkg_err_check "$f_update"
+fi
 
-$PKG install $gz_entire_fmri || pkg_err_check "$f_update"
+LC_ALL=C $PKG install --no-refresh $incorp_list  || pkg_err_check "$f_update"
 
-printf "$m_sync_done\n" $gz_entire_fmri
-printf "$m_complete\n"
+log "$m_sync_done"
+log "$m_complete"
 
 EXIT_CODE=$ZONE_SUBPROC_OK
 exit $ZONE_SUBPROC_OK
--- a/src/brand/common.ksh	Sat Apr 24 23:40:12 2010 -0400
+++ b/src/brand/common.ksh	Mon Apr 26 02:19:08 2010 -0700
@@ -18,9 +18,9 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
 #
 
 unset LD_LIBRARY_PATH
@@ -88,8 +88,7 @@
 	return 0
 }
 
-sanity_check()
-{
+sanity_check() {
 	typeset dir="$1"
 	shift
 	res=0
@@ -293,11 +292,11 @@
 	zoneadm -z $ZONENAME mount -f || fatal "$e_badmount"
 
 	zlogin -S $ZONENAME /usr/sbin/sys-unconfig -R /a \
-            </dev/null >/dev/null 2>&1
-        if (( $? != 0 )); then
-                error "$e_unconfig"
+	    </dev/null >/dev/null 2>&1
+	if (( $? != 0 )); then
+		error "$e_unconfig"
 		failed=1
-        fi
+	fi
 
 	vlog "$v_unmount"
 	zoneadm -z $ZONENAME unmount || fatal "$e_badunmount"
@@ -307,19 +306,30 @@
 }
 
 #
+# Emits to stdout the fmri for the supplied package,
+# stripped of publisher name and other junk.
+#
+get_pkg_fmri() {
+	typeset pname=$1
+	typeset pkg_fmri=
+	typeset info_out=
+
+	info_out=$(LC_ALL=C $PKG info pkg:/$pname 2>/dev/null)
+	if [[ $? -ne 0 ]]; then
+		return 1
+	fi
+	pkg_fmri=$(echo $info_out | grep FMRI | cut -d'@' -f 2)
+	echo "$pname@$pkg_fmri"
+	return 0
+}
+
+#
 # Emits to stdout the entire incorporation for this image,
 # stripped of publisher name and other junk.
 #
 get_entire_incorp() {
-	typeset entire_fmri
-	entire_fmri=$($PKG list -Hv entire | nawk '{print $1}')
-	if [[ $? -ne 0 ]]; then
-		return 1
-	fi
-	entire_fmri=$(echo $entire_fmri | sed 's@^pkg://[^/]*/@@')
-	entire_fmri=$(echo $entire_fmri | sed 's@^pkg:/@@')
-	echo $entire_fmri
-	return 0
+	get_pkg_fmri entire
+	return $?
 }
 
 #
@@ -329,8 +339,8 @@
 # ("mirror" or "origin").
 #
 get_publisher_attrs() {
-	pname=$1
-	utype=$2
+	typeset pname=$1
+	typeset utype=$2
 
 	LC_ALL=C $PKG publisher -HF tsv| \
 	    nawk '$5 == "'"$utype"'" && $1 == "'"$pname"'" \
@@ -344,8 +354,11 @@
 # ("mirror" or "origin").
 #
 get_publisher_attr_args() {
+	typeset args=
+	typeset sticky=
+	typeset preferred=
+	typeset enabled=
 
-	args=""
 	get_publisher_attrs $1 $2 |
 	while IFS=" " read sticky preferred enabled; do
 		if [ $sticky == "true" ]; then
@@ -374,15 +387,14 @@
 # the list of the requested URLs separated by spaces, followed by a
 # newline after each unique publisher.  It expects two parameters,
 # publisher type ("all", "preferred", "non-preferred") and URL type
-# ("mirror" or "origin".
+# ("mirror" or "origin".)
 #
 get_publisher_urls() {
-	ptype=$1
-	utype=$2
-
-	__pub_prefix=""
-	__publisher_urls=""
-	ptype_filter=""
+	typeset ptype=$1
+	typeset utype=$2
+	typeset __pub_prefix=
+	typeset __publisher_urls=
+	typeset ptype_filter=
 
 	if [ "$ptype" == "all" ]
 	then
@@ -426,6 +438,9 @@
 # as the main publisher.
 #
 get_pub_secinfo() {
+	typeset key=
+	typeset cert=
+
 	key=$(LC_ALL=C $PKG publisher $1 |
 	    nawk -F': ' '/SSL Key/ {print $2; exit 0}')
 	cert=$(LC_ALL=C $PKG publisher $1 |
@@ -438,6 +453,6 @@
 # No changes were made - nothing to do.  Any other exit code is an error.
 #
 pkg_err_check() {
-	res=$?
+	typeset res=$?
 	(( $res != 0 && $res != 4 )) && fail_fatal "$1"
 }
--- a/src/brand/pkgcreatezone	Sat Apr 24 23:40:12 2010 -0400
+++ b/src/brand/pkgcreatezone	Mon Apr 26 02:19:08 2010 -0700
@@ -19,9 +19,9 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
 #
 
 #
@@ -284,9 +284,7 @@
 # It's ok to not find entire in the current image, since this means the user
 # can install pre-release development bits for testing purposes.
 #
-raw_entire_fmri=$($PKG list -Hv entire | nawk '{print $1}')
-entire_fmri=$(echo $raw_entire_fmri | sed 's@^pkg://[^/]*/@@')
-entire_fmri=$(echo $entire_fmri | sed 's@^pkg:/@@')
+entire_fmri=$(get_entire_incorp)
 
 #
 # Before installing the zone, set up ZFS dataset hierarchy for the zone root
@@ -382,7 +380,7 @@
 # and build catalog information.  This substantially reduces the amount of
 # time needed to create a zone.
 #
-$PKG image-create -f --no-refresh --zone --full \
+LC_ALL=C $PKG image-create -f --no-refresh --zone --full \
     -p $publisher=$pub_first_origin $pub_add_origins $pub_add_mirrors $secinfo \
     $ZONEROOT || fail_incomplete "$f_img"
 
@@ -398,7 +396,8 @@
 # --no-refresh is used here so that update operations can be
 # coalesced.
 # Update our new publisher
-$PKG set-publisher --no-refresh $attrs $publisher || fail_incomplete "$f_img"
+LC_ALL=C $PKG set-publisher --no-refresh $attrs $publisher \
+    || fail_incomplete "$f_img"
 
 # add extra publishers
 # If cert and key information are ever allowed at the origin or
@@ -423,7 +422,7 @@
 		export PKG_IMAGE
 		# --no-refresh is used here so that update operations can be
 		# coalesced.
-		$PKG set-publisher --no-refresh $attrs \
+		LC_ALL=C $PKG set-publisher --no-refresh $attrs \
                     ${pub_add_origins}${pub_prefix} || fail_incomplete "$f_img"
 	done
 
@@ -447,7 +446,7 @@
 			export PKG_IMAGE
 			# --no-refresh is used here so that update operations
 			# can be coalesced.
-			$PKG set-publisher --no-refresh $attrs \
+			LC_ALL=C $PKG set-publisher --no-refresh $attrs \
 			    ${pub_add_mirrors}${pub_prefix} || \
 			    fail_incomplete "$f_img"
 		done
@@ -456,7 +455,7 @@
 
 # Now that all of the publisher configurations are in place, attempt a refresh.
 # If this fails, assume the image is incomplete.
-$PKG refresh || fail_incomplete "$f_img"
+LC_ALL=C $PKG refresh || fail_incomplete "$f_img"
 
 if [ -d /var/pkg/download ]; then
 	PKG_CACHEDIR=/var/pkg/download
@@ -478,7 +477,7 @@
 #
 if [[ -n $entire_fmri ]]; then
 	printf "$m_incorp\n"
-	$PKG list -af pkg://$publisher/$entire_fmri > /dev/null 2>&1
+	LC_ALL=C $PKG list -af pkg://$publisher/$entire_fmri > /dev/null 2>&1
 	if [[ $? -ne 0 ]]; then
 		fail_fatal "$f_no_entire_in_pref" $entire_fmri $publisher
 	fi
@@ -494,11 +493,11 @@
 # hopefully go away once "primordial" actions arrive.
 #
 if [[ -n $entire_fmri ]]; then
-	$PKG install -q --no-refresh --no-index $entire_fmri || \
+	LC_ALL=C $PKG install -q --no-refresh --no-index $entire_fmri || \
 	    pkg_err_check "$f_pkg"
 fi
-$PKG install --no-refresh --no-index SUNWcsd || pkg_err_check "$f_pkg"
-$PKG install --no-refresh --no-index SUNWcs || pkg_err_check "$f_pkg"
+LC_ALL=C $PKG install --no-refresh --no-index SUNWcsd || pkg_err_check "$f_pkg"
+LC_ALL=C $PKG install --no-refresh --no-index SUNWcs || pkg_err_check "$f_pkg"
 
 printf "$m_more\n"
 pkglist=""
@@ -558,7 +557,7 @@
 # Do the install; we just refreshed on image-create, so skip that.  We
 # also skip indexing here, as that is also what the LiveCD does.
 #
-$PKG install --no-index --no-refresh $pkglist || pkg_err_check "$f_pkg"
+LC_ALL=C $PKG install --no-index --no-refresh $pkglist || pkg_err_check "$f_pkg"
 
 printf "\n$m_mannote\n"