src/brand/pkgcreatezone
changeset 1504 265a1d6b86bd
parent 1493 625950c12e71
child 1516 8c950a3b4171
--- a/src/brand/pkgcreatezone	Tue Nov 17 14:25:48 2009 -0800
+++ b/src/brand/pkgcreatezone	Tue Nov 17 17:06:35 2009 -0600
@@ -58,9 +58,9 @@
 m_incorp=$(gettext      "Sanity Check: Looking for 'entire' incorporation.\n")
 m_key_prop=$(gettext    " Credentials: Propagating %s\n")
 m_cert_prop=$(gettext   " Credentials: Propagating %s\n")
-m_core=$(gettext        "  Installing: Core System (output follows)\n")
-m_more=$(gettext        "  Installing: Additional Packages (output follows)\n")
-m_smf=$(gettext	        " Postinstall: Copying SMF seed repository ...")
+m_core=$(gettext	"  Installing: Core System (output follows)\n")
+m_more=$(gettext	"  Installing: Additional Packages (output follows)\n")
+m_smf=$(gettext		" Postinstall: Copying SMF seed repository ...")
 m_more_brokenness=$(gettext " Postinstall: Applying workarounds.")
 m_mannote=$(gettext     "        Note: Man pages can be obtained by installing SUNWman")
 
@@ -79,7 +79,8 @@
 extra_packages=""
 ZONENAME=""
 ZONEPATH=""
-pub_and_url=""
+pub_and_origins=""
+pub_and_mirrors=""
 
 # Setup i18n output
 TEXTDOMAIN="SUNW_OST_OSCMD"
@@ -105,19 +106,19 @@
 	case $opt in
 		a)	# We're expecting a path to an archive
 			if [[ ! -f $OPTARG ]]; then
-			 	# If old style 'pub=uri' parameter then error.
+				# If old style 'pub=uri' parameter then error.
 				echo $OPTARG | egrep -s =
 				if (( $? == 0 )); then
 					fail_usage "$f_a_obs"
 				fi
 			fi
-		 	install_archive="-a $OPTARG";;
+			install_archive="-a $OPTARG";;
 		c)	certfile="$OPTARG" ;;
-		d) 	source_dir="-d $OPTARG";;
+		d)	source_dir="-d $OPTARG";;
 		e)	extra_packages="$extra_packages $OPTARG" ;;
 		h)	fail_usage "";;
 		k)	keyfile="$OPTARG" ;;
-		P)	pub_and_url="$OPTARG" ;;
+		P)	pub_and_origins="$OPTARG" ;;
 		p)	preserve_zone="-p";;
 		R)	ZONEPATH="$OPTARG" ;;
 		s)	silent_mode=1;;
@@ -158,7 +159,8 @@
 
 # IPS options aren't allowed when installing from a system image.
 if [[ -n "$install_archive" || -n "$source_dir" ]]; then
-	[[ -n $pub_and_url ]] && fail_usage "$f_incompat_options" "-a|-d" "-P"
+	[[ -n $pub_and_origins ]] && fail_usage "$f_incompat_options" \
+	    "-a|-d" "-P"
 	[[ -n "$extra_packages" ]] && \
 	    fail_usage "$f_incompat_options" "-a|-d" "-e"
 	[[ "$certfile" != "None" ]] && \
@@ -179,7 +181,7 @@
 #
 propagate_secinfo=
 propagate_extra=
-if [[ -z $pub_and_url ]]; then
+if [[ -z $pub_and_origins ]]; then
 	if [[ $keyfile != "None" ]]; then
 		fail_usage "$f_key_file"
 	fi
@@ -187,12 +189,17 @@
 		fail_usage "$f_cert_file"
 	fi
 
-	# We look for a preferred online origin.
-	tpub_and_url=`LC_ALL=C $PKG publisher -PH | \
-	    awk '$2 == "origin" && $3 == "online" \
-	    {printf "%s=%s\n", $1, $4; exit 0;}'`
+	# Look for a preferred online origin.
+	tpub_and_origins=$(get_publisher_urls preferred origin)
+	[[ $? -eq 0 && -n $tpub_and_origins ]] && \
+	    pub_and_origins="$tpub_and_origins"
 
-	[[ $? -eq 0 && -n $tpub_and_url ]] && pub_and_url="$tpub_and_url"
+	# Get preferred mirror information as well if the above succeeded.
+	if [[ -n "$tpub_and_origins" ]]; then
+		tpub_and_mirrors=$(get_publisher_urls preferred mirror)
+		[[ $? -eq 0 && -n $tpub_and_mirrors ]] && \
+		    pub_and_mirrors="$tpub_and_mirrors"
+	fi
 
 	# Note that later we need to propagate key & cert.
 	propagate_secinfo=1
@@ -203,25 +210,43 @@
 	#
 	propagate_extra=1
 fi
-[[ -z $pub_and_url ]] && fail_usage "$f_no_pref_publisher"
+[[ -z $pub_and_origins ]] && fail_usage "$f_no_pref_publisher"
 
 # find the remaining publishers in the global zone
-publishers_extra=""
+publishers_extra_origins=""
+publishers_extra_mirrors=""
+
 if [[ -n $propagate_extra ]]; then
-	LC_ALL=C $PKG publisher -H | awk '
-		$2 == "origin" && $3 == "online" {printf "%s=%s\n", $1, $4}
-		END {exit(0)}
-	' | while IFS== read publisher publisherurl; do
-		[[ "$publisher=$publisherurl" = "$pub_and_url" ]] && continue
+
+	# If cert and key information are ever allowed at the origin or
+	# mirror level, then this will have to be changed.
+	get_publisher_urls non-preferred origin | \
+	    while IFS="=" read pub pub_urls; do
+		# skip extra publishers that need a key/cert
+		[[ "`get_pub_secinfo $pub`" != "None None" ]] && \
+		    continue
 
-		# skip extra publishers that need a key
-		[[ "`get_pub_secinfo $publisher`" != "None None" ]] && continue
+		if [[ -z "$publishers_extra_origins" ]]; then
+			publishers_extra_origins="$pub=$pub_urls"
+		else
+			publishers_extra_origins=`printf "%s\n%s" \
+			    "$pub=$pub_urls" \
+			    "$publishers_extra_origins"`
+		fi
+	done
 
-		if [[ -z "$publishers_extra" ]]; then
-			publishers_extra="$publisher=$publisherurl"
+	get_publisher_urls non-preferred mirror | \
+	    while IFS="=" read pub pub_urls; do
+		# skip extra publishers that need a key/cert
+		[[ "`get_pub_secinfo $pub`" != "None None" ]] && \
+		    continue
+
+		if [[ -z "$publishers_extra_mirrors" ]]; then
+			publishers_extra_mirrors="$pub=$pub_urls"
 		else
-			publishers_extra=`printf "%s\n%s" \
-			    "$publisher=$publisherurl" "$publishers_extra"`
+			publishers_extra_mirrors=`printf "%s\n%s" \
+			    "$pub=$pub_urls" \
+			    "$publishers_extra_mirrors"`
 		fi
 	done
 fi
@@ -229,10 +254,11 @@
 #
 # Crack pub=url into two pieces.
 #
-echo $pub_and_url | IFS== read publisher publisherurl
-if [[ -z $publisher || -z $publisherurl ]]; then
+echo $pub_and_origins | IFS="=" read publisher pub_origins
+if [[ -z $publisher || -z $pub_origins ]]; then
 	fail_usage "$f_bad_publisher"
 fi
+echo $pub_and_mirrors | IFS="=" read ignored pub_mirrors
 
 if [[ -n $propagate_secinfo ]]; then
 	#
@@ -286,11 +312,22 @@
 	exit $ZONE_SUBPROC_OK
 fi
 
-printf "$m_publisher\n" $publisher $publisherurl
-echo "$publishers_extra" | while IFS== read publisher publisherurl; do
-	[ -z "$publisher" ] && break
-	printf "$m_publisher\n" $publisher $publisherurl
-done
+# Display preferred publisher origin and mirror information.
+printf "$m_publisher\n" $publisher "$pub_origins $pub_mirrors"
+
+# Display extra publisher origin and mirror information.  This does mean that
+# the extras have to be displayed twice to show mirror information.
+if [[ -n "$publishers_extra_origins" ]]; then
+	echo "$publishers_extra_origins" | while IFS="=" read pub pub_urls; do
+		printf "$m_publisher\n" $pub "$pub_urls"
+	done
+	if [[ -n "$publishers_extra_mirrors" ]]; then
+		echo "$publishers_extra_mirrors" | while IFS="=" read pub pub_urls; do
+			printf "$m_publisher\n" $pub "$pub_urls"
+		done
+	fi
+fi
+
 printf "$m_image\n" $ZONEROOT
 
 #
@@ -321,21 +358,78 @@
 # we must pass the -f (force) option to image-create, since it thinks that
 # something must be wrong, as the image exists.
 #
-# XXX in the future, we can create the image --no-refresh, then
-# set the publisher.  But image-create --no-refresh is broken right now.
+pub_first_origin=""
+pub_add_origins=""
+for origin in $pub_origins; do
+	if [[ -z "$pub_first_origin" ]]; then
+		# The first origin is semi-special in that the publisher
+		# argument to image-create requires it to be specified
+		# by itself and then any additional origins after that.
+		# Technically, image-create doesn't care if you specify
+		# the first one again using -g, but there's no point in
+		# doing so.
+		pub_first_origin=$origin
+		continue
+	fi
+	pub_add_origins="${pub_add_origins}-g $origin "
+done
+
+pub_add_mirrors=""
+for mirror in $pub_mirrors; do
+	pub_add_mirrors="${pub_add_mirrors}-m $mirror "
+done
+
 #
-$PKG image-create -f --zone --full -p "$pub_and_url" $secinfo $ZONEROOT || \
-    fail_incomplete "$f_img"
+# The image is created with --no-refresh so that all of the publisher
+# configuration can be put into place first before attempting to retrieve
+# and build catalog information.  This substantially reduces the amount of
+# time needed to create a zone.
+#
+$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"
 
 PKG_IMAGE="$ZONEROOT"
 export PKG_IMAGE
 
 # add extra publishers
-echo "$publishers_extra" | while IFS== read publisher publisherurl; do
-	[ -z "$publisher" ] && break
-	$PKG set-publisher -O $publisherurl $publisher ||
-		fail_incomplete "$f_img"
-done
+# If cert and key information are ever allowed at the origin or
+# mirror level, then this will have to be changed.
+if [[ -n "$publishers_extra_origins" ]]; then
+	echo "$publishers_extra_origins" | while IFS="=" read pub pub_urls; do
+		pub_prefix=$pub
+		pub_add_origins=""
+		for origin in $pub_urls; do
+			pub_add_origins="${pub_add_origins}-g $origin "
+		done
+
+		# --no-refresh is used here so that update operations can be
+		# coalesced.
+		$PKG set-publisher --no-refresh \
+                    ${pub_add_origins}${pub_prefix} || fail_incomplete "$f_img"
+	done
+
+	if [[ -n "$publishers_extra_mirrors" ]]; then
+		echo "$publishers_extra_mirrors" | \
+		    while IFS="=" read pub pub_urls; do
+			pub_prefix=$pub
+			pub_add_mirrors=""
+			for mirror in $pub_urls; do
+				pub_add_mirrors="${pub_add_mirrors}-m $mirror "
+			done
+
+			# --no-refresh is used here so that update operations
+			# can be coalesced.
+			$PKG set-publisher --no-refresh \
+			    ${pub_add_mirrors}${pub_prefix} || \
+			    fail_incomplete "$f_img"
+		done
+	fi
+fi
+
+# 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"
 
 if [ -d /var/pkg/download ]; then
 	PKG_CACHEDIR=/var/pkg/download
@@ -355,7 +449,6 @@
 # the system, we can't do this test without first configuring the image.
 #
 printf "$m_incorp\n"
-echo $pub_and_url | IFS== read publisher publisherurl
 $PKG list -a pkg://$publisher/$entire_fmri > /dev/null 2>&1
 if [[ $? -ne 0 ]]; then
 	fail_fatal "$f_no_entire_in_pref" $entire_fmri $publisher