Allow passing a device name to ceph
[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_network"
16       if [[ $enabled_network_list =~ "public_network" ]]; then
17         undercloud_nets+=" public_network"
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 $CONFIG/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 $RESOURCES/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 $RESOURCES/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   if [[ "$net_isolation_enabled" == "TRUE" ]]; then
125     echo -e "${blue}Network Environment set for Deployment: ${reset}"
126     cat /tmp/network-environment.yaml
127     scp ${SSH_OPTIONS[@]} /tmp/network-environment.yaml "stack@$UNDERCLOUD":
128
129     # check for ODL L3/ONOS
130     if [ "${deploy_options_array['sdn_l3']}" == 'True' ]; then
131       ext_net_type=br-ex
132     fi
133
134     if [ "${deploy_options_array['dataplane']}" == 'ovs_dpdk' ]; then
135       ovs_dpdk_bridge='br-phy'
136     else
137       ovs_dpdk_bridge=''
138     fi
139
140     if ! controller_nic_template=$(python3.4 -B $LIB/python/apex_python_utils.py nic-template -r controller -s $NETSETS $net_isolation_arg -t $CONFIG/nics-template.yaml.jinja2 -n "$enabled_network_list" -e "br-ex" -af $ip_addr_family); then
141       echo -e "${red}ERROR: Failed to generate controller NIC heat template ${reset}"
142       exit 1
143     fi
144
145     if ! compute_nic_template=$(python3.4 -B $LIB/python/apex_python_utils.py nic-template -r compute -s $NETSETS $net_isolation_arg -t $CONFIG/nics-template.yaml.jinja2 -n "$enabled_network_list" -e $ext_net_type -af $ip_addr_family -d "$ovs_dpdk_bridge"); then
146       echo -e "${red}ERROR: Failed to generate compute NIC heat template ${reset}"
147       exit 1
148     fi
149     ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" << EOI
150 mkdir nics/
151 cat > nics/controller.yaml << EOF
152 $controller_nic_template
153 EOF
154 cat > nics/compute.yaml << EOF
155 $compute_nic_template
156 EOF
157 EOI
158   fi
159
160   # ensure stack user on Undercloud machine has an ssh key
161   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" "if [ ! -e ~/.ssh/id_rsa.pub ]; then ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa; fi"
162
163   if [ "$virtual" == "TRUE" ]; then
164
165       # copy the Undercloud VM's stack user's pub key to
166       # root's auth keys so that Undercloud can control
167       # vm power on the hypervisor
168       ssh ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" "cat /home/stack/.ssh/id_rsa.pub" >> /root/.ssh/authorized_keys
169
170       INSTACKENV=$CONFIG/instackenv-virt.json
171
172       # upload instackenv file to Undercloud for virtual deployment
173       scp ${SSH_OPTIONS[@]} $INSTACKENV "stack@$UNDERCLOUD":instackenv.json
174   fi
175
176   # allow stack to control power management on the hypervisor via sshkey
177   # only if this is a virtual deployment
178   if [ "$virtual" == "TRUE" ]; then
179       ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" <<EOI
180 while read -r line; do
181   stack_key=\${stack_key}\\\\\\\\n\${line}
182 done < <(cat ~/.ssh/id_rsa)
183 stack_key=\$(echo \$stack_key | sed 's/\\\\\\\\n//')
184 sed -i 's~INSERT_STACK_USER_PRIV_KEY~'"\$stack_key"'~' instackenv.json
185 EOI
186   fi
187
188   # copy stack's ssh key to this users authorized keys
189   ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "cat /home/stack/.ssh/id_rsa.pub" >> ~/.ssh/authorized_keys
190
191   # disable requiretty for sudo
192   ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "sed -i 's/Defaults\s*requiretty//'" /etc/sudoers
193
194   # configure undercloud on Undercloud VM
195   echo "Running undercloud configuration."
196   echo "Logging undercloud configuration to undercloud:/home/stack/apex-undercloud-install.log"
197   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" << EOI
198 if [[ "$net_isolation_enabled" == "TRUE" ]]; then
199   sed -i 's/#local_ip/local_ip/' undercloud.conf
200   sed -i 's/#network_gateway/network_gateway/' undercloud.conf
201   sed -i 's/#network_cidr/network_cidr/' undercloud.conf
202   sed -i 's/#dhcp_start/dhcp_start/' undercloud.conf
203   sed -i 's/#dhcp_end/dhcp_end/' undercloud.conf
204   sed -i 's/#inspection_iprange/inspection_iprange/' undercloud.conf
205   sed -i 's/#undercloud_debug/undercloud_debug/' undercloud.conf
206
207   openstack-config --set undercloud.conf DEFAULT local_ip ${admin_network_provisioner_ip}/${admin_network_cidr##*/}
208   openstack-config --set undercloud.conf DEFAULT network_gateway ${admin_network_provisioner_ip}
209   openstack-config --set undercloud.conf DEFAULT network_cidr ${admin_network_cidr}
210   openstack-config --set undercloud.conf DEFAULT dhcp_start ${admin_network_dhcp_range%%,*}
211   openstack-config --set undercloud.conf DEFAULT dhcp_end ${admin_network_dhcp_range##*,}
212   openstack-config --set undercloud.conf DEFAULT inspection_iprange ${admin_network_introspection_range}
213   openstack-config --set undercloud.conf DEFAULT undercloud_debug false
214   openstack-config --set undercloud.conf DEFAULT undercloud_hostname "undercloud.${domain_name}"
215   sudo openstack-config --set /etc/ironic/ironic.conf disk_utils iscsi_verify_attempts 30
216   sudo openstack-config --set /etc/ironic/ironic.conf disk_partitioner check_device_max_retries 40
217
218 fi
219
220 if [[ -n "${deploy_options_array['ceph_device']}" ]]; then
221     sed -i '/ExtraConfig/a\\    ceph::profile::params::osds: {\\x27${deploy_options_array['ceph_device']}\\x27: {}}' opnfv-environment.yaml
222 fi
223
224 sudo sed -i '/CephClusterFSID:/c\\  CephClusterFSID: \\x27$(cat /proc/sys/kernel/random/uuid)\\x27' /usr/share/openstack-tripleo-heat-templates/environments/storage-environment.yaml
225 sudo sed -i '/CephMonKey:/c\\  CephMonKey: \\x27'"\$(ceph-authtool --gen-print-key)"'\\x27' /usr/share/openstack-tripleo-heat-templates/environments/storage-environment.yaml
226 sudo sed -i '/CephAdminKey:/c\\  CephAdminKey: \\x27'"\$(ceph-authtool --gen-print-key)"'\\x27' /usr/share/openstack-tripleo-heat-templates/environments/storage-environment.yaml
227
228 # we assume that packages will not need to be updated with undercloud install
229 # and that it will be used only to configure the undercloud
230 # packages updates would need to be handled manually with yum update
231 sudo cp -f /usr/share/diskimage-builder/elements/yum/bin/install-packages /usr/share/diskimage-builder/elements/yum/bin/install-packages.bak
232 cat << 'EOF' | sudo tee /usr/share/diskimage-builder/elements/yum/bin/install-packages > /dev/null
233 #!/bin/sh
234 exit 0
235 EOF
236
237 openstack undercloud install &> apex-undercloud-install.log || {
238     # cat the undercloud install log incase it fails
239     echo "ERROR: openstack undercloud install has failed. Dumping Log:"
240     cat apex-undercloud-install.log
241     exit 1
242 }
243
244 sleep 30
245 sudo systemctl restart openstack-glance-api
246 # Set nova domain name
247 sudo openstack-config --set /etc/nova/nova.conf DEFAULT dns_domain ${domain_name}
248 sudo openstack-config --set /etc/nova/nova.conf DEFAULT dhcp_domain ${domain_name}
249 sudo systemctl restart openstack-nova-conductor
250 sudo systemctl restart openstack-nova-compute
251 sudo systemctl restart openstack-nova-api
252 sudo systemctl restart openstack-nova-scheduler
253
254 # Set neutron domain name
255 sudo openstack-config --set /etc/neutron/neutron.conf DEFAULT dns_domain ${domain_name}
256 sudo systemctl restart neutron-server
257 sudo systemctl restart neutron-dhcp-agent
258
259 sudo sed -i '/num_engine_workers/c\num_engine_workers = 2' /etc/heat/heat.conf
260 sudo sed -i '/#workers\s=/c\workers = 2' /etc/heat/heat.conf
261 sudo systemctl restart openstack-heat-engine
262 sudo systemctl restart openstack-heat-api
263 EOI
264
265 # configure external network
266   ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" << EOI
267 if [[ "$public_network_vlan" != "native" ]]; then
268   cat <<EOF > /etc/sysconfig/network-scripts/ifcfg-vlan${public_network_vlan}
269 DEVICE=vlan${public_network_vlan}
270 ONBOOT=yes
271 DEVICETYPE=ovs
272 TYPE=OVSIntPort
273 BOOTPROTO=static
274 IPADDR=${public_network_provisioner_ip}
275 PREFIX=${public_network_cidr##*/}
276 OVS_BRIDGE=br-ctlplane
277 OVS_OPTIONS="tag=${public_network_vlan}"
278 EOF
279   ifup vlan${public_network_vlan}
280 else
281   if ! ip a s eth2 | grep ${public_network_provisioner_ip} > /dev/null; then
282       ip a a ${public_network_provisioner_ip}/${public_network_cidr##*/} dev eth2
283       ip link set up dev eth2
284   fi
285 fi
286 EOI
287
288 # WORKAROUND: must restart the above services to fix sync problem with nova compute manager
289 # TODO: revisit and file a bug if necessary. This should eventually be removed
290 # as well as glance api problem
291 echo -e "${blue}INFO: Sleeping 15 seconds while services come back from restart${reset}"
292 sleep 15
293
294 }