Ignore error if network already undefined
[apex.git] / apex / clean.py
1 ##############################################################################
2 # Copyright (c) 2016 Tim Rozet (trozet@redhat.com) and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9
10 import argparse
11 import fileinput
12 import libvirt
13 import logging
14 import os
15 import pyipmi
16 import pyipmi.interfaces
17 import sys
18
19 from apex.common import (
20     constants,
21     utils)
22 from apex.network import jumphost
23 from apex.common.exceptions import ApexCleanException
24 from virtualbmc import manager as vbmc_lib
25
26
27 def clean_nodes(inventory):
28     inv_dict = utils.parse_yaml(inventory)
29     if inv_dict is None or 'nodes' not in inv_dict:
30         logging.error("Inventory file is empty or missing nodes definition")
31         sys.exit(1)
32     for node, node_info in inv_dict['nodes'].items():
33         logging.info("Cleaning node: {}".format(node))
34         try:
35             interface = pyipmi.interfaces.create_interface(
36                 'ipmitool', interface_type='lanplus')
37             connection = pyipmi.create_connection(interface)
38             connection.session.set_session_type_rmcp(node_info['ipmi_ip'])
39             connection.target = pyipmi.Target(0x20)
40             connection.session.set_auth_type_user(node_info['ipmi_user'],
41                                                   node_info['ipmi_pass'])
42             connection.session.establish()
43             connection.chassis_control_power_down()
44         except Exception as e:
45             logging.error("Failure while shutting down node {}".format(e))
46             sys.exit(1)
47
48
49 def clean_vbmcs():
50     vbmc_manager = vbmc_lib.VirtualBMCManager()
51     vbmcs = vbmc_manager.list()
52     for vbmc in vbmcs:
53         logging.info("Deleting vbmc: {}".format(vbmc['domain_name']))
54         vbmc_manager.delete(vbmc['domain_name'])
55
56
57 def clean_vms():
58     logging.info('Destroying all Apex VMs')
59     conn = libvirt.open('qemu:///system')
60     if not conn:
61         raise ApexCleanException('Unable to open libvirt connection')
62     pool = conn.storagePoolLookupByName('default')
63     domains = conn.listAllDomains()
64
65     for domain in domains:
66         vm = domain.name()
67         if vm != 'undercloud' and not vm.startswith('baremetal'):
68             continue
69         logging.info("Cleaning domain: {}".format(vm))
70         if domain.isActive():
71             logging.debug('Destroying domain')
72             domain.destroy()
73         domain.undefineFlags(libvirt.VIR_DOMAIN_UNDEFINE_NVRAM)
74         # delete storage volume
75         try:
76             stgvol = pool.storageVolLookupByName("{}.qcow2".format(vm))
77         except libvirt.libvirtError:
78             logging.warning("Skipping volume cleanup as volume not found for "
79                             "vm: {}".format(vm))
80             stgvol = None
81         if stgvol:
82             logging.info('Deleting storage volume')
83             stgvol.wipe(0)
84             stgvol.delete(0)
85     pool.refresh()
86
87
88 def clean_ssh_keys(key_file='/root/.ssh/authorized_keys'):
89     logging.info('Removing any stack pub keys from root authorized keys')
90     if not os.path.isfile(key_file):
91         logging.warning("Key file does not exist: ".format(key_file))
92         return
93     for line in fileinput.input(key_file, inplace=True):
94         line = line.strip('\n')
95         if 'stack@undercloud' not in line:
96             print(line)
97
98
99 def clean_networks():
100     logging.debug('Cleaning all network config')
101     for network in constants.OPNFV_NETWORK_TYPES:
102         logging.info("Cleaning Jump Host Network config for network "
103                      "{}".format(network))
104         jumphost.detach_interface_from_ovs(network)
105         jumphost.remove_ovs_bridge(network)
106
107     conn = libvirt.open('qemu:///system')
108     if not conn:
109         raise ApexCleanException('Unable to open libvirt connection')
110     logging.debug('Destroying all virsh networks')
111     for network in conn.listNetworks():
112         if network in constants.OPNFV_NETWORK_TYPES:
113             virsh_net = conn.networkLookupByName(network)
114             logging.debug("Destroying virsh network: {}".format(network))
115             if virsh_net.isActive():
116                 virsh_net.destroy()
117             try:
118                 virsh_net.undefine()
119             except libvirt.libvirtError as e:
120                 if 'Network not found' in e.get_error_message():
121                     logging.debug('Network already undefined')
122                 else:
123                     raise
124
125
126 def main():
127     clean_parser = argparse.ArgumentParser()
128     clean_parser.add_argument('-i',
129                               dest='inv_file',
130                               required=False,
131                               default=None,
132                               help='File which contains inventory')
133     args = clean_parser.parse_args(sys.argv[1:])
134     os.makedirs(os.path.dirname('./apex_clean.log'), exist_ok=True)
135     formatter = '%(asctime)s %(levelname)s: %(message)s'
136     logging.basicConfig(filename='./apex_clean.log',
137                         format=formatter,
138                         datefmt='%m/%d/%Y %I:%M:%S %p',
139                         level=logging.DEBUG)
140     console = logging.StreamHandler()
141     console.setLevel(logging.DEBUG)
142     console.setFormatter(logging.Formatter(formatter))
143     logging.getLogger('').addHandler(console)
144     if args.inv_file:
145         if not os.path.isfile(args.inv_file):
146             logging.error("Inventory file not found: {}".format(args.inv_file))
147             raise FileNotFoundError("Inventory file does not exist")
148         else:
149             logging.info("Shutting down baremetal nodes")
150             clean_nodes(args.inv_file)
151     # Delete all VMs
152     clean_vms()
153     # Delete vbmc
154     clean_vbmcs()
155     # Clean network config
156     clean_networks()
157
158     # clean pub keys from root's auth keys
159     clean_ssh_keys()
160
161     logging.info('Apex clean complete!')
162
163
164 if __name__ == '__main__':
165     main()