11684 desire option to not propagate certs to non-global zones (remove brand script changes)
--- a/src/brand/Makefile Thu Apr 28 11:44:04 2011 -0700
+++ b/src/brand/Makefile Thu Apr 28 12:52:19 2011 -0700
@@ -51,12 +51,10 @@
$(ROOTETCBRAND)/smf_disable.conf \
$(ROOTETCZONES)/SUNWipkg.xml \
$(ROOTBRANDPKG)/attach \
- $(ROOTBRANDPKG)/boot \
$(ROOTBRANDPKG)/clone \
$(ROOTBRANDPKG)/common.ksh \
$(ROOTBRANDPKG)/detach \
$(ROOTBRANDPKG)/fmri_compare \
- $(ROOTBRANDPKG)/halt \
$(ROOTBRANDPKG)/image_install \
$(ROOTBRANDPKG)/p2v \
$(ROOTBRANDPKG)/pkgcreatezone \
--- a/src/brand/attach Thu Apr 28 11:44:04 2011 -0700
+++ b/src/brand/attach Thu Apr 28 12:52:19 2011 -0700
@@ -34,6 +34,7 @@
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_need_nonsticky=$(gettext " Evaluation: Publisher %s in zone %s needs to be set to non-sticky")
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.")
@@ -50,6 +51,9 @@
f_sanity_variant=$(gettext " Sanity Check: FAILED, couldn't determine %s from image.")
f_sanity_global=$(gettext " Sanity Check: FAILED, appears to be a global zone (%s=%s).")
f_update=$(gettext "Could not update attaching zone")
+f_no_pref_publisher=$(gettext "Unable to get preferred publisher information for zone '%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")
f_ds_config=$(gettext "Failed to configure dataset %s: could not set %s.")
f_no_active_ds_mounted=$(gettext "Failed to locate any dataset mounted at %s. Attach requires a mounted dataset.")
f_nonsticky=$(gettext "Could not set legacy publisher to non-sticky")
@@ -144,9 +148,129 @@
# 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}
+ elif [[ "$origin" == "None" ]]; then
+ # Publisher with no origins.
+ origin=""
+ 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
+ if [[ -n "$origin" ]]; then
+ 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}
+ else
+ # Publisher has no origins.
+ publisher.keyfile="None"
+ publisher.certfile="None"
+ fi
+ 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.
#
@@ -161,6 +285,47 @@
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
@@ -211,11 +376,6 @@
exit $ZONE_SUBPROC_OK
fi
-enable_zones_services
-if [[ $? -ne 0 ]]; then
- exit $ZONE_SUBPROC_NOTCOMPLETE
-fi
-
LOGFILE=$(/usr/bin/mktemp -t -p /var/tmp ${zone.name}.attach_log.XXXXXX)
if [[ -z "$LOGFILE" ]]; then
fatal "$e_tmpfile"
@@ -244,6 +404,28 @@
# Check that the variant is non-global, else fail
[[ $variantval = "nonglobal" ]] || fatal "$f_sanity_global" $VARIANT $variantval
+# 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.
+
+#
+# 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.
+#
+gz_publisher_pref=$(get_preferred_publisher gz_publishers)
+
+if [[ $? -ne 0 ]]; then
+ fail_usage "$f_no_pref_publisher" "global"
+fi
+
+vlog "Preferred global publisher: $gz_publisher_pref"
#
# Try to find the "entire" incorporation's FMRI in the gz.
@@ -304,9 +486,69 @@
fi
#
-# Set the use-system-repo property.
+# 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
+
+LC_ALL=C $PKG set-publisher --no-refresh -P -g http://localhost:10000 $ZNAME
+for key in ${!gz_publishers[*]}; do
+ typeset newloc=""
+
+ args=$(print_publisher_pkg_defn gz_publishers $key)
+
+ # Copy credentials from global zone.
+ safe_dir var
+ safe_dir var/pkg
+
+ eval publisher="${gz_publishers[$key]}"
+ if [[ ${publisher.keyfile} != "None" || \
+ ${publisher.certfile} != "None" ]]; then
+ if [[ -e $ZONEROOT/$KEYDIR ]]; then
+ safe_dir $KEYDIR
+ else
+ mkdir -m 755 $ZONEROOT/$KEYDIR
+ fi
+ fi
+
+ if [[ ${publisher.keyfile} != "None" ]]; then
+ relnewloc="$KEYDIR/$(basename ${publisher.keyfile})"
+ newloc="$ZONEROOT/$relnewloc"
+ safe_copy ${publisher.keyfile} $newloc
+ chmod 644 $newloc
+ chown -h root:root $newloc
+ args="$args -k $relnewloc"
+ fi
+ if [[ ${publisher.certfile} != "None" ]]; then
+ relnewloc="$KEYDIR/$(basename ${publisher.certfile})"
+ newloc="$ZONEROOT/$relnewloc"
+ safe_copy ${publisher.certfile} $newloc
+ chmod 644 $newloc
+ chown -h root:root $newloc
+ args="$args -c $relnewloc"
+ fi
+ LC_ALL=C $PKG unset-publisher $key >/dev/null 2>&1
+ LC_ALL=C $PKG set-publisher $args $key
+
+done
+
#
-LC_ALL=C $PKG set-property use-system-repo true
+# Now remove our temporary publisher
+#
+LC_ALL=C $PKG unset-publisher $ZNAME
+
+#
+# Make sure that the solaris publisher can update packages that first
+# came from opensolaris.org.
+#
+if [[ $allow_update == 1 ]] && \
+ $PKG publisher opensolaris.org >/dev/null 2>&1; then
+ LC_ALL=C $PKG set-publisher --no-refresh --non-sticky \
+ opensolaris.org || pkg_err_check "$f_nonsticky"
+fi
#
# Bring the ngz entire incorporation into sync with the gz as follows:
@@ -329,7 +571,7 @@
fi
if [[ $allow_update == 0 ]]; then
- LC_ALL=C $PKG install --accept -n $incorp_list
+ LC_ALL=C $PKG install --accept --no-refresh -n $incorp_list
if [[ $? == 4 ]]; then
log "\n$m_complete"
EXIT_CODE=$ZONE_SUBPROC_OK
@@ -348,11 +590,11 @@
# same version as we have in the GZ.
#
if [[ -n $gz_entire_fmri && -z $ngz_entire_fmri ]]; then
- LC_ALL=C $PKG install --accept entire || \
+ LC_ALL=C $PKG install --accept --no-refresh entire || \
pkg_err_check "$f_update"
fi
-LC_ALL=C $PKG install --accept $incorp_list || \
+LC_ALL=C $PKG install --accept --no-refresh $incorp_list || \
pkg_err_check "$f_update"
log "\n$m_sync_done"
--- a/src/brand/boot Thu Apr 28 11:44:04 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-#!/bin/ksh -p
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
-#
-
-. /usr/lib/brand/ipkg/common.ksh
-
-ZONENAME=$1
-ZONEPATH=$2
-
-enable_zones_services
-if [[ $? -ne 0 ]]; then
- exit $ZONE_SUBPROC_NOTCOMPLETE
-fi
-
-/usr/lib/zones/zpadm $ZONENAME
-if [[ $? -ne 0 ]]; then
- exit $ZONE_SUBPROC_NOTCOMPLETE
-fi
--- a/src/brand/common.ksh Thu Apr 28 11:44:04 2011 -0700
+++ b/src/brand/common.ksh Thu Apr 28 12:52:19 2011 -0700
@@ -57,9 +57,6 @@
f_cp=$(gettext "Failed to cp %s %s.")
f_cp_unsafe=$(gettext "Failed to safely copy %s to %s.")
-f_sysrepo_fail=$(gettext "Unable to enable svc:/system/pkg/sysrepo, please enable the service manually.")
-f_zones_proxyd_fail=$(gettext "Unable to enable svc:/system/zones-proxyd, please enable the service manually.")
-
m_brnd_usage=$(gettext "brand-specific usage: ")
v_unconfig=$(gettext "Performing zone sys-unconfig")
@@ -287,6 +284,130 @@
}
#
+# Emits to stdout the extended attributes for a publisher. The
+# attributes are emitted in the order "sticky preferred enabled". It
+# expects two parameters: publisher name and URL type which can be
+# ("mirror" or "origin").
+#
+get_publisher_attrs() {
+ typeset pname=$1
+ typeset utype=$2
+
+ LC_ALL=C $PKG publisher -HF tsv| \
+ nawk '($5 == "'"$utype"'" || \
+ ("'"$utype"'" == "origin" && $5 == "")) \
+ && $1 == "'"$pname"'" \
+ {printf "%s %s %s\n", $2, $3, $4;}'
+ return 0
+}
+
+#
+# Emits to stdout the extended attribute arguments for a publisher. It
+# expects two parameters: publisher name and URL type which can be
+# ("mirror" or "origin").
+#
+get_publisher_attr_args() {
+ typeset args=
+ typeset sticky=
+ typeset preferred=
+ typeset enabled=
+
+ get_publisher_attrs $1 $2 |
+ while IFS=" " read sticky preferred enabled; do
+ if [ $sticky == "true" ]; then
+ args="--sticky"
+ else
+ args="--non-sticky"
+ fi
+
+ if [ $preferred == "true" ]; then
+ args="$args -P"
+ fi
+
+ if [ $enabled == "true" ]; then
+ args="$args --enable"
+ else
+ args="$args --disable"
+ fi
+ done
+ echo $args
+
+ return 0
+}
+
+#
+# Emits to stdout the publisher's prefix followed by a '=', and then
+# 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".)
+#
+get_publisher_urls() {
+ typeset ptype=$1
+ typeset utype=$2
+ typeset __pub_prefix=
+ typeset __publisher_urls=
+ typeset ptype_filter=
+
+ if [ "$ptype" == "all" ]
+ then
+ ptype_filter=""
+ elif [ "$ptype" == "preferred" ]
+ then
+ ptype_filter="true"
+ elif [ "$ptype" == "non-preferred" ]
+ then
+ ptype_filter="false"
+ fi
+
+ LC_ALL=C $PKG publisher -HF tsv | \
+ nawk '($5 == "'"$utype"'" || \
+ ("'"$utype"'" == "origin" && $5 == "")) && \
+ ( "'"$ptype_filter"'" == "" || $3 == "'"$ptype_filter"'" ) \
+ {printf "%s %s\n", $1, $7;}' |
+ while IFS=" " read __publisher __publisher_url; do
+ if [[ "$utype" == "origin" && \
+ -z "$__publisher_url" ]]; then
+ # Publisher without origins.
+ __publisher_url="None"
+ fi
+
+ if [[ -n "$__pub_prefix" && \
+ "$__pub_prefix" != "$__publisher" ]]; then
+ # Different publisher so emit accumulation and
+ # clear existing data.
+ echo $__pub_prefix=$__publisher_urls
+ __publisher_urls=""
+ fi
+ __pub_prefix=$__publisher
+ __publisher_urls="$__publisher_urls$__publisher_url "
+ done
+
+ if [[ -n "$__pub_prefix" && -n "$__publisher_urls" ]]; then
+ echo $__pub_prefix=$__publisher_urls
+ fi
+
+ return 0
+}
+
+#
+# Emit to stdout the key and cert associated with the publisher
+# name provided. Returns 'None' if no information is present.
+# For now we assume that the mirrors all use the same key and cert
+# 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 |
+ nawk -F': ' '/SSL Cert/ {print $2; exit 0}')
+ print $key $cert
+}
+
+#
# Handle pkg exit code. Exit 0 means Command succeeded, exit 4 means
# No changes were made - nothing to do. Any other exit code is an error.
#
@@ -294,20 +415,3 @@
typeset res=$?
(( $res != 0 && $res != 4 )) && fail_fatal "$1"
}
-
-#
-# Enable the services needed to perform packaging operations inside a zone.
-#
-enable_zones_services() {
- /usr/sbin/svcadm enable -t -s /system/pkg/sysrepo
- if [[ $? -ne 0 ]]; then
- error "$f_sysrepo_fail"
- return 1
- fi
- /usr/sbin/svcadm enable -t -s /system/zones-proxyd
- if [[ $? -ne 0 ]]; then
- error "$f_zones_proxyd_fail"
- return 1
- fi
- return 0
-}
--- a/src/brand/halt Thu Apr 28 11:44:04 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-#!/bin/ksh -p
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
-#
-
-. /usr/lib/brand/ipkg/common.ksh
-
-ZONENAME=$1
-ZONEPATH=$2
-
-/usr/lib/zones/zpadm -R $ZONENAME
-if [[ $? -ne 0 ]]; then
- exit $ZONE_SUBPROC_NOTCOMPLETE
-fi
--- a/src/brand/p2v Thu Apr 28 11:44:04 2011 -0700
+++ b/src/brand/p2v Thu Apr 28 12:52:19 2011 -0700
@@ -477,8 +477,6 @@
log "$v_change_var"
pkg -R $ZONEROOT change-variant variant.opensolaris.zone=nonglobal || \
fatal "$e_change_var"
-# Set the property which tells the image to use the system publisher.
-pkg -R $ZONEROOT set-property use-system-repo true
#
# Run update on attach. State is currently 'incomplete' so use the private
--- a/src/brand/pkgcreatezone Thu Apr 28 11:44:04 2011 -0700
+++ b/src/brand/pkgcreatezone Thu Apr 28 12:52:19 2011 -0700
@@ -35,20 +35,34 @@
. /usr/lib/brand/ipkg/common.ksh
-f_a_obs=$(gettext "-a publisher=uri option is obsolete.")
+f_a_obs=$(gettext "-a publisher=uri option is obsolete, use -P instead.")
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.")
+f_key_file=$(gettext "Key file not allowed without -P")
+f_cert_file=$(gettext "Cert file not allowed without -P")
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.")
+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")
+f_key_prop=$(gettext "Unable to propagate key %s to %s")
+f_cert_prop=$(gettext "Unable to propagate cert %s to %s")
+f_get_secinfo=$(gettext "Failed to get key/cert information for publisher %s")
+f_nosuch_key=$(gettext "Failed to find key %s")
+f_nosuch_cert=$(gettext "Failed to find cert %s")
+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_key_prop=$(gettext " Credentials: Propagating %s\n")
+m_cert_prop=$(gettext " Credentials: Propagating %s\n")
m_core=$(gettext " Installing: 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 pkg:/system/manual")
-m_usage=$(gettext "\n install [-h]\n install\n [-e extrapkg [...]]\n install {-a archive|-d path} {-p|-u} [-s|-v]")
+m_usage=$(gettext "\n install [-h]\n install [-c certificate_file] [-k key_file] [-P publisher=uri]\n [-e extrapkg [...]]\n install {-a archive|-d path} {-p|-u} [-s|-v]")
m_done=$(gettext " done.")
@@ -63,26 +77,30 @@
extra_packages=""
ZONENAME=""
ZONEPATH=""
+pub_and_origins=""
+pub_and_mirrors=""
# Setup i18n output
TEXTDOMAIN="SUNW_OST_OSCMD"
export TEXTDOMAIN
+KEYDIR=/var/pkg/ssl
PKG=/usr/bin/pkg
-export PKG
#
# Just in case. This should probably be removed later.
#
[[ ! -x $PKG ]] && fail_incomplete "$f_pkg5_missing"
+certfile="None"
+keyfile="None"
unset install_archive
unset source_dir
unset msg
unset silent_mode
unset verbose_mode
-while getopts "a:d:e:hpR:suvz:" opt; do
+while getopts "a:c:d:e:hk:P:pR:suvz:" opt; do
case $opt in
a) # We're expecting a path to an archive
if [[ ! -f $OPTARG ]]; then
@@ -93,9 +111,12 @@
fi
fi
install_archive="-a $OPTARG";;
+ c) certfile="$OPTARG" ;;
d) source_dir="-d $OPTARG";;
e) extra_packages="$extra_packages $OPTARG" ;;
h) fail_usage "";;
+ k) keyfile="$OPTARG" ;;
+ P) pub_and_origins="$OPTARG" ;;
p) preserve_zone="-p";;
R) ZONEPATH="$OPTARG" ;;
s) silent_mode=1;;
@@ -118,6 +139,8 @@
is_brand_labeled
brand_labeled=$?
+secinfo=""
+
# An image install can't use both -a AND -d...
[[ -n "$install_archive" && -n "$source_dir" ]] &&
fail_usage "$f_incompat_options" "-a" "-d"
@@ -132,8 +155,14 @@
# IPS options aren't allowed when installing from a system image.
if [[ -n "$install_archive" || -n "$source_dir" ]]; then
+ [[ -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" ]] && \
+ fail_usage "$f_incompat_options" "-a|-d" "-c"
+ [[ "$keyfile" != "None" ]] && \
+ fail_usage "$f_incompat_options" "-a|-d" "-k"
fi
# p2v options aren't allowed when installing from a repo.
@@ -143,6 +172,113 @@
fi
#
+# If the user didn't give us a publisher, and there's a preferred publisher set
+# for the system, set that as the default.
+#
+propagate_secinfo=
+propagate_extra=
+if [[ -z $pub_and_origins ]]; then
+ if [[ $keyfile != "None" ]]; then
+ fail_usage "$f_key_file"
+ fi
+ if [[ $certfile != "None" ]]; then
+ fail_usage "$f_cert_file"
+ fi
+
+ # 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"
+
+ # 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
+
+ #
+ # since the user didn't specify a publisher, propagate all the
+ # publishers that don't have a key.
+ #
+ propagate_extra=1
+fi
+[[ -z $pub_and_origins ]] && fail_usage "$f_no_pref_publisher"
+
+# find the remaining publishers in the global zone
+publishers_extra_origins=""
+publishers_extra_mirrors=""
+
+if [[ -n $propagate_extra ]]; then
+
+ # 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
+ if [[ "$pub_urls" != "None" ]]; then
+ # skip extra publishers that need a key/cert
+ [[ "`get_pub_secinfo $pub`" != "None None" ]] && \
+ continue
+ else
+ pub_urls=""
+ fi
+
+ if [[ -z "$publishers_extra_origins" ]]; then
+ publishers_extra_origins="$pub=$pub_urls"
+ else
+ publishers_extra_origins=$(printf "%s\n%s" \
+ "$publishers_extra_origins" \
+ "$pub=$pub_urls")
+ fi
+ done
+
+ 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_mirrors=$(printf "%s\n%s" \
+ "$publishers_extra_mirrors" \
+ "$pub=$pub_urls")
+ fi
+ done
+fi
+
+#
+# Crack pub=url into two pieces.
+#
+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
+ #
+ # Get the global zone's cert and key (if any) so that we can propagate
+ # them into the new image.
+ #
+ get_pub_secinfo $publisher | read keyfile certfile
+ if [[ $? -ne 0 ]]; then
+ fail_usage "$f_get_secinfo" $publisher
+ fi
+fi
+#
+# Do some sanity checks on key and cert.
+#
+[[ $keyfile != "None" && ! -f $keyfile ]] && \
+ fail_usage "$f_nosuch_key" $keyfile
+[[ $certfile != "None" && ! -f $certfile ]] && \
+ fail_usage "$f_nosuch_cert" $certfile
+
+#
# 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.
@@ -173,26 +309,182 @@
exit $ZONE_SUBPROC_OK
fi
+# 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
-enable_zones_services
-if [[ $? -ne 0 ]]; then
- exit $ZONE_SUBPROC_NOTCOMPLETE
+#
+# We copy the credentials from the global zone into the new image
+# we're about to create.
+#
+if [[ $keyfile != "None" ]]; then
+ newkeylocation="$KEYDIR/$(basename $keyfile)"
+ secinfo="$secinfo -k $newkeylocation"
+ printf "$m_key_prop\n" $(basename $keyfile)
+ mkdir -p -m 755 $ZONEROOT/$KEYDIR || fail_fatal "$f_key_prop"
+ cp $keyfile $ZONEROOT/$newkeylocation || fail_fatal "$f_key_prop"
+ chmod 644 $ZONEROOT/$newkeylocation
+ chown -h root:root $ZONEROOT/$newkeylocation
+fi
+if [[ $certfile != "None" ]]; then
+ newcertlocation="$KEYDIR/$(basename $certfile)"
+ secinfo="$secinfo -c $newcertlocation"
+ printf "$m_cert_prop\n" $(basename $certfile)
+ mkdir -p -m 755 $ZONEROOT/$KEYDIR || fail_fatal "$f_cert_prop"
+ cp $certfile $ZONEROOT/$newcertlocation || fail_fatal "$f_cert_prop"
+ chmod 644 $ZONEROOT/$newcertlocation
+ chown -h root:root $ZONEROOT/$newcertlocation
fi
#
-# The image is created.
+# Regrettably, since we already copied the key information into place,
+# we must pass the -f (force) option to image-create, since it thinks that
+# something must be wrong, as the image exists.
#
-LC_ALL=C $PKG image-create --zone --full \
- --set-property use-system-repo=true \
+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
+
+#
+# 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.
+#
+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"
+# Retrieve publisher attributes and update our new publisher
+attrs=$(get_publisher_attr_args $publisher "origin")
+
# Change the value of PKG_IMAGE so that future PKG operation will work
# on the newly created zone rather than the global zone
PKG_IMAGE="$ZONEROOT"
export PKG_IMAGE
+# --no-refresh is used here so that update operations can be
+# coalesced.
+# Update our new publisher
+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
+# 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
+
+ # Retrieve publisher attributes. Since we are retrieving
+ # these attributes from the GLOBAL zone, we must reset
+ # PKG_IMAGE temporarily
+ SAVE_PKG_IMAGE=$PKG_IMAGE
+ PKG_IMAGE=$GZ_IMAGE
+ export PKG_IMAGE
+ attrs=$(get_publisher_attr_args $pub_prefix "origin")
+ # Now restore the save PKG_IMAGE value
+ PKG_IMAGE=$SAVE_PKG_IMAGE
+ export PKG_IMAGE
+ # --no-refresh is used here so that update operations can be
+ # coalesced.
+ LC_ALL=C $PKG set-publisher --no-refresh $attrs \
+ ${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
+
+ # Retrieve publisher attributes. Since we are retrieving
+ # these attributes from the GLOBAL zone, we must reset
+ # PKG_IMAGE temporarily
+ SAVE_PKG_IMAGE=$PKG_IMAGE
+ PKG_IMAGE=$GZ_IMAGE
+ export PKG_IMAGE
+ attrs=$(get_publisher_attr_args $pub_prefix "mirror")
+ PKG_IMAGE=$SAVE_PKG_IMAGE
+ export PKG_IMAGE
+ # --no-refresh is used here so that update operations
+ # can be coalesced.
+ LC_ALL=C $PKG set-publisher --no-refresh $attrs \
+ ${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.
+LC_ALL=C $PKG refresh || fail_incomplete "$f_img"
+
+if [[ -f /var/pkg/pkg5.image && -d /var/pkg/publisher ]]; then
+ PKG_CACHEROOT=/var/pkg/publisher
+ export PKG_CACHEROOT
+ printf "$m_cache\n" $PKG_CACHEROOT
+fi
+
+#
+# If we found an "entire" incorporation in the current image, then
+# 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.
+#
+if [[ -n $entire_fmri ]]; then
+ printf "$m_incorp\n"
+ 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
+fi
+
printf "$m_core\n"
pkglist=""
if [[ -n $entire_fmri ]]; then
@@ -210,9 +502,7 @@
pkg:///compress/gzip
pkg:///compress/zip
pkg:///compress/unzip
- pkg:///package/pkg
- pkg:///package/sysrepo
- pkg:///package/sysrepo-K"
+ pkg:///package/pkg"
#
# Get some diagnostic tools, truss, dtrace, etc.
--- a/src/pkg/manifests/system%2Fzones%2Fbrand%2Fipkg.p5m Thu Apr 28 11:44:04 2011 -0700
+++ b/src/pkg/manifests/system%2Fzones%2Fbrand%2Fipkg.p5m Thu Apr 28 12:52:19 2011 -0700
@@ -41,12 +41,10 @@
dir path=usr/lib/brand
dir path=usr/lib/brand/ipkg
file path=usr/lib/brand/ipkg/attach mode=0755
-file path=usr/lib/brand/ipkg/boot mode=0755
file path=usr/lib/brand/ipkg/clone mode=0755
file path=usr/lib/brand/ipkg/common.ksh
file path=usr/lib/brand/ipkg/detach mode=0755
file path=usr/lib/brand/ipkg/fmri_compare mode=0755
-file path=usr/lib/brand/ipkg/halt mode=0755
file path=usr/lib/brand/ipkg/image_install mode=0755
file path=usr/lib/brand/ipkg/p2v mode=0755
file path=usr/lib/brand/ipkg/pkgcreatezone mode=0755