--- 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