summaryrefslogtreecommitdiff
path: root/src/g5k
diff options
context:
space:
mode:
authorLoic Guegan <manzerberdes@gmx.com>2019-05-22 11:24:17 +0200
committerLoic Guegan <manzerberdes@gmx.com>2019-05-22 11:24:17 +0200
commit8bdcd37ac44fe96d2c59424a24752f87f0444e36 (patch)
treee31a0fe38c01bc6814a0b35474875fe538ea87c2 /src/g5k
parent5a77b67d6baae0414310d29cab6f240963866062 (diff)
Update paper
Diffstat (limited to 'src/g5k')
-rw-r--r--src/g5k/README.md12
-rwxr-xr-xsrc/g5k/clients.py48
-rwxr-xr-xsrc/g5k/energyFromLogs.sh26
-rwxr-xr-xsrc/g5k/recordEnergy.sh42
-rwxr-xr-xsrc/g5k/run-sim.sh39
-rw-r--r--src/g5k/setup-mysql.sql8
-rwxr-xr-xsrc/g5k/utils.sh137
7 files changed, 312 insertions, 0 deletions
diff --git a/src/g5k/README.md b/src/g5k/README.md
new file mode 100644
index 0000000..15969f8
--- /dev/null
+++ b/src/g5k/README.md
@@ -0,0 +1,12 @@
+# G5K Simulation Scripts
+
+- client.py is run by utils.sh
+- setup-mysql.sql used by utils.sh to configure server database
+- utils.sh contains functionnality to:
+ - Subscribe in G5K
+ - Kill all VMs on the subscribed nodes
+ - Inspect the database
+ - Purge the database
+- run-sim.sh use utils.sh to run all the simulations
+- record-energy.sh fetch energy csv files from G5K
+- energyFromLogs.sh use record-energy.sh to fetch energy data using run-sim.sh logs
diff --git a/src/g5k/clients.py b/src/g5k/clients.py
new file mode 100755
index 0000000..db40996
--- /dev/null
+++ b/src/g5k/clients.py
@@ -0,0 +1,48 @@
+#!/usr/bin/python
+from __future__ import division
+import os,sys,random, time,datetime
+from subprocess import Popen
+
+# Check script argument
+if len(sys.argv) != 6:
+ print("Usage: "+sys.argv[0]+" <mysqlServerIp> <nbSensors> <nbSensorsFactor> <requestPerSensor> <sendInterval>")
+ exit(1)
+
+# Init script parameters
+serverIp=sys.argv[1]
+nbSensors=int(sys.argv[2])
+nbSensorsFactor=int(sys.argv[3])
+effectiveNbSensors=nbSensors*nbSensorsFactor
+requestPerSensor=int(sys.argv[4])
+sendInterval=int(sys.argv[5])
+avgSiteTemp=list()
+for i in range(0,effectiveNbSensors):
+ avgSiteTemp.append(random.randint(-10,30))
+
+
+def insert(sensorId, value):
+ """ Send value of sensorId into the database """
+ stamp=int(time.mktime(datetime.datetime.today().timetuple()))
+ insertCMD = "mysql -u user --password=mysql --host="+serverIp+" experiment -e"
+ insertCMD=insertCMD.split()
+ insertCMD.append("INSERT INTO temperature (id,stamp,val) VALUES("+str(sensorId)+","+str(stamp)+","+str(value)+");")
+ Popen(insertCMD) # Run command asynchronously
+
+def send():
+ """ Send temperature of each sensors into the database """
+ for i in range(0,effectiveNbSensors):
+ insert(i,random.gauss(avgSiteTemp[i], 3))
+
+
+# Print infos
+print("Launching clients with:")
+print(" - Mysql Server IP {:>20}".format(serverIp))
+print(" - Number of sensors {:>18}".format(effectiveNbSensors))
+print(" - Number of request per sensor {:>7}".format(effectiveNbSensors))
+
+# Send data
+for i in range(0, requestPerSensor):
+ send()
+ time.sleep(sendInterval) # We assume send() take no time
+
+
diff --git a/src/g5k/energyFromLogs.sh b/src/g5k/energyFromLogs.sh
new file mode 100755
index 0000000..0336f03
--- /dev/null
+++ b/src/g5k/energyFromLogs.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+
+logFile="$(dirname $(readlink -f $0))"/simLogs.txt
+
+
+getValue () {
+ line=$(echo "$1" | grep "Simulation para"|sed "s/Simulation parameters: //g")
+ key=$2
+ echo "$line"|awk 'BEGIN{RS=" ";FS=":"}"'$key'"==$1{gsub("\n","",$0);print $2}'
+}
+
+IFS=$'\n'
+for cmd in $(cat $logFile|grep "Simulation parameters")
+do
+ nodeName=$(getValue $cmd serverNodeName)
+ from=$(getValue $cmd simStart)
+ to=$(getValue $cmd simEnd)
+ vmSize=$(getValue $cmd vmSize)
+ nbSensors=$(getValue $cmd nbSensors)
+ simKey=$(getValue $cmd simKey)
+ delayStart=$(getValue $cmd delayStart)
+ ./recordEnergy.sh nova $nodeName $from $to "${simKey}_${vmSize}VMSIZE_${nbSensors}NBSENSORS_${from}${to}.csv"
+ ./recordEnergy.sh nova $nodeName $delayStart $from "${simKey}_${vmSize}VMSIZE_${nbSensors}NBSENSORS_${from}${to}_IDLE.csv"
+done
+
diff --git a/src/g5k/recordEnergy.sh b/src/g5k/recordEnergy.sh
new file mode 100755
index 0000000..c345136
--- /dev/null
+++ b/src/g5k/recordEnergy.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+# Parse argument
+[ $# != 5 ] && { echo "Usage: $0 <cluster-name> <node-name> <from> <to> <output-file>"; exit 1; }
+
+# Init arguments
+clusterName="$1"
+nodeName="$2"
+outputFile="$5"
+wattmeter=$(curl -s https://api.grid5000.fr/stable/sites/lyon/clusters/${clusterName}/nodes/${nodeName}.json | jq -r '.sensors.power.via.pdu[0].uid')
+port=$(curl -s https://api.grid5000.fr/stable/sites/lyon/pdus/${wattmeter}.json | jq -r '.ports|to_entries|map(select(.value=="'${nodeName}'"))[0].key')
+energyEntry=$(( 5 + port )) # Define the entry in the CSV that correspond to the correct energy value
+
+if [ -z $wattmeter ] || [ -z $port ]
+then
+ echo -ne "\nCannot find energy informations (wattmeter/port) for node $nodeName\n"
+ echo -ne "\nCheck the node name (do not use hostname! only node name ex: nova-7)\n"
+ exit 1
+fi
+
+echo "Node ${nodeName} is connected on wattmeter ${wattmeter} on port ${port}"
+
+# Fetching energy and save in csv format
+from=$(date -d "@$3" "+%s")
+to=$(date -d "@$4" "+%s")
+echo "ts,energy" > $outputFile # Write CSV header
+for time in $(seq $from 3600 $to)
+do
+ # We need gz extension if it is not the current hour
+ [ $(date -d "@$time" "+%Y-%m-%dT%H") != $(date "+%Y-%m-%dT%H") ] && ext='.gz' || ext=''
+ powerFilename=$(date -d "@$time" "+power.csv.%Y-%m-%dT%H${ext}")
+ url="http://wattmetre.lyon.grid5000.fr/data/${wattmeter}-log/${powerFilename}"
+ echo "- Fetching logs from ${url}"
+
+ # Fetch logs data
+ [ ! -z $ext ] && csvContent=$(curl -s "${url}" | zcat) || csvContent=$(curl -s "${url}")
+
+ # Parse data and extract the right values in csv format
+ toSave=$(echo "$csvContent" | awk -F, 'int($3)>='$from'&& int($3)<='$to'{printf "%s,%s\n",$3,$5+'$port'};')
+ echo "$toSave" >> $outputFile # Save data in csv
+done
+echo "Done"
diff --git a/src/g5k/run-sim.sh b/src/g5k/run-sim.sh
new file mode 100755
index 0000000..9274677
--- /dev/null
+++ b/src/g5k/run-sim.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+# Parameters
+delay=60 # Delay before starting simulation (let CPU energy going down on the server)
+nbSensors=20 # Number of sensors that will send request to de server
+nbSensorsFactor=3 # nbSensors*nbSensorFactor
+simulationTime=300 # Approximative
+sensorsSendInterval=10 # Delay between sensors requests
+# requestPerSensor dynamically computed inside init-nodes
+vmSize=2048 # Number of alocated ram
+simKey="NONE"
+
+# Where script is located
+simScript=$(dirname $(readlink -f "$0"))/utils.sh
+
+# Build a function using the script
+initNodes () {
+ source "$simScript"
+}
+
+
+##### Test VM RAM #####
+simKey="vmSize"
+for vmSize in $(echo 1024 2048 4096)
+do
+ initNodes deploy
+ initNodes kill # Kill all vms (do not forget :D)
+done
+
+vmSize=2048 # Reset vmSize
+
+simKey="nbSensors"
+##### Test number of sensors #####
+for nbSensors in $(echo 20 100 300)
+do
+ initNodes deploy
+ initNodes kill # Kill all vms
+done
+
diff --git a/src/g5k/setup-mysql.sql b/src/g5k/setup-mysql.sql
new file mode 100644
index 0000000..05042a3
--- /dev/null
+++ b/src/g5k/setup-mysql.sql
@@ -0,0 +1,8 @@
+create DATABASE IF NOT EXISTS experiment;
+use experiment;
+create TABLE IF NOT EXISTS temperature (id INTEGER,stamp INTEGER, val INTEGER);
+
+use mysql;
+CREATE USER 'user'@'%' IDENTIFIED BY 'mysql';
+GRANT ALL ON experiment.* TO 'user'@'%';
+
diff --git a/src/g5k/utils.sh b/src/g5k/utils.sh
new file mode 100755
index 0000000..cf7ca23
--- /dev/null
+++ b/src/g5k/utils.sh
@@ -0,0 +1,137 @@
+#!/bin/bash
+
+##### Parameters #####
+if [ -z ${nbSensors+x} ] # If nbSensors exists, so all parameters are already define
+then
+ delay=60 # Delay before starting simulation (let CPU energy going down on the server)
+ nbSensors=30 # Number of sensors that will send request to de server
+ nbSensorsFactor=3 # nbSensors*nbSensorFactor
+ simulationTime=300 # Approximative
+ sensorsSendInterval=10 # Delay between sensors requests
+ vmSize=2048 # Number of alocated ram
+ simKey="NONE"
+fi
+nHours=3 # Reservation dutation
+requestPerSensor=$(( simulationTime / sensorsSendInterval )) # Theorical simulation time is $requestPerSensor*$sensorsSendInterval
+######################
+
+
+logFile="./simLogs.txt"
+log () {
+ echo -e "\033[0;34m$@\033[0m"
+}
+
+sshWait () {
+ log "Waiting for for an ssh connection to a vm ($1)"
+ error=255
+ until [ $error -eq 0 ]
+ do
+ ssh -q root@$1 echo "Connected to $(hostname)"
+ error=$?
+ sleep 4
+ done
+}
+
+if [ "$1" = "subscribe" ] && [ $# -eq 1 ]
+then
+ log "Subscribing..."
+ oarsub -l slash_22=1+{"virtual!='NO' AND cluster='nova'"}/nodes=2,walltime=$nHours 'sleep "10d"' # On node send request to the other
+# oarsub -l slash_22=1+{"virtual!='NO'"}/nodes=2,walltime=$nHours 'sleep "10d"' # On node send request to the other
+
+elif [ "$1" = "deploy" ] && [ $# -eq 1 ]
+then
+ # Get machine mac address
+ serverSubnet=$(g5k-subnets -im|sed "1q;d")
+ serverMac=$(echo "$serverSubnet"|sed "s/^.*\t//g")
+ serverIp=$(echo "$serverSubnet"|sed "s/\t.*$//g")
+ clientIp=$(hostname) # Not really a IP but :P
+ clientNode=$(hostname)
+ serverNode=$(cat $OAR_NODE_FILE|uniq|sed "s/$clientNode//g"|sed "s/ //g"|tr -d '\n')
+ onS="oarsh $serverNode" # For convenience
+
+
+ # Init vm images
+ log "Create server vm image"
+ $onS cp -n /grid5000/virt-images/debian9-x64-base.qcow2 /tmp/
+ $onS qemu-img create -f qcow2 -o backing_file=/tmp/debian9-x64-base.qcow2 /tmp/img.qcow2
+ sleep 1 # Wait for fun
+
+ # Build cloud init iso (to have ssh access witouth password
+ log "Create server cloud-init image"
+ $onS cp /grid5000/virt-images/cloud-init-example.sh /tmp/
+ $onS "cd /tmp && export cloud_init_key=\$(cat ~/.ssh/id_rsa.pub) && ./cloud-init-example.sh"
+ $onS "cd /tmp && genisoimage -output cloud-init-data.iso -volid cidata -joliet -rock cloud-init-data/user-data cloud-init-data/meta-data"
+
+ # Launch vm
+ log "Launch server vm"
+ $onS kvm -m ${vmSize}M -hda /tmp/img.qcow2 -netdev bridge,id=br0 -device virtio-net-pci,netdev=br0,id=nic1,mac=$serverMac -cdrom /tmp/cloud-init-data.iso -display none -daemonize &
+
+
+ ##### Server #####
+ onS="ssh root@$serverIp" # Don't forget to use vm
+ sshWait $serverIp
+ # One apt-get update seems to be not enought to get mysql-server
+ $onS "apt-get update && apt-get update"
+ $onS apt-get -y install mysql-server
+ # Enable mysql connection from outside
+ $onS sed -i "s/bind-address/#bind-address/g" /etc/mysql/mariadb.conf.d/50-server.cnf
+ $onS 'echo -e "[mysqld]\nmax_connections = 100000" >> /etc/mysql/my.cnf' # Otherwise you will have the error "TOO MANY CONNECTION"
+ $onS systemctl restart mysql
+ rsync -avh setup-mysql.sql root@$serverIp:/tmp/ # Send mysl setup script
+ $onS "mysql < /tmp/setup-mysql.sql" # Then execute it
+
+ ##### Start Simulation #####
+ serverNodeName=$(echo $serverNode|grep -o ^.*[-][0-9]*|tr -d '\n') # For logging
+ log "Simulation will start in ${delay}s"
+ delayStart=$(date "+%s") # Used to compute the idle energy consumption
+ sleep $delay
+ simStart=$(date "+%s")
+ echo "---------- Simulation (key=${simKey}) start at $simStart ($(date -d @${simStart}))" >> $logFile
+ python ./clients.py $serverIp $nbSensors $nbSensorsFactor $requestPerSensor $sensorsSendInterval
+ simEnd=$(date "+%s")
+ echo "Simulation parameters: serverNode:$serverNode serverIp:$serverIp serverMac:$serverMac clientNode:$clientNode clientNode:$clientNode clientMac:$clientMac delay:$delay delayStart:${delayStart} nbSensors:$nbSensors nbSensorsFactor:$nbSensorsFactor requestPerSensors:$requestPerSensor sensorsSendInterval:${sensorsSendInterval} simKey:${simKey} simStart:${simStart} simEnd:${simEnd} duration:$(( simEnd - simStart )) serverNodeName:${serverNodeName} vmSize:${vmSize}" >> $logFile
+ echo "./recordEnergy.sh nova $serverNodeName $simStart $simEnd energy_${simKey}_${nbSensors}NS_${vmSize}vmSize_${simStart}_${simEnd}.csv" >> $logFile
+ echo -e "---------- Simulation (key=${simKey}) end at ${simEnd} ($(date -d @${simEnd}))\n" >> $logFile
+ log "Simulation end ! Please see $logFile for more infos"
+ ##### End Simulation #####
+
+ ##### Print some infos #####
+ log "Network Settings:"
+ log " - Server $serverNode, $serverIp, $serverMac"
+ log " - Client $clientNode, $clientIp, $clientMac"
+ log "Simulation Settings:"
+ log " - Simulation delay ${delay}s"
+ log " - Number of sensors $(( nbSensors * nbSensorsFactor))"
+ log " - Number of request per sensors $requestPerSensor"
+ log " - Number of request per seconds on eachsensors $sensorsRequestPerSec"
+
+elif [ "$1" = "kill" ] && [ $# -eq 1 ]
+then
+ ##### Kill all kvm on the subscribed nodes #####
+ isServer=1
+ finished=0
+ for node in $(cat $OAR_NODE_FILE|uniq)
+ do
+ [ $isServer -eq 1 ] && { curMac=$serverMac; isServer=0; serverNode=$node; } || { curMac=$clientMac; finished=1; clientNode=$node; }
+ log "Killing vm on node $node"
+ oarsh $node pkill -9 qemu &
+ [ $finished -eq 1 ] && break
+ done
+elif [ "$1" = "inspect" ] && [ $# -eq 2 ]
+then
+ ##### Show content of the database #####
+ mysql --host="$2" -u user --password="mysql" experiment -e "SELECT * FROM temperature;"
+elif [ "$1" = "flush" ] && [ $# -eq 2 ]
+then
+ ##### Flush content of the temperature table #####
+ log "Cleaning database table..."
+ mysql --host="$2" -u user --password="mysql" experiment -e "TRUNCATE TABLE temperature;"
+else
+ echo "Usage:"
+ echo " - $0 subscribe"
+ echo " - $0 deploy"
+ echo " - $0 kill"
+ echo " - $0 inspect <serverIP>"
+ echo " - $0 flush <serverIP>"
+fi
+