Dev compute script generation
[osm/openvim.git] / scripts / host-add-develop.sh
index ed84cdf..d62db8d 100755 (executable)
@@ -1,3 +1,4 @@
+
 #!/bin/bash
 
 ##
 #Get configuration of a host for using it as a compute node
 
 function usage(){
-    echo  -e "usage: $0 user ip_name nb_cores GiB_memory nb_10GB_interfaces [hostname] [>> host.yaml]\n  Get host parameters and generated a yaml file to be used for openvim host-add"
-    echo -e "  - In case hostname is not specified it will be used the name of the machine where the script is run"
-    echo -e "  - nb_cores must be an odd number and bigger or equal to 4."
-    echo -e "  - GiB_memory must be an odd number and bigger or equal to 16. 4GiB of memory will be reserved for the host OS, the rest will be used by VM."
-    echo -e "  - nb_10GB_interfaces must be an odd number and bigger or equal to 4."
-    echo -e "  - The output will be a server descriptor with two numas and resources (memory, cores and interfaces) equally distributed between them."
-    echo -e "  - Each interface (physical funtion) will have defined 8 SR-IOV (virtual functions)."
+
+    echo -e "\nUsage: $0 --user <user> --ip=<X.X.X.X> --cores=<core_number> --huge-pages-1G=<huga_pages_number> --nb-10GB-interfaces==<interface_number>"
+    echo -e "Generate a develop host yaml to be used for openvim host-add\n"
+    echo -e "   --user  -u  <user>        Server OAM Ip"
+    echo -e "   --ip    -i  <ip>          Server hostname"
+    echo -e "   --cores -c  <cores>       Numa Cores available must be an odd number and bigger or equal to 4."
+    echo -e "   --huge-pages-1G      -hp  <huge_pages_number>   Must be an odd number and bigger or equal to 16. 4GiB of memory will be reserved for the host OS, the rest will be used by VM."
+    echo -e "   --nb-10GB-interfaces -ni  <nb-10GB-interfaces>  Dataplane interfaces must be an odd number and bigger or equal to 4."
+    echo -e "\n"
+    echo -e "The output will be a server descriptor with two numas and resources (memory, cores and interfaces) equally distributed between them."
+    echo -e "Each interface (physical funtion) will have defined 8 SR-IOV (virtual functions)."
+    echo -e "\n"
     exit 1
 }
 
-function get_hash_value() {   echo `eval  echo $\{\`echo $1[$2]\`\}`; }
+function get_hash_value() {   echo `eval  echo $\{\`echo $USER[$IP]\`\}`; }
 
 function get_mac(){
   seed=$1
@@ -47,105 +53,298 @@ function get_mac(){
   echo $mac
 }
 
+function _parse_opts(){
 
-#check root privileges and non a root user behind
+    #help argument
+    if [ -n "$option_help" ];
+    then
+        usage
+    fi
 
-[ "$#" -lt "5" ] && echo "Missing parameters" && usage
-[ "$#" -gt "6" ] && echo "Too many parameters" && usage
-HOST_NAME=`cat /etc/hostname`
-[ "$#" -eq "6" ] && HOST_NAME=$6
-FEATURES_LIST="lps,dioc,hwsv,tlbps,ht,lps,64b,iommu"
-NUMAS=2
-CORES=$3
-MEMORY=$4
-INTERFACES=$5
-
-#Ensure the user input is big enough
-([ $((CORES%2)) -ne 0 ] || [ $CORES -lt 4 ] ) && echo -e "ERROR: Wrong number of cores\n" && usage
-([ $((MEMORY%2)) -ne 0 ] || [ $MEMORY -lt 16 ] ) && echo -e "ERROR: Wrong number of memory\n" && usage
-([ $((INTERFACES%2)) -ne 0 ] || [ $INTERFACES -lt 4 ] ) && echo -e "ERROR: Wrong number of interfaces\n" && usage
-
-#Generate a cpu topology for 4 numas with hyperthreading
-CPUS=`pairs_gap=$((CORES/NUMAS));numa=0;inc=0;sibling=0;for((thread=0;thread<=$((pairs_gap-1));thread++)); do printf " ${numa}-${sibling}-${thread} ${numa}-${sibling}-$((thread+pairs_gap))";numa=$(((numa+1)%$NUMAS)); sibling=$((sibling+inc)); inc=$(((inc+1)%2));  done`     
-
-#in this developing/fake server all cores can be used
-
-echo "#This file was created by $0"
-echo "#for adding this compute node to openvim"
-echo "#copy this file to openvim controller and run"
-echo "#openvim host-add <this>"
-echo
-echo "host:"
-echo "  name:    $HOST_NAME"
-echo "  user:    $1"
-echo "  ip_name: $2"
-echo "host-data:"
-echo "  name:        $HOST_NAME"
-echo "  user:        $1"
-echo "  ip_name:     $2"
-echo "  ranking:     100"
-echo "  description: $HOST_NAME"
-echo "  features:    $FEATURES_LIST"
-echo "  numas:"
-
-numa=0
-last_iface=0
-iface_counter=0
-while [ $numa -lt $NUMAS ]
-do
-  echo "  - numa_socket:  $numa"
-#MEMORY
-  echo "    hugepages: $((MEMORY/2-2))"
-  echo "    memory:    $((MEMORY/2))"
-
-#CORES
-  echo "    cores:"
-  for cpu in $CPUS
-  do
-    PHYSICAL=`echo $cpu | cut -f 1 -d"-"`
-    CORE=`echo $cpu | cut -f 2 -d"-"`
-    THREAD=`echo $cpu | cut -f 3 -d"-"`
-    [ $PHYSICAL != $numa ] && continue   #skip non physical
-    echo "    - core_id:   $CORE"
-    echo "      thread_id: $THREAD"
-    [ $CORE -eq 0 ] && echo "      status:    noteligible"
-  done
-
-  #GENERATE INTERFACES INFORMATION AND PRINT IT
-  seed=$RANDOM
-  echo "    interfaces:"
-  for ((iface=0;iface<$INTERFACES;iface+=2))
-  do
-    name="iface$iface_counter"
-    bus=$((iface+last_iface))
-    pci=`printf "0000:%02X:00.0" $bus`
-    mac=`get_mac $seed`
-    seed=$((seed+1))
-  
-    echo "    - source_name: $name"
-    echo "      Mbps: 10000"
-    echo "      pci: \"$pci\""
-    echo "      mac: \"$mac\""
-    echo "      switch_dpid: \"01:02:03:04:05:06\""
-    echo "      switch_port: fake0/$iface_counter"
-    echo "      sriovs:"
-
-    for((nb_sriov=0;nb_sriov<8;nb_sriov++))
+    #User argument
+    [ -z "$option_user" ] && echo -e "ERROR: User argument is mandatory, --user=<user>\n" && usage
+    USER=${option_user}
+
+    [ -z "$option_ip" ] && echo -e "ERROR: OAM IP argument is mandatory, --ip=<X.X.X.X>\n" && usage
+    IP=${option_ip}
+
+    #TODO to be checl diference between real cores an numa cores
+    #cores argument
+    REAL_CORES=$(grep -c "^processor" "/proc/cpuinfo")
+    if [ -z "$option_cores" ] ; then
+        CORES=REAL_CORES
+    else
+        CORES=${option_cores}
+    fi
+
+    #Ensure the core user input is big enough
+    ([ $((CORES%2)) -ne 0 ]) && echo -e "ERROR: Wrong number of cores\n" && usage
+
+    MEMORY=$(($(grep MemTotal /proc/meminfo | awk '{print $2}') /1024/1024))
+    if [ -z "$option_huge_pages_1G" ] ; then
+        HUGE_PAGES_MEMORY=0
+    else
+        HUGE_PAGES_MEMORY=${option_huge_pages_1G}
+    fi
+    #Ensure the memory user input is big enough
+    #([ $((MEMORY%2)) -ne 0 ] || [ $MEMORY -lt 16 ] ) && echo -e "ERROR: Wrong number of memory\n" && usage
+
+    #nb_10GB_interfaces argument
+    if [ -z "$nb_10GB_interfaces" ] ; then
+        INTERFACES=8
+    else
+        INTERFACES=${nb_10GB_interfaces}
+    fi
+    ([ $((INTERFACES%2)) -ne 0 ] || [ $INTERFACES -lt 4 ] ) && echo -e "ERROR: Wrong number of interfaces\n" && usage
+
+    # Parameter by default
+    NUMAS=1
+    ([ $((NUMAS%2)) -ne 0 ]) && NUMAS=1
+}
+
+function _generate_compute_develope_yaml(){
+
+    _yaml_init
+
+    FEATURES_LIST="lps,dioc,hwsv,tlbps,ht,lps,64b,iommu"
+
+    #Generate a cpu topology for 4 numas with hyperthreading
+    #in this developing/fake server all cores can be used
+    #TODO check if this calculation is correct
+    echo2file "#This file was created by $0"
+    echo2file "#for adding this compute node to openvim"
+    echo2file "#copy this file to openvim controller and run"
+    echo2file "#openvim host-add <this>"
+    echo2file
+    echo2file "host:"
+    echo2file "  name:    $HOST_NAME"
+    echo2file "  user:    $USER"
+    echo2file "  ip_name: $IP"
+    echo2file "host-data:"
+    echo2file "  name:        $HOST_NAME"
+    echo2file "  user:        $USER"
+    echo2file "  ip_name:     $IP"
+    echo2file "  ranking:     100"
+    echo2file "  description: $HOST_NAME"
+    echo2file "  features:    $FEATURES_LIST"
+    echo2file "  numas:"
+
+    numa=0
+    last_iface=0
+    iface_counter=0
+
+    while [ $numa -lt $NUMAS ]
     do
-      pci=`printf "0000:%02X:10.%i" $bus $nb_sriov`
-      mac=`get_mac $seed`
-      seed=$((seed+1))
-      echo "      - mac: \"$mac\""
-      echo "        pci: \"$pci\""
-      echo "        source_name: $nb_sriov"
+
+      HUGE_PAGES=$((HUGE_PAGES_MEMORY/2-2))
+      ([ ${HUGE_PAGES} -lt -1 ]) && HUGE_PAGES=0
+
+      echo2file "  - numa_socket:  $numa"
+    #MEMORY
+      echo2file "    hugepages: $((HUGE_PAGES))"
+      echo2file "    memory:    $((MEMORY/$NUMAS))"
+    #CORES
+      echo2file "    cores:"
+
+      for((n_core=0;n_core<$REAL_CORES;n_core++))
+        do
+            THREAD_ID=$(($n_core+1))
+            CORE_ID=$(($((${n_core}+${numa}))/2))
+            echo2file "    - core_id:   ${CORE_ID}"
+            echo2file "      thread_id: ${THREAD_ID}"
+            [ $CORE_ID -eq 0 ] && echo2file "      status:    noteligible"
+
+            thread_counter=$((thread_counter+1))
+      done
+      # GENERATE INTERFACES INFORMATION AND PRINT IT
+      seed=$RANDOM
+      echo2file "    interfaces:"
+      for ((iface=0;iface<$INTERFACES;iface+=2))
+      do
+        name="iface$iface_counter"
+        bus=$((iface+last_iface))
+        bus=$((iface))
+        pci=`printf "0000:%02X:00.0" $bus`
+        mac=`get_mac $seed`
+        seed=$((seed+1))
+
+        echo2file "    - source_name: $name"
+        echo2file "      Mbps: 10000"
+        echo2file "      pci: \"$pci\""
+        echo2file "      mac: \"$mac\""
+        echo2file "      sriovs:"
+
+        PCI_COUNTER=0
+        for((nb_sriov=0;nb_sriov<8;nb_sriov++))
+        do
+          #PCI_COUNTER=$((PCI_COUNTER+2))
+          #echo2file "nb_sriov "$nb_sriov
+          #echo2file "PCI_COUNTER "$PCI_COUNTER
+
+          pci=`printf "0000:%02X:10.%i" $bus $nb_sriov`
+          mac=`get_mac $seed`
+          seed=$((seed+1))
+          echo2file "      - source_name: eth$nb_sriov"
+          echo2file "        mac: \"$mac\""
+          echo2file "        pci: \"$pci\""
+        done
+        iface_counter=$((iface_counter+1))
+      done
+      last_iface=$(((numa+1)*127/NUMAS+5)) #made-up formula for more realistic pci numbers
+      numa=$((numa+1))
     done
-  
-  iface_counter=$((iface_counter+1))
-  done
-  last_iface=$(((numa+1)*127/NUMAS+5)) #made-up formula for more realistic pci numbers 
-  
-
-  numa=$((numa+1))
-done
+}
+
+function _yaml_init(){
+    echo -n > host-develope.yaml
+}
+
+function echo2file(){
+    echo "${1}"
+    echo "${1}" >> host-develope.yaml
+}
+
+function _get_opts()
+{
+    [[ ${BASH_SOURCE[0]} != $0 ]] && ___exit="return" || ___exit="exit"
+
+    options="$1"
+    shift
+
+    get_argument=""
+    #reset variables
+    params=""
+    for option_group in $options
+    do
+        _name=${option_group%%:*}
+        _name=${_name%=}
+        _name=${_name//-/_}
+        eval option_${_name}='""'
+    done
+
+    while [[ $# -gt 0 ]]
+    do
+        argument="$1"
+        shift
+        if [[ -n $get_argument ]]
+        then
+            [[ ${argument:0:1} == "-" ]] && echo "option '-$option' requires an argument"  >&2 && $___exit 1
+            eval ${get_argument}='"$argument"'
+            #echo option $get_argument with argument
+            get_argument=""
+            continue
+        fi
+
+
+        #short options
+        if [[ ${argument:0:1} == "-" ]] && [[ ${argument:1:1} != "-" ]] && [[ ${#argument} -ge 2 ]]
+        then
+            index=0
+            while index=$((index+1)) && [[ $index -lt ${#argument} ]]
+            do
+                option=${argument:$index:1}
+                bad_option=y
+                for option_group in $options
+                do
+                    _name=""
+                    for o in $(echo $option_group | tr ":=" " ")
+                    do
+                        [[ -z "$_name" ]] && _name=${o//-/_}
+                        #echo option $option versus $o
+                        if [[ "$option" == "${o}" ]]
+                        then
+                            eval option_${_name}='${option_'${_name}'}-'
+                            bad_option=n
+                            if [[ ${option_group:${#option_group}-1} != "=" ]]
+                            then
+                                continue
+                            fi
+                            if [[ ${#argument} -gt $((index+1)) ]]
+                            then
+                                eval option_${_name}='"${argument:$((index+1))}"'
+                                index=${#argument}
+                            else
+                                get_argument=option_${_name}
+                                #echo next should be argument $argument
+                            fi
+
+                            break
+                        fi
+                    done
+                done
+                [[ $bad_option == y ]] && echo "invalid argument '-$option'?  Type -h for help" >&2 && $___exit 1
+            done
+        elif [[ ${argument:0:2} == "--" ]] && [[ ${#argument} -ge 3 ]]
+        then
+            option=${argument:2}
+            option_argument=${option#*=}
+            option_name=${option%%=*}
+            [[ "$option_name" == "$option" ]] && option_argument=""
+            bad_option=y
+            for option_group in $options
+            do
+                _name=""
+                for o in $(echo $option_group | tr ":=" " ")
+                do
+                    [[ -z "$_name" ]] && _name=${o//-/_}
+                    #echo option $option versus $o
+                    if [[ "$option_name" == "${o}" ]]
+                    then
+                        bad_option=n
+                        if [[ ${option_group:${#option_group}-1} != "=" ]]
+                        then #not an argument
+                            [[ -n "${option_argument}" ]] && echo "option '--${option%%=*}' do not accept an argument " >&2 && $___exit 1
+                            eval option_${_name}='"${option_'${_name}'}-"'
+                        elif [[ -n "${option_argument}" ]]
+                        then
+                            eval option_${_name}='"${option_argument}"'
+                        else
+                            get_argument=option_${_name}
+                            #echo next should be argument $argument
+                        fi
+                        break
+                    fi
+                done
+            done
+            [[ $bad_option == y ]] && echo "invalid argument '-$option'?  Type -h for help" >&2 && $___exit 1
+        elif [[ ${argument:0:2} == "--" ]]
+        then
+            option__="$*"
+            bad_option=y
+            for o in $options
+            do
+                if [[ "$o" == "--" ]]
+                then
+                    bad_option=n
+                    option__=" $*"
+                    break
+                fi
+            done
+            [[ $bad_option == y ]] && echo "invalid argument '--'?  Type -h for help" >&2 && $___exit 1
+            break
+        else
+            params="$params ${argument}"
+        fi
+
+    done
+
+    [[ -n "$get_argument" ]] && echo "option '-$option' requires an argument"  >&2 && $___exit 1
+    $___exit 0
+
+}
+
+#check root privileges and non a root user behind
+[ "${USER}" != "root" ] && echo "Needed root privileges" && _usage && exit -1
+
+#process options
+DIRNAME=$(readlink -f ${BASH_SOURCE[0]})
+DIRNAME=$(dirname $DIRNAME)
+
+#source ${DIRNAME}/get-options.sh "help:h user:u= ip:i= cores:c= huge-pages-1G:hp= nb-10GB-interfaces:ni="  $*
+_get_opts "help:h user:u= ip:i= cores:c= huge-pages-1G:hp= nb-10GB-interfaces:ni="  $*
+_parse_opts
+
+HOST_NAME=`cat /etc/hostname`
+
+_generate_compute_develope_yaml