#!/bin/sh # #pragma ident "@(#)setup_install_server.sh 1.40 09/06/03 SMI" # # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # Sun considers its source code as an unpublished, proprietary trade # secret, and it is available only under strict license provisions. # This copyright notice is placed here only to protect Sun in the # event the source is deemed a published work. Dissassembly, # decompilation, or other means of reducing the object code to human # readable form is prohibited by the license agreement under which # this code is provided to the user or company in possession of this # copy. # # RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the Government # is subject to restrictions as set forth in subparagraph (c)(1)(ii) of the # Rights in Technical Data and Computer Software clause at DFARS 52.227-7013 # and in similar clauses in the FAR and NASA FAR Supplement. # # Used to copy all or part of the install CD onto a system to set it up as # a long term install server with the install media available on local disk. # # To override the user defined umask umask 022 # # use -b flag to set up a root-only boot server; slice 0 obtained elsewhere. # use -t flag to specify the location of the install boot image # (required if running this utility from the cdrom) dial_pid=0 trap "cleanup_and_exit 1" 1 2 3 15 # make sure path is ok PATH=/usr/bin:/usr/etc:/usr/sbin:${PATH} # set ID and SED path ID=/usr/bin/id SED=/usr/bin/sed CHMOD=/usr/bin/chmod WANBOOT_SUPPORTED_PLATFORMS="sun4u" # # cleanup_and_exit # # Purpose : Call cleanup and exit with the passed parameter # # Arguments : # exit code # cleanup_and_exit() { dial_off exit $1 } print_err() { echo "$@" >&2 } # # validate_uid # # Purpose : Make sure script is being run by root # # Arguments : # none # validate_uid() { uid=`$ID | $SED 's/uid=\([0-9]*\)(.*/\1/'` if [ $uid != 0 ] ; then print_err "You must be root to execute this script" exit 1 fi } # # usage # # Purpose : Print the usage message in the event the user # has input illegal command line parameters and # then exit # # Arguments : # none # usage() { print_err "Usage: $myname [-b] [-t ] [-w ] " cleanup_and_exit 1 } # # dial_on # # Purpose : Turn the spinner on so that the user sees some activity # Log the process id so that it can be killed later # # Arguments : # none # # Side Effects : # dial_id - set to the process id of the dial process # dial_on() { if [ -x ${TOOLS_DIR}/dial ]; then ${TOOLS_DIR}/dial & dial_pid=$! fi } # # dial_off # # Purpose : Turn the spinner off # # Arguments : # none # # Side Effects : # dial_id - set to 0 # dial_off() { if [ -x ${TOOLS_DIR}/dial -a $dial_pid -ne 0 ]; then ${TOOLS_DIR}/dial $dial_pid fi dial_pid=0 } # # check_target # # Purpose : Create the directory that will contain the boot image # and the product distribution. If the target is not on # the local system then print an error message and exit # because it cannot be exported if it is not local. # # Arguments : # $1 - pathname to the directory # # Side Effects : # diskavail - the amount of space available for the the install # server is set # check_target() { echo $1 | grep '^/.*' >/dev/null 2>&1 status=$? if [ "$status" != "0" ] ; then print_err "ERROR: A full pathname is required for the " usage fi if [ ! -d $1 ]; then mkdir -p -- $1 if [ $? -ne 0 ]; then print_err "ERROR: unable to create $1" cleanup_and_exit 1 fi fi # check to see if target is a local filesystem # because we cannot export it otherwise. df -l $1 >/dev/null 2>&1 if [ $? -ne 0 ] ; then print_err "ERROR: $1 is not located in a local filesystem, cannot export $1 for install clients" cleanup_and_exit 1 fi diskavail=`df ${Opts_df} $1 | \ ( read junk; read j1 j2 j3 size j5; echo $size )` } # # set_netmask # # Purpose : Get the net mask for the local machine and setup # the netmask file for the install server. # # Arguments : # none # # Side Effects : # NETMASK - the value of the net mask is set # set_netmask() { HEX_MASK=`/sbin/ifconfig -a 2>/dev/null | \ while read ifname flags ; do if [ "${ifname}" = "ether" ]; then # We just read in the 'ether' line from # previous interface, read next line which # is an ifname line. read ifname flags if [ $? -ne 0 ]; then break fi elif [ "${ifname}" = "groupname" ]; then # We just read in the 'groupname' line from # from the previous interface, continue to # read next line. continue; fi read inet ipaddr netmask mask broadcast broadaddr if [ "${ifname}" = "lo0:" ]; then continue; fi if [ "$inet" = "zone" ]; then # Found an interface dedicated to a local zone. # Read in the real "inet" line and continue. read inet ipaddr netmask mask broadcast broadaddr if [ $? -ne 0 ]; then break fi continue; fi echo ${mask} break done` f1=`expr $HEX_MASK : '\(..\)......'` f2=`expr $HEX_MASK : '..\(..\)....'` f3=`expr $HEX_MASK : '....\(..\)..'` f4=`expr $HEX_MASK : '......\(..\)'` F1=`echo "$f1=d" | adb` F2=`echo "$f2=d" | adb` F3=`echo "$f3=d" | adb` F4=`echo "$f4=d" | adb` tmp="${F1}.${F2}.${F3}.${F4}" NET_MASK=`echo $tmp | sed 's/ //g'` echo $NET_MASK >${target}/${VERSION}/Tools/Boot/netmask } # # copy_boot_image # # Purpose : Copy the install boot image to the net install # boot directory. This is located in the Tools # directory under boot. # # Arguments : # none # copy_boot_image() { # # Only copy the Tools directory if it doesn't already exist # if [ ! -d ${target}/${VERSION}/Tools ]; then # copy the contents of the Tools directory echo "Copying ${VERSION} Tools hierarchy..." dial_on mkdir -p ${target}/${VERSION}/Tools old_dir=`pwd` cd ${TOOLS_DIR} find . -depth -print | grep -v Boot | \ cpio -pdmu ${target}/${VERSION}/Tools >/dev/null 2>&1 copy_ret=$? dial_off if [ $copy_ret -ne 0 ]; then print_err "ERROR: copy of ${VERSION} Tools directory failed" cleanup_and_exit 1 fi cd ${old_dir} fi echo "Copying Install Boot Image hierarchy..." dial_on mkdir -p ${target}/${VERSION}/Tools/Boot old_dir=`pwd` cd ${BOOT_DIR} find . -depth -print | \ cpio -pdmu ${target}/${VERSION}/Tools/Boot >/dev/null 2>&1 copy_ret=$? dial_off if [ $copy_ret -ne 0 ]; then echo "ERROR: copy of install boot image failed" cleanup_and_exit 1 fi if [ -d $PROD_DIR/boot ] ; then echo "Copying /boot netboot hierarchy..." dial_on mkdir -p ${target}/boot cd ${PROD_DIR}/boot find . -depth -print | \ cpio -pdmu ${target}/boot >/dev/null 2>&1 copy_ret=$? dial_off if [ $copy_ret -ne 0 ]; then echo "ERROR: copy of /boot netboot failed" cleanup_and_exit 1 fi fi # # Copy the product directory control files # .install_config and .slicemapfile into the # boot image # [ -f ${PROD_DIR}/.slicemapfile ] && \ cp ${PROD_DIR}/.slicemapfile ${target} cp -r ${PROD_DIR}/.install_config ${target} cd ${old_dir} } # # Used to build the WAN boot miniroot image file # cpio_copy() { _Generic() { [ "$OPT_DEBUG" = "true" ] && set -x cc_src=$1 cc_dest=$2 cc_cpio_opts=$3 if [ ! -d $cc_src ] ; then print_err "Cannod find $cc_src" return 1; fi if [ ! -d $cc_dest ] ; then mkdir -p $cc_dest fi ERROR=0 (cd $cc_src; find . -print | cpio $cc_cpio_opts $cc_dest) || ERROR=$? return $ERROR } copy() { _Generic $* -pdum return $? } link() { _Generic $* -pduml return $? } $* } # install_wanmini() # # Purpose: install the wanboot miniroot as miniroot # # Arguments : # $1 - boot archive miniroot # $2 - pathname to WAN boot miniroot image file destination directory # install_wanmini() { [ "${OPT_DEBUG}" = "true" ] && set -x archive=$1 dest=$2 if [ ! -f $archive ]; then print_err "ERROR: $archive not found" cleanup_and_exit 1 fi echo "Installing $archive as $dest/miniroot" dial_on mkdir -p $dest cp $archive $dest/miniroot status=$? if [ $status -ne 0 ] ; then print_err "ERROR: installing $archive failed" cleanup_and_exit 1 fi dial_off return 0 } ################################################################# # MAIN # if [ -f /etc/vfstab ]; then Opts_df="-k" Opts_du="-ks" Arch=`uname -p` else Opts_df="" Opts_du="-s" Arch=`mach` fi myname=$0 # # Check the arguments # -b - optional argument that if present # will cause this script to create # only the information necessary to # create a boot server # -t - optional argument that allows the # user to specify the location of the # install boot image # this is required if this utility is # being run from CD since there is no # way to automatically locate the boot # image # # -p - debug argument that allows the user to # specify the location of the path to the # Tools directory. This included to allow # the testing of installation tools with # an existing CD # boot_server=0 wanboot=0 while [ "$1"x != "x" -a $# -gt 1 ]; do case $1 in -b) boot_server=1; shift;; -t) boot_image=$2; if [ -z "$boot_image" ]; then usage; fi shift 2;; -p) tools_path=$2; if [ -z "$tools_path" ]; then usage; fi shift 2;; -w) wanboot_path=$2; if [ -z "$wanboot_path" ]; then usage; fi wanboot=1; case ${myname} in # absolute path /*) WANBOOT_DIR=`dirname $0` ;; # relative path ./* | ../*) WANBOOT_DIR=`pwd`/`dirname ${myname}` WANBOOT_DIR=`(cd ${WANBOOT_DIR} ; pwd )` ;; esac shift 2;; -*) # -anything else is an unknown argument usage;; *) # not a command-line argument - get out break ;; esac done if [ $# -ne 1 ]; then usage fi validate_uid check_target $1 target=$1 shift # # Get path to hierarchy # must maintain the hierarchy structure and RUN THIS COMMAND FROM THE HIERARCHY # # (1) find the path of the hierarchy. # it may be absolute path # it may be some relative path # it may be given in PATH if [ -n "$tools_path" ]; then TOOLS_DIR=$tools_path else case ${myname} in # absolute path, or found via $PATH (shells turn into abs path) /*) TOOLS_DIR=`dirname ${myname}` myname=`basename ${myname}` ;; # relative path from "./" or ../, so we do a bit of clean up ./* | ../*) TOOLS_DIR=`pwd`/`dirname ${myname}` TOOLS_DIR=`(cd ${TOOLS_DIR} ; pwd )` myname=`basename ${myname}` ;; # name found via "." in $PATH *) TOOLS_DIR=`pwd` ;; esac fi # TOOLS_DIR is now an absolute path to the tools # directory ## Set the PROD_DIR to the product directory PROD_DIR=`(cd ${TOOLS_DIR}/../.. ; pwd )` if [ ! -f $PROD_DIR/.cdtoc ]; then print_err "ERROR: The product distribution does not contain " print_err " a product table of contents" cleanup_and_exit 1 fi if [ -n "${boot_image}" ]; then BOOT_DIR=${boot_image} else BOOT_DIR=${TOOLS_DIR}/Boot fi # # Boot archive directory is where the boot archive # miniroot provided on the media resides # BOOT_ARCHIVE="" BOOT_ARCHIVE_DIR=$PROD_DIR/boot BOOT_ARCHIVE_I=$BOOT_ARCHIVE_DIR/x86.miniroot BOOT_ARCHIVE_S=$BOOT_ARCHIVE_DIR/sparc.miniroot if [ ! -f $BOOT_ARCHIVE_S -a ! -f $BOOT_ARCHIVE_I ]; then print_err "ERROR: The product distribution does not contain " print_err " a boot archive miniroot" cleanup_and_exit 1 elif [ -f $BOOT_ARCHIVE_S -a -f $BOOT_ARCHIVE_I ]; then print_err "ERROR: The product distribution contains a boot " print_err " archive miniroot for multiple platforms" cleanup_and_exit 1 elif [ -f $BOOT_ARCHIVE_S ]; then BOOT_ARCHIVE="$BOOT_ARCHIVE_S" elif [ -f $BOOT_ARCHIVE_I ]; then BOOT_ARCHIVE="$BOOT_ARCHIVE_I" fi ## Check to see whether or not the install boot image is in ## the current directory structure if [ -z "${BOOT_DIR}" ]; then print_err "ERROR: Install boot image not specified" print_err usage fi # # Verify that BOOT_DIR is a valid boot image and exists # if [ ! -d ${BOOT_DIR} ]; then print_err "ERROR: Install boot image ${BOOT_DIR} does not exist" print_err " Check that boot image exists, or use [-t] to" print_err " specify a valid boot image elsewhere." cleanup_and_exit 1 fi if [ ! -f $BOOT_ARCHIVE_S -a ! -f ${BOOT_DIR}/multiboot ]; then print_err "ERROR: ${BOOT_DIR} is not a valid install boot image" print_err " Check that boot image is valid, or use [-t]" print_err " to specify a valid boot image." cleanup_and_exit 1 fi ## make sure we are able to build a wanboot image. if [ "$wanboot" -eq 1 ] ; then # can't make it when running on platforms other than i386 and sparc if [ "$Arch" != i386 -a "$Arch" != sparc ] ; then print_err "ERROR: Cannot make WAN boot Image file on this platform" print_err " You must create WAN boot Image file on i386 or sparc" print_err " platforms only." cleanup_and_exit 1 fi # can't make it from miniroot without one of the supported platforms FOUND=0 for plat in $WANBOOT_SUPPORTED_PLATFORMS; do if [ -d $BOOT_DIR/platform/$plat ] ; then FOUND=1 break; fi done if [ "$FOUND" -eq 0 ] ; then print_err "ERROR: Cannot make WAN boot Image file from boot image" print_err " ${BOOT_DIR}." print_err " It does not contain support for at least one of the" print_err " WAN boot platforms: $WANBOOT_SUPPORTED_PLATFORMS" cleanup_and_exit 1 fi fi # # Validate the target directory # echo "Verifying target directory..." cnt=`find ${target} -print | wc -l` if [ ${cnt} -gt 1 ]; then if [ ${cnt} -eq 2 -a -d ${target}/lost+found ]; then : else cat </dev/null 2>&1 else # cpio on 4.1.x has an obscure bug with symlinks on # hsfs media. Use bar instead. bar cf - . | (cd ${target}; bar xfBp -) fi copy_ret=$? dial_off if [ $copy_ret -ne 0 ]; then print_err "ERROR: Copy of CD image failed" cleanup_and_exit 1 fi # copy the Boot image copy_boot_image fi if [ $wanboot -eq 1 ]; then install_wanmini ${BOOT_ARCHIVE} ${wanboot_path} status=$? if [ $status -ne 0 ] ; then print_err "ERROR: WAN boot Image creation failed" cleanup_and_exit 1 fi echo "WAN boot Image creation complete" echo echo "\tThe WAN boot Image file has been placed in" echo "\t\t$wanboot_path/miniroot" echo echo "\tEnsure that you move this file to a location" echo "\taccessible to the web server, and that the" echo "\tWAN boot configuration file wanboot.conf(4)" echo "\tfor each WAN boot client contains the entries:" echo echo "\t\troot_server=" echo "\t\t\twhere is an HTTP or HTTPS URL" echo "\t\t\tscheme pointing to the location of the" echo "\t\t\tWAN boot CGI program" echo echo "\t\troot_file=" echo "\t\t\twhere is the path and file" echo "\t\t\tname, relative to the web server" echo "\t\t\tdocument directory, of 'miniroot'" echo echo "\tYou should also make sure you have initialized" echo "\tthe key generation process by issuing (once):" echo echo "\t\t# /usr/sbin/wanbootutil keygen -m" echo fi set_netmask echo "Install Server setup complete" cleanup_and_exit 0