src/brand/pkgcreatezone
changeset 954 8614b0c63fb3
parent 943 e04a1ccbeac8
child 1091 fc73bc2d78ce
--- a/src/brand/pkgcreatezone	Fri Mar 13 15:53:27 2009 -0500
+++ b/src/brand/pkgcreatezone	Wed Mar 18 18:35:27 2009 -0700
@@ -26,22 +26,31 @@
 
 . /usr/lib/brand/ipkg/common.ksh
 
-f_img=$(gettext "failed to create image")
-f_pkg=$(gettext "failed to install package")
-f_interrupted=$(gettext "Installation cancelled due to interrupt.")
+f_pkg5_missing=$(gettext "pkg(5) does not seem to be present on this system.\n")
+f_no_pref_publisher=$(gettext "Unable to get global zone preferred publisher information, and none was supplied.\nYou must specify one using the -P option.\n")
+f_img=$(gettext "failed to create image\n")
+f_pkg=$(gettext "failed to install package\n")
+f_interrupted=$(gettext "Installation cancelled due to interrupt.\n")
+f_bad_publisher=$(gettext "Syntax error in publisher information.\n")
+f_no_entire=$(gettext "Unable to find 'entire' incorporation in the global zone image.\n")
+f_no_entire_in_pref=$(gettext "Unable to locate the incorporation '%s' in the preferred publisher '%s'.\nUse -P to supply a publisher which contains this package.\n")
+
 
-m_authority=$(gettext   "  Authority: Using %s.")
-m_cache=$(gettext   "      Cache: Using %s.")
-m_image=$(gettext     "      Image: Preparing at %s ...")
-m_core=$(gettext      " Installing: (output follows)\n")
-m_smf=$(gettext	      "Postinstall: Copying SMF seed repository ...")
-m_brokenness=$(gettext "Postinstall: Working around http://defect.opensolaris.org/bz/show_bug.cgi?id=681")
-m_more_brokenness=$(gettext "Postinstall: Working around http://defect.opensolaris.org/bz/show_bug.cgi?id=741")
-m_mannote=$(gettext   "       Note: Man pages can be obtained by installing SUNWman")
-m_complete=$(gettext  "       Done: Installation completed in %s seconds.")
-m_postnote=$(gettext  " Next Steps: Boot the zone, then log into the zone console")
+m_publisher=$(gettext   "   Publisher: Using %s (%s).")
+m_cache=$(gettext       "       Cache: Using %s.")
+m_image=$(gettext       "       Image: Preparing at %s ...")
+m_incorp=$(gettext      "Sanity Check: Looking for 'entire' incorporation.\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_more_brokenness=$(gettext " Postinstall: Applying workarounds.")
+m_mannote=$(gettext     "        Note: Man pages can be obtained by installing SUNWman")
+m_complete=$(gettext    "        Done: Installation completed in %s seconds.")
+m_postnote=$(gettext    "  Next Steps: Boot the zone, then log into the zone console")
 m_postnote2=$(gettext "             (zlogin -C) to complete the configuration process")
 
+m_usage=$(gettext    "$0: [-h] [-P publisher=uri] [-e extrapkg [...]]")
+
 m_done=$(gettext      " done.")
 
 trap_cleanup() {
@@ -50,36 +59,34 @@
 }
 
 int_code=$ZONE_SUBPROC_NOTCOMPLETE
-
 trap trap_cleanup INT
 
+extra_packages=""
 zonename=""
 zonepath=""
-
-#
-# If there's a preferred authority set for the system, set that as our
-# default.  Otherwise use opensolaris.org.
-#
-authority="opensolaris.org=http://pkg.opensolaris.org"
-if [[ -x /usr/bin/pkg ]]; then
-	sysauth=`LC_ALL=C /usr/bin/pkg authority | grep preferred | awk '{printf "%s=%s", $1, $3}'`
-	if [[ $? -eq 0 && -n "$sysauth" ]]; then
-		authority=$sysauth
-	fi
-fi
+pub_and_url=""
 
 # Setup i18n output
 TEXTDOMAIN="SUNW_OST_OSCMD"
 export TEXTDOMAIN
 
+PKG=/usr/bin/pkg
+#
+# Just in case.  This should probably be removed later.
+#
+[[ ! -x $PKG ]] && fail_incomplete "$f_pkg5_missing"
 
-while getopts "a:z:R:h" opt; do
+while getopts "a:P:z:R:h:e:" opt; do
 	case $opt in
-		h)	fail_usage "$0 [-h] [-a <authority>]";;
+		h)	fail_usage "$m_usage";;
 		R)	zonepath="$OPTARG" ;;
 		z)	zonename="$OPTARG" ;;
-		a)	authority="$OPTARG" ;;
-		*)	fail_usage "$0 [-h] [-a <authority>]";;
+		a)	pub_and_url="$OPTARG";
+			print -u2 \
+			    "WARNING: -a is deprecated.  Use -P instead." ;;
+		P)	pub_and_url="$OPTARG" ;;
+		e)	extra_packages="$extra_packages $OPTARG" ;;
+		*)	fail_usage "$m_usage";;
 	esac
 done
 shift $((OPTIND-1))
@@ -92,6 +99,52 @@
 zoneroot=$zonepath/root
 
 #
+# If the user didn't give us a publisher, and there's a preferred publisher set
+# for the system, set that as the default.
+#
+if [[ -z $pub_and_url ]]; then
+	#
+	# We look for a preferred online origin.
+	#
+	tpub_and_url=`LC_ALL=C $PKG -R / publisher -PH | \
+	    awk '$2 == "origin" && $3 == "online" \
+	    {printf "%s=%s\n", $1, $4; exit 0;}'`
+
+	[[ $? -eq 0 && -n $tpub_and_url ]] && pub_and_url="$tpub_and_url"
+fi
+
+#
+# In the unlikely event that we were not able to get the system's
+# preferred publisher, and that the user didn't give us a publisher, we
+# prompt the user to provide it.
+#
+[[ -z $pub_and_url ]] && fail_usage "$f_no_pref_publisher"
+
+#
+# Crack pub=url into two pieces.
+#
+echo $pub_and_url | IFS== read publisher publisherurl
+if [[ -z $publisher || -z $publisherurl ]]; then
+	fail_usage "$f_bad_publisher"
+fi
+
+#
+# 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.
+#
+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:/@@')
+if [[ $raw_entire_fmri == "pkg://"* ]]; then
+	entire_fmri_pub=$(echo $raw_entire_fmri | sed 's@^pkg://\([^/]*\)/.*@\1@')
+fi
+
+if [[ -z $entire_fmri ]]; then
+	fail_incomplete "$f_no_entire"
+fi
+
+#
 # Before installing the zone, set up ZFS dataset hierarchy for the zone root
 # dataset.
 #
@@ -105,11 +158,16 @@
 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 
+/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
@@ -144,13 +202,12 @@
 #
 # Done setting up the zone's datasets.
 #
-
-printf "$m_authority" `echo $authority | cut -d= -f 2`
+printf "$m_publisher" $publisher $publisherurl
 printf "\n$m_image" $zoneroot
-pkg image-create -z -F -a "$authority" $zoneroot || fail_incomplete "$f_img"
+$PKG image-create --zone --full -p "$pub_and_url" $zoneroot || \
+	fail_incomplete "$f_img"
 printf "$m_done\n"
 
-entire_fmri=$(pkg list -Hv entire | nawk '{print $1}')
 
 PKG_IMAGE="$zoneroot"
 export PKG_IMAGE
@@ -160,15 +217,42 @@
 	printf "$m_cache\n" $PKG_CACHEDIR
 fi
 
+#
+# Check to see if the user's choice of preferred publisher contains the
+# version of the 'entire' incorporation needed.  This helps us to prevent
+# mishaps in the event the user selected some weirdo publisher as their
+# preferred one, or passed a preferred pub on the command line which doesn't
+# have a suitable 'entire' in it.
+#
+# n.b. it would be nice to do this before we provision the zfs dataset, etc.
+# but since the publisher specified by the user might not be known to
+# the system, we can't do this test without first configuring the image.
+#
+printf "$m_incorp\n"
+$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
+fi
+
 printf "$m_core\n"
-pkg install -q $entire_fmri || fail_incomplete "$f_pkg"
-pkg install -q SUNWcsd || fail_incomplete "$f_pkg"
+#
+# We have to take baby steps here: first, by installing entire, to
+# constrain everything.  Then, SUNWcsd, to lay down device files which
+# are subsequently needed by driver actions.  Then SUNWcs to lay down
+# /etc/passwd, /etc/group, etc so that subsequent user and group actions
+# work.  This can all hopefully go away once "primordial" actions
+# arrive.
+#
+$PKG install -q --no-refresh --no-index $entire_fmri || fail_fatal "$f_pkg"
+$PKG install -q --no-refresh --no-index SUNWcsd || fail_fatal "$f_pkg"
+$PKG install --no-refresh --no-index SUNWcs || fail_fatal "$f_pkg"
 
+printf "$m_more\n"
 pkglist=""
 pkglist="$pkglist SUNWcnetr SUNWesu SUNWadmr SUNWadmap SUNWbzip SUNWgzip"
 
 #
-# Workaround: For now, SUNWipkg has no dependencies so we must supply it python.
+# Workaround: For now, SUNWipkg has no dependency on python, so we supply it.
 #
 pkglist="$pkglist SUNWPython SUNWipkg"
 
@@ -203,8 +287,19 @@
 #
 pkglist="$pkglist SUNWdoc"
 
-# Do the install
-pkg install $pkglist || fail_incomplete "$f_pkg"
+#
+# Add in any extra packages requested by the user.
+#
+pkglist="$pkglist $extra_packages"
+
+#
+# Do the install; we just refreshed on image-create, so skip that.  We
+# also skip indexing again here, because, due to the above --no-index
+# operations, pkg(1) will decide that, before doing anything else, it must
+# build the index.  Then it'll do work, and build the index again.
+#
+$PKG install --no-index --no-refresh $pkglist || fail_fatal "$f_pkg"
+$PKG rebuild-index
 
 printf "\n$m_mannote\n"
 
@@ -236,13 +331,14 @@
 	#
 	# Set root from a role back to... not a role.  Grr.
 	#
-	print "s/^root::::type=role;/root::::/\nw" | 
+	print "s/^root::::type=role;/root::::/\nw" |
 	    ed -s $zoneroot/etc/user_attr
 fi
 
 #
 # Make sure sysidtools run; we manually poke in the SSH action
 # so that we get an SSH key.  Yes, this is seriously borken.
+# See http://defect.opensolaris.org/bz/show_bug.cgi?id=741
 #
 printf "$m_more_brokenness\n"
 /usr/sbin/sysidconfig -b $zoneroot -a /lib/svc/method/sshd