for JumpStart Begin/Finish Scripts
If you've ever managed a large Solaris environment, you are
probably familiar with JumpStart. JumpStart is a system for automating
the installation of new Solaris systems, over a network. With JumpStart,
an administrator can install an OS on multiple systems at once,
with little or no user intervention.
This article covers one aspect of the JumpStart process --
the begin and finish scripts. It is presumed that the reader already
has some knowledge of the JumpStart system. To learn more about
JumpStart, I recommend reading "Automating Solaris Installations:
A Custom JumpStart Guide" by Kasper/McCellen, or the "Solaris
Advanced Installation Guide" that comes with your Solaris distribution.
Unlike other installation systems, JumpStart gives an administrator
two points where she can customize the installation process --
the begin script, and the finish script. The scripts give you full
access to the hardware and software, so it's possible to automate
tasks that are normally performed manually after the installation.
Here is what happens during a JumpStart installation process:
1. When the new host is booted from the network, its configuration
is examined to see which rules best identify the host. The rules
specify how an installation proceeds based on the architecture of
the host, the network the host is on, the size of the disks on the
host, or other parameters.
2. The begin script runs. Because no operating system or software
has been installed yet, there aren't very many things you can
customize at this point. However, you can perform special disk partitioning
operations, change eeprom settings, or create a dynamic installation
3. The pfinstall program runs. This program performs the
partitioning, filesystem setup, and package installation. The parameters
for this process are specified in the JumpStart profile.
4. The finish script runs. This is usually where more of the customization
occurs because this is the first chance to be able to access the
files installed on the new system. Typically, most admins use the
finish script to edit /etc files, build home directories,
or install patches.
5. The system reboots. Ideally, at this point, the new system
should be fully configured and ready to be put in service. You may
have to change some network settings, but other than that, the system
should be fully operational.
To elaborate on how JumpStart begin and finish scripts can assist
in building a new system, I'll discuss a fictional system environment.
This environment has three distinct classes of Solaris systems:
desktop systems for employees, public Internet servers, and large-scale
Each system group has different installation requirements. Listed
below is the base installation cluster each system requires, and
a checklist of operations that need to be performed before the system
can be put in production. See Table 1.
The installation process for each of these system groups is pretty
complicated, but everything we want to do can be accomplished by
using a begin or finish script.
Unfortunately, we can only specify one begin script and one finish
script in the rules file. Writing one giant script to perform the
tasks listed above would have several disadvantages. It'd be
pretty awkward to maintain, difficult to debug, and each script
we'd write would have repeated code to perform identical tasks.
The solution to this is to break down these tasks into a group
of smaller scripts, each one performing an individual function.
One script disables the Sendmail daemon, one script makes sure every
entry in inetd.conf is commented out, and so on. A controlling
script manages the whole process by running the scripts you specify
at the begin or finish phase, and in the proper order.
The controlling script is known as the wrapper script, and the
smaller scripts that perform the installation customization are
known as the operation scripts.
The scripts are organized in a layout similar to the startup/shutdown
scripts in the /etc/rc?.d directories, which are really links
to the real files in /etc/init.d/.
If your JumpStart directory is /export/jumpstart/, create
the following directory structure:
Then, create a subdirectory for each installation group:
The master.d directory is our base directory for all of our
operation scripts. When scripts need to be placed in the installation
group directories, a link is created.
The Wrapper Script
The wrapper script is placed in /export/jumpstart/scripts/
(see Listing 1). Here is an explanation of what the script does:
1. The script breaks down its calling name to find out if it is
called at the begin phase or the finish phase, and to see what directory
the operation scripts are in.
2. It searches for scripts to run. If we are in the begin phase,
we will run every script that starts with a B. If we are in the
finish phase, we will run every script that starts with an F.
3. The operation scripts are run. When the script is called, the
word "begin" or "finish" is passed as the first
argument, in case the operation script needs to know when it is
being called. Each script and the time it ran is clearly labeled
in the standard output, which JumpStart saves to a file in /var/sadm/system/logs/.
The wrapper script only needs to be written once. To create future
instances, just create two hard links or soft links to it. One link
is for the begin script, the other for the finish script.
So, a ls of our script directory might look like this:
$ ls -F scripts/
appsvr.beg@ desktop.beg@ inetsvr.beg@ master*
appsvr.d/ desktop.d/ inetsvr.d/ master.d/
appsvr.fin@ desktop.fin@ inetsvr.fin@
The JumpStart rules file would look similar to this.
(rule) scripts/desktop.beg profiles/desktop scripts/desktop.fin
(rule) scripts/inetsvr.beg profiles/inetsvr scripts/inetsvr.fin
(rule) scripts/appsvr.beg profiles/appsvr scripts/appsvr.fin
The infrastructure is in place and we need to populate the directories
with the operation scripts that perform the individual tasks.
The Operation Scripts
All of the scripts we write will be kept in the master.d
directory. Then we create links in the corresponding group directory
that identify when the scripts are called and in what order.
Because the operation scripts are meant to be written only once,
they need to be flexible. Even though they only perform one operation,
they should be able to cope with different installation environments.
Example 1 -- Creating the /etc/shells File
This script puts together an /etc/shells file that determines
what user accounts can have ftp access to a host (see Listing
The script only builds an /etc/shells file if one doesn't
already exist, and it only lists a shell in the file if it is present
on the host filesystem.
The script's filename is set-shells and it's
placed in the scripts/master.d directory. When it needs to
be placed in one of the installation group directories, it is linked
to the directory with a name starting with F followed by an order
$ cd scripts
$ ls -F master.d
$ ln -s master.d/set-shells desktop.d/F42set-shells
$ ls -F desktop.d
When the desktop.fin script runs, it will call the F42set-shells
Example 2 -- Populating the passwd and Shadow Files
One added benefit of using this system is that your operation
scripts are not limited to the borne shell. You could use bash,
csh, or ksh. The boot server installation of Solaris
8 also includes a Perl 5 distribution, so you could write your operation
scripts in Perl.
Listing 3 is a Perl script that populates the /etc/passwd,
/etc/shadow, /etc/group, and /etc/auto_home
files. The script reads in two datafiles -- one detailing the
user account information, the other detailing the group information.
It populates each file with the user or group entries and it makes
some changes to the data, if necessary. For example, it can limit
which accounts are added to the system by group id, or it can change
the user's default shell if it isn't installed on the
Example 3 - Preserving a Configuration File During an Upgrade
When JumpStart performs an upgrade of a system, it removes the
existing packages on a host system, and replaces them with the packages
consistent with the same metacluster of the new operating system.
That is, when you upgrade an old Solaris 7 SUNWCreq installation
to Solaris 8, it removes the old packages and installs the equivalent
In most situations, configuration files are preserved, but that
may not be the case with some third-party applications. To ensure
peace of mind, create a single operation script that runs during
the begin phase and the finish phase to preserve the configuration
files and then restore them after the upgraded package has been
installed (see Listing 4).
When called from the begin script, it mounts the root filesystem,
finds the configuration files, and copies them to a different directory
on the disk that isn't referenced in the package's installation
data. When it's finished, it unmounts the disk.
When called from the finish script, it copies the new configuration
files to a different directory, and replaces the configuration files
that it saved during the begin phase.
When testing this software, I put a standalone server into production
in less than 45 minutes. That included patching the system, building
home directories, securing the daemons, and installing backup software.
There were 20 operation scripts that ran during the installation
for this particular environment, and when the system was done, all
I had to do was change the IP address, gateway, and hostname.
However, I still see environments where administrators go though
a manual post-installation process of removing software, adding
software, copying files, changing name services. They've repeated
the process for so long, it's practically second nature to
them. Unfortunately, it takes up more time, and there is a higher
chance of mistakes.
JumpStart can fully automate a system installation, but only if
we take advantage of its capabilities. These scripts can help you
get started on a framework for your own JumpStart environment. Then,
you can expand the system by writing more operation scripts. Don't
miss the opportunity to automate a task if it can simplify future
Chris Josephes is currently self-employed as a systems engineer
in Minneapolis, Minnesota. He can be reached at: firstname.lastname@example.org.