SUN Packaging Guide -
Creating A Package

Creating a package

Whoa! The last two chapters were hard stuff to read, so I think we continue with our example of the binary calculator. First I want to explain to you, which commands we will need:

/bin/pkgproto This command creates a basic prototype file with all entries we need. This generic prototype file has to be edited later to include further pkg information files.
/bin/pkgmk This command creates the package.
/bin/pkgtrans This command is used to transfer packages from the directory format to a package file.
/bin/pkgckeck This command is used to check the integrity of a package

If you remember, our pkginfo file looks like this:

PKG=ARbc
NAME="bc - a binary calculator"
ARCH=sparc
VERSION=1.0.6
CATEGORY=utility
DESC="bc - a binary commandline calculator often used in shellscripts for
calculating"
VENDOR="(C) 2002 Garex Inc."
VSTOCK="123456"
HOTLINE="+49-123456-TOLL-FREE"
EMAIL="garex@garex.net"
BASEDIR=/
MAXINST=1
INTONLY=1
CLASSES=application none
ISTATES="S 2 3"
RSTATES="S 2 3"
PSTAMP="20020718 19:35"
ULIMIT=20
ORDER=none application

And our generic prototype file looks like this, as we created it by the pkgproto command:

d none usr ? ? ?
d none usr/local ? ? ?
d none usr/local/bin ? ? ?
d none usr/local/info ? ? ?
d none usr/local/man ? ? ?
d none usr/local/man/man1 ? ? ?
f none usr/local/bin/bc 0755 bin bin
f none usr/local/bin/dc 0755 bin bin
f none usr/local/info/bc.info 0644 bin bin
f none usr/local/info/dc.info 0644 bin bin
f none usr/local/man/man1/bc.1 0644 bin bin
f none usr/local/man/man1/dc.1 0644 bin bin

Completing the prototype file

There are several lines are missing for our package. The include of the pkginfo file, usually located in the same directory as the prototype file, the line for our simple, but useless bc bootscript and its symbolic link. Therefore we have to add the following lines to the prototype file:

i pkginfo=pkginfo
...
f none etc/init.d/bc_startup=bc_startup 0755 root other
s none etc/rc3.d/S99bc_startup=../init.d/bc_startup

So our final prototype looks like this:

i pkginfo
d none etc ? ? ?
d none etc/init.d ? ? ?
d none etc/rc3.d ? ? ?
d none usr ? ? ?
d none usr/local ? ? ?
d none usr/local/bin ? ? ?
d none usr/local/info ? ? ?
d none usr/local/man ? ? ?
d none usr/local/man/man1 ? ? ?
f none usr/local/bin/bc 0755 bin bin
f none usr/local/bin/dc 0755 bin bin
f none usr/local/info/bc.info 0644 bin bin
f none usr/local/info/dc.info 0644 bin bin
f none usr/local/man/man1/bc.1 0644 bin bin
f none usr/local/man/man1/dc.1 0644 bin bin
f none etc/init.d/bc_startup=bc_startup 0755 root other
s none etc/rc3.d/S99bc_startup=../init.d/bc_startup

REMEMBER: When adding files to the package, every directory leading to the destination has to be included as well! That's the reason why etc, etc/init.d and etc/rc3.d has to be listed here as well!
There may be several reasons to omit a directory, e.g. let /opt be a symbolic lic to /var/opt due to less diskspace. Adding /opt as of type d then results in replacing the symbolic link /opt with a real directory called /opt, which will be created in "/" and your package may be not installed, if "/" has not enough disk space!

The pkgmk command

Assuming you did the final "make install", we can now go to the final package creation using "pkgmk". Before we invoke "pkgmk", you have to know about the three main options we will need:

-o Overwrites an existing package instance in the PKG spool directory /var/spool/pkg. Useful if you are testing PKG creation techniques for the first time.
-r <root-path> By using this option, you override the default destination paths defined in the prototype file
-b <base_src_dir> Prepend the indicated base_src_dir to locate relocatable objects on the source machine.
Instead of including all files in the prototype file as <dst>=<src>, you can tell pkgmk where to search for the files.

Now let's invoke the pkgmk command:

$ pkgmk -o -b / -r /
## Building pkgmap from package prototype file.
## Processing pkginfo file.
## Attempting to volumize 17 entries in pkgmap.
part  1 -- 853 blocks, 19 entries
## Packaging one part.
/var/spool/pkg/ARbc/pkgmap
/var/spool/pkg/ARbc/pkginfo
/var/spool/pkg/ARbc/reloc/etc/init.d/bc_startup
/var/spool/pkg/ARbc/reloc/usr/local/bin/bc
/var/spool/pkg/ARbc/reloc/usr/local/bin/dc
/var/spool/pkg/ARbc/reloc/usr/local/info/bc.info
/var/spool/pkg/ARbc/reloc/usr/local/info/dc.info
/var/spool/pkg/ARbc/reloc/usr/local/man/man1/bc.1
/var/spool/pkg/ARbc/reloc/usr/local/man/man1/dc.1
## Validating control scripts.
## Packaging complete.

The pkgchk command

Now we created our ARbc package. Finally, we have to verify its integrity with

$ cd /var/spool/pkg
$ pkgchk -vd . ARbc
Checking uninstalled directory format package <ARbc> from </var/spool/pkg>
## Checking control scripts.
## Checking package objects.
etc/init.d/bc_startup
pkginfo
usr/local/bin/bc
usr/local/bin/dc
usr/local/info/bc.info
usr/local/info/dc.info
usr/local/man/man1/bc.1
usr/local/man/man1/dc.1
## Checking is complete.

If no errors were found, your package is fine.

The pkgtrans command

Finally as a gimmick we transfer the package directory to a package file, which is easier to transfer to remote hosts:

$ pkgtrans /var/spool/pkg /tmp/ARbc-1.0-sol8-test ARbc
Transferring  package instance
$ ls -l /tmp/ARbc-1.0-sol8-test
-rw-r--r--   1 garex     staff     402432 Jul 22 19:26 /tmp/ARbc-1.0-sol8-test

Transferring the file back to the package directory is also quite simple:

$ pkgtrans /tmp/ARbc-1.0-sol8-test /tmp ARbc
Transferring  package instance
$ ls -ld /tmp/ARbc
drwxr-xr-x   3 garex     staff        306 Jul 22 19:29 /tmp/ARbc

Doing a testinstallation

Now try installing the packge first from the directory, then from the file:

$ cd /tmp
$ pkgadd -d . ARbc
...
$ pkgrm ARbc
...
$ pkgadd -d ARbc-1.0-sol8-test
...
$ pkgrm ARbc
...

If this works, you are really through it. CONGRATULATIONS!