blob: 51adbb65aa033c23d6c2a7f65f8955fcdada026e [file] [log] [blame]
Nikolay Pliashechnykov316823e2020-08-14 15:44:50 +01001#!/usr/bin/python
2import json
3def lookup_near(ls, name):
4 for vm in ls:
5 if vm['id'] == name:
6 return vm['id']
7 return False
8def lookup_far(dc, name):
9 result_hvs = []
10 for hv in dc:
11 res = lookup_near(dc[hv], name)
12 if res:
13 result_hvs.append(hv)
14 return result_hvs
15lost_vms = {}
16hypervisors = {}
17hypervisor_pattern = "cmp" #Replace with your own pattern, ensure it's unique so it wouldn't mix up with VM names
18skip_pattern = "------------"
19current_hv = ""
20vm_pattern = "-"
21with open("virsh_vms", "rt") as f:
22 for line in f.readlines():
23 line = line.replace("\n", "")
24 if skip_pattern in line:
25 continue
26 elif hypervisor_pattern in line:
27 current_hv = line.replace(":", "")
28 if current_hv in hypervisors:
29 print("Duplicate hypervisor %s, exiting" % current_hv)
30 break
31 else:
32 hypervisors[current_hv] = []
33 elif vm_pattern in line:
34 if not current_hv:
35 print("Malformed virsh list, exiting")
36 break
37 vm_info_struct = [x for x in line.replace("\n", "").replace("\t"," ").replace("shut off", "shutoff").split(" ") if x]
38 if len(vm_info_struct) == 4:
39 iid, virsh_id, iname, state = vm_info_struct
40 hypervisors[current_hv].append({"id": iid, "state": state})
41 elif len(vm_info_struct) == 3: #No UUID assigned
42 virsh_id, iname, state = vm_info_struct
43 if not lost_vms.has_key(current_hv):
44 lost_vms[current_hv] = [iname + ":" + state]
45 else:
46 lost_vms[current_hv].append(iname + ":" + state)
47nova_out = ""
48nova_vms = {}
49with open("nova_vms", "rt") as f:
50 for line in f.readlines():
51 if "servers" in line:
52 if "RESP BODY" in line:
53 nova_out = line.replace("RESP BODY: ", "").replace("\n", "")
54 nova_vms_json = json.loads(nova_out)
55 for vm in nova_vms_json['servers']:
56 vm_id = vm['id']
57 vm_iname = vm['OS-EXT-SRV-ATTR:instance_name']
58 vm_hv = vm['OS-EXT-SRV-ATTR:hypervisor_hostname']
59 vm_state = vm['OS-EXT-STS:vm_state']
60 if vm_hv not in nova_vms:
61 nova_vms[vm_hv] = []
62 nova_vms[vm_hv].append({"id": vm_id, "name": vm_iname, "state": vm_state})
63rev = {}
64lsdup = []
65for hv in hypervisors:
66 for vm in hypervisors[hv]:
67 if not vm['id'] in rev:
68 rev[vm['id']] = [hv+"(%s)"%vm['state']]
69 else:
70 rev[vm['id']].append(hv+"(%s)"%vm['state'])
71for vm_id in rev:
72 if len(rev[vm_id]) > 1:
73 print "Duplicate VM: %s on %s" % (vm_id, rev[vm_id])
74 lsdup.append(vm_id)
75for hv in hypervisors:
76 if hv not in nova_vms and len(hypervisors[hv]) > 0:
77 #print "WARN: hypervisor %s exists but nova doesn't know that it has following VMs:" % hv
78 for vm in hypervisors[hv]:
79 if not lookup_far(nova_vms, vm["id"]):
80 print "Nova doesn't know that vm %s is running on %s" %(vm["id"], hv)
81 continue
82 for vm in hypervisors[hv]:
83 report = ""
84 if not lookup_near(nova_vms[hv], vm['id']):
85 if vm['id'] in lsdup:
86 continue
87 report += "WARN: VM %s is on hypervisor %s" % (vm['id'], hv)
88 nova_hvs = lookup_far(nova_vms, vm["id"])
89 if nova_hvs:
90 report += ", but nova thinks it is running on %s." % (str(nova_hvs))
91 else:
92 report += ", but nova doesn't know about it."
93 report += " VM state is %s " % vm['state']
94 if report:
95 print(report)
96if lost_vms:
97 print("Lost VMs report (existing in virsh without an UUID and completely untracked in Openstack)")
98for hv in lost_vms:
99 print(hv+":")
100 for vm in lost_vms[hv]:
101 print(vm)