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