blob: 01b877f2d9baf229fc35bd595e12301333b69e6a [file] [log] [blame]
#!/bin/bash
##
# Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
# This file is part of openvim
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# For those usages not covered by the Apache License, Version 2.0 please
# contact with: nfvlabs@tid.es
##
#Get configuration of a host for using it as a compute node
function usage(){
echo -e "\nUsage: $0 --user-name <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-name -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 " * Mandatory arguments"
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)."
exit 1
}
function get_hash_value() { echo `eval echo $\{\`echo $USER[$IP]\`\}`; }
function get_mac(){
seed=$1
b1=$((seed%16)); seed=$((seed/16))
b2=$((seed%16)); seed=$((seed/16))
b3=$((seed%16)); seed=$((seed/16))
b4=$((seed%16)); seed=$((seed/16))
b5=$((seed%16)); seed=$((seed/16))
mac=`printf "%02X:%02X:%02X:%02X:%02X:%02X" 2 $b5 $b4 $b3 $b2 $b1`
echo $mac
}
function _parse_opts(){
#help argument
if [ -n "$option_help" ];
then
usage
fi
#User argument
[ -z "$option_user_name" ] && echo -e "ERROR: User argument is mandatory, --user-name=<user>\n" && usage
USER_NAME=${option_user_name}
[ -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_NAME"
echo2file " ip_name: $IP"
echo2file "host-data:"
echo2file " name: $HOST_NAME"
echo2file " user: $USER_NAME"
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
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
}
function _yaml_init(){
echo -n > host-develope.yaml
}
function echo2file(){
echo "${1}"
echo "${1}" >> host-develope.yaml
}
function _get_opts()
{
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 && return 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 && return 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 && return 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 && return 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 && return 1
break
else
params="$params ${argument}"
fi
done
[[ -n "$get_argument" ]] && echo "option '-$option' requires an argument" >&2 && return 1
return 0
}
#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-name:u= ip:i= cores:c= huge-pages-1G:hp= nb-10GB-interfaces:ni=" $* || exit 1
_parse_opts
#check root privileges
[ "${USER}" != "root" ] && echo "Needed root privileges" >&2 && exit 2
#check root privileges and non a root user behind
HOST_NAME=`cat /etc/hostname`
_generate_compute_develope_yaml