deploy.sh 12.3 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash

# Deploy script to install provisioning server for OPNFV Apex
# author: Dan Radez (dradez@redhat.com)
# author: Tim Rozet (trozet@redhat.com)
#
# Based on RDO Manager http://www.rdoproject.org
#
# Pre-requisties:
#  - Supports 3 or 4 network interface configuration
#  - Target system must be RPM based
#  - Provisioned nodes expected to have following order of network connections (note: not all have to exist, but order is maintained):
#    eth0- admin network
#    eth1- private network (+storage network in 3 NIC config)
#    eth2- public network
#    eth3- storage network
#  - script assumes /24 subnet mask

set -e

##VARIABLES
22
23
24
25
26
#reset=`tput sgr0`
#blue=`tput setaf 4`
#red=`tput setaf 1`
#green=`tput setaf 2`

Tim Rozet's avatar
Tim Rozet committed
27
vm_index=4
Dan Radez's avatar
Dan Radez committed
28
ha_enabled="TRUE"
29
30
31
declare -i CNT
declare UNDERCLOUD

32
SSH_OPTIONS=(-o StrictHostKeyChecking=no -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null -o LogLevel=error)
33
34
35
36
DEPLOY_OPTIONS=""
RESOURCES=/var/opt/opnfv/stack
CONFIG=/var/opt/opnfv

37
##FUNCTIONS
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
##verify internet connectivity
#params: none
function verify_internet {
  if ping -c 2 8.8.8.8 > /dev/null; then
    if ping -c 2 www.google.com > /dev/null; then
      echo "${blue}Internet connectivity detected${reset}"
      return 0
    else
      echo "${red}Internet connectivity detected, but DNS lookup failed${reset}"
      return 1
    fi
  else
    echo "${red}No internet connectivity detected${reset}"
    return 1
  fi
}

##download dependencies if missing and configure host
#params: none
function configure_deps {
  if ! verify_internet; then
    echo "${red}Will not download dependencies${reset}"
    internet=false
  else
    internet=true
  fi

  # ensure brbm network is configured
  systemctl start openvswitch
  ovs-vsctl list-br | grep brbm > /dev/null || ovs-vsctl add-br brbm
  virsh net-list --all | grep brbm > /dev/null || virsh net-create $CONFIG/brbm-net.xml
  virsh net-list | grep -E "brbm\s+active" > /dev/null || virsh net-start brbm

  # ensure storage pool exists and is started
  virsh pool-list --all | grep default > /dev/null || virsh pool-create $CONFIG/default-pool.xml
  virsh pool-list | grep -Eo "default\s+active" > /dev/null || virsh pool-start default

  if virsh net-list | grep default > /dev/null; then
    num_ints_same_subnet=$(ip addr show | grep "inet 192.168.122" | wc -l)
    if [ "$num_ints_same_subnet" -gt 1 ]; then
      virsh net-destroy default
      ##go edit /etc/libvirt/qemu/networks/default.xml
      sed -i 's/192.168.122/192.168.123/g' /etc/libvirt/qemu/networks/default.xml
      sed -i 's/192.168.122/192.168.123/g' instackenv-virt.json
      sleep 5
      virsh net-start default
      virsh net-autostart default
    fi
  fi

  if ! egrep '^flags.*(vmx|svm)' /proc/cpuinfo > /dev/null; then
    echo "${red}virtualization extensions not found, kvm kernel module insertion may fail.\n  \
Are you sure you have enabled vmx in your bios or hypervisor?${reset}"
  fi

  modprobe kvm
  modprobe kvm_intel

  if ! lsmod | grep kvm > /dev/null; then
    echo "${red}kvm kernel modules not loaded!${reset}"
    return 1
  fi

  ##sshkeygen for root
  if [ ! -e ~/.ssh/id_rsa.pub ]; then
    ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
  fi

  echo "${blue}All dependencies installed and running${reset}"
}
108
109
110
111

##verify vm exists, an has a dhcp lease assigned to it
##params: none 
function setup_instack_vm {
112
  if ! virsh list --all | grep instack > /dev/null; then
113
      #virsh vol-create default instack.qcow2.xml
114
      virsh define $CONFIG/instack.xml
115

116
117
118
119
120
121
      #Upload instack image
      #virsh vol-create default --file instack.qcow2.xml
      virsh vol-create-as default instack.qcow2 30G --format qcow2
      virsh vol-upload --pool default --vol instack.qcow2 --file $CONFIG/stack/instack.qcow2

      sleep 1 # this was to let the copy settle, needed with vol-upload?
122
123
124
125

  else
      echo "Found Instack VM, using existing VM"
  fi
126
127
128
129
130
131
132
133
134
135
136

  # if the VM is not running update the authkeys and start it
  if ! virsh list | grep instack > /dev/null; then
    echo "Injecting ssh key to instack VM"
    virt-customize -c qemu:///system -d instack --upload ~/.ssh/id_rsa.pub:/root/.ssh/authorized_keys \
        --run-command "chmod 600 /root/.ssh/authorized_keys && restorecon /root/.ssh/authorized_keys" \
        --run-command "cp /root/.ssh/authorized_keys /home/stack/.ssh/" \
        --run-command "chown stack:stack /home/stack/.ssh/authorized_keys && chmod 600 /home/stack/.ssh/authorized_keys"
    virsh start instack
  fi

137
138
139
  sleep 3 # let DHCP happen

  CNT=10
140
141
  echo -n "${blue}Waiting for instack's dhcp address${reset}"
  while ! grep instack /var/lib/libvirt/dnsmasq/default.leases > /dev/null && [ $CNT -gt 0 ]; do
142
143
144
145
146
147
      echo -n "."
      sleep 3
      CNT=CNT-1
  done

  # get the instack VM IP
148
  UNDERCLOUD=$(grep instack /var/lib/libvirt/dnsmasq/default.leases | awk '{print $3}' | head -n 1)
149
150

  CNT=10
151
  echo -en "${blue}\rValidating instack VM connectivity${reset}"
152
153
154
155
156
157
  while ! ping -c 1 $UNDERCLOUD > /dev/null && [ $CNT -gt 0 ]; do
      echo -n "."
      sleep 3
      CNT=CNT-1
  done
  CNT=10
158
  while ! ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "echo ''" 2>&1> /dev/null && [ $CNT -gt 0 ]; do
159
160
161
162
163
164
      echo -n "."
      sleep 3
      CNT=CNT-1
  done

  # extra space to overwrite the previous connectivity output
165
166
167
168
169
170
  echo -e "${blue}\rInstack VM has IP $UNDERCLOUD                                    ${reset}"

  ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "if ! ip a s eth1 | grep 192.0.2.1 > /dev/null; then ip a a 192.0.2.1/24 dev eth1; fi"
  # ssh key fix for stack user
  ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "restorecon -r /home/stack"
}
171

Tim Rozet's avatar
Tim Rozet committed
172
173
##Create virtual nodes in virsh
##params: none
174
175
176
function setup_virtual_baremetal {
  for i in $(seq 0 $vm_index); do
    if ! virsh list --all | grep baremetalbrbm_${i} > /dev/null; then
Tim Rozet's avatar
Tim Rozet committed
177
178
179
      if [ ! -e $CONFIG/baremetalbrbm_${i}.xml ]; then
        define_virtual_node baremetalbrbm_${i}
      fi
180
181
182
183
184
185
      virsh define $CONFIG/baremetalbrbm_${i}.xml
    else
      echo "Found Baremetal ${i} VM, using existing VM"
    fi
    virsh vol-list default | grep baremetalbrbm_${i} 2>&1> /dev/null || virsh vol-create-as default baremetalbrbm_${i}.qcow2 40G --format qcow2
  done
186
187
188
}

##Copy over the glance images and instack json file
Tim Rozet's avatar
Tim Rozet committed
189
##params: none
190
191
function copy_materials {

192
193
  echo
  echo "Copying configuration file and disk images to instack"
194
195
196
197
198
199
200
201
  scp ${SSH_OPTIONS[@]} $RESOURCES/deploy-ramdisk-ironic.initramfs "stack@$UNDERCLOUD":
  scp ${SSH_OPTIONS[@]} $RESOURCES/deploy-ramdisk-ironic.kernel "stack@$UNDERCLOUD":
  scp ${SSH_OPTIONS[@]} $RESOURCES/ironic-python-agent.initramfs "stack@$UNDERCLOUD":
  scp ${SSH_OPTIONS[@]} $RESOURCES/ironic-python-agent.kernel "stack@$UNDERCLOUD":
  scp ${SSH_OPTIONS[@]} $RESOURCES/ironic-python-agent.vmlinuz "stack@$UNDERCLOUD":
  scp ${SSH_OPTIONS[@]} $RESOURCES/overcloud-full.initrd "stack@$UNDERCLOUD":
  scp ${SSH_OPTIONS[@]} $RESOURCES/overcloud-full.qcow2 "stack@$UNDERCLOUD":
  scp ${SSH_OPTIONS[@]} $RESOURCES/overcloud-full.vmlinuz "stack@$UNDERCLOUD":
202
203
204
205
206
207
208
209
  scp ${SSH_OPTIONS[@]} $CONFIG/opendaylight.yaml "stack@$UNDERCLOUD":

  ## WORK AROUND
  # when OpenDaylight lands in upstream RDO manager this can be removed
  # apply the opendaylight patch
  scp ${SSH_OPTIONS[@]} $CONFIG/opendaylight.patch "root@$UNDERCLOUD":
  ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "cd /usr/share/openstack-tripleo-heat-templates/; patch -Np1 < /root/opendaylight.patch"
  ## END WORK AROUND
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244

  # ensure stack user on instack machine has an ssh key
  ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" "if [ ! -e ~/.ssh/id_rsa.pub ]; then ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa; fi"

  if [ $virtual == "TRUE" ]; then
      # fix MACs to match new setup
      for i in $(seq 0 $vm_index); do
        pyscript="import json
data = json.load(open('$CONFIG/instackenv-virt.json'))
print data['nodes'][$i]['mac'][0]"

        old_mac=$(python -c "$pyscript")
        new_mac=$(virsh dumpxml baremetalbrbm_$i | grep "mac address" | cut -d = -f2 | grep -Eo "[0-9a-f:]+")
        if [ "$old_mac" != "$new_mac" ]; then
          echo "${blue}Modifying MAC for node from $old_mac to ${new_mac}${reset}"
          sed -i 's/'"$old_mac"'/'"$new_mac"'/' $CONFIG/instackenv-virt.json
        fi
      done

      # upload virt json file
      scp ${SSH_OPTIONS[@]} $CONFIG/instackenv-virt.json "stack@$UNDERCLOUD":instackenv.json

      # allow stack to control power management on the hypervisor via sshkey
      ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" <<EOI
while read -r line; do
  stack_key=\${stack_key}\\\\\\\\n\${line}
done < <(cat ~/.ssh/id_rsa)
stack_key=\$(echo \$stack_key | sed 's/\\\\\\\\n//')
sed -i 's~INSERT_STACK_USER_PRIV_KEY~'"\$stack_key"'~' instackenv.json
EOI
      DEPLOY_OPTIONS+="--libvirt-type qemu"
  else
      scp ${SSH_OPTIONS[@]} $CONFIG/instackenv.json "stack@$UNDERCLOUD":
  fi

245

246
247
# copy stack's ssh key to this users authorized keys
ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "cat /home/stack/.ssh/id_rsa.pub" >> ~/.ssh/authorized_keys
248
249
250
}

##preping it for deployment and launch the deploy
Tim Rozet's avatar
Tim Rozet committed
251
##params: none
252
function undercloud_prep_overcloud_deploy {
Tim Rozet's avatar
Tim Rozet committed
253
  # check if HA is enabled
Dan Radez's avatar
Dan Radez committed
254
  if [ $ha_enabled == "TRUE" ]; then
Tim Rozet's avatar
Tim Rozet committed
255
256
257
258
     DEPLOY_OPTIONS+=" --control-scale 3 --compute-scale 2"
     DEPLOY_OPTIONS+=" -e /usr/share/openstack-tripleo-heat-templates/environments/puppet-pacemaker.yaml"
     DEPLOY_OPTIONS+="  --ntp-server pool.ntp.org"
  fi
259
260

  ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" <<EOI
261
source stackrc
262
263
set -o errexit
echo "Uploading overcloud glance images"
264
openstack overcloud image upload
265
echo "Configuring undercloud and discovering nodes"
266
267
268
openstack baremetal import --json instackenv.json
openstack baremetal configure boot
openstack baremetal introspection bulk start
269
270
echo "Configuring flavors"
openstack flavor list | grep baremetal || openstack flavor create --id auto --ram 4096 --disk 39 --vcpus 1 baremetal
271
openstack flavor set --property "cpu_arch"="x86_64" --property "capabilities:boot_option"="local" baremetal
272
273
echo "Configuring nameserver on ctlplane network"
neutron subnet-update \$(neutron subnet-list | grep -v id | grep -v \\\\-\\\\- | awk {'print \$2'}) --dns-nameserver 8.8.8.8
274
echo "Executing overcloud deployment, this should run for an extended period without output."
275
sleep 60 #wait for Hypervisor stats to check-in to nova
276
openstack overcloud deploy --templates $DEPLOY_OPTIONS -e opendaylight.yaml
277
278
279
280
281
282
283
EOI

}

display_usage() {
  echo -e "\n\n${blue}This script is used to deploy the Apex Installer and Provision OPNFV Target System${reset}\n\n"
  echo -e "\nUsage:\n$0 [arguments] \n"
284
285
286
  echo -e "\n   -c|--config : Full path of settings file to parse. Optional.  Will provide a new base settings file rather than the default.  Example:  --config /opt/myinventory.yml \n"
  echo -e "\n   -r|--resources : Full path of settings file to parse. Optional.  Will provide a new base settings file rather than the default.  Example:  --config /opt/myinventory.yml \n"
  echo -e "\n   -v|--virtual : Virtualize compute nodes instead of using baremetal. \n"
Dan Radez's avatar
Dan Radez committed
287
288
  echo -e "\n   -p|--ping-site : site to use to verify IP connectivity from the VM when -virtual is used.  Format: -ping_site www.blah.com \n"
  echo -e "\n   -n|--no-ha : disable High Availablility deploymnet scheme, this assumes a single controller and single compute node \n"
289
290
291
292
293
294
295
296
297
298
}

##translates the command line paramaters into variables
##params: $@ the entire command line is passed
##usage: parse_cmd_line() "$@"
parse_cmdline() {
  echo -e "\n\n${blue}This script is used to deploy the Apex Installer and Provision OPNFV Target System${reset}\n\n"
  echo "Use -h to display help"
  sleep 2

Dan Radez's avatar
Dan Radez committed
299
  while [ "${1:0:1}" = "-" ]
300
301
302
  do
    echo $1
    case "$1" in
303
304
305
306
307
308
        -h|--help)
                display_usage
                exit 0
            ;;
        -c|--config)
                CONFIG=$2
309
310
                shift 2
            ;;
311
312
313
        -r|--resources)
                RESOURCES=$2
                shift 2
314
            ;;
315
        -v|--virtual)
316
317
318
                virtual="TRUE"
                shift 1
            ;;
Dan Radez's avatar
Dan Radez committed
319
        -p|--ping-site)
320
321
322
                ping_site=$2
                shift 2
            ;;
Dan Radez's avatar
Dan Radez committed
323
        -n|--no-ha )
Dan Radez's avatar
Dan Radez committed
324
		ha_enabled="FALSE"
Tim Rozet's avatar
Tim Rozet committed
325
326
                shift 1
           ;;
327
328
329
330
331
332
333
334
335
336
337
338
        *)
                display_usage
                exit 1
            ;;
    esac
  done
}

##END FUNCTIONS

main() {
  parse_cmdline "$@"
339
  configure_deps
340
  setup_instack_vm
341
342
343
  if [ $virtual == "TRUE" ]; then
    setup_virtual_baremetal
  fi
344
345
346
347
348
  copy_materials
  undercloud_prep_overcloud_deploy
}

main "$@"