Fixes clean to restore network config to LF jumphost
[genesis.git] / common / ci / clean.sh
1 #!/usr/bin/env bash
2
3 #Common clean script to uninstall provisioning server
4 #author: Tim Rozet (trozet@redhat.com)
5 #
6 #Removes Libvirt, KVM, Vagrant, VirtualBox
7 #
8 #Destroys Vagrant VMs running in $vm_dir/
9 #Shuts down all nodes found in Khaleesi settings
10 #Removes hypervisor kernel modules (VirtualBox & KVM/Libvirt)
11
12 ##VARS
13 reset=`tput sgr0`
14 blue=`tput setaf 4`
15 red=`tput setaf 1`
16 green=`tput setaf 2`
17 pxe_bridge='pxebr'
18 vm_dir=/var/opt/opnfv
19 first_interface='enp6s0'
20 second_interface='enp7s0'
21 management_vid=300
22 management_interface="${first_interface}.${management_vid}"
23 ##END VARS
24
25 ##FUNCTIONS
26 display_usage() {
27   echo -e "\n\n${blue}This script is used to uninstall and clean the OPNFV Target System${reset}\n\n"
28   echo -e "\nUsage:\n$0 [arguments] \n"
29   echo -e "\n   -no_parse : No variable parsing into config. Flag. \n"
30   echo -e "\n   -base_config : Full path of ksgen settings file to parse. Required.  Will provide BMC info to shutdown hosts.  Example:  -base_config /opt/myinventory.yml \n"
31 }
32
33 remove_interface_with_name_pattern() {
34   if [ -z $1 ]; then
35     echo "${red}Cannot remove interface. No interface name pattern specified!${reset}"
36     exit 1
37   fi
38   local interface_name_pattern=$1
39   echo "${blue} Looking for interface with name pattern: ${interface_name_pattern}${reset}"
40   interface=$(ip link show | grep -oP ${interface_name_pattern})
41   if [ ! -z "${interface}" ]; then
42     echo "${blue}Interface ${interface} detected! Removing...${reset}"
43     ip link del ${interface}
44     if ip link show | grep -oP ${interface_name_pattern}; then
45       echo "${red}Could not remove interface ${interface} ${reset}"
46       exit 1
47     else
48       echo "${blue}Interface ${interface} successfully removed${reset}"
49     fi
50   else
51     echo "${blue}Interface with name pattern ${interface_name_pattern} does not exist, nothing to remove${reset}"
52   fi
53 }
54 ##END FUNCTIONS
55
56 if [[ ( $1 == "--help") ||  $1 == "-h" ]]; then
57     display_usage
58     exit 0
59 fi
60
61 echo -e "\n\n${blue}This script is used to uninstall and clean the OPNFV Target System${reset}\n\n"
62 echo "Use -h to display help"
63 sleep 2
64
65 while [ "`echo $1 | cut -c1`" = "-" ]
66 do
67     echo $1
68     case "$1" in
69         -base_config)
70                 base_config=$2
71                 shift 2
72             ;;
73         *)
74                 display_usage
75                 exit 1
76             ;;
77 esac
78 done
79
80 if [ ! -z "$base_config" ]; then
81   # Install ipmitool
82   # Major version is pinned to force some consistency for Arno
83   if ! yum list installed | grep -i ipmitool; then
84     if ! yum -y install ipmitool-1*; then
85       echo "${red}Unable to install ipmitool!${reset}"
86       exit 1
87     fi
88   else
89     echo "${blue}Skipping ipmitool as it is already installed!${reset}"
90   fi
91
92   ###find all the bmc IPs and number of nodes
93   node_counter=0
94   output=`grep bmc_ip $base_config | grep -Eo '[0-9]+.[0-9]+.[0-9]+.[0-9]+'`
95   for line in ${output} ; do
96     bmc_ip[$node_counter]=$line
97     ((node_counter++))
98   done
99
100   max_nodes=$((node_counter-1))
101
102   ###find bmc_users per node
103   node_counter=0
104   output=`grep bmc_user $base_config | sed 's/\s*bmc_user:\s*//'`
105   for line in ${output} ; do
106     bmc_user[$node_counter]=$line
107     ((node_counter++))
108   done
109
110   ###find bmc_pass per node
111   node_counter=0
112   output=`grep bmc_pass $base_config | sed 's/\s*bmc_pass:\s*//'`
113   for line in ${output} ; do
114     bmc_pass[$node_counter]=$line
115     ((node_counter++))
116   done
117   for mynode in `seq 0 $max_nodes`; do
118     echo "${blue}Node: ${bmc_ip[$mynode]} ${bmc_user[$mynode]} ${bmc_pass[$mynode]} ${reset}"
119     if ipmitool -I lanplus -P ${bmc_pass[$mynode]} -U ${bmc_user[$mynode]} -H ${bmc_ip[$mynode]} chassis power off; then
120       echo "${blue}Node: $mynode, ${bmc_ip[$mynode]} powered off!${reset}"
121     else
122       echo "${red}Error: Unable to power off $mynode, ${bmc_ip[$mynode]} ${reset}"
123       exit 1
124     fi
125   done
126 else
127   echo "${blue}Skipping Baremetal node poweroff as base_config was not provided${reset}"
128 fi
129 ###check to see if vbox is installed
130 vboxpkg=`rpm -qa | grep VirtualBox`
131 if [ $? -eq 0 ]; then
132   skip_vagrant=0
133 else
134   skip_vagrant=1
135 fi
136
137 ###legacy VM location check
138 ###remove me later
139 if [ -d /tmp/bgs_vagrant ]; then
140   cd /tmp/bgs_vagrant
141   vagrant destroy -f
142   rm -rf /tmp/bgs_vagrant
143 fi
144
145 ###destroy vagrant
146 if [ $skip_vagrant -eq 0 ]; then
147   if [ -d $vm_dir ]; then
148     ##all vm directories
149     for vm in $( ls $vm_dir ); do
150       cd $vm_dir/$vm
151       if vagrant destroy -f; then
152         echo "${blue}Successfully destroyed $vm Vagrant VM ${reset}"
153       else
154         echo "${red}Unable to destroy $vm Vagrant VM! Attempting to killall vagrant if process is hung ${reset}"
155         killall vagrant
156         echo "${blue}Checking if vagrant was already destroyed and no process is active...${reset}"
157         if ps axf | grep vagrant; then
158           echo "${red}Vagrant process still exists after kill...exiting ${reset}"
159           exit 1
160         else
161           echo "${blue}Vagrant process doesn't exist.  Moving on... ${reset}"
162         fi
163       fi
164
165       ##Vagrant boxes appear as VboxHeadless processes
166       ##try to gracefully destroy the VBox VM if it still exists
167       if vboxmanage list runningvms | grep $vm; then
168         echo "${red} $vm VBoxHeadless process still exists...Removing${reset}"
169         vbox_id=$(vboxmanage list runningvms | grep $vm | awk '{print $1}' | sed 's/"//g')
170         vboxmanage controlvm $vbox_id poweroff
171         if vboxmanage unregistervm --delete $vbox_id; then
172           echo "${blue}$vm VM is successfully deleted! ${reset}"
173         else
174           echo "${red} Unable to delete VM $vm ...Exiting ${reset}"
175           exit 1
176         fi
177       else
178         echo "${blue}$vm VM is successfully deleted! ${reset}"
179       fi
180     done
181   else
182     echo "${blue}${vm_dir} doesn't exist, no VMs in OPNFV directory to destroy! ${reset}"
183   fi
184
185   echo "${blue}Checking for any remaining virtual box processes...${reset}"
186   ###kill virtualbox
187   if ps axf | grep virtualbox; then
188     echo "${blue}virtualbox processes are still running. Killing any remaining VirtualBox processes...${reset}"
189     killall virtualbox
190   fi
191
192   ###kill any leftover VMs (brute force)
193   if ps axf | grep VBoxHeadless; then
194     echo "${blue}VBoxHeadless processes are still running. Killing any remaining VBoxHeadless processes...${reset}"
195     killall VBoxHeadless
196   fi
197
198   ###remove virtualbox
199   echo "${blue}Removing VirtualBox... ${reset}"
200   yum -y remove $vboxpkg
201
202 else
203   echo "${blue}Skipping Vagrant destroy + VBox Removal as VirtualBox package is already removed ${reset}"
204 fi
205
206 ###remove working vm directory
207 echo "${blue}Removing working VM directory: $vm_dir ${reset}"
208 rm -rf $vm_dir
209
210 ###check to see if libvirt is installed
211 echo "${blue}Checking if libvirt/KVM is installed"
212 if rpm -qa | grep -iE 'libvirt|kvm'; then
213   echo "${blue}Libvirt/KVM is installed${reset}"
214   echo "${blue}Checking for any QEMU/KVM VMs...${reset}"
215   vm_count=0
216   while read -r line; do ((vm_count++)); done < <(virsh list --all | sed 1,2d | head -n -1)
217   if [ $vm_count -gt 0 ]; then
218     echo "${blue}VMs Found: $vm_count${reset}"
219     vm_runnning=0
220     while read -r line; do ((vm_running++)); done < <(virsh list --all | sed 1,2d | head -n -1| grep -i running)
221     echo "${blue}Powering off $vm_running VM(s)${reset}"
222     while read -r vm; do
223       if ! virsh destroy $vm; then
224         echo "${red}WARNING: Unable to power off VM ${vm}${reset}"
225       else
226         echo "${blue}VM $vm powered off!${reset}"
227       fi
228     done < <(virsh list --all | sed 1,2d | head -n -1| grep -i running | sed 's/^[ \t]*//' | awk '{print $2}')
229     echo "${blue}Destroying libvirt VMs...${reset}"
230     while read -r vm; do
231       if ! virsh undefine --remove-all-storage $vm; then
232         echo "${red}ERROR: Unable to remove the VM ${vm}${reset}"
233         exit 1
234       else
235         echo "${blue}VM $vm removed!${reset}"
236       fi
237     done < <(virsh list --all | sed 1,2d | head -n -1| awk '{print $2}')
238   else
239     echo "${blue}No VMs found for removal"
240   fi
241   echo "${blue}Removing libvirt and kvm packages"
242   yum -y remove libvirt-*
243   yum -y remove *qemu*
244 else
245   echo "${blue}libvirt/KVM is not installed${reset}"
246 fi
247
248 ###remove possible VMs (needed for 'rmmod kvm_intel')
249 if [ -n "$(ps -ef | grep qemu-kvm | grep -v grep)" ]; then
250     echo "${blue}Removing existing VMs ${reset}"
251     killall -9 qemu-kvm
252 fi
253
254 ###remove kernel modules
255 echo "${blue}Removing kernel modules ${reset}"
256 for kernel_mod in vboxnetadp vboxnetflt vboxpci vboxdrv kvm_intel kvm; do
257   if ! rmmod $kernel_mod; then
258     if rmmod $kernel_mod 2>&1 | grep -i 'not currently loaded'; then
259       echo "${blue} $kernel_mod is not currently loaded! ${reset}"
260     else
261       echo "${red}Error trying to remove Kernel Module: $kernel_mod ${reset}"
262       exit 1
263     fi
264   else
265     echo "${blue}Removed Kernel Module: $kernel_mod ${reset}"
266   fi
267 done
268
269 ###remove PXE bridge
270 echo "${blue}Checking whether PXE bridge ${pxe_bridge} exists${reset}"
271 if ! brctl show ${pxe_bridge} 2>&1 | grep -i 'No such device'; then
272   echo "${blue}PXE bridge ${pxe_bridge} detected! Removing...${reset}"
273   link_state=$(ip link show ${pxe_bridge} | grep -oP 'state \K[^ ]+')
274   if [[ ${link_state} != 'DOWN' ]]; then
275     ip link set dev ${pxe_bridge} down
276     sleep 5
277     link_state=$(ip link show ${pxe_bridge} | grep -oP 'state \K[^ ]+')
278     if [[ ${link_state} != 'DOWN' ]]; then
279       echo "${red}Could not bring DOWN bridge ${pxe_bridge} link state is ${link_state}${reset}"
280       exit 1
281     fi
282   fi
283   brctl delbr ${pxe_bridge}
284   if ifconfig | grep ${pxe_bridge} || brctl show | grep ${pxe_bridge}; then
285     echo "${red}Error trying to remove ${pxe_bridge}${reset}"
286     exit 1
287   else
288     echo "${blue}PXE bridge ${pxe_bridge} removed${reset}"
289   fi
290 else
291   echo "${blue}PXE bridge ${pxe_bridge} does not exist${reset}"
292 fi
293
294 ###remove PXE interface (VLAN 0)
295 echo "${blue}Checking whether PXE interface (VLAN 0) exists and remove it${reset}"
296 remove_interface_with_name_pattern "enp.+s.+\.0"
297
298 ###remove Openstack Management interface (VLAN 300)
299 echo "${blue}Checking whether Openstack Management interface (VLAN 300) exists and remove it${reset}"
300 remove_interface_with_name_pattern "enp.+s.+\.${management_vid}"
301
302 ###bounce interfaces to restore default IP config
303 echo "${blue}Bouncing interfaces to restore IP config${reset}"
304 for interface in $first_interface $second_interface; do
305   echo "${blue}Bouncing interface: ${interface}${reset}"
306   ifdown $interface
307   sleep 5
308   ifup $interface
309   tries=5
310   counter=0
311   while [ $counter -lt $tries ]; do
312     if ip addr show $interface | grep -Eo "inet [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"; then
313       temp_ip=$(ip addr show $interface | grep -Eo "inet [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" | awk '{print $2}')
314       echo "${blue}IP found on ${interface}.  IP is ${temp_ip}${reset}"
315       break
316     else
317       ((counter++))
318       sleep 2
319     fi
320   done
321
322   if [ "$counter" -ge 5 ]; then
323     echo "${red}Error: Unable to get IP address on ${interface}${reset}"
324     exit 1
325   fi
326 done