Auto Installation of Solaris Packages

What I often have to do is install a whole bunch of packages onto a new machine, (or domain on an Enterprise system), and if I had to do it manually, even with the benefit of a script to unpack each package tgz file, it'd take a lot of time. (Not as much time as compiling and installing all the files on each machine, but when you have to install all the files on a lab of 20 new machines, half an hour each makes for a long tedious day This way you can rcp out the scripts and the files, fire off the install scripts in parallel and then go chat to the cute new girl/guy).

What one can do is have a simple shell script which installs all of the packages you want, plus a special file which tells pkgadd to not ask you any questions and to just install the packages as is.

Here is a shell script to install a group of packages automatically:

#!/bin/sh -x
umask 000
/usr/bin/tar -xvvf GNUzip.1.2.4.SPARC.Solaris.2.6.pkg.tar
/usr/sbin/pkgadd -d. -a noask GNUzip
rm -rf GNUzip
/usr/local/bin/gunzip -c GNUbison.1.25.SPARC.Solaris.2.6.pkg.tgz | /usr/bin/tar -xvvf -
/usr/sbin/pkgadd -d. -a noask GNUbison
rm -rf GNUbison
/usr/local/bin/gunzip -c GNUcvs.1.9.SPARC.Solaris.2.6.pkg.tgz | /usr/bin/tar -xvvf -
/usr/sbin/pkgadd -d. -a noask GNUcvs
rm -rf GNUcvs
/usr/local/bin/gunzip -c GNUflex.2.5.4a.SPARC.Solaris.2.6.pkg.tgz | /usr/bin/tar -xvvf -
/usr/sbin/pkgadd -d. -a noask GNUflex
rm -rf GNUflex
/usr/local/bin/gunzip -c GNUgcc.2.8.1.SPARC.Solaris.2.6.pkg.tgz | /usr/bin/tar -xvvf -
/usr/sbin/pkgadd -d. -a noask GNUgcc
rm -rf GNUgcc
/usr/local/bin/gunzip -c GNUgdb.4.16.SPARC.Solaris.2.6.pkg.tgz | /usr/bin/tar -xvvf -
/usr/sbin/pkgadd -d. -a noask GNUgdb
rm -rf GNUgdb

You can see the pkgadd line has a -a noask option. This tells pkgadd to refer to the noask file when it reaches a point in the package installation where it needs to ask a question. The noask file essentially tells pkgadd to skip any checks and just go ahead. Since I've made all the packages I am installing, I know how the system will look after the bulk installation, and that suits me just fine.

The noask file contains:

mail=
instance=overwrite
partial=nocheck
runlevel=nocheck
idepend=nocheck
rdepend=nocheck
space=nocheck
setuid=nocheck
conflict=nocheck
action=nocheck
basedir=default

Below is a perl script to build another script which will do the bulk install for you. It relies on some conventions in the package name that don't always apply. For instance it will use the first word in the large package file to attempt to pkgadd the packge. E.g. when GNUbison.1.28.SPARC.Solaris.2.6.pkg.tgz is added to the system the package name to add is GNUbison. This is true for 95% of the packages. However some packages have names that won't fit into the nine character limit on package names so they have been 'crunched' up, or it made sense to call the package something else. E.g GNUghostscript installs as GNUghoscr and fvwm installs as fvwm2.

How does this affect the script below? Not too much since it automatically checks to see if the guessed at package installed. If it didn't, then it doesn't delete the files afterwards. If you don't actually want to have your big package files deleted after installation then remember to modify the script first.

Note: You need to manually add GNUzip and perl onto your system first.

Here is is:

#!/usr/local/bin/perl
#
# Program : mkbulkinstaller
# Author  : Mark <mark@ibiblio.org>
# Purpose : Generate package bulk installation script
#
open(NOASK, ">noask");
print NOASK "mail=\n";
print NOASK "instance=overwrite\npartial=nocheck\nrunlevel=nocheck\n";
print NOASK "idepend=nocheck\nrdepend=nocheck\nspace=nocheck\n";
print NOASK "setuid=nocheck\nconflict=nocheck\naction=nocheck\n";
print NOASK "basedir=default\n";
close(NOASK);

opendir(DIR, ".");
@files = readdir(DIR);
closedir(DIR);

open(OUTPUT, ">bulkinstall");
print OUTPUT "#!/bin/sh -x\n";
print OUTPUT "umask 000\n";

# The pkgname is usually right 95% of the time. If the name is different then
# you will have to manually add the package.

foreach $file (@files) {
   next if ($file !~ /\.pkg\.tgz$/);
   print OUTPUT "/usr/local/bin/gunzip -c $file | /usr/bin/tar -xvvf -\n";
   $pkgname = $file;
   $pkgname =~ s/\..*//;
   print OUTPUT "/usr/sbin/pkgadd -d. -a noask $pkgname\n";
   print OUTPUT "if [ \$? -eq 0 ]; then\n";
   print OUTPUT "    /bin/rm -rf $file\n";
   print OUTPUT "fi\n";
   print OUTPUT "/bin/rm -rf $pkgname\n";
}
close(OUTPUT);
chmod(0755, "bulkinstall");
chmod(0644, "noask");