blob: 2f6d72ebc1aa1c50bfd9947978a235e038fa9cde [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
Mirabalc569a032016-12-29 13:38:56 +000024# Authors: Antonio Lopez, Pablo Montes, Alfonso Tierno, Leonardo Mirabal
Leonardod9cd5962016-11-17 14:33:07 +010025# 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(){
Mirabalc569a032016-12-29 13:38:56 +000049 echo -e "Usage: sudo $0 [-f] --user=<user-name> --overlay=ovs --iface-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"
Mirabalc569a032016-12-29 13:38:56 +000054 echo -e " -o --overlay: ovs, bridge and bridge-and-ovs. Specify the networking overlay used by openvim, by default ovs is used"
55 echo -e " -in --iface-name: creates bridge interfaces on this interface, needed for openvim overlay networks"
56
Mirabal9aea0432016-11-23 15:55:09 +000057 exit 1
Leonardod9cd5962016-11-17 14:33:07 +010058}
59
60function _interface_cfg_generator(){
Leonardod9cd5962016-11-17 14:33:07 +010061 #$1 interface name | $2 vlan | $3 virbrMan | $4 MTU
62
63echo "
64auto ${1}.${2}
65iface ${1}.${2} inet manual
Mirabalc569a032016-12-29 13:38:56 +000066 vlan-raw-device ${1}
67 post-up ip link set mtu $MTU dev ${1}.${2}
Leonardod9cd5962016-11-17 14:33:07 +010068
69auto ${3}
70iface ${3} inet manual
71 bridge_ports ${1}.${2}
Mirabalc569a032016-12-29 13:38:56 +000072 post-up ip link set dev ${3} && ip link set mtu $MTU dev ${3}
73
Leonardod9cd5962016-11-17 14:33:07 +010074" >> ${interfaced_path}${1}.${2}."cfg"
75}
76
77function _install_user() {
78 # create user given by the user and add to groups need it.
79 # Add required groups
80 groupadd -f admin
Mirabalc569a032016-12-29 13:38:56 +000081 groupadd -f libvirtd #for other operating systems may be libvirtd
Leonardod9cd5962016-11-17 14:33:07 +010082
83 # Adds user, default password same as name
tiernoe5d685e2016-11-22 17:29:16 +010084 if grep -q "^${option_user}:" /etc/passwd
Leonardod9cd5962016-11-17 14:33:07 +010085 then
86 #user exist, add to group
tiernoe5d685e2016-11-22 17:29:16 +010087 echo "adding user ${option_user} to groups libvirt,admin"
Mirabalc569a032016-12-29 13:38:56 +000088 usermod -a -G libvirtd,admin -g admin ${option_user}
Leonardod9cd5962016-11-17 14:33:07 +010089 else
90 #create user if it does not exist
tiernoe5d685e2016-11-22 17:29:16 +010091 [ -z "$FORCE" ] && read -p "user '${option_user}' does not exist, create (Y/n)" kk
Leonardod9cd5962016-11-17 14:33:07 +010092 if ! [ -z "$kk" -o "$kk"="y" -o "$kk"="Y" ]
93 then
94 exit
95 fi
tiernoe5d685e2016-11-22 17:29:16 +010096 echo "creating and configuring user ${option_user}"
Mirabalc569a032016-12-29 13:38:56 +000097 useradd -m -G libvirtd,admin -g admin ${option_user}
Leonardod9cd5962016-11-17 14:33:07 +010098 #Password
99 if [ -z "$FORCE" ]
100 then
tiernoe5d685e2016-11-22 17:29:16 +0100101 echo "Provide a password for ${option_user}"
102 passwd ${option_user}
Leonardod9cd5962016-11-17 14:33:07 +0100103 else
tiernoe5d685e2016-11-22 17:29:16 +0100104 echo -e "$option_user\n$option_user" | passwd --stdin ${option_user}
Leonardod9cd5962016-11-17 14:33:07 +0100105 fi
106 fi
107
108}
109
110function _openmano_img_2_libvirt_img(){
111 # Links the OpenMANO required folder /opt/VNF/images to /var/lib/libvirt/images.
112 # The OS installation
113 # should have only a / partition with all possible space available
114
115 echo " link /opt/VNF/images to /var/lib/libvirt/images"
tiernoe5d685e2016-11-22 17:29:16 +0100116 if [ "$option_user" != "" ]
Leonardod9cd5962016-11-17 14:33:07 +0100117 then
118 # The orchestator needs to link the images folder
119 rm -f /opt/VNF/images
120 mkdir -p /opt/VNF/
121 ln -s /var/lib/libvirt/images /opt/VNF/images
tiernoe5d685e2016-11-22 17:29:16 +0100122 chown -R ${option_user}:admin /opt/VNF
Leonardod9cd5962016-11-17 14:33:07 +0100123 chown -R root:admin /var/lib/libvirt/images
124 chmod g+rwx /var/lib/libvirt/images
125 else
126 mkdir -p /opt/VNF/images
127 chmod o+rx /opt/VNF/images
128 fi
129}
130
Mirabalc569a032016-12-29 13:38:56 +0000131function _install_packages_dependencies()
Leonardod9cd5962016-11-17 14:33:07 +0100132{
133 # Required packages by openvim
134 apt-get -y update
135 apt-get -y install grub-common screen virt-manager ethtool build-essential \
136 x11-common x11-utils libguestfs-tools hwloc libguestfs-tools \
Mirabalc569a032016-12-29 13:38:56 +0000137 numactl vlan nfs-common nfs-kernel-server openvswitch-switch
Leonardod9cd5962016-11-17 14:33:07 +0100138 echo "Remove unneeded packages....."
139 apt-get -y autoremove
140}
141
142function _network_configuration(){
143 # adding vlan support
144 grep -q '8021q' '/etc/modules'; [ $? -eq 1 ] && sudo su -c 'echo "8021q" >> /etc/modules'
145
Leonardod9cd5962016-11-17 14:33:07 +0100146 # Network interfaces static configuration
147 echo "Interface ==> $interface"
148 if [ -n "$interface" ]
149 then
150 # For management and data interfaces
151 rm -f /etc/udev/rules.d/pci_config.rules # it will be created to define VFs
152 # Set ONBOOT=on and MTU=9000 on the interface used for the bridges
153 echo "configuring iface $interface"
Mirabalc569a032016-12-29 13:38:56 +0000154 if [ "$option_overlay" == "bridge" ] || [ "$option_overlay" == "bridge-and-ovs" ]
155 then
156 # Static network interface configuration and MTU
157 MTU=9000
158 virbrMan_interface_number=20
Leonardod9cd5962016-11-17 14:33:07 +0100159
Mirabalc569a032016-12-29 13:38:56 +0000160 #Create bridge interfaces
161 echo "Creating bridge ifaces: "
162 for ((i =1; i <= ${virbrMan_interface_number}; i++))
163 do
164 i2digits=${i}
165 [ ${i} -lt 10 ] && i2digits="0${i}"
166 echo " ${interface} ${VLAN_INDEX}${i2digits}"
167 echo " virbrMan${i} vlan ${VLAN_INDEX}${i2digits}"
168 j=${i}
169 #$1 interface name | $2 vlan | $3 MTU | $3 virbrMan | $4 bridge_ports
170 _interface_cfg_generator ${interface} ${VLAN_INDEX}${i2digits} 'virbrMan'${i} ${MTU}
171 done
172 fi
Leonardod9cd5962016-11-17 14:33:07 +0100173 fi
174}
175
176function _disable_aaparmor(){
177 #Deactivating apparmor while looking for a better solution
178 /etc/init.d/apparmor stop
179 update-rc.d -f apparmor remove
180}
181
182function _check_interface(){
183 #check if interface given as an argument exits
184 if [ -n "$1" ] && ! ifconfig $1 &> /dev/null
185 then
186 echo "Error: interface '$1' is not present in the system"\n
Leonardod9cd5962016-11-17 14:33:07 +0100187 exit 1
188 fi
189}
190
191function _user_remainder_pront()
192{
193 echo
194 echo "Do not forget to create a shared (NFS, Samba, ...) where original virtual machine images are allocated"
195 echo
tiernoe5d685e2016-11-22 17:29:16 +0100196 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 +0100197 echo
198 echo "Reboot the system to make the changes effective"
199}
200
201function _libvirt_configuration(){
202 # Libvirt options for openvim
203 echo "configure Libvirt options"
204 sed -i 's/#unix_sock_group = "libvirt"/unix_sock_group = "libvirt"/' /etc/libvirt/libvirtd.conf
205 sed -i 's/#unix_sock_rw_perms = "0770"/unix_sock_rw_perms = "0770"/' /etc/libvirt/libvirtd.conf
206 sed -i 's/#unix_sock_dir = "\/var\/run\/libvirt"/unix_sock_dir = "\/var\/run\/libvirt"/' /etc/libvirt/libvirtd.conf
207 sed -i 's/#auth_unix_rw = "none"/auth_unix_rw = "none"/' /etc/libvirt/libvirtd.conf
208
209 chmod a+rwx /var/lib/libvirt/images
210 mkdir /usr/libexec/
211 pushd /usr/libexec/
212 ln -s /usr/bin/qemu-system-x86_64 qemu-kvm
213 popd
214}
215
216function _hostinfo_config()
217{
218
219 echo "#By default openvim assumes control plane interface naming as em1,em2,em3,em4 " > /opt/VNF/images/hostinfo.yaml
220 echo "creating local information /opt/VNF/images/hostinfo.yaml"
221 echo "#and bridge ifaces as virbrMan1, virbrMan2, ..." >> /opt/VNF/images/hostinfo.yaml
222 echo "#if compute node contain a different name it must be indicated in this file" >> /opt/VNF/images/hostinfo.yaml
223 echo "#with the format extandard-name: compute-name" >> /opt/VNF/images/hostinfo.yaml
224 chmod o+r /opt/VNF/images/hostinfo.yaml
Mirabalc569a032016-12-29 13:38:56 +0000225 if [ "$interface" != "" -a "$interface" != "em1" ]
226 then
227 echo "iface_names:" >> /opt/VNF/images/hostinfo.yaml
228 echo " em1: ${interface}" >> /opt/VNF/images/hostinfo.yaml
229 fi
Leonardod9cd5962016-11-17 14:33:07 +0100230}
231
Mirabalc569a032016-12-29 13:38:56 +0000232function _add_user_to_visudo()
233{
234# Allow admin users to access without password
235if ! grep -q "#openmano" /etc/sudoers
236then
237 cat >> /home/${option_user}/script_visudo.sh << EOL
238#!/bin/bash
239echo "#openmano allow to group admin to grant root privileges without password" >> \$1
240echo "${option_user} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
241EOL
242 chmod +x /home/${option_user}/script_visudo.sh
243 echo "allowing admin user to get root privileges withut password"
244 export EDITOR=/home/${option_user}/script_visudo.sh && sudo -E visudo
245 rm -f /home/${option_user}/script_visudo.sh
246fi
247
248}
Leonardod9cd5962016-11-17 14:33:07 +0100249function _get_opts()
250{
Leonardod9cd5962016-11-17 14:33:07 +0100251 options="$1"
252 shift
253
254 get_argument=""
255 #reset variables
256 params=""
257 for option_group in $options
258 do
259 _name=${option_group%%:*}
260 _name=${_name%=}
261 _name=${_name//-/_}
262 eval option_${_name}='""'
263 done
264
265 while [[ $# -gt 0 ]]
266 do
267 argument="$1"
268 shift
269 if [[ -n $get_argument ]]
270 then
tiernoe5d685e2016-11-22 17:29:16 +0100271 [[ ${argument:0:1} == "-" ]] && echo "option '-$option' requires an argument" >&2 && return 1
Leonardod9cd5962016-11-17 14:33:07 +0100272 eval ${get_argument}='"$argument"'
273 #echo option $get_argument with argument
274 get_argument=""
275 continue
276 fi
277
278
279 #short options
280 if [[ ${argument:0:1} == "-" ]] && [[ ${argument:1:1} != "-" ]] && [[ ${#argument} -ge 2 ]]
281 then
282 index=0
283 while index=$((index+1)) && [[ $index -lt ${#argument} ]]
284 do
285 option=${argument:$index:1}
286 bad_option=y
287 for option_group in $options
288 do
289 _name=""
290 for o in $(echo $option_group | tr ":=" " ")
291 do
292 [[ -z "$_name" ]] && _name=${o//-/_}
293 #echo option $option versus $o
294 if [[ "$option" == "${o}" ]]
295 then
296 eval option_${_name}='${option_'${_name}'}-'
297 bad_option=n
298 if [[ ${option_group:${#option_group}-1} != "=" ]]
299 then
300 continue
301 fi
302 if [[ ${#argument} -gt $((index+1)) ]]
303 then
304 eval option_${_name}='"${argument:$((index+1))}"'
305 index=${#argument}
306 else
307 get_argument=option_${_name}
308 #echo next should be argument $argument
309 fi
310
311 break
312 fi
313 done
314 done
tiernoe5d685e2016-11-22 17:29:16 +0100315 [[ $bad_option == y ]] && echo "invalid argument '-$option'? Type -h for help" >&2 && return 1
Leonardod9cd5962016-11-17 14:33:07 +0100316 done
317 elif [[ ${argument:0:2} == "--" ]] && [[ ${#argument} -ge 3 ]]
318 then
319 option=${argument:2}
320 option_argument=${option#*=}
321 option_name=${option%%=*}
322 [[ "$option_name" == "$option" ]] && option_argument=""
323 bad_option=y
324 for option_group in $options
325 do
326 _name=""
327 for o in $(echo $option_group | tr ":=" " ")
328 do
329 [[ -z "$_name" ]] && _name=${o//-/_}
330 #echo option $option versus $o
331 if [[ "$option_name" == "${o}" ]]
332 then
333 bad_option=n
334 if [[ ${option_group:${#option_group}-1} != "=" ]]
335 then #not an argument
tiernoe5d685e2016-11-22 17:29:16 +0100336 [[ -n "${option_argument}" ]] && echo "option '--${option%%=*}' do not accept an argument " >&2 && return 1
Leonardod9cd5962016-11-17 14:33:07 +0100337 eval option_${_name}='"${option_'${_name}'}-"'
338 elif [[ -n "${option_argument}" ]]
339 then
340 eval option_${_name}='"${option_argument}"'
341 else
342 get_argument=option_${_name}
343 #echo next should be argument $argument
344 fi
345 break
346 fi
347 done
348 done
tiernoe5d685e2016-11-22 17:29:16 +0100349 [[ $bad_option == y ]] && echo "invalid argument '-$option'? Type -h for help" >&2 && return 1
Leonardod9cd5962016-11-17 14:33:07 +0100350 elif [[ ${argument:0:2} == "--" ]]
351 then
352 option__="$*"
353 bad_option=y
354 for o in $options
355 do
356 if [[ "$o" == "--" ]]
357 then
358 bad_option=n
359 option__=" $*"
360 break
361 fi
362 done
tiernoe5d685e2016-11-22 17:29:16 +0100363 [[ $bad_option == y ]] && echo "invalid argument '--'? Type -h for help" >&2 && return 1
Leonardod9cd5962016-11-17 14:33:07 +0100364 break
365 else
366 params="$params ${argument}"
367 fi
368
369 done
370
tiernoe5d685e2016-11-22 17:29:16 +0100371 [[ -n "$get_argument" ]] && echo "option '-$option' requires an argument" >&2 && return 1
372 return 0
Leonardod9cd5962016-11-17 14:33:07 +0100373}
374
375function _parse_opts()
376{
tiernoe5d685e2016-11-22 17:29:16 +0100377 [ -n "$option_help" ] && _usage && exit 0
378
Leonardod9cd5962016-11-17 14:33:07 +0100379 FORCE=""
tiernoe5d685e2016-11-22 17:29:16 +0100380 [ -n "$option_force" ] && FORCE="yes"
Leonardod9cd5962016-11-17 14:33:07 +0100381
tiernoe5d685e2016-11-22 17:29:16 +0100382 [ -z "$option_user" ] && echo -e "ERROR: User argument is mandatory, --user=<user>\n" >&2 && _usage
Leonardod9cd5962016-11-17 14:33:07 +0100383
tiernoe5d685e2016-11-22 17:29:16 +0100384 [ -z "$option_iface_name" ] && echo -e "ERROR: iface-name argument is mandatory, --iface-name=<interface>\n" && _usage
Leonardod9cd5962016-11-17 14:33:07 +0100385 interface=$option_iface_name
386
Mirabalc569a032016-12-29 13:38:56 +0000387 if [ "$option_overlay" != "bridge" ] && [ "$option_overlay" != "ovs" ] && [ "$option_overlay" != "bridge-and-ovs" ];
388 then
389 option_overlay='ovs'
390 echo 'ERROR: overlay argument must be "ovs", "bridge", "bridge-and-ovs"' && _usage
391 fi
Leonardod9cd5962016-11-17 14:33:07 +0100392}
Leonardod9cd5962016-11-17 14:33:07 +0100393
394#Parse opts
Mirabalc569a032016-12-29 13:38:56 +0000395_get_opts "help:h force:f user:u= overlay:o= iface-name:in= " $* || exit 1
Mirabal9aea0432016-11-23 15:55:09 +0000396_parse_opts
tiernoe5d685e2016-11-22 17:29:16 +0100397
398#check root privileges
399[ "${USER}" != "root" ] && echo "Needed root privileges" >&2 && exit 2
400
Leonardod9cd5962016-11-17 14:33:07 +0100401echo "checking interface "$interface
402
403_check_interface $interface
404
405echo '
406#################################################################
407##### INSTALL USER #####
408#################################################################'
409_install_user
Mirabalc569a032016-12-29 13:38:56 +0000410_add_user_to_visudo
Leonardod9cd5962016-11-17 14:33:07 +0100411echo '
412#################################################################
413##### INSTALL NEEDED PACKETS #####
414#################################################################'
Mirabalc569a032016-12-29 13:38:56 +0000415_install_packages_dependencies
Leonardod9cd5962016-11-17 14:33:07 +0100416
417echo '
418#################################################################
419##### OTHER CONFIGURATION #####
420#################################################################'
421_openmano_img_2_libvirt_img
422_hostinfo_config
423_libvirt_configuration
424
425echo '
426#################################################################
427##### NETWORK CONFIGURATION #####
428#################################################################'
Mirabalc569a032016-12-29 13:38:56 +0000429
Leonardod9cd5962016-11-17 14:33:07 +0100430_network_configuration
Mirabalc569a032016-12-29 13:38:56 +0000431
432
Leonardod9cd5962016-11-17 14:33:07 +0100433_disable_aaparmor
434_user_remainder_pront
435
436
437