Prepare and Finish Scripts
Overview
Sometimes it is necessary to run a procedure before the package archive extraction begins, and directly afterwards. The Package module implements the installation lifecycle in four steps each implemented by a separate command.
- prepare: Procedure to run before the package archive is downloaded from the repository and extracted.
- get: Retrieves the package from the repository.
- extract: Extracts the package archive into the installation root directory.
- finish: Procedure to run after the package archive has been extracted.
The prepare and extract commands are essentially hook commands that can be configured to run a user-specified script. This document describes how to specify scripts you've written as the procedures for those commands to invoke.
There can be any number of reasons why prepare and finish procedures might be necessary. A preparation procedure might ensure the environment complies to the assumptions of the package installation. The finish step might involve customizing files after extraction.
The following sections describes how you can incorporate your procedures into the package installation life cycle.
Registering prepare and finish scripts
As you may have already learned from the creating packages document, packages are registered during the creation or upload step. Facilitating the registration process is a package metadata file. Using the package metadata file, you can also register scripts to be run by the prepare and finish commands.
The following example shows how to the necessary XML tags for the package metadata and assumes you want to upload a package file at hand.
1. Define the package metadata file
The example XML file below shows metadata about a tomcat package. In addition to using the package tag, there are several other tags. The setting tags are used to define the prepare and finish scripts you wish to run. The resources tags are used to tie that information as settings of the package.
The bolded text shows paths to scripts that are assumed to exist on the target machine.
The italized text shows a convention which you might choose to employ which uses the package's name as the name for the setting names. The name acts like a key that links the information. This naming is nothing more than convention and you are free to choose any convention that assists identification and correspondence.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE project PUBLIC "-//ControlTier Software Inc.//DTD Project Document 1.0//EN"
"project.dtd">
<project>
<!--
**
** Defines path to the prepare and finish scripts
**
-->
<setting type="PackagePrepareScript" name="apache-tomcat-5.5.26.zip"
description="The script used during finish"
settingValue="$HOME/bin/tomcat-prepare.sh" settingType="script"/>
<setting type="PackageFinishScript" name="apache-tomcat-5.5.26.zip"
description="The script used during prepare"
settingValue="$HOME/bin/tomcat-finish.sh" settingType="script"/>
<package
arch="noarch"
base="apache-tomcat-5.5.26"
buildtime="2008061570109"
description="The Tomcat application server."
filename="apache-tomcat-5.5.26.zip"
filetype="zip"
installroot="/demo/apache-tomcat-5.5.26"
installrank=""
name="apache-tomcat-5.5.26.zip"
release=""
releasetag=""
repoUrl="${framework.pkgRepo.upload-url}/default/zip/zips/apache-tomcat-5.5.26.zip"
restart="false"
type="zip"
vendor=""
version="5.5.26"
>
<!--
**
** References the prepare and finish scripts as dependencies to the package
**
-->
<resources>
<resource type="PackagePrepareScript" name="apache-tomcat-5.5.26.zip"/>
<resource type="PackageFinishScript" name="apache-tomcat-5.5.26.zip"/>
</resources>
</package>
</project>
2. Upload the file to the repository
The next step is to upload the file to the repository using the metadata defined in the xml file above.
ctl -m zip -c upload -- \
-xml /tmp/package.xml
-filename /tmp/apache-tomcat-5.5.26.zip
Formalizing your package control scripts
The above approach is useful when you can rely on the fact the prepare or finish scripts exist on each of the machines where your packages are to be installed. You may also find cases where you want to provide a set of additional files used during the prepare and finish steps. Finally, it might be desireable to define default script path names for the prepare and finish steps, thus avoiding having to always specify them in the package metadata file.
Package control is governed by a CTL module (like "zip" used in the example above). CTL modules are useful for defining your own defaults, and for packaging your scripts and additional files those scripts might need.
1. Create a new Package type
Module creation is done via the "ProjectBuilder" module's create-type command. For this example, the "zip" type is subtyped to one called "myzip".
ctl -m ProjectBuilder -c create-type -- -supertype zip -type myzip
After running the command you will have the initial source code for the myzip module. By default, the source should be found in: $CTL_BASE/src/modules/myzip.
Modules have a standard directory structure with standard subdirectories where you can store your files.
module_name
|
|--- type.xml // file containing module definitions
|
+--- bin/ // optional binaries, shell scripts, etc.
|
+--- commands/ // contains generated command files
|
+--- lib/ // optional resource files
By convention, the bin directory is where you can locate scripts called by the prepare and finish steps. In the lib subdirectory, you can store other files like templates, or data files your scripts might need.
2. Place your scripts into the module source directory
Let's assume you have already written scripts for your preparation and finish steps. These scripts might already exist or you may be just now formalizing accepted procedure.
In this example, assume you have two bourne shell scripts ready to go, one called prepare.sh and the other finish.sh.
Copy the preparation script:
cp prepare.sh $CTL_BASE/src/modules/myzip/bin/prepare.sh
Copy the finish script:
cp finish.sh $CTL_BASE/src/modules/myzip/bin/finish.sh
The scripts are now part of the module's source files and will be packaged into the module in step#4. Packaging your scripts and files inside the module ensures they'll be at hand when the prepare and finish steps occur during package installation.
The standard ControlTier package types support three kinds of scripts and recognizes them based on their file extension:
- .sh: a bourne shell script
- .bat: a windows batch file
- .xml: an ant build file
If you have script code you'd like to run and do not want to invoke it via any of these three script types above, you can override the create and finish commands.
3. Assign the defaults
Defaults are defined using the attribute-default tags inside the type.xml file.
Edit the generated type.xml file and modify the attribute definitions for the package-prepare-script and package-finish-script attributes (eg, edit $CTL_BASE/src/modules/myzip/type.xml). Locate the attributes tag and change the following attribute-default definitions:
<attributes>
...
<attribute-default name="package-prepare-script"
value="${module.dir}/bin/prepare.sh">
<doc>script to execute for prepare command</doc>
</attribute-default>
<attribute-default name="package-finish-script"
value="${module.dir}/bin/finish.sh">
<doc>script to execute for finish command</doc>
</attribute-default>
</attributes>
In step#2, the scripts were copied into the bin/ subdirectory of the module source. The ${module.dir}/bin path represents the module directory's bin/ path after the module has been installed.
Only convention suggests to name your scripts prepare.sh and finish.sh. You can name them whatever you wish; just specify the correct filenames in the attribute-default tags.
4. Build the new Package type
The last step packages your files into the module and makes them ready during package installation.
ctl -m ProjectBuilder -c build-type -- -type myzip -upload
You may wish to add other files to your module source later. Simply, rerun the build-type command to ensure they are loaded into the repository.


