X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=guest.init;h=c2e5aae9224fd17a80de73a326f1aa71342f933d;hb=e50aa533a7ff20580d6cf3dbf34c5e459a250a5c;hp=6cd8beb87abdbdca0349b24b3b47691028a37473;hpb=3b19d9b88291bad1c75b7e5a196f37119af8825d;p=myplc.git diff --git a/guest.init b/guest.init index 6cd8beb..c2e5aae 100755 --- a/guest.init +++ b/guest.init @@ -6,552 +6,70 @@ # # description: Manages all PLC services on this machine # -# $Id: guest.init,v 1.3 2006/03/27 22:03:38 mlhuang Exp $ +# $Id: guest.init,v 1.20 2006/08/08 23:19:52 mlhuang Exp $ # -PATH=/sbin:/bin:/usr/bin:/usr/sbin - -# Source function library. -. /etc/init.d/functions +# Source function library and configuration +. /etc/plc.d/functions # Verbosity verbose=0 -# Keep in order! All steps should be idempotent. This means that you -# should be able to run them multiple times without depending on -# anything previously being run. The idea is that when the -# configuration changes, "service plc restart" is called, all -# dependencies are fixed up, and everything just works. -steps=( -network -syslog -postgresql -ssl -gpg -ssh -apache -api -cron -) +# All steps should be idempotent. This means that you should be able +# to run them multiple times without depending on anything previously +# being run. The idea is that when the configuration changes, "service +# plc restart" is called, all dependencies are fixed up, and +# everything just works. +steps=($( +for step in /etc/plc.d/* ; do + if [ -f $step -a -x $step ] ; then + priority=$(sed -ne 's/# priority: \(.*\)/\1/p' $step) + echo $priority $(basename $step) + fi +done | sort -n | cut -d' ' -f2 +)) nsteps=${#steps[@]} -gethostbyname () -{ - perl -MSocket -e '($a,$b,$c,$d,@addrs) = gethostbyname($ARGV[0]); print inet_ntoa($addrs[0]) . "\n";' $1 2>/dev/null -} - # Regenerate configuration files reload () { - # Load configuration - plc-config --shell >/etc/planetlab/plc_config - . /etc/planetlab/plc_config - - # Generate various defaults - if [ -z "$PLC_DB_PASSWORD" ] ; then - PLC_DB_PASSWORD=$(uuidgen) - plc-config --category=plc_db --variable=password --value="$PLC_DB_PASSWORD" --save - fi - - if [ -z "$PLC_API_MAINTENANCE_PASSWORD" ] ; then - PLC_API_MAINTENANCE_PASSWORD=$(uuidgen) - plc-config --category=plc_api --variable=maintenance_password --value="$PLC_API_MAINTENANCE_PASSWORD" --save - fi - - if [ -z "$PLC_API_MAINTENANCE_SOURCES" ] ; then - for server in API BOOT WWW ; do - eval hostname=\${PLC_${server}_HOST} - ip=$(gethostbyname $hostname) - if [ -n "$ip" ] ; then - if [ -n "$PLC_API_MAINTENANCE_SOURCES" ] ; then - PLC_API_MAINTENANCE_SOURCES="$PLC_API_MAINTENANCE_SOURCES $ip" - else - PLC_API_MAINTENANCE_SOURCES=$ip - fi - fi - done - plc-config --category=plc_api --variable=maintenance_sources --value="$PLC_API_MAINTENANCE_SOURCES" --save - fi - - # Save configuration - mkdir -p /etc/planetlab/php - plc-config --php >/etc/planetlab/php/plc_config.php - plc-config --shell >/etc/planetlab/plc_config - - # For backward compatibility, until we can convert all code to use - # the now standardized variable names. - - # DB constants are all named the same - ln -sf plc_config /etc/planetlab/plc_db - - # API constants - cat >/etc/planetlab/plc_api <>/etc/planetlab/plc_api - - cat >/etc/planetlab/php/site_constants.php <<"EOF" -'); -DEFINE('PLANETLAB_SUPPORT_EMAIL_ONLY', PLC_MAIL_SUPPORT_ADDRESS); -?> -EOF -} - -config_network () -{ - case "$1" in - start) - # Minimal /etc/hosts - ( - echo "127.0.0.1 localhost.localdomain localhost" - for server in API BOOT WWW ; do - eval hostname=\${PLC_${server}_HOST} - ip=$(gethostbyname $hostname) - if [ -n "$ip" ] ; then - echo "$ip $hostname" - fi - done - ) >/etc/hosts - - # Set up nameservers - ( - [ -n "$PLC_NET_DNS1" ] && echo "nameserver $PLC_NET_DNS1" - [ -n "$PLC_NET_DNS2" ] && echo "nameserver $PLC_NET_DNS2" - ) >/etc/resolv.conf - ;; - esac -} - -config_syslog () -{ - service syslog $1 - RETVAL=$? -} - -config_postgresql () -{ - # Default locations - PGDATA=/var/lib/pgsql/data - postgresql_conf=$PGDATA/postgresql.conf - pghba_conf=$PGDATA/pg_hba.conf - - case "$1" in - start) - if [ "$PLC_DB_ENABLED" != "1" ] ; then - return 0 - fi - - # Set data directory and redirect startup output to /var/log/pgsql - mkdir -p /etc/sysconfig/pgsql - ( - echo "PGDATA=$PGDATA" - echo "PGLOG=/var/log/pgsql" - ) >>/etc/sysconfig/pgsql/postgresql - - # Fix ownership (rpm installation may have changed it) - chown -R -H postgres:postgres $(dirname $PGDATA) - - # PostgreSQL must be started at least once to bootstrap - # /var/lib/pgsql/data - if [ ! -f $postgresql_conf ] ; then - service postgresql start - service postgresql stop - fi - - # Enable DB server. PostgreSQL >=8.0 defines listen_addresses, - # PostgreSQL 7.x uses tcpip_socket. - if grep -q listen_addresses $postgresql_conf ; then - sed -i -e '/^listen_addresses/d' $postgresql_conf - echo "listen_addresses = '*'" >>$postgresql_conf - elif grep -q tcpip_socket $postgresql_conf ; then - sed -i -e '/^tcpip_socket/d' $postgresql_conf - echo "tcpip_socket = true" >>$postgresql_conf - fi - - # Disable access to all DBs from all hosts - sed -i -e '/^\(host\|local\)/d' $pghba_conf - - # Enable passwordless localhost access - echo "local all all trust" >>$pghba_conf - - # Enable access from the API and web servers - PLC_API_IP=$(gethostbyname $PLC_API_HOST) - PLC_WWW_IP=$(gethostbyname $PLC_WWW_HOST) - ( - echo "host $PLC_DB_NAME $PLC_DB_USER $PLC_API_IP/32 password" - echo "host $PLC_DB_NAME $PLC_DB_USER $PLC_WWW_IP/32 password" - ) >>$pghba_conf - - # Fix ownership (sed -i changes it) - chown postgres:postgres $postgresql_conf $pghba_conf - - # Start up the server - service postgresql start - # /etc/init.d/postgresql always returns 0, even on failure - status postmaster - RETVAL=$? - - # Create/update the unprivileged database user and password - if ! psql -U $PLC_DB_USER -c "" template1 >/dev/null 2>&1 ; then - psql -U postgres -c "CREATE USER $PLC_DB_USER PASSWORD '$PLC_DB_PASSWORD'" template1 + force=$1 + + # Regenerate the main configuration file from default values + # overlaid with site-specific and current values. + files=( + /etc/planetlab/default_config.xml + /etc/planetlab/configs/*.xml + /etc/planetlab/plc_config.xml + ) + for file in "${files[@]}" ; do + if [ -n "$force" -o $file -nt /etc/planetlab/plc_config.xml ] ; then + tmp=$(mktemp /tmp/plc_config.xml.XXXXXX) + plc-config --xml "${files[@]}" >$tmp + if [ $? -eq 0 ] ; then + mv $tmp /etc/planetlab/plc_config.xml + chmod 644 /etc/planetlab/plc_config.xml else - psql -U postgres -c "ALTER USER $PLC_DB_USER WITH PASSWORD '$PLC_DB_PASSWORD'" template1 - fi - - # Create the database if necessary - if ! psql -U $PLC_DB_USER -c "" $PLC_DB_NAME >/dev/null 2>&1 ; then - createdb -U postgres $PLC_DB_NAME - psql -U $PLC_DB_USER -f /usr/share/pl_db/plc_schema_3.sql $PLC_DB_NAME - fi - ;; - - stop) - # Drop the current user in case the username changes - psql -U postgres -c "DROP USER $PLC_DB_USER" template1 - - # WARNING: If the DB name changes, the old DB will be left - # intact and a new one will be created. If it changes - # back, the old DB will not be re-created. - - # Shut down the server - service postgresql stop - RETVAL=$? - ;; - esac -} - -# Generate GPG keys -config_gpg () -{ - case "$1" in - start) - # Generate GPG keyrings - if [ ! -f $PLC_ROOT_GPG_KEY_PUB -o ! -f $PLC_ROOT_GPG_KEY ] ; then - mkdir -p $(dirname $PLC_ROOT_GPG_KEY_PUB) - mkdir -p $(dirname $PLC_ROOT_GPG_KEY) - - # Temporarily replace /dev/random with /dev/urandom to - # avoid running out of entropy. - rm -f /dev/random - mknod /dev/random c 1 9 - gpg --homedir=/root --batch --gen-key <$PLC_WWW_SSL_KEY - RETVAL=$(($RETVAL+$?)) - chmod 600 $PLC_WWW_SSL_KEY - fi - - # Generate self-signed certificate - if [ ! -f $PLC_WWW_SSL_CRT ] ; then - mkdir -p $(dirname $PLC_WWW_SSL_CRT) - openssl req -new -x509 -days 365 -set_serial $RANDOM \ - -key $PLC_WWW_SSL_KEY -out $PLC_WWW_SSL_CRT <$PLC_API_SSL_KEY_PUB - RETVAL=$(($RETVAL+$?)) - fi - if [ ! -f $PLC_API_SSL_CRT ] ; then - cp -a $PLC_WWW_SSL_CRT $PLC_API_SSL_CRT - fi - if [ ! -f $PLC_API_SSL_KEY ] ; then - cp -a $PLC_WWW_SSL_KEY $PLC_API_SSL_KEY - fi - if [ ! -f $PLC_API_SSL_CRT ] ; then - cp -a $PLC_WWW_SSL_CRT $PLC_API_SSL_CRT - fi - - # Install into both /etc/pki (Fedora Core 4) and - # /etc/httpd/conf (Fedora Core 2). If the API, boot, and - # web servers are all running on the same machine, the web - # server certificate takes precedence. - for server in API BOOT WWW ; do - eval enabled=\${PLC_${server}_ENABLED} - if [ "$enabled" != "1" ] ; then - continue - fi - eval ssl_crt=\${PLC_${server}_SSL_CRT} - eval ssl_key=\${PLC_${server}_SSL_KEY} - - symlink $ssl_crt /etc/pki/tls/certs/localhost.crt - symlink $ssl_key /etc/pki/tls/private/localhost.key - symlink $ssl_crt /etc/httpd/conf/ssl.crt/server.crt - symlink $ssl_key /etc/httpd/conf/ssl.key/server.key - done - ;; - esac -} - -# Generate SSH keys -config_ssh () -{ - # XXX Could make these configurable - KEY_TYPE_ROOT=rsa - KEY_LEN_ROOT=1024 - KEY_TYPE_DEBUG=rsa - KEY_LEN_DEBUG=2048 - - case "$1" in - start) - tmp=$(mktemp -d /tmp/ssh.XXXXXX) - - # Generate root SSH key - if [ ! -f $PLC_ROOT_SSH_KEY_PUB -o ! -f $PLC_ROOT_SSH_KEY ] ; then - ssh-keygen -N "" -C "$PLC_NAME Central <$PLC_MAIL_SUPPORT_ADDRESS>" \ - -b $KEY_LEN_ROOT -t $KEY_TYPE_ROOT -f $tmp/root - RETVAL=$(($RETVAL+$?)) - install -D -m 600 $tmp/root $PLC_ROOT_SSH_KEY - install -D -m 600 $tmp/root.pub $PLC_ROOT_SSH_KEY_PUB - fi - - # Generate debug SSH key - if [ ! -f $PLC_DEBUG_SSH_KEY_PUB -o ! -f $PLC_DEBUG_SSH_KEY ] ; then - ssh-keygen -N "" -C "$PLC_NAME Central <$PLC_MAIL_SUPPORT_ADDRESS>" \ - -b $KEY_LEN_DEBUG -t $KEY_TYPE_DEBUG -f $tmp/debug - RETVAL=$(($RETVAL+$?)) - install -D -m 600 $tmp/debug $PLC_DEBUG_SSH_KEY - install -D -m 600 $tmp/debug.pub $PLC_DEBUG_SSH_KEY_PUB - fi - - rm -rf $tmp - ;; - esac -} - -# Configure Apache web server -config_apache () -{ - # Default locations - DocumentRoot=/var/www/html - php_ini=/etc/php.ini - httpd_conf=/etc/httpd/conf/httpd.conf - ssl_conf=/etc/httpd/conf.d/ssl.conf - plc_conf=/etc/httpd/conf.d/plc.conf - - case "$1" in - start) - if [ "$PLC_API_ENABLED" != "1" -a \ - "$PLC_BOOT_ENABLED" != "1" -a \ - "$PLC_WWW_ENABLED" != "1" ] ; then - return 0 - fi - - # Set the default include path - include_path=".:$DocumentRoot/includes:$DocumentRoot/generated:/etc/planetlab/php" - sed -i -e "s@;include_path = \"\.:.*\"@include_path = \"$include_path\"@" $php_ini - - # Set the port numbers. If the API, boot, and web servers - # are all running on the same machine, the web server port - # numbers take precedence. - for server in API BOOT WWW ; do - eval enabled=\${PLC_${server}_ENABLED} - if [ "$enabled" != "1" ] ; then - continue - fi - eval http_port=\${PLC_${server}_PORT} - eval https_port=\${PLC_${server}_SSL_PORT} - - if [ -n "$http_port" ] ; then - sed -i -e "s/^Listen .*/Listen $http_port/" $httpd_conf - fi - if [ -n "$https_port" ] ; then - sed -i \ - -e "s/^Listen .*/Listen $https_port/" \ - -e "s///" \ - $ssl_conf - fi - done - - # Set custom Apache directives - ( - if [ "$PLC_API_ENABLED" = "1" ] ; then - cat < - SetHandler python-program - PythonPath "sys.path + ['/usr/share/plc_api']" - PythonHandler mod_pythonXMLRPC - -EOF - fi - - cat < - Redirect /db https://$PLC_WWW_HOST:$PLC_WWW_SSL_PORT/db - -EOF - ) >$plc_conf - - # Make alpina-logs directory writable for bootmanager log upload - chown apache:apache $DocumentRoot/alpina-logs/nodes - - service httpd start - RETVAL=$? - ;; - - stop) - service httpd stop - RETVAL=$? - ;; - esac -} - -config_api () -{ - case "$1" in - start) - if [ "$PLC_API_ENABLED" -ne 1 ] ; then - return - fi - - # Update the maintenance account username. This can't be - # done through the api-config script since it uses the - # maintenance account to access the API. The maintenance - # account should be person_id 1 since it is created by the - # DB schema itself. - psql -U $PLC_DB_USER -c "UPDATE persons SET email='$PLC_API_MAINTENANCE_USER' WHERE person_id=1" $PLC_DB_NAME - - # Bootstrap the DB - api-config - RETVAL=$? - ;; - esac -} - -config_cron () -{ - case "$1" in - start) - cat >/etc/cron.d/plc.cron </etc/planetlab/plc_config + fi + if [ -n "$force" -o /etc/planetlab/plc_config.xml -nt /etc/planetlab/php/plc_config.php ] ; then + mkdir -p /etc/planetlab/php + plc-config --php >/etc/planetlab/php/plc_config.php + fi } usage() { - echo "Usage: $0 [OPTION]... [COMMAND]" + echo "Usage: $0 [OPTION]... [COMMAND] [STEP]..." echo " -v Be verbose" echo " -h This message" echo @@ -560,6 +78,13 @@ usage() echo " stop Stop all PLC subsystems" echo " reload Regenerate configuration files" echo " restart Restart all PLC subsystems" + echo + echo "Steps:" + for step in "${steps[@]}" ; do + if [ -x /etc/plc.d/$step ] ; then + echo " $(basename $step)" + fi + done exit 1 } @@ -568,7 +93,6 @@ while getopts "vh" opt ; do case $opt in v) verbose=1 - set -x ;; h|*) usage @@ -576,36 +100,45 @@ while getopts "vh" opt ; do esac done +# Redirect stdout and stderr of each step to /var/log/boot.log +if [ $verbose -eq 0 ] ; then + touch /var/log/boot.log + chmod 600 /var/log/boot.log + exec 1>>/var/log/boot.log + exec 2>>/var/log/boot.log +fi + +# Get command shift $(($OPTIND - 1)) if [ -z "$1" ] ; then usage fi +command=$1 -exec 3>&1 -exec 4>&2 -if [ $verbose -eq 0 ] ; then - exec 1>>/var/log/boot.log - exec 2>>/var/log/boot.log +# Get step(s) +shift 1 +if [ -z "$1" ] ; then + # Start or stop everything. Regenerate configuration first. + reload force +else + # Start or stop a particular step + steps=("$@") + nsteps=${#steps[@]} fi -# Generate and load configuration -reload -. /etc/planetlab/plc_config - RETVAL=0 start () { for step in "${steps[@]}" ; do - echo -n $"PLC: Starting $step: " >&3 - RETVAL=0 - config_$step start - if [ $RETVAL -eq 0 ] ; then - success $"PLC: $step startup" >&3 + if [ -x /etc/plc.d/$step ] ; then + /etc/plc.d/$step start + # Steps may alter the configuration, may need to regenerate + reload else - failure $"PLC: $step startup" >&3 + echo "PLC: $step: unrecognized step" >&4 + exit 1 fi - echo >&3 done } @@ -613,21 +146,20 @@ stop () { for i in $(seq 1 $nsteps) ; do step=${steps[$(($nsteps - $i))]} - echo -n $"PLC: Shutting down $step: " >&3 - RETVAL=0 - config_$step stop - if [ $RETVAL -eq 0 ] ; then - success $"PLC: $step shutdown" >&3 + if [ -x /etc/plc.d/$step ] ; then + /etc/plc.d/$step stop + # Steps may alter the configuration, may need to regenerate + reload else - failure $"PLC: $step shutdown" >&3 + echo "PLC: $step: unrecognized step" >&4 + exit 1 fi - echo >&3 done } -case "$1" in +case "$command" in start|stop) - $1 + $command ;; restart) @@ -636,6 +168,7 @@ case "$1" in ;; reload) + reload force ;; *)