Using the Finalizer Scripts
The distribution constructor application includes default scripts in the /usr/share/distro_const directory and subdirectories. These
scripts are already referenced in the finalizer section of the default manifest file.
See the Manifest File.
Note - It is recommended that you use the default scripts without editing them. You
do have the option to write your own scripts to perform additional operations.
The default scripts are as follows:
pre_bootroot_pkg_image_mod – Image area modifications for all types of images
slim_cd/slimcd_pre_bootroot_pkg_image_mod – Image area modifications specific to Slim CD
bootroot_initialize.py – Boot-root initialization
slim_cd/slimcd_bootroot_configure – Boot-root configuration specific to Slim CD
bootroot_configure – Boot-root configuration
bootroot_archive.py – Boot-root archiving
slim_cd/slimcd_post_bootroot_pkg_image_mod – Post-boot-root image area modification specific to Slim CD
grub_setup – Initialization of grub menu
post_bootroot_pkg_image_mod – Post-boot-root image area modification
create_iso – ISO image creation
create_usb – USB image creation
Customizing Finalizer Scripts
Use the default scripts without editing them. You can also create custom scripts
to perform additional tasks. Use the existing scripts as models for creating new
scripts.
You can locate your scripts in the /usr/share/distro_const directory or anywhere on
the system or network. Make sure that root can execute these scripts.
Reference the script names in the finalizer section of the manifest file. Be
sure to specify the full path to your scripts in the manifest
file, even if they are in the /usr/share/distro_const directory.
When adding the script to the finalizer section of the manifest file, include
a checkpoint name and description for reference when checkpointing. See the formatting in
the Manifest File.
Note - The checkpoint message is optional. If a message is omitted, the path of
the script is used in the checkpoint message.
Note the following characteristics of the finalizer scripts:
Scripts can be Python programs, shell scripts, or binaries.
Scripts are executed in the order that they are listed in the manifest.
The stdout and stderr parameters for the scripts are captured in the log files.
The argslist, which can accept a list of items, uses double-quotes to delimit the list arguments. When no double-quotes are used, or if one set of double-quotes envelopes the entire string, the entire string including spaces and newlines is interpreted as one argument. Do not use commas between arguments.
The Distribution Constructor passes five initial arguments to all scripts which are executed. These five arguments are not included as entries in the manifest file. The manifest file specifies additional arguments passed in after these five arguments. The initial arguments are as follows:
Table 2-2 Finalizer Script Arguments
Argument |
Description |
Server socket file name |
The first argument is the manifest reader socket. This
argument specifies the socket that is used with /usr/bin/ManifestRead for accessing the manifest data.
See the section below about Using the ManifestReader. |
Package image area path |
The second argument is
the PKG_IMG_PATH, which specifies the path to the area where the package image
is created. Use this argument to locate a file in the package image
area. The following example checks whether the user “jack” is in the
password file. PKG_IMG_PATH=$2
/usr/bin/grep jack $PKG_IMG_PATH/etc/passwd >/dev/null
if [[ $? == "0" ]] ; then
print "Found Jack"
fi |
Temp directory |
The third argument specifies a directory that is used when
creating temporary files needed during the build process. In the following example, we
want to create a file in the temporary directory for building the
boot root. TMP_DIR=$3
/usr/sbin/mkfile $TMP_DIR/bootroot_archive
/usr/sbin/lofiadm -a $TMP_DIR/bootroot_archive |
Bootroot build area |
The fourth argument is the boot root build area, where
the boot root files are gathered. See the following example from the
bootroot_archive.py module. The module references the boot root build area in order
to size the boot root before creating the archive. BR_BUILD = sys.argv[4] # Bootroot build area
print "Sizing bootroot requirements..."
cmd = /usr/bin/du + " -sk " + BR_BUILD + " | " + /usr/bin/awk + " '{print $1}'"
bootroot_size = int(Popen(cmd, shell=True,
stdout=PIPE).communicate()[0].strip()) |
Media area |
The fifth argument specifies
where the finished media is deposited. In the following example, the create_iso
script uses this argument to place the resultant ISO image. MEDIA_DIR=$5
...
DIST_ISO=${MEDIA_DIR}/${DISTRO_NAME}.iso
... |
Additional arguments |
A list of
additional arguments to be passed into a script is tagged in the manifest
with the <argslist> tag. The first of these arguments is passed in
as arg6. In the following example from the slim_cd.xml manifest file, two additional arguments
are passed to the bootroot_configure script, as arg6 and arg7: <argslist>
"/usr/share/distro_const/slim_cd/slimcd_generic_live.xml"
".livecd"
</argslist> Another method for
specifying additional arguments is to use key-value pairs. See the following section. |
Using the ManifestReader
The distribution constructor passes the manifest reader socket argument into finalizer scripts. This
argument specifies the socket that is used with /usr/bin/ManifestRead for accessing the
manifest data.
The following example calls ManifestRead to request the name item from the manifest
file. ManifestRead returns zero or more items, each on its own line.
If ManifestRead is given multiple items to search for, the lines
returned contain both the item being searched for and a result.
MFEST_SOCKET=$1
VOLNAME=`/usr/bin/ManifestRead ${MFEST_SOCKET} "name"`
if [ "XX${VOLNAME}" == "XX" ] ; then
print -u2 "$0: Error retrieving volume ID"
exit 1
fi
The following example shows how to make use of ManifestRead from a
python script:
from osol_install.ManifestRead import ManifestRead
# get the manifest reader object from the socket
manifest_reader_obj = ManifestRead(MFEST_SOCKET)
# get bootroot compression type
BR_COMPR_TYPE = get_manifest_value(manifest_reader_obj,
"img_params/output_image/bootroot/compression/type")
if (BR_COMPR_TYPE == None):
raise Exception, (sys.argv[0] +
": bootroot compression type missing from manifest")
Specifying Key-Value Pairs
Another method for passing arguments into scripts is to specify a key-value pair.
This method is useful for passing the same argument into multiple scripts without
duplication. A script can access a keyed value by specifying the key to
/usr/bin/ManifestRead from within the script. Provide the server socket as the first argument
and then provide the nodepaths to the items whose values are needed, as
in the following examples.
Example 2-1 Shell Script
...
MFEST_SOCKET=$1
...
/usr/bin/ManifestRead -k $MFEST_SOCKET iso_sort
iso_sort_file=`/usr/bin/ManifestRead $MFEST_SOCKET iso_sort`
The above example calls ManifestRead from a shell script to get a keyed
value as in this sample script.
Example 2-2 Python Script
from osol_install.ManifestRead import ManifestRead
...
IS_KEY = True
iso_sort_file = manifest_reader_obj.get_values("iso_sort", IS_KEY)
fd = open(iso_sort_file,....)
The above example calls ManifestRead from python to get the same keyed value.
Examples of Custom Finalizer Scripts
The following examples illustrate some practical applications for custom finalizer scripts.
Adding Packages
When putting together an image, you can experiment with how an image works
when packages are added or removed from a working set. This type
of experimentation is supported by the distribution constructor.
Additional packages can be added to the existing list in the package
section of the manifest file. And, packages that you want to remove can
be added to the post_install_remove_package section.
After you made your modifications to the manifest file, you need to restart
the build process from the beginning, and re-download all the packages. That can
take time. You can do these modifications more rapidly by using finalizer scripts.
Because these finalizer scripts add or remove packages from the package image area,
add them as the first finalizer scripts in the <finalizer> section of
the manifest file. For example, if you have created a script, export/home/user1/test_my_pkg,
to test your custom package, you would add it as follows in the
finalizer section of the manifest file.
<finalizer>
<script name="/export/home/user1/test_my_pkg">
<checkpoint name="my_test" message="Running my test package"
</script>
<script name="/usr/share/distro_const/pre_bootroot_pkg_image_mod">
<checkpoint name="im-mod" message="Image area modifications"/>
</script>
........
</finalizer>
After you made the changes to the manifest file, start your build
from the beginning once. After that, if you make any changes to your
package, you do not need to restart from the beginning . You can
generate an image with your modified package by starting at the checkpoint that
runs your script.
The following are the sequence of commands a user would execute to
repeatedly test their modifications to packages.
Run the build from the beginning after modifying the manifest. Do this only once.
distro_const build /my_updated_manifest.xml
Check steps that are resumable.
distro_const build -l /my_updated_manifest.xml
Restart from the step of your package modification. You can restart from this step as many times as you need while you debugging your modified contents.
distro_const build -r my_test /my_updated_manifest.xml
The following custom script adds an IPS package to the image from
an alternate repository specified in the manifest file. The package is added to the
package image area. The name of the package to add is included
in the script.
This example also demonstrates how to use the ManifestRead program to get
values from the manifest file.
Example 2-3 Script for Adding Packages
#!/bin/ksh
#
#
# Args:
#
# 5 arguments are passed in by default from the DC.
#
# MFEST_SOCKET: Socket needed to get manifest data via ManifestRead object
# PKG_IMG_PATH: Package image area
# TMP_DIR: Temporary directory
# BR_BUILD: Area where bootroot is put together (not used in this example)
# MEDIA_DIR: Area where the media is put (not used)
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if [ "$#" != "5" ] ; then
print -u2 "Usage: $0: Requires 5 args:"
print -u2 " Reader socket, pkg_image area, tmp dir,"
print -u2 " bootroot build area, media area"
exit 1
fi
MFEST_SOCKET=$1
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
PKGCMD="/bin/pkg"
#Hard code package to install
TEST_PKGS="SUNWcdrw"
#
# You would have specified the additional repository like this in the manifest
#
#
# <pkg_repo_addl_authority>
# <main url="https://localhost:10000" authname="localtest"/>
# </pkg_repo_addl_authority>
# Get the alternate repository URL from the manifest
add_url=/usr/bin/ManifestRead ${MFEST_SOCKET} "distro_constr_params/pkg_repo_addl_authority/main/url"
# Get the alternate repository authority from the manifest
add_auth=/usr/bin/ManifestRead ${MFEST_SOCKET} "distro_constr_params/pkg_repo_addl_authority/main/authname"
added_authority=0
#
# Check to see if authority is already set in the package image area
# if not, add it in
#
${PKGCMD} -R $PKG_IMG_PATH authority $add_auth > /dev/null 2>& 1
if [ $? != 0 ] ; then
${PKGCMD} -R $PKG_IMG_PATH set-authority -O ${add_url} ${add_auth}
added_authority=1
fi
if [$? != "0" ] ; then
print -u2 "$0: Unable to set additional authority"
exit 1
fi
for t in ${TEST_PKGS} ; do
pkg_name="pkg://${add_auth}/${t}"
${PKGCMD} -R $PKG_IMG_PATH install ${pkg_name}
if [$? != "0" ] ; then
print -u2 "$0: Unable to install ${pkg_name}"
exit 1
fi
done
# if we have added the additional authority, unset it so it doesn't pollute what's
# originally there
if [ $added_authority == 1 ] ; then
${PKGCMD} -R $PKG_IMG_PATH unset-authority ${add_auth}
fi
return 0
Testing Packages
When a particular package is specified in the package section of the
manifest file, that package is installed in the package image area by the
distribution constructor. If you have an alternate version of this package, such as
your own private copy of a package, you could test this version of
the package by using a custom finalizer script. The finalizer script would replace
the previously installed version of the package with a test version from an
alternate repository.
In the example below, an IPS repository server is running on https://localhost:10000.
The name of the package to replace is passed as an argument. The
script first uninstalls the existing version of the package, then installs the test
version from the alternate repository.
This example also demonstrates how to get arguments passed in as finalizer script
arguments.
Example 2-4 Script for Testing an Alternate Package
#!/bin/ksh
#
#
# Args:
#
# These Arguments are passed in by default from the DC.
#
# MFEST_SOCKET: Socket needed to get manifest data via ManifestRead object (not used in this example)
# PKG_IMG_PATH: Package image area
# TMP_DIR: Temporary directory
# BR_BUILD: Area where bootroot is put together (not used in this example)
# MEDIA_DIR: Area where the media is put (not used)
# PKG_NAMES: Package to replace with one from the test repo.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if [ "$#" != "6" ] ; then
print -u2 "Usage: $0: Requires 6 args:"
print -u2 " Reader socket, pkg_image area, tmp dir,"
print -u2 " bootroot build area, media area, pkg_name"
exit 1
fi
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
PKGCMD="/bin/pkg"
#The test packages are passed in as arguments to this finalizer script
#You would have specified the argument like this in the finalizer section
#to pass in the argument
#
#
# <finalizer>
# <script name="/my/update_my_pkg_test">
# <checkpoint name="update-pkg" message="Replaces an existing package with my own"/>
# <argslist>
# "SUNWcdrw"
# </argslist>
# </script>
# </finalizer>
#
TEST_PKG=$6
#hard code alternate repository and authority. Assume that my test package resides in
#a repository running on port 10000 of the localhost.
# Get the alternate repository URL from the manifest
add_url="https://localhost:10000"
# Get the alternate repository authority from the manifest
add_auth="MY_TEST"
added_authority=0
# Check to see if authority is already set in the package image area, if not,
# add it in
${PKGCMD} -R $PKG_IMG_PATH authority $add_auth > /dev/null 2>& 1
if [ $? != 0 ] ; then
${PKGCMD} -R $PKG_IMG_PATH set-authority -O ${add_url} ${add_auth}
added_authority=1
fi
if [$? != "0" ] ; then
print -u2 "$0: Unable to set additional authority"
exit 1
fi
# Remove the package that's currently in the package image area.
${PKGCMD} -R $PKG_IMG_PATH uninstall ${TEST_PKG}
if [$? != "0" ] ; then
print -u2 "$0: Unable to uninstall ${TEST_PKG}"
exit 1
fi
# Install the package from test repo
pkg_name="pkg://${add_auth}/${TEST_PKG}"
${PKGCMD} -R $PKG_IMG_PATH install ${pkg_name}
if [$? != "0" ] ; then
print -u2 "$0: Unable to install ${pkg_name}"
exit 1
fi
# if we have added the additional authority, unset it so it doesn't pollute what's
# originally there
if [ $added_authority == 1 ] ; then
${PKGCMD} -R $PKG_IMG_PATH unset-authority ${add_auth}
fi
return 0
Adding a SVR4 Package
If you have a package that is in SVR4 format, you can
test that package in an image before you convert it into an IPS
package. You can use a finalizer script to add the content of a
SVR4 package to the image. See the following example.
Example 2-5 Script for Adding a SVR4 Package
#!/bin/ksh
#
#
# Args:
#
# 5 arguments are passed in by default from the DC.
#
# MFEST_SOCKET: Socket needed to get manifest data via ManifestRead object (not used)
# PKG_IMG_PATH: Package image area
# TMP_DIR: Temporary directory
# BR_BUILD: Area where bootroot is put together (not used in this example)
# MEDIA_DIR: Area where the media is put (not used)
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if [ "$#" != "5" ] ; then
print -u2 "Usage: $0: Requires 5 args:"
print -u2 " Reader socket, pkg_image area, tmp dir,"
print -u2 " bootroot build area, media area, pkg_name"
exit 1
fi
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
TMP_DIR=$3
#
# Install a SVR4 packages into the package image area
#
#create an admin file for non-interactive pkgadd's
ADMIN_FILE=${TMP_DIR}/admin.$$
cat << \ADMIN_EOF > $ADMIN_FILE
mail=
instance=unique
partial=nocheck
runlevel=nocheck
idepend=nocheck
rdepend=nocheck
space=nocheck
setuid=nocheck
conflict=nocheck
action=nocheck
networktimeout=60
networkretries=3
authentication=quit
keystore=/var/sadm/security
proxy=
basedir=default
ADMIN_EOF
#
# Path to your new packages
#
PKG_PATH=/path/to/my/test/svr4_pkg
#
# Test package name
#
SVR4_TEST_PKG=SUNWmy-test
/usr/sbin/pkgadd -n -a ${ADMIN_FILE} -d $PKG_PATH -R ${PKG_IMG_PATH} ${SVR4_TEST_PKG}
if [ $? != "0" ] ; then
echo "installing package failed"
exit 1
fi
/bin/rm ${ADMIN_FILE}
return 0