Application Packaging Developer's Guide

Chapter 3 Enhancing the Functionality of a Package (Tasks)

This chapter describes how to create optional information files and installation scripts for a package. While Chapter 2, Building a Package discussed the minimum requirements for making a package, this chapter discusses additional functionality that you can build into a package. This additional functionality is based on the criteria you considered when planning how to design your package. For more information, see Considerations Before Building a Package.

This is a list of the overview information in this chapter.

Creating Information Files and Installation Scripts (Task Map)

The following task map describes the optional features you can build into a package.

Table 3–1 Creating Information Files and Installation Scripts (Task Map)

Task 

Description 

For Instructions 

1. Create information files 

Define package dependencies

A definition of package dependencies allows you to specify whether your package is compatible with previous versions, dependent on other packages, or whether other packages are dependent on yours. 

How to Define Package Dependencies

 

Write a copyright message

A copyright file provides legal protection for your software application.

How to Write a Copyright Message

 

Reserve additional space on the target system.

A space file sets aside blocks on the target system, which enables you to create files during installation that are not defined in the pkgmap file.

How to Reserve Additional Space on a Target System

2. Create installation scripts 

Obtain information from the installer

A request script enables you to obtain information from the person installing your package.

How to Write a request Script

 

Gather file system data needed for installation

A checkinstall script enables you to perform an analysis of the target system and set up the correct environment for, or cleanly halt, the installation.

How to Gather File System Data

 

Write procedure scripts

Procedure scripts enable you to provide customized installation instructions during specific phases of the installation or removal process. 

How to Write Procedure Scripts

 

Write class action scripts

Class action scripts enable you to specify a set of instructions to be executed during package installation and removal on specific groups of package objects. 

How to Write Class Action Scripts

Creating Information Files

This section discusses optional package information files. With these files you can define package dependencies, provide a copyright message, and reserve additional space on a target system.

Defining Package Dependencies

You need to determine whether your package has dependencies on other packages and if any other packages depend on yours. Package dependencies and incompatibilities can be defined with two of the optional package information files, compver and depend.

Delivering a compver file lets you name previous versions of your package that are compatible with the package being installed.

Delivering a depend file lets you define three types of dependencies associated with your package. These dependency types are as follows:

The depend file resolves only very basic dependencies. If your package depends upon a specific file, its contents, or its behavior, the depend file does not supply adequate precision. In this case, a request script or the checkinstall script should be used for detailed dependency checking. The checkinstall script is also the only script capable of cleanly halting the package installation process.


Note –

Be certain that your depend and compver files have entries in the prototype file. The file type should be i (for package information file).


Refer to the depend(4) and compver(4) man pages for more information.

ProcedureHow to Define Package Dependencies

  1. Make the directory that contains your information files the current working directory.

  2. If previous versions of your package exist and you need to specify that your new package is compatible with them, create a file named compver with your favorite text editor.

    List the versions with which your package is compatible. Use this format:


    string string . . .
    

    The value of string is identical to the value assigned to the VERSION parameter in the pkginfo file, for each compatible package.

  3. Save your changes and quit the editor.

  4. If your package depends on the existence of other packages, other packages depend on the existence of your package, or your package is incompatible with another package, create a file named depend with your favorite text editor.

    Add an entry for each dependency. Use this format:


    type pkg-abbrev pkg-name
        (arch) version
        (arch) version . . .
    
    type

    Defines the dependency type. Must be one of the following characters: P (prerequisite package), I (incompatible package), or R (reverse dependency).

    pkg-abbrev

    Specifies the package abbreviation, such as SUNWcadap.

    pkg-name

    Specifies the full package name, such as Chip designers need CAD application software to design abc chips. Runs only on xyz hardware and is installed in the usr partition.

    (arch)

    Optional. Specifies the type of hardware on which the package runs. For example, sparc or x86. If you specify an architecture, you must use the parentheses as delimiters.

    version

    Optional. Specifies the value assigned to the VERSION parameter in the pkginfo file.

    For more information, see depend(4).

  5. Save your changes and quit the editor.

  6. Complete one of the following tasks:

  7. Build your package.

    See How to Build a Package, if needed.


Example 3–1 compver File

In this example, there are four versions of a package: 1.0, 1.1, 2.0, and the new package, 3.0. The new package is compatible with all the three previous versions. The compver file for the newest version might look like the following:


release 3.0
release 2.0
version 1.1
1.0

The entries do not have to be in sequential order. However, they should exactly match the definition of the VERSION parameter in each package's pkginfo file. In this example, the package designers used different formats in the first three versions.



Example 3–2 depend File

This example assumes that the sample package, SUNWcadap, requires that the SUNWcsr and SUNWcsu packages already be installed on a target system. The depend file for SUNWcadap looks like the following:


P SUNWcsr Core Solaris, (Root)
P SUNWcsu Core Solaris, (Usr)

See Also

After you build the package, install it to confirm that it installs correctly and verify its integrity. Chapter 4, Verifying and Transferring a Package explains these tasks and provides step-by-step instructions on how to transfer your verified package to a distribution medium.

Writing a Copyright Message

You need to decide whether your package should display a copyright message while it is being installed. If so, create the copyright file.


Note –

You should include a copyright file to provide legal protection for your software application. Check with the legal department of your company for the exact wording of the message.


To deliver a copyright message, you must create a file named copyright. During installation, the message is displayed exactly as it appears in the file (with no formatting). See the copyright(4) man page for more information.


Note –

Be certain that your copyright file has an entry in the prototype file. The file type should be i (for package information file).


ProcedureHow to Write a Copyright Message

  1. Make the directory that contains your information files the current working directory.

  2. Create a file named copyright with your favorite text editor.

    Type the text of the copyright message exactly as you want it to appear as your package is installed.

  3. Save your changes and quit the editor.

  4. Complete one of the following tasks.

  5. Build your package.

    See How to Build a Package, if needed.


Example 3–3 copyright File

For example, a partial copyright message might look like the following:


Copyright (c) 2003 Company Name
All Rights Reserved
 
This product is protected by copyright and distributed under
licenses restricting copying, distribution, and decompilation.

See Also

After you build the package, install it to confirm that it installs correctly and verify its integrity. Chapter 4, Verifying and Transferring a Package explains these tasks and provides step-by-step instructions on how to transfer your verified package to a distribution medium.

Reserving Additional Space on a Target System

You need to determine whether your package needs additional disk space on the target system. This space is in addition to the space required by the package objects. If so, create the space information file. This task is different than creating empty files and directories at installation time, as discussed in Defining Additional Objects to Be Created at Install Time.

The pkgadd command ensures that there is enough disk space to install your package based on the object definitions in the pkgmap file. However, a package may require additional disk space beyond that needed by the objects defined in the pkgmap file. For example, your package might create a file after installation, which may contain a database, log files, or some other growing file that consumes disk space. To be sure that there is space reserved for it, you should include a space file that specifies the disk space requirements. The pkgadd command checks for the additional space specified in a space file. Refer to the space(4) man page for more information.


Note –

Be certain that your space file has an entry in the prototype file. The file type should be i (for package information file).


ProcedureHow to Reserve Additional Space on a Target System

  1. Make the directory that contains your information files the current working directory.

  2. Create a file named space with your favorite text editor.

    Specify any additional disk space requirements needed by your package. Use this format:


    pathname blocks inodes
    
    pathname

    Specifies a directory name, which may or may not be the mount point for a file system.

    blocks

    Specifies the number of 512-byte blocks that you want reserved.

    inodes

    Specifies the number of required inodes.

    For more information, see the space(4) man page.

  3. Save your changes and quit the editor.

  4. Complete one of the following tasks.

  5. Build your package.

    See How to Build a Package, if needed.


Example 3–4 space File

This example space file specifies that 1000 512-byte blocks and 1 inode be reserved in the /opt directory on the target system.


/opt   1000   1

See Also

After you build the package, install it to confirm that it installs correctly and verify its integrity. Chapter 4, Verifying and Transferring a Package explains these tasks and provides step-by-step instructions on how to transfer your verified package to a distribution medium.

Creating Installation Scripts

This section discusses optional package installation scripts. The pkgadd command automatically performs all the actions necessary to install a package using the package information files as input. You do not have to supply any package installation scripts. However, if you want to create customized installation procedures for your package, you can do so with installation scripts. Installation scripts:

There are four types of installation scripts with which you can perform customized actions:

Script Processing During Package Installation

The type of scripts you use depends on when the action of the script is needed during the installation process. As a package is installed, the pkgadd command performs the following steps:

  1. Executes the request script.

    This step is the only point at which your package can solicit input from the administrator who is installing the package.

  2. Executes the checkinstall script.

    The checkinstall script gathers file system data and can create or alter environment variable definitions to control the subsequent installation. For more information on package environment variables, see Package Environment Variables.

  3. Executes the preinstall script.

  4. Installs package objects, for each class to be installed.

    Installation of these files occurs class by class, and class action scripts are executed accordingly. The list of classes operated on and the order in which they should be installed is initially defined with the CLASSES parameter in your pkginfo file. However, your request script or checkinstall script can change the value of the CLASSES parameter. For more information on how classes are processed during installation, see How Classes Are Processed During Package Installation.

    1. Creates symbolic links, devices, named pipes, and required directories.

    2. Installs the regular files (file types e, v, f), based on their class

      The class action script is passed only regular files to install. All other package objects are created automatically from information in the pkgmap file.

    3. Creates all hard links.

  5. Executes the postinstall script.

Script Processing During Package Removal

When a package is being removed, the pkgrm command performs these steps:

  1. Executes the preremove script.

  2. Removes the package objects, for each class

    Removal also occurs class by class. Removal scripts are processed in the reverse order of installation, based on the sequence defined in the CLASSES parameter. For more information on how classes are processed during installation, see How Classes Are Processed During Package Installation.

    1. Removes hard links.

    2. Removes regular files.

    3. Removes symbolic links, devices, and named pipes.

  3. Executes the postremove script.

The request script is not processed at the time of package removal. However, the script's output is retained in the installed package and made available to removal scripts. The request script's output is a list of environment variables.

Package Environment Variables Available to Scripts

The following groups of environment variables are available to all installation scripts. Some of the environment variables can be modified by a request script or a checkinstall script.

Obtaining Package Information for a Script

Two commands can be used from scripts to solicit information about a package:

Exit Codes for Scripts

Each script must exit with one of the exit codes shown in the following table.

Table 3–2 Installation Script Exit Codes

Code 

Meaning 

Successful completion of script.  

Fatal error. Installation process is terminated at this point.  

2  

Warning or possible error condition. Installation continues. A warning message is displayed at the time of completion.  

3  

The pkgadd command is cleanly halted. Only the checkinstall script returns this code.

10  

System should be rebooted when installation of all selected packages is completed. (This value should be added to one of the single-digit exit codes.)  

20  

System should be rebooted immediately upon completing installation of the current package. (This value should be added to one of the single-digit exit codes.)  

See Chapter 5, Case Studies of Package Creation for examples of exit codes that are returned by installation scripts.


Note –

All installation scripts delivered with your package should have an entry in the prototype file. The file type should be i (for package installation script).


Writing a request Script

The request script is the only way your package can interact directly with the administrator who is installing it. This script can be used, for example, to ask the administrator if optional pieces of a package should be installed.

The output of a request script must be a list of environment variables and their values. This list can include any of the parameters that you created in the pkginfo file, and the CLASSES and BASEDIR parameters. The list can also introduce environment variables that have not been defined elsewhere. However, the pkginfo file should always provide default values when practical. For more information on package environment variables, see Package Environment Variables.

When your request script assigns values to an environment variable, it must then make those values available to the pkgadd command and other package scripts.

request Script Behaviors

Design Rules for request Scripts


Note –

If the administrators who will be installing your package might use the JumpStartTM product, then the installation of your package must not be interactive. Either you should not provide a request script with your package, or you need to communicate to the administrators that they should use the pkgask command prior to installation. The pkgask command stores their responses to the request script. For more information on the pkgask command, see the pkgask(1M) man page.


ProcedureHow to Write a request Script

  1. Make the directory that contains your information files the current working directory.

  2. Create a file named request with your favorite text editor.

  3. Save your changes and quit the editor when you are done.

  4. Complete one of the following tasks.

  5. Build your package.

    See How to Build a Package, if needed.


Example 3–5 Writing a request Script

When a request script assigns values to environment variables, it must make those values available to the pkgadd command. This example shows a request script segment that performs this task for the four environment variables: CLASSES, NCMPBIN, EMACS, and NCMPMAN. Assume that these variables were defined in an interactive session with the administrator earlier in the script.


# make environment variables available to installation
# service and any other packaging script we might have
 
cat >$1 <<!
CLASSES=$CLASSES
NCMPBIN=$NCMPBIN
EMACS=$EMACS
NCMPMAN=$NCMPMAN
!

See Also

After you build the package, install it to confirm that it installs correctly and verify its integrity. Chapter 4, Verifying and Transferring a Package explains these tasks and provides step-by-step instructions on how to transfer your verified package to a distribution medium.

Gathering File System Data With the checkinstall Script

The checkinstall script is executed shortly after the optional request script. The checkinstall script runs as the user install, if such a user exists, or as the user nobody. The checkinstall script does not have the authority to change file system data. However, based on the information the script gathers, it can create or modify environment variables in order to control the course of the resulting installation. The script is also capable of cleanly halting the installation process.

The checkinstall script is intended to perform basic checks on a file system that would not be normal for the pkgadd command. For example, this script can be used to check ahead to determine if any files from the current package are going to overwrite existing files, or manage general software dependencies. The depend file only manages package-level dependencies.

Unlike the request script, the checkinstall script is executed whether or not a response file is provided. The script's presence does not brand the package as interactive. The checkinstall script can be used in situations where a request script is forbidden or administrative interaction is not practical.


Note –

The checkinstall script is available starting with the Solaris 2.5 and compatible releases.


checkinstall Script Behaviors

Design Rules for checkinstall Scripts

ProcedureHow to Gather File System Data

  1. Make the directory that contains your information files the current working directory.

  2. Create a file named checkinstall with your favorite text editor.

  3. Save your changes and quit the editor when you are done.

  4. Complete one of the following tasks.

  5. Build your package.

    See How to Build a Package, if needed.


Example 3–6 Writing a checkinstall Script

This example checkinstall script checks to see if database software needed by the SUNWcadap package is installed.


# checkinstall script for SUNWcadap
#
# This confirms the existence of the required specU database
 
# First find which database package has been installed.
pkginfo -q SUNWspcdA	# try the older one
 
if [ $? -ne 0 ]; then
   pkginfo -q SUNWspcdB	# now the latest
 
	  if [ $? -ne 0 ]; then	# oops
		    echo "No database package can be found. Please install the"
		    echo "SpecU database package and try this installation again."
		    exit 3		# Suspend
	  else
		    DBBASE="`pkgparam SUNWsbcdB BASEDIR`/db"	# new DB software
	  fi
else
	  DBBASE="`pkgparam SUNWspcdA BASEDIR`/db"	# old DB software
fi
 
# Now look for the database file we will need for this installation
if [ $DBBASE/specUlatte ]; then
	  exit 0		# all OK
else
	  echo "No database file can be found. Please create the database"
	  echo "using your installed specU software and try this"
	  echo "installation again."
	  exit 3		# Suspend
fi
 

See Also

After you build the package, install it to confirm that it installs correctly and verify its integrity. Chapter 4, Verifying and Transferring a Package explains these tasks and provides step-by-step instructions on how to transfer your verified package to a distribution medium.

Writing Procedure Scripts

The procedure scripts provide a set of instructions to be performed at particular points in package installation or removal. The four procedure scripts must be named one of the predefined names, depending on when the instructions are to be executed. The scripts are executed without arguments.

Procedure Script Behaviors

Procedure scripts are executed as uid=root and gid=other.

Design Rules for Procedure Scripts

ProcedureHow to Write Procedure Scripts

  1. Make the directory that contains your information files the current working directory.

  2. Create one or more procedure scripts with your favorite text editor.

    A procedure script must be named one of the predefined names: preinstall, postinstall, preremove, or postremove.

  3. Save your changes and quit the editor.

  4. Complete one of the following tasks.

  5. Build your package.

    See How to Build a Package, if needed.

See Also

After you build the package, install it to confirm that it installs correctly and verify its integrity. Chapter 4, Verifying and Transferring a Package explains these tasks and provides step-by-step instructions on how to transfer your verified package to a distribution medium.

Writing Class Action Scripts

Defining Object Classes

Object classes allow a series of actions to be performed on a group of package objects at installation or removal. You assign objects to a class in the prototype file. All package objects must be given a class, although the class of none is used by default for objects that require no special action.

The installation parameter CLASSES, defined in the pkginfo file, is a list of classes to be installed (including the none class).


Note –

Objects defined in the pkgmap file that belong to a class not listed in this parameter in the pkginfo file will not be installed.


The CLASSES list determines the order of installation. Class none is always installed first, if present, and removed last. Since directories are the fundamental support structure for all other file system objects, they should all be assigned to the none class. Exceptions can be made, but as a general rule, the none class is safest. This strategy ensures that the directories are created before the objects they will contain. In addition, no attempt is made to delete a directory before it has been emptied.

How Classes Are Processed During Package Installation

The following describes the system actions that occur when a class is installed. The actions are repeated once for each volume of a package, as that volume is being installed.

  1. The pkgadd command creates a path name list.

    The pkgadd command creates a list of path names upon which the action script operates. Each line of this list contains source and destination path names, separated by a space. The source path name indicates where the object to be installed resides on the installation volume. The destination path name indicates the location on the target system where the object should be installed. The contents of the list are restricted by the following criteria:

    • The list contains only path names that belong to the associated class.

    • If the attempt to create the package object fails, then directories, named pipes, character devices, block devices, and symbolic links are included in the list with the source path name set to /dev/null. Normally, these items are automatically created by the pkgadd command (if not already in existence) and given proper attributes (mode, owner, group) as defined in the pkgmap file.

    • Linked files where the file type is l are not included in the list under any circumstances. Hard links in the given class are created in item 4.

  2. If no class action script is provided for installation of a particular class, the path names in the generated list are copied from the volume to the appropriate target location.

  3. A class action script is executed if one exists.

    The class action script is invoked with standard input that contains the list generated in item 1. If this volume is the last volume of the package, or no more objects exist in this class, the script is executed with the single argument of ENDOFCLASS.


    Note –

    Even if no regular files of this class exist in the package, the class action script is called at least once with an empty list and the ENDOFCLASS argument.


  4. The pkgadd command performs a content and attribute audit, and creates hard links.

    After successfully executing items 2 or 3, the pkgadd command audits both content and attribute information for the list of path names. The pkgadd command creates the links associated with the class automatically. Detected attribute inconsistencies are corrected for all path names in the generated list.

How Classes Are Processed During Package Removal

Objects are removed class by class. Classes that exist for a package but are not listed in the CLASSES parameter are removed first (for example, an object installed with the installf command). Classes listed in the CLASSES parameter are removed in reverse order. The none class is always removed last. The following describes the system actions that occur when a class is removed:

  1. The pkgrm command creates a path name list.

    The pkgrm command creates a list of installed path names that belong to the indicated class. Path names referenced by another package are excluded from the list unless their file type is e. A file type of e means the file should be edited upon installation or removal.

    If the package being removed had modified any files of type e during installation, it should remove just the lines it added. Do not delete a non-empty editable file. Remove the lines that the package added.

  2. If no class action script exists, the path names are deleted.

    If your package has no removal class action script for the class, all the path names in the list generated by the pkgrm command are deleted.


    Note –

    Files with a file type of e (editable) are not assigned to a class and an associated class action script. These files are removed at this point, even if the path name is shared with other packages.


  3. If a class action script exists, the script is executed.

    The pkgrm command invokes the class action script with standard input for the script that contains the list generated in item 1.

  4. The pkgrm command performs an audit.

    After successfully executing the class action script, the pkgrm command removes references to the path names from the package database unless a path name is referenced by another package.

The Class Action Script

The class action script defines a set of actions to be executed during installation or removal of a package. The actions are performed on a group of path names based on their class definition. See Chapter 5, Case Studies of Package Creation for examples of class action scripts.

The name of a class action script is based on the class on which it should operate and whether those operations should occur during package installation or package removal. The two name formats are shown in the following table:

Name Format 

Description 

i.class

Operates on path names in the indicated class during package installation 

r.class

Operates on path names in the indicated class during package removal  

For example, the name of the installation script for a class named manpage would be i.manpage. The removal script would be named r.manpage.


Note –

This file name format is not used for files that belong to the sed, awk, or build system classes. For more information on these special classes, see The Special System Classes.


Class Action Script Behaviors

Design Rules for Class Action Scripts

The Special System Classes

The system provides four special classes:

If several files in a package require special processing that can be fully defined through sed, awk, or sh commands, installation is faster by using the system classes rather than multiple classes and their corresponding class action scripts.

The sed Class Script

The sed class provides a method to modify an existing object on the target system. The sed class action script executes automatically at installation if a file that belongs to class sed exists. The name of the sed class action script should be the same as the name of the file on which the instructions are executed.

A sed class action script delivers sed instructions in the following format:

Two commands indicate when instructions should be executed. The sed instructions that follow the !install command are executed during package installation. The sed instructions that follow the !remove command are executed during package removal. The order in which these commands are used in the file does not matter.

For more information on sed instructions, see the sed(1) man page. For examples of sed class action scripts, see Chapter 5, Case Studies of Package Creation.

The awk Class Script

The awk class provides a method to modify an existing object on the target system. Modifications are delivered as awk instructions in an awk class action script.

The awk class action script is executed automatically at installation if a file that belongs to class awk exists. Such a file contains instructions for the awk class script in the following format:

Two commands indicate when instructions should be executed. The awk instructions that follow the !install command are executed during package installation. The instructions that follow the !remove command are executed during package removal. These commands may be used in any order.

The name of the awk class action script should be the same as the name of the file on which the instructions are executed.

The file to be modified is used as input to the awk command and the output of the script ultimately replaces the original object. Environment variables may not be passed to the awk command with this syntax.

For more information on awk instructions, see the awk(1) man page.

The build Class Script

The build class creates or modifies a package object file by executing Bourne shell instructions. These instructions are delivered as the package object. The instructions run automatically at installation if the package object belongs to the build class.

The name of the build class action script should be the same as the name of the file on which the instructions are executed. The name must also be executable by the sh command. The script's output becomes the new version of the file as it is built or modified. If the script produces no output, the file is not created or modified. Therefore, the script can modify or create the file itself.

For example, if a package delivers a default file, /etc/randomtable, and if the file does not already exist on the target system, the prototype file entry might be as follows:


e build /etc/randomtable ? ? ?

The package object, /etc/randomtable, might look like the following:


!install
# randomtable builder
if [ -f $PKG_INSTALL_ROOT/etc/randomtable ]; then
		echo "/etc/randomtable is already in place.";
	    else
		echo "# /etc/randomtable" > $PKG_INSTALL_ROOT/etc/randomtable
		echo "1121554	# first random number" >> $PKG_INSTALL_ROOT/etc/randomtable
fi
 
!remove
# randomtable deconstructor
if [ -f $PKG_INSTALL_ROOT/etc/randomtable ]; then
		# the file can be removed if it's unchanged
		if [ egrep "first random number" $PKG_INSTALL_ROOT/etc/randomtable ]; then
			rm $PKG_INSTALL_ROOT/etc/randomtable;
		fi
fi
 

See Chapter 5, Case Studies of Package Creation for another example using the build class.

The preserve Class Script

The preserve class preserves a package object file by determining whether or not an existing file should be overwritten when the package is installed. Two possible scenarios when using a preserve class script are:

Both scenario outcomes are considered successful by the preserve script. A failure occurs only in the second scenario when the file is unable to be copied to the target directory.

Starting with the Solaris 7 release, the i.preserve script and a copy of this script, i.CONFIG.prsv, can be found in the /usr/sadm/install/scripts directory with the other class action scripts.

Modify the script to include the filename or filenames you would like to preserve.

The manifest Class Script

The manifest class automatically installs and uninstalls SMF (Service Management Facility) services associated with an SMF manifest. If you are not familiar with SMF, see Chapter 17, Managing Services (Overview), in System Administration Guide: Basic Administration for information about how to use SMF to manage services.

All service manifests within packages should be identified with the class manifest. Class action scripts that install and remove service manifests are included in the packaging subsystem. When pkgadd(1M) is invoked, the service manifest is imported. When pkgrm(1M) is invoked, instances in the service manifest that are disabled are deleted. Any services in the manifest that have no remaining instances are also deleted. If the -R option is supplied to pkgadd(1M) or pkgrm(1M), these service manifest actions will be done when the system is next rebooted with that alternate root path.

The following portion of code from a package information file shows the use of the manifest class.

# packaging files
i pkginfo
i copyright
i depend
i preinstall
i postinstall
i i.manifest
i r.manifest
#
# source locations relative to the prototype file
#
d none var 0755 root sys
d none var/svc 0755 root sys
d none var/svc/manifest 0755 root sys
d none var/svc/manifest/network 0755 root sys
d none var/svc/manifest/network/rpc 0755 root sys
f manifest var/svc/manifest/network/rpc/smserver.xml 0444 root sys

ProcedureHow to Write Class Action Scripts

  1. Make the directory that contains your information files the current working directory.

  2. Assign the package objects in the prototype file the desired class names.

    For example, assigning objects to an application and manpage class would look like the following:


    f manpage /usr/share/man/manl/myappl.1l
    f application /usr/bin/myappl
  3. Modify the CLASSES parameter in the pkginfo file to contain the class names you want to use in your package.

    For example, entries for the application and manpage classes would look like the following:


    CLASSES=manpage application none

    Note –

    The none class is always installed first and removed last, regardless of where it appears in the definition of the CLASSES parameter.


  4. If you are a creating a class action script for a file that belongs to the sed, awk, or build class, make the directory that contains the package object your current working directory.

  5. Create the class action scripts or package objects (for files that belong to the sed, awk, or build class).

    For example, an installation script for a class named application would be named i.application and a removal script would be named r.application.

    Remember, when a file is part of a class that has a class action script, the script must install the file. The pkgadd command does not install files for which a class action script exists, although it does verify the installation. And, if you define a class but do not deliver a class action script, the only action taken for that class is to copy components from the installation medium to the target system (the default pkgadd behavior).

  6. Complete one of the following tasks.

  7. Build your package.

    See How to Build a Package, if needed.

Where to Go Next

After you build the package, install it to confirm that it installs correctly and verify its integrity. Chapter 4, Verifying and Transferring a Package explains how to do this and provides step-by-step instructions on how to transfer your verified package to a distribution medium.

Creating Signed Packages

The process of creating signed packages involves a number of steps and requires some comprehension of new concepts and terminology. This section provides information about signed packages, its terminology, and information about certificate management. This section also provides step-by-step procedures about how to create a signed package.

Signed Packages

A signed package is a normal stream-format package that has a digital signature (PEM-encoded PKCS7 digital signature which is defined below) that verifies the following:

A signed package is identical to an unsigned package, except for the signature. A signed package is binary-compatible with an unsigned package. Therefore, a signed package can be used with older versions of the packaging tools. However, the signature is ignored in this case.

The signed packaging technology introduces some new terminology and abbreviations, which are described in the following table.

Term 

Definition 

ASN.1 

Abstract Syntax Notation 1 - A way of expressing abstract objects. For example, ASN.1 defines a public key certificate, all of the objects that make up the certificate, and the order in which the objects are collected. However, ASN.1 does not specify how the objects are serialized for storage or transmission.

X.509 

ITU-T Recommendation X.509 - Specifies the widely-adopted X.509 public key certificate syntax.

DER 

Distinguished Encoding Rules - A binary representation of an ASN.1 object and defines how an ASN.1 object is serialized for storage or transmission in computing environments. 

PEM 

Privacy Enhanced Message - A way to encode a file (in DER or another binary format) using base 64 encoding and some optional headers. PEM was initially used for encoding MIME-type email messages. PEM is also used extensively for encoding certificates and private keys into a file that exists on a file system or in an email message.

PKCS7 

Public Key Cryptography Standard #7 - This standard describes a general syntax for data that may have cryptography applied to it, such as digital signatures and digital envelopes. A signed package contains an embedded PKCS7 signature. This signature contains at a minimum the encrypted digest of the package, along with the signer's X.509 public key certificate. The signed package can also contain chain certificates. Chain certificates can be used when forming a chain of trust from the signer's certificate to a locally-stored trusted certificate. 

PKCS12 

Public Key Cryptography Standard #12 - This standard describes a syntax for storing cryptographic objects on disk. The package keystore is maintained in this format. 

Package keystore 

A repository of certificates and keys that can be queried by the package tools. 

Certificate Management

Before creating a signed package, you must have a package keystore. This package keystore contains certificates in the form of objects. Two types of objects exist in a package keystore:

Trusted certificate

A trusted certificate contains a single public key certificate that belongs to another entity. The trusted certificate is named as such because the keystore owner trusts that the public key in the certificate indeed belongs to the identity indicated by the “subject” (owner) of the certificate. The issuer of the certificate vouches for this trust by signing the certificate.

Trusted certificates are used when verifying signatures and when initiating a connection to a secure (SSL) server.

User key

A user key holds sensitive cryptographic key information. This information is stored in a protected format to prevent unauthorized access. A user key consists of both the user's private key and the public key certificate that corresponds to the private key.

User keys are used when creating a signed package.

By default, the package keystore is stored in the /var/sadm/security directory. Individual users can also have their own keystore stored by default in the $HOME/.pkg/security directory.

On disk, a package keystore can be in two formats: a multiple-file format and a single-file format. A multiple-file format stores its objects in multiple files. Each type of object is stored in a separate file. All of these files must be encrypted using the same passphrase. A single-file keystore stores all of its objects in a single file on the file system.

The primary utility used to manage the certificates and the package keystore is the pkgadm command. The following subsections describe the more common tasks used for managing the package keystore.

Adding Trusted Certificates to the Package Keystore

A trusted certificate can be added to the package keystore using the pkgadm command. The certificate can be in PEM or DER format. For example:


$ pkgadm addcert -t /tmp/mytrustedcert.pem

In this example, the PEM format certificate called mytrustedcert.pem is added to the package keystore.

Adding a User Certificate and Private Key to the Package Keystore

The pkgadm command does not generate user certificates or private keys. User certificates and private keys are normally obtained from a Certificate Authority, such as Verisign. Or, they are generated locally as a self-signed certificate. Once the key and certificate are obtained, they can be imported into the package keystore using the pkgadm command. For example:


pkgadm addcert -n myname -e /tmp/myprivkey.pem /tmp/mypubcert.pem

In this example, the following options are used:

-n myname

Identifies the entity (myname) in the package keystore on which you wish to operate. The myname entity becomes the alias under which the objects are stored.

-e /tmp/myprivkey.pem

Specifies the file that contains the private key. In this case, the file is myprivkey.pem, which is located in the /tmp directory.

/tmp/mypubcert.pem

Specifies the PEM format certificate file called mypubcert.pem.

Verifying the Contents in the Package Keystore

The pkgadm command is also used to view the contents of the package keystore. For example:


$ pkgadm listcert

This command displays the trusted certificates and private keys in the package keystore.

Deleting Trusted Certificates and Private Keys From the Package Keystore

The pkgadm command can be used to delete trusted certificates and private keys from the package keystore.

When you delete user certificates, the alias of the certificate/key pair must be specified. For example:


$ pkgadm removecert -n myname

The alias of the certificate is the common name of the certificate, which can be identified using the pkgadm listcert command. For example, this command deletes a trusted certificate entitled Trusted CA Cert 1:


$ pkgadm removecert -n "Trusted CA Cert 1"

Note –

If you have both a trusted certificate and a user certificate stored using the same alias, they are both deleted when you specify the -n option.


Signed Packages Creation

The process of creating signed packages involves three basic steps:

  1. Creating an unsigned, directory-format package.

  2. Importing the signing certificate, CA certificates, and private key into the package keystore.

  3. Signing the package from Step 1 with the certificates from Step 2.


Note –

The packaging tools do not create certificates. These certificates must be obtained from a Certificate Authority, such as Verisign or Thawte.


Each step for creating signed packages is described in the following procedures.

ProcedureHow to Create an Unsigned, Directory-Format Package

The procedure for creating an unsigned, directory-format package is the same as the procedure for creating a normal package, as previously described in this manual. The following procedure describes the process of creating this unsigned, directory-format package. If you need more information, refer to the previous sections about building packages.

  1. Create the pkginfo file.

    The pkginfo file should have the following basic content:


    PKG=SUNWfoo
    BASEDIR=/
    NAME=My Test Package
    ARCH=sparc
    VERSION=1.0.0
    CATEGORY=application
  2. Create the prototype file.

    The prototye file should have the following basic content:


    $cat prototype
    i pkginfo
    d none usr 0755 root sys
    d none usr/bin 0755 root bin
    f none usr/bin/myapp=/tmp/myroot/usr/bin/myapp 0644 root bin
  3. List the contents of the object source directory.

    For example:


    $ ls -lR /tmp/myroot
    

    The output would appear similar to the following:


    /tmp/myroot:
    total 16
    drwxr-xr-x   3 abc      other        177 Jun  2 16:19 usr
    
    /tmp/myroot/usr:
    total 16
    drwxr-xr-x   2 abc      other        179 Jun  2 16:19 bin
    
    /tmp/myroot/usr/bin:
    total 16
    -rw-------   1 abc      other       1024 Jun  2 16:19 myapp
  4. Create the unsigned package.


    pkgmk -d `pwd`
    

    The output would appear similar to the following:


    ## Building pkgmap from package prototype file.
    ## Processing pkginfo file.
    WARNING: parameter <PSTAMP> set to "syrinx20030605115507"
    WARNING: parameter <CLASSES> set to "none"
    ## Attempting to volumize 3 entries in pkgmap.
    part  1 -- 84 blocks, 7 entries
    ## Packaging one part.
    /tmp/SUNWfoo/pkgmap
    /tmp/SUNWfoo/pkginfo
    /tmp/SUNWfoo/reloc/usr/bin/myapp
    ## Validating control scripts.
    ## Packaging complete.

    The package now exists in the current directory.

ProcedureHow to Import the Certificates Into the Package Keystore

The certificate and private key to be imported must exist as a PEM- or DER-encoded X.509 certificate and private key. In addition, any intermediate or “chain” certificates linking your signing certificate to the Certificate Authority certificate must be imported into the package keystore before a package can be signed.


Note –

Each Certificate Authority can issue certificates in various formats. To extract the certificates and private key out of the PKCS12 file and into a PEM-encoded X.509 file (suitable for importing into the package keystore), use a freeware conversion utility such as OpenSSL.


If your private key is encrypted (which should usually be the case), you are prompted for the passphrase. Also, you are prompted for a password to protect the resulting package keystore. You can optionally not supply any password, but doing so results in an unencrypted package keystore.

The following procedure describes how to import the certificates using the pkgadm command once the certificate is in the proper format.

  1. Import all the Certificate Authority certificates found in your PEM- or DER-encoded X.509 certificate file.

    For example, to import all the Certificate Authority certificates found in the file ca.pem, you would type the following:


    $ pkgadm addcert -k ~/mykeystore -ty ca.pem
    

    The output would appear similar to the following:


    Trusting certificate <VeriSign Class 1 CA Individual \
    Subscriber-Persona Not Validated>
    Trusting certificate </C=US/O=VeriSign, Inc./OU=Class 1 Public \
    Primary Certification Authority
    Type a Keystore protection Password.
    Press ENTER for no protection password (not recommended): 
    For Verification: Type a Keystore protection Password.
    Press ENTER for no protection password (not recommended): 
    Certificate(s) from <ca.pem> are now trusted

    In order to import your signing key into the package keystore, you must supply an alias that is used later when signing the package. This alias can also be used if you want to delete the key from the package keystore.

    For example, to import your signing key from the file sign.pem, you would type the following:


    $ pkgadm addcert -k ~/mykeystore -n mycert sign.pem
    

    The output would appear similar to the following:


    Enter PEM passphrase:
    Enter Keystore Password: 
    Successfully added Certificate <sign.pem> with alias <mycert>
  2. Verify that the certificates are in the package keystore.

    For example, to view the certificates in the keystore created in the previous step, you would type the following:


    $ pkgadm listcert -k ~/mykeystore
    

ProcedureHow to Sign the Package

Once the certificates are imported into the package keystore, you can now sign the package. The actual signing of the package is done using the pkgtrans command.

  1. Sign the package using the pkgtrans command. Supply the location of the unsigned package and the alias of the key to sign the package.

    For example, using the examples from the previous procedures, you would type the following to create a signed package called SUNWfoo.signed:


    $ pkgtrans -g -k ~/mykeystore -n mycert . ./SUNWfoo.signed SUNWfoo
    

    The output of this command would appear similar to the following:


    Retrieving signing certificates from keystore </home/user/mykeystore>
    Enter keystore password:
    Generating digital signature for signer <Test User>
    Transferring <SUNWfoot> package instance

    The signed package is created in the file SUNWfoo.signed and is in the package-stream format. This signed package is suitable for copying to a web site and being installed using the pkgadd command and a URL.