#!/bin/sh
# Author: Blake, Kuo-Lien Huang 
# Description: configurate DRBL as Grid Box
# License: GPL

drblhost="/var/lib/diskless/default"

# must be root
ID=`id -u`
if [ "$ID" != "0" ]; then
  echo "You must be root to use this script."
  echo "Use sudo to enable it for users."
  exit 1
fi

## helper function
removeentries() {
  while read line; do
    case "$line" in $1)
      while read line; do
        if [ "$line" = "$2" ]; then break; fi
      done
    esac
    if [ "$line" = "$2" ]; then continue; fi
    echo "$line"
  done < $3
}
START_TAG="# Added by DRBL."
END_TAG="# Added by DRBL Done."

# install_if_necessary
install_if_necessary() {

  found_mpich=0; found_pbs=0; found_ganglia=0; found_globus=0
  if [ "$(dpkg -l mpich | grep "mpich" | cut -d" " -f1)" = "ii" ]; then found_mpich=1; fi
  #if [ "$(dpkg -l openpbs-oscar-server | grep "openpbs" | cut -d" " -f1)" = "ii" ]; then found_pbs=1; fi
  if [ "$(dpkg -l openpbs | grep "openpbs" | cut -d" " -f1)" = "ii" ]; then found_pbs=1; fi
  if [ "$(dpkg -l ganglia-monitor | grep "ganglia" | cut -d" " -f1)" = "ii" ]; then found_ganglia=1; fi
  if [ -d /opt/Globus/globus-2.4.2 ]; then found_globus=1; fi

  # number of cpu
  if [ $found_mpich -eq 0 -o $found_pbs -eq 0 -o $found_ganglia -eq 0 -o $found_globus -eq 0 ]; then
    NCPUS="$(cat /proc/cpuinfo | grep "processor" | wc -l)"
    echo -n "The number of cpus on each node [$NCPUS]? "
    read ncpus
    if [ "$ncups" = "" ]; then ncups="$NCPUS"; fi

    apt-get update
    mpich $ncups
    openpbs_maui $ncups
    ganglia $ncups
    globus $ncups

    #source /etc/profile.d/pbs-oscar.sh
    source /etc/profile.d/openpbs.sh
    source /etc/profile.d/globus.sh
  fi
}

# mpich
mpich() {
  ncpus=$1
  if [ "$(dpkg -l mpich | grep "mpich" | cut -d" " -f1)" = "ii" ]; then return; fi

  # install
  apt-get -y install mpich; drbl-get -y install mpich

  # configure
  cat <<-EOF > /etc/mpich/machines.LINUX
# Change this file to contain the machines that you want to use
# to run MPI jobs on.  The format is one host name per line, with either
#    hostname
# or
#    hostname:n
# where n is the number of processors in an SMP.  The hostname should
# be the same as the result from the command "hostname"
EOF
  if [ "$ncpus" = "1" ]; then
    cat /etc/dhcp3/dhcpd.conf | grep "fixed-address" | cut -d';' -f1 | awk '{ print $2; }' >> /etc/mpich/machines.LINUX
  else
    cat /etc/dhcp3/dhcpd.conf | grep "fixed-address" | cut -d';' -f1 | awk -v ncpus=$ncpus '{ print $2":"ncpus; }' >> /etc/mpich/machines.LINUX
  fi

  ## copy to all drbl clients
  drbl-cp /etc/mpich/machines.LINUX [:ALL_HOSTS:]/etc/mpich
}

openpbs_maui() {
  ncpus=$1
  #if [ "$(dpkg -l openpbs-oscar-server | grep "openpbs-oscar-server" | cut -d" " -f1)" = "ii" ]; then return; fi
  if [ "$(dpkg -l openpbs | grep "openpbs" | cut -d" " -f1)" = "ii" ]; then return; fi

  # install
  #apt-get -y install openpbs-oscar openpbs-oscar-server openpbs-oscar-mom openpbs-oscar-client
  #apt-get -y install maui-oscar
  #drbl-get -y install openpbs-oscar 
  #drbl-get -y install openpbs-oscar-mom 
  #drbl-get -y install openpbs-oscar-client
  apt-get -y install openpbs maui
  /usr/sbin/update-rc.d -f pbs_sched remove
  #drbl-get -y install openpbs 
  drbl-cp /var/spool/pbs [:ALL_HOSTS:]/var/spool
  drbl-cp /etc/init.d/pbs_mom [:ALL_HOSTS:]/etc/init.d

  ## autosshkeygen (because we use scp to deliver file ...)
  #resshkeygen=0
  #if [ ! -f /root/.ssh/id_rsa ]; then
  #  apps/autosshkeygen root
  #  mv /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys
  #  resshkeygen=1 
  #fi
  resshkeygen=0
  if [ ! -f /root/.ssh/id_rsa ]; then
    cat <<-EOF > autosshkeygen.$$
#!/bin/sh
# \\
exec expect "\$0" \${1+"\$@"}
set username [lindex \$argv 0]
spawn sudo -u \$username ssh-keygen -t rsa
expect "Enter file in which to save the key"
send "\r"
expect "Enter passphrase"
send "\r"
expect "Enter same passphrase again"
send "\r"
expect eof
EOF
    chmod 755 autosshkeygen.$$
    ./autosshkeygen.$$ root
    mv /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys
    resshkeygen=1 
    rm -f ./autosshkeygen.$$
  fi

  for host in `ls $drblhost`
  do
    if [ "$host" = "." -o "$host" = ".." -o "$host" = "root" ]; then
      continue
    fi
    if [ $resshkeygen -eq 1 -o ! -f $drblhost/$host/root/.ssh/id_rsa ]; then
      mkdir -p $drblhost/$host/root/.ssh
      cp /root/.ssh/id_rsa $drblhost/$host/root/.ssh/id_rsa
      cp /root/.ssh/authorized_keys $drblhost/$host/root/.ssh/authorized_keys
    fi
  done
  ## end autosshkeygen

  # configure
  #echo "$(hostname)" > /var/spool/pbs/server_priv/nodes
  if [ "$ncups" = "1" ]; then
    cat /etc/dhcp3/dhcpd.conf | grep -B2 "fixed-address" | grep "host" | awk '{ print $2; }' >> /var/spool/pbs/server_priv/nodes
  else
    cat /etc/dhcp3/dhcpd.conf | grep -B2 "fixed-address" | grep "host" | awk -v ncups=$ncups '{ print $2" np="ncups; }' >> /var/spool/pbs/server_priv/nodes
  fi

  for host in `ls $drblhost`; do
    if [ "$host" = "." -o "$host" = ".." -o "$host" = "root" ]; then continue; fi
    pbs_server_ip=""
    while read spec file vfstype others; do
      if [ "$file" = "/" ]; then
        pbs_server_ip="$(echo "$spec" | cut -d: -f1)"
        break
      fi
    done < $drblhost/$host/etc/fstab
    if [ "$pbs_server_ip" = "" ]; then pbs_server="$(hostname)"
    else pbs_server="$(cat /etc/hosts | grep "$pbs_server_ip" | awk '{ print $3; }')"
    fi
    echo "$pbs_server" > $drblhost/$host/var/spool/pbs/server_name
    cat <<-EOF > $drblhost/$host/var/spool/pbs/mom_priv/config
\$clienthost $pbs_server
\$logevent 0x1ff
\$usecp $pbs_server:/home /home
#\$restricted $pbs_server
EOF
  done

  /etc/init.d/pbs_server restart
  /etc/init.d/maui restart
  /etc/init.d/pbs_mom restart

  # configure queue
  #c="$(cat /var/spool/pbs/server_priv/nodes | wc -l)"
  #max_running=`expr $c \* $ncpus`
  cat <<-EOF > /tmp/pbs_conf.$$
#
# Create and define queue verylong
#
create queue verylong
set queue verylong queue_type = Execution
set queue verylong Priority = 40
set queue verylong max_running = 10
set queue verylong resources_max.cput = 72:00:00
set queue verylong resources_min.cput = 12:00:01
set queue verylong resources_default.cput = 72:00:00
set queue verylong enabled = True
set queue verylong started = True
#
# Create and define queue long
#
create queue long
set queue long queue_type = Execution
set queue long Priority = 60
set queue long max_running = 10
set queue long resources_max.cput = 12:00:00
set queue long resources_min.cput = 02:00:01
set queue long resources_default.cput = 12:00:00
set queue long enabled = True
set queue long started = True
#
# Create and define queue medium
#
create queue medium
set queue medium queue_type = Execution
set queue medium Priority = 80
set queue medium max_running = 10
set queue medium resources_max.cput = 02:00:00
set queue medium resources_min.cput = 00:20:01
set queue medium resources_default.cput = 02:00:00
set queue medium enabled = True
set queue medium started = True
#
# Create and define queue small
#
create queue small
set queue small queue_type = Execution
set queue small Priority = 100
set queue small max_running = 10
set queue small resources_max.cput = 00:20:00
set queue small resources_default.cput = 00:20:00
set queue small enabled = True
set queue small started = True                   
#
# Create and define queue default
#
create queue default
set queue default queue_type = Route
set queue default max_running = 10
set queue default route_destinations = small
set queue default route_destinations += medium
set queue default route_destinations += long
set queue default route_destinations += verylong
set queue default enabled = True
set queue default started = True
#
# Set server attributes.
#
set server scheduling = True
set server max_user_run = 6
set server acl_host_enable = True
set server acl_hosts = *
set server default_queue = default
set server log_events = 63
set server mail_from = root
set server query_other_jobs = True
set server resources_default.cput = 01:00:00
set server resources_default.neednodes = 1
set server resources_default.nodect = 1
set server resources_default.nodes = 1
set server scheduler_iteration = 60
set server default_node = 1
EOF
  echo "PBS will be configured as follow:"
  echo "========================================================"
  cat /tmp/pbs_conf.$$
  echo "========================================================"
  echo "You may change it by editing the file '/tmp/pbs_conf.$$'"
  echo -n "Press any key to continue.."
  read anykey
  /opt/pbs/bin/qmgr < /tmp/pbs_conf.$$
  mv /tmp/pbs_conf.$$ /usr/share/doc/openpbs/pbs_conf

  # queue defined above do not work until you start them
  /opt/pbs/bin/qstart default
  /opt/pbs//bin/qenable default

  rm -f /tmp/pbs_conf.$$
}

ganglia() {
  if [ "$(dpkg -l ganglia-monitor | grep "ganglia" | cut -d" " -f1)" = "ii" ]; then continue; fi

  # install
  apt-get -y install ganglia-monitor gmetad ganglia-webfrontend
  drbl-get -y install ganglia-monitor

  # configure
  # 1. ganglia-monitor
  removeentries "$STARTTAG" "$ENDTAG" /etc/gmond.conf > /tmp/gmond.conf.$$
  echo "$STARTTAG" >> /tmp/gmond.conf.$$
  ## trusted_hosts
  echo -n "trusted_hosts=" >> /tmp/gmond.conf.$$
  for netdev in `cat /proc/net/dev | awk -F: '/eth.:|tr.:/{print $1}'`; do
    ip="$(/sbin/ifconfig $netdev | grep "inet addr:" | cut -d: -f2 | cut -d' ' -f1)"
    echo -n "$ip " >> /tmp/gmond.conf.$$
  done
  cat /etc/dhcp3/dhcpd.conf | grep "fixed-address" | cut -d';' -f1 | awk '{ print $2; }' |\
  while read ip; do
    echo -n "$ip " >> /tmp/gmond.conf.$$
  done
  echo >> /tmp/gmond.conf.$$
  echo "$ENDTAG" >> /tmp/gmond.conf.$$
  mv /tmp/gmond.conf.$$ /etc/gmond.conf

  drbl-cp /etc/gmond.conf [:ALL_HOSTS:]/etc
  # 2. gmetad
  removeentries "$STARTTAG" "$ENDTAG" /etc/gmetad.conf > /tmp/gmetad.conf.$$
  /usr/bin/perl -p -i -e "s/^data_source/# data_source/g" /tmp/gmetad.conf.$$
  echo "$STARTTAG" >> /tmp/gmetad.conf.$$
  ## data_source
  echo -n "data_source \"$(hostname)\" localhost " >> /tmp/gmetad.conf.$$
  while read ip; do
    echo -n "$ip " >> /tmp/gmetad.conf.$$
  done
  ## trusted_hosts
  echo -n "trusted_hosts=" >> /tmp/gmetad.conf.$$
  for netdev in `cat /proc/net/dev | awk -F: '/eth.:|tr.:/{print $1}'`; do
    ip="$(/sbin/ifconfig $netdev | grep "inet addr:" | cut -d: -f2 | cut -d' ' -f1)"
    echo -n "$ip " >> /tmp/gmetad.conf.$$
  done
  cat /etc/dhcp3/dhcpd.conf | grep "fixed-address" | cut -d';' -f1 | awk '{ print $2; }' |\
  while read ip; do
    echo -n "$ip " >> /tmp/gmetad.conf.$$
  done
  echo >> /tmp/gmetad.conf.$$
  echo "$ENDTAG" >> /tmp/gmetad.conf.$$
  mv /tmp/gmetad.conf.$$ /tmp/gmetad.conf

  # restart
  /etc/init.d/ganglia-monitor restart
  /etc/init.d/gmetad restart
  drbl-doit -b /etc/init.d/ganglia-monitor restart
  echo "I had installed the ganglia-webfrontend for you."
  echo "After apache installed (apt-get install apache),"
  echo "you can get the status of your gridbox via http://localhost/ganglia"
  echo "Press any key to continue..."
  read anykey
}

globus() {
  ncups=$1
  if [ -d /opt/Globus/globus-2.4.2 ]; then return; fi
  /opt/drbl/misc/globus-2.4.2.sh $ncups
  echo
}

install_if_necessary

case "$1" in
  "start")
    ##
    /etc/init.d/pbs_server restart
    #/etc/init.d/pbs_sched restart
    /etc/init.d/maui restart
    /etc/init.d/pbs_mom restart
    /usr/sbin/update-rc.d pbs_server defaults 60
    #/usr/sbin/update-rc.d pbs_sched defaults 61
    /usr/sbin/update-rc.d maui defaults 61
    /usr/sbin/update-rc.d pbs_mom defaults 62
    drbl-doit -b /etc/init.d/pbs_mom restart
    drbl-cp /etc/rc2.d/S62pbs_mom [:ALL_HOSTS:]/etc/rc2.d
    ## globus
    update-inetd --enable gsigatekeeper
    update-inetd --enable gsiftp
    /etc/init.d/inetd restart
    if [ -e /etc/rc2.d/S99globus-mds ]; then /etc/rc2.d/S99globus-mds start; fi
    ;;
  "stop")
    ## openpbs & maui
    /etc/init.d/pbs_server stop
    #/etc/init.d/pbs_sched stop
    /etc/init.d/maui stop
    /etc/init.d/pbs_mom stop
    /opt/drbl/bin/drbl-doit -b /etc/init.d/pbs_mom stop
    /usr/sbin/update-rc.d -f pbs_server remove
    /usr/sbin/update-rc.d -f pbs_sched remove
    /usr/sbin/update-rc.d -f maui remove
    #/usr/sbin/update-rc.d -f pbs_mom remove
    drbl-rm [:ALL_HOSTS:]/etc/rc2.d/S62pbs_mom
    ## globus 2.4.2
    /usr/sbin/update-inetd --disable gsigatekeeper
    /usr/sbin/update-inetd --disable gsiftp
    /etc/init.d/inetd restart
    if [ -e /etc/rc2.d/S99globus-mds ]; then /etc/rc2.d/S99globus-mds stop; fi
    ;;
esac
