#!/bin/bash SVNREV='$Rev: 59528 $' usage () { [ "${1}" ] && echo -e "\n${1}\n\n" echo "Usage: ${NAME} --root|-r ROOTNUM" echo " --ssp|-s SSP --portage|-P PORTAGE" echo " --disk|-d DISKDEV --profile|-p PROFILE" echo " --bootpart BOOTPART --logsize LOGSZ" echo " [--base|-b BASE]" echo " [-v|--verbose] [--pretend] [--noninteractive]" echo " [--minpart] [--repartition] [--keep-boot]" echo " [--ethers ETHERS] [--hostkeys HOSTKEYS]" echo " [--script SCRIPT]..." echo echo "Install a software release to a disk partition on an SSP." echo "If BASE is not specified then SSP and PORTAGE are required." echo echo "Required:" echo " --root|-r ROOTNUM install to partition number " echo echo "Required (with defaults):" echo " --ssp|-s SSP ssp software release tarball" echo " default: /ssp.tgz" echo " --portage|-P PORTAGE portage tree seed tarball (for /usr/portage)" echo " default: /portage.tgz" echo " --disk|-d DISKDEV install to disk device " echo " default: unique disk in /proc/partitions" echo " --profile|-p PROFILE system profile (sfx, sca, sc, sci, scx)" echo " default: already installed profile" echo " --bootpart BOOTPART use as boot partition" echo " default: partition 1 of " echo " --logsize LOGSZ log partition size in GB" echo " default: sfx, sc, sci, sca : 30 GB" echo " scx : 60 GB" echo echo "Optional:" echo " --verbose|-v verbose output" echo " --pretend print actions that would be done" echo " --noninteractive answer yes to all interactive questions" echo " --base|-b BASE BASE is used as a default prefix for" echo " and ." echo " --minpart make partition 6 and 7 tiny to save space" echo " --repartition repartition and format the whole disk" echo " --keep-boot keep the current grub boot option" echo " --ethers ETHERS install ETHERS as /etc/ethers file" echo " --hostkeys HOSTKEYS install ssh host keys from HOSTKEYS tarball" echo " --diags|-D DIAGS diags tree tarball (for /opt/sicortex/diags)" echo " default: /diags.tgz" echo " --script SCRIPT additional script to run after install" echo echo "SSP, PORTAGE, DIAGS, ETHERS, HOSTKEYS and SCRIPT can be a path" echo "to a file, a HTTP URL to be downloaded with 'wget', or a" echo "subversion URL to be downloaded using 'svn cat'. ${NAME} will" echo "check that the these locations exist before doing anything." echo "permanent." echo echo "Additional scripts specified using --script SCRIPT should" echo "accept command line options: -v (verbose), -p (pretend)," echo "and --root ROOT (location of install). The --script option can" echo "be specified multiple times and the scripts will be run in the" echo "order specified." echo echo "The partition layout and sizes is as follows:" echo " /boot - partition 1 (1 GB)" echo " swap - partition 2 (4 GB)" echo " / - partition 5, 6, 7 (40 GB each)" echo " /var/log - partition 8 (30-60 GB based on profile)" echo echo "If --minpart is specified then partition 6 and 7 will be" echo "created as tiny (unuseable) partitions to save space. The" echo "primary use is for the installation within VMWare." echo echo "Examples:" echo echo "Repartition and reformat all partition of /dev/sda and then" echo "download and install a software release and portage tree seed" echo "to /dev/sda5. Set the profile to be a SC648 system (sc)." echo echo " ${NAME} --repartition --profile sc --disk /dev/sda --root 5 \\" echo " --base http://apollo/release/latest/" echo echo "Do the same for a frost devel system. Download and install" echo "an ethers file for this system." echo echo " ${NAME} --repartition --profile sfx --disk /dev/sda --root 5 \\" echo " --ssp http://apollo/release/latest/ssp.tgz \\" echo " --portage http://apollo/release/portage.tgz \\" echo " --ethers http://apollo/install/ssp016.ethers" echo echo "Install to partition 6 of a SC5832 (scx) without partitioning" echo "the disk. This example uses short options." echo echo " ${NAME} -p scx -d /dev/cciss/c0d0 -r 6 \\" echo " -s http://apollo/release/latest/ssp.tgz \\" echo " -P http://apollo/release/latest/portage.tgz" echo echo "Use /proc/partitions to determine the disk and use the current" echo "installed profile. Download and run an additional install script" echo "against the installed partition." echo echo " ${NAME} -r 7 -b http://apollo/release/latest \\" echo " --script http://apollo/release/mkinhouse-ssp" exit 2 } # TODO: output which root partitions have installs and 'yesno' if # installing to already installed partition. # Global settings and defaults NAME=$(basename ${0}) SUCCESS= # Whether we succeeded or not BASE=${BASE} SSP=${SSP} SSP1= SSP2= PORTAGE=${PORTAGE} DIAGS=${DIAGS} VERBOSE=${VERBOSE} PRETEND=${PRETEND} PROFILE=${PROFILE} DISKDEV=${DISKDEV} PARTITION=${PARTITION} KEEP_BOOT=${KEEP_BOOT} ETHERS=${ETHERS} HOSTKEYS=${HOSTKEYS} MINPART= SPLIT_SSP_IMAGE= BOOTNUM=${BOOTNUM:-1} # /boot - partition 1 BOOTSZ=${BOOTSZ:-1} # - 1 GB SWAPNUM=${SWAPNUM:-2} # swap - partition 2 SWAPSZ=${BOOTSZ:-4} # - 4 GB ROOTNUM=${ROOTNUM} # / - partition 5, 6, 7 (no default) ROOTSZ=${ROOTSZ:-40} # - 40 GB LOGNUM=${LOGNUM:-8} # /var/log - partition 8 LOGSZ=${LOGSZ} # - 30G - 60G (based on profile) # empty - partition 9 MNT="/mnt/gentoo" # Utility functions qecho() { [ "$*" ] && echo -e "===>${NAME}> $*"; } vecho() { [ "${VERBOSE}" ] && qecho "$*"; } function die () { local ret=$1; shift; qecho >&2 "$*" exit $ret } # returns 0 for 'yes' or 1 for 'no' yesno() { local answer= [ "${NOASK}" ] && qecho "$* y" && return 0 while read -p "===>${NAME}> $*" answer; do case ${answer} in y|yes|Y|Yes|YES) return 0 ;; n|no|N|No|NO) return 1 ;; *) qecho "Eh?"; answer= ;; esac done } # Check to make sure an input file is accessible check_file() { case ${1} in http://*) wget --spider "${1}" 2>&1 | grep -q OK && return 0 ;; svn://*) svn cat "${1}" &> /dev/null && return 0 ;; ${MNT}/*) qecho >&2 "Skipping check of ${1}"; return 0 ;; /*|./*) [ -r "${1}" ] && return 0 ;; *) qecho >&2 "Unknown source type for ${1}"; return 1 ;; esac echo >&2 "Could not access ${1}" return 1 } # If needed, download file and set SFILE to path wink_file() { local type= cnt= SFILE=${MNT}/${1##*/} CLEAN_FILES="${CLEAN_FILES} ${SFILE}" case ${1} in http://*) qecho "Downloading (wget) ${1}" ;; svn://*) qecho "Downloading (svn) ${1}" ;; /*|./*) qecho "Copying ${1}" ;; *) die 1 "Unknown source type" ;; esac for cnt in $(seq 1 3); do case ${1} in http://*) ${do} ${WGET} "${1}" -O ${SFILE} ;; svn://*) ${do} svn cat "${1}" > ${SFILE} ;; /*|./*) ${do} cp ${1} ${SFILE} ;; esac [ $? -eq 0 ] && return 0 qecho " Failed retrieval attempt ${cnt} of 3" sleep 3 # Hopefully the problem goes away done die 1 "File retrieval of ${1} failed" } # Format the disk do_partition() { if [ -z "${PRETEND}" ]; then echo yesno "About to format ${DISKDEV}. Continue (y/n)? " fi qecho "Formatting ${DISKDEV}" if [ "${PRETEND}" ]; then [ "${VERBOSE}" ] && \ echo :::: echo \""${diskformat}"\" '|' sfdisk -uM ${DISKDEV} else echo "${diskformat}" | sfdisk -uM ${DISKDEV} \ || die 1 "sfdisk of ${DISKDEV} failed" fi vecho "Formatting ${BOOTP}" ${do} ${MKE2FS} ${BOOTP} || die "mke2fs ${BOOTP} failed" vecho "Formatting ${SWAPP}" ${do} mkswap ${SWAPP} || die "mkswap ${SWAPP} failed" vecho "Formatting ${LOGP}" ${do} ${MKFS_EXT3} ${LOGP} || die "mkfs.ext3 ${LOGP} failed" } # Install grub do_inst_grub() { local curopt= offset=0 curopt=${GRUB_CUROPT} if [ "${KEEP_BOOT}" ]; then newopt=${curopt} else [ "${curopt}" ] && offset=$(( (curopt-1) % 3 )) newopt=$(( (ROOTNUM-5)*3 + offset + 1)) fi qecho "Installing grub" vecho " (switching grub boot default from ${curopt} to ${newopt})" cat > /tmp/do_grub <<-EOF #!/bin/bash source /etc/profile cat /proc/mounts > /etc/mtab echo "(hd0) ${1}" > /boot/grub/device.map grub-install --no-floppy hd0 || exit 1 grub-set-default ${newopt} || exit 1 exit 0 EOF ${do} cp /tmp/do_grub ${MNT}/do_grub ${do} chmod +x ${MNT}/do_grub ${do} chroot ${MNT} ./do_grub || die 1 "Install of grub failed" ${do} rm -f ${MNT}/do_grub /tmp/do_grub } cleanup() { local ret=0 trap - TERM QUIT INT EXIT for SFILE in ${CLEAN_FILES}; do case ${SFILE} in ${MNT}/*) ${do} rm -f ${SFILE} ;; esac done # Log this attempt qecho "Logging to ${MNT}/var/log/install-ssp.log" if [ "${SUCCESS}" ]; then msg="Installed ${RELEASE} to ${ROOTP}" else msg="Failed to install ${RELEASE} to ${ROOTP}" fi if [ -z "${PRETEND}" ]; then echo "$(date +"%Y-%m-%dT%H:%m:%S") ${msg}" \ >> ${MNT}/var/log/install-ssp.log fi qecho "Unmounting filesystems" ${do} umount ${MNT}/{boot,proc,var/log,} || ret=$? if [ "${swapped_on}" ]; then ${do} swapoff ${SWAPP} || ret=$? fi [ -e "/tmp/hostkeys.$$.tgz" ] && rm -f /tmp/hostkeys.$$.tgz if [ "${SUCCESS}" ]; then echo "Install complete" else echo echo "*** Install FAILED ***" echo fi return $ret } do_ssh_keys() { if [ ! -e ${MNT}/root/.ssh/id_dsa ]; then qecho "Generating ssh DSA key for root" ${do} mkdir -p ${MNT}/root/.ssh/ ${do} ssh-keygen -t dsa -N '' -f ${MNT}/root/.ssh/id_dsa ${do} chmod 755 ${MNT}/root/.ssh/ fi local partitions= partition= modules= module= nodes= node= local profile=${PROFILE} local ssp_root=${MNT} local node_root=${ssp_root}/opt/sicortex/rootfs/default local rsa_key=$(${do} cat ${node_root}/etc/ssh/ssh_host_rsa_key.pub) case ${profile} in sm0) partitions="" ;; # sm0 does not need ssh keys sfx) partitions="sf0 sf1 sf2 sf3 sx0 sx1 sx2 sx3" ;; sca) partitions="sca" ;; sc) partitions="sc0 sc1" ;; sci) partitions="sci" ;; scx) partitions="scx" ;; *) die 2 "unknown profile ${profile}" ;; esac for partition in ${partitions}; do case ${partition} in # sm0 does not need ssh keys sf[0-3]) modules=1 nodes=4 ;; sca) modules=1 nodes=12 ;; sx[0-3]) modules=1 nodes=27 ;; sc[0-1]) modules=4 nodes=27 ;; sci) modules=9 nodes=27 ;; scx) modules=36 nodes=27 ;; *) die 2 "unknown partition type ${partition}" ;; esac for module in $(seq 0 $((${modules}-1))); do for node in $(seq 0 $((${nodes}-1))); do echo "${partition}-m${module}n${node} ${rsa_key}" \ >> /tmp/known_hosts.$$ done done done qecho "Creating /etc/ssh/ssh_known_hosts with node RSA keys" ${do} mv /tmp/known_hosts.$$ ${ssp_root}/etc/ssh/ssh_known_hosts } # ---------------- Process Parameters and Sanity Check -------------- while [ "$*" ]; do param=$1; shift; OPTARG=$1 case $param in -v|--verbose) VERBOSE="$param" ;; --pretend) PRETEND="$param" ;; --noninteractive) NOASK=1 ;; -p|--profile) PROFILE=${OPTARG}; shift ;; -b|--base) BASE=${OPTARG}; shift ;; -s|--ssp) SSP=${OPTARG}; shift ;; -P|--portage) PORTAGE=${OPTARG}; shift ;; -d|--disk) DISKDEV=${OPTARG}; shift ;; -r|--root) ROOTNUM=${OPTARG}; shift ;; --bootpart) BOOTP=${OPTARG}; shift ;; --logsize) LOGSZ=${OPTARG}; shift ;; --minpart) MINPART=1 ;; --repartition) PARTITION=1 ;; --keep-boot) KEEP_BOOT=1 ;; --ethers) ETHERS=${OPTARG}; shift ;; --hostkeys) HOSTKEYS=${OPTARG}; shift ;; --script) SCRIPT="${SCRIPT} ${OPTARG}" ; shift ;; *) usage "Unrecognized option '${param}'" ;; esac done # SSP and PORTAGE default based on BASE if [ -z "${BASE}" ] && [ -e /mnt/cdrom/sicortex/ssp.tgz ]; then yesno "Continue using /mnt/cdrom/sicortex for BASE (y/n)? " && \ BASE=/mnt/cdrom/sicortex fi [ "${BASE}" ] && [ -z "${SSP}" ] && SSP=${BASE}/ssp.tgz [ "${BASE}" ] && [ -z "${PORTAGE}" ] && PORTAGE=${BASE}/portage.tgz [ -z "${SSP}" ] && die 2 "SSP or BASE must be specified" [ -z "${PORTAGE}" ] && die 2 "PORTAGE or BASE must be specified" [ -z "${ROOTNUM}" ] && die 2 "ROOTNUM must be specified" if [ $(date +%Y) -lt 2008 ]; then qecho "The date seems incorrect: $(date +%Y-%m-%d)." yesno "Continue anyways (y/n)? " || die 1 fi if [ -z "${PROFILE}" ] && [ -e /var/state/scprofile ]; then source /var/state/scprofile 2>/dev/null PROFILE=${_SCv_system_profile} if [ "${PROFILE}" ]; then yesno "Continue using installed profile '${PROFILE}' (y/n)? " || die 1 else die 2 "Could not determine PROFILE, please use --profile" fi fi [ -z "${PROFILE}" ] && die 2 "PROFILE must be specified" if [ -z "${DISKDEV}" ]; then DISKDEVS=$(cat /proc/partitions | egrep "c0d[0-9]$|sd[a-z]$" \ | awk '{print "/dev/"$NF}') dev_cnt=$(echo ${DISKDEVS}| wc -w) DISKDEV=$(echo "${DISKDEVS}" | head -n1) if [ "${dev_cnt}" -eq "1" ]; then yesno "Continue using DISKDEV '${DISKDEV}' (y/n)? " || die 1 elif [ "${dev_cnt}" -gt "1" ]; then qecho "Detected ${dev_cnt} disks: $(echo ${DISKDEVS})" yesno "Continue using DISKDEV '${DISKDEV}' (y/n)? " \ || die 1 "You must specify --disk" else die 2 "Could not determine DISKDEV" fi fi if [ "${PRETEND}" ]; then if [ "${VERBOSE}" ]; then do=${VERBOSE:+echo ::::} else do=": " fi fi if [ "${VERBOSE}" ]; then WGET="wget --retry-connrefused --progress bar:force" TAR="tar --checkpoint=.500 -xpSzf" MKE2FS="mke2fs" MKFS_EXT3="mkfs.ext3" else WGET="wget --retry-connrefused -nv" TAR="tar --checkpoint=.10000 -xpSzf" MKE2FS="mke2fs -q" MKFS_EXT3="mkfs.ext3 -q" fi case ${ROOTNUM} in 5|6|7) true ;; *) die 2 "ROOTNUM must be 5, 6 or 7" ;; esac if [ "${MINPART}" ] && [ "${ROOTNUM}" != "5" ]; then die 2 "--root must be 5 if --minpart is specified" fi case ${DISKDEV} in *cciss*) dev=${DISKDEV}p ;; *) dev=${DISKDEV} ;; esac BOOTP=${BOOTP:-${dev}${BOOTNUM}} # Allow user override SWAPP=${dev}${SWAPNUM} ROOTP=${dev}${ROOTNUM} LOGP=${dev}${LOGNUM} if [ "$(stat -f -c '%T' /)" = "tmpfs" ]; then # We are booted from the install CD/DVD if [ -z "${HOSTKEYS}" ]; then qecho "LiveDVD boot and no hostkeys specified." yesno "Continue and generate new host keys (y/n)? " || die 1 fi else # We are not booted from the install CD/DVD if [ -z "${HOSTKEYS}" ] && [ -z "${PARTITION}" ]; then if yesno "No --hostkeys, reuse installed ssh host keys (y/n)? "; then (cd /etc/ssh && tar czf /tmp/hostkeys.$$.tgz ssh_host_*) \ || die 1 "Could not package up ssh host keys." HOSTKEYS=/tmp/hostkeys.$$.tgz fi fi fi if [ "${PARTITION}" ] && [ "${KEEP_BOOT}" ]; then die 2 "--repartition and --keep-boot are mutually exclusive" fi if [ -z "${ETHERS}" ] && [ "${PROFILE}" = 'sfx' ]; then if [ -z "${PARTITION}" ]; then if yesno "No --ethers, reuse installed ethers file (y/n)? "; then ETHERS=/etc/ethers fi else yesno "'sfx PROFILE specified without --ethers, continue (y/n)? " \ || die 1 fi fi # Check the devices if ! file ${DISKDEV} | egrep -qs "block special.*/(0|16)\)"; then die 2 "${DISKDEV} does not appear to be a disk device" fi if [ -z "${PARTITION}" ]; then for part in ${BOOTP} ${SWAPP} ${ROOTP} ${LOGP}; do if ! file ${part} | grep -qs "block special"; then qecho >&2 "${part} does not appear to be a device partition" die 2 "Perhaps you meant to use --repartition" fi done fi if check_file "${SSP}.manifest" 2>/dev/null; then # the ssp image is too big, and has been split into two parts SPLIT_SSP_IMAGE=1 SSP1=${SSP}.aa SSP2=${SSP}.ab fi # if [ "${DIAGS}" ]; then check_file "${DIAGS}" || die 1 elif [ "${BASE}" ]; then DIAGS=${BASE}/diags.tgz if ! check_file "${DIAGS}"; then vecho "Skipping diags tarball install" DIAGS= fi fi # Validate source files if [ "${SPLIT_SSP_IMAGE}" ]; then check_file "${SSP1}" || die 1 check_file "${SSP2}" || die 1 else check_file "${SSP}" || die 1 fi check_file "${PORTAGE}" || die 1 if [ "${DIAGS}" ]; then check_file "${DIAGS}" || die 1 fi if [ "${ETHERS}" ]; then check_file "${ETHERS}" || die 1 fi if [ "${HOSTKEYS}" ]; then check_file "${HOSTKEYS}" || die 1 fi for script in ${SCRIPT}; do check_file "${script}" || die 1 done # Set some defaults based on PROFILE case ${PROFILE} in sfx|sca|sc|sci) LOGSZ=${LOGSZ:-30} ;; sm0) LOGSZ=${LOGSZ:-30} ;; scx) LOGSZ=${LOGSZ:-60} ;; *) die 2 "PROFILE must sfx, sca, sc, sci or scx" esac # Check sizes for formatting disksize=$(grep "\<${DISKDEV##*/}$" /proc/partitions | awk '{print $3}') disksize=$(( disksize / 1000000 )) if [ "${MINPART}" ]; then ROOTSZ_B=1 else ROOTSZ_B=${ROOTSZ} fi needsize=$(( BOOTSZ + SWAPSZ + ROOTSZ + ROOTSZ_B * 2 + LOGSZ )) # More sanity checks if reformatting if [ "${PARTITION}" ]; then if [ "${needsize}" -gt ${disksize} ]; then die 1 "Not enough space on ${DISKDEV} (${needsize} Gb > ${disksize} Gb)" fi mounts=$(grep "${DISKDEV}" /proc/mounts /proc/cmdline /proc/swaps) if [ "${mounts}" ]; then die 1 "Cannot format ${DISKDEV} because it is in use:\n${mounts}" fi fi mounts=$(grep "${ROOTP}" /proc/mounts /proc/cmdline) if [ "${mounts}" ]; then die 1 "Cannot format ${ROOTP} because it is in use:\n${mounts}" fi diskformat=" 0,${BOOTSZ}000,L,* ,${SWAPSZ}000,S ,0,0 ,,E ,${ROOTSZ}000,L ,${ROOTSZ_B}000,L ,${ROOTSZ_B}000,L ,${LOGSZ}000,L ,,L " vecho "Parameters/Defaults:" vecho " VERBOSE: ${VERBOSE}" vecho " PRETEND: ${PRETEND}" vecho " SSP: ${SSP}${SSP1:+ ($SSP1}${SSP2:+ $SSP2)}" vecho " PORTAGE: ${PORTAGE}" vecho " DIAGS: ${DIAGS}" vecho " PROFILE: ${PROFILE}" vecho " DISKDEV: ${DISKDEV}" vecho " ROOTNUM: ${ROOTNUM}" vecho " PARTITION: ${PARTITION}" vecho " LOGSZ: ${LOGSZ}" vecho vecho "Derived Values:" vecho " BOOTP: ${BOOTP}" vecho " SWAPP: ${SWAPP}" vecho " ROOTP: ${ROOTP}" vecho " LOGP: ${LOGP}" vecho " disksize: ${disksize}" vecho " needsize: ${needsize}" vecho " do: ${do}" # ---------------- Do the install ----------------------------------- echo [ "${PRETEND}" ] && qecho "Here is what I would do:" [ "${PARTITION}" ] && do_partition qecho "Formatting ${ROOTP}" ${do} ${MKFS_EXT3} ${ROOTP} || die 1 "mkfs.ext3 ${ROOTP} failed" qecho "Creating directory structure in ${MNT} (${ROOTP})" ${do} mkdir -p ${MNT} # Trap on exit and unmount mounts trap cleanup TERM QUIT INT EXIT ${do} mount ${ROOTP} ${MNT}/ \ || die 1 "mounting ${ROOTP} on ${MNT} failed" ${do} mkdir -p ${MNT}/{boot,var/log,var/log.local,proc} if grep -q "${BOOTP}" /proc/mounts; then ${do} mount --bind /boot ${MNT}/boot/ \ || die 1 "mounting bind /boot to ${MNT}/boot failed" else ${do} mount ${BOOTP} ${MNT}/boot/ \ || die 1 "mounting ${BOOTP} on ${MNT}/boot failed" fi if grep -q "${LOGP}" /proc/mounts; then ${do} mount --bind /var/log ${MNT}/var/log \ || die 1 "mounting bind /var/log to ${MNT}/var/log failed" else ${do} mount ${LOGP} ${MNT}/var/log \ || die 1 "mounting ${LOGP} on ${MNT}/var/log failed" fi if swapon -s | grep -q "^/dev"; then vecho "Skipping turning on swap" else swapped_on=1 ${do} swapon ${SWAPP} \ || die "swapon ${SWAPP} failed" fi ${do} mount -t proc proc ${MNT}/proc \ || die 1 "mounting proc on ${MNT}/proc failed" # Other misc file setup ${do} mkdir -p ${MNT}/boot/state ${do} ln -sf ../boot/state ${MNT}/var/state \ || die 1 "failed to create ${MNT}/var/state symlink." ${do} ln -sf ../log.local/emerge.log ${MNT}/var/log/emerge.log \ || die 1 "failed to create ${MNT}/var/log/emerge.log symlink." ${do} touch ${MNT}/var/log/msp-messages-$(date +%Y%m) # Read the current grub boot option setting GRUB_CUROPT=$(grep -as "^[0-9]" ${MNT}/boot/grub/default | head -n1) # Retrieve all the source files if [ "${SPLIT_SSP_IMAGE}" ]; then wink_file ${SSP1} && SFILE_SSP1=${SFILE} wink_file ${SSP2} && SFILE_SSP2=${SFILE} SFILE=${MNT}/${SSP##*/} qecho "concatenating two parts of ssp image" cat ${SFILE_SSP1} ${SFILE_SSP2} > ${SFILE} SFILE_SSP=${SFILE} else wink_file ${SSP} && SFILE_SSP=${SFILE} fi wink_file ${PORTAGE} && SFILE_PORTAGE=${SFILE} if [ "${DIAGS}" ]; then wink_file ${DIAGS} && SFILE_DIAGS=${SFILE} fi if [ "${ETHERS}" ]; then wink_file ${ETHERS} && SFILE_ETHERS=${SFILE} fi if [ "${HOSTKEYS}" ]; then wink_file ${HOSTKEYS} && SFILE_HOSTKEYS=${SFILE} fi for script in ${SCRIPT}; do wink_file ${script} && SFILE_SCRIPTS="${SFILE_SCRIPTS} ${SFILE}" done # Unpack the software release qecho "Unpacking software release to ${MNT}" ${do} ${TAR} ${SFILE_SSP} -C ${MNT} \ --exclude='*var/cache/edb/dep/*' \ --exclude='*opt/sicortex/rootfs/build/var-shared/cache/edb/dep/*' \ || die 1 "Software release unpack failed" echo # Unpack the portage tree (if specified) if [ "${PORTAGE}" ]; then qecho "Unpacking portage tree to ${MNT}/usr/portage" ${do} ${TAR} ${SFILE_PORTAGE} -C ${MNT}/usr/portage \ || die 1 "Portage tree unpack failed" echo ${do} chown -R portage:portage ${MNT}/usr/portage \ || die 1 "Portage tree ownership change failed" ${do} chmod g+ws ${MNT}/usr/portage/distfiles \ || die 1 "Portage distfiles permission change failed" fi # Unpack the diags tree if [ "${DIAGS}" ]; then qecho "Unpacking diag tree to ${MNT}/opt/sicortex/diags" mkdir -p ${MNT}/opt/sicortex/diags ${do} ${TAR} ${SFILE_DIAGS} -C ${MNT}/opt/sicortex/diags \ --exclude=".svn" --exclude="dash_logs" \ || die 1 "Diag tree unpack failed" echo fi # ---------------- System specific setup ---------------------------- qecho "System specific setup (fstab, profile, ethers, etc)" ${do} sed -i "s:/dev/BOOT:${BOOTP}:" ${MNT}/etc/fstab ${do} sed -i "s:\(/boot.*\)noauto,:\1:" ${MNT}/etc/fstab ${do} sed -i "s:/dev/ROOT:${ROOTP}:" ${MNT}/etc/fstab ${do} sed -i "s:/dev/SWAP:${SWAPP}:" ${MNT}/etc/fstab if [ "${PRETEND}" ]; then if [ "${VERBOSE}" ]; then echo :::: echo "${LOGP} /var/log ext3 noatime 0 1" '>>' \ ${MNT}/etc/fstab echo :::: echo "_SCv_system_profile='${PROFILE}'" '>' \ ${MNT}/var/state/scprofile ${do} [add r8169 and asix to modules.autoload.d/kernel-2.6] fi else echo "${LOGP} /var/log ext3 noatime 0 1" >> \ ${MNT}/etc/fstab echo "_SCv_system_profile='${PROFILE}'" > \ ${MNT}/var/state/scprofile mod_file=${MNT}/etc/modules.autoload.d/kernel-2.6 def_dir=${MNT}/etc/runlevels/default case ${PROFILE} in sfx) for sys in {0..3}; do ln -sf msp_linux.bin ${MNT}/tftproot/sf${sys}-msp0_linux.bin ln -sf msp_linux.bin ${MNT}/tftproot/sx${sys}-msp0_linux.bin done # Load mini-ITX kernel modules grep -qs "r8169" ${mod_file} \ || echo -e "\n# Mini-ITX support\nr8169\nasix\n" >> ${mod_file} ;; sca) ln -sf msp_linux.bin ${MNT}/tftproot/sca-msp0_linux.bin # Load mini-ITX kernel modules grep -qs "r8169" ${mod_file} \ || echo -e "\n# Mini-ITX support\nr8169\nasix\n" >> ${mod_file} ;; sm0) # The mfg. config requires additional configs for x in {0..7}; do ln -sf uclinux.bin ${MNT}/tftproot/sm${x}-msp0_linux.bin ln -sf /etc/init.d/net.lo ${MNT}/etc/init.d/net.ctl${x} ln -sf /etc/init.d/net.ctl${x} ${MNT}/etc/runlevels/default/net.ctl${x} ln -sf dnsmasq ${MNT}/etc/conf.d/dnsmasq${x} ln -sf dnsmasq ${MNT}/etc/init.d/dnsmasq${x} ln -sf /etc/init.d/dnsmasq${x} ${MNT}/etc/runlevels/default/dnsmasq${x} done rm -f ${MNT}/etc/init.d/net.ctl rm -f ${MNT}/etc/init.d/net.mgt* rm -f ${MNT}/etc/runlevels/default/net.ctl rm -f ${MNT}/etc/runlevels/default/net.mgt* ;; sc) for msp in {0..3}; do ln -sf msp_linux.bin ${MNT}/tftproot/sc0-msp${msp}_linux.bin ln -sf msp_linux.bin ${MNT}/tftproot/sc1-msp${msp}_linux.bin done ;; sci) for msp in {0..8}; do ln -sf msp_linux.bin ${MNT}/tftproot/sci-msp${msp}_linux.bin done # Make net.mgt{1} start on boot ln -sf /etc/init.d/net.mgt1 ${def_dir}/net.mgt1 ;; scx) for msp in {0..35}; do ln -sf msp_linux.bin ${MNT}/tftproot/scx-msp${msp}_linux.bin done # Make net.mgt{1,2,3} start on boot ln -sf /etc/init.d/net.mgt1 ${def_dir}/net.mgt1 ln -sf /etc/init.d/net.mgt2 ${def_dir}/net.mgt2 ln -sf /etc/init.d/net.mgt3 ${def_dir}/net.mgt3 ;; esac fi if [ "${ETHERS}" ]; then ${do} cp ${SFILE_ETHERS} ${MNT}/etc/ethers || die 1 "ethers copy failed" fi if [ "${HOSTKEYS}" ]; then ${do} ${TAR} ${SFILE_HOSTKEYS} -C ${MNT}/etc/ssh/ \ || die 1 "ssh host key unpack failed" ${do} chmod 600 ${MNT}/etc/ssh/ssh_host_* ${do} chmod 644 ${MNT}/etc/ssh/ssh_host_*.pub fi qecho "Setting up grub.conf" grubd=${MNT}/boot/grub/grub.conf.d grubsect=0$(( ROOTNUM - 4 ))partition${ROOTNUM} if [ "${PRETEND}" ]; then ${do} [determine kernel version] ${do} [determine release version] ${do} [create ${grubd}/${grubsect}] ${do} [create section stubs] ${do} [create ${MNT}/boot/grub/grub.conf] else # Figure out the kernel revision KERNEL=vmlinuz-$(ls -rt ${MNT}/lib/modules/ | tail -n1) [ -e "${MNT}/boot/${KERNEL}" ] \ || die 1 "Could not find kernel ${MNT}/boot/${KERNEL}" RELEASE=$(cat ${MNT}/etc/sicortex-release |sed 's/^[^0-9]*//') # Create the grub section cat /dev/null > ${grubd}/${grubsect} for netb in 172.31 10.137 192.168; do cat >> ${grubd}/${grubsect} <<-EOF title Boot ${ROOTP#/dev/}, ${RELEASE}, internal netblock ${netb}.x.x/16 kernel /${KERNEL} root=${ROOTP} sysrq=1 INTERNAL_NETBLOCK=${netb} savedefault EOF done echo >> ${grubd}/${grubsect} vecho "Creating stub grub options for uninstalled partitions" for part in 5 6 7; do grubsect=0$(( part - 4 ))partition${part} [ -e "${grubd}/${grubsect}" ] && continue cat > ${grubd}/${grubsect} <<-EOF title Placeholder for partition ${part}, netblock 172.31.x.x/16 kernel /vmlinuz root=none title Placeholder for partition ${part}, netblock 10.137.x.x/16 kernel /vmlinuz root=none title Placeholder for partition ${part}, netblock 192.168.x.x/16 kernel /vmlinuz root=none EOF done # Now merge the grub.conf.d files in numerical order cat $(ls -vd ${grubd}/*) > ${MNT}/boot/grub/grub.conf fi qecho "Doing miscellaneous file cleanup" ${do} touch ${MNT}/var/log/wtmp ${do} chown root:utmp ${MNT}/var/log/wtmp do_inst_grub ${DISKDEV} for script in ${SFILE_SCRIPTS}; do ${do} chmod +x ${script} qecho "Running post-install script: ${script##*/}" ${do} ${script} ${VERBOSE} ${PRETEND} --root ${MNT} \ || die 1 "Post-install script ${script} failed." done # Now that everything else has run, check things that should be # created if they don't exist yet do_ssh_keys ${do} mkdir -p ${MNT}/var/state/etc conffile=${MNT}/var/state/etc/sicortex-system.conf if [ ! -e "${conffile}" ]; then qecho "Creating stub ${conffile#${MNT}} file" if [ -z "${PRETEND}" ]; then echo "# SiCortex system configuration" > ${conffile} echo "# See /etc/sicortex-system.conf.example" >> ${conffile} echo "" >> ${conffile} echo "" >> ${conffile} echo "# This header is necessary for the config" >> ${conffile} echo "# parser module. Do not alter." >> ${conffile} echo "[DEFAULT]" >> ${conffile} fi fi policydfile=${MNT}/var/state/etc/sicortex/policyd.conf mkdir -p ${policydfile%/*} if [ ! -e "${policydfile}" ]; then qecho "Creating ${policydfile} file" if [ -z "${PRETEND}" ]; then if [ -e ${MNT}/etc/sicortex/policyd.conf.example ]; then cp ${MNT}/etc/sicortex/policyd.conf.example ${policydfile} \ || die "Failed to create ${policydfile}" else touch ${MNT}/etc/sicortex/policyd.conf.example \ || die "Failed to create ${policydfile}" fi fi fi watchdogdfile=${MNT}/var/state/etc/sicortex/watchdogd.conf mkdir -p ${watchdogdfile%/*} if [ ! -e "${watchdogdfile}" ]; then qecho "Creating ${watchdogdfile} file" if [ -z "${PRETEND}" ]; then if [ -e ${MNT}/etc/sicortex/watchdogd.conf.example ]; then cp ${MNT}/etc/sicortex/watchdogd.conf.example ${watchdogdfile} \ || die "Failed to create ${watchdogdfile}" else touch ${watchdogdfile} \ || die "Failed to create ${watchdogdfile}" fi fi fi # # Version specific hacks # case ${RELEASE} in 3*) vecho "Disabling kernmond in default runlevel" rm -f ${MNT}/etc/runlevels/default/kernmond ;; esac # Unmount everything under ${MNT} SUCCESS=1 cleanup || die 1 "Some unmounts failed" exit 0