#!/bin/bash -e

  #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  #
  # Script Name: chameleon_cluster_setup
  # Author:      Cristian Ramon-Cortes Vilarrodona
  #              Barcelona SuperComputing Center (BSC-CNS)
  #
  # Description: Script to setup a COMPSs cluster within a
  #              Chameleon lease
  #
  #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

  ##########################################################
  # Script variables
  user=cc
  instanceCreationTime=8        # Iterations over 30s
  sshUpTime=6			# Iterations over 30s
  randomID=$RANDOM
  tmpFile=/tmp/compss-workers-${randomID}.tmp
  HALF_MIN=30s
  SLEEP_BETWEEN_WORKER_CREATION=5

  ##########################################################
  # Prompt warning message
  echo "!! WARNING: Remember to source the OpenStack RC File"
  echo " "
  sleep 2s

  # Prompt messages to get information
  echo "Provide the name of the COMPSs Master Instance (this instance):"
  read -r masterName
  echo "Provide the reservation ID to deploy COMPSs:"
  read -r reservationId
  echo "Provide the number of COMPSs Workers:"
  read -r numWorkers
  echo " "

  ##########################################################
  # Retrieve other information
  echo "* Retrieving configuration parameters from Chameleon..."
  image=$(nova show $masterName | grep image | tr "|" "\t" | awk {'print $2'})
  netId=$(neutron net-list | grep sharednet1 | tr "|" "\t" | awk {' print $1 '})


  ##########################################################
  # Launch workers 
  echo "* Launching workers..."
  # Insert COMPSs Master key to OpenStack. Create workers with COMPSsMaster key authorized
  nova keypair-add --pub_key /home/cc/.ssh/id_dsa.pub COMPSsMaster${randomID}

  # Create workers
  for (( i=1; i<=$numWorkers; i++ )); do
    cmd="nova boot --flavor baremetal --image $image --key-name COMPSsMaster${randomID} --nic net-id=$netId --hint reservation=$reservationId COMPSsWorker$i"
    echo "$cmd"
    $cmd
    sleep $SLEEP_BETWEEN_WORKER_CREATION
  done

  ##########################################################
  # Waiting Workers creation
  echo "* Waiting for COMPSs Workers creation (eta 7 min)"
  for (( i=1; i<=$instanceCreationTime; i++ )); do
    printf "."
    sleep ${HALF_MIN}
  done
  printf "\n"

  for (( i=1; i<=$numWorkers; i++ )); do
    # Wait for each worker
    status=$(nova list | grep "COMPSsWorker$i" | tr "|" "\t" | awk {' print $3 '})
    while [ "$status" != "ACTIVE" ]; do
      sleep ${HALF_MIN}
      status=$(nova list | grep "COMPSsWorker$i" | tr "|" "\t" | awk {' print $3 '})
    done
    echo "   - COMPSsWorker$i is ACTIVE"
  done


  ##########################################################
  # Retrieving COMPSs Workers information
  echo "* Retrieving COMPSs Workers information..."

  echo "# Automatically added hostnames by chameleon_cluster_setup" > $tmpFile
  workerIPs=""
  for (( i=1; i<=$numWorkers; i++ )); do
    workerIP=$(nova show COMPSsWorker$i | grep "network" | tr "|" "\t" | awk {' print $3 '} | tr "," "\t" | awk {'print $1 '})
    # Update worker list
    workerIPs="$workerIPs $workerIP"
    # Update hosts tmp file"
    echo "$workerIP	COMPSsWorker$i" >> $tmpFile
    # Log worker IP
    echo "   - COMPSsWorker$i has IP = $workerIP"
  done

  # Adding configuration to COMPSs Master /etc/hosts file
  sudo /bin/bash -c "cat $tmpFile >> /etc/hosts"
  masterIP=$(nova show $masterName | grep "network" | tr "|" "\t" | awk {' print $3 '} | tr "," "\t" | awk {'print $1 '})
  echo "$masterIP     COMPSsMaster" >> $tmpFile

  # Configuring COMPSs Workers
  echo "* Configuring COMPSs Workers... (eta 3 min)"
  for (( i=1; i<=$sshUpTime; i++ )); do
    printf "."
    sleep ${HALF_MIN}
  done
  printf "\n"

  for workerIP in $workerIPs; do
    scp -o StrictHostKeyChecking=no $tmpFile $user@$workerIP:$tmpFile
    ssh -t -t -o StrictHostKeyChecking=no -o BatchMode=yes -o ChallengeResponseAuthentication=no $user@$workerIP "sudo /bin/bash -c 'cat $tmpFile >> /etc/hosts'"
    ssh -t -t -o StrictHostKeyChecking=no -o BatchMode=yes -o ChallengeResponseAuthentication=no $user@$workerIP "rm -f $tmpFile"
  done 

  # Clean tmpfile
  rm -f $tmpFile


  ##########################################################
  # Update COMPSs project / resources files
  echo "* Updating COMPSs project and resources files..."
  project=/opt/COMPSs/Runtime/configuration/xml/projects/default_project.xml
  resources=/opt/COMPSs/Runtime/configuration/xml/resources/default_resources.xml

  cat > $project << EOT
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Project>
    <MasterNode/>

EOT
  for (( i=1; i<=$numWorkers; i++ )); do
    cat >> $project << EOT
    <ComputeNode Name="COMPSsWorker$i">
        <InstallDir>/opt/COMPSs/Runtime/scripts/system/</InstallDir>
        <WorkingDir>/tmp/COMPSsWorker$i/</WorkingDir>
        <User>$user</User>
    </ComputeNode>

EOT
  done
  cat >> $project << EOT
</Project>
EOT

  cat > $resources << EOT
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ResourcesList>
EOT
  for (( i=1; i<=$numWorkers; i++ )); do
    cat >> $resources << EOT
    <ComputeNode Name="COMPSsWorker$i">
        <Processor Name="MainProcessor">
            <ComputingUnits>24</ComputingUnits>
            <Architecture>IA32</Architecture>
            <Speed>3.0</Speed>
        </Processor>
        <OperatingSystem>
            <Type>Linux</Type>
        </OperatingSystem>
        <Memory>
            <Size>125</Size>
        </Memory>
        <Software>
            <Application>JAVA</Application>
            <Application>PYTHON</Application>
            <Application>EXTRAE</Application>
            <Application>COMPSS</Application>
        </Software>
        <Adaptors>
            <Adaptor Name="integratedtoolkit.nio.master.NIOAdaptor">
                <SubmissionSystem>
                    <Interactive/>
                </SubmissionSystem>
                <Ports>
                    <MinPort>43001</MinPort>
                    <MaxPort>43102</MaxPort>
                </Ports>
            </Adaptor>
            <Adaptor Name="integratedtoolkit.gat.master.GATAdaptor">
                <SubmissionSystem>
                    <Interactive/>
                </SubmissionSystem>
                <BrokerAdaptor>sshtrilead</BrokerAdaptor>
            </Adaptor>
        </Adaptors>
    </ComputeNode>

EOT
  done
  cat >> $resources << EOT
</ResourcesList>
EOT


  ##########################################################
  # End
  echo "SUCCESS!"
  exit

