2013-04-10 06:18:46 +00:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
|
|
|
# "SystemImager"
|
|
|
|
#
|
|
|
|
# Copyright (C) 1999-2011 Brian Elliott Finley <brian@thefinleys.com>
|
|
|
|
#
|
|
|
|
# $Id: functions 4559 2011-07-05 21:04:36Z finley $
|
|
|
|
# vi: set filetype=sh et ts=4:
|
|
|
|
#
|
|
|
|
# Others who have contributed to this code:
|
|
|
|
# Charles C. Bennett, Jr. <ccb@acm.org>
|
|
|
|
# Sean Dague <japh@us.ibm.com>
|
|
|
|
# Dann Frazier <dannf@dannf.org>
|
|
|
|
# Curtis Zinzilieta <czinzilieta@valinux.com>
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Variables
|
|
|
|
#
|
|
|
|
PATH=/sbin:/bin:/usr/bin:/usr/sbin:/tmp
|
|
|
|
LD_LIBRARY_PATH=/lib
|
|
|
|
SCRIPTS=scripts
|
|
|
|
SCRIPTS_DIR=/scripts
|
|
|
|
TORRENTS=torrents
|
|
|
|
TORRENTS_DIR=/torrents
|
|
|
|
FLAMETHROWER_DIRECTORY_DIR=/var/lib/systemimager/flamethrower
|
|
|
|
BOEL_BINARIES_DIR=/tmp/boel_binaries
|
|
|
|
VERSION="4.3.0"
|
|
|
|
FLAVOR="standard"
|
|
|
|
IMAGESERVER=$XCATMASTER
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
|
|
|
|
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Subroutines
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# logmsg
|
|
|
|
#
|
|
|
|
# Usage: log a message, redirects to console / syslog depending on usage
|
|
|
|
logmsg() {
|
|
|
|
# log to console
|
|
|
|
echo $@
|
|
|
|
# log to temporary file (which will go away when we reboot)
|
|
|
|
# this is good for envs that have bad consoles
|
|
|
|
local FILE=/tmp/si.log
|
|
|
|
echo $@ >> $FILE || shellout
|
|
|
|
|
|
|
|
# if syslog is running, log to it. In order to avoid hangs we have to
|
|
|
|
# add the "logger: " part in case $@ is ""
|
|
|
|
if [ ! -z $USELOGGER ] ;
|
|
|
|
then logger "logger: $@"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# check_version
|
|
|
|
#
|
|
|
|
# Usage: check_version
|
|
|
|
check_version() {
|
|
|
|
logmsg
|
|
|
|
logmsg check_version
|
|
|
|
INITRD_VERSION=$VERSION
|
|
|
|
KERNEL_VERSION=`uname -r | sed -e s/.*boel_v//`
|
|
|
|
if [ "$INITRD_VERSION" != "$KERNEL_VERSION" ] ; then
|
|
|
|
logmsg "FATAL: Kernel version ($KERNEL_VERSION) doesn't match initrd version ($INITRD_VERSION)!"
|
|
|
|
shellout
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# get_arch
|
|
|
|
#
|
|
|
|
# Usage: get_arch; echo $ARCH
|
|
|
|
get_arch() {
|
|
|
|
logmsg
|
|
|
|
logmsg get_arch
|
|
|
|
ARCH=`uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/`
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# adjust_arch
|
|
|
|
#
|
|
|
|
# based on info in /proc adjust the ARCH variable. This needs to run
|
|
|
|
# after proc is mounted.
|
|
|
|
#
|
|
|
|
adjust_arch() {
|
|
|
|
logmsg
|
|
|
|
logmsg adjust_arch
|
|
|
|
if [ "ppc64" = "$ARCH" ] ; then
|
|
|
|
# This takes a little bit of futzing with due to all the PPC platforms that exist.
|
|
|
|
if [ -d /proc/iSeries ] ; then
|
|
|
|
ARCH=ppc64-iSeries
|
|
|
|
logmsg "Detected ppc64 is really an iSeries partition..."
|
|
|
|
fi
|
|
|
|
if grep -qs PS3 /proc/cpuinfo; then
|
|
|
|
ARCH=ppc64-ps3
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# write_variables
|
|
|
|
#
|
|
|
|
# Usage: write_variables
|
|
|
|
write_variables() {
|
|
|
|
|
|
|
|
logmsg
|
|
|
|
logmsg write_variables
|
|
|
|
|
|
|
|
# pass all variables set here on to the hostname.sh script
|
|
|
|
rm -f /tmp/variables.txt
|
|
|
|
|
|
|
|
echo "HOSTNAME=$HOSTNAME" >> /tmp/variables.txt || shellout
|
|
|
|
echo "DOMAINNAME=$DOMAINNAME" >> /tmp/variables.txt
|
|
|
|
|
|
|
|
echo "DEVICE=$DEVICE" >> /tmp/variables.txt
|
|
|
|
echo "IPADDR=$IPADDR" >> /tmp/variables.txt
|
|
|
|
echo "NETMASK=$NETMASK" >> /tmp/variables.txt
|
|
|
|
echo "NETWORK=$NETWORK" >> /tmp/variables.txt
|
|
|
|
echo "BROADCAST=$BROADCAST" >> /tmp/variables.txt
|
|
|
|
|
|
|
|
echo "GATEWAY=$GATEWAY" >> /tmp/variables.txt
|
|
|
|
echo "GATEWAYDEV=$GATEWAYDEV" >> /tmp/variables.txt
|
|
|
|
|
|
|
|
echo "IMAGESERVER=$IMAGESERVER" >> /tmp/variables.txt
|
|
|
|
echo "IMAGENAME=$IMAGENAME" >> /tmp/variables.txt
|
|
|
|
|
|
|
|
echo "LOG_SERVER=$LOG_SERVER" >> /tmp/variables.txt
|
|
|
|
echo "LOG_SERVER_PORT=$LOG_SERVER_PORT" >> /tmp/variables.txt
|
|
|
|
echo "USELOGGER=$USELOGGER" >> /tmp/variables.txt
|
|
|
|
|
|
|
|
echo "TMPFS_STAGING=$TMPFS_STAGING" >> /tmp/variables.txt
|
|
|
|
|
|
|
|
echo "SSH=$SSH" >> /tmp/variables.txt
|
|
|
|
echo "SSHD=$SSHD" >> /tmp/variables.txt
|
|
|
|
echo "SSH_USER=$SSH_USER" >> /tmp/variables.txt
|
|
|
|
echo "SSH_DOWNLOAD_URL=$SSH_DOWNLOAD_URL" >> /tmp/variables.txt
|
|
|
|
|
|
|
|
echo "FLAMETHROWER_DIRECTORY_PORTBASE=$FLAMETHROWER_DIRECTORY_PORTBASE" >> /tmp/variables.txt
|
|
|
|
|
|
|
|
echo "MONITOR_SERVER=$MONITOR_SERVER" >> /tmp/variables.txt
|
|
|
|
echo "MONITOR_PORT=$MONITOR_PORT" >> /tmp/variables.txt
|
|
|
|
echo "MONITOR_CONSOLE=$MONITOR_CONSOLE" >> /tmp/variables.txt
|
|
|
|
|
|
|
|
echo "BITTORRENT=$BITTORRENT" >> /tmp/variables.txt
|
|
|
|
echo "BITTORRENT_STAGING=$BITTORRENT_STAGING" >> /tmp/variables.txt
|
|
|
|
echo "BITTORRENT_POLLING_TIME=$BITTORRENT_POLLING_TIME" >> /tmp/variables.txt
|
|
|
|
echo "BITTORRENT_SEED_WAIT=$BITTORRENT_SEED_WAIT" >> /tmp/variables.txt
|
|
|
|
echo "BITTORRENT_UPLOAD_MIN=$BITTORRENT_UPLOAD_MIN" >> /tmp/variables.txt
|
|
|
|
|
|
|
|
echo "GROUPNAMES=\"$GROUPNAMES\"" >> /tmp/variables.txt
|
|
|
|
echo "GROUP_OVERRIDES=\"$GROUP_OVERRIDES\"" >> /tmp/variables.txt
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Description:
|
|
|
|
# watches the tmpfs filesystem (/) and gives warnings and/or does a shellout
|
|
|
|
#
|
|
|
|
# Usage: tmpfs_watcher
|
|
|
|
#
|
|
|
|
tmpfs_watcher() {
|
|
|
|
|
|
|
|
logmsg
|
|
|
|
logmsg tmpfs_watcher
|
|
|
|
|
|
|
|
# Note: Transfer to staging area can fail if tmpfs runs out of inodes.
|
|
|
|
{
|
|
|
|
while :; do
|
|
|
|
DF=`df -k / | egrep ' /$' | sed -e 's/ */ /g' -e 's/.*[0-9] //' -e 's/%.*//'`
|
|
|
|
[ $DF -ge 95 ] && logmsg "WARNING: Your tmpfs filesystem is ${DF}% full!"
|
|
|
|
[ $DF -ge 99 ] && logmsg " Search the FAQ for tmpfs to learn about sizing options."
|
|
|
|
[ $DF -ge 99 ] && shellout
|
|
|
|
sleep 1
|
|
|
|
done
|
|
|
|
unset DF
|
|
|
|
}&
|
|
|
|
TMPFS_WATCHER_PID=$!
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Description:
|
|
|
|
# Exit with the message stored in /etc/issue.
|
|
|
|
#
|
|
|
|
# Usage: $COMMAND || shellout
|
|
|
|
#
|
|
|
|
shellout() {
|
|
|
|
|
|
|
|
logmsg "Last command exited with $?"
|
|
|
|
COUNT="$RETRY"
|
|
|
|
logmsg "Killing off running processes."
|
|
|
|
kill -9 $TMPFS_WATCHER_PID >/dev/null 2>/dev/null
|
|
|
|
killall -9 udp-receiver rsync >/dev/null 2>/dev/null
|
|
|
|
write_variables
|
|
|
|
cat /etc/issue
|
|
|
|
if [ ! -z $USELOGGER ] ;
|
|
|
|
then cat /etc/issue | logger
|
|
|
|
fi
|
|
|
|
if [ ! -z $MONITOR_SERVER ]; then
|
|
|
|
logmsg "Installation failed!! Stopping report task."
|
|
|
|
stop_report_task -1
|
|
|
|
fi
|
|
|
|
exec sh > /dev/console 2>&1
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Description:
|
|
|
|
# Count the specified number, printing each number, and exit only the count
|
|
|
|
# loop when <ctrl>+<c> is hit (SIGINT, or Signal 2). Thanks to
|
|
|
|
# CCB <ccb@acm.org> for this chunk of code. -BEF-
|
|
|
|
#
|
|
|
|
# Usage:
|
|
|
|
# count_loop 35
|
|
|
|
# count_loop $ETHER_SLEEP
|
|
|
|
#
|
|
|
|
count_loop() {
|
|
|
|
|
|
|
|
COUNT=$1
|
|
|
|
|
|
|
|
trap 'echo ; echo "Skipping ETHER_SLEEP -> Caught <ctrl>+<c>" ; I=$COUNT' INT
|
|
|
|
|
|
|
|
I=0
|
|
|
|
while [ $I -lt $COUNT ]; do
|
|
|
|
I=$(( $I + 1 ))
|
|
|
|
logmsg -n "$I "
|
|
|
|
sleep 1
|
|
|
|
done
|
|
|
|
|
|
|
|
trap INT
|
|
|
|
|
|
|
|
logmsg
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Usage: get_torrents_directory
|
|
|
|
#
|
|
|
|
get_torrents_directory() {
|
|
|
|
if [ ! "x$BITTORRENT" = "xy" ]; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
logmsg
|
|
|
|
logmsg get_torrents_directory
|
|
|
|
|
|
|
|
if [ ! -z $FLAMETHROWER_DIRECTORY_PORTBASE ]; then
|
|
|
|
#
|
|
|
|
# We're using Multicast, so we should already have a directory
|
|
|
|
# full of scripts. Break out here, so that we don't try to pull
|
|
|
|
# the scripts dir again (that would be redundant).
|
|
|
|
#
|
|
|
|
MODULE_NAME="autoinstall_torrents"
|
|
|
|
DIR="${SCRIPTS_DIR}"
|
|
|
|
RETRY=7
|
|
|
|
flamethrower_client
|
|
|
|
|
|
|
|
else
|
|
|
|
mkdir -p ${TORRENTS_DIR}
|
|
|
|
CMD="rsync -a ${IMAGESERVER}::${TORRENTS}/ ${TORRENTS_DIR}/"
|
|
|
|
logmsg "$CMD"
|
|
|
|
$CMD
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Usage: get_scripts_directory
|
|
|
|
#
|
|
|
|
get_scripts_directory() {
|
|
|
|
logmsg
|
|
|
|
logmsg get_scripts_directory
|
|
|
|
|
|
|
|
if [ ! -z $FLAMETHROWER_DIRECTORY_PORTBASE ]; then
|
|
|
|
#
|
|
|
|
# We're using Multicast, so we should already have a directory
|
|
|
|
# full of scripts. Break out here, so that we don't try to pull
|
|
|
|
# the scripts dir again (that would be redundant).
|
|
|
|
#
|
|
|
|
MODULE_NAME="autoinstall_scripts"
|
|
|
|
DIR="${SCRIPTS_DIR}"
|
|
|
|
RETRY=7
|
|
|
|
flamethrower_client
|
|
|
|
|
|
|
|
else
|
|
|
|
mkdir -p ${SCRIPTS_DIR}
|
|
|
|
CMD="rsync -a ${IMAGESERVER}::${SCRIPTS}/ ${SCRIPTS_DIR}/"
|
|
|
|
logmsg "$CMD"
|
|
|
|
$CMD || shellout
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Usage: get_flamethrower_directory
|
|
|
|
#
|
|
|
|
get_flamethrower_directory() {
|
|
|
|
logmsg
|
|
|
|
logmsg Using multicast...
|
|
|
|
logmsg get_flamethrower_directory
|
|
|
|
|
|
|
|
MODULE_NAME=flamethrower_directory
|
|
|
|
DIR=${FLAMETHROWER_DIRECTORY_DIR}
|
|
|
|
RETRY=7
|
|
|
|
PORTBASE=9000
|
|
|
|
flamethrower_client
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Usage:
|
|
|
|
#
|
|
|
|
# MODULE_NAME=my_module # Required
|
|
|
|
# DIR=/my/destination/dir # Required
|
|
|
|
# [RETRY=7] # Optional
|
|
|
|
# [PORTBASE=9000] # Required if a sourceable file called $MODULE_NAME
|
|
|
|
# # doesn't exist
|
|
|
|
# [FLAMETHROWER_TARPIPE] # If not empty, untar received data directly,
|
|
|
|
# # without storing it to a temporary file
|
|
|
|
#
|
|
|
|
# flamethrower_client
|
|
|
|
#
|
|
|
|
flamethrower_client() {
|
|
|
|
|
|
|
|
if [ ! -z $FLAMETHROWER_TARPIPE ]; then
|
|
|
|
FLAMETHROWER_TARPIPE=tarpipe
|
|
|
|
fi
|
|
|
|
logmsg
|
|
|
|
logmsg "flamethrower_client(${MODULE_NAME}) $FLAMETHROWER_TARPIPE "
|
|
|
|
logmsg ---------------------------------------------------------------------
|
|
|
|
|
|
|
|
# validate
|
|
|
|
if [ -z $PORTBASE ]; then
|
|
|
|
if [ -f ${FLAMETHROWER_DIRECTORY_DIR}/${MODULE_NAME} ]; then
|
|
|
|
. ${FLAMETHROWER_DIRECTORY_DIR}/${MODULE_NAME}
|
|
|
|
else
|
|
|
|
logmsg WARNING WARNING WARNING WARNING WARNING
|
|
|
|
logmsg You must either set PORTBASE, or have a sourceable file called
|
|
|
|
logmsg ${FLAMETHROWER_DIRECTORY_DIR}/MODULE_NAME
|
|
|
|
# allow for now to continue until overrides get their modules
|
|
|
|
return
|
|
|
|
#shellout
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
if [ -z $DIR ]; then
|
|
|
|
logmsg "Must set DIR !!!"
|
|
|
|
shellout
|
|
|
|
else
|
|
|
|
mkdir -p $DIR
|
|
|
|
fi
|
|
|
|
|
|
|
|
# build command
|
|
|
|
UDP_RECEIVER_OPTIONS="--interface ${DEVICE} --portbase $PORTBASE --nokbd"
|
|
|
|
if [ ! -z $TTL ]; then
|
|
|
|
UDP_RECEIVER_OPTIONS="$UDP_RECEIVER_OPTIONS --ttl $TTL"
|
|
|
|
fi
|
|
|
|
if [ "$NOSYNC" = "on" ]; then
|
|
|
|
UDP_RECEIVER_OPTIONS="$UDP_RECEIVER_OPTIONS --nosync"
|
|
|
|
fi
|
|
|
|
if [ "$ASYNC" = "on" ]; then
|
|
|
|
UDP_RECEIVER_OPTIONS="$UDP_RECEIVER_OPTIONS --async"
|
|
|
|
fi
|
|
|
|
if [ ! -z $MCAST_ALL_ADDR ]; then
|
|
|
|
UDP_RECEIVER_OPTIONS="$UDP_RECEIVER_OPTIONS --mcast-all-addr $MCAST_ALL_ADDR"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Which tar opts should we use? If our tar has --overwrite capability, use it.
|
|
|
|
# Summary: busybox tar doesn't (boel_binaries and prior).
|
|
|
|
# Debian patched gnu tar does (image and on).
|
|
|
|
# We want this option enabled for the image to ensure proper directory
|
|
|
|
# permissions. -BEF-
|
|
|
|
tar --help 2>&1 | grep -q overwrite && TAR_OPTS='--overwrite -xp' || TAR_OPTS='-x'
|
|
|
|
|
|
|
|
# set vars
|
|
|
|
[ -z $RETRY ] && RETRY=0
|
|
|
|
COUNT=0
|
|
|
|
FLAMETHROWER_CLIENT_SLEEP=3
|
|
|
|
|
|
|
|
# it's the new new style (loop)
|
|
|
|
SUCCESS="Not Yet"
|
|
|
|
until [ "$SUCCESS" = "yes" ]
|
|
|
|
do
|
|
|
|
# receive cast
|
|
|
|
# example udp-receiver command:
|
|
|
|
# udp-receiver --interface lo --portbase 9002 --nokbd --nosync --file /tmp/multicast.tar
|
|
|
|
|
|
|
|
if [ ! -z $FLAMETHROWER_TARPIPE ]; then
|
|
|
|
TAR_OPTS="$TAR_OPTS -f -"
|
|
|
|
logmsg "udp-receiver $UDP_RECEIVER_OPTIONS | tar $TAR_OPTS -C $DIR"
|
|
|
|
udp-receiver $UDP_RECEIVER_OPTIONS | tar $TAR_OPTS -C $DIR
|
|
|
|
TAR_EXIT_STATUS=$?
|
|
|
|
UDP_RECEIVER_EXIT_STATUS=0
|
|
|
|
else
|
|
|
|
logmsg udp-receiver $UDP_RECEIVER_OPTIONS --file /tmp/multicast.tar
|
|
|
|
udp-receiver $UDP_RECEIVER_OPTIONS --file /tmp/multicast.tar
|
|
|
|
UDP_RECEIVER_EXIT_STATUS=$?
|
|
|
|
|
|
|
|
# untar it
|
|
|
|
if [ "$UDP_RECEIVER_EXIT_STATUS" = "0" ]; then
|
|
|
|
logmsg tar ${TAR_OPTS} -f /tmp/multicast.tar -C ${DIR}
|
|
|
|
tar ${TAR_OPTS} -f /tmp/multicast.tar -C ${DIR}
|
|
|
|
TAR_EXIT_STATUS=$?
|
|
|
|
fi
|
|
|
|
# discard used tarball like an old sock (recommended by: Ramon Bastiaans <bastiaans@sara.nl>)
|
|
|
|
rm -f /tmp/multicast.tar
|
|
|
|
fi
|
|
|
|
|
|
|
|
# did everything work properly
|
|
|
|
if [ $UDP_RECEIVER_EXIT_STATUS -eq 0 ] && [ $TAR_EXIT_STATUS -eq 0 ]; then
|
|
|
|
SUCCESS=yes
|
|
|
|
else
|
|
|
|
if [ $COUNT -lt $RETRY ]; then
|
|
|
|
COUNT=$(( $COUNT + 1 ))
|
|
|
|
logmsg "flamethrower_client: Proceeding with retry $COUNT of $RETRY"
|
|
|
|
else
|
|
|
|
logmsg
|
|
|
|
logmsg "flamethrower_client: FATAL: Initial attempt and $RETRY retries failed!"
|
|
|
|
shellout
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
# sleep apnea
|
|
|
|
sleep_loop $FLAMETHROWER_CLIENT_SLEEP
|
|
|
|
done
|
|
|
|
|
|
|
|
# done
|
|
|
|
logmsg 'finished!'
|
|
|
|
logmsg
|
|
|
|
|
|
|
|
# Unset vars, so next module (which may not have them set) won't use then unintentially
|
|
|
|
unset TTL
|
|
|
|
unset NOSYNC
|
|
|
|
unset ASYNC
|
|
|
|
unset MCAST_ALL_ADDR
|
|
|
|
unset RETRY
|
|
|
|
unset COUNT
|
|
|
|
unset DIR
|
|
|
|
unset PORTBASE
|
|
|
|
unset UDP_RECEIVER_EXIT_STATUS
|
|
|
|
unset UDP_RECEIVER_OPTIONS
|
|
|
|
unset TAR_EXIT_STATUS
|
|
|
|
unset TAR_OPTS
|
|
|
|
unset SUCCESS
|
|
|
|
unset FLAMETHROWER_TARPIPE
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Autodetect a staging directory for the bittorrent tarball
|
|
|
|
#
|
|
|
|
# Usage: bittorrent_autodetect_staging_dir torrent
|
|
|
|
#
|
|
|
|
bittorrent_autodetect_staging_dir() {
|
|
|
|
torrent=$1
|
|
|
|
if [ ! -f $torrent ]; then
|
|
|
|
logmsg "warning: torrent file $torrent does not exist!"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
# List of preferred staging directory (/tmp = ramdisk staging)
|
|
|
|
preferred_dirs="/tmp /a/tmp `df 2>/dev/null | sed '1d' | sed 's/[[:space:]]\+/ /g' | cut -d' ' -f6`"
|
|
|
|
|
|
|
|
# Use a breathing room of 100MB (this should be enough for a lot of cases)
|
|
|
|
breathing_room=102400
|
|
|
|
|
|
|
|
# Evaluate torrent size
|
|
|
|
torrent_size=$((`/bin/torrentinfo-console $torrent | sed -ne 's/^file size\.*: \([0-9]\+\).*$/\1/p'` / 1024 + $breathing_room))
|
|
|
|
|
|
|
|
# Find a directory to host the image tarball
|
|
|
|
for dir in $preferred_dirs; do
|
|
|
|
[ ! -d $dir ] && continue;
|
|
|
|
dir_space=`df $dir 2>/dev/null | sed '1d' | sed 's/[[:space:]]\+/ /g' | cut -d' ' -f4 | sed -ne '$p'`
|
|
|
|
[ -z $dir_space ] && continue
|
|
|
|
[ $torrent_size -lt $dir_space ] && echo $dir && return
|
|
|
|
done
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Download a file using bittorrent.
|
|
|
|
#
|
|
|
|
# Usage: bittorrent_get_file torrent destination
|
|
|
|
#
|
|
|
|
bittorrent_get_file() {
|
|
|
|
torrent=$1
|
|
|
|
destination=$2
|
|
|
|
|
|
|
|
# Bittorrent log file
|
|
|
|
bittorrent_log=/tmp/bittorrent-`basename ${torrent}`.log
|
|
|
|
# Time to poll bittorrent events
|
|
|
|
bittorrent_polling_time=${BITTORRENT_POLLING_TIME:-5}
|
|
|
|
# Wait after the download is finished to seed the other peers
|
|
|
|
bittorrent_seed_wait=${BITTORRENT_SEED_WAIT:-n}
|
|
|
|
# Minimum upload rate threshold (in KB/s), if lesser stop seeding
|
|
|
|
bittorrent_upload_min=${BITTORRENT_UPLOAD_MIN:-50}
|
|
|
|
|
|
|
|
# Start downloading.
|
|
|
|
/bin/bittorrent-console --no_upnp --no_start_trackerless_client --max_upload_rate 0 --display_interval 1 --rerequest_interval 1 --bind ${IPADDR} --save_in ${destination} ${torrent} > $bittorrent_log &
|
|
|
|
pid=$!
|
|
|
|
if [ ! -d /proc/$pid ]; then
|
|
|
|
logmsg "error: couldn't run bittorrent-console!"
|
|
|
|
shellout
|
|
|
|
fi
|
|
|
|
unset pid
|
|
|
|
|
|
|
|
# Wait for BitTorrent log to appear.
|
|
|
|
while [ ! -e $bittorrent_log ]; do
|
|
|
|
sleep 1
|
|
|
|
done
|
|
|
|
|
|
|
|
# Checking download...
|
|
|
|
while :; do
|
|
|
|
while :; do
|
|
|
|
status=`grep 'percent done:' $bittorrent_log | sed -ne '$p' | sed 's/percent done: *//' | sed -ne '/^[0-9]*\.[0-9]*$/p'`
|
|
|
|
[ ! -z "$status" ] && break
|
|
|
|
done
|
|
|
|
logmsg "percent done: $status %"
|
|
|
|
if [ "$status" = "100.0" ]; then
|
|
|
|
# Sleep until upload rate reaches the minimum threshold
|
|
|
|
while [ "$bittorrent_seed_wait" = "y" ]; do
|
|
|
|
sleep $bittorrent_polling_time
|
|
|
|
while :; do
|
|
|
|
upload_rate=`grep 'upload rate:' $bittorrent_log | sed -ne '$p' | sed 's/upload rate: *\([0-9]*\)\.[0-9]* .*$/\1/' | sed -ne '/^\([0-9]*\)$/p'`
|
|
|
|
[ ! -z $upload_rate ] && break
|
|
|
|
done
|
|
|
|
logmsg "upload rate: $upload_rate KB/s"
|
|
|
|
[ $upload_rate -lt $bittorrent_upload_min ] && break
|
|
|
|
done
|
|
|
|
logmsg "Download completed"
|
|
|
|
unset bittorrent_log upload_rate counter
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
sleep $bittorrent_polling_time
|
|
|
|
done
|
|
|
|
|
|
|
|
unset bittorrent_polling_time
|
|
|
|
unset bittorrent_seed_wait
|
|
|
|
unset bittorrent_upload_min
|
|
|
|
unset torrent
|
|
|
|
unset destination
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Stop bittorrent client.
|
|
|
|
#
|
|
|
|
# Usage: bittorrent_stop
|
|
|
|
#
|
|
|
|
bittorrent_stop() {
|
|
|
|
# Try to kill all the BitTorrent processes
|
|
|
|
btclient="bittorrent-console"
|
|
|
|
|
|
|
|
logmsg "killing BitTorrent client..."
|
|
|
|
killall -15 $btclient >/dev/null 2>&1
|
|
|
|
|
|
|
|
# Forced kill after 5 secs.
|
|
|
|
sleep 5
|
|
|
|
killall -9 $btclient >/dev/null 2>&1
|
|
|
|
|
|
|
|
# Remove bittorrent logs.
|
|
|
|
rm -rf /tmp/bittorrent*.log
|
|
|
|
unset btclient
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Get other binaries, kernel module tree, and miscellaneous other stuff that
|
|
|
|
# got put in the binaries tarball. -BEF-
|
|
|
|
#
|
|
|
|
get_boel_binaries_tarball() {
|
|
|
|
|
|
|
|
logmsg
|
|
|
|
logmsg get_boel_binaries_tarball
|
|
|
|
# mkdir -p ${BOEL_BINARIES_DIR}
|
|
|
|
#
|
|
|
|
# if [ ! -z $SSH_DOWNLOAD_URL ]; then
|
|
|
|
# # If we're using SSH, get the boel_binaries from a web server.
|
|
|
|
# logmsg "SSH_DOWNLOAD_URL variable is set, so we will install over SSH!"
|
|
|
|
#
|
|
|
|
# if [ ! -z $FLAMETHROWER_DIRECTORY_PORTBASE ]; then
|
|
|
|
# logmsg "FLAMETHROWER_DIRECTORY_PORTBASE is also set, but I will be conservative and proceed with SSH."
|
|
|
|
# fi
|
|
|
|
#
|
|
|
|
# # Remove possible trailing / from URL
|
|
|
|
# SSH_DOWNLOAD_URL=`echo $SSH_DOWNLOAD_URL | sed 's/\/$//'`
|
|
|
|
#
|
|
|
|
# cd ${BOEL_BINARIES_DIR}
|
|
|
|
# CMD="wget ${SSH_DOWNLOAD_URL}/${ARCH}/${FLAVOR}/boel_binaries.tar.gz"
|
|
|
|
# logmsg "$CMD"
|
|
|
|
# $CMD || shellout
|
|
|
|
#
|
|
|
|
# elif [ "x$BITTORRENT" = "xy" ]; then
|
|
|
|
#
|
|
|
|
# # Download BOEL binaries from peers
|
|
|
|
# bittorrent_tarball="boel_binaries.tar.gz"
|
|
|
|
# logmsg "Start downloading ${bittorrent_tarball} (${ARCH}) using bittorrent"
|
|
|
|
# logmsg ""
|
|
|
|
# logmsg "--> INFO: remember to start /etc/init.d/systemimager-server-bittorrent on the image server!"
|
|
|
|
# logmsg ""
|
|
|
|
# bittorrent_get_file ${TORRENTS_DIR}/${ARCH}-${bittorrent_tarball}.torrent ${BOEL_BINARIES_DIR}
|
|
|
|
# cd ${BOEL_BINARIES_DIR} && mv ${ARCH}-${bittorrent_tarball} ${bittorrent_tarball}
|
|
|
|
# unset bittorrent_tarball
|
|
|
|
#
|
|
|
|
# elif [ ! -z $FLAMETHROWER_DIRECTORY_PORTBASE ]; then
|
|
|
|
#
|
|
|
|
# MODULE_NAME="boot-${ARCH}-${FLAVOR}"
|
|
|
|
# DIR="${BOEL_BINARIES_DIR}"
|
|
|
|
# RETRY=7
|
|
|
|
# flamethrower_client
|
|
|
|
#
|
|
|
|
# else
|
|
|
|
# # Use rsync
|
|
|
|
# CMD="rsync -av ${IMAGESERVER}::boot/${ARCH}/${FLAVOR}/boel_binaries.tar.gz ${BOEL_BINARIES_DIR}"
|
|
|
|
# logmsg "$CMD"
|
|
|
|
# $CMD || shellout
|
|
|
|
# fi
|
|
|
|
#
|
|
|
|
# # Untar the tarball
|
|
|
|
# tar -C / -xzf ${BOEL_BINARIES_DIR}/boel_binaries.tar.gz || shellout
|
|
|
|
# chown -R 0.0 /lib/modules || shellout
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Parse tmpfs options from /proc/cpuinfo
|
|
|
|
#
|
|
|
|
parse_tmpfs_opts() {
|
|
|
|
logmsg
|
|
|
|
logmsg parse_tmpfs_opts
|
|
|
|
tmpfs_size=$(tr ' ' '\n' < /proc/cmdline | grep tmpfs_size\= | sed 's/.*=//')
|
|
|
|
tmpfs_nr_blocks=$(tr ' ' '\n' < /proc/cmdline | grep tmpfs_nr_blocks\= | sed 's/.*=//')
|
|
|
|
tmpfs_nr_inodes=$(tr ' ' '\n' < /proc/cmdline | grep tmpfs_nr_inodes\= | sed 's/.*=//')
|
|
|
|
tmpfs_mode=$(tr ' ' '\n' < /proc/cmdline | grep tmpfs_mode\= | sed 's/.*=//')
|
|
|
|
|
|
|
|
if [ "$tmpfs_size" != "" ]; then
|
|
|
|
tmpfs_opts="size=$tmpfs_size"
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ "$tmpfs_nr_blocks" != "" ]; then
|
|
|
|
if [ "$tmpfs_opts" != "" ]; then
|
|
|
|
tmpfs_opts="${tmpfs_opts},nr_blocks=$tmpfs_nr_blocks"
|
|
|
|
else
|
|
|
|
tmpfs_opts="nr_blocks=$tmpfs_nr_blocks"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ "$tmpfs_nr_inodes" != "" ]; then
|
|
|
|
if [ "$tmpfs_opts" != "" ]; then
|
|
|
|
tmpfs_opts="${tmpfs_opts},nr_inodes=$tmpfs_nr_inodes"
|
|
|
|
else
|
|
|
|
tmpfs_opts="nr_inodes=$tmpfs_nr_inodes"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ "$tmpfs_mode" != "" ]; then
|
|
|
|
if [ "$tmpfs_opts" != "" ]; then
|
|
|
|
tmpfs_opts="${tmpfs_opts},mode=$tmpfs_mode"
|
|
|
|
else
|
|
|
|
tmpfs_opts="mode=$tmpfs_mode"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ "$tmpfs_opts" != "" ]; then
|
|
|
|
tmpfs_opts="-o $tmpfs_opts"
|
|
|
|
fi
|
|
|
|
|
|
|
|
unset tmpfs_size
|
|
|
|
unset tmpfs_nr_blocks
|
|
|
|
unset tmpfs_nr_inodes
|
|
|
|
unset tmpfs_mode
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Switch root to tmpfs
|
|
|
|
#
|
|
|
|
#switch_root_to_tmpfs() {
|
|
|
|
# local MODULE=tmpfs
|
|
|
|
# logmsg
|
|
|
|
# logmsg switch_root_to_tmpfs
|
|
|
|
# logmsg "Loading $MODULE... "
|
|
|
|
# modprobe $MODULE 2>/dev/null && logmsg "done!" || logmsg "Didn't load -- assuming it's built into the kernel."
|
|
|
|
# parse_tmpfs_opts
|
|
|
|
#
|
|
|
|
# # Switch root over to tmpfs so we don't have to worry about the size of
|
|
|
|
# # the tarball and binaries that users may decide to copy over. -BEF-
|
|
|
|
# if [ -d /old_root ]; then
|
|
|
|
# logmsg
|
|
|
|
# logmsg "already switched to tmpfs..."
|
|
|
|
# else
|
|
|
|
# logmsg
|
|
|
|
# logmsg "switching root to tmpfs..."
|
|
|
|
#
|
|
|
|
# mkdir -p /new_root || shellout
|
|
|
|
# mount tmpfs /new_root -t tmpfs $tmpfs_opts || shellout
|
|
|
|
#
|
|
|
|
# cd / || shellout
|
|
|
|
# cp -a `/bin/ls | grep -v -E '^(new_root|dev)$'` /new_root/ || shellout
|
|
|
|
#
|
|
|
|
# mkdir -p /new_root/dev || shellout
|
|
|
|
# mount -t devtmpfs -o mode=0755 none /new_root/dev || shellout
|
|
|
|
#
|
|
|
|
# cd /new_root || shellout
|
|
|
|
# mkdir -p old_root || shellout
|
|
|
|
# pivot_root . old_root || switch_root
|
|
|
|
# fi
|
|
|
|
#
|
|
|
|
# unset tmpfs_opts
|
|
|
|
#}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
mount_initial_filesystems() {
|
|
|
|
|
|
|
|
# Much of this taken from "init" from an Ubuntu Lucid initrd.img
|
|
|
|
logmsg
|
|
|
|
logmsg mount_initial_filesystems
|
|
|
|
|
|
|
|
[ -d /dev ] || mkdir -m 0755 /dev
|
|
|
|
[ -d /root ] || mkdir -m 0700 /root
|
|
|
|
[ -d /sys ] || mkdir /sys
|
|
|
|
[ -d /proc ] || mkdir /proc
|
|
|
|
[ -d /tmp ] || mkdir /tmp
|
|
|
|
|
|
|
|
mkdir -p /var/lock
|
|
|
|
|
|
|
|
mount -t sysfs -o nodev,noexec,nosuid none /sys
|
|
|
|
mount -t proc -o nodev,noexec,nosuid none /proc
|
|
|
|
|
|
|
|
# Note that this only becomes /dev on the real filesystem if udev's scripts
|
|
|
|
# are used; which they will be, but it's worth pointing out
|
|
|
|
if ! mount -t devtmpfs -o mode=0755 none /dev; then
|
|
|
|
mount -t tmpfs -o mode=0755 none /dev
|
|
|
|
mknod -m 0600 /dev/console c 5 1
|
|
|
|
mknod -m 0666 /dev/null c 1 3
|
|
|
|
mknod -m 0660 /dev/kmsg c 1 11
|
|
|
|
fi
|
|
|
|
|
|
|
|
mkdir /dev/pts
|
|
|
|
mount -t devpts -o noexec,nosuid,gid=5,mode=0620 none /dev/pts || true
|
|
|
|
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
monitor_save_dmesg() {
|
|
|
|
if [ -z $MONITOR_SERVER ]; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
logmsg
|
|
|
|
logmsg monitor_save_dmesg
|
|
|
|
dmesg -s 16392 > /tmp/si_monitor.log
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
start_udevd() {
|
|
|
|
logmsg
|
|
|
|
logmsg start_udevd
|
|
|
|
echo -n " "
|
|
|
|
/etc/init.d/udev start
|
|
|
|
|
|
|
|
# If udev failed fall back to a static /dev
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
logmsg "failed!"
|
|
|
|
#XXX -delete me -BEF- - logmsg "Creating a static /dev..."
|
|
|
|
# cd / && tar -xzf dev.tar.gz || shellout
|
|
|
|
logmsg done
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Configure loopback interface (may as well)
|
|
|
|
ifconfig_loopback() {
|
|
|
|
logmsg
|
|
|
|
logmsg ifconfig_loopback
|
|
|
|
ifconfig lo 127.0.0.1
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Load any modules that were placed in the my_modules directory prior to
|
|
|
|
# running "make initrd.gz". -BEF-
|
|
|
|
load_my_modules() {
|
|
|
|
logmsg
|
|
|
|
logmsg load_my_modules
|
|
|
|
cd /my_modules || shellout
|
|
|
|
sh ./INSMOD_COMMANDS
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# read in varibles obtained from kernel appends
|
|
|
|
#
|
|
|
|
read_kernel_append_parameters() {
|
|
|
|
logmsg
|
|
|
|
logmsg read_kernel_append_parameters
|
|
|
|
|
|
|
|
. /tmp/kernel_append_parameter_variables.txt
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Variable-ize /proc/cmdline arguments
|
|
|
|
#
|
|
|
|
variableize_kernel_append_parameters() {
|
|
|
|
logmsg
|
|
|
|
logmsg variableize_kernel_append_parameters
|
|
|
|
cat /proc/cmdline | tr ' ' '\n' | grep '=' > /tmp/kernel_append_parameter_variables.txt
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Look for local.cfg file
|
|
|
|
# This code inspired by Ian McLeod <ian@valinux.com>
|
|
|
|
#
|
|
|
|
read_local_cfg() {
|
|
|
|
logmsg
|
|
|
|
logmsg read_local_cfg
|
|
|
|
|
|
|
|
if [ "x$SKIP_LOCAL_CFG" = "xy" ]; then
|
|
|
|
logmsg "Skipping local.cfg: option SKIP_LOCAL_CFG=y has been specified"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Try with local.cfg directly from initrd.
|
|
|
|
if [ -f /local.cfg ]; then
|
|
|
|
cp -f /local.cfg /tmp/local.cfg
|
|
|
|
fi
|
|
|
|
|
|
|
|
#
|
|
|
|
# BEGIN try hard drive
|
|
|
|
#
|
|
|
|
if [ ! -z "$LAST_ROOT" ]; then
|
|
|
|
|
|
|
|
logmsg
|
|
|
|
logmsg "Checking for /local.cfg file on hard drive..."
|
|
|
|
mkdir /last_root
|
|
|
|
logmsg "Mounting hard drive..."
|
|
|
|
mount $LAST_ROOT /last_root -o ro > /dev/null 2>&1
|
|
|
|
if [ $? != 0 ]; then
|
|
|
|
logmsg "FATAL: Couldn't mount hard drive!"
|
|
|
|
logmsg "Your kernel must have all necessary block and filesystem drivers compiled in"
|
|
|
|
logmsg "statically (not modules) in order to use a local.cfg on your hard drive. The"
|
|
|
|
logmsg "standard SystemImager kernel is modular, so you will need to compile your own"
|
|
|
|
logmsg "kernel. See the SystemImager documentation for details. To proceed at this"
|
|
|
|
logmsg "point, you will need to unset the LAST_ROOT append parameter by typing"
|
|
|
|
logmsg ""systemimager LAST_ROOT=", or similar, at your boot prompt. This will not use"
|
|
|
|
logmsg "the local.cfg file on your hard drive, but will still use one on a floppy."
|
|
|
|
shellout
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -f /last_root/local.cfg ]; then
|
|
|
|
logmsg "Found /local.cfg on hard drive."
|
|
|
|
logmsg "Copying /local.cfg settings to /tmp/local.cfg."
|
|
|
|
cat /last_root/local.cfg >> /tmp/local.cfg || shellout
|
|
|
|
else
|
|
|
|
logmsg "No /local.cfg on hard drive."
|
|
|
|
fi
|
|
|
|
logmsg "Unmounting hard drive..."
|
|
|
|
umount /last_root || shellout
|
|
|
|
logmsg
|
|
|
|
fi
|
|
|
|
# END try hard drive
|
|
|
|
|
|
|
|
### BEGIN try floppy ###
|
|
|
|
logmsg "Checking for floppy diskette."
|
|
|
|
logmsg 'YOU MAY SEE SOME "wrong magic" ERRORS HERE, AND THAT IS NORMAL.'
|
|
|
|
mkdir -p /floppy
|
|
|
|
mount /dev/fd0 /floppy -o ro > /dev/null 2>&1
|
|
|
|
if [ $? = 0 ]; then
|
|
|
|
logmsg "Found floppy diskette."
|
|
|
|
if [ -f /floppy/local.cfg ]; then
|
|
|
|
logmsg "Found /local.cfg on floppy."
|
|
|
|
logmsg "Copying /local.cfg settings to /tmp/local.cfg."
|
|
|
|
logmsg "NOTE: local.cfg settings from a floppy will override settings from"
|
|
|
|
logmsg " a local.cfg file on your hard drive and DHCP."
|
|
|
|
# We use cat instead of copy, so that floppy settings can
|
|
|
|
# override hard disk settings. -BEF-
|
|
|
|
cat /floppy/local.cfg >> /tmp/local.cfg || shellout
|
|
|
|
else
|
|
|
|
logmsg "No /local.cfg on floppy diskette."
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
logmsg "No floppy diskette in drive."
|
|
|
|
fi
|
|
|
|
### END try floppy ###
|
|
|
|
|
|
|
|
# /tmp/local.cfg may be created from a local.cfg file on the hard drive, or a
|
|
|
|
# floppy. If both are used, settings on the floppy take precedence. -BEF-
|
|
|
|
if [ -f /tmp/local.cfg ]; then
|
|
|
|
logmsg "Reading configuration from /tmp/local.cfg"
|
|
|
|
. /tmp/local.cfg || shellout
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Configure network interface using local.cfg settings if possible, else
|
|
|
|
# use DHCP. -BEF-
|
|
|
|
#
|
|
|
|
start_network() {
|
|
|
|
logmsg
|
|
|
|
logmsg start_network
|
|
|
|
if [ ! -z $IPADDR ]; then
|
|
|
|
|
|
|
|
# configure interface and add default gateway
|
|
|
|
ifconfig $DEVICE $IPADDR netmask $NETMASK broadcast $BROADCAST
|
|
|
|
if [ $? != 0 ]; then
|
|
|
|
logmsg
|
|
|
|
logmsg "I couldn't configure the network interface using your pre-boot settings:"
|
|
|
|
logmsg " DEVICE: $DEVICE"
|
|
|
|
logmsg " IPADDR: $IPADDR"
|
|
|
|
logmsg " NETMASK: $NETMASK"
|
|
|
|
logmsg " BROADCAST: $BROADCAST"
|
|
|
|
logmsg
|
|
|
|
shellout
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ ! -z $GATEWAY ]; then
|
|
|
|
route add default gw $GATEWAY
|
|
|
|
if [ $? != 0 ]; then
|
|
|
|
logmsg
|
|
|
|
logmsg "The command \"route add default gw $GATEWAY\" failed."
|
|
|
|
logmsg "Check your pre-boot network settings."
|
|
|
|
logmsg
|
|
|
|
shellout
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
### try dhcp ###
|
|
|
|
logmsg "IP Address not set with pre-boot settings."
|
|
|
|
|
|
|
|
### BEGIN ether sleep ###
|
|
|
|
# Give the switch time to start passing packets. Some switches won't
|
|
|
|
# forward packets until 30 seconds or so after an interface comes up.
|
|
|
|
# This means the dhcp server won't even get the request for 30 seconds.
|
|
|
|
# Many ethernet cards aren't considered "up" by the switch until the
|
|
|
|
# driver is loaded. Because the driver is compiled directly into the
|
|
|
|
# kernel here, the driver is definitely loaded at this point.
|
|
|
|
#
|
|
|
|
# Default is 0. The recommended setting of ETHER_SLEEP=35 can be set
|
|
|
|
# with a local.cfg file. -BEF-
|
|
|
|
#
|
|
|
|
[ -z $ETHER_SLEEP ] && ETHER_SLEEP=0
|
|
|
|
logmsg
|
|
|
|
logmsg "sleep $ETHER_SLEEP: This is to give your switch (if you're using one) time to"
|
|
|
|
logmsg " recognize your ethernet card before we try the network."
|
|
|
|
logmsg " Tip: You can use <ctrl>+<c> to pass the time (pun intended)."
|
|
|
|
logmsg
|
|
|
|
count_loop $ETHER_SLEEP
|
|
|
|
logmsg
|
|
|
|
### END ether sleep ###
|
|
|
|
|
|
|
|
# create directory to catch dhcp information
|
|
|
|
DHCLIENT_DIR="/var/state/dhcp"
|
|
|
|
mkdir -p $DHCLIENT_DIR
|
|
|
|
|
|
|
|
# combine systemimager code to the stock debian dhclient-script
|
|
|
|
# and make executable
|
|
|
|
cat /etc/dhclient-script.si-prefix \
|
|
|
|
/etc/dhclient-script.debian-dist \
|
|
|
|
> /etc/dhclient-script
|
|
|
|
chmod +x /etc/dhclient-script
|
|
|
|
|
|
|
|
# be sure AF_PACKET is supported in the kernel
|
|
|
|
[ -f /lib/modules/`uname -r`/modules.dep ] && modprobe af_packet &> /dev/null
|
|
|
|
|
|
|
|
# get info via dhcp
|
|
|
|
logmsg
|
|
|
|
logmsg "dhclient"
|
|
|
|
dhclient $DEVICE
|
|
|
|
if [ ! -s ${DHCLIENT_DIR}/dhclient.leases ]; then
|
|
|
|
logmsg
|
|
|
|
logmsg "I couldn't configure the network interface using DHCP."
|
|
|
|
logmsg
|
|
|
|
shellout
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -z ${DEVICE} ]; then
|
|
|
|
# Figure out which interface actually got configured.
|
|
|
|
# Suggested by James Oakley.
|
|
|
|
#
|
|
|
|
DEVICE=`grep interface ${DHCLIENT_DIR}/dhclient.leases | \
|
|
|
|
sed -e 's/^.*interface "//' -e 's/";//'`
|
|
|
|
fi
|
|
|
|
|
|
|
|
# read dhcp info in as variables -- this file will be created by
|
|
|
|
# the /etc/dhclient-start script that is run automatically by
|
|
|
|
# dhclient.
|
|
|
|
. /tmp/dhcp_info.${DEVICE} || shellout
|
|
|
|
### END dhcp ###
|
|
|
|
|
|
|
|
# Re-read configuration information from local.cfg to over-ride
|
|
|
|
# DHCP settings, if necessary. -BEF-
|
|
|
|
if [ -f /tmp/local.cfg ]; then
|
|
|
|
logmsg
|
|
|
|
logmsg "Overriding any DHCP settings with pre-boot local.cfg settings."
|
|
|
|
. /tmp/local.cfg || shellout
|
|
|
|
fi
|
|
|
|
|
|
|
|
logmsg
|
|
|
|
logmsg "Overriding any DHCP settings with pre-boot settings from kernel append"
|
|
|
|
logmsg "parameters."
|
|
|
|
read_kernel_append_parameters
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Ping test
|
|
|
|
ping_test() {
|
|
|
|
logmsg
|
|
|
|
logmsg ping_test
|
|
|
|
|
|
|
|
# The reason we don't ping the IMAGESERVER if FLAMETHROWER_DIRECTORY_PORTBASE
|
|
|
|
# is set, is that the client may never be given, know, or need to know, the
|
|
|
|
# IP address of the imageserver because the client is receiving _all_ of it's
|
|
|
|
# data via multicast, which is more like listening to a channel, as compared
|
|
|
|
# with connecting directly to a server. -BEF-
|
|
|
|
#
|
|
|
|
if [ ! -z "$FLAMETHROWER_DIRECTORY_PORTBASE" ]; then
|
|
|
|
PING_DESTINATION=$GATEWAY
|
|
|
|
HOST_TYPE="default gateway"
|
|
|
|
else
|
|
|
|
PING_DESTINATION=$IMAGESERVER
|
|
|
|
HOST_TYPE="SystemImager server"
|
|
|
|
fi
|
|
|
|
logmsg
|
|
|
|
logmsg "Pinging your $HOST_TYPE to ensure we have network connectivity."
|
|
|
|
logmsg
|
|
|
|
|
|
|
|
|
|
|
|
# Ping test code submitted by Grant Noruschat <grant@eigen.ee.ualberta.ca>
|
|
|
|
# modified slightly by Brian Finley.
|
|
|
|
PING_COUNT=1
|
|
|
|
PING_EXIT_STATUS=1
|
|
|
|
while [ "$PING_EXIT_STATUS" != "0" ]
|
|
|
|
do
|
|
|
|
logmsg "PING ATTEMPT $PING_COUNT: "
|
|
|
|
ping -c 1 $PING_DESTINATION
|
|
|
|
PING_EXIT_STATUS=$?
|
|
|
|
|
|
|
|
if [ "$PING_EXIT_STATUS" = "0" ]; then
|
|
|
|
logmsg
|
|
|
|
logmsg " We have connectivity to your $HOST_TYPE!"
|
|
|
|
fi
|
|
|
|
|
|
|
|
PING_COUNT=$(( $PING_COUNT + 1 ))
|
|
|
|
if [ "$PING_COUNT" = "4" ]; then
|
|
|
|
logmsg
|
|
|
|
logmsg " WARNING: Failed ping test."
|
|
|
|
logmsg " Despite this seemingly depressing result, I will attempt"
|
|
|
|
logmsg " to proceed with the install. Your $HOST_TYPE may be"
|
|
|
|
logmsg " configured to not respond to pings, but it wouldn't hurt"
|
|
|
|
logmsg " to double check that your networking equipment is"
|
|
|
|
logmsg " working properly!"
|
|
|
|
logmsg
|
|
|
|
sleep 5
|
|
|
|
PING_EXIT_STATUS=0
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
unset PING_DESTINATION
|
|
|
|
unset HOST_TYPE
|
|
|
|
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
start_syslogd() {
|
|
|
|
logmsg
|
|
|
|
logmsg start_syslogd
|
|
|
|
if [ ! -z $LOG_SERVER ]; then
|
|
|
|
logmsg "Starting syslogd..."
|
|
|
|
[ -z $LOG_SERVER_PORT ] && LOG_SERVER_PORT="514"
|
|
|
|
syslogd -R ${LOG_SERVER}:${LOG_SERVER_PORT}
|
|
|
|
# as long as we are starting syslogd, start klogd as well, in case
|
|
|
|
# there is a kernel issue that happens
|
|
|
|
klogd
|
|
|
|
# set USELOGGER=1 so logmsg knows to do the right thing
|
|
|
|
USELOGGER=1
|
|
|
|
logmsg "Successfully started syslogd!"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
show_loaded_modules() {
|
|
|
|
# Show loaded modules
|
|
|
|
logmsg ">> Loaded kernel modules:"
|
|
|
|
for m in `cut -d' ' -f1 /proc/modules`; do
|
|
|
|
logmsg "$m"
|
|
|
|
done
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
get_hostname_by_hosts_file() {
|
|
|
|
|
|
|
|
logmsg
|
|
|
|
logmsg get_hostname_by_hosts_file
|
|
|
|
|
|
|
|
#
|
|
|
|
# Look in $FILE for that magic joy.
|
|
|
|
#
|
|
|
|
FILE=${SCRIPTS_DIR}/hosts
|
|
|
|
if [ -e $FILE ]; then
|
|
|
|
|
|
|
|
logmsg "Hosts file exists..."
|
|
|
|
|
|
|
|
# add escape characters to IPADDR so that it can be used to find HOSTNAME below
|
|
|
|
IPADDR_ESCAPED=`echo "$IPADDR" | sed -e 's/\./\\\./g'`
|
|
|
|
|
|
|
|
# get HOSTNAME by parsing hosts file
|
|
|
|
logmsg "Searching for this machine's hostname in $FILE by IP: $IPADDR"
|
|
|
|
|
|
|
|
# Command summary by line:
|
|
|
|
# 1: convert tabs to spaces -- contains a literal tab: <ctrl>+<v> then <tab>
|
|
|
|
# 2: remove comments
|
|
|
|
# 3: add a space at the beginning of every line
|
|
|
|
# 4: get line with IP address (no more no less)
|
|
|
|
# 5: strip out ip address
|
|
|
|
# 6: strip out space(s) before first hostname on line
|
|
|
|
# 7: remove any aliases on line
|
|
|
|
# 8: remove domain name, leaving naught but the hostname, naked as the day it were born
|
|
|
|
|
|
|
|
HOSTNAME=`
|
|
|
|
sed 's/[[:space:]]/ /g' $FILE | \
|
|
|
|
grep -v '^ *#' | \
|
|
|
|
sed 's/^/ /' | \
|
|
|
|
grep " $IPADDR_ESCAPED " | \
|
|
|
|
sed 's/ [0-9]*\.[0-9]*\.[0-9]*\.[0-9]*//' | \
|
|
|
|
sed 's/ *//' | \
|
|
|
|
sed 's/ .*//' | \
|
|
|
|
sed 's/\..*$//g'
|
|
|
|
`
|
|
|
|
else
|
|
|
|
logmsg "No hosts file."
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
get_hostname_by_dns() {
|
|
|
|
|
|
|
|
logmsg
|
|
|
|
logmsg get_hostname_by_dns
|
|
|
|
|
|
|
|
# Get base hostname. For example, www7.domain.com will become www7. -BEF-
|
|
|
|
HOSTNAME=`nslookup $IPADDR | sed -ne "s/^Address 1:[[:space:]]\+$IPADDR[[:space:]]\+\([^\.]\+\).*$/\1/p"`
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
get_base_hostname() {
|
|
|
|
BASE_HOSTNAME=`echo $HOSTNAME | sed "s/[.0-9].*$//"`
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
get_group_name() {
|
|
|
|
if [ -f ${SCRIPTS_DIR}/cluster.txt ]; then
|
|
|
|
[ -z "$GROUPNAMES" ] && \
|
|
|
|
GROUPNAMES=`unique $(grep "^${HOSTNAME}:" ${SCRIPTS_DIR}/cluster.txt | cut -d: -f2 | tr "\n" ' ')`
|
|
|
|
[ -z "$IMAGENAME" ] && \
|
|
|
|
IMAGENAME=`grep "^${HOSTNAME}:" ${SCRIPTS_DIR}/cluster.txt | cut -d: -f3 | grep -v '^[[:space:]]*$' | sed -ne '1p'`
|
|
|
|
if [ -z "$GROUP_OVERRIDES" ]; then
|
|
|
|
GROUP_OVERRIDES=`reverse $(unique $(grep "^${HOSTNAME}:" ${SCRIPTS_DIR}/cluster.txt | cut -d: -f4 | tr "\n" ' '))`
|
|
|
|
# Add the global override on top (least important).
|
|
|
|
GROUP_OVERRIDES="`sed -ne 's/^# global_override=:\([^:]*\):$/\1/p' ${SCRIPTS_DIR}/cluster.txt` $GROUP_OVERRIDES"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
choose_autoinstall_script() {
|
|
|
|
|
|
|
|
logmsg
|
|
|
|
logmsg choose_autoinstall_script
|
|
|
|
|
|
|
|
#
|
|
|
|
# Get the base hostname for the last attempt at choosing an autoinstall
|
|
|
|
# script. For example, if the hostname is compute99, then try to get
|
|
|
|
# compute.master. -BEF-
|
|
|
|
#
|
|
|
|
get_base_hostname
|
|
|
|
|
|
|
|
# Get group name (defined in /etc/systemimager/cluster.xml on the image
|
|
|
|
# server). -AR-
|
|
|
|
get_group_name
|
|
|
|
|
|
|
|
#
|
|
|
|
# If SCRIPTNAME is specified as a kernel append, or via local.cfg, then use that script.
|
|
|
|
#
|
|
|
|
if [ ! -z $SCRIPTNAME ]; then
|
|
|
|
#
|
|
|
|
# SCRIPTNAME was specified, but let's be flexible. Try explicit first, then .master, .sh. -BEF-
|
|
|
|
#
|
|
|
|
SCRIPTNAMES="${SCRIPTS_DIR}/${SCRIPTNAME} ${SCRIPTS_DIR}/${SCRIPTNAME}.sh ${SCRIPTS_DIR}/${SCRIPTNAME}.master"
|
|
|
|
|
|
|
|
else
|
|
|
|
#
|
|
|
|
# If SCRIPTNAME was not specified, choose one, in order of preference. First hit wins.
|
|
|
|
# Order of preference is:
|
|
|
|
# HOSTNAME (i.e. node001.sh)
|
|
|
|
# GROUPNAMES (i.e. Login.sh) - see /etc/systemimager/cluster.xml on the image server
|
|
|
|
# BASE_HOSTNAME (i.e. node.sh)
|
|
|
|
# IMAGENAME (i.e. ubuntu7_04.sh)
|
|
|
|
#
|
|
|
|
[ ! -z $HOSTNAME ] && \
|
|
|
|
SCRIPTNAMES="${SCRIPTNAMES} ${SCRIPTS_DIR}/${HOSTNAME}.sh ${SCRIPTS_DIR}/${HOSTNAME}.master"
|
|
|
|
for GROUPNAME in $GROUPNAMES; do
|
|
|
|
SCRIPTNAMES="${SCRIPTNAMES} ${SCRIPTS_DIR}/${GROUPNAME}.sh ${SCRIPTS_DIR}/${GROUPNAME}.master"
|
|
|
|
done
|
|
|
|
unset GROUPNAME
|
|
|
|
[ ! -z $BASE_HOSTNAME ] && \
|
|
|
|
SCRIPTNAMES="${SCRIPTNAMES} ${SCRIPTS_DIR}/${BASE_HOSTNAME}.sh ${SCRIPTS_DIR}/${BASE_HOSTNAME}.master"
|
|
|
|
[ ! -z $IMAGENAME ] && \
|
|
|
|
SCRIPTNAMES="${SCRIPTNAMES} ${SCRIPTS_DIR}/${IMAGENAME}.sh ${SCRIPTS_DIR}/${IMAGENAME}.master"
|
|
|
|
fi
|
|
|
|
|
|
|
|
#
|
|
|
|
# Choose a winner!
|
|
|
|
#
|
|
|
|
for SCRIPTNAME in $SCRIPTNAMES
|
|
|
|
do
|
|
|
|
[ -e $SCRIPTNAME ] && break
|
|
|
|
done
|
|
|
|
|
|
|
|
# Did we really find one, or just exit the loop without a 'break'
|
|
|
|
if [ ! -e $SCRIPTNAME ]; then
|
|
|
|
logmsg "FATAL: couldn't find any of the following autoinstall scripts!"
|
|
|
|
logmsg "---"
|
|
|
|
logmsg ${SCRIPTNAMES}
|
|
|
|
logmsg "---"
|
|
|
|
logmsg "Be sure that at least one of the scripts above exists in"
|
|
|
|
logmsg "the autoinstall scripts directory on your image server."
|
|
|
|
logmsg
|
|
|
|
logmsg "See also: si_mkautoinstallscript(8)."
|
|
|
|
shellout
|
|
|
|
fi
|
|
|
|
logmsg "Using autoinstall script: ${SCRIPTNAME}"
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
run_autoinstall_script() {
|
|
|
|
|
|
|
|
logmsg
|
|
|
|
logmsg run_autoinstall_script
|
|
|
|
|
|
|
|
# Run the autoinstall script.
|
|
|
|
chmod 755 $SCRIPTNAME || shellout
|
|
|
|
logmsg ">>> $SCRIPTNAME"
|
|
|
|
$SCRIPTNAME || shellout
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Description: remove duplicated elements from a list, preserving the order.
|
|
|
|
#
|
|
|
|
unique() {
|
|
|
|
ret=
|
|
|
|
for i in $*; do
|
|
|
|
flag=0
|
|
|
|
for j in $ret; do
|
|
|
|
[ "$i" = "$j" ] && flag=1 && break
|
|
|
|
done
|
|
|
|
[ $flag -eq 0 ] && ret="$ret $i"
|
|
|
|
done
|
|
|
|
echo $ret
|
|
|
|
unset i j flag ret
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Description: reverse a list
|
|
|
|
#
|
|
|
|
reverse() {
|
|
|
|
ret=
|
|
|
|
for i in $*; do
|
|
|
|
ret="$i $ret"
|
|
|
|
done
|
|
|
|
echo $ret
|
|
|
|
unset i
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
run_pre_install_scripts() {
|
|
|
|
|
|
|
|
logmsg
|
|
|
|
logmsg run_pre_install_scripts
|
|
|
|
|
|
|
|
get_base_hostname
|
|
|
|
|
|
|
|
# Get group name (defined in /etc/systemimager/cluster.xml on the image
|
|
|
|
# server). -AR-
|
|
|
|
get_group_name
|
|
|
|
|
|
|
|
if [ -e "${SCRIPTS_DIR}/pre-install/" ]; then
|
|
|
|
|
|
|
|
cd ${SCRIPTS_DIR}/pre-install/
|
|
|
|
|
|
|
|
PRE_INSTALL_SCRIPTS="$PRE_INSTALL_SCRIPTS `ls | grep "^[0-9][0-9]all\..*"`"
|
|
|
|
PRE_INSTALL_SCRIPTS="$PRE_INSTALL_SCRIPTS `ls | grep "^[0-9][0-9]${IMAGENAME}\..*"`"
|
|
|
|
PRE_INSTALL_SCRIPTS="$PRE_INSTALL_SCRIPTS `ls | grep "^[0-9][0-9]${BASE_HOSTNAME}\..*"`"
|
|
|
|
for GROUPNAME in ${GROUPNAMES}; do
|
|
|
|
PRE_INSTALL_SCRIPTS="$PRE_INSTALL_SCRIPTS `ls | grep "^[0-9][0-9]${GROUPNAME}\..*"`"
|
|
|
|
done
|
|
|
|
unset GROUPNAME
|
|
|
|
PRE_INSTALL_SCRIPTS="$PRE_INSTALL_SCRIPTS `ls | grep "^[0-9][0-9]${HOSTNAME}\..*"`"
|
|
|
|
|
|
|
|
# Now, to get rid of those pesky newlines. -BEF-
|
|
|
|
PRE_INSTALL_SCRIPTS=`echo $PRE_INSTALL_SCRIPTS | tr '\n' ' '`
|
|
|
|
|
|
|
|
if [ ! -z "`echo ${PRE_INSTALL_SCRIPTS}|sed 's/ //'`" ]; then
|
|
|
|
|
|
|
|
for PRE_INSTALL_SCRIPT in `unique $PRE_INSTALL_SCRIPTS`
|
|
|
|
do
|
|
|
|
logmsg ">>> $PRE_INSTALL_SCRIPT"
|
|
|
|
chmod +x $PRE_INSTALL_SCRIPT || shellout
|
|
|
|
./$PRE_INSTALL_SCRIPT || shellout
|
|
|
|
done
|
|
|
|
else
|
|
|
|
logmsg "No pre-install scripts found."
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -e "/tmp/pre-install_variables.txt" ]; then
|
|
|
|
. /tmp/pre-install_variables.txt
|
|
|
|
fi
|
|
|
|
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
run_post_install_scripts() {
|
|
|
|
|
|
|
|
logmsg
|
|
|
|
logmsg run_post_install_scripts
|
|
|
|
|
|
|
|
get_base_hostname
|
|
|
|
|
|
|
|
# Get group name (defined in /etc/systemimager/cluster.xml on the image
|
|
|
|
# server). -AR-
|
|
|
|
get_group_name
|
|
|
|
|
|
|
|
if [ -e "${SCRIPTS_DIR}/post-install/" ]; then
|
|
|
|
|
|
|
|
# make a copy of variables.txt available to post-install scripts -BEF-
|
|
|
|
cp -f /tmp/variables.txt ${SCRIPTS_DIR}/post-install/
|
|
|
|
|
|
|
|
cd ${SCRIPTS_DIR}/post-install/
|
|
|
|
|
|
|
|
POST_INSTALL_SCRIPTS="$POST_INSTALL_SCRIPTS `ls | grep "^[0-9][0-9]all\..*" | grep -v "~$" `"
|
|
|
|
POST_INSTALL_SCRIPTS="$POST_INSTALL_SCRIPTS `ls | grep "^[0-9][0-9]${IMAGENAME}\..*" | grep -v "~$" `"
|
|
|
|
POST_INSTALL_SCRIPTS="$POST_INSTALL_SCRIPTS `ls | grep "^[0-9][0-9]${BASE_HOSTNAME}\..*" | grep -v "~$" `"
|
|
|
|
for GROUPNAME in ${GROUPNAMES}; do
|
|
|
|
POST_INSTALL_SCRIPTS="$POST_INSTALL_SCRIPTS `ls | grep "^[0-9][0-9]${GROUPNAME}\..*" | grep -v "~$" `"
|
|
|
|
done
|
|
|
|
POST_INSTALL_SCRIPTS="$POST_INSTALL_SCRIPTS `ls | grep "^[0-9][0-9]${HOSTNAME}\..*" | grep -v "~$" `"
|
|
|
|
|
|
|
|
# Now, to get rid of those pesky newlines. -BEF-
|
|
|
|
POST_INSTALL_SCRIPTS=`echo $POST_INSTALL_SCRIPTS | tr '\n' ' '`
|
|
|
|
|
|
|
|
if [ ! -z "`echo ${POST_INSTALL_SCRIPTS}|sed 's/ //'`" ]; then
|
|
|
|
|
|
|
|
mkdir -p /a/tmp/post-install/ || shellout
|
|
|
|
|
|
|
|
rsync -a ${SCRIPTS_DIR}/post-install/ /a/tmp/post-install/ || shellout
|
|
|
|
|
|
|
|
for POST_INSTALL_SCRIPT in `unique $POST_INSTALL_SCRIPTS`
|
|
|
|
do
|
|
|
|
if [ -e "$POST_INSTALL_SCRIPT" ]; then
|
|
|
|
logmsg ">>> $POST_INSTALL_SCRIPT"
|
|
|
|
chmod +x /a/tmp/post-install/$POST_INSTALL_SCRIPT || shellout
|
|
|
|
chroot /a/ /tmp/post-install/$POST_INSTALL_SCRIPT || shellout
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
else
|
|
|
|
logmsg "No post-install scripts found."
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Clean up post-install script directory.
|
|
|
|
rm -rf /a/tmp/post-install/ || shellout
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Stuff for SSH installs
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
|
|
start_sshd() {
|
|
|
|
mkdir -p /root/.ssh/ || shellout
|
|
|
|
|
|
|
|
# download ssh authorized_keys if it's not present into the initrd.
|
|
|
|
if [ ! -f /root/.ssh/authorized_keys ]; then
|
|
|
|
if [ -z $SSH_DOWNLOAD_URL ]; then
|
|
|
|
logmsg
|
|
|
|
logmsg "error: authorized_keys not found and SSH_DOWNLOAD_URL not defined in the installation parameters!"
|
|
|
|
logmsg "sshd can't be started!"
|
|
|
|
shellout
|
|
|
|
fi
|
|
|
|
CMD="wget ${SSH_DOWNLOAD_URL}/${ARCH}/ssh/authorized_keys"
|
|
|
|
logmsg
|
|
|
|
logmsg $CMD
|
|
|
|
$CMD || shellout
|
|
|
|
fi
|
|
|
|
|
|
|
|
# set permissions to 600 -- otherwise, sshd will refuse to use it
|
|
|
|
chmod 600 /root/.ssh/authorized_keys || shellout
|
|
|
|
|
|
|
|
# must be owned by root
|
|
|
|
chown -R 0.0 /root/
|
|
|
|
|
|
|
|
# create a private host key for this autoinstall client
|
|
|
|
logmsg
|
|
|
|
logmsg "Using ssh-keygen to create this hosts private key"
|
|
|
|
logmsg
|
|
|
|
mkdir -p /var/empty || shellout
|
|
|
|
if [ ! -f /etc/ssh/ssh_host_dsa_key ]; then
|
|
|
|
ssh-keygen -t dsa -N "" -f /etc/ssh/ssh_host_dsa_key || shellout
|
|
|
|
fi
|
|
|
|
if [ ! -f /etc/ssh/ssh_host_rsa_key ]; then
|
|
|
|
ssh-keygen -t rsa -N "" -f /etc/ssh/ssh_host_rsa_key || shellout
|
|
|
|
fi
|
|
|
|
|
|
|
|
# try to mount devpts (sometimes it's not really necessary)
|
|
|
|
mkdir -p /dev/pts
|
|
|
|
mount -t devpts none /dev/pts >/dev/null 2>&1
|
|
|
|
|
|
|
|
# fire up sshd
|
|
|
|
mkdir -p /var/run/sshd || shellout
|
|
|
|
chmod 0755 /var/run/sshd || shellout
|
|
|
|
/usr/sbin/sshd || shellout
|
|
|
|
logmsg "sshd started"
|
|
|
|
touch /tmp/sshd_started
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
start_ssh() {
|
|
|
|
|
|
|
|
# create root's ssh dir
|
|
|
|
mkdir -p /root/.ssh
|
|
|
|
|
|
|
|
############################################################################
|
|
|
|
#
|
|
|
|
# If a private key exists, put it in the right place so this autoinstall
|
|
|
|
# client can use it to authenticate itself to the imageserver.
|
|
|
|
#
|
|
|
|
if [ -e /root/.ssh/id_dsa ]; then
|
|
|
|
# (ssh2 dsa style user private key)
|
|
|
|
PRIVATE_KEY=/root/.ssh/id_dsa
|
|
|
|
chmod 600 $PRIVATE_KEY || shellout
|
|
|
|
elif [ -e /root/.ssh/id_rsa ]; then
|
|
|
|
# (ssh2 rsa style user private key)
|
|
|
|
PRIVATE_KEY=/root/.ssh/id_rsa
|
|
|
|
chmod 600 $PRIVATE_KEY || shellout
|
|
|
|
elif [ -e /floppy/id_dsa ]; then
|
|
|
|
# (ssh2 dsa style user private key) from floppy
|
|
|
|
PRIVATE_KEY=/root/.ssh/id_dsa
|
|
|
|
cp /floppy/id_dsa $PRIVATE_KEY || shellout
|
|
|
|
chmod 600 $PRIVATE_KEY || shellout
|
|
|
|
elif [ -e /floppy/id_rsa ]; then
|
|
|
|
#
|
|
|
|
# (ssh2 rsa style user private key) from floppy
|
|
|
|
PRIVATE_KEY=/root/.ssh/id_rsa
|
|
|
|
cp /floppy/id_rsa $PRIVATE_KEY || shellout
|
|
|
|
chmod 600 $PRIVATE_KEY || shellout
|
|
|
|
fi
|
|
|
|
#
|
|
|
|
############################################################################
|
|
|
|
|
|
|
|
# If we have a private key from the media above, go ahead and open secure tunnel
|
|
|
|
# to the imageserver and continue with the autoinstall like normal.
|
|
|
|
if [ ! -z $PRIVATE_KEY ]; then
|
|
|
|
|
|
|
|
# With the prep ready, start the ssh tunnel connection.
|
|
|
|
#
|
|
|
|
# Determine if we should run interactive and set redirection options appropriately.
|
|
|
|
# So if the key is blank, go interactive. (Suggested by Don Stocks <don_stocks@leaseloan.com>)
|
|
|
|
if [ -s $PRIVATE_KEY ]; then
|
|
|
|
# key is *not* blank
|
|
|
|
REDIRECTION_OPTIONS="> /dev/null 2>&1"
|
|
|
|
else
|
|
|
|
# key is blank - go interactive
|
|
|
|
REDIRECTION_OPTIONS=""
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Default ssh user is root.
|
|
|
|
[ -z $SSH_USER ] && SSH_USER=root
|
|
|
|
|
|
|
|
CMD="ssh -N -l $SSH_USER -n -f -L873:127.0.0.1:873 $IMAGESERVER $REDIRECTION_OPTIONS"
|
|
|
|
logmsg $CMD
|
|
|
|
$CMD || shellout
|
|
|
|
|
|
|
|
# Since we're using SSH, change the $IMAGESERVER variable to reflect
|
|
|
|
# the forwarded connection.
|
|
|
|
IMAGESERVER=127.0.0.1
|
|
|
|
|
|
|
|
else
|
|
|
|
########################################################################
|
|
|
|
#
|
|
|
|
# Looks like we didn't get a private key so let's just fire up
|
|
|
|
# sshd and wait for someone to connect to us to initiate the
|
|
|
|
# next step of the autoinstall.
|
|
|
|
#
|
|
|
|
if [ -z $HOSTNAME ]; then
|
|
|
|
logmsg
|
|
|
|
logmsg "Trying to get hostname via DNS..."
|
|
|
|
logmsg
|
|
|
|
get_hostname_by_dns
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -z $HOSTNAME ]; then
|
|
|
|
HOST_OR_IP=$IPADDR
|
|
|
|
else
|
|
|
|
HOST_OR_IP=$HOSTNAME
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ ! -f /tmp/sshd_started ]; then
|
|
|
|
start_sshd
|
|
|
|
# Give sshd time to initialize before we yank the parent process
|
|
|
|
# rug out from underneath it.
|
|
|
|
sleep 15
|
|
|
|
fi
|
|
|
|
|
|
|
|
logmsg
|
|
|
|
logmsg
|
|
|
|
logmsg "Started sshd. You must now go to your imageserver and issue"
|
|
|
|
logmsg "the following command:"
|
|
|
|
logmsg
|
|
|
|
logmsg " \"si_pushinstall --hosts ${HOST_OR_IP}\"."
|
|
|
|
logmsg
|
|
|
|
logmsg
|
|
|
|
|
|
|
|
# Since we're using SSH, change the $IMAGESERVER variable to reflect
|
|
|
|
# the forwarded connection.
|
|
|
|
IMAGESERVER=127.0.0.1
|
|
|
|
|
|
|
|
while [ ! -f /tmp/si_pushupdate.completed ]; do
|
|
|
|
sleep 5
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# send_monitor_msg
|
|
|
|
#
|
|
|
|
# Description:
|
|
|
|
# Redirect a message to the monitor server.
|
|
|
|
#
|
|
|
|
# Usage: send_monitor_msg "var=$msg"
|
|
|
|
#
|
|
|
|
|
|
|
|
send_monitor_msg() {
|
|
|
|
if [ -z $MONITOR_SERVER ]; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
if [ -z $MONITOR_PORT ]; then
|
|
|
|
MONITOR_PORT=8181
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Message to send.
|
|
|
|
msg=`echo "$@"`
|
|
|
|
|
|
|
|
# Get the client mac address.
|
|
|
|
if [ -z "$mac" ]; then
|
2014-06-14 02:36:34 +00:00
|
|
|
#mac=`ifconfig $DEVICE 2>/dev/null | sed -ne "s/.*HWaddr //p" | sed "s/ //g" | sed s/:/./g`
|
|
|
|
mac=`ip -4 -oneline link show $DEVICE 2>/dev/null|grep -i ether|sed -ne "s/.*ether //p"|awk -F ' ' '{print $1}'|sed s/:/./g`
|
2013-04-10 06:18:46 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
# Collect some special info only after proc file system is mounted.
|
|
|
|
if [ `mount 2>/dev/null | grep proc > /dev/null; echo $?` -eq 0 ]; then
|
|
|
|
# Collect the CPU info.
|
|
|
|
if [ -z "$cpu" ]; then
|
|
|
|
cpu=$(echo `cat /proc/cpuinfo | grep "cpu\|clock\|model name\|cpu MHz" | grep -v "cpu family" | sed -ne '1,2p' | sed "s/.*: //" | sed "s/^\([0-9\.]*\)MHz$/(\1 MHz)/" | sed "s/^\([0-9\.]*\)$/(\1 MHz)/"` | sed "s/\(MHz)\)/\1 |/g" | sed "s/ |$//")
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Collect the number of CPUs.
|
|
|
|
if [ -z "$ncpus" ]; then
|
|
|
|
ncpus=$((`cat /proc/cpuinfo | grep "^processor" | sed -n '$p' | sed "s/.*: \([0-9]\)*$/\1/"` + 1))
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Collect the kernel information.
|
|
|
|
if [ -z "$kernel_name" ]; then
|
|
|
|
kernel_name=`uname -r`
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Collect the amount of phyisical memory.
|
|
|
|
if [ -z "$mem" ]; then
|
|
|
|
mem=`cat /proc/meminfo | sed -ne "s/MemTotal: *//p" | sed "s/ kB//"`
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Evaluate the amount of available RAM.
|
|
|
|
tmpfs=`df | grep tmpfs | grep "/$" | sed "s/.* \([0-9]*%\) .*/\1/"`
|
|
|
|
|
|
|
|
# Evaluate the uptime of the client.
|
|
|
|
time=`cat /proc/uptime | sed "s/\..*//"`
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Report the message to the monitor server.
|
|
|
|
send_msg=`echo "mac=$mac:ip=$IPADDR:host=$HOSTNAME:cpu=$cpu:ncpus=$ncpus:kernel=$kernel_name:mem=$mem:os=$IMAGENAME:tmpfs=$tmpfs:time=$time:$msg"`
|
|
|
|
|
|
|
|
# Send data to monitor server.
|
|
|
|
echo "$send_msg" | nc $MONITOR_SERVER $MONITOR_PORT
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# send_monitor_stdout
|
|
|
|
#
|
|
|
|
# Description:
|
|
|
|
# Redirect a stdout of a command to the monitor console.
|
|
|
|
#
|
|
|
|
# Usage: <cmd> | send_monitor_stdout
|
|
|
|
#
|
|
|
|
|
|
|
|
send_monitor_stdout() {
|
|
|
|
while read l; do
|
|
|
|
# echo to the console -AR-
|
|
|
|
echo "$l"
|
|
|
|
# Send the message to the monitor daemon.
|
|
|
|
if [ "x$MONITOR_CONSOLE" = "xy" ]; then
|
|
|
|
MONITOR_CONSOLE=yes
|
|
|
|
fi
|
|
|
|
if [ "x$MONITOR_CONSOLE" = "xyes" ]; then
|
|
|
|
# Log message into the global monitor log.
|
|
|
|
echo "$l" >> /tmp/si_monitor.log
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Initialize the monitor server
|
|
|
|
#
|
|
|
|
|
|
|
|
init_monitor_server() {
|
|
|
|
# Send initialization status.
|
|
|
|
send_monitor_msg "status=0:first_timestamp=on:speed=0"
|
|
|
|
logmsg "Monitoring initialized."
|
|
|
|
# Start client log gathering server: for each connection
|
|
|
|
# to the local client on port 8181 the full log is sent
|
|
|
|
# to the requestor. -AR-
|
|
|
|
if [ "x$MONITOR_CONSOLE" = "xy" ]; then
|
|
|
|
MONITOR_CONSOLE=yes
|
|
|
|
fi
|
|
|
|
if [ "x$MONITOR_CONSOLE" = "xyes" ]; then
|
|
|
|
while :; do nc -p 8181 -l < /tmp/si_monitor.log; done &
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Report installation status to the monitor server
|
|
|
|
#
|
|
|
|
|
|
|
|
start_report_task() {
|
|
|
|
# Reporting interval (in sec).
|
|
|
|
REPORT_INTERVAL=10
|
|
|
|
|
|
|
|
# Evaluate image size.
|
|
|
|
logmsg "Evaluating image size..."
|
|
|
|
if [ ! "x$BITTORRENT" = "xy" ]; then
|
|
|
|
IMAGESIZE=`rsync -av --numeric-ids $IMAGESERVER::$IMAGENAME | grep "total size" | sed -e "s/total size is \([0-9]*\).*/\1/"`
|
|
|
|
else
|
|
|
|
if [ -f "${TORRENTS_DIR}/image-${IMAGENAME}.tar.torrent" ]; then
|
|
|
|
torrent_file="${TORRENTS_DIR}/image-${IMAGENAME}.tar.torrent"
|
|
|
|
elif [ -f "${TORRENTS_DIR}/image-${IMAGENAME}.tar.gz.torrent" ]; then
|
|
|
|
torrent_file="${TORRENTS_DIR}/image-${IMAGENAME}.tar.gz.torrent"
|
|
|
|
else
|
|
|
|
logmsg "error: cannot find a valid torrent file for image ${IMAGENAME}"
|
|
|
|
shellout
|
|
|
|
fi
|
|
|
|
IMAGESIZE=`/bin/torrentinfo-console $torrent_file | sed -ne "s/file size\.*: \([0-9]*\) .*$/\1/p"`
|
|
|
|
fi
|
|
|
|
IMAGESIZE=`expr $IMAGESIZE / 1024`
|
|
|
|
logmsg " --> Image size = `expr $IMAGESIZE / 1024`MiB"
|
|
|
|
|
|
|
|
# Evaluate disks size.
|
|
|
|
LIST=`df 2>/dev/null | grep "/" | sed "s/ */ /g" | cut -d' ' -f3 | sed -ne 's/^\([0-9]*\)$/\1+/p'`0
|
|
|
|
DISKSIZE=`echo $LIST | bc`
|
|
|
|
|
|
|
|
# Spawn the report task -AR-
|
|
|
|
{
|
|
|
|
TOT=0; CURR_SIZE=0
|
|
|
|
while :; do
|
|
|
|
LIST=`df 2>/dev/null | grep "/" | sed "s/ */ /g" | cut -d' ' -f3 | sed -ne 's/^\([0-9]*\)$/\1+/p'`0
|
|
|
|
TOT=`echo $LIST | bc`
|
|
|
|
|
|
|
|
# Evaluate bandwidth.
|
|
|
|
speed=`echo "scale=2; (($TOT - $DISKSIZE) - $CURR_SIZE) / $REPORT_INTERVAL" | bc`
|
|
|
|
speed=`echo "scale=2; if ($speed >= 0) { print $speed; } else { print 0; }" | bc`
|
|
|
|
|
|
|
|
# Evaluate status.
|
|
|
|
CURR_SIZE=$(($TOT - $DISKSIZE))
|
|
|
|
status=`echo "scale=2; $CURR_SIZE * 100 / $IMAGESIZE" | bc`
|
|
|
|
if [ `echo "scale=2; $status <= 0" | bc` -eq 1 ]; then
|
|
|
|
status=1
|
|
|
|
elif [ `echo "scale=2; $status >= 100" | bc` -eq 1 ]; then
|
|
|
|
status=99
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Send status and bandwidth to the monitor server.
|
|
|
|
send_monitor_msg "status=$status:speed=$speed"
|
|
|
|
|
|
|
|
# Wait $REPORT_INTERVAL sec between each report -AR-
|
|
|
|
sleep $REPORT_INTERVAL
|
|
|
|
done
|
|
|
|
}&
|
|
|
|
|
|
|
|
logmsg "Report task started."
|
|
|
|
REPORT_PID=$!
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Stop to report installation status to the monitor server
|
|
|
|
#
|
|
|
|
|
|
|
|
stop_report_task() {
|
|
|
|
if [ ! -z $REPORT_PID ]; then
|
|
|
|
kill -9 $REPORT_PID
|
|
|
|
logmsg "Report task stopped."
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Try to report the error to the monitor server.
|
|
|
|
send_monitor_msg "status=$1:speed=0"
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Beep incessantly
|
|
|
|
#
|
|
|
|
beep_incessantly() {
|
|
|
|
local SECONDS=1
|
|
|
|
local MINUTES
|
|
|
|
local MINUTES_X_SIXTY
|
|
|
|
{ while :;
|
|
|
|
do
|
|
|
|
echo -n -e "\\a"
|
|
|
|
if [ $SECONDS -lt 60 ]; then
|
|
|
|
logmsg "I have been done for $SECONDS seconds. Reboot me already!"
|
|
|
|
else
|
|
|
|
MINUTES=`echo "$SECONDS / 60"|bc`
|
|
|
|
MINUTES_X_SIXTY=`echo "$MINUTES * 60"|bc`
|
|
|
|
if [ "$MINUTES_X_SIXTY" = "$SECONDS" ]; then
|
|
|
|
logmsg "I have been done for $MINUTES minutes now. Reboot me already!"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
sleep 1
|
|
|
|
SECONDS=`echo "$SECONDS + 1"|bc`
|
|
|
|
done
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Beep incessantly
|
|
|
|
#
|
|
|
|
# Usage: beep [$COUNT [$INTERVAL]]
|
|
|
|
# Usage: beep
|
|
|
|
beep() {
|
|
|
|
local COUNT=$1
|
|
|
|
local INTERVAL=$2
|
|
|
|
|
|
|
|
[ -z $COUNT ] && COUNT=1
|
|
|
|
[ -z $INTERVAL ] && INTERVAL=1
|
|
|
|
|
|
|
|
local COUNTED=0
|
|
|
|
until [ "$COUNTED" = "$COUNT" ]
|
|
|
|
do
|
|
|
|
echo -n -e "\\a"
|
|
|
|
sleep $INTERVAL
|
|
|
|
COUNTED=$(( $COUNTED + 1 ))
|
|
|
|
done
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# Print out dots while sleeping
|
|
|
|
#
|
|
|
|
# Usage: sleep_loop [[$COUNT [$INTERVAL]] $CHARACTER]
|
|
|
|
# Usage: sleep_loop
|
|
|
|
sleep_loop() {
|
|
|
|
local COUNT=$1
|
|
|
|
local INTERVAL=$2
|
|
|
|
local CHARACTER=$3
|
|
|
|
local COUNTED
|
|
|
|
|
|
|
|
[ -z $COUNT ] && COUNT=1
|
|
|
|
[ -z $INTERVAL ] && INTERVAL=1
|
|
|
|
[ -z $CHARACTER ] && CHARACTER=.
|
|
|
|
|
|
|
|
COUNTED=0
|
|
|
|
until [ "$COUNTED" = "$COUNT" ]
|
|
|
|
do
|
|
|
|
echo -n "$CHARACTER"
|
|
|
|
sleep $INTERVAL
|
|
|
|
COUNTED=$(( $COUNTED + 1 ))
|
|
|
|
done
|
|
|
|
}
|
|
|
|
#
|
|
|
|
################################################################################
|