Administrative Notes - Scripts for Creating
and Testing Packages
The scripts I've written to speed up the packaging/testing of software packages
are run as follows:
"makepkg usr foo 3.1.4"
"testpkg usr foo 3.1.4"
"restpkg usr foo 3.1.4"
"dupepkg foo 3.1.4"
"donepkg usr foo 3.1.4"
Each of the five scripts are detailed below. I don't claim that they are the
finest examples of script-writing I've ever done, but they work for me.
I hope you find them useful (at least as a catalyst for thought) in your
work. I apologize for not taking the time to format the HTML code to properly
indent the code for readability - you may find it easier to decipher if you
view the HTML page source itself...it is indented for readability.
Jay Thompson
University of Tennessee - Telecommunications and Network Services
March 1998
Creating the "PKG.tar.gz" File (makepkg)
Prior to running this script, the program to be packaged must be completely installed
on the local system under either /usr/local/ or /opt/.
Since we are producing packages for both root locations, we start by installing
and packaging for /usr/local/. This allows us to later use the
dupepkg script to set the package up for /opt/.
Assuming that you are packaging up version 3.1.4 of foo
which has been installed to /usr/local/, you invoke the script with the
command:
"makepkg usr foo 3.1.4"
Which will create the package, foo-3.1.4-USRPKG.tar.gz, and place it
in our permanent storage area,
/opt/x86pkgs/archive/final-packages/usrpkgs.
Below is the script code itself:
#!/bin/csh
# Script for making packages written by Jay Thompson - March 1998
#
# USAGE: makepkg ROOTDIR PARENTDIR VERSION
#
# WHERE: ROOTDIR = "opt" or "usr"
# PARENTDIR = top level directory for program directory tree (also name of package)
# VERSION = package version number
#
# EG: makepkg usr foo 1.3.4
#
# will expect to find /usr/local/foo-1.3.4 acting as the program
# root for version 1.3.4 of the program "foo".
#
# Script will create "pkginfo" file and "prototype" file for
# a package whose name will be "foo". It will then create the
# package and tar it up, storing it in either:
#
# /opt/x86pkgs/archive/final-packages/optpkgs
# /opt/x86pkgs/archive/final-packages/usrpkgs
#
# (depending on "rootdir" parameter)
echo " "
if ( !($1 == "") ) then
if ( $1 == "opt" ) then
set ROOTDIR = "/opt"
set TAG = "OPT"
else
if ( $1 == "usr" ) then
set ROOTDIR = "/usr/local"
set TAG = "USR"
else
goto badparam1
endif
endif
else
goto badparam1
endif
if ( !($2 == "") ) then
set PKG = $2
if ( !($3 == "") ) then
set VER = $3
set DESC = $PKG"-"$VER
set BASEDIR = $ROOTDIR"/"$DESC
if ( -e $BASEDIR ) then
goto execute
else
goto baddir
endif
else
goto badparam3
endif
else
goto badparam2
endif
goto execute
badparam1:
echo " "
echo "ERROR: Invalid ROOTDIR"
goto printuse
badparam2:
echo " "
echo "ERROR: Missing PARENTDIR"
goto printuse
badparam3:
echo " "
echo "ERROR: Missing VERSION"
goto printuse
baddir:
echo " "
echo "ERROR: Program directory "'$BASEDIR'" does not exist"
goto printuse
printuse:
echo " "
echo "USAGE: makepkg ROOTDIR PARENTDIR VERSION"
echo " "
echo " ROOTDIR = 'opt' or 'usr'"
echo " PARENTDIR = Top level directory of program tree"
echo " VERSION = Version number of package"
echo " "
echo "EG: makepkg usr foo 1.2.4"
echo " "
echo " Will build package 'foo' from '/usr/local/foo-1.2.4'"
exit 1
# EVERYTHING CHECKS - GO AHEAD AND BUILD PACKAGE
# ----------------------------------------------
execute:
echo " "
echo "Building package '$PKG' from '$BASEDIR'"
cd $BASEDIR
if ( -e "prototype" ) then
rm prototype
endif
if ( -e "pkginfo" ) then
rm pkginfo
endif
if ( -e "prototemp" ) then
rm prototemp
endif
find . -print | pkgproto > prototemp
echo "i pkginfo=$BASEDIR/pkginfo" > prototype
cat prototemp >> prototype
rm prototemp
echo PKG='"'$PKG'"' > pkginfo
echo NAME='"'$PKG'"' >> pkginfo
echo ARCH='"Solaris 2.6"' >> pkginfo
echo VERSION='"'$VER'"' >> pkginfo
echo CATEGORY='"application"' >> pkginfo
echo DESC='"'$DESC'"' >> pkginfo
echo CLASSES='"none"' >> pkginfo
echo BASEDIR='"'$BASEDIR'"' >> pkginfo
echo MAXINST=1000 >> pkginfo
set PKGDIR = /var/spool/pkg/$PKG
if ( -e $PKGDIR ) then
rm -R $PKGDIR
endif
pkgmk -r $BASEDIR $PKG
set STOREDIR = /opt/x86pkgs/archive/final-packages/$1pkgs/
set TARFILE = $DESC-$TAG"PKG.tar"
set GZFILE = $TARFILE.gz
set STOREFILE = $STOREDIR$GZFILE
cd /var/spool/pkg
tar -cf $TARFILE $PKG
gzip -9 $TARFILE
if ( -e $STOREFILE ) then
echo " "
echo "Cannot store file '$STOREFILE'"
echo "File already exists"
echo " "
else
echo " "
echo "Storing file '$STOREFILE'"
echo " "
cp $GZFILE $STOREFILE
endif
echo " "
echo "Package '$PKG' from '$BASEDIR' successfully built"
echo " "
echo " "
Testing the "PKG.tar.gz" File (testpkg)
Prior to running this script, the program to be tested must be packaged (using the
makepkg script) and the final PKG.tar.gz file must
be stored into it's appropriate storage area (which makepkg does
automagically for you). Then to test the packaging, invoke the script with the
command:
"testpkg usr foo 3.1.4"
Which will take the file, foo-3.1.4-USRPKG.tar.gz, from our
permanent storage area, /opt/x86pkgs/archive/final-packages/usrpkgs,
and install it to /usr/local/foo-3.1.4/.
Below is the script code itself:
#!/bin/csh
# Script for testing packages written by Jay Thompson - March 1998
#
# USAGE: testpkg ROOTDIR PARENTDIR VERSION
#
# ROOTDIR = "opt" or "usr"
# PARENTDIR = Top level directory of program tree
# VERSION = Version number of package
#
# testpkg usr foo 1.2.4
#
# Will install package "foo"
# from file "/opt/x86pkgs/archive/final-packages/usrpkgs/foo-1.2.4-USRPKGS.tar.gz"
# to directory "/usr/local/foo-1.2.4"
echo " "
if ( !($1 == "") ) then
if ( $1 == "opt" ) then
set ROOTDIR = "/opt"
set TAG = "OPT"
else
if ( $1 == "usr" ) then
set ROOTDIR = "/usr/local"
set TAG = "USR"
else
goto badparam1
endif
endif
else
goto badparam1
endif
if ( !($2 == "") ) then
set PKG = $2
if ( !($3 == "") ) then
set VER = $3
set DESC = $PKG"-"$VER
set BASEDIR = $ROOTDIR"/"$DESC
goto execute
endif
else
goto badparam3
endif
else
goto badparam2
endif
goto execute
badparam1:
echo " "
echo "ERROR: Invalid ROOTDIR"
goto printuse
badparam2:
echo " "
echo "ERROR: Missing PARENTDIR"
goto printuse
badparam3:
echo " "
echo "ERROR: Missing VERSION"
goto printuse
printuse:
echo " "
echo "USAGE: testpkg ROOTDIR PARENTDIR VERSION"
echo " "
echo " ROOTDIR = 'opt' or 'usr'"
echo " PARENTDIR = Top level directory of program tree"
echo " VERSION = Version number of package"
echo " "
echo "EG: testpkg usr foo 1.2.4"
echo " "
echo " Will install package 'foo' from file"
echo " "'/opt/x86pkgs/archive/final-packages/usrpkgs/foo-1.2.4-USRPKGS.tar.gz'"
echo " to directory '/usr/local/foo-1.2.4'"
echo " "
echo " "
exit 1
# EVERYTHING CHECKS - GO AHEAD AND INSTALL PACKAGE
# ------------------------------------------------
execute:
set STOREDIR = /opt/x86pkgs/archive/final-packages/$1pkgs/
set TARFILE = $DESC-$TAG"PKG.tar"
set GZFILE = $TARFILE.gz
set STOREFILE = $STOREDIR$GZFILE
if ( !( -e $STOREFILE ) ) then
echo " "
echo "ERROR: Cannot continue with package install"
echo " File '$STOREFILE' does not exist"
echo " "
echo " "
exit 1
endif
echo " "
echo "Installing package '$PKG' to '$BASEDIR'"
cd $ROOTDIR
if ( -e $PKG-hold.tar) then
rm $PKG-hold.tar
endif
if ( -e $BASEDIR ) then
tar -cf $PKG-hold.tar $DESC
rm -R $DESC
endif
cd /pkgtmp
if ( -e $PKG ) then
rm -R $PKG
endif
if ( -e $GZFILE ) then
rm $GZFILE
endif
if ( -e $TARFILE ) then
rm $TARFILE
endif
cp $STOREFILE .
gunzip $GZFILE
tar -xof $TARFILE
pkgadd -d /pkgtmp $PKG
rm $TARFILE
echo " "
echo "Package '$PKG' installed to '$BASEDIR'"
echo "If no errors were reported, then the installation was successful"
echo " "
echo " "
What if it Didn't Work? (restpkg)
If the packaging/testing process did not work for some reason (which may require that
you "massage" the files manually), you can restore the installed software in it's form
prior to packaging with the restpkg script. Then, depending on what you
have to do to get it working, you may be able to simply start again with the
makepkg script, or you may have to carry out the packaging/testing
process manually.
That is, if the packaging process failed because of something inherent in the installed
software itself (which you are able to correct), then you can start again with the
makepkg script after you have corrected the problem.
However, if resolving the problem requires some kind of "tweak" to the
pkginfo or prototype files, then you will have
to carry out the packaging process manually (since the makepkg
script automatically creates these files and does not allow massaging prior to
the packaging operation).
You invoke the restore script with the command:
"restpkg usr foo 3.1.4"
Which will untar a "hold" file, created by the makepkg script
called /usr/local/foo-hold.tar. Once untarred, the software will
be returned to its pre-packaged state except that it will have both the
pkginfo and prototype files in place for your
review.
Below is the script code itself:
#!/bin/csh
# Script for restoring software after a packaging process has been initiated with
# the "makepkg" script. - Written by Jay Thompson - March 1998
#
# USAGE: restpkg ROOTDIR PARENTDIR VERSION
#
# WHERE: ROOTDIR = "opt" or "usr"
# PARENTDIR = top level directory for program directory tree
# (also name of package)
# VERSION = package version number
#
# EG: restpkg usr foo 1.3.4
#
# will expect to find the file, "/usr/local/foo-hold.tar", will untar to
# a directory tree rooted at "/usr/local/foo-1.3.4".
echo " "
if ( !($1 == "") ) then
if ( $1 == "opt" ) then
set ROOTDIR = "/opt"
set TAG = "OPT"
else
if ( $1 == "usr" ) then
set ROOTDIR = "/usr/local"
set TAG = "USR"
else
goto badparam1
endif
endif
else
goto badparam1
endif
if ( !($2 == "") ) then
set PKG = $2
if ( !($3 == "") ) then
set VER = $3
set DESC = $PKG"-"$VER
set BASEDIR = $ROOTDIR"/"$DESC
goto execute
endif
else
goto badparam3
endif
else
goto badparam2
endif
goto execute
badparam1:
echo " "
echo "ERROR: Invalid ROOTDIR"
goto printuse
badparam2:
echo " "
echo "ERROR: Missing PARENTDIR"
goto printuse
badparam3:
echo " "
echo "ERROR: Missing VERSION"
goto printuse
printuse:
echo " "
echo "USAGE: restpkg ROOTDIR PARENTDIR VERSION"
echo " "
echo " ROOTDIR = 'opt' or 'usr'"
echo " PARENTDIR = Top level directory of program tree"
echo " VERSION = Version number of package"
echo " "
echo "EG: restpkg usr foo 1.2.4"
echo " "
echo " Will use file 'usr/local/foo-hold.tar' and untar to a"
echo " directory tree rooted at 'usr/local/foo-1.2.4'"
echo " "
echo " "
exit 1
# EVERYTHING CHECKS - GO AHEAD AND RESTORE PACKAGE
# ------------------------------------------------
execute:
set TARFILE = $PKG-hold.tar
cd $ROOTDIR
if ( !( -e $TARFILE) ) then
echo "ERROR: Cannot restore '$PKG' - file '$ROOTDIR/$TARFILE' not found"
echo " "
echo " "
exit 1
endif
if ( -e $DESC ) then
rm -R $DESC
endif
tar -xof $TARFILE
rm $TARFILE
echo "'$PKG' successfully restored"
echo " "
echo " "
Duplicating the Work for /opt/ (dupepkg)
Once the package has been successfully created and tested for installation to
/usr/local/, it must then be created and tested for installation to
/opt/. Assuming that you have just finished the testing for
installation to /usr/local/, then you have a working version of
the software installed to /usr/local/.
You can now invoke the dupepkg script with the command:
"dupepkg foo 3.1.4"
Which will duplicate the software installation copying from /usr/local
over to /opt/ after which, you can repeat the package creation/testing
process for /opt/.
Below is the script code itself:
#!/bin/csh
# Duplicate the /usr/local/ installation to /opt/
# Written by Jay Thompson - March 1998
#
# USAGE: dupepkg PARENTDIR VERSION
#
# PARENTDIR = Top level directory of program tree
# VERSION = Version number of package
#
# dupepkg foo 1.2.4
#
# Will duplicate directory tree usr/local/foo-1.2.4 to /opt/foo-1.2.4
echo " "
if ( !($1 == "") ) then
set PKG = $1
if ( !($2 == "") ) then
set VER = $2
set DESC = $PKG"-"$VER
else
goto badparam2
endif
else
goto badparam1
endif
goto execute
badparam1:
echo " "
echo "ERROR: Missing PARENTDIR"
goto printuse
badparam2:
echo " "
echo "ERROR: Missing VERSION"
goto printuse
printuse:
echo " "
echo "USAGE: dupepkg PARENTDIR VERSION"
echo " "
echo " PARENTDIR = Top level directory of program tree"
echo " VERSION = Version number of package"
echo " "
echo "EG: donepkg foo 1.2.4"
echo " "
echo " Will duplicate directory tree 'usr/local/foo-1.2.4' to '/opt/foo-1.2.4'"
echo " "
echo " "
exit 1
# EVERYTHING CHECKS - GO AHEAD AND DUPLICATE
# -------------------------------------------------
execute:
set SRCDIR = "/usr/local"
set DSTDIR = "/opt"
set TARFILE = $DESC"-temp.tar"
set GZFILE = $TARFILE".gz"
cd $SRCDIR
if ( !( -e $DESC ) ) then
echo "ERROR: Cannot duplicate '$PKG' - '$DESC' does not exist in /usr/local/"
echo " "
echo " "
exit 1
else
echo "Duplicating '$PKG' from /usr/local/ to /opt/"
endif
if ( -e $TARFILE ) then
rm $TARFILE
endif
if ( -e $GZFILE ) then
rm $GZFILE
endif
tar -cf $TARFILE $DESC
cd $DSTDIR
if ( -e $DESC) then
rm -R $DESC
endif
if ( -e $TARFILE ) then
rm $TARFILE
endif
if ( -e $GZFILE ) then
rm $GZFILE
endif
mv $SRCDIR"/"$TARFILE .
tar -xof $TARFILE
rm $TARFILE
echo " "
echo "Package '$PKG' successfully duplicated from /usr/local/ to /opt/"
echo " "
echo " "
Final Cleanup (donepgk)
Once completed, you will have two versions of the package installed, one to
/usr/local/ and one to /opt/. Additionally
the "hold" files that allow you to run restpkg will still be
out there. This script will clean out the hold files and one version of the
installed package.
You invoke the script with the command:
"donepkg usr foo 3.1.4"
Which will delete the /usr/local/foo-hold.tar and
/opt/foo-hold.tar files. Additionally, since you specified
"usr", it will KEEP the package
installed to /usr/local as the final installed version
(removing the one installed to /opt/). Finally, it will search
all pre-determined work areas and clean out whatever "residual" files
may be left that are no longer needed now that the packaging of
foo-3.1.4 is complete.
Below is the script code itself:
#!/bin/csh
# Final cleanup script after packages have been successfully created/tested
# Written by Jay Thompson - March 1998
#
# USAGE: donepkg ROOTDIR PARENTDIR VERSION
#
# ROOTDIR = "opt" or "usr"
# PARENTDIR = Top level directory of program tree
# VERSION = Version number of package
#
# donepkg usr foo 1.2.4
#
# Will delete un-needed files left over from creating package "foo".
# Will leave the version installed to /usr/local/ if "usr" is specified as ROOTDIR
# Will leave the version installed to /opt/ if "opt" is specified as ROOTDIR
echo " "
if ( !($1 == "") ) then
if ( $1 == "opt" ) then
set ROOTDIR = "/opt"
set ALTDIR = "/usr/local"
set TAG = "OPT"
else
if ( $1 == "usr" ) then
set ROOTDIR = "/usr/local"
set ALTDIR = "/opt"
set TAG = "USR"
else
goto badparam1
endif
endif
else
goto badparam1
endif
if ( !($2 == "") ) then
set PKG = $2
if ( !($3 == "") ) then
set VER = $3
set DESC = $PKG"-"$VER
set BASEDIR = $ROOTDIR"/"$DESC
else
goto badparam3
endif
else
goto badparam2
endif
goto execute
badparam1:
echo " "
echo "ERROR: Invalid ROOTDIR"
goto printuse
badparam2:
echo " "
echo "ERROR: Missing PARENTDIR"
goto printuse
badparam3:
echo " "
echo "ERROR: Missing VERSION"
goto printuse
printuse:
echo " "
echo "USAGE: donepkg ROOTDIR PARENTDIR VERSION"
echo " "
echo " ROOTDIR = 'opt' or 'usr'"
echo " PARENTDIR = Top level directory of program tree"
echo " VERSION = Version number of package"
echo " "
echo "EG: donepkg usr foo 1.2.4"
echo " "
echo " Will delete un-needed files left over from creating package 'foo'"
echo " Will leave the version installed to /usr/local/ if 'usr' is specified as ROOTDIR"
echo " Will leave the version installed to /opt/ if 'opt' is specified as ROOTDIR"
echo " "
echo " "
exit 1
# EVERYTHING CHECKS - GO AHEAD AND COMPLETE CLEANUP
# -------------------------------------------------
execute:
set TARFILE = $DESC"-USRPKG.tar"
set GZFILE = $TARFILE.gz
set STOREDIR = /opt/x86pkgs/archive/final-packages/usrpkgs/
set STOREFILE = $STOREDIR$GZFILE
if ( !( -e $STOREFILE ) ) then
echo "ERROR: Cannot continue with final cleanup - Cannot find storage file:"
echo " '$STOREFILE'"
echo " "
echo " "
exit 1
endif
set TARFILE = $DESC"-OPTPKG.tar"
set GZFILE = $TARFILE.gz
set STOREDIR = /opt/x86pkgs/archive/final-packages/optpkgs/
set STOREFILE = $STOREDIR$GZFILE
if ( !( -e $STOREFILE ) ) then
echo "ERROR: Cannot continue with final cleanup - Cannot find storage file:"
echo " '$STOREFILE'"
echo " "
echo " "
exit 1
endif
echo " "
echo "Cleaning up files after completion of packaging '$PKG'"
cd $ROOTDIR
if ( !( -e $DESC) ) then
echo "ERROR: Cannot continue with cleanup - '$DESC' does not exist in '$ROOTDIR'"
echo " "
echo " "
exit 1
endif
if ( -e $PKG-hold.tar) then
rm $PKG-hold.tar
endif
cd $ALTDIR
if ( -e $PKG-hold.tar) then
rm $PKG-hold.tar
endif
if ( -e $DESC ) then
rm -R $DESC
endif
cd /var/spool/pkg
if ( -e $PKG ) then
rm -R $PKG
endif
if ( -e $GZFILE ) then
rm $GZFILE
endif
if ( -e $TARFILE ) then
rm $TARFILE
endif
cd /pkgtmp
if ( -e $PKG ) then
rm -R $PKG
endif
if ( -e $GZFILE ) then
rm $GZFILE
endif
if ( -e $TARFILE ) then
rm $TARFILE
endif
echo " "
echo "Finished with '$PKG' cleanup"
echo "Final working version is in '$BASEDIR'"
echo " "
echo " "
Please send comments to
x86admin@sunsite.utk.edu