Thursday, January 21, 2010

Step-by-Step guide to Install OpenSolaris with Automated Installer (2009.06)

If you want to install OpenSolaris on to many computers then you will need to use Automated Installer (AI) which allows you to remotely install the Operating System hands free. This article will be a first of a few examples which will show you how to to do this.

To demonstrate the whole procedure of using AI to build and install OpenSolaris, local packages and finish scripts I am going to do this in a closed environment without a network. It is a complete OpenSolaris Automated Install (AI) example. All you will need is a computer (a good specification desktop or laptop) where we will install OpenSolaris and use VirtualBox as the AI install client. You will not require a network to do any this after you have you have download all the software requirements.
  1. Install OpenSolaris
  2. Download all the relevant software and save it on your system
  3. Install VirtualBox
  4. Setup server for static IP address
  5. Reboot
  6. Create a OpenSolaris VirtualBox client
  7. Setup up Automated Install server
  8. Give it a test
  9. Create new AI Manifests
  10. Create local repository to replace
  11. Check repository
  12. You can now do your first auto install by booting VirtualBox client
  13. Setup local Repository for your Packages
  14. Create a test package
  15. Create the "jumpstart finish script" package
  16. FINISHpkg package information
  17. Add package to our local repository
  18. Need to alter AI Manifests
  19. Moment of truth..
1. Install OpenSolaris
2. Download all the relevant software and save it on your system
$ pfexec pkg install SUNWinstalladm-tools
$ pfexec mkdir /export/aiserver  /export/aiimages
$ ls -1 /export/aiimages

3. Install VirtualBox
$ cd /export/aiimages
$ pfexec gzip -dc VirtualBox-3.1.2-56127-SunOS.tar.gz | tar xf -
$ pfexec pkgadd -d VirtualBox-3.1.2-SunOS-r56127.pkg

4. Setup server for static IP address
$  ifconfig -a
e1000g0: flags=......
vboxnet0: flags=.....   inet netmask ffffff00 broadcast
  • Disable auto magic network
$ pfexec svcadm disable network/physical:nwam
  • Edit the following /etc/hosts (hostname which I used was opensolaris)
  • Before
# Internet host table
::1  opensolaris opensolaris.local  localhost   loghost   opensolaris  opensolaris.local  localhost  loghost
  • After
# Internet host table
::1   loghost  localhost  opensolaris  opensolaris.local    loghost
  • And start up the network service
$ pfexec svcadm enable network/physical:default

5. Reboot (Just to make sure all is working)
  • If you want a network then you can active it (my interface is e1000g0)
  • $ pfexec  ifconfig e1000g0 plumb
    $ pfexec  ifconfig e1000g0 dhcp
    $ pfexec  cp  /etc/nsswitch.dns  /etc/nsswitch.conf
6. Create a OpenSolaris VirtualBox client
  • Ref: PXE booting with NAT , PXE Booting in VirtualBox
  • Start VirtualBox and create a OpenSolaris guest.
  • I will call it ai_client and save virtual disk in default location
  • Minimum disk size is 13GB
  • Set up network boot ai_client-> Settings -> System -> Motherboard (tab) -> Boot Order: (Select) Network
  • Move Network to the top of the list
  • You don't need to do the above, but make sure when you start the client you press F12 for boot menu then select (l) LAN
  • Set up the PXE, TFTP boot
$ mkdir $HOME/.VirtualBox/TFTP
  • Start the ai_client guest and with any luck you will see PXE software message, but it will fail since you have no tftp file to load
  • Now we are going to inform the VirualBox Client where to look for the boot server (note my machine is using the e1000 network interface)
$ VBoxManage setextradata "ai_client" "VBoxInternal/Devices/e1000/0/LUN#0/Config/NextServer"
$ VBoxManage getextradata "ai_client" enumerate
VirtualBox Command Line Management Interface Version 3.1.2
(C) 2005-2009 Sun Microsystems, Inc.
All rights reserved.

Key: GUI/AutoresizeGuest, Value: on
Key: GUI/Fullscreen, Value: off
Key: GUI/InfoDlgState, Value: 400,450,normal
Key: GUI/LastCloseAction, Value: powerOff
Key: GUI/LastWindowPostion, Value: 430,184,720,474
Key: GUI/MiniToolBarAlignment, Value: bottom
Key: GUI/MiniToolBarAutoHide, Value: on
Key: GUI/SaveMountedAtRuntime, Value: yes
Key: GUI/Seamless, Value: off
Key: GUI/ShowMiniToolBar, Value: yes
Key: VBoxInternal/Devices/e1000/0/LUN#0/Config/NextServer, Value:

7. Setup up Automated Install server
$ pfexec installadm create-service -n 0906x86 -s /export/aiimages/osol-0906-ai-x86.iso  /export/aiserver/osol-0906-ai-x86
Setting up the target image at /export/aiserver/osol-0906-ai-x86 ...
Registering the service 0906x86._OSInstall._tcp.local

Detected that DHCP is not set up on this server.
If not already configured, please create a DHCP macro
named dhcp_macro_0906x86 with:
Boot server IP (BootSrvA) :
Boot file      (BootFile) : 0906x86
GRUB Menu      (GrubMenu) : menu.lst.0906x86
If you are running Sun's DHCP server, use the following
command to add the DHCP macro, dhcp_macro_0906x86:
/usr/sbin/dhtadm -g -A -m dhcp_macro_0906x86 -d :BootSrvA=

Additionally, if the site specific symbol GrubMenu
is not present, please add it as follows:
/usr/sbin/dhtadm -g -A -s GrubMenu -d Site,150,ASCII,1,0

Note: Be sure to assign client IP address(es) if needed
(e.g., if running Sun's DHCP server, run pntadm(1M)).
adding tftp to /etc/inetd.conf
Converting /etc/inetd.conf
copying boot file to /tftpboot/pxegrub.I86PC.OpenSolaris-1
Service discovery fallback mechanism set up
  • This will start a new service called install/server and populate /export/aiserver/osol-0906-ai-x86 and /tftpboot
  • When VirtualBox Client boots via PXE it will want to download specific file names off this tftpboot server, depending on the name of the VirtualBox client. We will create them manually
  • Before you ask! I am not using installadm install-client since it does not take a hostname
$ cd /tftpboot
$ ls -l
lrwxrwxrwx   1 root     root          27 Aug 28 10:50 0906x86 -> pxegrub.I86PC.OpenSolaris-1
drwxr-xr-x   6 root     sys            9 May 18  2009 I86PC.OpenSolaris-1
-rw-r--r--   1 root     root         325 Aug 28 10:50 menu.lst.0906x86
-rwxr-xr-x   2 root     root      139024 Aug 28 10:50 pxegrub.I86PC.OpenSolaris-1
-rw-r--r--   1 root     root         130 Aug 28 10:50 rm.0906x86

$ pfexec ln -s pxegrub.I86PC.OpenSolaris-1  ai_client.pxe
$ pfexec ln -s menu.lst.0906x86 menu.lst.ai_client.pxe

8. Give it a quick test
  • Try rebooting your client to see if it boots. We are not finished yet, but the VirtualBox Client should load the basic kernel. It will fail!

9. Create new AI Manifests
  • Ref: Administer the Manifest Files
  • Going to use the default Manifest but with a couple of modifications:
  • First point at our local copy of repository which will be created next
  • Secondly - which we will leave for a little later - to add our own repository for our software
$ cd /export/aiserver/osol-0906-ai-x86/auto_install
$ pfexec cp default.xml  aibuild.xml
  • Edit aibuild.xml and replace
<main url="" authname=""/>
  • with
<main url="" authname=""/>
  • Then we need to process this manifest
$ pfexec /usr/sbin/installadm add -m aibuild.xml -n 0906x86

10. Create local repository to replace
$ pfexec zfs create -o compression=on -o atime=off rpool/export/pkg
$ pfexec lofiadm -a /export/aiimages/osol-repo-0906-full.iso
$ pfexec mount -F hsfs /dev/lofi/1 /mnt
$ pfexec rsync -aP /mnt/repo /export/pkg
  • Edit your repo settings
pfexec vi /export/pkg/repo/cfg_cache
  • replace
origins =
  • with
origins =
  • Configure and start the pkg-server
$ pfexec svccfg import /var/svc/manifest/application/pkg-server.xml
$ pfexec svccfg -s application/pkg/server setprop pkg/inst_root=/export/pkg/repo
$ pfexec svccfg -s application/pkg/server setprop pkg/readonly=true
$ pfexec svcadm refresh pkg/server
$ pfexec svcadm enable pkg/server

11. Check repository
  • Open the URL in your browser http://localhost and you should see all the packages

You can now do your first auto install by booting VirtualBox client
  • After some time you should get a working OpenSolaris system in your VirtualBox client, but this is just a standard build
  • Now we want to add our packages and run a finished script to do some systems changes on first boot. At Last!!

Setup local Repository for your Packages
  • Ref: Creating Repositories and Setting Up a Mirror Repository
  • Before we create our own packages you need a local repository
  • Default location is "/var/pkg/repo" since using the existing configuration files. Not sure what needs to exist to use a new location!
$ pfexec svccfg -s pkg/server
svc:/application/pkg/server> add local
svc:/application/pkg/server> select local
svc:/application/pkg/server:local> addpg pkg application
svc:/application/pkg/server:local> addpg start method
svc:/application/pkg/server:local> setprop start/exec= astring: "/usr/lib/pkg.depotd -p %{pkg/port} -d %{pkg/inst_root} -t %{pkg/socket_timeout} -s %{pkg/threads} --log-access=%{pkg/log_access} --log-errors=%{pkg/log_errors}"
svc:/application/pkg/server:local> setprop pkg/inst_root = astring: "/var/pkg/repo"
svc:/application/pkg/server:local> setprop pkg/threads = count: 50
svc:/application/pkg/server:local> setprop pkg/port = count: 9000
svc:/application/pkg/server:local> exit
$ pfexec svcadm refresh pkg/server:local
$ pfexec svcadm enable pkg/server:local
$ svcs pkg/server
STATE          STIME    FMRI
online         12:45:40 svc:/application/pkg/server:local
online         12:44:12 svc:/application/pkg/server:default
  • Any errors can be located in the log file
$ svcs -l pkg/server:local
fmri         svc:/application/pkg/server:local
name         image packaging repository
enabled      true
state        online
next_state   none
state_time   22 January 2010 13:02:15 GMT
logfile      /var/svc/log/application-pkg-server:local.log
restarter    svc:/system/svc/restarter:default
contract_id  120
dependency   require_all/none svc:/system/filesystem/local (online)
dependency   optional_all/none svc:/system/filesystem/autofs (online)
dependency   optional_all/none svc:/network/ntp (disabled)
dependency   require_all/none svc:/milestone/network (online)
  • You can check all is well via the URL http://localhost:9000

14. Create a test package

$ cd /export
# pfexec bash
# mkdir pkgs
# cd pkgs
# mkdir -p opt/local
# echo "Hello" > opt/local/Hello.txt
# chmod 0600 opt/local/Hello.txt
# chmod 0755 opt  opt/local
# chown root:bin opt opt/local opt/local/Hello.txt
# cat > hellopkg.ips
set            value="Hello"
set name=pkg.description     value="Hello Program"
dir mode=0755 owner=root group=bin path=/opt
dir mode=0755 owner=root group=bin path=/opt/local
file opt/local/Hello.txt mode=0600 owner=root group=bin path=/opt/local/Hello.txt
# eval `pkgsend -s http://localhost:9000 open hellopkg@1.0-0`
# pfexec pkgsend -s http://localhost:9000 include hellopkg.ips
# pkgsend -s http://localhost:9000 close
  • You can then see the package at URL http://localhost:9000

15. Create the "jumpstart finish script" package

  • Now we are going to build a package which will do the job of the old Solaris Jumpstart finish script.
  • The package will be installed at build time.
  • The package will contain files which will setup any personnel settings.
  • The package may overwrite existing files.
  • The package will contain a SMF service which will be executed at first boot to alter the machine at run time

16. FINISHpkg package information

  • Here is an example list of files you can have in such a package, these files would allow for LDAP setup, automount setup, Network Setup, etc
  • The way you would create these files is to install OpenSolaris on a machine and set it up manually to the way you want it and transfer these files to this package.
  • In this example I will look at a subset of the above
  • /etc/X11/gdm/custom.conf - so that we add the Reboot to the Login Window.
  • Staying as root
# cd /export/pkgs
# mkdir FINISHpkg
# cd FINISHpkg
# find /etc/X11/gdm/custom.conf -print | cpio -pdm .
  • Altered file (/export/pkgs/FINISHpkg/etc/X11/gdm/custom.conf) to set the following options:


  • Add a site.xml file which is used to modify default services on boot.
# cd /export/pkgs/FINISHpkg
# mkdir -p var/svc/profile
# cat /export/pkgs/FINISHpkg/var/svc/profile/site.xml
<?xml version='1.0'?>
<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
<service_bundle type="profile" name="default">

   <!-- lets switch off sendmail -->
   <service name='network/smtp' version='1' type='service'>
      <instance name='sendmail' enabled='false'/>

   <!-- Lets Start a service -->
   <service name='network/ftp' version='1' type='service'>
       <instance name='default' enabled='true'/>
# cd /export/pkgs/FINISHpkg
# mkdir -p var/svc/manifest/system lib/svc/method
# cat /export/pkgs/FINISHpkg/var/svc/manifest/system/ai-finish.xml
<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
 Created by Andrew Watkins 22nd Jan 2010

<service_bundle type='manifest' name='ai-finish'>
    name='system/ai-finish' type='service' version='1'>

    <property_group name='startd' type='framework'>
            <propval name='duration' type='astring' value='transient' />

    <instance name='install' enabled='true'>
        <dependency name='filesystem-local'
                <service_fmri value='svc:/system/filesystem/local:default' />

            We want the ai-finish service to complete before
            user action begins.
                        value='svc:/milestone/multi-user' />
                exec='/lib/svc/method/ai-finish %i'
                timeout_seconds='0' />

                timeout_seconds='0' />
    <stability value='Unstable' />

                <loctext xml:lang='C'>
                <loctext xml:lang='C'>
                        AI finish script


# cat /export/pkgs/FINISHpkg/lib/svc/method/ai-finish 

#!/bin/sh -x

. /lib/svc/share/

LC_ALL=C; export LC_ALL



install() {
    # Disable nwam & enable dhcp
    # In our network we need this since we use Microsoft DNS/DHCP and nwam does not configure dhcp correctly to pass nodename to DHCP server
    # Not sure what will happen in a VirtualBox client but again it shows what can be done
    if [ -s "/etc/nwam/llp" ]; then
        #If nwam has found a interface it will populate the above file so we will use it
        echo "disable nwam"
        svcadm disable svc:/network/physical:nwam
        INTERFACE=`awk ' { print $1 } ' /etc/nwam/llp`
        echo "Found interface: $INTERFACE"
        if [ -n "$INTERFACE" ]; then
           echo "inet $MYHOST" > /etc/hostname.$INTERFACE
           cp /etc/default/dhcpagent /tmp
           sed -e s/#.*CLIENT_ID=/CLIENT_ID=$MYHOST/ -e 's/#.*REQUEST_HOSTNAME=no/REQUEST_HOSTNAME=yes/' /tmp/dhcpagent > /etc/default/dhcpagent
           touch /etc/dhcp.$INTERFACE

           echo "Starrting network/physical:default"
           svcadm enable svc:/network/physical:default

           # reset name_service to ldap to always use ldap
           # In our example this will not run
           if [ -h /var/svc/profile/name_service.xml -a -f  /var/svc/profile/ns_ldap.xml -a -f /var/ldap/ldap_client_file ]; then
              rm /var/svc/profile/name_service.xml
              ln -s /var/svc/profile/ns_ldap.xml /var/svc/profile/name_service.xml

case "$1" in
    # Run it

    # Disable this service so that it doesn't run again.
    /usr/sbin/svcadm disable system/ai-finish

    if [ "$REBOOT" = "yes" ]; then
       echo "Rebooting"
       ( sleep 30; init 6 ) &
    echo "Finished"
    if [ $? -ne 0 ] ; then
        exit $SMF_EXIT_ERR_CONFIG

    echo "Usage: $0 { install }"

  • I have not add many comments here but I hope there is enough information to help you
  • Create the manifest for this package
# cd /export/pkgs/FINISHpkg
# cat > /export/pkgs/FINISHpkg/FINISHpkg.ips
set            value="FINISHpkg"
set name=pkg.description     value="setup machine we want it"
dir  mode=0755 owner=root group=root path=/etc
dir  mode=0755 owner=root group=root path=/etc/X11
dir  mode=0755 owner=root group=root path=/etc/X11/gdm
dir  mode=0755 owner=root group=sys path=/var
dir  mode=0755 owner=root group=sys path=/var/svc
dir  mode=0755 owner=root group=sys path=/var/svc/manifest
dir  mode=0755 owner=root group=sys path=/var/svc/profile
file etc/X11/gdm/custom.conf mode=0644 owner=root group=root path=/etc/X11/gdm/custom.conf
file var/svc/profile/site.xml mode=0644 owner=root group=root path=/var/svc/profile/site.xml
file lib/svc/method/ai-finish mode=0754 owner=root group=bin path=/lib/svc/method/ai-finish
file var/svc/manifest/system/ai-finish.xml mode=0644 owner=root group=sys path=/var/svc/manifest/system/ai-finish.xml

17. Add package to our local repository

# eval `pkgsend -s http://localhost:9000 open FINISHpkg@1.0-0`
# pkgsend -s http://localhost:9000 include FINISHpkg.ips
# pkgsend -s http://localhost:9000 close
  • Check it appears in the repository

18. Need to alter
AI Manifests

  • Here are 2 new manifest files to replace the early one
  • I have highted the changes
# cd /export/aiserver/osol-0906-ai-x86/auto_install
# cat aibuild.xml

The contents of this file are subject to the terms of the
Common Development and Distribution License (the "License").
You may not use this file except in compliance with the License.

You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
See the License for the specific language governing permissions
and limitations under the License.

When distributing Covered Code, include this CDDL HEADER in each
file and include the License file at usr/src/OPENSOLARIS.LICENSE.
If applicable, add the following below this CDDL HEADER, with the
fields enclosed by brackets "[]" replaced with your own identifying
information: Portions Copyright [yyyy] [name of copyright owner]


Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
Use is subject to license terms.

<ai_manifest name="default">
      <main url="" authname=""/>
      <mirror url=""/>
      <main url="" authname="local"/>
By default the latest build available, in the specified IPS
repository, is installed.
If another build is required, the build number has
to be appended to the 'entire' package in following

Due to dependency issues, entire must be listed first
in the package list, followed by SUNWcsd, and then SUNWcs.
Any additional packages must be listed after SUNWcs.
<pkg name="entire"/>
<pkg name="SUNWcsd"/>
<pkg name="SUNWcs"/>
<pkg name="babel_install"/>
      <!-- You can add more packages if you want -->
      <!-- <pkg name="openoffice"/> -->
      <pkg name="FINISHpkg"/>
<pkg name="babel_install"/>
<pkg name="slim_install"/>

<sc_manifest_file name="AI" URI="./scbuild.xml"/>


# cat scbuild.xml
<?xml version='1.0'?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<service_bundle type="profile" name="name">
<service name="ai_properties" version="1" type="service">
<instance name="default" enabled="true">
<property_group name="ai" type="application">
        <propval name="username" type="astring" value="guest"/>
        <!--passwd = letmein -->
        <propval name="userpass" type="astring" value="eAcu7bKjwwxb6"/>
<propval name="description" type="astring" value="default_user"/>
<!--default root passsord -->
<propval name="rootpass" type="astring" value="$5$VgppCOxA$ycFmYW4ObRRHhtsGEygDdexk5bugqgSiaSR9niNCouC"/>
<propval name="timezone" type="astring" value="GB"/>
        <propval name='hostname' type='astring' value='ai_client'/>

# /usr/sbin/installadm add -m aibuild.xml -n 0906x86

19. Moment of truth..
  • Now boot your VirtualBox client and lets see what happens...and wait.....
  • login on root/opensolaris
  • monitor the process cat /tmp/install_log
  • You will have to manually reboot the client when finished since I have set auto_reboot=false
  • When you reboot you must make sure you change the setting to boot off disk. either press F12 in intro screen or deselect Network (Settings -> System -> Motherboard (tab) -> Boot Order: (UnSelect) Network