2a370bff8c20f74dcf451985b18ea1c661bc07e4
[apex.git] / lib / undercloud-functions.sh
1 #!/usr/bin/env bash
2 ##############################################################################
3 # Copyright (c) 2015 Tim Rozet (Red Hat), Dan Radez (Red Hat) and others.
4 #
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9 ##############################################################################
10
11 ##verify vm exists, an has a dhcp lease assigned to it
12 ##params: none
13 function setup_undercloud_vm {
14   if ! virsh list --all | grep undercloud > /dev/null; then
15       undercloud_nets="default admin"
16       if [[ $enabled_network_list =~ "external" ]]; then
17         undercloud_nets+=" external"
18       fi
19       define_vm undercloud hd 30 "$undercloud_nets" 4 12288
20
21       ### this doesn't work for some reason I was getting hangup events so using cp instead
22       #virsh vol-upload --pool default --vol undercloud.qcow2 --file $BASE/stack/undercloud.qcow2
23       #2015-12-05 12:57:20.569+0000: 8755: info : libvirt version: 1.2.8, package: 16.el7_1.5 (CentOS BuildSystem <http://bugs.centos.org>, 2015-11-03-13:56:46, worker1.bsys.centos.org)
24       #2015-12-05 12:57:20.569+0000: 8755: warning : virKeepAliveTimerInternal:143 : No response from client 0x7ff1e231e630 after 6 keepalive messages in 35 seconds
25       #2015-12-05 12:57:20.569+0000: 8756: warning : virKeepAliveTimerInternal:143 : No response from client 0x7ff1e231e630 after 6 keepalive messages in 35 seconds
26       #error: cannot close volume undercloud.qcow2
27       #error: internal error: received hangup / error event on socket
28       #error: Reconnected to the hypervisor
29
30       local undercloud_dst=/var/lib/libvirt/images/undercloud.qcow2
31       cp -f $IMAGES/undercloud.qcow2 $undercloud_dst
32
33       # resize Undercloud machine
34       echo "Checking if Undercloud needs to be resized..."
35       undercloud_size=$(LIBGUESTFS_BACKEND=direct virt-filesystems --long -h --all -a $undercloud_dst |grep device | grep -Eo "[0-9\.]+G" | sed -n 's/\([0-9][0-9]*\).*/\1/p')
36       if [ "$undercloud_size" -lt 30 ]; then
37         qemu-img resize /var/lib/libvirt/images/undercloud.qcow2 +25G
38         LIBGUESTFS_BACKEND=direct virt-resize --expand /dev/sda1 $IMAGES/undercloud.qcow2 $undercloud_dst
39         LIBGUESTFS_BACKEND=direct virt-customize -a $undercloud_dst --run-command 'xfs_growfs -d /dev/sda1 || true'
40         new_size=$(LIBGUESTFS_BACKEND=direct virt-filesystems --long -h --all -a $undercloud_dst |grep filesystem | grep -Eo "[0-9\.]+G" | sed -n 's/\([0-9][0-9]*\).*/\1/p')
41         if [ "$new_size" -lt 30 ]; then
42           echo "Error resizing Undercloud machine, disk size is ${new_size}"
43           exit 1
44         else
45           echo "Undercloud successfully resized"
46         fi
47       else
48         echo "Skipped Undercloud resize, upstream is large enough"
49       fi
50
51   else
52       echo "Found existing Undercloud VM, exiting."
53       exit 1
54   fi
55
56   # if the VM is not running update the authkeys and start it
57   if ! virsh list | grep undercloud > /dev/null; then
58     echo "Injecting ssh key to Undercloud VM"
59     LIBGUESTFS_BACKEND=direct virt-customize -a $undercloud_dst --run-command "mkdir -p /root/.ssh/" \
60         --upload ~/.ssh/id_rsa.pub:/root/.ssh/authorized_keys \
61         --run-command "chmod 600 /root/.ssh/authorized_keys && restorecon /root/.ssh/authorized_keys" \
62         --run-command "cp /root/.ssh/authorized_keys /home/stack/.ssh/" \
63         --run-command "chown stack:stack /home/stack/.ssh/authorized_keys && chmod 600 /home/stack/.ssh/authorized_keys"
64     virsh start undercloud
65     virsh autostart undercloud
66   fi
67
68   sleep 10 # let undercloud get started up
69
70   # get the undercloud VM IP
71   CNT=10
72   echo -n "${blue}Waiting for Undercloud's dhcp address${reset}"
73   undercloud_mac=$(virsh domiflist undercloud | grep default | awk '{ print $5 }')
74   while ! $(arp -en | grep ${undercloud_mac} > /dev/null) && [ $CNT -gt 0 ]; do
75       echo -n "."
76       sleep 10
77       CNT=$((CNT-1))
78   done
79   UNDERCLOUD=$(arp -en | grep ${undercloud_mac} | awk {'print $1'})
80
81   if [ -z "$UNDERCLOUD" ]; then
82     echo "\n\nCan't get IP for Undercloud. Can Not Continue."
83     exit 1
84   else
85      echo -e "${blue}\rUndercloud VM has IP $UNDERCLOUD${reset}"
86   fi
87
88   CNT=10
89   echo -en "${blue}\rValidating Undercloud VM connectivity${reset}"
90   while ! ping -c 1 $UNDERCLOUD > /dev/null && [ $CNT -gt 0 ]; do
91       echo -n "."
92       sleep 3
93       CNT=$((CNT-1))
94   done
95   if [ "$CNT" -eq 0 ]; then
96       echo "Failed to contact Undercloud. Can Not Continue"
97       exit 1
98   fi
99   CNT=10
100   while ! ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "echo ''" 2>&1> /dev/null && [ $CNT -gt 0 ]; do
101       echo -n "."
102       sleep 3
103       CNT=$((CNT-1))
104   done
105   if [ "$CNT" -eq 0 ]; then
106       echo "Failed to connect to Undercloud. Can Not Continue"
107       exit 1
108   fi
109
110   # extra space to overwrite the previous connectivity output
111   echo -e "${blue}\r                                                                 ${reset}"
112   sleep 1
113
114   # ssh key fix for stack user
115   ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "restorecon -r /home/stack"
116 }
117
118 ##Copy over the glance images and instackenv json file
119 ##params: none
120 function configure_undercloud {
121   local controller_nic_template compute_nic_template
122   echo
123   echo "Copying configuration files to Undercloud"
124   echo -e "${blue}Network Environment set for Deployment: ${reset}"
125   cat $APEX_TMP_DIR/network-environment.yaml
126   scp ${SSH_OPTIONS[@]} $APEX_TMP_DIR/network-environment.yaml "stack@$UNDERCLOUD":
127
128   # check for ODL L3/ONOS
129   if [ "${deploy_options_array['sdn_l3']}" == 'True' ]; then
130     if [ "${deploy_options_array['dataplane']}" == 'fdio' ]; then
131       ext_net_type=vpp_interface
132     else
133       ext_net_type=br-ex
134     fi
135   fi
136
137   if [ "${deploy_options_array['dataplane']}" == 'ovs_dpdk' ]; then
138     ovs_dpdk_bridge='br-phy'
139   else
140     ovs_dpdk_bridge=''
141   fi
142
143   if ! controller_nic_template=$(python3 -B $LIB/python/apex_python_utils.py nic-template -r controller -s $NETSETS -t $BASE/nics-template.yaml.jinja2 -e "br-ex" --deploy-settings-file $DEPLOY_SETTINGS_FILE); then
144     echo -e "${red}ERROR: Failed to generate controller NIC heat template ${reset}"
145     exit 1
146   fi
147
148   if ! compute_nic_template=$(python3 -B $LIB/python/apex_python_utils.py nic-template -r compute -s $NETSETS -t $BASE/nics-template.yaml.jinja2 -e $ext_net_type -d "$ovs_dpdk_bridge" --deploy-settings-file $DEPLOY_SETTINGS_FILE); then
149     echo -e "${red}ERROR: Failed to generate compute NIC heat template ${reset}"
150     exit 1
151   fi
152   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" << EOI
153 mkdir nics/
154 cat > nics/controller.yaml << EOF
155 $controller_nic_template
156 EOF
157 cat > nics/compute.yaml << EOF
158 $compute_nic_template
159 EOF
160 EOI
161
162   # ensure stack user on Undercloud machine has an ssh key
163   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" "if [ ! -e ~/.ssh/id_rsa.pub ]; then ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa; fi"
164
165   if [ "$virtual" == "TRUE" ]; then
166
167       # copy the Undercloud VM's stack user's pub key to
168       # root's auth keys so that Undercloud can control
169       # vm power on the hypervisor
170       ssh ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" "cat /home/stack/.ssh/id_rsa.pub" >> /root/.ssh/authorized_keys
171   fi
172
173   # allow stack to control power management on the hypervisor via sshkey
174   # only if this is a virtual deployment
175   if [ "$virtual" == "TRUE" ]; then
176       ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" <<EOI
177 while read -r line; do
178   stack_key=\${stack_key}\\\\\\\\n\${line}
179 done < <(cat ~/.ssh/id_rsa)
180 stack_key=\$(echo \$stack_key | sed 's/\\\\\\\\n//')
181 sed -i 's~INSERT_STACK_USER_PRIV_KEY~'"\$stack_key"'~' instackenv.json
182 EOI
183   fi
184
185   # copy stack's ssh key to this users authorized keys
186   ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "cat /home/stack/.ssh/id_rsa.pub" >> ~/.ssh/authorized_keys
187
188   # disable requiretty for sudo
189   ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "sed -i 's/Defaults\s*requiretty//'" /etc/sudoers
190
191   # configure undercloud on Undercloud VM
192   echo "Running undercloud configuration."
193   echo "Logging undercloud configuration to undercloud:/home/stack/apex-undercloud-install.log"
194   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" << EOI
195 sed -i 's/#local_ip/local_ip/' undercloud.conf
196 sed -i 's/#network_gateway/network_gateway/' undercloud.conf
197 sed -i 's/#network_cidr/network_cidr/' undercloud.conf
198 sed -i 's/#dhcp_start/dhcp_start/' undercloud.conf
199 sed -i 's/#dhcp_end/dhcp_end/' undercloud.conf
200 sed -i 's/#inspection_iprange/inspection_iprange/' undercloud.conf
201 sed -i 's/#undercloud_debug/undercloud_debug/' undercloud.conf
202
203 openstack-config --set undercloud.conf DEFAULT local_ip ${admin_installer_vm_ip}/${admin_cidr##*/}
204 openstack-config --set undercloud.conf DEFAULT network_gateway ${admin_installer_vm_ip}
205 openstack-config --set undercloud.conf DEFAULT network_cidr ${admin_cidr}
206 openstack-config --set undercloud.conf DEFAULT dhcp_start ${admin_dhcp_range%%,*}
207 openstack-config --set undercloud.conf DEFAULT dhcp_end ${admin_dhcp_range##*,}
208 openstack-config --set undercloud.conf DEFAULT inspection_iprange ${admin_introspection_range}
209 openstack-config --set undercloud.conf DEFAULT undercloud_debug false
210 openstack-config --set undercloud.conf DEFAULT undercloud_hostname "undercloud.${domain_name}"
211 sudo openstack-config --set /etc/ironic/ironic.conf disk_utils iscsi_verify_attempts 30
212 sudo openstack-config --set /etc/ironic/ironic.conf disk_partitioner check_device_max_retries 40
213
214 if [[ -n "${deploy_options_array['ceph_device']}" ]]; then
215     sed -i '/ExtraConfig/a\\    ceph::profile::params::osds: {\\x27${deploy_options_array['ceph_device']}\\x27: {}}' ${ENV_FILE}
216 fi
217
218 sudo sed -i '/CephClusterFSID:/c\\  CephClusterFSID: \\x27$(cat /proc/sys/kernel/random/uuid)\\x27' /usr/share/openstack-tripleo-heat-templates/environments/storage-environment.yaml
219 sudo sed -i '/CephMonKey:/c\\  CephMonKey: \\x27'"\$(ceph-authtool --gen-print-key)"'\\x27' /usr/share/openstack-tripleo-heat-templates/environments/storage-environment.yaml
220 sudo sed -i '/CephAdminKey:/c\\  CephAdminKey: \\x27'"\$(ceph-authtool --gen-print-key)"'\\x27' /usr/share/openstack-tripleo-heat-templates/environments/storage-environment.yaml
221
222 # we assume that packages will not need to be updated with undercloud install
223 # and that it will be used only to configure the undercloud
224 # packages updates would need to be handled manually with yum update
225 sudo cp -f /usr/share/diskimage-builder/elements/yum/bin/install-packages /usr/share/diskimage-builder/elements/yum/bin/install-packages.bak
226 cat << 'EOF' | sudo tee /usr/share/diskimage-builder/elements/yum/bin/install-packages > /dev/null
227 #!/bin/sh
228 exit 0
229 EOF
230
231 openstack undercloud install &> apex-undercloud-install.log || {
232     # cat the undercloud install log incase it fails
233     echo "ERROR: openstack undercloud install has failed. Dumping Log:"
234     cat apex-undercloud-install.log
235     exit 1
236 }
237
238 sleep 30
239 sudo systemctl restart openstack-glance-api
240 # Set nova domain name
241 sudo openstack-config --set /etc/nova/nova.conf DEFAULT dns_domain ${domain_name}
242 sudo openstack-config --set /etc/nova/nova.conf DEFAULT dhcp_domain ${domain_name}
243 sudo systemctl restart openstack-nova-conductor
244 sudo systemctl restart openstack-nova-compute
245 sudo systemctl restart openstack-nova-api
246 sudo systemctl restart openstack-nova-scheduler
247
248 # Set neutron domain name
249 sudo openstack-config --set /etc/neutron/neutron.conf DEFAULT dns_domain ${domain_name}
250 sudo systemctl restart neutron-server
251 sudo systemctl restart neutron-dhcp-agent
252
253 sudo sed -i '/num_engine_workers/c\num_engine_workers = 2' /etc/heat/heat.conf
254 sudo sed -i '/#workers\s=/c\workers = 2' /etc/heat/heat.conf
255 sudo systemctl restart openstack-heat-engine
256 sudo systemctl restart openstack-heat-api
257 EOI
258
259 # configure external network
260 if [[ "$enabled_network_list" =~ "external" ]]; then
261   ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" << EOI
262 if [[ "$external_installer_vm_vlan" != "native" ]]; then
263   cat <<EOF > /etc/sysconfig/network-scripts/ifcfg-vlan${external_installer_vm_vlan}
264 DEVICE=vlan${external_installer_vm_vlan}
265 ONBOOT=yes
266 DEVICETYPE=ovs
267 TYPE=OVSIntPort
268 BOOTPROTO=static
269 IPADDR=${external_installer_vm_ip}
270 PREFIX=${external_cidr##*/}
271 OVS_BRIDGE=br-ctlplane
272 OVS_OPTIONS="tag=${external_installer_vm_vlan}"
273 EOF
274   ifup vlan${external_installer_vm_vlan}
275 else
276   if ! ip a s eth2 | grep ${external_installer_vm_ip} > /dev/null; then
277       ip a a ${external_installer_vm_ip}/${external_cidr##*/} dev eth2
278       ip link set up dev eth2
279   fi
280 fi
281 EOI
282 fi
283
284 # WORKAROUND: must restart the above services to fix sync problem with nova compute manager
285 # TODO: revisit and file a bug if necessary. This should eventually be removed
286 # as well as glance api problem
287 echo -e "${blue}INFO: Sleeping 15 seconds while services come back from restart${reset}"
288 sleep 15
289
290 }