blob: d54bf702d8bf760feeaa734a141f7094c5f5949e [file] [log] [blame]
Leonardod9cd5962016-11-17 14:33:07 +01001#!/bin/bash
2
3##
4# Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
5# This file is part of openvim
6# All Rights Reserved.
7#
8# Licensed under the Apache License, Version 2.0 (the "License"); you may
9# not use this file except in compliance with the License. You may obtain
10# a copy of the License at
11#
12# http://www.apache.org/licenses/LICENSE-2.0
13#
14# Unless required by applicable law or agreed to in writing, software
15# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17# License for the specific language governing permissions and limitations
18# under the License.
19#
20# For those usages not covered by the Apache License, Version 2.0 please
21# contact with: nfvlabs@tid.es
22##
23
24# Authors: Antonio Lopez, Pablo Montes, Alfonso Tierno
25# June 2015
26
27# Personalize RHEL7.1 on compute nodes
28# Prepared to work with the following network card drivers:
29# tg3, igb drivers for management interfaces
30# ixgbe (Intel Niantic) and i40e (Intel Fortville) drivers for data plane interfaces
31
32# To download:
33# wget https://raw.githubusercontent.com/nfvlabs/openmano/master/scripts/configure-compute-node-develope-UBUNTU16.04.sh
34# To execute:
35# chmod +x ./configure-compute-node-RHEL7.1.sh
36# sudo ./configure-compute-node-RHEL7.1.sh <user> <iface>
37
38# Assumptions:
39# All virtualization options activated on BIOS (vt-d, vt-x, SR-IOV, no power savings...)
40# RHEL7.1 installed without /home partition and with the following packages selection:
41# @base, @core, @development, @network-file-system-client, @virtualization-hypervisor, @virtualization-platform, @virtualization-tools
42
43interfaced_path='/etc/network/interfaces.d/'
44#interfaced_path='/home/ubuntu/openvim_install/openvim/test-inter/'
45set_mtu_path='/etc/'
46VLAN_INDEX=20
Leonardod9cd5962016-11-17 14:33:07 +010047
tiernoe5d685e2016-11-22 17:29:16 +010048function _usage(){
Leonardod9cd5962016-11-17 14:33:07 +010049 echo -e "Usage: sudo $0 [-y] <user-name> <iface-name>"
tiernoe5d685e2016-11-22 17:29:16 +010050 echo -e " Configure compute host for VIM usage. (version 0.4). OPTIONS:"
51 echo -e " -h --help this help"
52 echo -e " -f --force: do not prompt for confirmation. If a new user is created, the user name is set as password"
53 echo -e " -u --user: Create if not exist and configure this user for openvim to connect"
54 echo -e " --in --iface-name: creates bridge interfaces on this interface, needed for openvim overlay networks"
Leonardod9cd5962016-11-17 14:33:07 +010055}
56
57function _interface_cfg_generator(){
58 #$1 interface name | $2 MTU | $3 type
59
60echo "
61auto ${1}
62iface ${1} inet ${3}
63 mtu ${2}
64 ${bridge_ports}
65" >> ${interfaced_path}${1}."cfg"
66}
67
68
69function _interface_cfg_generator(){
70 #$1 interface name | $2 vlan | $3 virbrMan | $4 MTU
71
72echo "
73auto ${1}.${2}
74iface ${1}.${2} inet manual
75 mtu ${4}
76 post-up vconfig add ${1} ${2}
77 post-down vconfig rem ${1}.${2}
78
79auto ${3}
80iface ${3} inet manual
81 bridge_ports ${1}.${2}
82 mtu ${4}
83 vlan-raw-device $1
84" >> ${interfaced_path}${1}.${2}."cfg"
85}
86
87function _install_user() {
88 # create user given by the user and add to groups need it.
89 # Add required groups
90 groupadd -f admin
91 groupadd -f libvirt #for other operating systems may be libvirtd
92
93 # Adds user, default password same as name
tiernoe5d685e2016-11-22 17:29:16 +010094 if grep -q "^${option_user}:" /etc/passwd
Leonardod9cd5962016-11-17 14:33:07 +010095 then
96 #user exist, add to group
tiernoe5d685e2016-11-22 17:29:16 +010097 echo "adding user ${option_user} to groups libvirt,admin"
98 usermod -a -G libvirt,admin -g admin ${option_user}
Leonardod9cd5962016-11-17 14:33:07 +010099 else
100 #create user if it does not exist
tiernoe5d685e2016-11-22 17:29:16 +0100101 [ -z "$FORCE" ] && read -p "user '${option_user}' does not exist, create (Y/n)" kk
Leonardod9cd5962016-11-17 14:33:07 +0100102 if ! [ -z "$kk" -o "$kk"="y" -o "$kk"="Y" ]
103 then
104 exit
105 fi
tiernoe5d685e2016-11-22 17:29:16 +0100106 echo "creating and configuring user ${option_user}"
107 useradd -m -G libvirt,admin -g admin ${option_user}
Leonardod9cd5962016-11-17 14:33:07 +0100108 #Password
109 if [ -z "$FORCE" ]
110 then
tiernoe5d685e2016-11-22 17:29:16 +0100111 echo "Provide a password for ${option_user}"
112 passwd ${option_user}
Leonardod9cd5962016-11-17 14:33:07 +0100113 else
tiernoe5d685e2016-11-22 17:29:16 +0100114 echo -e "$option_user\n$option_user" | passwd --stdin ${option_user}
Leonardod9cd5962016-11-17 14:33:07 +0100115 fi
116 fi
117
118}
119
120function _openmano_img_2_libvirt_img(){
121 # Links the OpenMANO required folder /opt/VNF/images to /var/lib/libvirt/images.
122 # The OS installation
123 # should have only a / partition with all possible space available
124
125 echo " link /opt/VNF/images to /var/lib/libvirt/images"
tiernoe5d685e2016-11-22 17:29:16 +0100126 if [ "$option_user" != "" ]
Leonardod9cd5962016-11-17 14:33:07 +0100127 then
128 # The orchestator needs to link the images folder
129 rm -f /opt/VNF/images
130 mkdir -p /opt/VNF/
131 ln -s /var/lib/libvirt/images /opt/VNF/images
tiernoe5d685e2016-11-22 17:29:16 +0100132 chown -R ${option_user}:admin /opt/VNF
Leonardod9cd5962016-11-17 14:33:07 +0100133 chown -R root:admin /var/lib/libvirt/images
134 chmod g+rwx /var/lib/libvirt/images
135 else
136 mkdir -p /opt/VNF/images
137 chmod o+rx /opt/VNF/images
138 fi
139}
140
141function _install_pacckags_dependences()
142{
143 # Required packages by openvim
144 apt-get -y update
145 apt-get -y install grub-common screen virt-manager ethtool build-essential \
146 x11-common x11-utils libguestfs-tools hwloc libguestfs-tools \
147 numactl vlan nfs-common nfs-kernel-server
148 echo "Remove unneeded packages....."
149 apt-get -y autoremove
150}
151
152function _network_configuration(){
153 # adding vlan support
154 grep -q '8021q' '/etc/modules'; [ $? -eq 1 ] && sudo su -c 'echo "8021q" >> /etc/modules'
155
156 #grep -q ${interface} '/etc/network/interfaces.d/50-cloud-init.cfg'; [ $? -eq 0 ] && sed -e '/'${interface}'/ s/^#*/#/' -i '/etc/network/interfaces.d/50-cloud-init.cfg'
157
158 # Network interfaces static configuration
159 echo "Interface ==> $interface"
160 if [ -n "$interface" ]
161 then
162 # For management and data interfaces
163 rm -f /etc/udev/rules.d/pci_config.rules # it will be created to define VFs
164 # Set ONBOOT=on and MTU=9000 on the interface used for the bridges
165 echo "configuring iface $interface"
166
167 # Static network interface configuration and MTU
168 MTU=9000
169 virbrMan_interface_number=20
170
171 #Create bridge interfaces
172 echo "Creating bridge ifaces: "
173 for ((i =1; i <= ${virbrMan_interface_number}; i++))
174 do
175 i2digits=${i}
176 [ ${i} -lt 10 ] && i2digits="0${i}"
177 echo " ${interface} ${VLAN_INDEX}${i2digits}"
178 echo " virbrMan${i} vlan ${VLAN_INDEX}${i2digits}"
179 j=${i}
180 #$1 interface name | $2 vlan | $3 MTU | $3 virbrMan | $4 bridge_ports
181 _interface_cfg_generator ${interface} ${VLAN_INDEX}${i2digits} 'virbrMan'${i} ${MTU}
182 done
183
184 fi
185}
186
187function _disable_aaparmor(){
188 #Deactivating apparmor while looking for a better solution
189 /etc/init.d/apparmor stop
190 update-rc.d -f apparmor remove
191}
192
193function _check_interface(){
194 #check if interface given as an argument exits
195 if [ -n "$1" ] && ! ifconfig $1 &> /dev/null
196 then
197 echo "Error: interface '$1' is not present in the system"\n
Leonardod9cd5962016-11-17 14:33:07 +0100198 exit 1
199 fi
200}
201
202function _user_remainder_pront()
203{
204 echo
205 echo "Do not forget to create a shared (NFS, Samba, ...) where original virtual machine images are allocated"
206 echo
tiernoe5d685e2016-11-22 17:29:16 +0100207 echo "Do not forget to copy the public ssh key into /home/${option_user}/.ssh/authorized_keys for authomatic login from openvim controller"
Leonardod9cd5962016-11-17 14:33:07 +0100208 echo
209 echo "Reboot the system to make the changes effective"
210}
211
212function _libvirt_configuration(){
213 # Libvirt options for openvim
214 echo "configure Libvirt options"
215 sed -i 's/#unix_sock_group = "libvirt"/unix_sock_group = "libvirt"/' /etc/libvirt/libvirtd.conf
216 sed -i 's/#unix_sock_rw_perms = "0770"/unix_sock_rw_perms = "0770"/' /etc/libvirt/libvirtd.conf
217 sed -i 's/#unix_sock_dir = "\/var\/run\/libvirt"/unix_sock_dir = "\/var\/run\/libvirt"/' /etc/libvirt/libvirtd.conf
218 sed -i 's/#auth_unix_rw = "none"/auth_unix_rw = "none"/' /etc/libvirt/libvirtd.conf
219
220 chmod a+rwx /var/lib/libvirt/images
221 mkdir /usr/libexec/
222 pushd /usr/libexec/
223 ln -s /usr/bin/qemu-system-x86_64 qemu-kvm
224 popd
225}
226
227function _hostinfo_config()
228{
229
230 echo "#By default openvim assumes control plane interface naming as em1,em2,em3,em4 " > /opt/VNF/images/hostinfo.yaml
231 echo "creating local information /opt/VNF/images/hostinfo.yaml"
232 echo "#and bridge ifaces as virbrMan1, virbrMan2, ..." >> /opt/VNF/images/hostinfo.yaml
233 echo "#if compute node contain a different name it must be indicated in this file" >> /opt/VNF/images/hostinfo.yaml
234 echo "#with the format extandard-name: compute-name" >> /opt/VNF/images/hostinfo.yaml
235 chmod o+r /opt/VNF/images/hostinfo.yaml
236}
237
238function _get_opts()
239{
Leonardod9cd5962016-11-17 14:33:07 +0100240 options="$1"
241 shift
242
243 get_argument=""
244 #reset variables
245 params=""
246 for option_group in $options
247 do
248 _name=${option_group%%:*}
249 _name=${_name%=}
250 _name=${_name//-/_}
251 eval option_${_name}='""'
252 done
253
254 while [[ $# -gt 0 ]]
255 do
256 argument="$1"
257 shift
258 if [[ -n $get_argument ]]
259 then
tiernoe5d685e2016-11-22 17:29:16 +0100260 [[ ${argument:0:1} == "-" ]] && echo "option '-$option' requires an argument" >&2 && return 1
Leonardod9cd5962016-11-17 14:33:07 +0100261 eval ${get_argument}='"$argument"'
262 #echo option $get_argument with argument
263 get_argument=""
264 continue
265 fi
266
267
268 #short options
269 if [[ ${argument:0:1} == "-" ]] && [[ ${argument:1:1} != "-" ]] && [[ ${#argument} -ge 2 ]]
270 then
271 index=0
272 while index=$((index+1)) && [[ $index -lt ${#argument} ]]
273 do
274 option=${argument:$index:1}
275 bad_option=y
276 for option_group in $options
277 do
278 _name=""
279 for o in $(echo $option_group | tr ":=" " ")
280 do
281 [[ -z "$_name" ]] && _name=${o//-/_}
282 #echo option $option versus $o
283 if [[ "$option" == "${o}" ]]
284 then
285 eval option_${_name}='${option_'${_name}'}-'
286 bad_option=n
287 if [[ ${option_group:${#option_group}-1} != "=" ]]
288 then
289 continue
290 fi
291 if [[ ${#argument} -gt $((index+1)) ]]
292 then
293 eval option_${_name}='"${argument:$((index+1))}"'
294 index=${#argument}
295 else
296 get_argument=option_${_name}
297 #echo next should be argument $argument
298 fi
299
300 break
301 fi
302 done
303 done
tiernoe5d685e2016-11-22 17:29:16 +0100304 [[ $bad_option == y ]] && echo "invalid argument '-$option'? Type -h for help" >&2 && return 1
Leonardod9cd5962016-11-17 14:33:07 +0100305 done
306 elif [[ ${argument:0:2} == "--" ]] && [[ ${#argument} -ge 3 ]]
307 then
308 option=${argument:2}
309 option_argument=${option#*=}
310 option_name=${option%%=*}
311 [[ "$option_name" == "$option" ]] && option_argument=""
312 bad_option=y
313 for option_group in $options
314 do
315 _name=""
316 for o in $(echo $option_group | tr ":=" " ")
317 do
318 [[ -z "$_name" ]] && _name=${o//-/_}
319 #echo option $option versus $o
320 if [[ "$option_name" == "${o}" ]]
321 then
322 bad_option=n
323 if [[ ${option_group:${#option_group}-1} != "=" ]]
324 then #not an argument
tiernoe5d685e2016-11-22 17:29:16 +0100325 [[ -n "${option_argument}" ]] && echo "option '--${option%%=*}' do not accept an argument " >&2 && return 1
Leonardod9cd5962016-11-17 14:33:07 +0100326 eval option_${_name}='"${option_'${_name}'}-"'
327 elif [[ -n "${option_argument}" ]]
328 then
329 eval option_${_name}='"${option_argument}"'
330 else
331 get_argument=option_${_name}
332 #echo next should be argument $argument
333 fi
334 break
335 fi
336 done
337 done
tiernoe5d685e2016-11-22 17:29:16 +0100338 [[ $bad_option == y ]] && echo "invalid argument '-$option'? Type -h for help" >&2 && return 1
Leonardod9cd5962016-11-17 14:33:07 +0100339 elif [[ ${argument:0:2} == "--" ]]
340 then
341 option__="$*"
342 bad_option=y
343 for o in $options
344 do
345 if [[ "$o" == "--" ]]
346 then
347 bad_option=n
348 option__=" $*"
349 break
350 fi
351 done
tiernoe5d685e2016-11-22 17:29:16 +0100352 [[ $bad_option == y ]] && echo "invalid argument '--'? Type -h for help" >&2 && return 1
Leonardod9cd5962016-11-17 14:33:07 +0100353 break
354 else
355 params="$params ${argument}"
356 fi
357
358 done
tiernoe5d685e2016-11-22 17:29:16 +0100359 echo option_help "$option_help"
Leonardod9cd5962016-11-17 14:33:07 +0100360
tiernoe5d685e2016-11-22 17:29:16 +0100361 [[ -n "$get_argument" ]] && echo "option '-$option' requires an argument" >&2 && return 1
362 return 0
Leonardod9cd5962016-11-17 14:33:07 +0100363}
364
365function _parse_opts()
366{
tiernoe5d685e2016-11-22 17:29:16 +0100367 [ -n "$option_help" ] && _usage && exit 0
368
Leonardod9cd5962016-11-17 14:33:07 +0100369 FORCE=""
tiernoe5d685e2016-11-22 17:29:16 +0100370 [ -n "$option_force" ] && FORCE="yes"
Leonardod9cd5962016-11-17 14:33:07 +0100371
tiernoe5d685e2016-11-22 17:29:16 +0100372 [ -z "$option_user" ] && echo -e "ERROR: User argument is mandatory, --user=<user>\n" >&2 && _usage
373 #echo "user_name = "$option_user
Leonardod9cd5962016-11-17 14:33:07 +0100374
tiernoe5d685e2016-11-22 17:29:16 +0100375 [ -z "$option_iface_name" ] && echo -e "ERROR: iface-name argument is mandatory, --iface-name=<interface>\n" && _usage
Leonardod9cd5962016-11-17 14:33:07 +0100376 interface=$option_iface_name
377
378}
379#1 CHECK input parameters
Leonardod9cd5962016-11-17 14:33:07 +0100380
381#Parse opts
tiernoe5d685e2016-11-22 17:29:16 +0100382_get_opts "help:h force:f user:u= iface-name:in= " $* || exit 1
383
384#check root privileges
385[ "${USER}" != "root" ] && echo "Needed root privileges" >&2 && exit 2
386
Leonardod9cd5962016-11-17 14:33:07 +0100387_parse_opts
388
389echo "checking interface "$interface
390
391_check_interface $interface
392
393echo '
394#################################################################
395##### INSTALL USER #####
396#################################################################'
397_install_user
398
399echo '
400#################################################################
401##### INSTALL NEEDED PACKETS #####
402#################################################################'
403_install_pacckags_dependences
404
405echo '
406#################################################################
407##### OTHER CONFIGURATION #####
408#################################################################'
409_openmano_img_2_libvirt_img
410_hostinfo_config
411_libvirt_configuration
412
413echo '
414#################################################################
415##### NETWORK CONFIGURATION #####
416#################################################################'
417_network_configuration
418_disable_aaparmor
419_user_remainder_pront
420
421
422