Cover V10, I10

Article
Table 1

oct2001.tar

A Framework for JumpStart Begin/Finish Scripts

Chris Josephes

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 profile.

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 application/development servers.

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.

Filesystem Layout

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:

/export/jumpstart/scripts/
/export/jumpstart/scripts/master.d/
Then, create a subdirectory for each installation group:

/export/jumpstart/scripts/desktop.d/
/export/jumpstart/scripts/inetsvr.d/
/export/jumpstart/scripts/appsvr.d/
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 2).

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 number:

$ cd scripts
$ ls -F master.d
set-shells*
$ ln -s master.d/set-shells desktop.d/F42set-shells
$ ls -F desktop.d
F42set-shells@
When the desktop.fin script runs, it will call the F42set-shells script.

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 system.

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 SUNWCreq cluster.

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.

Conclusion

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 installations.

Chris Josephes is currently self-employed as a systems engineer in Minneapolis, Minnesota. He can be reached at: cpj1@visi.com.