Sunday, July 16, 2006

How small can you make Open Solaris - Part 3

In this post I have decided to focus on installing Solaris directly without using the normal Solaris installer. If you are like me and forever installing the latest Solaris Nevada version, and would like to do this without rebooting and running the Solaris installer then the script below might be for you. If you are playing around to see what packages you can remove to shrink a Solaris installation, then a modified version of this script might be what you are looking for.

Solaris already has an excellent tool for upgrading your current system called live upgrade. The script below is different, as it does a totally fresh install. Hopefully the next version will also install directly onto a ZFS filesystem rather than a UFS partition.

To start off you need a Solaris X86 system (one which uses grub) with a free Solaris partition that has enough diskspace to hold the installation. Note, this script does no checking! It assumes you have configured the settings correctly, and have allocated enough space. You also have to have a DVD (or image) of Solaris (or maybe a jumpstart type installation directory).

Going through the script, at the beginning you will find some variables to may need to change to refect your setup. Since it uses the Solaris Meta Clusters you will need to define which one you want. The functions (which is most of the code), rattle through the cluster table of contents file and produces an order list of packages for the meta cluster you selected. Once it has a list a pkgadd is executed for each package.

After the packages have been installed, there are a few system configurations and device links that are required to get the system booted correctly. You can have the system automatically configure itself on reboot if you have a valid sysidcfg file in your current directory. Otherwise, the system will ask you many questions on reboot to configure hostnames, networking etc. If you are familiar with building zones, this will not be new.

Before you start, you should read through the script so you know exactly what it does. The is very little error/sanity checks in the script, and incorrect settings could be devastating as you will need to be root (or have the correct privs) to use it. When you have finish the installation you will need to modify grub to boot off the correct partition. Below the relevent section of my /boot/grub/menu.lst file.


title Solaris Test
root (hd0,0,d)
kernel /platform/i86pc/multiboot
module /platform/i86pc/boot_archive


Enjoy, and Good Luck!!!


#!/bin/bash
#
# Quick and Dirty Solaris installer
# Version 0.1
#
PROD=/cdrom/sol_11_x86/Solaris_11/Product
TOK=${PROD}/.clustertoc
ORDER=${PROD}/.order

# Current metaclusters are
# SUNWCXall - Entire Distribution plus OEM support
# SUNWCall - Entire Distribution
# SUNWCprog - Developer System Support
# SUNWCuser - End User System Suppor
# SUNWCreq - Core System Support
# SUNWCrnet - Reduced Networking Core System Support
# SUNWCmreq - Minimal Core System Support
METACLUSTER=SUNWCrnet

#
# Change these to relect your system. The next version should
# use ZFS rather that UFS.
#
ROOTDEV=/dev/dsk/c0d0s4
RAWROOTDEV=/dev/rdsk/c0d0s4

SWAP=/dev/dsk/c0d0s1
LOG=/tmp/install.log

SVCPROFILE=generic_limited_net.xml

typeset -a pkgs

#
# Solaris packages need to be installed in the correct order.
# The .order file contains all the packages in the correct
# installation order
#
function reorder_pkgs() {
typeset -a pkglist=( ${pkgs[@]} )
pkgcnt=0

while read order_pkg ; do
for i in ${pkglist[@]} ; do
[ "$order_pkg" = "${i%.i}" ] && {
pkgs[$(( pkgcnt++ ))]="${i}"
printf "."
}
done
done < ${ORDER}
}

#
# This function builds a list of packages in a cluster
# If there is a cluster within a cluster, it will call itself to
# resolve all the packages.
#
# Before calling make sure you initialize pkgcnt to 0
# Arg: $1 contains the cluster name
# Affected vars: pkgs, pkgcnt
#
function get_pkg_list() {
local IFS="="
local print_on=0
local cluster=$1

while read arg1 arg2
do
[ "${arg1}" = "END" -a "${print_on}" = "1" ] && break;
[ -z "${arg2}" ] && continue;

[ "${arg2}" = "${cluster}" ] && {
print_on=1
continue
}

[ "${print_on}" = "1" -a "${arg1}" = "SUNW_CSRMEMBER" ] && {
ifcluster=`expr "${arg2}" : '\(SUNWC\)'`
if [ "${ifcluster}" = "SUNWC" ]; then
get_pkg_list ${arg2}
else
[ -d ${PROD}/${arg2} ] && {
pkgs[$(( pkgcnt++ ))]="${arg2}"
printf "."
continue;
}

arg2="${arg2}.i"
[ -d ${PROD}/${arg2} ] && pkgs[$(( pkgcnt++ ))]="${arg2}"
printf "."
fi
}
done < ${TOK}
}

#
# Check for the installation image before proceeding
#
[ ! -d ${PROD} ] && {
echo "Cannot find Solaris Installation"
exit 1
}

#
# Create a pkg admin file - see man admin(4)
#
sed 's/ask/nocheck/' /var/sadm/install/admin/default > /tmp/.admin.doit

#
# Build an ordered list of packages from the Solaris installation image
#
printf "Building a list of packages "
pkgcnt=0
get_pkg_list ${METACLUSTER}
echo
printf "Sorting packages into the correct order for installation "
reorder_pkgs
echo

newfs ${ROOTDEV} || exit 1
mount ${ROOTDEV} /mnt

#
# Install packages from Solaris installation image
#
echo "Starting installation of packages"
echo
(
for i in ${pkgs[@]} ; do
pkgadd -n -a /tmp/.admin.doit -d ${PROD} -R /mnt $i
done
) > ${LOG}

#
# Update /etc/vfstab with swap and root partitions
#
(
printf "${SWAP}\t-\t-\tswap\t-\tno\t-\n"
printf "${ROOTDEV}\t${RAWROOTDEV}\t/\tufs\t1\tno\t-\n"
) >> /mnt/etc/vfstab

#
# Copy links for disk partitions in /dev/dsk and /dev/rdsk
# This is needed so the system can find the root partion on boot
#
( cd /dev && find dsk rdsk -depth | cpio -pdm /mnt/dev 2>/dev/null )

#
# Configure system to initialize identity on first boot
# If there is a sysidcfg file in the current directory. This will
# be copied across.
#
PROFILEDIR=/mnt/var/svc/profile
[ -f ${PROFILEDIR}/${SVCPROFILE} ] && {
if [ -f ./sysidcfg ]; then
cp ./sysidcfg /mnt/etc
else
touch /mnt/etc/.UNCONFIGURED
fi
cp -p ${PROFILEDIR}/${SVCPROFILE} ${PROFILEDIR}/generic.xml
}

#
# set bootpath to root filesystem.
# Also set the console to text
#
(
BOOTPATH=$( ls -l ${ROOTDEV} | nawk '{print $11}' |
sed -e 's#[./]*/devices/#/#' )

printf "setprop bootpath ${BOOTPATH}\n"
printf "setprop console 'text'\n"
) >> /mnt/boot/solaris/bootenv.rc

#
# If found execute local script before /mnt is unmounted
#
[ -x ./local_install.bash ] && ./local_install.bash

#
# Finish off installation
#
bootadm update-archive -R /mnt
echo "You will need to configure /boot/grub/menu.lst to boot this partition"

umount /mnt
# eject cdrom

No comments: