Wednesday, September 19, 2012

Non-relocatable SVr4 package

Packages advantages, such as consistency and standardization are quite obvious.
Of course one can get very complex about it, but it suffices to play it simple.
   
An essential distinction is between relocatable and non-relocatable options.
Relocatable packages comprises a directory hierarchy that can be rooted at will.
Non-relocatable packages merge their contents into the preexistent directory hierarchy.
   
It's very easy to create a simple non-relocatable SVr4 package.
Begin by organizing disjoint directories where to put sources and output.
A ZFS file-system proves useful for handling many versions via snapshots and clones.
   
# zfs create -o mountpoint=/pkg data/pkg
# zfs create data/pkg/src
# zfs create data/pkg/out
   
It's a good practice to give a package name a well defined prefix.
Typically an abbreviation of an organization name or other acronym is used.
    
# mkdir /pkg/src/PHXsvc1
    
All the subsequent work will be done inside the source directory.
Actually this isn't required but will simplify matters.
   
# cd /pkg/src/PHXsvc1
    
Once in the source directory, create or put the package contents (files and directories).
Adjust mode and ownership as it should be on the target system after the installation.
    
# ll
total ...
-r--r--r--   1 root  sys    934 Sep 13 15:36 manifest.xml
-r-xr-xr-x   1 root  sys    582 Sep 12 15:55 script.sh
...
   
Generate the base prototype.
The above and below highlights shows related information.
    
# find . ! -name . -a ! -name prototype | pkgproto > prototype
# cat prototype 
f none manifest.xml 0444 root sys
f none script.sh 0555 root sys
   
Edit the prototype to describe where each item will be placed on the target system.
New directories (d) can be created and existent ones can be referenced within new files (f).
Except for JumpStart, when packaging SMF services set the class to manifest.
Every new class that's used must also be referenced in pkginfo's CLASSES.
The below highlights shows what's been edited in the base prototype.
          
# cat prototype 
f manifest /var/svc/manifest/site/manifest.xml 0444 root sys
d none /opt/site 0755 root sys
f none /opt/site/script.sh 0555 root sys
     
Create the information files copyright, pkginfo and scripts in the source directory.
For SMF manifests the search clause is required to point to supporting scripts.
For JumpStart, the search clause and the supporting scripts shouldn't be used.
Reference them all in the prototype along with the package contents.
   
# cat copyright

  Copyright (c) 2012 ...
  All Rights Reserved.


  This product is protected by copyright and distributed under
  licenses restricting copying, distribution, and decompilation.


  
# cat pkginfo
PKG="PHXsvc1"
NAME="Non-relocatable sample package"
ARCH="i386,sparc"
VERSION="1.0"
CATEGORY="system"
DESC="Non-relocatable package demonstration"
VENDOR="AZ - Learnings on Solaris"
PSTAMP="Sep 19, 2012"
CLASSES="none manifest" 
   
# cat prototype 
! search /usr/sadm/install/scripts/
i copyright
i pkginfo
i i.manifest
i r.manifest

f manifest /var/svc/manifest/site/manifest.xml 0444 root sys
d none /opt/site 0755 root sys
f none /opt/site/script.sh 0555 root sys
   
Finally, create the package.    
   
# pkgmk -o -d /pkg/out
## Building pkgmap from package prototype file.
## Processing pkginfo file.
WARNING: missing directory entry for </opt>
WARNING: missing directory entry for </var>
WARNING: missing directory entry for </var/svc>
WARNING: missing directory entry for </var/svc/manifest>
WARNING: missing directory entry for </var/svc/manifest/site>
## Attempting to volumize 3 entries in pkgmap.
part  1 -- 31 blocks, 17 entries
## Packaging one part.
/pkg/out/PHXsvc1/pkgmap
/pkg/out/PHXsvc1/pkginfo
/pkg/out/PHXsvc1/root/opt/site/script.sh
/pkg/out/PHXsvc1/root/var/svc/manifest/site/manifest.xml
/pkg/out/PHXsvc1/install/copyright
/pkg/out/PHXsvc1/install/i.manifest
/pkg/out/PHXsvc1/install/r.manifest
## Validating control scripts.
## Packaging complete.
       
It may be convenient to convert the package to a streamed format.
Notably because it's easier to deal with a single file instead of a directory hierarchy.
     
# pkgtrans /pkg/out /pkg/out/PHXsvc1.pkg PHXsvc1
 
# ll /pkg/out 
total ...
drwxr-xr-x   3 root  root      5 Sep 19 10:28 PHXsvc1
-rw-r--r--   1 root  root   3.5K Sep 19 10:55
PHXsvc1.pkg
...
   

A few verifications could be:
   
# pkgchk -d /pkg/out/PHXsvc1.pkg all 
Checking uninstalled stream format package <PHXsvc1> from </pkg/out/PHXsvc1.pkg>
## Checking control scripts.
## Checking package objects.
## Checking is complete.
  
  
# pkginfo -l -d /pkg/out/PHXsvc1.pkg
   PKGINST:  PHXsvc1
      NAME:  Non-relocatable sample package
  CATEGORY:  system
      ARCH:  i386,sparc
   VERSION:  1.0
    VENDOR:  AZ - Learnings on Solaris
      DESC:  Non-relocatable package demonstration
    PSTAMP:  Sep 19, 2012
    STATUS:  spooled
     FILES:        8 spooled pathnames
                   1 directories
                   1 executables
                   5 package information files
                   3 blocks used (approx)
   
       

Monday, September 10, 2012

Patching the boot miniroot

Assume that the setup is according to Custom JumpStart framework setup.
Consider that no operations have happened yet from /install/Solaris_10/Tools.
The booting miniroot should be unpacked to a subdirectory, not a ZFS dataset.
  
IMPORTANT
It can be considered best practice to patch the boot miniroot as soon as possible.
It's known to be necessary when performing a flash install of an updated ZFS-root image.
/install/Solaris_10/Tools should already exist as per the previous assumptions.
For correct patchadd behavior patch 119255-86 / 119254-86 must be installed.
  
The whole operation is as follows:
  
# mkdir /patch/miniroot
# /boot/solaris/bin/root_archive
    unpackmedia /install /patch/miniroot 

# cp -p /patch/miniroot/sbin/rc2{,.0}
# cp -p /patch/miniroot/sbin/sulogin{,.0}
  
# smpatch download -d /tmp -f -i 147441
147441-23 has been validated.
  
# patchadd -C /patch/miniroot /tmp/147441-23 
Patch 147441-23 has been successfully installed.
See /patch/miniroot/var/sadm/patch/147441-23/log for details
Executing postpatch script...
Patch packages installed:
  SUNWbtool
  SUNWcakr
  SUNWckr
  SUNWcsl
  SUNWcslr
  SUNWcsr
  SUNWcsu
  SUNWesu
  SUNWgss
  SUNWmdb
  SUNWmdbr
  SUNWmptsas
  SUNWnfsckr
  SUNWnfscr
  SUNWnfscu
  SUNWnfsskr
  SUNWnfssu
  SUNWos86r
  SUNWxvmpv
  SUNWzfskr
  SUNWzfsr
  SUNWzfsu
  SUNWzoneu
  
# export SVCCFG_REPOSITORY=/patch/miniroot/etc/svc/repository.db
  
# svccfg -s system/manifest-import setprop start/exec = :true
# svccfg -s system/filesystem/usr setprop start/exec = :true
# svccfg -s system/identity:node setprop start/exec = :true
# svccfg -s system/device/local setprop start/exec = :true
# svccfg -s network/loopback:default setprop start/exec = :true
# svccfg -s network/physical:default setprop start/exec = :true
# svccfg -s milestone/multi-user setprop start/exec = :true

  
# mv /patch/miniroot/sbin/rc2{.0,}
# mv /patch/miniroot/sbin/sulogin{.0,}

# /boot/solaris/bin/root_archive
    packmedia /install /patch/miniroot

Now, other boot and/or JumpStart servers can be more easily updated.
Assuming that the updated server js-01 can (rw) mount js-02:/install:
  
js-01 # cd /install
js-01 # find boot Solaris_10/Tools/Boot |

          cpio -pdum /net/js-02/install
   

Thursday, September 6, 2012

Custom JumpStart flash install

Assume that the setup is according to Custom JumpStart framework setup.
Consider 192.168.0.12 as the IP address of the js-01 X86 Custom JumpStart server.
 
Solaris have always addressed the enterprise needs.
Automated installation is just another example of that.
All that's needed is already included built-in.
 
Solaris is continuously evolving and since Solaris 10 U9, support for Flash Archives have been incorporated to ZFS-root-based Custom JumpStart installations.
 
Compared to the conventional process, the flash install option is simpler.
The main benefit is that a fully updated system can be deployed in one step.
The conventional process requires a time-consuming post-installation update.
Since Solaris has many updates, currently U10 for Solaris 10, the catch-up is long.
Nonetheless, the conventional process is still invaluable to get to consistent images.
 
Another benefit is that it can be part of a disaster recovery procedure for a global zone (GZ).
This assumes, of course, that the non-global zones are backed up by other means.
My preferred NGZ backup option is through ZFS snapshots and streams.

The initial step is, of course, to create a Flash Archive base installation image.
As mentioned, the conventional Custom JumpStart can be used as a starting point.
In fact, I'd say that, for consistency, it's the preferred way to start creating an image.
  
Don't create NGZs for applications yet as they'll be carried out on a later phase.
  
Next, fully update the system.
Begin by applying the most recent patchset for the bulk part.
Wrap up by taking advantage of smpatch for a more fine grained control. 
Use no alternate BEs (ABE) as they aren't supported in the image.
   
Perform some clean-up before creating the image. 
Verify /var/tmp and possibly delete /var/run and inactive BEs (boot environments).
  
Finally, archive the image to where it can be used by Custom JumpStart.
 
js-01:~ # zfs create
            -o mountpoint=/images
            -o sharenfs='rw=base-01,ro=...' ...
js-01:~ # chmod 1777 /images 
 
base-01:~ # mount -F lofs -o nosub / /mnt
base-01:~ # [ -d /mnt/var/run ] && rm -r /mnt/var/run
base-01:~ # ls -la /mnt/var
base-01:~ # umount /mnt
base-01:~ # rm -r /var/tmp/...
base-01:~ # ludelete -R
 
base-01:~ # flarcreate
              -S -n base-01 /net/js-01/images/base-01.flar
 
js-01:~ # chown root:root /images/base-01.flar
  
If not going to use a Flash Archive file anytime soon, consider compressing it.
To achieve the highest compression ratio 7za is the answer.
 
# 7za a base-01{,.flar}
# [ -f base-01.7z ] && rm base-01.flar
  
A few adjustments to the Custom JumpStart profile and rules are needed as follows:
  
# cat rules

# keyword value   begin-script  profile          finish-script
# ------- ------- ------------- ---------------- ---------------
  karch   i86pc   -             profile_x86_flar finish_x86_flar

# cat profile_x86_flar
#
# keyword               value
# --------------------  -------------------------------------
  install_type          flash_install
  archive_location      nfs 192.168.0.12:/images/base-01.flar
  partitioning          explicit
  pool                  rpool auto auto auto mirror any any


# cat finish_x86_flar
#!/bin/sh
  
BASE=/a
BIN=$BASE/usr/bin
SBIN=$BASE/usr/sbin

#................................................................
# X86 fix - The boot device isn't where Solaris was installed
  
$BIN/sync
$SBIN/reboot
   
There's still one important problem: patching the boot miniroot.
Due to the natural evolution of ZFS, the miniroot must be updated accordingly.
The original booting miniroot can't handle the recent ZFS updates on a fully updated image.
   

Friday, August 31, 2012

Custom JumpStart finish (extras)

Assume that the setup is according to Custom JumpStart framework setup.
For convenience, a finish script can reference /jumpstart/extras subdirectories:
 
# cd /jumpstart/extras
# ll -a
total ...
drwxr-xr-x   2 root   root      12 Aug 31 14:38 .
drwxr-xr-x   3 root   root       8 Aug 31 12:47 ..
-rw-r--r--   1 root   other     49 Aug 29 14:36 .bashrc
-rw-r--r--   1 root   other     30 Aug 29 14:32 .inputrc
-rw-r--r--   1 root   other    411 Aug 31 11:10 .profile
-rw-r--r--   1 root   other     20 Aug 29 14:32 .screenrc
-rwxr-xr-x   1 root   root     28M Aug 20 08:51 install_stb.sh
-rw-r--r--   1 root   sys      270 Aug 30 13:54 issue
-rw-r--r--   1 root   root    2.8K Aug 30 14:27 pam.conf
-rw-r--r--   1 root   root    1.1K Aug 30 13:50 syslog.conf
-r--r--r--   1 root   sys     1.2K Oct 10 08:39 site.xml
-rw-r-----   1 root   sys       11 Aug 30 13:52 user.allow
  
It may be good to document the contents of some of these files in more detail.
  
# cat issue

THIS IS ... INFORMATION SYSTEM.
ACCESS IS PROVIDED FOR AUTHORIZED USE ONLY.
YOU MUST COMPLY WITH THE POLICIES AND CONDITIONS.
COMMUNICATION CAN BE MONITORED AND DATA INSPECTED AND SEIZED.

  
# cat .screenrc
defscrollback 10000
  
# cat .bashrc
if [ "$LOGNAME" = "root" ]
then
    typeset +x PS1=

      '\[\e[31m\]\h\[\e[0m\]'
else
    typeset +x PS1=

      '\[\e[0;36m\]\u\[\e[0;34m\]@\[\e[2;34m\]\h\[\e[0m\]'
fi
typeset +x PS1=$PS1':\[\e[0;34m\]\w\[\e[0m\] \$ '
 

alias ll='ls -lh'
  
# cat .inputrc
$if term=xterm
"\e[3~":delete-char
$endif
 
# cat .profile
PATH=/usr/bin:/usr/sbin
PATH=$PATH:/usr/ccs/bin:/usr/ucb:/usr/openwin/bin:/usr/sfw/bin
[ -d /opt/sfw ] && PATH=/opt/sfw/bin:/opt/sfw/sbin:$PATH
 
MANPATH=/usr/man
 
if [ -d /opt/SUNWexplo ]
then
    PATH=$PATH:/opt/SUNWexplo/bin
    MANPATH=$MANPATH:/opt/SUNWexplo/man
fi
 
if [ -d /opt/SUNWlwact ]
then
    PATH=$PATH:/opt/SUNWlwact/bin
    MANPATH=$MANPATH:/opt/SUNWlwact/man
fi
 
if [ -d /opt/SUNWsneep ]
then
    PATH=$PATH:/opt/SUNWsneep/bin
    MANPATH=$MANPATH:/opt/SUNWsneep/man
fi
 
if [ -d /opt/CTEact ]
then
    PATH=$PATH:/opt/CTEact/bin
    MANPATH=$MANPATH:/opt/CTEact/man
fi
 
if [ -d /opt/CTEactx ]
then
    PATH=$PATH:/opt/CTEactx/bin
fi
 
if [ -d /opt/ocm ]
then
    PATH=$PATH:/opt/ocm/ccr/bin:/opt/ocm/bin
    MANPATH=$MANPATH:/opt/ocm/ccr/sysman
fi
 
if [ -d /opt/SUNWsasm ]
then
    PATH=$PATH:/opt/SUNWsasm/bin
fi
 
if [ -d /opt/SUNWsftransport ]
then
    PATH=$PATH:/opt/SUNWsftransport/bin
    MANPATH=$MANPATH:/opt/SUNWsftransport/man
fi
 
case `uname -p` in
 
sparc)

   
    if [ -d /usr/platform/`uname -i`/rsc ]
    then
        PATH=$PATH:/usr/platform/`uname -i`/rsc
    fi
 
    if [ -d /opt/SUNWconn/man ]
    then
        PATH=$PATH:/opt/SUNWconn/man
        MANPATH=
$MANPATH:/opt/SUNWconn/man:
                         /opt/SUNWconn/trunking/man
    fi
  

    if [ -d /opt/SUNWrtvc ]
    then
        PATH=$PATH:/opt/SUNWrtvc/bin
        MANPATH=$MANPATH:/opt/SUNWrtvc/man
    fi
 
    if [ -d /opt/SUNWswasr ]
    then
        [ -d /opt/SUNWswasr/bin ] &&

        PATH=$PATH:/opt/SUNWswasr/bin
        PATH=$PATH:/opt/SUNWswasr/asrassetbundle

    fi
  
    ;;
  
i386)
    ;;
  
esac      
 
if [ -e /opt/sfw/bin/vim ]
then
        EDITOR=/opt/sfw/bin/vim
else
        EDITOR=/usr/bin/vi
fi
 
PAGER="/usr/bin/less -ins"
 
case ${SHELL} in
*bash)
    source .bashrc
    ;;
esac
 
export PATH
export MANPATH
export EDITOR
export PAGER

   
# cat syslog.conf
*.err;kern.notice;auth.notice               /dev/sysmsg
*.err;kern.debug;daemon.notice;mail.crit    /var/adm/messages

*.alert;kern.err;daemon.err                 operator
*.alert                                     root
*.emerg                                     *

auth.notice                                 /var/log/authlog
mail.debug                                  /var/log/syslog
 
# cat user.allow
root
prime
...
   
# cat pam.conf
ppp     auth     requisite  pam_deny.so.1
ppp     account  requisite  pam_deny.so.1
ppp     session  requisite  pam_deny.so.1
ppp     password requisite  pam_deny.so.1

krlogin auth     required   pam_unix_cred.so.1
krlogin auth     required   pam_krb5.so.1

rlogin  auth     requisite  pam_deny.so.1
rlogin  account  requisite  pam_deny.so.1
rlogin  session  requisite  pam_deny.so.1
rlogin  password requisite  pam_deny.so.1

krsh    auth     required   pam_unix_cred.so.1
krsh    auth     required   pam_krb5.so.1

rsh     auth     requisite  pam_deny.so.1
rsh     account  requisite  pam_deny.so.1
rsh     session  requisite  pam_deny.so.1
rsh     password requisite  pam_deny.so.1

ktelnet auth     required   pam_unix_cred.so.1
ktelnet auth     required   pam_krb5.so.1

telnet  auth     requisite  pam_deny.so.1
telnet  account  requisite  pam_deny.so.1
telnet  session  requisite  pam_deny.so.1
telnet  password requisite  pam_deny.so.1

passwd  auth     required   pam_passwd_auth.so.1
cron    account  required   pam_unix_account.so.1
cups    account  required   pam_unix_account.so.1

other   auth     requisite  pam_authtok_get.so.1
other   auth     required   pam_dhkeys.so.1
other   auth     required   pam_unix_cred.so.1
#other  auth     sufficient pam_krb5.so.1
other   auth     required   pam_unix_auth.so.1

other   account  requisite  pam_roles.so.1
other   account  requisite  pam_list.so.1   allow=/etc/user.allow
#other  account  sufficient pam_krb5.so.1
other   account  required   pam_unix_account.so.1

other   session  required   pam_unix_session.so.1

other   password required   pam_dhkeys.so.1
other   password requisite  pam_authtok_get.so.1
other   password requisite  pam_authtok_check.so.1    force_check
#other  password sufficient pam_krb5.so.1
other   password required   pam_authtok_store.so.1

# cat site.xml 
<?xml version='1.0'?>
<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>


<!--
    Copyright (c) 2012 ...
    All rights reserved.

    This file, /var/svc/profile/site.xml, 

    is a distinguished location for
    a site-specific service profile,
    treated otherwise equivalently to

    generic_limited_net.xml file.
-->


<service_bundle type='profile' name='site'
         xmlns:xi='http://www.w3.org/2003/XInclude' >

  <!--
      Disable otherwise enabled CDE services.
  -->


  <service 
name='application/cde-printinfo'
    version='1' type='service'>
      <instance name='default' enabled='false' />
  </service>


  <service 
name='network/rpc/cde-ttdbserver'
    version='1' type='service'>
      <instance name='tcp' enabled='false' />
  </service>


  <service 
name='application/graphical-login/cde-login'
    version='1' type='service'>
      <instance name='default' enabled='false' />
  </service>


  <service 
name='network/rpc/cde-calendar-manager'
    version='1' type='service'>
      <instance name='default' enabled='false'/>
  </service>

  <!--
      Disable yet other services.
  -->


  <service 
name='system/webconsole' 
    version='0' type='service'>
      <instance name='console' enabled='false'/>
  </service>

</service_bundle>

  

Custom JumpStart finish script

Assume that the setup is according to Custom JumpStart framework setup.
Finish scripts are useful for carrying out customizations at the end of the installation.
In fact some X86 require it ending by the reboot command.
  
The finish scripts are placed in the /jumpstart directory:
 
# cd /jumpstart
# ll
total 145
-r-xr-xr-x   1 root   root     63K Aug 21 15:04 check
drwxr-xr-x   3 root   root      13 Aug 31 11:11 extras
-rw-r--r--   1 root   root    3.2K Aug 31 12:47 finish_x86
-rw-r--r--   1 root   root     693 Aug 31 07:49 profile_x86
-rw-r--r--   1 root   root     277 Aug 29 14:06 rules
-rw-r--r--   1 root   root     112 Aug 31 09:39 rules.ok
 
   
A finish script is referenced in the rules file:
 
# cat rules
 
# keyword & value             begin  profile        finish
# --------------------------- ------ -------------- -----------
  karch i86pc                 -      profile_x86    finish_x86    
    
The following is a sample finish script designed on X86.
It references the extras subdirectory in an effort to complement or simplify the work.