Thursday, December 2, 2010

Building Solaris Package(pkg) from Scratch

### Building Solaris Packages Quickly ###
ftype Description
d directory
x exclusive directory (package specific)
p named pipe
c character special
b block special
s symbolic link
f executable or data file
e editable file
v volatile file (content may change)
l linked file
i meta-file

To add a package
# pkgadd -d
# pkgadd -d . , for example pkgadd -d . SFWsnort
To remove a package
# pkgrm
To get short description (info) on a package
# pkginfo -x
# pkginfo -l
To list all installed packages
# pkginfo
To list the files that constitute the package
• pkgchk -l
• pkgchk -l | grep Pathname # lists files only.
• pkgchk -d -l
To what package the file /usr/bin/ls belongs:
pkgchk -lp /usr/bin/ls


To package any software you need to know the files that are to be included in the package.
Creating Package Configuration Files
Once the software is installed you need to create a table of contents suitable to be used for the package creation tool.
% cat /tmp/{Custom-Folder} | pkgproto > /tmp/Prototype
This will create a /tmp/Prototype file with the following in it:

After manually reviewing the /tmp/Prototype file you may notice the permissions are not to your liking. Simply edit the file to specify what permissions you want on each inode. I manually alter each file in the package archive to have all files world readable, root owned, root group and all directories read and execute. (drwx-r-xr-x or -rw-r--r--).
So to the front of the Prototype file I add:
i pkginfo
If you want checkinstall, preinstall and postinstall scripts run simply include them at the top.
checkinstall is a script that is run at install time, by the user "nobody". With it you can check for dependancies and problems and if needed, exit the pkgadd gracefully. Care is needed when building the package that the permissions on the directories are set up so the user "nobody" can get to the script.
preinstall is run as root when the package is actually installing. An abort here will require the user to pkgrm the half installed package. You are asked by pkgadd if you want to run this script.
postinstall is a script that runs after the rest of the package is installed. With it you can do things like utilize the just installed software, install kernel drivers, create devices and other post-install things. This script also runs as root. You are asked by pkgadd if you want to run this script.
To add them to the Prototype file put in a line like:
i preinstall
i postinstall
i checkinstall
These scripts are run after installation starts, so if something goes wrong with the install in those scripts and they exit with non-zero then a pkgrm will be required to clean up the half installed package

pkginfo
PKG="GNUbison"
NAME="GNU bison 1.24 SPARC Solaris 2.6"
VERSION="1.24"
ARCH="sparc"
CLASSES="none"
CATEGORY="utility"
VENDOR="GNU"
PSTAMP="12thAugust2004"
EMAIL="request@gnu.ai.mit.edu"
ISTATES="S s 1 2 3"
RSTATES="S s 1 2 3"
BASEDIR="/"


Prototype
i pkginfo
i checkinstall
d none /usr/local/bin 0755 root root
d none /usr/local/man 0755 root root

checkinstall
#!/bin/sh
#
# expected_release="5.6"
expected_platform="sparc"
#
release=`uname -r`
platform=`uname -p`
#
if [ ${platform} != ${expected_platform} ]; then
echo "\n\n\n\tThis package must be installed on a ${expected_platform} architecture\n"
echo "\tAborting installation.\n\n\n"
exit 1
fi
# if [ ${release} != ${expected_release} ]; then
# echo "\n\n\n\tThis package must be installed on a ${expected_release} machine\n"
# echo "\tAborting installation.\n\n\n"
# exit 1
# fi
exit 0

There are also several command that permit creation of your own custom packages or modification of existing packages:
• pkgmk Makes a new package from the specifications contained within a prototype file
• pkgproto Develops a new package specification to be stored within a prototype file
• pkgtrans Translates all of the files in a directory into a single package archive
Making New Packages
You need to create a specification for how an archive is to be built (called a prototype file), by using the pkgproto command, before using the pkgmk command to actually build the package. This material needs to be included in a pkginfo file. Here's a list of the most commonly used parameters that can be specified in the pkginfo file:
ARCH: The architecture (sparc or intel) for which the package is designed
BASEDIR: The target directory into which the files will be unpacked
CATEGORY: The archive type (system or application)
EMAIL: The contact details for the package builder
NAME: The package name
PSTAMP: The name of the package builder
VENDOR: The creator of the software being archived
VERSION: The release level of the software which is to be packaged

Once the pkginfo and prototype files have been created, it's very easy to build a package using pkgmk.
The pkginfo file should define all the necessary parameters (such as ARCH, BASEDIR, and CATEGORY), which were outlined previously. For the Borland Application Server, these elements would look like this:
PKG="BAS_LOCAL"
NAME="Borland App Server"
ARCH="sparc"/”all”
VERSION="4.5"
CATEGORY="application"
VENDOR="Borland"
EMAIL="support@borland.com"
PSTAMP="Paul Watters"
BASEDIR="/usr/local/inprise/bas45"
CLASSES="none"
We can interpret these entries in the following way:

*The package name is BAS_LOCAL (indicating a local installation of the BAS).
*The package title is Borland Application Server.
*The target architecture is SPARC.
*The version number is 4.5.
*The category of BAS is an application.
*The vendor of BAS is Borland.
*The e-mail address of the vendor is support@borland.com.
*The name of the package builder is the author of this book.
*The base installation directory is /usr/local/inprise/bas45.
Package Dependencies:
If you want your package to depend on another package, you need to create a 'depend' file and add to prototype file
i depend=”path”

Once the pkginfo file is created, we should use the following command to create the prototype file:
#touch prototype
Next, we need to specify the location of the pkginfo file, by inserting the following line into the prototype file:
i pkginfo=/usr/local/borland/bas45/pkginfo
In the base installation directory specified in the pkginfo file, you can use the following command to generate a list of relative pathnames and files that is then piped through the pkgproto command. The output is then appended to the prototype file:
# find . -print | pkgproto >> prototype
We should then be able to examine the contents of the newly constructed prototype file:
bash-2.03# head /usr/local/borland/bas45/prototype
i pkginfo=/usr/local/borland/bas45/pkginfo
f none install.idb 0644 bas borland
d none bin 0775 bas borland
f none bin/JdsExplorer 0775 bas borland
f none bin/JdsExplorer.config 0775 bas borland
f none bin/JdsServer 0775 bas borland
f none bin/JdsServer.config 0775 bas borland
f none bin/jdbce 0775 bas borland
f none bin/jdbce.config 0775 bas borland
f none bin/jsql 0775 bas borland
f none bin/jsql.config 0775 bas borland
Every file (f) and directory (d) underneath the root directory is represented by a unique entry in the prototype file.
After the prototype file has been modified to your satisfaction, create the package with the following command:
# pkgmk -o -r /usr/local/borland/bas45
The files to be packaged have been transferred to the /var/spool/pkg/BAS_LOCAL directory at this point. Next, you simply need to use the pkgtrans command to bundle the files into a single archive file:
# pkgtrans -s /var/spool/pkg /backup/BAS_LOCAL.pkg

Each Solaris package is represented as a directory that has the same name as the package. The package contains many files and directories out of which only pkginfo and pkgmap are mandatory. All other items shown in the figure are optional.
The pkginfo and pkgmap files are meta-information files. The pkginfo file acts like a label on a box. It contains information such as name, identifier, build date, who to contact if there's a problem, and so on.
The pkgmap file is a packing list, where each item in the package is defined and its size and checksum are stored. The size and checksum help in determining that the package has not been tampered with. The various items in the pkgmap are recognized by their ftype entry as shown here.

When a package is installed (using pkgadd), first directories (d), devices (c/b), and symlinks (s) are created. Then the files of type f, e, or v are copied into the file system. Hard links (ftype l) are created after all the other files have been installed. The install meta-files (ftype i) are used to direct the installation and removal of software and are not installed on the system.
A Solaris package typically contains reloc and install directories. The reloc directory contains all the files that are to be installed relative to a base directory, i.e. it contains the relocatable files. An optional root directory contains files that are to be installed relative to the root directory. Another optional directory called archive may also be present, which contains general-purpose files whose functions are defined by the package developer. The install directory contains scripts and other auxiliary files. All files of ftype i except pkginfo and pkgmap go into install.
The install directory contains a copyright file, an optional depend file, and scripts like checkinstall, preinstall, postinstall, preremove, and postremove. This directory may also contain a set of some special scripts known as Class Action Scripts. All the meta-info files are Bourne shell scripts.
The checkinstall script performs a detailed analysis of the system and gathers data; it doesn't change anything on a file system. The script may create or alter environment variables to control the installation. The script can cleanly halt the package installation, if necessary.
preinstall runs just before the actual file installation begins. This script is involved in things such as initializing the prototype and meta-files for the backout package, which will be constructed later by the postinstall script.
If a package is removed (using pkgrm), the preremove and postremove scripts, if present, run before and after the removal of the package to do some tasks like deleting the contents of some directories.
All the objects in a package fall under some class that is defined during package creation. If an object doesn't fall under any class, none class is used by default. All the classes to be installed are listed in the parameter CLASSES, which is defined in the pkginfo file. The installation occurs in the order they are listed in pkginfo. Objects with class none are always installed first. So none, if present in pkginfo, is always the first class entry. If a class isn't listed in the pkginfo, the objects in that class won't get installed even if they are defined in pkgmap.
Class Action Scripts (CAS) redefine how to add or remove an object from the package. That is, instead of a simple copy of files from the package to the appropriate file system, CAS may allow merging entries with an existing file, or saving a copy of an existing file. The Class Action Scripts work similarly during removal of a package. The install and removal Class Action Scripts are named i. and r., respectively, for . Files with ftype e and v are expected to have Class Action Scripts.
All the dependencies that a package might have on other packages are listed in the depend file.
As mentioned previously, pkginfo and pkgmap are the only required files in a package. One can create a package with just these two files. Such a package is perfectly acceptable, though it doesn't provide any important functionality per se.
Solaris packages can also be delivered in Package Datastream format. In this format there is a file containing one or more packages. This file is different from the directory format explained previously, which had one directory containing a package. Package datastreams are easier to distribute. We can convert from one format to another using pkgtrans.

No comments: