PSARC/2011/212 Zones Support for Automated Install
18013 Update pkgcreatezone to call the Automated Installer
18145 pkgcreatezone should not copy the lib/svc/seed/nonglobal.db with the integration of EMI
--- a/src/brand/attach Thu Jun 02 12:13:18 2011 +1200
+++ b/src/brand/attach Wed Jun 01 22:33:36 2011 -0700
@@ -31,7 +31,7 @@
m_attach_log=$(gettext "Log File: %s")
m_zfs=$(gettext "A ZFS file system was created for the zone.")
-m_usage=$(gettext "attach [-a archive] [-d dataset] [-r zfs-recv] [-v] [-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.\n\tThe -v option enables verbose output.")
+m_usage=$(gettext "attach [-a archive] [-d dataset] [-n] [-r zfs-recv] [-u] [-v] [-c profile | dir]\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.\n\tThe -v option enables verbose output.\n\tThe -c option gives a profile or a directory of profiles to be applied to the system after attach.")
m_attach_root=$(gettext " Attach Path: %s")
m_attach_ds=$(gettext " Attach ZFS Dataset: %s")
m_gzinc=$(gettext " Global zone version: %s")
@@ -153,6 +153,7 @@
noexecute=0
unset inst_type
+unset sc_config
# Get publisher information for global zone. These structures are used
# to store information about the global zone publishers and
@@ -163,7 +164,7 @@
#
verbose=""
# Other brand attach options are invalid for this brand.
-while getopts "a:d:n:r:uv" opt; do
+while getopts "a:c:d:n:r:uv" opt; do
case $opt in
a)
if [[ -n "$inst_type" ]]; then
@@ -172,6 +173,7 @@
inst_type="archive"
install_media="$OPTARG"
;;
+ c) sc_config="$OPTARG" ;;
d)
if [[ -n "$inst_type" ]]; then
fatal "$incompat_options" "$m_usage"
@@ -312,6 +314,8 @@
LC_ALL=C $PKG install $verbose pkg:///package/pkg/zones-proxy || \
pkg_err_check "$f_sysrepo"
+[[ -n $sc_config ]] && reconfigure_zone $sc_config
+
log "\n$m_sync_done"
log "$m_complete"
--- a/src/brand/clone Thu Jun 02 12:13:18 2011 +1200
+++ b/src/brand/clone Wed Jun 01 22:33:36 2011 -0700
@@ -24,7 +24,7 @@
. /usr/lib/brand/ipkg/common.ksh
-m_usage=$(gettext "clone {sourcezone}")
+m_usage=$(gettext "clone {sourcezone} [-c profile | dir]\n\tThe -c option gives a profile or a directory of profiles to be applied to the system after clone.")
f_nosource=$(gettext "Error: unable to determine source zone dataset.")
# Clean up on failure
@@ -39,8 +39,9 @@
}
# Source and destination zones
+unset sc_config
typeset src dst
-# Other brand clone options are invalid for this brand.
+# Brand clone options are handled below
while getopts "R:z:" opt; do
case $opt in
R) opt_R="$OPTARG" ;;
@@ -50,12 +51,22 @@
done
shift $((OPTIND-1))
-if (($# != 1)); then
- fail_usage "";
+if (($# < 1)); then
+ fail_usage ""
fi
init_zone dst "$opt_z" "$opt_R"
init_zone src "$1"
+shift
+
+let OPTIND=1
+# Other brand clone options are invalid for this brand.
+while getopts "c:" opt; do
+ case $opt in
+ c) sc_config="$OPTARG" ;;
+ *) fail_usage "";;
+ esac
+done
get_current_gzbe
get_active_be src || fatal "$e_no_active_be"
@@ -74,11 +85,11 @@
trap trap_exit EXIT
#
-# Completion of unconfigure_zone will leave the zone root mounted for
+# Completion of reconfigure_zone will leave the zone root mounted for
# ipkg brand zones. The root won't be mounted for labeled brand zones.
#
is_brand_labeled
-(( $? == 0 )) && unconfigure_zone
+(( $? == 0 )) && reconfigure_zone $sc_config
trap - EXIT
exit $ZONE_SUBPROC_OK
--- a/src/brand/common.ksh Thu Jun 02 12:13:18 2011 +1200
+++ b/src/brand/common.ksh Wed Jun 01 22:33:36 2011 -0700
@@ -63,8 +63,8 @@
m_brnd_usage=$(gettext "brand-specific usage: ")
-v_unconfig=$(gettext "Performing zone sys-unconfig")
-e_unconfig=$(gettext "sys-unconfig failed")
+v_reconfig=$(gettext "Performing zone system configuration")
+e_reconfig=$(gettext "System configuration failed")
v_mounting=$(gettext "Mounting the zone")
e_badmount=$(gettext "Zone mount failed")
v_unmount=$(gettext "Unmounting zone")
@@ -237,10 +237,11 @@
}
#
-# Run sys-unconfig on the zone.
+# Run system configuration inside a zone.
#
-unconfigure_zone() {
- vlog "$v_unconfig"
+reconfigure_zone() {
+ typeset sc_config=$1
+ vlog "$v_reconfig"
vlog "$v_mounting"
ZONE_IS_MOUNTED=1
@@ -250,17 +251,32 @@
SC_ONLINE=$(svcprop -p restarter/state \
svc:/milestone/unconfig:default 2> /dev/null)
if (( $? == 0 )) && [[ $SC_ONLINE == "online" ]]; then
- zlogin -S $ZONENAME "export _UNCONFIG_ALT_ROOT=/a; \
- /usr/sbin/sysconfig unconfigure -g system; \
- export _UNCONFIG_ALT_ROOT= ;" \
- </dev/null >/dev/null 2>&1
+ if [[ -n $sc_config ]]; then
+ safe_copy $sc_config \
+ $ZONEPATH/lu/system/volatile/$sc_config
+ zlogin -S $ZONENAME "export _UNCONFIG_ALT_ROOT=/a; \
+ /usr/sbin/sysconfig configure -g system \
+ -c /system/volatile/$sc_config;
+ export _UNCONFIG_ALT_ROOT= ;" \
+ </dev/null >/dev/null 2>&1
+ else
+ zlogin -S $ZONENAME "export _UNCONFIG_ALT_ROOT=/a; \
+ /usr/sbin/sysconfig unconfigure -g system; \
+ export _UNCONFIG_ALT_ROOT= ;" \
+ </dev/null >/dev/null 2>&1
+ fi
+ ret=$?
else
zlogin -S $ZONENAME /usr/sbin/sys-unconfig -R /a \
</dev/null >/dev/null 2>&1
+ ret=$?
+ if [[ -n $sc_config ]]; then
+ safe_copy $sc_config $ZONEPATH/lu/a/etc/sysidcfg
+ fi
fi
- if (( $? != 0 )); then
- error "$e_unconfig"
+ if (( $ret != 0 )); then
+ error "$e_reconfig"
failed=1
fi
--- a/src/brand/image_install Thu Jun 02 12:13:18 2011 +1200
+++ b/src/brand/image_install Wed Jun 01 22:33:36 2011 -0700
@@ -37,8 +37,9 @@
# Allows developer to override some things like PATH and PYTHONPATH
. /usr/lib/brand/ipkg/developerenv.ksh
+m_usage=$(gettext "\n install {-a archive|-d path} {-p|-u} [-s|-v] \
+ [-c profile | dir]")
-m_usage=$(gettext "\n install {-a archive|-d path} {-p|-u} [-s|-v]")
install_log=$(gettext " Log File: %s")
p2ving=$(gettext "Postprocessing: This may take a while...")
@@ -109,6 +110,7 @@
unset msg
unset silent_mode
unset verbose_mode
+unset OPT_C
#
# It is worth noting here that we require the end user to pick one of
@@ -120,7 +122,7 @@
unset unconfig_zone
unset preserve_zone
-while getopts "a:d:psuv" opt
+while getopts "a:c:d:psuv" opt
do
case "$opt" in
a)
@@ -130,6 +132,7 @@
inst_type="archive"
install_media="$OPTARG"
;;
+ c) OPT_C="-c $OPTARG";;
d)
if [[ -n "$inst_type" ]]; then
fatal "$both_kinds" "zoneadm install"
@@ -194,9 +197,9 @@
# to find the log file and then reopen the log (O_APPEND) when p2v is done.
#
log "$p2ving"
-vlog "running: p2v $verbose_mode $unconfig_zone $ZONENAME $ZONEPATH"
+vlog "running: p2v $verbose_mode $unconfig_zone $ZONENAME $ZONEPATH $OPT_C"
/usr/lib/brand/ipkg/p2v -l "$LOGFILE" $verbose_mode $unconfig_zone $ZONENAME \
- $ZONEPATH
+ $ZONEPATH $OPT_C
p2v_result=$?
exec 2>>$LOGFILE
--- a/src/brand/p2v Thu Jun 02 12:13:18 2011 +1200
+++ b/src/brand/p2v Wed Jun 01 22:33:36 2011 -0700
@@ -341,9 +341,11 @@
OPT_U=
OPT_V=
OPT_L=
-while getopts "b:uvl:" opt
+sc_config=
+while getopts "b:c:uvl:" opt
do
case "$opt" in
+ c) sc_config="$OPTARG";;
u) OPT_U="-u";;
v) OPT_V="-v";;
l) LOGFILE="$OPTARG"; OPT_L="-l \"$OPTARG\"";;
@@ -502,7 +504,7 @@
zoneadm -z $ZONENAME mark incomplete || fatal "$e_badupdate"
log "$v_updatedone"
-[[ -n $OPT_U ]] && unconfigure_zone
+[[ -n $OPT_U ]] && reconfigure_zone $sc_config
(( $brand_labeled == 1 )) && mount_active_be zone
--- a/src/brand/pkgcreatezone Thu Jun 02 12:13:18 2011 +1200
+++ b/src/brand/pkgcreatezone Wed Jun 01 22:33:36 2011 -0700
@@ -24,35 +24,24 @@
# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
#
-#
-# Resetting GZ_IMAGE to something besides slash allows for simplified
-# debugging of various global zone image configurations-- simply make
-# an image somewhere with the appropriate interesting parameters.
-#
-GZ_IMAGE=${GZ_IMAGE:-/}
-PKG_IMAGE=$GZ_IMAGE
-export PKG_IMAGE
-
. /usr/lib/brand/ipkg/common.ksh
# Allows developers to override some things like PATH and PYTHONPATH
. /usr/lib/brand/ipkg/developerenv.ksh
f_a_obs=$(gettext "-a publisher=uri option is obsolete.")
-f_pkg5_missing=$(gettext "pkg(5) does not seem to be present on this system.\n")
-f_img=$(gettext "failed to create image\n")
-f_imglink=$(gettext "failed to link image to global zone\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_mktemp=$(gettext "Unable to make temporary filename.")
+f_aimanifest_load=$(gettext "Unable to aimanifest load.")
+f_aimanifest_add=$(gettext "Unable to aimanifest add.")
+f_autoinstall=$(gettext "auto-install failed.")
m_image=$(gettext " Image: Preparing at %s.")
-m_core=$(gettext " Installing: Packages (output follows)\n")
-m_smf=$(gettext " Postinstall: Copying SMF seed repository ...")
+m_link=$(gettext " Postinstall: Making symlinks ...")
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 [-m manifest] [-c profile | dir]\n install {-a archive|-d path} {-p|-u} [-s|-v] [-c profile | dir]")
m_done=$(gettext " done.")
@@ -64,7 +53,8 @@
EXIT_CODE=$ZONE_SUBPROC_NOTCOMPLETE
trap trap_cleanup INT
-extra_packages=""
+manifest=""
+profile_dir=""
ZONENAME=""
ZONEPATH=""
@@ -76,11 +66,13 @@
unset install_archive
unset source_dir
-unset msg
unset silent_mode
unset verbose_mode
+unset sc_config
+unset OPT_C
+unset temp_manifest
-while getopts "a:d:e:hpR:suvz:" opt; do
+while getopts "a:c:d:hm:pR:suvz:" opt; do
case $opt in
a) # We're expecting a path to an archive
if [[ ! -f $OPTARG ]]; then
@@ -91,9 +83,11 @@
fi
fi
install_archive="-a $OPTARG";;
+ c) sc_config="$OPTARG"
+ OPT_C="-c $OPTARG" ;;
d) source_dir="-d $OPTARG";;
- e) extra_packages="$extra_packages $OPTARG" ;;
h) fail_usage "";;
+ m) manifest="$OPTARG" ;;
p) preserve_zone="-p";;
R) ZONEPATH="$OPTARG" ;;
s) silent_mode=1;;
@@ -128,10 +122,10 @@
[[ -n $unconfig_zone && -n $preserve_zone ]] && \
fail_usage "$f_incompat_options" "-u" "-p"
-# IPS options aren't allowed when installing from a system image.
+# AI zone manifest option isn`t allowed when installing from a system image.
if [[ -n "$install_archive" || -n "$source_dir" ]]; then
- [[ -n "$extra_packages" ]] && \
- fail_usage "$f_incompat_options" "-a|-d" "-e"
+ [[ -n "$manifest" ]] && fail_usage \
+ "$f_incompat_options" "-a|-d" "-m"
fi
# p2v options aren't allowed when installing from a repo.
@@ -150,19 +144,15 @@
entire_fmri=$(get_entire_incorp)
#
-# Before installing the zone, set up ZFS dataset hierarchy for the zone root
-# dataset.
-#
-create_active_ds zone || fail_fatal "$f_no_ds"
-mount_active_be -c zone || fail_fatal "$f_no_ds"
-
-#
# If we're installing from an image, branch off to that installer.
+# Set up ZFS dataset hierarchy for the zone root dataset.
#
if [[ -n $install_archive || -n $source_dir ]]; then
+ create_active_ds zone || fail_fatal "$f_no_ds"
+ mount_active_be -c zone || fail_fatal "$f_no_ds"
/usr/lib/brand/ipkg/image_install $ZONENAME $ZONEPATH \
$install_archive $source_dir $verbose_mode $silent_mode \
- $unconfig_zone $preserve_zone
+ $unconfig_zone $preserve_zone $OPT_C
ii_result=$?
if (( $ii_result != 0 )); then
@@ -178,100 +168,104 @@
exit $ZONE_SUBPROC_NOTCOMPLETE
fi
-#
-# The image is created.
-#
-LC_ALL=C $PKG image-create --zone --full \
- --set-property use-system-repo=true \
- $ZONEROOT || fail_incomplete "$f_img"
-
-# Link this image to the parent image.
-printf "$m_image_link\n" $GZ_IMAGE
-LC_ALL=C $PKG attach-linked -q -f --no-refresh --no-index --linked-md-only \
- -c zone:$ZONENAME $ZONEROOT || fail_incomplete "$f_imglink"
-
-# 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
-
-if [[ -f /var/pkg/pkg5.image && -d /var/pkg/publisher ]]; then
- # respect PKG_CACHEROOT if the caller has it set.
- [ -z "$PKG_CACHEROOT" ] && PKG_CACHEROOT=/var/pkg/publisher
- export PKG_CACHEROOT
- printf "$m_cache\n" $PKG_CACHEROOT
-fi
-
-printf "$m_core\n"
-pkglist=""
-
-#
-# 'entire' is essentially optional-- if you don't have it in your global
-# zone, you are probably an OS developer, and therefore you probably don't
-# want it in your non-global zone. We follow the preference we find in
-# the global zone.
-if [[ -n $entire_fmri ]]; then
- pkglist="$pkglist pkg:///entire"
+# Use default AI zone manifest if none is given
+if [[ ! -n $manifest ]]; then
+ manifest=/usr/share/auto_install/manifest/zone_default.xml
fi
#
-# If this is a labeled brand, install the trusted desktop package.
-# Otherwise, install the small server package
+# Add packages to AI zone manifest for TX zones if appropriate.
+# Add entire package if installed in GZ
+# The environment variable AIM_MANIFEST contains the file where all the
+# aimanifest changes will be made. The load operation loads that manifest
+# into the working file. The add operation adds the entries to the
+# working file.
#
-if (( $brand_labeled == 1 )); then
- pkglist="$pkglist pkg:///group/feature/trusted-desktop"
-else
- pkglist="$pkglist pkg:///group/system/solaris-small-server"
+if (( $brand_labeled == 1 )) || [[ -n $entire_fmri ]]; then
+ temp_manifest=`mktemp -t manifest.xml.XXXXXX`
+ if [[ -z $temp_manifest ]]; then
+ print "$f_mktemp"
+ exit $ZONE_SUBPROC_NOTCOMPLETE
+ fi
+ export AIM_MANIFEST=$temp_manifest
+ aimanifest load $manifest
+ if [[ $? -ne 0 ]]; then
+ print "$f_aimanifest_load"
+ exit $ZONE_SUBPROC_NOTCOMPLETE
+ fi
+ if (( $brand_labeled == 1 )); then
+ aimanifest add \
+ /auto_install/ai_instance/software/software_data[@action="install"]/name \
+ pkg:/group/feature/trusted-desktop
+ if [[ $? -ne 0 ]]; then
+ print "$f_aimanifest_add"
+ exit $ZONE_SUBPROC_NOTCOMPLETE
+ fi
+ fi
+ if [[ -n $entire_fmri ]]; then
+ aimanifest add \
+ /auto_install/ai_instance/software/software_data[@action="install"]/name \
+ pkg:///entire
+ if [[ $? -ne 0 ]]; then
+ print "$f_aimanifest_add"
+ exit $ZONE_SUBPROC_NOTCOMPLETE
+ fi
+ fi
+ manifest=$temp_manifest
fi
#
-# Add in any extra packages requested by the user.
+# Before installing the zone, set up ZFS dataset for the zone root dataset,
+# but don't create rpool/ROOT or rpool/export hierarchies since installer
+# will create them.
#
-pkglist="$pkglist $extra_packages"
+create_active_ds -r zone || fail_fatal "$f_no_ds"
#
-# Do the install; we just refreshed after image-create, so skip that. We
-# also skip indexing here, as that is also what the LiveCD does.
+# If unconfig service is online, then call auto-install with the default
+# profile or with the caller supplied profile.
+# If unconfig service is offline or doesn't exist, then don't pass
+# any profile to auto-install since this will cause SCI tool to start in
+# zone on boot. Previous sysconfig method handled below after install.
#
-LC_ALL=C $PKG install --accept --no-index --no-refresh $pkglist || \
- pkg_err_check "$f_pkg"
+SC_ONLINE=$(svcprop -p restarter/state \
+ svc:/milestone/unconfig:default 2> /dev/null)
+if (( $? == 0 )) && [[ $SC_ONLINE == "online" ]]; then
+ if [[ -n $sc_config ]]; then
+ /usr/bin/auto-install -Z ${zone.rpool_ds} -m $manifest $OPT_C
+ else
+ /usr/bin/auto-install -Z ${zone.rpool_ds} -m $manifest \
+ -c /usr/share/auto_install/sc_profiles/enable_sci.xml
+ fi
+else
+ /usr/bin/auto-install -Z ${zone.rpool_ds} -m $manifest
+fi
+if [[ $? -ne 0 ]]; then
+ fail_fatal "$f_autoinstall"
+fi
+
+if [[ -n $temp_manifest ]]; then
+ rm $temp_manifest
+fi
printf "\n$m_mannote\n"
-printf "$m_smf"
-PROFILEDIR=etc/svc/profile
-ln -s ns_files.xml $ZONEROOT/$PROFILEDIR/name_service.xml
-ln -s generic_limited_net.xml $ZONEROOT/$PROFILEDIR/generic.xml
-ln -s inetd_generic.xml $ZONEROOT/$PROFILEDIR/inetd_services.xml
-ln -s platform_none.xml $ZONEROOT/$PROFILEDIR/platform.xml
-
-# This was formerly done in i.manifest
-repfile=$ZONEROOT/etc/svc/repository.db
-cp $ZONEROOT/lib/svc/seed/nonglobal.db $repfile
-chmod 0600 $repfile
-chown root:sys $repfile
-
printf "$m_done\n"
#
-# If unconfig service exists and is online then copy in enable_sci.xml
-# sysconfig file to trigger config cycle on boot of zone.
+# If unconfig service is offline or doesn't exist, then use
+# previous sysconfig method since that is still being used by the
+# zone. Copy sysidcfg file if given, but only copy if it isn't the
+# new SC file enable_sci.xml. The enable_sci.xml file causes
+# sysid to generate warnings in a zone.
#
-SC_ONLINE=$(svcprop -p restarter/state \
- svc:/milestone/unconfig:default 2> /dev/null)
-if (( $? == 0 )) && [[ $SC_ONLINE == "online" ]]; then
- cp /usr/share/auto_install/sc_profiles/enable_sci.xml \
- $ZONEROOT/etc/svc/profile/site
-else
- #
- # 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
-
+mount_active_be -c zone || fail_fatal "$f_no_ds"
+if [[ $SC_ONLINE != "online" ]]; then
touch $ZONEROOT/etc/.UNCONFIGURED
+ if [[ -n $sc_config ]] && [[ $sc_config != \
+ "/usr/share/auto_install/sc_profiles/enable_sci.xml" ]]; then
+ cp $sc_config $ZONEROOT/etc/sysidcfg
+ fi
fi
#