src/brand/pkgcreatezone
author Andrzej Szeszo <aszeszo@gmail.com>
Wed, 01 Jun 2011 13:11:09 +0100
changeset 2391 90c532b69592
parent 2365 3501bd50829f
parent 2390 f1c659f5c28e
child 2392 57fd6b333437
permissions -rwxr-xr-x
Merge

#!/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) 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.")

m_image=$(gettext       "       Image: Preparing at %s.")
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_done=$(gettext      " done.")

trap_cleanup() {
	print "$f_interrupted"
	exit $int_code
}

int_code=$ZONE_SUBPROC_NOTCOMPLETE
trap trap_cleanup INT

extra_packages=""
ZONENAME=""
ZONEPATH=""

# Setup i18n output
TEXTDOMAIN="SUNW_OST_OSCMD"
export TEXTDOMAIN

PKG=pkg

unset install_archive
unset source_dir
unset msg
unset silent_mode
unset verbose_mode

while getopts "a:d:e:hpR:suvz:" opt; do
	case $opt in
		a)	# We're expecting a path to an archive
			if [[ ! -f $OPTARG ]]; then
				# 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";;
		d)	source_dir="-d $OPTARG";;
		e)	extra_packages="$extra_packages $OPTARG" ;;
		h)	fail_usage "";;
		p)	preserve_zone="-p";;
		R)	ZONEPATH="$OPTARG" ;;
		s)	silent_mode=1;;
		u)	unconfig_zone="-u";;
		v)	verbose_mode="-v";;
		z)	ZONENAME="$OPTARG" ;;
		*)	fail_usage "";;
	esac
done
shift $((OPTIND-1))

if [[ -z $ZONEPATH || -z $ZONENAME ]]; then
	print -u2 "Brand error: No zone path or name"
	exit $ZONE_SUBPROC_USAGE
fi

# XXX shared/common script currently uses lower case zonename & zonepath
zonename="$ZONENAME"
zonepath="$ZONEPATH"

is_brand_labeled
brand_labeled=$?

ZONEROOT=$ZONEPATH/root
secinfo=""

# An image install can't use both -a AND -d...
[[ -n "$install_archive" && -n "$source_dir" ]] &&
    fail_usage "$f_incompat_options" "-a" "-d"

# The install can't be both verbose AND silent...
[[ -n $silent_mode && -n $verbose_mode ]] && \
    fail_usage "$f_incompat_options" "-s" "-v"

# The install can't both preserve and unconfigure
[[ -n $unconfig_zone && -n $preserve_zone ]] && \
    fail_usage "$f_incompat_options" "-u" "-p"

# IPS options aren'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"
fi

# p2v options aren't allowed when installing from a repo.
if [[ -z $install_archive && -z $source_dir ]]; then
	[[ -n $preserve_zone || -n $unconfig_zone ]] && \
		fail_usage "$f_incompat_options" "default" "-p|-u"
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.
# It's ok to not find entire in the current image, since this means the user
# can install pre-release development bits for testing purposes.
#
entire_fmri=$(get_entire_incorp)

#
# Before installing the zone, set up ZFS dataset hierarchy for the zone root
# dataset.
#
create_active_ds

#
# If we're installing from an image, branch off to that installer.
#
if [[ -n $install_archive || -n $source_dir ]]; then
	/usr/lib/brand/ipkg/image_install $ZONENAME $ZONEPATH \
	    $install_archive $source_dir $verbose_mode $silent_mode \
	    $unconfig_zone $preserve_zone
	ii_result=$?

	if (( $ii_result != 0 )); then
		exit $ZONE_SUBPROC_NOTCOMPLETE
	fi
	exit $ZONE_SUBPROC_OK
fi

printf "$m_image\n" $ZONEROOT

enable_zones_services
if [[ $? -ne 0 ]]; then
	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"
fi

#
# If this is a labeled brand, install the trusted desktop package.
# Otherwise, install the small server package
#
if (( $brand_labeled == 1 )); then
    pkglist="$pkglist pkg:///group/feature/trusted-desktop"
else
    pkglist="$pkglist pkg:///group/system/solaris-small-server"
fi

#
# Add in any extra packages requested by the user.
#
pkglist="$pkglist $extra_packages"

#
# 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.
#
LC_ALL=C $PKG install --accept --no-index --no-refresh $pkglist || \
    pkg_err_check "$f_pkg"

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

	touch $ZONEROOT/etc/.UNCONFIGURED
fi

#
# Labeled zones need to be able to modify /etc/gconf files, when gnome
# packages are installed in the zone.  Set up links in the zone to the
# global zone files -- this will provide default versions from the global
# zone, which can be modified by the zone, breaking the link.
if (( $brand_labeled == 1 )); then
	cd /etc/gconf
	for i in $(find .); do
		if [ ! -e $ZONEROOT/etc/gconf/$i ]; then
			if [ -d $i ]; then
				mkdir $ZONEROOT/etc/gconf/$i
			else
				ln -s /etc/gconf-global/$i \
				    $ZONEROOT/etc/gconf/$i
			fi
		fi
	done
fi

printf "$m_complete\n\n" ${SECONDS}
if (( $brand_labeled == 0 )); then
	printf "$m_postnote\n"
	printf "$m_postnote2\n"
else
	# Umount the dataset on the root.
	umount $ZONEROOT || printf "$f_zfs_unmount" "$ZONEPATH/root"
fi

exit $ZONE_SUBPROC_OK