Sie sind auf Seite 1von 59

#!

/bin/ksh
# use "create_zone.sh {-v} -h" to get the usage help
#
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License, Version 1.0 only
# (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 2006 Bernd Schemmer All rights reserved.
# Use is subject to license terms.
#
## ----------------------------------------------------------------------------##
## create_zone.sh - script to create zones unattended
##
## Author: Bernd Schemmer (Bernd.Schemmer@gmx.de)
##
## Version: see variable ${__SCRIPT_VERSION} below
##
(see variable ${__SCRIPT_TEMPLATE_VERSION} for the template
##
version used)
##
## Supported OS: Solaris 10 and newer
##
##
## Description
##
## This script can be used to create and configure a zone without user interacti
on.
##
## You can use this script fore example in finish_scripts to create initial zone
s.
## The script supports a finish script for the zone, a customization script for
the zone,
## and a SMF profile. Various settings for the zone can be done via parameter an
d
## configuration file.
##
## Configuration file
##
## This script supports a configuration file called <scriptname>.conf.
## The configuration file is searched in the working directory,
## the home directory of the user executing this script and the
## directory /etc (in this order).

##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##

The configuration file is read before the parameter are read.


See the variable __CONFIG_PARAMETER below for the possible entries in
the config file.
Parameter
see the subroutines ShowShortUsage and ShowUsage
History
12.06.2006 /bs
initial release
------------------scriptt.sh History:
2004 v1.0.0 /bs
initial release
06.06.20064 1.21.6 04/27/2006 /bs
current release

Defined return codes:


1 - show usage and exit
2 - invalid parameter found
5
6
8
11
14
15
17
20
23
26
29
32
35

parameter missing: name for the zone


script executed in a non-global zone
parameter missing: IP address for the zone
the directory for the zone does not exist
zone creation aborted by the user
can not detect the interface to use for the zone
customize script for the zone not found or not readable
zone configuration is not okay (see previous error messages
can not delete the existing zone
can not remove the exisiting zone directory
error configuring the zone with zonecfg
error installing the zone with zoneadm ... install
error preparing the zone with zoneadm .. ready

100
102
105
106
107
108

error creating the sysidcfg file of the zone


error creating one of the files for the nameserver configuration
error creating the directory for the customize script for the zone
error creating the customize script for the zone
error creating the SMF profile for the zone
the finish script for the zone returned an error

246
247
248
249
250

error writing the config file


include script not found
unsupported OS version
Script not executed by root
Script is already running

##
##
##
##
##

252
251
253
254

User break
QUIT signal received
TERM signal received
unknown external signal received

## ----------------------------------------------------------------------------##
## ##### general hints
##
## Do not use variable names beginning with __ (these are reserved for
## internal use)
##
##
##
##
##
##
##
##

Uncomment the next if block if you want the script running with RBAC control
(Solaris 10 and newer only!)
Allow the use of RBAC to control who can access this script. Useful for
administrators without root permissions

##if [ "$_" != "/usr/bin/pfexec" -a -x /usr/bin/pfexec ]; then


##
/usr/bin/pfexec $0 $*
##
exit $?
##fi
##
## ##### defined variables that may be changed
##
## __DEBUG_CODE - code executed at start of every predefined sub routine
##
__DEBUG_CODE=""
## __CONFIG_PARAMETER
## The variable __CONFIG_PARAMETER contains the configuraton variables
##
## The defaults for these variables are defined here. You
## can use a config file to overwrite the defaults.
##
## Use the parameter -C to create a default configuration file
##
## Note: The config file is read and interpreted via ". configfile" therefor yo
u can
##
add also some code her!
##
__CONFIG_PARAMETER='
##
## Settings in the configuration file
## ---------------------------------##
## DEFAULT_BACKUP_EXTENSION
## extension for backup files
##
DEFAULT_BACKUP_EXTENSION=".$$.backup"
## NAME_SERVER_CONFIG_FILES

##
##
##

name server configuration files


Note: Add only fully qualified filenames here!

NAME_SERVER_CONFIG_FILES="/etc/resolv.conf
/etc/nsswitch.conf"
## DEFAULT_FREE_SPACE_FOR_THE_ZONE
## free space neccessary for the zone in KB
## (the default depends on the type of the zone)
##
DEFAULT_FREE_SPACE_FOR_THE_ZONE=""
## DEFAULT_FREE_SPACE_FOR_A_BIG_ZONE
## default free space needed for a big zone in KB
##
DEFAULT_FREE_SPACE_FOR_A_BIG_ZONE=3500000
## DEFAULT_FREE_SPACE_FOR_A_SMALL_ZONE
## default free space needed for a small zone in KB
##
DEFAULT_FREE_SPACE_FOR_A_SMALL_ZONE=200000
## DEFAULT_ZONE_MODE
## default type of the new zone;
## possible values: small or big
##
DEFAULT_ZONE_MODE="small"
## DEFAULT_ZONE_PATH
## base directory for zones (can be a symbolic link;
## this will be resolved by the script)
##
DEFAULT_ZONE_PATH="/zones"
## DEFAULT_ZONE_ROOT_PASSWORD
## default for the root password is the password
## of the existing root user
##
DEFAULT_ZONE_ROOT_PASSWORD="$( grep root /etc/shadow 2>/dev/null | cut -f2 -d
":" )"
## DEFAULT_ZONE_TZ
## the default timezone is the timezone of the machine
##
DEFAULT_ZONE_TZ="$( grep "^TZ=" /etc/TIMEZONE 2>/dev/null | cut -f2 -d"=" )"
[ "${DEFAULT_TZ}"x = ""x ] && DEFAULT_TZ="${TZ}"
## DEFAULT_ZONE_LOCALE
## default locale is the current locale
##
DEFAULT_ZONE_LOCALE="${LANG}"
[ "${DEFAULT_ZONE_LOCAL}"x = ""x ] && DEFAULT_ZONE_LOCALE="C"
## DEFAULT_ZONE_TERMINAL
## default terminal type for the zone
##
DEFAULT_ZONE_TERMINAL="${TERM:-vt100}"
## DEFAULT_ZONE_TIMESERVER
## default timeserver for the zones

##
DEFAULT_ZONE_TIMESERVER="localhost"
## DEFAULT_ZONE_CUSTOMIZE_SCRIPT_SOURCE
## default customize script for the zone
## Possible values for this variabe are:
##
"builtin", "none", or the name of an existing script
## The customize script runs inside the new zone
## while first rebooting the zone
##
DEFAULT_ZONE_CUSTOMIZE_SCRIPT_SOURCE="builtin"
## DEFAULT_ZONE_CUSTOMIZE_SCRIPT_TARGET
## fully qualified name of the customize script inside the zone
##
## Note: The runlevel in which the script runs depends on the path of the cust
omize scripts
##
The default is rc3.d = multi-user-server
##
DEFAULT_ZONE_CUSTOMIZE_SCRIPT_TARGET="/etc/rc3.d/S99customize_script"
## DEFAULT_ZONE_SMF_PROFILE
## SMF site profile for the zone; default: none
##
DEFAULT_ZONE_SMF_PROFILE=""
## DEFAULT_ZONE_IP_ADDRESS
## there is no default IP address for the zone
##
DEFAULT_ZONE_IP_ADDRESS=""
## DEAULT_ZONE_NAME
## there is no default name for the zone
##
DEAULT_ZONE_NAME=""
## DEFAULT_USE_EXISTING_NAMESERVER_CONFIG
## default nameserver configuration is:
##
use the existing nameserver configuration
##
DEFAULT_USE_EXISTING_NAMESERVER_CONFIG=${__TRUE}
## DEFAULT_ZONE_AUTOBOOT
## enable zone autoboot?
##
DEFAULT_ZONE_AUTOBOOT=${__FALSE}
## DEFAULT_ZONE_NETWORK_INTERFACE
## the default network interface for the zone
## The default is the network interface which hosts the
## network with the IP address for the zone
##
DEFAULT_ZONE_NETWORK_INTERFACE=""
## DEFAULT_BOOT_THE_ZONE_NOW
## boot the zone after installation?
##
DEFAULT_BOOT_THE_ZONE_NOW=${__FALSE}
## DEFAULT_ZONE_FINISH_SCRIPT

##
## finish script for creating the zone
## This script is called in the global zone after the new
## zone is created and configured but before it is booted
## The parameters for the script are
##
- the fully qualified name of the directory for the zone
##
## Note: Please write your finish scripts so that they handle multiple paramet
er correct
##
because there may be additional parameter in a future version of this
script!
##
## The finish script must end with 0 if everything is okay; everthing else
## is interpreted as error.
##
## All environment variables beginning with ZONE_ are exported and can be used
by the
## finish script. The exported variables are:
##
##
ZONE_AUTOBOOT
##
ZONE_CUSTOMIZE_SCRIPT_CONTENTS
##
ZONE_CUSTOMIZE_SCRIPT_SOURCE
##
ZONE_CUSTOMIZE_SCRIPT_TARGET
##
ZONE_FINISH_SCRIPT
##
ZONE_IP_ADDRESS
##
ZONE_LOCALE
##
ZONE_MODE
##
ZONE_NAME
##
ZONE_NETWORK_INTERFACE
##
ZONE_PATH
##
ZONE_ROOT_PASSWORD
##
ZONE_SMF_PROFILE
##
ZONE_TERMINAL
##
ZONE_TIMESERVER
##
ZONE_TZ
##
DEFAULT_ZONE_FINISH_SCRIPT=""
## DEFAULT_ZONE_CUSTOMIZE_SCRIPT_CONTENTS
## builtin customize script for the zones
## The customize script runs inside the new zone while first
## booting the zone
##
DEFAULT_ZONE_CUSTOMIZE_SCRIPT_CONTENTS="
echo \"Customization of the zone is running ...\"
echo \"Disabling sendmail ...\"
svcadm disable sendmail
echo \" ... customization done. Removing the customize script\"
rm \$0
"
# only change the following variables if you know
# what you are doing
#
# __DEBUG_CODE
# sample debug code:
#

# __DEBUG_CODE=" eval echo Entering the subroutine \$__FUNCTION ... "


# Note: Use an include script for more complicate debug code, e.g.
# __DEBUG_CODE=" eval . /var/tmp/mydebugcode"
#
# no further internal variables defined yet
'
# end of config parameters
## __SHORT_DESC - short description (for help texts, etc)
##
Change to your need
##
typeset -r __SHORT_DESC="create zones unattended"
## __SCRIPT_VERSION - the version of your script
##
typeset -r __SCRIPT_VERSION="v1.0.0"
## __SCRIPT_TEMPLATE_VERSION - version of the template
##
typeset -r __SCRIPT_TEMPLATE_VERSION="1.21.6 04/27/2006"
## __TRUE - true (0)
## __FALSE - false (1)
##
typeset -r __TRUE=0
typeset -r __FALSE=1
## __MUST_BE_ROOT (def.: false)
## set to ${__TRUE} for scripts that must be executed by root only
##
__MUST_BE_ROOT=${__TRUE}
## __ONLY_ONCE (def.: false)
## set to ${__TRUE} for scripts that can not run more than one
## instance at the same time
##
__ONLY_ONCE=${__FALSE}
## __REQUIRED_OS_VERSION
## minimum OS version necessary, e.g. 5.10; "" - no minimum OS version check n
ecessary
##
__REQUIRED_OS_VERSION="5.10"
## __VERBOSE_LEVEL - count of -v parameter (def. 0)
##
typeset -i __VERBOSE_LEVEL=0
## __RT_VERBOSE_LEVEL - level of -v for runtime messages
##
## e.g. 1 = -v -v is necessary to print info messages of the runtime system
##
2 = -v -v -v is necessary to print info messages of the runtime system
##
##
__RT_VERBOSE_LEVEL=1

## __QUIET_MODE - do not print messages to STDOUT (def.: false)


## use the parameter -q/+q to change this variable
##
__QUIET_MODE=${__FALSE}
## __VERBOSE_MODE - print verbose messages (def. false)
## use the parameter -v/+v to change this variable
##
__VERBOSE_MODE=${__FALSE}
## __FORCE - do the action anyway (-> the function "die" will return
## if called with an RC not zero)
## use the parameter -f/+f to change this variable
##
__FORCE=${__FALSE}
## __USE_COLORS - use colors (def. false) use the parameter -a/+a to
## change this variable
##
__USE_COLORS=${__FALSE}
## __USER_BREAK_ALLOWED - CTRL-C aborts program or not (def. true)
## (no parameter to change this variable)
##
__USER_BREAK_ALLOWED=${__TRUE}
## __OVERWRITE mode - overwrite existing files or not (def. false
## use the parameter -O/+O to change this variable
##
__OVERWRITE_MODE=${__FALSE}
## __DEBUG_MODE - use single step mode for main (def. false)
## use the parameter -D/+D to change this variable
##
__DEBUG_MODE=${__FALSE}
__SCRIPT_ARRAY[0]=0
## __LIST_OF_TMP_MOUNTS - list of mounts that should be umounted at program end
##
__LIST_OF_TMP_MOUNTS=""
## __LIST_OF_TMP_DIRS - list of directories that should be removed at program en
d
##
__LIST_OF_TMP_DIRS=""
## __LIST_OF_TMP_FILES - list of files that should be removed at program end
##
__LIST_OF_TMP_FILES=""
## __EXITROUTINES - list of routines that should be executed before the script e
nds
##
__EXITROUTINES=""
## __REBOOT_REQUIRED - set to true to reboot automatically at
## script end (def. false)
##
__REBOOT_REQUIRED=${__FALSE}

## __REBOOT_PARAMETER - parameter for the reboot command (def.: none)


##
__REBOOT_PARAMETER=""
## __PRINT_LIST_OF_WARNINGS_MSGS
## print the list of warning messages at program end (def. false)
##
__PRINT_LIST_OF_WARNINGS_MSGS=${__FALSE}
## __PRINT_LIST_OF_ERROR_MSGS
## print the list of error messages at program end (def. false)
##
__PRINT_LIST_OF_ERROR_MSGS=${__FALSE}
## __PRINT_SUMMARIES - print error/warning msg summaries at script end
##
## print error and/or warning message summaries at program end
## known values:
##
0 no summarys,
##
1 = print error msgs,
##
2 = print warning msgs
##
3 = print error and warning mgs
## Use the parameter -S to change this variable
##
__PRINT_SUMMARIES=0
## __MAINRC - return code of the program
##
__MAINRC=0
# ----------------------------------------------------------------------------#
# ----------------------------------------------------------------------------# init the global variables
#
## ##### defined variables that should not be changed
##
# init the variable for the TRAP handlers
__INCLUDE_SCRIPT_RUNNING=""
#
# internal variables for push/pop
#
typeset -i __STACK_POINTER=0
__STACK[0]=${__STACK_POINTER}
#
# internal variables for the single-step routine
#
typeset -i __BREAKPOINT_LINE=0
typeset -i __STEP_COUNT=0
typeset -i __TRACE_COUNT=0
__DEBUG_HISTFILE="/tmp/ksh.history.$$"
# delete the history file at program end

__LIST_OF_TMP_FILES="${__LIST_OF_TMP_FILES} ${__DEBUG_HISTFILE}"
__USER_RESPONSE_IS=""
## __SCRIPTNAME - name of the script without the path
##
typeset -r __SCRIPTNAME="${0##*/}"
## __SCRIPTDIR - path of the script (as entered by the user!)
##
__SCRIPTDIR="${0%/*}"
## __REAL_SCRIPTDIR - path of the script (real path, maybe a link)
##
__REAL_SCRIPTDIR=$( cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P )
## __CONFIG_FILE - name of the config file
## (use ReadConfigFile to read the config file;
## use WriteConfigFile to write it)
##
__CONFIG_FILE="${__SCRIPTNAME%.*}.conf"
## __HOSTNAME - hostname
##
__HOSTNAME="$( uname -n )"
## __NODENAME - nodename
##
__NODENAME=${__HOSTNAME}
[ -f /etc/nodename ] && __NODENAME="$( cat /etc/nodename )"
## __OS - Operating system (e.g. SunOS)
##
__OS="$( uname -s )"
## __OS_VERSION - Operating system version (e.g 5.8)
##
__OS_VERSION="$( uname -r )"
## __ZONENAME - name of the current zone if running in Solaris 10 or newer
##
__ZONENAME="$( zonename 2>/dev/null )"
## __OS_RELEASE - Operating system release (e.g. Generic_112233-08)
##
__OS_RELEASE="$( uname -v )"
## __MACHINE_CLASS - Machine class (e.g sun4u)
##
__MACHINE_CLASS="$( uname -m )"
## __MACHINE_TYPE - machine type (e.g. SUNW,Ultra-4)
##
__MACHINE_TYPE="$( uname -i )"
## __MACHINE_SUBTYPE - machine type (e.g Sun Fire 3800)
##
__MACHINE_SUBTYPE=""
if [ -x /usr/platform/${__MACHINE_TYPE}/sbin/prtdiag ] ; then
( set -- $( /usr/platform/${__MACHINE_TYPE}/sbin/prtdiag | grep "System Config

uration" ) ; shift 5; echo $* ) | read __MACHINE_SUBTYPE


fi
## __MACHINE_ARC - machine architecture (e.g. sparc)
##
__MACHINE_ARC="$( uname -p )"
## __START_DIR - working directory when starting the script
##
__START_DIR="$( pwd )"
## __LOGFILE - fully qualified name of the logfile used
## Note: use -l to change the logfile
##
if [ -d /var/log ] ; then
__DEF_LOGFILE="/var/log/${__SCRIPTNAME%.*}.LOG"
else
__DEF_LOGFILE="/tmp/${__SCRIPTNAME%.*}.LOG"
fi
__LOGFILE=${__DEF_LOGFILE}
## __TEMPFILE1, __TEMPFILE2
## temporary files (these files are deleted at program end)
##
__TEMPFILE1="/tmp/${__SCRIPTNAME}.$$.TEMP1"
__TEMPFILE2="/tmp/${__SCRIPTNAME}.$$.TEMP2"
__LIST_OF_TEMPFILES="${__LIST_OF_TEMPFILES} ${__TEMPFILE1} ${__TEMPFILE2}"
# lock file (used if ${__ONLY_ONCE} is ${__TRUE})
# Note: This is only a symbolic link
#
__LOCKFILE="/tmp/${__SCRIPTNAME}.lock"
__LOCKFILE_CREATED=${__FALSE}
## __NO_OF_WARNINGS - No of warnings found
##
typeset -i __NO_OF_WARNINGS=0
## __LIST_OF_WARNINGS - List of warning messages
##
__LIST_OF_WARNINGS=""
## __NO_OF_ERRORS - No of errors found
##
typeset -i __NO_OF_ERRORS=0
## __LIST_OF_ERRORS - List of error messages
##
__LIST_OF_ERRORS=""
## __LOGON_USERID - ID of the user opening the session
##
__LOGIN_USERID=$( set -- $( who am i ) ; echo $1 )
[ "${__LOGIN_USERID}" = "" ] && __LOGIN_USERID=${LOGNAME}
## __USERID - ID of the user executing this script (e.g. xtrnaw7)
##
__USERID=${__LOGIN_USERID}
[ -x /usr/ucb/whoami ] && __USERID=$( /usr/ucb/whoami )

## __RUNLEVEL - current runlevel


##
## __RUNLEVEL=$( set -- $( who -r ) ; echo $7 )
__RUNLEVEL=$( who -r | tr -s " " | cut -f8 -d " " )
# ----------------------------------------------------------------------------# color variables
## Colorattributes:
## __COLOR_OFF, __COLOR_BOLD, __COLOR_NORMAL, - normal, __COLOR_UNDERLINE
## __COLOR_BLINK, __COLOR_REVERSE, __COLOR_INVISIBLE
##
__COLOR_OFF="\033[0;m"
__COLOR_BOLD="\033[1m"
__COLOR_NORMAL="\033[2m"
__COLOR_UNDERLINE="\033[4m"
__COLOR_BLINK="\033[5m"
__COLOR_REVERSE="\033[7m"
__COLOR_INVISIBLE="\033[8m"
##
##
##
##
##
##
##
##

Foreground Color variables:


__COLOR_FG_BLACK, __COLOR_FG_RED,
__COLOR_FG_GREEN, __COLOR_FG_YELLOW
__COLOR_FG_BLUE, __COLOR_FG_MAGENTA, __COLOR_FG_CYAN, __COLOR_FG_WHITE
Background Color variables:
__COLOR_BG_BLACK, __COLOR_BG_RED,
__COLOR_BG_GREEN, __COLOR_BG_YELLOW
__COLOR_BG_BLUE, __COLOR_BG_MAGENTA, __COLOR_BG_CYAN, __COLOR_BG_WHITE

__COLOR_FG_BLACK="\033[30m"
__COLOR_FG_RED="\033[31m"
__COLOR_FG_GREEN="\033[32m"
__COLOR_FG_YELLOW="\033[33m"
__COLOR_FG_BLUE="\033[34m"
__COLOR_FG_MAGENTA="\033[35m"
__COLOR_FG_CYAN="\033[36m"
__COLOR_FG_WHITE="\033[37m"
__COLOR_BG_BLACK="\033[40m"
__COLOR_BG_RED="\033[41m"
__COLOR_BG_GREEN="\033[42m"
__COLOR_BG_YELLOW="\033[43m"
__COLOR_BG_BLUE="\033[44m"
__COLOR_BG_MAGENTA="\033[45m"
__COLOR_BG_CYAN="\033[46m"
__COLOR_BG_WHITE="\033[47m"
#
#
#
#
#
#
#
#
#

position cursor:
Clear rest of line:
Clear screen:
Save Cursor Pos
Restore Cursor Pos
Cursor Up # lines
Cursor down # lines
Cursor right # columns
Cursor left # columns

ESC[row,colH or ESC[row;colf (1,1 = upper left corner)


ESC[K
ESC[2J
ESC[s
ESC[u
ESC{colsA
ESC{colsB
ESC{colsC
ESC{colsD

# Get Cursor Pos


#

ESC[6n

# ----------------------------------------------------------------------------##
## ##### defined sub routines
##
## -------------------------------------## ReadConfigFile
##
## read the config file
##
## usage: ReadConfigFile [configfile]
##
## where: configfile - name of the config file
##
default: search ${__CONFIG_FILE} in the current directory,
##
in the home directory, and in /etc (in this order)
##
## returns: ${__TRUE} - ok config read
##
${__FALSE} - error config file not found or not readable
##
ReadConfigFile() {
typeset __FUNCTION="ReadConfigFile"; ${__DEBUG_CODE}
typeset THIS_CONFIG="$1"
typeset THISRC=${__FALSE}
if [ "${THIS_CONFIG}"x = ""x ] ; then
THIS_CONFIG="./${__CONFIG_FILE}"
[ ! -f ${THIS_CONFIG} ] && THIS_CONFIG="${HOME}/${__CONFIG_FILE}"
[ ! -f ${THIS_CONFIG} ] && THIS_CONFIG="/etc/${__CONFIG_FILE}"
fi
if [ -f ${THIS_CONFIG} ] ; then
LogMsg "Reading the config file \"${THIS_CONFIG}\" ..."
includeScript ${THIS_CONFIG}
THISRC=${__TRUE}
else
LogMsg "No config file (\"${__CONFIG_FILE}\") found (use -C to create a defa
ult config file)"
fi
return ${THISRC}
}
##
##
##
##
##
##
##
##
##
##
##

-------------------------------------WriteConfigFile
write the variable ${__CONFIG_PARAMETER} to the config file
usage: WriteConfigFile [configfile]
where: configfile - name of the config file
default: write ${__CONFIG_FILE} in the current directory
returns: ${__TRUE} - ok config file written

##
${__FALSE} - error writing the config file
##
WriteConfigFile() {
typeset __FUNCTION="WriteConfigFile" ; ${__DEBUG_CODE}
typeset THIS_CONFIG_FILE="$1"
typeset THISRC=${__FALSE}
[ "${THIS_CONFIG_FILE}"x = ""x ] && THIS_CONFIG_FILE="./${__CONFIG_FILE}"
[ -f "${THIS_CONFIG_FILE}" ] && BackupFileIfNecessary "${THIS_CONFIG_FILE}"
LogMsg "Writing the config file \"${THIS_CONFIG_FILE}\" ..."
cat <<EOT >"${THIS_CONFIG_FILE}"
# config file for $0
${__CONFIG_PARAMETER}
EOT
THISRC=$?
return ${THISRC}
}
## -------------------------------------## NoOfStackElements
##
## return the no. of stack elements
##
## usage: NoOfStackElements; var=$?
##
## returns: no. of elements on the stack
##
NoOfStackElements() {
typeset __FUNCTION="NoOfStackElements"; ${__DEBUG_CODE}
return ${__STACK_POINTER}
}
## -------------------------------------## FlushStack
##
## flush the stack
##
## usage: FlushStack
##
## returns: no. of elements on the stack before flushing it
##
FlushStack() {
typeset __FUNCTION="FlushStack";
${__DEBUG_CODE}
typeset THISRC=${__STACK_POINTER}
__STACK_POINTER=0
return ${THISRC}
}
##
##
##
##
##
##

-------------------------------------push
push one or more values on the stack
usage: push value1 [...] [value#]

##
## returns: ##
push() {
typeset __FUNCTION="push";

${__DEBUG_CODE}

while [ $# -ne 0 ] ; do
(( __STACK_POINTER=__STACK_POINTER+1 ))
__STACK[${__STACK_POINTER}]="$1"
shift
done
}
## -------------------------------------## pop
##
## pop one or more values from the stack
##
## usage: pop variable1 [...] [variable#]
##
## returns: ##
pop() {
typeset __FUNCTION="pop";
${__DEBUG_CODE}
typeset NEWALUE=""
while [ $# -ne 0 ] ; do
if [ ${__STACK_POINTER} -eq 0 ] ; then
NEWVALUE=""
else
NEWVALUE="${__STACK[${__STACK_POINTER}]}"
(( __STACK_POINTER=__STACK_POINTER-1 ))
fi
eval $1="\"${NEWVALUE}\""
shift
done
}
## -------------------------------------## CheckYNParameter
##
## check if a parameter is y, n, 0, or 1
##
## usage: CheckYNParameter parameter
##
## returns: ${__TRUE} - the parameter is equal to yes
##
${__FALSE} - the parameter is equal to no
##
CheckYNParameter(){
typeset __FUNCTION="CheckYNParameter";
${__DEBUG_CODE}
typeset THISRC=255
case $1 in
"y" | "Y" | "yes" | "YES" | "true" | "TRUE" | 0 ) THISRC=${__TRUE} ;;
"n" | "N" | "no" | "NO" | "false" | "FALSE" | 1 ) THISRC=${__FALSE} ;;
* ) THISRC=255 ;;
esac
return ${THISRC}

}
## -------------------------------------## ConvertToYesNo
##
## convert the value of a variable to y or n
##
## usage: ConvertToYesNo parameter
##
## returns: ##
prints y, n or ? to STDOUT
##
ConvertToYesNo(){
typeset __FUNCTION="ConvertToYesNo";
${__DEBUG_CODE}
case
"y"
"n"
* )
esac

$1 in
| "Y" | "yes" | "YES" | 0 ) echo "y" ;;
| "N" | "no" | "NO" | 1 ) echo "n" ;;
echo "?" ;;

}
## -------------------------------------## InvertSwitch
##
## invert a switch from true to false or vice versa
##
## usage: InvertSwitch variable
##
## returns nothing
##
switch the variable "variable" from ${__TRUE} to
##
${__FALSE} or vice versa
##
InvertSwitch(){
typeset __FUNCTION="InvertSwitch";
${__DEBUG_CODE}
eval "[ \$$1 -eq ${__TRUE} ] && $1=${__FALSE} || $1=${__TRUE} "
}
## -------------------------------------## CheckInputDevice
##
## check if the input device is a terminal
##
## usage: CheckInputDevice
##
## returns: 0 - the input device is a terminal (interactive)
##
1 - the input device is NOT a terminal
##
CheckInputDevice(){
typeset __FUNCTION="CheckInputDevice";
${__DEBUG_CODE}
tty -s
return $?
}
## -------------------------------------## GetProgramDirectory

##
## get the directory where a program resides
##
## usage: GetProgramDirectory [programpath/]programname [resultvar]
##
## returns: the variable PRGDIR contains the directory with the program
##
if the parameter resultvar is missing
##
GetProgramDirectory() {
typeset __FUNCTION="GetProgramDirectory";
${__DEBUG_CODE}
typeset PRG=""
typeset RESULTVAR=$2
if [ ! -L $1 ] ; then
PRG=$( cd -P -- "$(dirname -- "$(command -v -- "$1")")" && pwd -P )
else
# resolve links - $1 may be a softlink
PRG="$1"
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '.*/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`/"$link"
fi
done
PRG="$(dirname $PRG)"
fi
if [ "${RESULTVAR}"x != ""x ] ; then
eval ${RESULTVAR}=$PRG
else
PRGDIR=$PRG
fi
}
## -------------------------------------## substr
##
## get a substring of a string
##
## usage: variable=$( substr sourceStr pos length )
##
or substr sourceStr pos length resultStr
##
## returns: 1 - parameter missing
##
0 - parameter okay
##
substr() {
typeset __FUNCTION="substr";
${__DEBUG_CODE}
typeset resultstr=""
typeset THISRC=1
if [ "$1"x != ""x ] ; then
typeset s="$1"
typeset p="$2"
typeset l="$3"

[ "$l"x = ""x ] && l=${#s}


[ "$p"x = ""x ] && p=1
resultstr="$( echo $s | cut -c${p}-$((${p}+${l}-1)) )"
THISRC=0
else
THISRC=1
resultstr="$1"
fi
if [ "$4"x != ""x ] ; then
eval $4=\"${resultstr}\"
else
echo "${resultstr}"
fi
return ${THISRC}
}
## -------------------------------------## replacestr
##
## replace a substring with another substring
##
## usage: variable=$( replacestr sourceStr oldsubStr newsubStr )
##
or replacestr sourceStr oldsubStr newsubStr resultvariable
##
## returns: 0 - substring replaced
##
1 - substring not found
##
3 - error, parameter missing
##
##
writes the substr to STDOUT if resultvariable is missing
##
replacestr() {
typeset __FUNCTION="replacestr";
${__DEBUG_CODE}
typeset THISRC=3
typeset sourcestring="$1"
typeset oldsubStr="$2"
typeset newsubStr="$3"
if [ "${sourcestring}"x != ""x -a "${oldsubStr}"x != ""x ] ; then
if [[ "${sourcestring}" == *${oldsubStr}* ]] ; then
sourcestring="${sourcestring%%${oldsubStr}*}${newsubStr}${sourcestring#*${
oldsubStr}}"
THISRC=0
else
THISRC=1
fi
fi
if [ "$4"x != ""x ] ; then
eval $4=\"${sourcestring}\"
else
echo "${sourcestring}"
fi
return ${THISRC}
}

## -------------------------------------## pos
##
## get the first position of a substring in a string
##
## usage: pos searchstring sourcestring
##
## returns: 0 - searchstring is not part of sourcestring
##
else the position of searchstring in sourcestring
##
pos() {
typeset __FUNCTION="pos";
${__DEBUG_CODE}
typeset searchstring="$1"
typeset sourcestring="$2"
if [[ "${sourcestring}" == *${searchstring}* ]] ; then
typeset f=${sourcestring%%${searchstring}*}
return $(( ${#f}+1 ))
else
return 0
fi
}
## -------------------------------------## lastpos
##
## get the last position of a substring in a string
##
## usage: lastpos searchstring sourcestring
##
## returns: 0 - searchstring is not part of sourcestring
##
else the position of searchstring in sourcestring
##
lastpos() {
typeset __FUNCTION="lastpos";
${__DEBUG_CODE}
typeset searchstring="$1"
typeset sourcestring="$2"
if [[ "${sourcestring}" == *${searchstring}* ]] ; then
typeset f=${sourcestring%${searchstring}*}
return $(( ${#f}+1 ))
else
return 0
fi
}
## -------------------------------------## isNumber
##
## check if a value is an integer
##
## usage: isNumber testValue
##
## returns: ${__TRUE} - testValue is a number else not
##
isNumber() {
typeset __FUNCTION="isNumber";
${__DEBUG_CODE}

typeset TESTVAR="$(echo "$1" | sed 's/[0-9]*//g' )"


[ "${TESTVAR}"x = ""x ] && return ${__TRUE} || return ${__FALSE}
}
## -------------------------------------## ConvertToHex
##
## convert the value of a variable to a hex value
##
## usage: ConvertToHex value
##
## returns: ##
prints the value in hex to STDOUT
##
ConvertToHex(){
typeset __FUNCTION="ConvertToHex";
${__DEBUG_CODE}
typeset -i16 HEXVAR
HEXVAR=$1
echo ${HEXVAR##*#}
}
## -------------------------------------## ConvertToOctal
##
## convert the value of a variable to a octal value
##
## usage: ConvertToOctal value
##
## returns: ##
prints the value in octal to STDOUT
##
ConvertToOctal(){
typeset __FUNCTION="ConvertToOctal";
${__DEBUG_CODE}
typeset -i8 OCTVAR
OCTVAR=$1
echo ${OCTVAR##*#}
}
## -------------------------------------## ConvertToBinary
##
## convert the value of a variable to a binary value
##
## usage: ConvertToBinary value
##
## returns: ##
prints the value in binary to STDOUT
##
ConvertToBinary(){
typeset __FUNCTION="ConverToBinary"; ${__DEBUG_CODE}
typeset -i2 BINVAR
BINVAR=$1
echo ${BINVAR##*#}
}

## -------------------------------------## toUppercase
##
## convert a string to uppercase
##
## usage: toUppercase sourceString | read resultString
##
or targetString=$( toUppercase sourceString )
##
or toUppercase sourceString resultString
##
## returns: writes the converted string to STDOUT if resultString is missing
##
toUppercase() {
typeset __FUNCTION="toUppercase";
${__DEBUG_CODE}
typeset -u testvar="$1"
if [ "$2"x != ""x ] ; then
eval $2=\"${testvar}\"
else
echo "${testvar}"
fi
}
## -------------------------------------## toLowercase
##
## convert a string to lowercase
##
## usage: toLowercase sourceString | read resultString
##
or targetString=$( toLowercase sourceString )
##
or toLowercase sourceString resultString
##
## returns: writes the converted string to STDOUT if resultString is missing
##
toLowercase() {
typeset __FUNCTION="toLowercase";
${__DEBUG_CODE}
typeset -l testvar="$1"
if [ "$2"x != ""x ] ; then
eval $2=\"${testvar}\"
else
echo "${testvar}"
fi
}
## -------------------------------------## executeCommand
##
## execute a command
##
## usage: executeCommand command parameter
##
## returns: the RC of the executed command
##
executeCommand() {
typeset __FUNCTION="executeCommand";
${__DEBUG_CODE}
set +e

LogInfo "Executing \"$@\" "


eval "$@"
}
## -------------------------------------## executeCommandAndLog
##
## execute a command and write STDERR and STDOUT to the logfile
##
## usage: executeCommandAndLog command parameter
##
## returns: the RC of the executed command
##
executeCommandAndLog() {
typeset __FUNCTION="executeCommandAndLog";
${__DEBUG_CODE}
set +e
typeset THISRC=0
LogRuntimeInfo "Executing \"$@\" "
if [ "${__LOGFILE}"x != ""x -a -f ${__LOGFILE} ] ; then
eval "$@" 2>&1 | tee -a ${__LOGFILE}
THISRC=$?
else
eval "$@"
THISRC=$?
fi
return ${THISRC}
}
## -------------------------------------## executeCommandAndLog
##
## execute a command and write STDERR to the logfile
##
## usage: executeCommandAndLogSTDERR command parameter
##
## returns: the RC of the executed command
##
executeCommandAndLogSTDERR() {
typeset __FUNCTION="executeCommandAndLogSTDERR";
${__DEBUG_CODE}
set +e
typeset THISRC=0
LogRuntimeInfo "Executing \"$@\" "
if [ "${__LOGFILE}"x != ""x -a -f ${__LOGFILE} ] ; then
eval "$@" 2>>${__LOGFILE}
THISRC=$?
else
eval "$@"
THISRC=$?
fi
return ${THISRC}
}

## -------------------------------------## UserIsRoot
##
## validate the user id
##
## usage: UserIsRoot
##
## returns: ${__TRUE} - the user is root; else not
##
UserIsRoot() {
typeset __FUNCTION="UserIsRoot";
${__DEBUG_CODE}
[ $( id | sed 's/uid=\([0-9]*\)(.*/\1/' ) = 0 ] && return ${__TRUE} || return
${__FALSE}
#) dummy comment for the syntax highlighting to work correct
}
## -------------------------------------## UserIs
##
## validate the user id
##
## usage: UserIs USERID
##
## where: USERID - userid (e.g oracle)
##
## returns: 0 - the user is this user
##
1 - the user is NOT this user
##
2 - the user does not exist on this machine
##
3 - missing parameter
##
UserIs() {
typeset __FUNCTION="UserIs";
${__DEBUG_CODE}
typeset THISRC=3
typeset USERID=""
if [ "$1"x != ""x ] ; then
THISRC=2
USERID=$( grep "^$1:" /etc/passwd | cut -d: -f3 )
if [ "${USERID}"x != ""x ] ; then
UID=`id | sed 's/uid=\([0-9]*\)(.*/\1/'`
[ ${UID} = ${USERID} ] && THISRC=0 || THISRC=1
fi
fi
return ${THISRC}
}
##
##
##
##
##
##
##
##
##

-------------------------------------GetCurrentUID
get the UID of the current user
usage: GetCurrentUID
where: -

## returns: the UID


##
GetCurrentUID() {
typeset __FUNCTION="GetCurrentUID";

${__DEBUG_CODE}

return `id | sed 's/uid=\([0-9]*\)(.*/\1/'`


}
## -------------------------------------## GetUserName
##
## get the name of a user
##
## usage: GetUserName UID
##
## where: UID - userid (e.g 1686)
##
## returns: __USERNAME contains the user name or "" if
##
the userid does not exist on this machine
##
GetUserName() {
typeset __FUNCTION="GetUserName";
${__DEBUG_CODE}
[ "$1"x != ""x ] && __USERNAME=$( grep ":$1:" /etc/passwd | cut -d: -f1 ) ||
__USERNAME=""
}
## -------------------------------------## GetUID
##
## get the UID for a username
##
## usage: GetUID username
##
## where: username - user name (e.g nobody)
##
## returns: __USER_ID contains the UID or "" if
##
the username does not exist on this machine
##
GetUID() {
typeset __FUNCTION="GetUID";
${__DEBUG_CODE}
[ "$1"x != ""x ] && __USER_ID=$( grep "^$1:" /etc/passwd | cut -d: -f3 ) || _
_USER_ID=""
}
# ======================================
##
##
##
##
##
##
##
##
##
##
##

-------------------------------------LogMsg
print a message to STDOUT and write it also to the logfile
usage: LogMsg message
returns: Notes: Use "-" to print a complete blank line

LogMsg() {
typeset __FUNCTION="LogMsg";

${__DEBUG_CODE}

if [ "$*"x = "-"x ] ; then


typeset THISMSG=""
else
typeset THISMSG="[$(date +"%d.%m.%Y %H:%M:%S")] $*"
fi
[ ${__QUIET_MODE} -ne ${__TRUE} ] && echo "${THISMSG} "
[ "${__LOGFILE}"x != ""x ] && [ -f ${__LOGFILE} ] && echo "${THISMSG}" >>${__
LOGFILE}
}
## -------------------------------------## LogOnly
##
## write a message to the logfile
##
## usage: LogOnly message
##
## returns: ##
LogOnly() {
typeset __FUNCTION="LogOnly";
${__DEBUG_CODE}
typeset THISMSG="[$(date +"%d.%m.%Y %H:%M:%S")] $*"
[ "${__LOGFILE}"x != ""x ] && [ -f ${__LOGFILE} ] && echo "${THISMSG}" >>${__
LOGFILE}
}
## -------------------------------------## LogInfo
##
## print a message to STDOUT and write it also to the logfile
## only if in verbose mode
##
## usage: LogInfo [loglevel] message
##
## returns: ##
## Notes: Output goes to STDERR, default loglevel is 0
##
LogInfo() {
typeset __FUNCTION="LogInfo";
${__DEBUG_CODE}
# [ ${__VERBOSE_MODE} -eq ${__TRUE} ] && LogMsg "INFO: $*"
typeset THISLEVEL=0
if [ ${__VERBOSE_MODE} -eq ${__TRUE} ] ; then
if [ $# -gt 1 ] ; then
isNumber $1
if [ $? -eq ${__TRUE} ] ; then
THISLEVEL=$1
shift
fi
fi

[ ${__VERBOSE_LEVEL} -gt ${THISLEVEL} ] && LogMsg "INFO: $*" >&2


fi
}
# internal sub routine for info messages
#
#
LogRuntimeInfo() {
typeset __FUNCTION="LogRuntimeInfo";
${__DEBUG_CODE}
LogInfo "${__RT_VERBOSE_LEVEL}" "$*"
}
## -------------------------------------## LogWarning
##
## print a warning to STDOUT and write it also to the logfile
##
## usage: LogWarning message
##
## returns: ##
## Notes: Output goes to STDERR
##
LogWarning() {
typeset __FUNCTION="LogWarning";
${__DEBUG_CODE}
LogMsg "WARNING: $*" >&2
(( __NO_OF_WARNINGS = __NO_OF_WARNINGS +1 ))
__LIST_OF_WARNINGS="${__LIST_OF_WARNINGS}
WARNING: $*"
}
## -------------------------------------## LogError
##
## print an error message to STDOUT and write it also to the logfile
##
## usage: LogError message
##
## returns: ##
## Notes: Output goes to STDERR
##
LogError() {
typeset __FUNCTION="LogError";
${__DEBUG_CODE}
LogMsg "ERROR: $*" >&2
(( __NO_OF_ERRORS=__NO_OF_ERRORS + 1 ))
__LIST_OF_ERRORS="${__LIST_OF_ERRORS}
ERROR: $*"
}
## --------------------------------------## BackupFileIfNecessary
##
## create a backup of a file if ${__OVERWRITE_MODE} is set to ${__FALSE}
##

## usage: BackupFileIfNecessary [file1} ... {filen}


##
## returns: 0 - done; else error
##
BackupFileIfNecessary() {
typeset __FUNCTION="BackupFileIfNecessary";
${__DEBUG_CODE}
[ "${BACKUP_EXTENSION}"x = ""x ] && BACKUP_EXTENSION=".$$"
typeset
typeset
typeset
typeset

FILES_TO_BACKUP="$*"
CURFILE=""
CUR_BKP_FILE=""
THISRC=0

if [ ${__OVERWRITE_MODE} -eq ${__FALSE} ] ; then


for CURFILE in ${FILES_TO_BACKUP} ; do
[ ! -f ${CURFILE} ] && continue
CUR_BKP_FILE="${CURFILE}${BACKUP_EXTENSION}"
LogMsg "Creating a backup of \"${CURFILE}\" in \"${CUR_BKP_FILE}\" ..."
cp ${CURFILE} CUR_BKP_FILE
THISRC=$?
if [ ${THISRC} -ne 0 ] ; then
LogError "Error creating the backup of the file ${CURFILE}"
break
fi
done
fi
}
## --------------------------------------## CopyDirectory
##
## copy a directory
##
## usage: CopyDirectory sourcedir targetDir
##
## returns: 0 - done;
##
else error
##
CopyDirectory() {
typeset __FUNCTION="CopyDirectory";
${__DEBUG_CODE}
typeset THISRC=1
if [ "$1"x != ""x -a "$2"x != ""x ] ; then
if [ -d $1 -a -d $2 ] ; then
LogMsg "Copying all files from \"$1\" to \"$2\" ..."
cd $1
find . -depth -print | cpio -pdumv $2
THISRC=$?
cd ${OLDPWD}
fi
fi
return ${THISRC}
}
## -------------------------------------## AskUser

##
## Ask the user (or use defaults depending on the parameter -n and -y)
##
## Usage: AskUser "message"
##
## returns: ${__TRUE} - user input is yes
##
${__FALSE} - user input is no
##
USER_INPUT contains the user input
##
## Notes: "all" is interpreted as yes for this and all other questions
##
"none" is interpreted as no for this and all other questions
##
AskUser() {
typeset __FUNCTION="AskUser";
${__DEBUG_CODE}
typeset THISRC=""
case ${__USER_RESPONSE_IS} in
"y" ) USER_INPUT="y" ; THISRC=${__TRUE}
;;
"n" ) USER_INPUT="n" ; THISRC=${__FALSE}
;;
* ) [ $# -ne 0 ] && LogMsg "$*"
read USER_INPUT
case ${USER_INPUT} in
"y" | "Y" ) THISRC=${__TRUE} ;;
"n" | "N" ) THISRC=${__FALSE} ;;
"all" ) __USER_RESPONSE_IS="y" ; THISRC=${__TRUE} ;;
"none" ) __USER_RESPONSE_IS="n" ; THISRC=${__FALSE} ;;
"*" ) THISRC=${__FALSE} ;;
esac
;;
esac
return ${THISRC}
}
#!/bin/sh
##
##
##
##
##
##
##
##
##
##
##

-------------------------------------GetKeystroke
read one key from STDIN
Usage: GetKeystroke "message"
returns: USER_INPUT contains the user input

GetKeystroke () {
typeset __FUNCTION="GetKeystroke";

${__DEBUG_CODE}

trap "" 2 3
[ $# -ne 0 ] && LogMsg "${THISMSG}"
typeset oldSttySettings=$( stty -g )
stty -echo raw
USER_INPUT=$( dd count=1 2> /dev/null )
stty $oldSttySettings
trap 2 3
}
## -------------------------------------## RebootIfNecessary
##
## Check if a reboot is necessary
##
## Usage: RebootIfNecessary
##
## Notes
## The routine asks the user if neither the paramteer -y nor the
## parameter -n is used
## Before using this routine uncomment the reboot command!
##
RebootIfNecessary() {
typeset __FUNCTION="RebootIfNecessary";
${__DEBUG_CODE}
if [ ${__REBOOT_REQUIRED} -eq 0 ] ; then
LogMsg "The changes made to the system require a reboot"
AskUser "Do you want to reboot now (y/n, default is NO)?"
if [ $? -eq ${__TRUE} ] ; then
LogMsg "Rebooting now ..."
echo "???" reboot ${__REBOOT_PARAMETER}
fi
fi
}
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##

--------------------------------------die
print a message and end the program
usage: die returncode {message}
returns: Notes:
This routine
- calls cleanup
- prints an error message if any (if returncode is not zero)
or the message if any (if returncode is zero)
- prints all warning messages again if ${__PRINT_LIST_OF_WARNING_MSGS}
is ${__TRUE}
- prints all error messages again if ${__PRINT_LIST_OF_ERROR_MSGS}
is ${__TRUE}
- prints a program end message and the program return code
and

##
- and ends the program
##
## If the variable ${__FORCE} is ${__TRUE} and the return code is NOT zero
## die() will only print the error message and return
##
die() {
typeset __FUNCTION="die";
${__DEBUG_CODE}
typeset THISRC=$1
shift
if [ "$*"x != ""x ] ; then
[ ${THISRC} = 0 ] && LogMsg "$*" || LogError "$*"
fi
[ ${__FORCE} = ${__TRUE} -a ${THISRC} != 0 ] && return
cleanup
if [ "${__NO_OF_WARNINGS}" != "0" -a ${__PRINT_LIST_OF_WARNINGS_MSGS} -eq ${__
TRUE} ] ; then
LogMsg "*** CAUTION: One or more WARNINGS found ***"
LogMsg "*** please check the logfile ***"
LogMsg "Summary of warnings:
${__LIST_OF_WARNINGS}
"
fi
if [ "${__NO_OF_ERRORS}" != "0" -a ${__PRINT_LIST_OF_ERROR_MSGS} -eq ${__TRUE}
] ; then
LogMsg "*** CAUTION: One or more ERRORS found ***"
LogMsg "*** please check the logfile ***"
LogMsg "Summary of error messages
${__LIST_OF_ERRORS}
"
fi
[[ -n ${__LOGFILE} ]] && LogMsg "The log file used was \"${__LOGFILE}\" "
__QUIET_MODE=${__FALSE}
LogMsg "${__SCRIPTNAME} ended on $( date )."
LogMsg "The RC is ${THISRC}."
__EXIT_VIA_DIE=${__TRUE}
exit ${THISRC}
}
# ======================================
##
## ##### defined internal sub routines (do NOT use; these routines are called
##
by the runtime system!)
##
# -------------------------------------## CreateLockFile
#
# Create the lock file (which is really a symbolic link) if possible

#
# usage: CreateLockFile
#
# returns: 0 - lock created
#
1 - lock already exist or erro creating the lock
#
# Note: Use a symbolic link because this is always a atomic operation
#
CreateLockFile() {
typeset __FUNCTION="CreateLockFile";
${__DEBUG_CODE}
typeset LN_RC=""
ln -s $0 "${__LOCKFILE}" 2>/dev/null
LN_RC=$?
if [ ${LN_RC} = 0 ] ; then
__LOCKFILE_CREATED=${__TRUE}
return 0
else
return 1
fi
}
# -------------------------------------## RemoveLockFile
#
# Remove the lock file if possible
#
# usage: RemoveLockFile
#
# returns: 0 - lock file removed
#
1 - lock file does not exist
#
2 - error removing the lock file
#
RemoveLockFile() {
typeset __FUNCTION="RemoveLockFile";
${__DEBUG_CODE}
[ ! -L "${__LOCKFILE}" ] && return 1
if [ ${__LOCKFILE_CREATED} -eq ${__TRUE} ] ; then
rm "${__LOCKFILE}" 1>/dev/null 2>/dev/null
[ $? -eq 0 ] && return 0
fi
return 2
}
# ======================================
# -------------------------------------## CreateTemporaryFiles
#
# create the temporary files
#
# usage: CreateTemporaryFiles
#
# returns: #
CreateTemporaryFiles() {
typeset __FUNCTION="CreateTemporaryFiles";

${__DEBUG_CODE}

typeset CURFILE=
__TEMPFILE_CREATED=${__TRUE}
LogRuntimeInfo "Creating the temporary files \"${__LIST_OF_TEMPFILES}\" ..."
for CURFILE in ${__LIST_OF_TEMPFILES} ; do
LogRuntimeInfo "Creating the temporary file \"${CURFILE}\" "
echo >"${CURFILE}" || return $?
# delete the file a program end
__LIST_OF_TMP_FILES="${__LIST_OF_TMP_FILES} ${CURFILE}"
done
return 0
}
# ======================================
# ======================================
##
## --------------------------------------## cleanup
##
## house keeping at program end
##
## usage: [called by the runtime system]
##
## returns: ##
## notes:
## execution order is
##
- call exit routines from ${__EXITROUTINES}
##
- remove files from ${__LIST_OF_TMP_FILES}
##
- umount mount points ${__LIST_OF_TMP_MOUNTS}
##
- remove directories ${__LIST_OF_TMP_DIRS}
##
cleanup() {
typeset __FUNCTION="cleanup";
${__DEBUG_CODE}
typeset EXIT_ROUTINE=
typeset OLDPWD=$( pwd )
cd /tmp
# call the defined exit routines
if [ "${__EXITROUTINES}"x != ""x ] ; then
LogRuntimeInfo "Executing the exit routines \"${__EXITROUTINES}\" ..."
for EXIT_ROUTINE in ${__EXITROUTINES} ; do
LogRuntimeInfo "Now calling the exit routine \"${EXIT_ROUTINE}\" ..."
eval ${EXIT_ROUTINE}
done
fi
# remove temporary files
for CURENTRY in ${__LIST_OF_TMP_FILES} ; do
LogRuntimeInfo "Removing the file \"${CURENTRY}\" ..."
if [ -f "${CURENTRY}" ] ; then

rm "${CURENTRY}"
[ $? -ne 0 ] && LogWarning "Error removing the file \"${CURENTRY}\" "
fi
done
# remove temporary mounts
typeset CURENTRY
for CURENTRY in ${__LIST_OF_TMP_MOUNTS} ; do
mount | grep "^${CURENTRY} " 1>/dev/null 2>/dev/null
if [ $? -eq 0 ] ; then
LogRuntimeInfo "Umounting \"${CURENTRY}\" ..."
umount "${CURENTRY}"
[ $? -ne 0 ] && LogWarning "Error umounting \"${CURENTRY}\" "
fi
done
# remove temporary directories
for CURENTRY in ${__LIST_OF_TMP_DIRS} ; do
LogRuntimeInfo "Removing the directory \"${CURENTRY}\" ..."
if [ -d "${CURENTRY}" ] ; then
rm -r "${CURENTRY}" 2>/dev/null
[ $? -ne 0 ] && LogWarning "Error removing the directory \"${CURENTRY}\" "
fi
done
[ -d "${OLDPWD}" ] && cd "${OLDPWD}"
}

## --------------------------------------## includeScript
##
## include a script via . [scriptname]
##
## usage: includeScript [scriptname]
##
## returns: ##
## notes:
##
includeScript() {
typeset __FUNCTION="includeScript";
${__DEBUG_CODE}
if [ $# -ne 0 ] ; then
# install trap handler
trap "GENERAL_SIGNAL_HANDLER
trap "GENERAL_SIGNAL_HANDLER
trap "GENERAL_SIGNAL_HANDLER
trap "GENERAL_SIGNAL_HANDLER
trap "GENERAL_SIGNAL_HANDLER

1" 1
2" 2
3" 3
15" 15
exit" exit

LogInfo "Including the script \"$*\" ..."


# set the variable for the TRAP handlers
__INCLUDE_SCRIPT_RUNNING="$1"
[ ! -f "$1" ] && die 247 "Include script \"$1\" not found"
# include the script

. $*
# reset the variable for the TRAP handlers
__INCLUDE_SCRIPT_RUNNING=""
fi
}
##
## ##### defined trap handler (you may change them)
##
## --------------------------------------## GENERAL_SIGNAL_HANDLER
##
## general trap handler
##
## usage: called automatically (parameter $1 is the signal number)
##
## returns: ##
GENERAL_SIGNAL_HANDLER() {
typeset __FUNCTION="GENERAL_SIGNAL_HANDLER";
${__DEBUG_CODE}
[ "${__INCLUDE_SCRIPT_RUNNING}"x != ""x ] && LogMsg "Trap occured inside of th
e include script \"${__INCLUDE_SCRIPT_RUNNING}\" "
case $1 in
1 )
LogWarning "HUP signal received."
InvertSwitch __VERBOSE_MODE
LogMsg "Switching verbose mode to $( ConvertToYesNo ${__VERBOSE_MODE} )"
;;
2 )
if [ ${__USER_BREAK_ALLOWED} -eq ${__TRUE} ] ; then
die 252 "Script aborted by the user via signal BREAK (CTRL-C)"
else
LogRuntimeInfo "Break signal (CTRL-C) received and ignored (Break is d
isabled)."
fi
;;
3 )
die 251 "QUIT signal received"
;;
15 )
die 253 "Script aborted by the external signal TERM"
;;
"exit" | 0 )
if [ "${__EXIT_VIA_DIE}"x != "${__TRUE}"x ] ; then
LogWarning "You should use the function \"die\" to end the program"
fi
return
;;

* ) die 254 "Unknown signal catched: $1 "


;;
esac
}
# ======================================
## --------------------------------------## DebugHandler
##
## handler for single step mode
##
## usage: called automatically
##
## returns: the RC of the previous executed command
##
DebugHandler() {
typeset __FUNCTION="DebugHandler";
${__DEBUG_CODE}
[ "${__DEBUG_MODE}" -ne ${__TRUE} ] && return ${__LAST_RC}
stty erase ^H
typeset __THIS_PID=$$
typeset -i i=0
typeset -i j=0
if [ "${__USE_COLORS}"x = "${__TRUE}"x ] ; then
typeset __LINE_COLOR="\033[0;36m\033[44m"
typeset __CUR_LINE_COLOR="\033[0;34m\033[46m"
typeset __DEBUG_MSG_COLOR="\033[0;31m\033[48m"
typeset __COLOR_OFF="\033[0;m"
else
typeset __LINE_COLOR=""
typeset __CUR_LINE_COLOR=""
typeset __DEBUG_MSG_COLOR=""
typeset __COLOR_OFF=""
fi
COLUMNS=80
[ -x /usr/openwin/bin/resize ] && eval $( /usr/openwin/bin/resize )
eval "typeset -L${COLUMNS} LINE_VAR"
# typeset -L80 __LINE_VAR=""
typeset __USERINPUT=""
set -o emacs
alias
alias
alias
alias
alias
alias
)

__A=$(print
__B=$(print
__C=$(print
__D=$(print
__H=$(print
__P=$(print

"\020")
"\016")
"\006")
"\002")
"\001")
"\004")

#
#
#
#
#
#

up arrow
down arrow
right arrow
left arrow
home
delete

->
->
->
->
->
->

Ctrl-P
Ctrl-N
Ctrl-F
Ctrl-B
Ctrl-A
Ctrl-D

(previous cmd)
(next cmd)
(move forward 1 char)
(move backward 1 char)
(go to beginning of line)
(delete char under cursor

alias __@=" "


alias __Q=$(print "\005")
alias __Z=$(print "\017")

# end
# end

-> Ctrl-E (go to end of line)


-> Ctrl-O (operate)

export HISTFILE="${__DEBUG_HISTFILE}"
# check for the break points
if [ "${__BREAKPOINT_LINE}"x != "0"x ] ; then
if [ "${__BREAKPOINT_LINE}" -ge "${__LINENO}" ] ; then
__LINE_VAR="*** DEBUG: Break point at line ${__LINENO} found"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
__BREAKPOINT_LINE=0
else
return ${__LAST_RC}
fi
fi
if [ "${__STEP_COUNT}"x != "0"x ] ; then
__STEP_COUNT=$(( __STEP_COUNT - 1 ))
if [ "${__STEP_COUNT}"x = "0"x ] ; then
__LINE_VAR="*** DEBUG: Break point at line ${__LINENO} found"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
else
return ${__LAST_RC}
fi
fi
# read the script into an array (only once!)
if [ ${__SCRIPT_ARRAY[0]} = 0 ] ; then
typeset oIFS=$IFS
IFS="\n"
i=1
while read -r __SCRIPT_ARRAY[$i] ; do
i=$(( i+1 ))
done <$0
__SCRIPT_ARRAY[0]=$i
IFS=$oIFS
fi
# define the variables for the output
i=${__SCRIPT_ARRAY[0]}
eval "typeset -R${#i} NUM_VAR"
j=$(( ${COLUMNS} - ${#i} -1 ))
# eval "typeset -L${j} __SRCLINE_VAR"
eval "typeset -L${COLUMNS} __SRCLINE_VAR"
if [ "${__TRACE_COUNT}"x != "0"x ] ; then
__SRCLINE_VAR="${NUM_VAR}>>> ${__SCRIPT_ARRAY[${__LINENO}]}"
print -u 2 "${__CUR_LINE_COLOR}${__SRCLINE_VAR}"
__TRACE_COUNT=$(( ${__TRACE_COUNT}-1 ))
print "${__COLOR_OFF}"
return ${__LAST_RC}
fi

#
#
#
#
#
#

write the script to a file


i=1
while [ i -lt ${__SCRIPT_ARRAY[0]} ] ; do
echo "$i ${__SCRIPT_ARRAY[$i]}" >>./test.out
i=$(( i+1 ))
done
__LINE_VAR=""
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
__LINE_VAR="*** DEBUG: Executed line: ${__LINENO}"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
__LINE_VAR="*** DEBUG: Line Context:"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
[ ${__LINENO} -gt 5 ] && i=$(( ${__LINENO}-5 )) || i=1
typeset CUR_SRC_WIN_START=$i
j=$(( ${__LINENO}+5 ))
[ ${j} -gt ${__SCRIPT_ARRAY[0]} ] && j=${__SCRIPT_ARRAY[0]}

# write the context of the line just executed


while [ i -lt j ] ; do
NUM_VAR=$i
if [ $i -eq ${__LINENO} ] ; then
__SRCLINE_VAR="${NUM_VAR}>>> ${__SCRIPT_ARRAY[$i]}"
print -u 2 "${__CUR_LINE_COLOR}${__SRCLINE_VAR}"
else
__SRCLINE_VAR="${NUM_VAR}
${__SCRIPT_ARRAY[$i]}"
print -u 2 "${__LINE_COLOR}${__SRCLINE_VAR}"
fi
i=$(( i+1 ))
done
print "${__COLOR_OFF}"
# read the user input
#
__LINE_VAR="*** DEBUG: \$\$ is ${__THIS_PID}; \$? is ${__LAST_RC}; \$! is ${__
LAST_BG_RC}"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
__LINE_VAR="*** DEBUG: Enter a command to execute or <enter> to execute the ne
xt command:"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
while [ 1 = 1 ] ; do
print -u 2 -n "${__DEBUG_MSG_COLOR}DEBUG>>> "
read -s __USERINPUT __USERPARMS __USERVALUE __USERVALUE2
case ${__USERINPUT} in
"help" | "?" ) __LINE_VAR="*** DEBUG:Known commands"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
cat 1>&2 <<EOT
help
trace count
trace off
trace at lineNo
trace not lineNumber
show lineNo [count]
exit [returncode]

- print this text


- execute count lines
- turn single mode off
- suspend single step until line linNo
- suspend single step for lineNumber statements
- show count (def. 10) lines after line lineNo
- exit the program with RC returnCode (def.: 1)

<return>
everything else

- execute next statement (single step)


- execute the command

EOT
;;
"" ) break
;;
"trace" ) :
case ${__USERPARMS} in
"off" )
__LINE_VAR="*** DEBUG: Turning single step mode off"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
__DEBUG_MODE=${__FALSE}
break
;;
"at" )
if [ "${__USERVALUE}"x = ""x ] ; then
__LINE_VAR="*** DEBUG: value missing"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
continue
fi
isNumber ${__USERVALUE} 2>/dev/null
if [ $? -ne 0 ] ; then
__LINE_VAR="*** DEBUG: \"${__USERVALUE}\" is not a number"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
continue
fi
__LINE_VAR="*** DEBUG: Suspending single step until line ${__USERV
ALUE}"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
__BREAKPOINT_LINE=${__USERVALUE}
break
;;
"not" )
if [ "${__USERVALUE}"x = ""x ] ; then
__LINE_VAR="*** DEBUG: value missing"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
continue
fi
isNumber ${__USERVALUE} 2>/dev/null
if [ $? -ne 0 ] ; then
__LINE_VAR="*** DEBUG: \"${__USERVALUE}\" is not a number"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
continue
fi
__LINE_VAR="*** DEBUG: Suspending single step for the next ${__USE
RVALUE} statements"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
__STEP_COUNT=${__USERVALUE}
break

;;
* )
isNumber ${__USERPARMS} 2>/dev/null
if [ $? -eq 0 ] ; then
__TRACE_COUNT=${__USERPARMS}
__LINE_VAR="*** DEBUG: Executing \"${__USERPARMS}\" lines"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
break
else
__LINE_VAR="*** DEBUG: unknown trace option \"${__USERPARMS}\" "
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
fi
;;
esac
;;
"show" )
[ "${__USERPARMS}"x = ""x ] && __USERPARMS=${CUR_SRC_WIN_START}
isNumber ${__USERPARMS} 2>/dev/null
if [ $? -ne 0 ] ; then
__LINE_VAR="*** DEBUG: \"${__USERPARMS}\" is not a number"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
continue
fi
if [ ${__USERPARMS} -lt 1 ] ; then
__LINE_VAR="*** DEBUG: \"${__USERPARMS}\" is out of range"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
continue
fi
if [ "${__USERPARMS}" -gt ${__SCRIPT_ARRAY[0]} ] ; then
__LINE_VAR="*** DEBUG: \"${__USERPARMS}\" is out of range (last lin
e is ${__SCRIPT_ARRAY[0]})"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
continue
fi
i=${__USERPARMS}
if [ "${__USERVALUE}"x != ""x ] ; then
isNumber ${__USERVALUE} 2>/dev/null
if [ $? -ne 0 ] ; then
__LINE_VAR="*** DEBUG: \"${__USERVALUE}\" is not a number"
print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
continue
fi
j=$(( ${i}+ ${__USERVALUE} -1 ))
else
j=$(( ${i}+9 ))
fi
[ ${j} -gt ${__SCRIPT_ARRAY[0]} ] && j=${__SCRIPT_ARRAY[0]}
while [ i -le j ] ; do
NUM_VAR=$i

if [ $i -eq ${__LINENO} ] ; then


__SRCLINE_VAR=">>> ${__SCRIPT_ARRAY[$i]}"
print -u 2 "${__CUR_LINE_COLOR}${NUM_VAR} ${__SRCLINE_VAR}"
else
__SRCLINE_VAR="
${__SCRIPT_ARRAY[$i]}"
print -u 2 "${__LINE_COLOR}${NUM_VAR} ${__SRCLINE_VAR}"
fi
i=$(( i+1 ))
done
;;
"exit" | "quit" ) :
print "${__COLOR_OFF}"
[ "${__USERPARMS}"x = ""x ] && die 252 "Program aborted by the user"
die ${__USERPARMS}
;;
* ) executeCommand ${__USERINPUT} ${__USERPARMS} ${__USERVALUE} ${__USERVA
LUE2}
;;
esac
done
print "${__COLOR_OFF}"
return ${__LAST_RC}
}
##
## ##### defined sub routines
##
## --------------------------------------## ShowShortUsage
##
## print the (short) usage help
##
## usage: ShowShortUsage
##
## returns: ##
ShowShortUsage() {
typeset __FUNCTION="ShowShortUsage";
${__DEBUG_CODE}
cat <<EOT
${__SCRIPTNAME} ${__SCRIPT_VERSION} - ${__SHORT_DESC}
Usage: ${__SCRIPTNAME} [-v|+v] [-q|+q] [-h] [-l logfile|+l] [-y|+y] [-n|+n]
[-D|+D] [-a|+a] [-O|+O] [-f|+f] [-C] [-H] [-S n]
-z zone_name -i zone_ip_address [-p zone_path]
[-A zone_network_adapter] [-b|+b] [-s freespace] [-x key=val
ue]
Known keys for -x :
zone_name zone_ip_address zone_network_interface zone_mode zone_path
zone_root_password zone_tz zone_locale zone_terminal zone_timeserver
zone_customize_script_source zone_customize_script_target use_existing_names
erver_config
zone_autboot boot_the_zone_now free_space_for_the_zone zone_profile

zone_finish_script
EOT
}
## --------------------------------------## ShowUsage
##
## print the (long) usage help
##
## usage: ShowUsage
##
## returns: ##
ShowUsage() {
typeset __FUNCTION="ShowUsage";
${__DEBUG_CODE}
ShowShortUsage
cat <<EOT
Note: Use -{switch} to turn an option on; use +{switch} to turn an option off
Parameter:
-v|+v - turn verbose mode on/off; current value: $( ConvertToYesNo "${__VE
RBOSE_MODE}" )
-q|+q - turn quiet mode on/off; current value: $( ConvertToYesNo "${__QUIE
T_MODE}" )
-h
- show usage
-l
- set the logfile
current value: ${NEW_LOGFILE:=${__DEF_LOGFILE}}
+l
- do not write a logfile
-y|+y - assume yes to all questions or not
-n|+n - assume no to all questions or not
-D|+D - run main in single step mode (and turn colors on)
-a|+a - turn colors on/off; current value: $( ConvertToYesNo "${__USE_COLO
RS}" )
-O|+O - overwrite existing files or not; current value: $( ConvertToYesNo
"${__OVERWRITE_MODE}" )
-f|+f - force; do it anyway
-C - write a default config file in the current directory and exit
-S n - print error/warning summaries: n = 0 on summarys, 1 = print error
msgs,
2 = print warning msgs, 3 = print error and warning mgs
Default: ${__PRINT_SUMMARIES}
-H
- write extended usage to STDERR
-z
-i
-p
-A
-b
+b
-s
-x

zone name, mandatory, no default


zone ip address, mandatory, no default
zone path; current value: ${ZONE_PATH}
zone network adapter; the default depends on the IP address choosen
create a big zone
create a small zone
freespace in KB necessary for the zone
key=value

Known key/value pairs for the parameter -x are


zone_name=name_of_the_zone, no default

shortcut: -z
address=ip_address_for_the_zone, no default
or
zone_ip_address=ip_address_for_the_zone, no default
shortcut: -i
zone_network_interface=network_interface_for_the_zone
or
physical=network_interface_for_the_zone
the default depends on the IP address choosen for the zone
shortcut: -A
zone_mode=[small|big]
current value: ${ZONE_MODE}
shortcut: -b|+b
zonepath=path_for_the_zone
or
zone_path=path_for_the_zone
current value: ${ZONE_PATH}
shortcut: -p
The zone will be created in the directory [zone_path]/[zone_name]
zone_root_password=encrypted_password_for_root
current value: ${ZONE_ROOT}
The default is the root passwort of the global zone
Use none for no root user password
zone_tz=timezone_for_the_zone
current value: ${ZONE_TZ}
The default is the current TIMEZONE of the global zone
zone_locale=locale_for_the_zone
current value: ${ZONE_LOCALE}
The default is the current locale
zone_terminal=terminal_type_for_the_zone
current value: ${ZONE_TERMINAL}
The default is the content of the variable TERM
or vt100 if the variable TERM is not set
zone_timeserver=timeserver_for_the_zone
current value: ${ZONE_TIMESERVER}
zone_finish_script=finish_script_for_the_zone
current value: ${ZONE_FINISH_SCRIPT}
The
but
the
Use

finish script runs after the zone is created and configured


before it is booted in the global zone. The parameter for
finish_script is the directory used for the zone
"none" for no finish script

zone_customize_script_source=customize_script_for_the_zone
use "builtin" for the builtin customize script; use "none" for
no customize script
current value: ${ZONE_CUSTOMIZE_SCRIPT_SOURCE}
The customization script runs inside the new zone
while first booting the zone.

The builtin customize script is:


# --- built in script starts
${ZONE_CUSTOMIZE_SCRIPT_CONTENTS}
# --- built in script ends
(defined in the variable DEFAULT_ZONE_CUSTOMIZE_SCRIPT_CONTENTS
in the config file)
zone_customize_script_target=fqn_of_the_customize_script_inside_the_zone
current value: ${ZONE_CUSTOMIZE_SCRIPT_TARGET}
zone_profile=smf_profile_for_the_zone
current value: ${ZONE_SMF_PROFILE}
use_existing_nameserver_config=[yes|no]
current value: $( ConvertToYesNo ${USE_EXISTING_NAMESERVER_CONFIG} )
If this variable is true the files
${NAME_SERVER_CONFIG_FILES}
from the global zone are copied to the new zone
(the list of files is defined in the variable NAME_SERVER_CONFIG_FILES
in the config file)
zone_autoboot=[yes|no]
or
autoboot=[yes|no]
current value: $( ConvertToYesNo ${ZONE_AUTOBOOT} )
boot_the_zone_now=[yes|no]
current value: $( ConvertToYesNo ${BOOT_THE_ZONE_NOW} )
if yes, the zone will be booted automatically if configured and
created without errors.
free_space_for_the_zone=freespace_necessary_in_kb
The defaults are
for big zones: ${DEFAULT_FREE_SPACE_FOR_A_BIG_ZONE} kb
for small zones: ${DEFAULT_FREE_SPACE_FOR_A_SMALL_ZONE} kb
Use 0 to suppress the free space check
shortcut: -s
EOT
return 0
}
# ----------------------------------------------------------------------------## -------------------------------------## YourRoutine
##
## description
##
## usage: YourRoutine
##
## returns: 0 - the input device is a terminal (interactive)
##
1 - the input device is NOT a terminal
##
YourRoutine(){

typeset __FUNCTION="YourRoutine";
THISRC=0

${__DEBUG_CODE}

# add code here


return ${THISRC}
}
## -------------------------------------## ProcessParameter
##
## description Process the parameter -x keyword=keyvalue
##
## usage: ProcessParameter
##
## returns: 0 - parameter okay
##
1 - parameter invalid
##
ProcessParameter(){
typeset __FUNCTION="ProcessParameter";
${__DEBUG_CODE}
THISRC=0
typeset THIS_PARM="$*"
typeset KEYVALUE="${THIS_PARM#*=}"
typeset KEYNAME="${THIS_PARM%%=*}"
case ${KEYNAME} in
"zone_mode" )
ZONE_MODE="${KEYVALUE:-${DEFAULT_ZONE_MODE}}"
;;
"zone_path" | "zonepath" )
ZONE_PATH="${KEYVALUE:-${DEFAULT_ZONE_PATH}}"
;;
"zone_name" | "zonename" )
ZONE_NAME="${KEYVALUE:-${ZONE_NAME}}"
;;
"zone_ip_address" | "address" )
ZONE_IP_ADDRESS="${KEYVALUE:-${DEFAULT_ZONE_IP_ADDRESS}}"
;;
"zone_network_interface" | "physical" )
ZONE_NETWORK_INTERFACE="${KEYVALUE:-${DEFAULT_ZONE_NETWORK_INTERFACE}}"
;;
"zone_root_password" )
if [ "${KEYVALUE}"x = "none"x ] ; then
ZONE_ROOT_PASSWORD=""
else
ZONE_ROOT_PASSWORD="${KEYVALUE:-${DEFAULT_ZONE_ROOT_PASSWORD}}"
fi
;;
"zone_tz" )
ZONE_TZ="${KEYVALUE:-${DEFAULT_ZONE_T}}"
;;

"zone_locale" )
ZONE_LOCALE="${KEYVALUE:-${DEFAULT_ZONE_LOCALE}}"
;;
"zone_terminal" )
ZONE_TERMINAL="${KEYVALUE:-${DEFAULT_ZONE_TERMINAL}}"
;;
"zone_timeserver" )
ZONE_TIMESERVER="${KEYVALUE:-${DEFAULT_ZONE_TIMESERVER}}"
;;
"zone_finish_script" )
ZONE_FINISH_SCRIPT="${KEYVALUE:-${DEFAULT_ZONE_FINISH_SCRIPT}}"
;;
"zone_customize_script_source" )
ZONE_CUSTOMIZE_SCRIPT_SOURCE="${KEYVALUE:-${DEFAULT_ZONE_CUSTOMIZE_SCRIPT_
SOURCE}}"
;;
"zone_customize_script_target" )
ZONE_CUSTOMIZE_SCRIPT_TARGET="${KEYVALUE:-${DEFAULT_ZONE_CUSTOMIZE_SCRIPT_
TARGET}}"
;;
"free_space_for_the_zone" )
FREE_SPACE_FOR_THE_ZONE="${KEYVALUE:-${DEFAULT_FREE_SPACE_FOR_THE_ZONE}}"
;;
"zone_autoboot" | "autoboot" )
CheckYNParameter "${KEYVALUE}"
THATRC=$?
if [ ${THATRC} -ne 255 ] ; then
ZONE_AUTOBOOT=${THATRC}
else
LogError "Invalid value for \"${KEYNAME}\" found: \"${KEYVALUE}\""
THISRC=5
fi
;;
"boot_the_zone_now" )
CheckYNParameter "${KEYVALUE}"
THATRC=$?
if [ ${THATRC} -ne 255 ] ; then
BOOT_THE_ZONE_NOW=${THATRC}
else
LogError "Invalid value for \"${KEYNAME}\" found: \"${KEYVALUE}\""
THISRC=5
fi
;;
"use_existing_nameserver_config" )
CheckYNParameter "${KEYVALUE}"
THATRC=$?
if [ ${THATRC} -ne 255 ] ; then
USE_EXISTING_NAMESERVER_CONFIG=${THATRC}

else
LogError "Invalid value for \"${KEYNAME}\" found: \"${KEYVALUE}\""
THISRC=5
fi
;;
"zone_profile" )
ZONE_SMF_PROFILE="${KEYVALUE:-${DEFAULT_ZONE_SMF_PROFILE}}"
;;
* )
LogError "Invalid Parameter found: \"${THIS_PARM}\" "
THISRC=5
;;
esac
return ${THISRC}
}
# ----------------------------------------------------------------------------# main:
#
# install trap handler
trap "GENERAL_SIGNAL_HANDLER
trap "GENERAL_SIGNAL_HANDLER
trap "GENERAL_SIGNAL_HANDLER
trap "GENERAL_SIGNAL_HANDLER
trap "GENERAL_SIGNAL_HANDLER

1" 1
2" 2
3" 3
15" 15
exit" exit

# use a temporary log file until we know the real log file
__TEMPFILE_CREATED=${__FALSE}
__MAIN_LOGFILE=${__LOGFILE}
__LOGFILE="/tmp/${__SCRIPTNAME}.$$.TEMP"
echo >${__LOGFILE}
LogMsg "${__SCRIPTNAME} started on $( date ) "
LogRuntimeInfo "Script template used is \"${__SCRIPT_TEMPLATE_VERSION}\" ."
__WRITE_CONFIG_AND_EXIT=${__FALSE}
# init the variables
eval "${__CONFIG_PARAMETER}"
# read the config file
ReadConfigFile
# init variables with the defaults
#
# format var=${DEFAULT_var}
#
ZONE_IP_ADDRESS="${DEFAULT_ZONE_IP_ADDRESS}"
ZONE_NAME="${DEFAULT_ZONE_NAME}"
ZONE_MODE="${DEFAULT_ZONE_MODE}"
ZONE_PATH="${DEFAULT_ZONE_PATH}"

ZONE_ROOT_PASSWORD="${DEFAULT_ZONE_ROOT_PASSWORD}"
ZONE_TZ="${DEFAULT_ZONE_TZ}"
ZONE_LOCALE="${DEFAULT_ZONE_LOCALE}"
ZONE_NETWORK_INTERFACE="${DEFAULT_ZONE_NETWORK_INTERFACE}"
ZONE_TERMINAL="${DEFAULT_ZONE_TERMINAL}"
ZONE_TIMESERVER="${DEFAULT_ZONE_TIMESERVER}"
ZONE_FINISH_SCRIPT="${DEFAULT_ZONE_FINISH_SCRIPT}"
ZONE_CUSTOMIZE_SCRIPT_SOURCE="${DEFAULT_ZONE_CUSTOMIZE_SCRIPT_SOURCE}"
ZONE_CUSTOMIZE_SCRIPT_TARGET="${DEFAULT_ZONE_CUSTOMIZE_SCRIPT_TARGET}"
ZONE_CUSTOMIZE_SCRIPT_CONTENTS="${DEFAULT_ZONE_CUSTOMIZE_SCRIPT_CONTENTS}"
ZONE_SMF_PROFILE="${DEFAULT_ZONE_SMF_PROFILE}"
USE_EXISTING_NAMESERVER_CONFIG="${DEFAULT_USE_EXISTING_NAMESERVER_CONFIG}"
ZONE_AUTOBOOT="${DEFAULT_ZONE_AUTOBOOT}"
BOOT_THE_ZONE_NOW="${DEFAULT_BOOT_THE_ZONE_NOW}"
FREE_SPACE_FOR_THE_ZONE="${DEFAULT_FREE_SPACE_FOR_THE_ZONE}"
FREE_SPACE_FOR_A_BIG_ZONE="${DEFAULT_FREE_SPACE_FOR_A_BIG_ZONE}"
FREE_SPACE_FOR_A_SMALL_ZONE="${DEFAULT_FREE_SPACE_FOR_A_SMALL_ZONE}"
# extension for backup files
BACKUP_EXTENSION="${DEFAULT_BACKUP_EXTENSION}"
# add additional exit routines
# __EXITROUTINES="${__EXITROUTINES} RebootIfNecessary"
THIS_PARAMETER=$*
# variables used by getops:
#
OPTIND = index of the current argument
#
OPTARG = current function character
#
INVALID_PARAMETER_FOUND=${__FALSE}
__PRINT_USAGE=${__FALSE}
while getopts :ynvqhHDfl:aOS:Cbp:i:z:A:x:s: CUR_SWITCH ; do
#
#
#
#

echo
echo
echo
echo

"CUR_SWITCH is $CUR_SWITCH"
"OPTIND = $OPTIND"
"OPTARG = $OPTARG"
"\$\* is \"$*\" "

if [ "${CUR_SWITCH}" = ":" ] ; then


CUR_SWITCH=${OPTARG}
OPTARG=""
fi
case ${CUR_SWITCH} in
"C" ) __WRITE_CONFIG_AND_EXIT=${__TRUE} ;;

"+D" ) __DEBUG_MODE=${__FALSE} ;;
"D" ) __DEBUG_MODE=${__TRUE} ; __USE_COLORS=${__TRUE} ;;
"+v" ) __VERBOSE_MODE=${__FALSE} ;;
"v" ) __VERBOSE_MODE=${__TRUE} ; (( __VERBOSE_LEVEL=__VERBOSE_LEVEL+1 ))
;;
"+q" ) __QUIET_MODE=${__FALSE} ;;
"q" ) __QUIET_MODE=${__TRUE} ;;
"+a" ) __USE_COLORS=${__FALSE} ;;
"a" ) __USE_COLORS=${__TRUE} ;;
"+O" ) __OVERWRITE_MODE=${__FALSE} ;;
"O" ) __OVERWRITE_MODE=${__TRUE} ;;
"f" ) __FORCE=${__TRUE} ;;
"+f" ) __FORCE=${__FALSE} ;;
"l" ) NEW_LOGFILE="${OPTARG:=nul}" ;;
"+l" ) NEW_LOGFILE="nul" ;;
"+h" ) ShowUsage ; die 1 ;;
"h" ) __PRINT_USAGE=${__TRUE} ;;
"H" )
echo " ---------------------------------------------------------------------------------" >&2
echo "
${__SCRIPTNAME} ${__SCRIPT_TEMPLATE_VERSION} ">&2
echo "
Documentation" >&2
echo " ---------------------------------------------------------------------------------" >&2
grep "^##" $0 | cut -c3-80 1>&2 ; die 0 ;;
"+y" ) __USER_RESPONSE_IS="" ;;
"y" ) __USER_RESPONSE_IS="y" ;;
"+n" ) __USER_RESPONSE_IS="" ;;
"n" ) __USER_RESPONSE_IS="n" ;;
"S" ) case ${OPTARG} in
0 | 1 | 2 | 3 ) : okay
;;
* ) LogError "Unknown value for -S found found: \"${OPTARG}\""
INVALID_PARAMETER_FOUND=${__TRUE}
;;

esac
;;
"b" )
ZONE_MODE="big"
;;
"+b" )
ZONE_MODE="small"
;;
"i" )
ZONE_IP_ADDRESS="${OPTARG}"
;;
"z" )
ZONE_NAME="${OPTARG}"
;;
"A" )
ZONE_NETWORK_INTERFACE="${OPTARG}"
;;
"s" )
FREE_SPACE_FOR_THE_ZONE="${OPTARG}"
;;
"p" )
ZONE_PATH="${OPTARG}"
;;
"x" )
ProcessParameter "${OPTARG}"
[ $? -ne 0 ] && INVALID_PARAMETER_FOUND=${__TRUE}
;;
\? ) LogError "Unknown parameter found: \"${OPTARG}\""
INVALID_PARAMETER_FOUND=${__TRUE}
break ;;
* ) LogError "Unknown parameter found: \"${CUR_SWITCH}\""
INVALID_PARAMETER_FOUND=${__TRUE}
break ;;
esac
done
if [ ${__PRINT_USAGE} = ${__TRUE} ] ; then
if [ ${__VERBOSE_MODE} -eq ${__TRUE} ] ; then
ShowUsage
__VERBOSE_MODE=${__FALSE}
else
ShowShortUsage
LogMsg "Use \"-v -h\" or \"+h\" for a long help text"
fi
die 1 ;
fi
shift $(( OPTIND - 1 ))

NOT_PROCESSED_PARAMETER="$*"
if [ "${NOT_PROCESSED_PARAMETER}"x != ""x ] ; then
for CUR_PARM in ${NOT_PROCESSED_PARAMETER} ; do
ProcessParameter "${CUR_PARM}"
[ $? -ne 0 ] && INVALID_PARAMETER_FOUND=${__TRUE}
done
fi
case ${__PRINT_SUMMARIES} in
0 ) __PRINT_LIST_OF_WARNINGS_MSGS=${__FALSE}
__PRINT_LIST_OF_ERROR_MSGS=${__FALSE}
;;
1 )

__PRINT_LIST_OF_WARNINGS_MSGS=${__FALSE}
__PRINT_LIST_OF_ERROR_MSGS=${__TRUE}
;;

2 )

__PRINT_LIST_OF_WARNINGS_MSGS=${__TRUE}
__PRINT_LIST_OF_ERROR_MSGS=${__FALSE}
;;

3 )

__PRINT_LIST_OF_WARNINGS_MSGS=${__TRUE}
__PRINT_LIST_OF_ERROR_MSGS=${__TRUE}
;;

* ) : this should never happen but who knows ...


__PRINT_LIST_OF_WARNINGS_MSGS=${__FALSE}
__PRINT_LIST_OF_ERROR_MSGS=${__FALSE}
esac
#
#
#
#
#
#
#
#
#
#
#
#
#

??? add parameter checking code here


set INVALID_PARAMETER_FOUND to ${__TRUE} if the script
should abort due to an invalid parameter
[ "${NOT_PROCESSED_PARAMETER}"x != ""x ] && INVALID_PARAMETER_FOUND=${__TRUE}
if [ "${NOT_PROCESSED_PARAMETER}"x != ""x ] ; then
LogError "Unknown parmeter: \"${NOT_PROCESSED_PARAMETER}\" "
INVALID_PARAMETER_FOUND=${__TRUE}
fi

# exit the program if there are one or more invalid parameter


#
if [ ${INVALID_PARAMETER_FOUND} -eq ${__TRUE} ] ; then
LogError "One or more invalid parameters found"
ShowShortUsage
die 2
fi
LogRuntimeInfo "Parameter after the options are: " "\"$*\" "
# copy the temporary log file to the real log file

if [ "${NEW_LOGFILE}"x = "nul"x ] ; then


LogMsg "Running without a log file"
__MAIN_LOGFILE=""
# delete the temporary logfile
rm ${__LOGFILE} 2>/dev/null
__LOGFILE=""
else
[ "${NEW_LOGFILE}"x != ""x ] && __MAIN_LOGFILE=${NEW_LOGFILE}
LogRuntimeInfo "Initializing the log file\"${__MAIN_LOGFILE}\" "
touch ${__MAIN_LOGFILE} 2>/dev/null
cat ${__LOGFILE} >>${__MAIN_LOGFILE} 2>/dev/null
if [ $? -ne 0 ] ; then
LogWarning "Error writing to the logfile \"${__MAIN_LOGFILE}\"."
LogWarning "Using the log file \"${__LOGFILE}\" "
else
rm ${__LOGFILE} 2>/dev/null
__LOGFILE=${__MAIN_LOGFILE}
fi
LogMsg "Using the log file \"${__LOGFILE}\" "
fi
LogRuntimeInfo "Parameter before getopt processing are: \"${THIS_PARAMETER}\"
"
LogRuntimeInfo "Not processed parameter after getopt processing are: \"${NOT_P
ROCESSED_PARAMETER}\" "
if [ "${__REQUIRED_OS_VERSION}"x != ""x ] ; then
LogRuntimeInfo "Curent OS version is \"${__OS_VERSION}\"; required OS versio
n is \"${__REQUIRED_OS_VERSION}\""
__OS_VERSION_OKAY=${__TRUE}
__CUR_MAJOR_VER="${__OS_VERSION%.*}"
__CUR_MINOR_VER="${__OS_VERSION#*.}"
__REQ_MAJOR_VER="${__REQUIRED_OS_VERSION%.*}"
__REQ_MINOR_VER="${__REQUIRED_OS_VERSION#*.}"
[ "${__CUR_MAJOR_VER}" -lt "${__REQ_MAJOR_VER}" ] && __OS_VERSION_OKAY=${__F
ALSE}
[ "${__CUR_MAJOR_VER}" -eq "${__REQ_MAJOR_VER}" -a "${__CUR_MINOR_VER}" -lt
"${__REQ_MINOR_VER}" ] && __OS_VERSION_OKAY=${__FALSE}
[ ${__OS_VERSION_OKAY} = ${__FALSE} ] && die 248 "Unsupported OS Version: $
{__OS_VERSION}; necessary OS version is ${__REQUIRED_OS_VERSION}"
fi
if [ ${__MUST_BE_ROOT} -eq ${__TRUE} ] ; then
UserIsRoot || die 249 "You must be root to execute this script"
fi
if [ ${__ONLY_ONCE} -eq ${__TRUE} ] ; then
CreateLockFile
if [ $? -ne 0 ] ; then
cat <<EOF

ERROR:
Either
or the
In the
in the

another instance of this script is already running


last execution of this script crashes.
first case wait until the other instance ends;
second case delete the lock file

${__LOCKFILE}
manually and restart the script.
EOF
die 250
fi
# remove the lock file at program end
__EXITROUTINES="${__EXITROUTINES} RemoveLockFile"
fi
# __ABSOLUTE_SCRIPTDIR real absolute directory (no link)
GetProgramDirectory $0 __ABSOLUTE_SCRIPTDIR
# create temporary files
CreateTemporaryFiles
if [ "${__DEBUG_MODE}" -eq ${__TRUE} ] ; then
__LIST_OF_TMP_FILES="${__LIST_OF_TMP_FILES} ${__DEBUG_HISTFILE}"
trap "__LAST_RC=\$?; __LAST_BG_RC=\$!; __LINENO=\$LINENO; DebugHandler" DEB
UG
:
echo "INFO: Starting single step mode - works only for the main routine!"
fi
# check for the parameter -C
if [ "${__WRITE_CONFIG_AND_EXIT}" = ${__TRUE} ] ; then
NEW_CONFIG_FILE="${__CONFIG_FILE}"
LogMsg "Creating the config file \"${NEW_CONFIG_FILE}\" ..."
WriteConfigFile ${NEW_CONFIG_FILE}
[ $? -ne 0 ] && die 246 "Error writing the config file \"${NEW_CONFIG_FILE}\
""
die 0 "Configfile \"${NEW_CONFIG_FILE}\" written successfully."
fi
# --- variables for the cleanup routine:
#
# add mounts that should be automatically be unmounted at script end to this var
iable
#
# __LIST_OF_TMP_MOUNTS="${__LIST_OF_TMP_MOUNTS} "
# add directories that should be automatically removed at script end to this var
iable
#
# __LIST_OF_TMP_DIRS="${__LIST_OF_TMP_DIRS} "
# add files that should be automatically removed at script end to this variable
# __LIST_OF_TMP_FILES="${__LIST_OF_TMP_FILES} "

# add functions that should be called automatically at program end to this varia
ble
#
# __EXITROUTINES="${__EXITROUTINES} "
# this script can only run in the global zone
#
[ "${__ZONENAME}"x != "global"x ] && die 6 "This script can only run in the gl
obal zone"
# check the mandatory parameter
#
[ "${ZONE_NAME}"x = ""x ] && die 5 "The parameter for the name of the zone mis
sing"
[ "${ZONE_IP_ADDRESS}"x = ""x ] && die 8 "The parameter for the IP address of
the zone is missing"
[ ! -d "${ZONE_PATH}" ] && die 11 "The directory for the zone \"${ZONE_PATH}\"
does not exist"
# resolv symbolic links for the ZONE_PATH
cd "${ZONE_PATH}"
THIS_ZONE_PATH="$( pwd -P )/${ZONE_NAME}"
cd - >/dev/null
# set defaults for the missing values
#
if [ "${FREE_SPACE_FOR_THE_ZONE}"x = ""x ] ; then
if [ "${ZONE_MODE}"x = "small"x ] ; then
FREE_SPACE_FOR_THE_ZONE="${DEFAULT_FREE_SPACE_FOR_A_SMALL_ZONE}"
else
FREE_SPACE_FOR_THE_ZONE="${DEFAULT_FREE_SPACE_FOR_A_BIG_ZONE}"
fi
fi
if [ "${ZONE_NETWORK_INTERFACE}"x = ""x ] ; then
typeset ZONE_NETWORK_INTERFACE="$(route -n get ${ZONE_IP_ADDRESS} | grep int
erface | tr -d " " | cut -f2 -d ":" )"
[ "${ZONE_NETWORK_INTERFACE}"x = ""x ] && die 15 "Can not detect the interfa
ce for the zone (use -A to specify the interface)"
fi
CUR_ZONE_STATUS=$( zoneadm -z ${ZONE_NAME} list -p | cut -f3 -d":" 2>/dev/null
)
# print the configuration
LogMsg "-"
LogMsg "Creating the zone \"${ZONE_NAME}\""
LogMsg "The path for the zone is \"${THIS_ZONE_PATH}\" "
LogMsg "The mode for the zone is \"${ZONE_MODE}\" "
LogMsg "The IP address of the zone is \"${ZONE_IP_ADDRESS}\""
LogMsg "The zone uses the network interface \"${ZONE_NETWORK_INTERFACE}\""
LogMsg "The locale for the zone is \"${ZONE_LOCALE}\" "
LogMsg "The timezone for the zone is \"${ZONE_TZ}\" "
LogMsg "The encrypted root password for the zone is \"${ZONE_ROOT_PASSWORD}\""
LogMsg "The terminal type for the zone is \"${ZONE_TERMINAL}\""
LogMsg "The timeserver for the zone is \"${ZONE_TIMESERVER}\""
LogMsg "The finish script for the zone is \"${ZONE_FINISH_SCRIPT}\""
LogMsg "The customize script for the zone is \"${ZONE_CUSTOMIZE_SCRIPT_SOURCE}

\" "
LogMsg "The customize script inside the zone is \"${ZONE_CUSTOMIZE_SCRIPT_TARG
ET}\""
LogMsg "The SMF profile for the zone is \"${ZONE_SMF_PROFILE}\""
LogMsg "Use the existing name server configuration: $( ConvertToYesNo ${USE_EX
ISTING_NAMESERVER_CONFIG} )"
LogMsg "Set autoboot to enable for the zone: $( ConvertToYesNo ${ZONE_AUTOBOOT
} )"
LogMsg "Boot the zone after installation: $( ConvertToYesNo ${BOOT_THE_ZONE_NO
W} )"
LogMsg "Free space in KB necessary for creating the zone is: ${FREE_SPACE_FOR_
THE_ZONE}"
LogMsg "-"
if [ "${CUR_ZONE_STATUS}"x != ""x ] ; then
LogWarning "The zone \"${ZONE_NAME}\" already exists; the status is \"${CUR_
ZONE_STATUS}\" "
LogMsg "-"
USER_PROMPT="ReCreate the zone (y/N)? "
else
USER_PROMPT="Create the zone (y/N)? "
fi
AskUser "${USER_PROMPT}"
[ $? -ne ${__TRUE} ] && die 14 "Script aborted by the user"
# check the configuraton
#
LogMsg "Checking the zone configuration ..."
ZONE_EXISTS=${__FALSE}
ZONE_PATH_EXISTS=${__FALSE}
ZONE_CONFIGURATION_OK=${__TRUE}
# check if the zone already exists
#
zoneadm list -c | grep "^${ZONE_NAME}$" >/dev/null
if [ $? -eq 0 ] ; then
ZONE_EXISTS=${__TRUE}
if [ ${__OVERWRITE_MODE} = ${__FALSE} ] ; then
LogError "The zone \"${ZONE_NAME}\" already exists (use the parameter -O t
o delete and recreate the zone)"
ZONE_CONFIGURATION_OK=${__FALSE}
fi
fi
# check if the zone is running
#
CUR_ZONE_STATUS=$( zoneadm -z ${ZONE_NAME} list -p | cut -f3 -d":" 2>/dev/null
)
if [ "${CUR_ZONE_STATUS}"x = "running"x ] ; then
ZONE_EXISTS=${__TRUE}
LogError "The zone \"${ZONE_NAME}\" is running - please stop the zone manual
ly before calling this script"
ZONE_CONFIGURATION_OK=${__FALSE}
fi
# check if the directory for the zone already exists
#

if [ -d "${THIS_ZONE_PATH}" ] ; then
ZONE_PATH_EXISTS=${__TRUE}
if [ ${__OVERWRITE_MODE} = ${__FALSE} ] ; then
LogError "The directory \"${THIS_ZONE_PATH}\" already exists (use the para
meter -O to delete and recreate the directory)"
ZONE_CONFIGURATION_OK=${__FALSE}
fi
fi
# check if the site profile for the zone exists (if any)
#
if [ "${ZONE_SMF_PROFILE}"x != ""x -a "${ZONE_SMF_PROFILE}"x != "none"x ] ; th
en
if [ ! -f "${ZONE_SMF_PROFILE}" ] ; then
LogError "The profile \"${ZONE_SMF_PROFILE}\" does not exist"
ZONE_CONFIGURATION_OK=${__FALSE}
fi
fi
# check if the finish script for the zone exists (if any)
#
if [ "${ZONE_FINISH_SCRIPT}"x != ""x -a "${ZONE_FINISH_SCRIPT}"x != "none"x ]
; then
if [ ! -x "${ZONE_FINISH_SCRIPT}" ] ; then
LogError "The finish script \"${ZONE_FINISH_SCRIPT}\" does not exist or is
not executable"
ZONE_CONFIGURATION_OK=${__FALSE}
fi
fi
# check if the customize script for the zone exists (if any)
#
if [ "${ZONE_CUSTOMIZE_SCRIPT_SOURCE}"x != ""x -a \
"${ZONE_CUSTOMIZE_SCRIPT_SOURCE}"x != "builtin"x -a \
"${ZONE_CUSTOMIZE_SCRIPT_SOURCE}"x != "none"x ] ; then
if [ ! -f "${ZONE_CUSTOMIZE_SCRIPT_SOURCE}" ] ; then
LogError "The customize script \"${ZONE_CUSTOMIZE_SCRIPT_SOURCE}\" does no
t exist"
ZONE_CONFIGURATION_OK=${__FALSE}
else
ZONE_CUSTOMIZE_SCRIPT_CONTENTS="$( cat "${ZONE_CUSTOMIZE_SCRIPT_SOURCE}" )
"
[ $? -ne 0 ] && die 17 "Error reading the customize script for the zone \"
${ZONE_CUSTOMIZE_SCRIPT_SOURCE}\" "
fi
fi
# check if the network interface for the zone exists
#
ifconfig "${ZONE_NETWORK_INTERFACE}" 1>/dev/null 2>/dev/null
if [ $? -ne 0 ] ; then
LogError "The network interface \"${ZONE_NETWORK_INTERFACE}\" does not exist
or is not plumbed"
ZONE_CONFIGURATION_OK=${__FALSE}
fi
# check if the IP address already exists
#

IP_ADDRESS_OK=${__TRUE}
ping "${ZONE_IP_ADDRESS}" >/dev/null 2 >/dev/null
if [ $? -eq 0 ] ; then
if [ ${ZONE_EXISTS} = ${__TRUE} -a ${__OVERWRITE_MODE} = ${__TRUE} ] ; then
# the zone already exists and should be overwritten -> check if the IP address i
s the IP address of the existing zone
grep "${ZONE_IP_ADDRESS}" 2>/dev/null 1>/dev/null <<EOT
$( zonecfg -z "${ZONE_NAME}" info | grep address | cut -f2 -d ":" )
EOT
[ $? -ne 0 ] && IP_ADDRESS_OK=${__FALSE}
else
IP_ADDRESS_OK=${__FALSE}
fi
if [ ${IP_ADDRESS_OK} != ${__TRUE} ] ; then
LogError "The IP address \"${ZONE_IP_ADDRESS}\" is already in use"
ZONE_CONFIGURATION_OK=${__FALSE}
fi
fi
# check the mode for the zone
#
if [ "${ZONE_MODE}" != "small" -a "${ZONE_MODE}" != "big" ] ; then
LogError "Invalid zone mode found: \"${ZONE_MODE}\""
ZONE_CONFIGURATION_OK=${__FALSE}
fi
# check the free space in the target directory
if [ "${FREE_SPACE_FOR_THE_ZONE}" != "0" ] ; then
FREE_SPACE=$( df -k "${ZONE_PATH}" | grep -v "Filesystem" | tr -s " " | cut
-f4 -d" " )
if [[ ${FREE_SPACE} -lt ${FREE_SPACE_FOR_THE_ZONE} ]] ; then
LogError "Not enough free space in \"${ZONE_PATH}\" to create the zone; fr
ee are ${FREE_SPACE} kb; necessary are ${FREE_SPACE_FOR_THE_ZONE} kb"
ZONE_CONFIGURATION_OK=${__FALSE}
fi
fi
[ ${ZONE_CONFIGURATION_OK} != ${__TRUE} ] && die 20 "Zone configuration is not
okay"
# create the zone
#
LogMsg "The zone configuration seems to be okay "
if [ ${ZONE_EXISTS} = ${__TRUE} ] ; then
LogMsg "Deleting the existing zone \"${ZONE_NAME}\" ..."
[ ${__FORCE} = ${__TRUE} ] && ADD_PARM="-F" || ADD_PARM=""
executeCommandAndLog zoneadm -z "${ZONE_NAME}" halt || LogWarning "Error ca
lling zoneadm -z ${ZONE_NAME} halt"
executeCommandAndLog zoneadm -z "${ZONE_NAME}" uninstall -F || LogWarning "E
rror calling zoneadm -z ${ZONE_NAME} uninstall -F"
executeCommandAndLog zonecfg -z "${ZONE_NAME}" delete -F || LogWarning "Erro
r calling zonecfg -z ${ZONE_NAME} delete -F"
zoneadm list -c | grep "^${ZONE_NAME}$" >/dev/null
[ $? -eq 0 ] && die 23 "Can not delete the existing zone"

fi
if [ ${ZONE_PATH_EXISTS} = ${__TRUE} -a -d "${THIS_ZONE_PATH}" ] ; then
LogMsg "Removing the existing zone directory \"${THIS_ZONE_PATH}\" ..."
rm -rf "${THIS_ZONE_PATH}"
[ -d "${THIS_ZONE_PATH}" ] && die 26 "Can not remove the existing zone direc
tory \"${THIS_ZONE_PATH}\" "
fi
LogMsg "Configuring the zone \"${ZONE_NAME}\" ..."
[ ${ZONE_AUTOBOOT} = ${__TRUE} ] && AUTOBOOT="true" || AUTOBOOT="false"
[ "${ZONE_MODE}"x = "big"x ] && CREATE="create -b" || CREATE="create"
zonecfg -z "${ZONE_NAME}" -f - <<EOF
${CREATE}
set autoboot=${AUTOBOOT}
set zonepath=${THIS_ZONE_PATH}
add net
set address=${ZONE_IP_ADDRESS}
set physical=${ZONE_NETWORK_INTERFACE}
end
commit
exit
EOF
[ $? -ne 0 ] && die 29 "Error configuring the zone \"${ZONE_NAME}\""
LogMsg "Installing the zone \"${ZONE_NAME}\" ..."
executeCommandAndLog zoneadm -z "${ZONE_NAME}" install
[ $? -ne 0 ] && die 32 "Error installing the zone \"${ZONE_NAME}\""
LogMsg "Preparing the zone \"${ZONE_NAME}\" for running applications ..."
executeCommandAndLog zoneadm -z "${ZONE_NAME}" ready
[ $? -ne 0 ] && die 35 "Error preparing the zone \"${ZONE_NAME}\""
LogMsg "Post configuring the zone \"${ZONE_NAME}\" ..."
ZONE_SYSIDCFG_FILE="${THIS_ZONE_PATH}/root/etc/sysidcfg"
cat <<EOT >> "${ZONE_SYSIDCFG_FILE}"
name_service=NONE
network_interface=NONE
{hostname=${ZONE_NAME}}
root_password=${ZONE_ROOT_PASSWORD}
system_locale=${ZONE_LOCALE}
timezone=${ZONE_TZ}
security_policy=NONE
timeserver=${ZONE_TIMESERVER}
terminal=${ZONE_TERMINAL}
EOT
if [ $? -ne 0 ] ; then
LogError "Error creating the file \"${ZONE_SYSIDCFG_FILE}\" "
__MAINRC=100
fi
if [ ${USE_EXISTING_NAMESERVER_CONFIG} = ${__TRUE} ] ; then
LogMsg "Changing the nameserver configuration of the zone \"${ZONE_NAME}\" .
.."
for CURFILE in ${NAME_SERVER_CONFIG_FILES} ; do
LogMsg "Processing the file \"${CURFILE}\" ..."
if [ -f ${CURFILE} ] ; then

cp ${CURFILE} "${THIS_ZONE_PATH}/root/${CURFILE}"
if [ $? -ne 0 ] ; then
LogError "Error creating \"${THIS_ZONE_PATH}/root/${CURFILE}\" "
__MAINRC=102
fi
else
LogWarning "\"${CURFILE}\" not found in the global zone"
fi
done
fi
touch "${THIS_ZONE_PATH}/root/etc/.NFS4inst_state.domain" || \
LogWarning "Error creating \"${THIS_ZONE_PATH}/root/etc/.NFS4inst_state.doma
in\" "
if [ "${ZONE_CUSTOMIZE_SCRIPT_SOURCE}"x != ""x -a \
"${ZONE_CUSTOMIZE_SCRIPT_SOURCE}"x != "none"x ] ; then
LogMsg "Installing the customize script \"${ZONE_CUSTOMIZE_SCRIPT_TARGET}\"
in the zone \"${ZONE_NAME}\" ..."
CUSTOMIZE_SCRIPT_INSIDE_THE_ZONE="${THIS_ZONE_PATH}/root${ZONE_CUSTOMIZE_SCR
IPT_TARGET}"
CREATE_CUSTOMIZE_SCRIPT=${__TRUE}
TARGET_DIR="$( dirname ${CUSTOMIZE_SCRIPT_INSIDE_THE_ZONE} )"
if [ ! -d "${TARGET_DIR}" ] ; then
LogWarning "The target directory \"${TARGET_DIR}\" does not exist - now cr
eating it..."
mkdir -p "${TARGET_DIR}"
if [ $? -ne 0 ] ; then
LogError "Can not create the target dir \"${TARGET_DIR}\" - customize sc
ript not created"
CREATE_CUSTOMIZE_SCRIPT=${__FALSE}
__MAINRC=105
fi
fi
if [ ${CREATE_CUSTOMIZE_SCRIPT} = ${__TRUE} ] ; then
echo "${ZONE_CUSTOMIZE_SCRIPT_CONTENTS}" >"${CUSTOMIZE_SCRIPT_INSIDE_THE_Z
ONE}"
if [ $? -ne 0 ] ; then
LogError "Error creating the file \"${CUSTOMIZE_SCRIPT_INSIDE_THE_ZONE}\
" "
__MAINRC=106
fi
chmod 755 "${CUSTOMIZE_SCRIPT_INSIDE_THE_ZONE}"
fi
fi
if [ "${ZONE_SMF_PROFILE}"x != ""x -a "${ZONE_SMF_PROFILE}"x != "none"x ] ; th
en
LogMsg "Installing the profile for the zone ..."
PROFILE_INSIDE_THE_ZONE="${THIS_ZONE_PATH}/root/var/svc/profile/site.xml"
cp "${ZONE_SMF_PROFILE}" "${PROFILE_INSIDE_THE_ZONE}"
if [ $? -ne 0 ] ; then
LogError "Can not create the profile for the zone \"${PROFILE_INSIDE_THE_Z
ONE}\" "
__MAINRC=107
fi
fi

if [ "${ZONE_FINISH_SCRIPT}"x != ""x -a "${ZONE_FINISH_SCRIPT}"x != "none"x ]


; then
LogMsg "Calling the finish script for the zone ..."
# export all variables beginnging with ZONE_
for i in $( set | grep "^ZONE_" ) ; do
CUR_VAR=${i%%=*} ; export $CUR_VAR
done
"${ZONE_FINISH_SCRIPT}" "${THIS_ZONE_PATH}"
if [ $? -ne 0 ] ; then
LogError "The finish script for the zone returned an error "
__MAINRC=108
fi
fi
LogMsg " ... done. zone \"${ZONE_NAME}\" installed and configured"
if [ ${BOOT_THE_ZONE_NOW} = ${__TRUE} ] ; then
if [ ${__MAINRC} != 0 -a ${__FORCE} != ${__TRUE} ] ; then
LogWarning "autobooting the zone is true but due to the errors while creat
ing the zone we will not boot the zone now"
LogWarning "Note: Use -f to force the boot of the zone anyway and suppress
this check the next time"
BOOT_THE_ZONE_NOW=${__FALSE}
fi
if [ ${BOOT_THE_ZONE_NOW} = ${__TRUE} ] ; then
LogMsg "Now booting the new created zone \"${ZONE_NAME}\" ..."
executeCommandAndLog zoneadm -z "${ZONE_NAME}" boot
fi
fi
die ${__MAINRC}
exit
##############################################################################
### This script is submitted to BigAdmin by a user of the BigAdmin community.
### Sun Microsystems, Inc. is not responsible for the
### contents or the code enclosed.
###
###
### Copyright 2006 Sun Microsystems, Inc. ALL RIGHTS RESERVED
### Use of this software is authorized pursuant to the
### terms of the license found at
### http://www.sun.com/bigadmin/common/berkeley_license.html
##############################################################################

Das könnte Ihnen auch gefallen