15163 DC needs to be enhanced to publish the AI image as an IPS repository
authorJoseph J Vlcek <Joseph.Vlcek@Sun.COM>
Sat, 27 Mar 2010 07:39:52 -0600
changeset 788 6dd44354b88b
parent 787 8ceafab5c775
child 789 282f473d34ee
15163 DC needs to be enhanced to publish the AI image as an IPS repository
usr/src/cmd/distro_const/auto_install/Makefile
usr/src/cmd/distro_const/auto_install/ai_pre_boot_archive_pkg_image_mod
usr/src/cmd/distro_const/auto_install/ai_publish_pkg
usr/src/cmd/distro_const/auto_install/ai_sparc_image.xml
usr/src/cmd/distro_const/auto_install/ai_x86_image.xml
usr/src/cmd/distro_const/distro_const.py
usr/src/pkgdefs/SUNWdistro-const/prototype_com
--- a/usr/src/cmd/distro_const/auto_install/Makefile	Fri Mar 26 10:40:23 2010 -0700
+++ b/usr/src/cmd/distro_const/auto_install/Makefile	Sat Mar 27 07:39:52 2010 -0600
@@ -39,7 +39,8 @@
 			ai_x86_image.xml \
 			ai_sparc_image.xml \
 			ai_boot_archive_configure \
-			ai_pre_boot_archive_pkg_image_mod
+			ai_pre_boot_archive_pkg_image_mod \
+			ai_publish_pkg
 
 ROOT_AUTOINSTALL_FILES=	$(AUTOINSTALL_FILES:%=$(ROOTDC_AI)/%)
 
--- a/usr/src/cmd/distro_const/auto_install/ai_pre_boot_archive_pkg_image_mod	Fri Mar 26 10:40:23 2010 -0700
+++ b/usr/src/cmd/distro_const/auto_install/ai_pre_boot_archive_pkg_image_mod	Sat Mar 27 07:39:52 2010 -0600
@@ -61,6 +61,10 @@
 #
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+builtin cat
+builtin cd
+builtin fgrep
+
 if [ "$#" != "5" ] ; then
 	print -u2 "Usage: $0: Requires 5 args:"
 	print -u2 "    Reader socket, pkg_image area, tmp dir,"
@@ -68,12 +72,18 @@
 	exit 1
 fi
 
-PKG_IMG_PATH=$2
+typeset -r PKG_IMG_PATH=$2
 if [ ! -d $PKG_IMG_PATH ] ; then
 	print -u2 "$0: Image package area $PKG_IMG_PATH is not valid"
 	exit 1
 fi
 
+typeset -r TMP_DIR="$3" 
+if [[ ! -d $TMP_DIR ]] ; then
+        print -u2 "\t${PROG}: Unable to access temporary directory $TMP_DIR"
+	exit 1
+fi
+
 # Define used commands
 CPIO=/usr/bin/cpio
 FIND=/usr/bin/find
@@ -97,4 +107,16 @@
 cd ${PKG_IMG_PATH}/usr/share/auto_install
 $FIND . -depth -print | $CPIO -pdum ${AI_DIR}
 
+# Store the auto-install package version information for use by
+# finalizer checkpoint ai-publish-pkg.
+typeset ai_pkg_fmri=$(/usr/bin/pkg -R ${PKG_IMG_PATH} info auto-install | fgrep FMRI:)
+if [[ $? != 0 ]] ; then
+        print -u2 "\t${PROG}: Error accessing the auto-install package information"
+	exit 1
+fi
+
+typeset ai_pkg_ver=${ai_pkg_fmri#*auto-install@*,}
+ai_pkg_ver=${ai_pkg_ver%:*}
+print "${ai_pkg_ver}" >  ${TMP_DIR}/ai_pkg_version
+
 exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/distro_const/auto_install/ai_publish_pkg	Sat Mar 27 07:39:52 2010 -0600
@@ -0,0 +1,431 @@
+#!/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 2010 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+# =============================================================================
+# =============================================================================
+# ai_publish_pkg
+#
+# Publish the package image area into an pkg(5) repository.
+# =============================================================================
+# =============================================================================
+
+
+# Set up the builtin commands.
+builtin cat
+builtin print
+builtin rm
+builtin uname
+
+#
+# Establish PATH for non-built in commands
+#
+export PATH=/usr/xpg4/bin:/bin:/usr/bin:/usr/sbin:/usr/lib
+
+# Define non-core-OS commands.
+MANIFEST_READ=/usr/bin/ManifestRead
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# usage
+#       Print the usage message.
+#
+#       This program runs as a Distro Constructor finalizer script.
+#       The first five arguments are provided directly by the
+#       Distro Constructor.
+#       Any remaining arguments need to be specifed in the Distro
+#       Constructor manifest.
+#
+# Input: none
+# Returns: none
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+function usage
+{
+        print -u2 "\n\tUsage: "
+        print -u2 "\t${PROG} runs as a Distro Constructor finalizer script."
+        print -u2 "\tThe first five arguments are provided directly by"
+        print -u2 "\tthe Distro Constructor."
+        print -u2 "\tAny remaining arguments need to be specifed in "
+        print -u2 "\tthe Distro Constructor manifest. \n"
+        print -u2 "\tThe first five arguments passed by Disto Construtor are:"
+        print -u2 "\t\treader socket, pkg_image area, temporary directory,"
+        print -u2 "\t\tbootroot build area, media area \n"
+        print -u2 "\tThe remaining optoinal arguments, as specified in the"
+        print -u2 "\tDistro Constructor manifest, are:"
+        print -u2 "\t\tpackage name"
+        print -u2 "\t\tpackage repository URL (protocol file:)"
+        print -u2 "\t\tpublisher prefix (no underscores)"
+}
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+# set_locale
+#
+#	Make sure all math stuff runs in the "C" locale to avoid problems
+#	with alternative radix point representations (e.g. ',' instead of
+#	'.' in de_DE.*-locales). This needs to be set _before_ any
+#	floating-point constants are defined in this script).
+#
+# Input: none
+# Returns: none
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+function set_locale
+{
+        if [[ "${LC_ALL}" != "" ]] ; then
+                export \
+                LC_MONETARY="${LC_ALL}" \
+                LC_MESSAGES="${LC_ALL}" \
+                LC_COLLATE="${LC_ALL}" \
+                LC_CTYPE="${LC_ALL}"
+                unset LC_ALL
+        fi
+        export LC_NUMERIC=C
+
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# cleanup
+#
+#	This function attempts to clean up any resources this script
+#	could generate. Depending on where in the script this function
+#	is involved some resources may not be there to cleanup, but
+#	that will not adversely effect anything.
+#
+#	This function is not defined using the function keyword
+#	to avoid an exit loop.
+#
+# Input: none
+# Returns: none
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+cleanup ()
+{
+	#
+	# It is not necessary to process errors.
+	#
+	{
+
+		trap "" ERR INT
+		set +o errexit
+
+		#
+		# Cleanup any repository possibly created by this script.
+		#
+
+		#
+		# Close it if it was opened. PKG_TRANS_ID and PKG_REPO
+		# will be set if it was opened.
+		# 
+		#
+		if [[ ! -z ${PKG_TRANS_ID} ]]; then
+			pkgsend -s ${PKG_REPO} close
+		fi
+
+		# The pkg_repo_path will be empty if the user had created
+		# it, started a depo server and specified http protocol for
+		# the optional argument: pkg_repo.
+		#
+		if [[ ! -z ${pkg_repo_path} ]]; then
+			rm -rf ${pkg_repo_path} > /dev/null 2>&1
+		fi
+
+
+	} > /dev/null 2>&1
+}
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# error_handler and error_handler_trap
+#
+#	The error_handler will set up the traps,
+#	invoke cleanup to clean up any temporary resources then
+#	exit with an error or 1.
+#
+#	These function is not defined using the function keyword
+#	to avoid an exit loop.
+#
+#	error_handler_trap is the entry point registered with
+#	the trap command for interupts (INT). Using this extra
+#	level allows arguments to be passed to error_handler().
+#
+# Input:
+#	stat - error status code to act upon
+#       msg  - message to issue if an error_code is not success
+#
+# Returns: none
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+error_handler_trap ()
+{
+	print -u2 "\nInvoking: error_handler_trap"
+	error_handler 1 "Interrupt encountered. Exiting"
+}
+
+error_handler ()
+{
+	typeset -i stat=$1
+	typeset    msg="$2"
+
+	if [[ ${stat} != 0 ]] ; then
+		print -u2 "\nInvoking: error_handler"
+
+		trap "" ERR INT
+		set +o errexit
+
+		print -u2 "${msg}"
+
+		#
+		# cleanup must be defined in the caller.
+		#
+		cleanup
+
+		exit 1
+	fi
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Main
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+# Publish the package image area into an pkg(5) repository.
+# 
+# Args:
+#   MFEST_SOCKET: Socket needed to get manifest data via ManifestRead object
+#
+#   PKG_IMG_PATH: Package image area
+#
+#   TMP_DIR: Temporary directory to contain the bootroot file
+#
+#   BA_BUILD: Area where boot archive is put together.
+#
+#   MEDIA_DIR: Area where the media is put.
+# 
+#   PKG_NAME_SUPPLIED: The package name
+#
+#   PKG_REPO_SUPPLIED: The package repository URL, protocol must befile.
+#
+#   PUB_PREF_SUPPLIED: The publisher prefix, no special characters
+#                      including no underscores.
+#
+# Note: This assumes a populated pkg_image area exists at the location
+#		${PKG_IMG_PATH} and that the bootroot has been built.
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+#
+# Make sure all math stuff runs in the "C" locale
+#
+set_locale
+
+#
+# Process command line arguments
+#
+typeset -r PROG="$0"
+if [[ ($# < 5) || ($# > 8) ]]; then
+        print -u2 "\t${PROG}: Requires a minimum of 5 and a maximum" \
+	    " of 8 arguments. $# supplied."
+	usage
+	exit 1
+fi
+
+#
+# Validate the arguments
+#
+typeset invalid_argument_found=false
+
+#
+# Process the 5 required arguments
+#
+typeset -r MFEST_SOCKET="$1"
+typeset -r PKG_IMG_PATH="$2"
+if [[ ! -d ${PKG_IMG_PATH} ]] ; then
+	print -u2 "\t${PROG}: Unable to access pkg_image area $PKG_IMG_PATH"
+	invalid_argument_found=true
+fi
+
+typeset -r TMP_DIR="$3" 
+if [[ ! -d $TMP_DIR ]] ; then
+	print -u2 "\t${PROG}: Unable to access temporary directory $TMP_DIR"
+	invalid_argument_found=true
+fi
+
+typeset -r BA_BUILD="$4" 
+if [[ ! -d $BA_BUILD ]] ; then
+	print -u2 "\t${PROG}: Unable to access bootroot directory $BA_BUILD"
+	invalid_argument_found=true
+fi
+
+typeset -r MEDIA_DIR="$5"
+if [[ ! -d $MEDIA_DIR ]] ; then
+	print -u2 "\t${PROG}: Unable to access media directory $MEDIA_DIR"
+	invalid_argument_found=true
+fi      
+
+#
+# Process any optional arguments
+# 
+typeset opt_arg_supplied=""
+typeset opt_arg_key=""
+typeset PKG_NAME_SUPPLIED=""
+typeset PKG_REPO_SUPPLIED=""
+typeset PUB_PREF_SUPPLIED=""
+shift 5
+while (( $# > 0)); do
+	opt_arg_supplied="$1"
+	opt_arg_key=${opt_arg_supplied%=*}
+	
+	case "${opt_arg_key}" in
+
+		pkg_name)
+			PKG_NAME_SUPPLIED=${opt_arg_supplied#*=}
+		;;
+
+		pkg_repo)
+			PKG_REPO_SUPPLIED=${opt_arg_supplied#*=}
+		;;
+
+		publisher_prefix)
+			PUB_PREF_SUPPLIED=${opt_arg_supplied#*=}
+		;;
+
+		*)
+			print -u2 "\t${PROG}: Invalid argument specifying" \
+			    "${opt_arg_supplied}"
+			invalid_argument_found=true
+		;;
+
+	esac
+	
+	
+        shift
+done
+
+if $invalid_argument_found ; then
+        print -u2 "\n\tError encountered: Invalid argument found. Exiting"
+        usage
+        exit 1
+fi
+
+#
+# Local command variables
+#
+typeset -i cmdsts=0
+typeset    cmdout=""
+
+#
+# Read the distribution name tag from the manifest 
+#
+typeset -r DIST_NAME=$(${MANIFEST_READ} ${MFEST_SOCKET} "name")
+
+#
+# Set the default package name to be the distribution_name from
+# the manifest appended with the version of the auto-install
+#  package installed in the package image area.
+# The version string for the auto-install package is stored
+# by DC checkpoint ai-im-mod in file: ${TMP_DIR}/ai_pkg_version.
+#      e.g.: image/[email protected]
+
+typeset -r AI_PKG_VER_FILE="${TMP_DIR}/ai_pkg_version"
+cmdout=$(cat ${AI_PKG_VER_FILE} 2>&1)
+cmdsts=$?
+error_handler ${cmdsts} "\nAccessing ${AI_PKG_VER_FILE} failed with ${cmdout}"
+typeset -r PKG_NAME_DEFAULT="image/${DIST_NAME}@${cmdout}"
+
+#
+# If available use the supplied pkg name. If not suppled
+# use the default name.
+#
+typeset -r PKG_NAME=${PKG_NAME_SUPPLIED:-${PKG_NAME_DEFAULT}}
+
+#
+# Set: Destination pkg(5) Repository Publisher Prefix
+#      Defaults to "ai.opensolaris.org if not supplied.
+#
+typeset -r PUB_PREF=${PUB_PREF_SUPPLIED:-"ai.opensolaris.org"}
+
+#
+# Set: Destination pkg(5) Repository Name
+#      Defaults to "file://${MEDIA_DIR}/ai_image_repo if not supplied.
+#
+typeset -r PKG_REPO=${PKG_REPO_SUPPLIED:-"file://${MEDIA_DIR}/ai_image_repo"}
+typeset    pkg_repo_path=""
+
+#
+# Set up error handling.
+#
+trap "error_handler_trap" INT
+set +o errexit
+
+if [[ ${PKG_REPO} == ~(E)file: ]]; then
+	pkg_repo_path=${PKG_REPO//file:\/\//}
+
+	#
+	# Create the repository if the specified protocol is: "file:".
+	#
+	pkgsend -s ${PKG_REPO} create-repository --set-property \
+	    publisher.prefix=${PUB_PREF}
+	cmdsts=$?
+	error_handler ${cmdsts} "\ncreate repository failed"
+fi
+
+#
+# Open the repository
+#
+#     pkgsend open writes to standard output a command of the form:
+#     export PKG_TRANS_ID="%s"
+#
+#     This command needs to be executed when pkgsend open succeeds
+#     so consecutive commands will be able to access the value of
+#     PKG_TRANS_ID.
+#
+#     Upon failure the output will be logged.
+#
+cmdout=$(pkgsend -s ${PKG_REPO} open ${PKG_NAME} 2>&1)
+cmdsts=$?
+error_handler ${cmdsts} "\npkgsend open failed with: ${cmdout}"
+${cmdout}
+
+#
+# Import the image into the repository
+#
+pkgsend -s ${PKG_REPO} import ${PKG_IMG_PATH}
+cmdsts=$?
+error_handler ${cmdsts} "\npkgsend import failed"
+
+#
+# Close/abandon the current transaction/repository
+#
+pkgsend -s ${PKG_REPO} close
+cmdsts=$?
+error_handler ${cmdsts} "\npkgsend close failed"
+
+#
+# exit with success status
+#
+exit 0
+
--- a/usr/src/cmd/distro_const/auto_install/ai_sparc_image.xml	Fri Mar 26 10:40:23 2010 -0700
+++ b/usr/src/cmd/distro_const/auto_install/ai_sparc_image.xml	Sat Mar 27 07:39:52 2010 -0600
@@ -128,6 +128,26 @@
 						"usr_zlib_compression=lzma"
 					</argslist>
 				</script>
+				<script name="/usr/share/distro_const/auto_install/ai_publish_pkg">
+					<checkpoint
+						name="ai-publish-pkg"
+						message="Publish Package"/>
+					<!--
+					     The following arguments are optional.
+
+					     If not specified the arguments default as:
+					         pkg_name - image/<distribution name>@<AI pkg version>
+					         pkg_repo - file://<MEDIA_DIR>/ai_image_repo
+					         publisher_prefix - ai.opensolaris.org
+					             Note: See pkg(5) and pkg.depotd(1M) for a description
+					                   of these optional arguments.
+					<argslist>
+						"pkg_name=<package name>"
+						"pkg_repo=<package repo>"
+						"publisher_prefix=<publisher prefix>"
+					</argslist>
+					-->
+				</script>
 				<script name="/usr/share/distro_const/create_iso">
 					<checkpoint
 						name="iso"
--- a/usr/src/cmd/distro_const/auto_install/ai_x86_image.xml	Fri Mar 26 10:40:23 2010 -0700
+++ b/usr/src/cmd/distro_const/auto_install/ai_x86_image.xml	Sat Mar 27 07:39:52 2010 -0600
@@ -138,6 +138,26 @@
 						"usr_zlib_compression=lzma"
 					</argslist>
 				</script>
+				<script name="/usr/share/distro_const/auto_install/ai_publish_pkg">
+					<checkpoint
+						name="ai-publish-pkg"
+						message="Publish Package"/>
+					<!--
+					     The following arguments are optional.
+
+					     If not specified the arguments default as:
+					         pkg_name - image/<distribution name>@<AI pkg version>
+					         pkg_repo - file://<MEDIA_DIR>/ai_image_repo
+					         publisher_prefix - ai.opensolaris.org
+					             Note: See pkg(5) and pkg.depotd(1M) for a description
+					                   of these optional arguments.
+					<argslist>
+						"pkg_name=<package name>"
+						"pkg_repo=<package repo>"
+						"publisher_prefix=<publisher prefix>"
+					</argslist>
+					-->
+				</script>
 				<script name="/usr/share/distro_const/create_iso">
 					<checkpoint
 						name="iso"
--- a/usr/src/cmd/distro_const/distro_const.py	Fri Mar 26 10:40:23 2010 -0700
+++ b/usr/src/cmd/distro_const/distro_const.py	Sat Mar 27 07:39:52 2010 -0600
@@ -19,7 +19,7 @@
 #
 # CDDL HEADER END
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -564,7 +564,6 @@
     else:
         dc_log.info("Build is successful.")
 
-    dcu.cleanup_dir(cp.get_build_area_mntpt() + TMP)
     return (status)
 
 if __name__ == "__main__":
--- a/usr/src/pkgdefs/SUNWdistro-const/prototype_com	Fri Mar 26 10:40:23 2010 -0700
+++ b/usr/src/pkgdefs/SUNWdistro-const/prototype_com	Sat Mar 27 07:39:52 2010 -0600
@@ -91,6 +91,7 @@
 f none usr/share/distro_const/auto_install/ai_boot_archive_configure 0555 root bin
 f none usr/share/distro_const/auto_install/ai_live.xml 0444 root sys
 f none usr/share/distro_const/auto_install/ai_pre_boot_archive_pkg_image_mod 0555 root bin
+f none usr/share/distro_const/auto_install/ai_publish_pkg 0555 root bin
 f none usr/share/distro_const/auto_install/ai_sparc_image.xml 0444 root sys
 f none usr/share/distro_const/auto_install/ai_x86_image.xml 0444 root sys
 f none usr/share/distro_const/boot_archive_archive.py 0555 root bin