Sample Manifests
The manifest is the blueprint from which the image is generated, the SUNWdistro-const package in 2008.11 comes with 3 sample manifests. These manifests are used for building images distributed in the 2008.11 release.
- /usr/share/distro_const/slim_cd/slim_cd.xml: Used for building the limited language OpenSolaris Live CD and USB images
- /usr/share/distro_const/slim_cd/all_lang_slim_cd.xml: Used for building the all language OpenSolaris Live CD and USB images
- /usr/share/distro_const/auto_install/ai_x86_image.xml: Used for building the automated installer image
Common Customization Tasks
The DC sets up the package image area, populates it with packages specified in the manifest, and customizes the image by executing finalizer scripts specified in the manifest. The manifest is the blueprint from which the image is generated, all your customizations should be specified in the manifest. See the Distribution Constructor design specification for details on each item in the manifest. Most of your customizations are done in the following sections.
<packages> section
<packages>
<pkg name="SUNWcsd"/>
<pkg name="slim_cd"/>
<pkg name="SUNWcs"/>
<pkg name="slim_install"/>
<pkg name="SUNWslim-utils"/>
<pkg name="entire"/>
</packages>
This is the list of packages or cluster of packages to be included in the image. Add or remove packages from this section to add/subtract content.
<bootroot_contents> section
<bootroot_contents>
<base_include type="file">usr/sbin/pmadm</base_include>
<base_include type="file">usr/sbin/lofiadm</base_include>
<base_include type="file">usr/sbin/devfsadm</base_include>
<base_include type="file">usr/sbin/modload</base_include>
<base_include type="file">usr/sbin/i86/modload</base_include>
<base_include type="file">usr/sbin/mount</base_include>
<base_include type="file">usr/sbin/hostconfig</base_include>
.........
<base_include type="dir">var/svc/manifest</base_include>
<base_include type="dir">var/svc/profile</base_include>
<base_include type="dir">var/pkg/catalog</base_include>
<base_include type="dir">etc</base_include>
<base_exclude type="dir">etc/gconf</base_exclude>
<base_exclude type="dir">etc/brltty</base_exclude>
<base_exclude type="dir">etc/gtk-2.0</base_exclude>
</bootroot_contents>
List of files and directories to be included in the bootroot of the image. All files and directories specified here are copied from the package image area. If a file or directory needs to be excluded, specify it with the "base_exclude" tag.
<finalizer> section
<finalizer>
<script name="/usr/share/distro_const/slim_cd/pre_bootroot_pkg_image_mod">
<checkpoint name="im-mod" message="Image area Modifications"/>
</script>
<script name="/usr/share/distro_const/bootroot_configuration.py">
<checkpoint name="br-config" message="Boot root configuration"/>
<argslist>
?/usr/share/distro_const/slim_cd/slimcd_generic_live.xml?
?.livecd?
</argslist>
</script>
<script name="/usr/share/distro_const/create_usb">
<checkpoint name="usb" message="USB image creation"/>
</script>
</finalizer>
List of scripts for customizing the image. These scripts are provided by the user. A few standard scripts are also included as part of DC. These scripts can be found in /usr/share/distro_const. Scripts are executed in the order they are listed in the <finalizer> section. These can be Python programs, shell scripts or binaries. By default, the DC passes 5 arguments to all programs/scripts executed. The 5 arguments are:
- server socket file name: server socket used for accessing manifest data
- package image area path: path to the package image area
- tmp dir: path to the /tmp directory for temp files.
- Bootroot build area: this is where the bootroot gets put together.
- Media area: this is where the output images will go
When specifying a finalizer script, you have to specify a name used for referencing this script during checkpointing. The checkpoint name can be any string as long as it is unique compared to other existing checkpoing names. The checkpoint message is optional. If it is not specified, the path of the script will be used as the checkpoint message.
Arguments to the finalizer scripts/programs are passed in by specifying them with the <argslist> tag. Spaces used for formatting the XML are also passed in, make sure your program/script strip them. Other information can also be passed to scripts by specifying them as key-value pairs. Stdout and stderr for the scripts are captured in the log files.
Finalizer Script Examples
When putting together an image, we find ourselves wanting to experiment with how an image will work when we add a few additional packages or remove a few packages from a known to be working set. This is fully supported by the Distribution Constructor. Additional packages can be added to the existing list in <package> section, and packages that you want to remove can be added to the <post_install_remove_package> section. Unfortunately, after you made your modification, you need to restart the build process from the very beginning, and re-download all the packages. That will take quiet a bit of time.
In the future, we will add support for downloading a major set of packages, then, allow people to add or subtract to this list, and have it be done in a separate checkpoint, so, people can easily experiment. At the mean time, you can do this yourself quiet easily with finalizer scripts.
These finalizer scripts will add or remove packages from the package image area. So, they should be the very first finalizer scripts in the <finalizer> section in the manifest. For example, if you have created a script "/export/home/user1/test_my_pkg" to test your own package, you would add it as follows in the finalizer section.
<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, you should start your build from the beginning once. After that, if you make any changes to your package, you don't need to re-start 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 very beginning after modifying the manifest. This just need to be done once.
distro_const build /my_updated_manifest.xml
- Check steps that are resumable
distro_const build -l /my_updated_manifest.xml
- Re-start from the step of your package modification. You can restart from this step as many times as you need while you debugging your modified package/contents.
distro_const build -r my_test /my_updated_manifest.xml
Example 1
A finalizer script to add an IPS package from an alternate repo specified in the manifest. The package will be added to the package image area. The name of the package to add is just hard coded in the script. This example also demonstrates how to use the ManifestRead program to get values from the manifest.
#!/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="http://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
Example 2
A package is already installed in the package image area because it is specified in the section of the manifest. I have a test version of this package, I want to test out my version of the package. So, we need a finalizer script to replace the previously installed version with a test version from an alternate repo. This will be helpful for testing your own private copy of a package. This example assumes that you have a IPS repository server running on http://localhost:10000. The name of the package to replace is passed as an argument. This example also demonstrates how to get arguments passed in as finalizer script arguments. The script first uninstalls the existing version, then, install the test version from the alternate repo.
#!/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 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) # # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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="http://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
Example 3
You have a package that's still in the SVR4 format. You want to include the content of this package into the image to see how it works before you convert it into an IPS package. This example shows you how to add a SVR4 package to the image using a finalizer script.
#!/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 ${PKG_IMG_PATH}/var/sadm/install/.lockfile /bin/rm ${ADMIN_FILE} return 0