| #!/usr/bin/python |
| import json |
| def lookup_near(ls, name): |
| for vm in ls: |
| if vm['id'] == name: |
| return vm['id'] |
| return False |
| def lookup_far(dc, name): |
| result_hvs = [] |
| for hv in dc: |
| res = lookup_near(dc[hv], name) |
| if res: |
| result_hvs.append(hv) |
| return result_hvs |
| lost_vms = {} |
| hypervisors = {} |
| hypervisor_pattern = "cmp" #Replace with your own pattern, ensure it's unique so it wouldn't mix up with VM names |
| skip_pattern = "------------" |
| current_hv = "" |
| vm_pattern = "-" |
| with open("virsh_vms", "rt") as f: |
| for line in f.readlines(): |
| line = line.replace("\n", "") |
| if skip_pattern in line: |
| continue |
| elif hypervisor_pattern in line: |
| current_hv = line.replace(":", "") |
| if current_hv in hypervisors: |
| print("Duplicate hypervisor %s, exiting" % current_hv) |
| break |
| else: |
| hypervisors[current_hv] = [] |
| elif vm_pattern in line: |
| if not current_hv: |
| print("Malformed virsh list, exiting") |
| break |
| vm_info_struct = [x for x in line.replace("\n", "").replace("\t"," ").replace("shut off", "shutoff").split(" ") if x] |
| if len(vm_info_struct) == 4: |
| iid, virsh_id, iname, state = vm_info_struct |
| hypervisors[current_hv].append({"id": iid, "state": state}) |
| elif len(vm_info_struct) == 3: #No UUID assigned |
| virsh_id, iname, state = vm_info_struct |
| if not lost_vms.has_key(current_hv): |
| lost_vms[current_hv] = [iname + ":" + state] |
| else: |
| lost_vms[current_hv].append(iname + ":" + state) |
| nova_out = "" |
| nova_vms = {} |
| with open("nova_vms", "rt") as f: |
| for line in f.readlines(): |
| if "servers" in line: |
| if "RESP BODY" in line: |
| nova_out = line.replace("RESP BODY: ", "").replace("\n", "") |
| nova_vms_json = json.loads(nova_out) |
| for vm in nova_vms_json['servers']: |
| vm_id = vm['id'] |
| vm_iname = vm['OS-EXT-SRV-ATTR:instance_name'] |
| vm_hv = vm['OS-EXT-SRV-ATTR:hypervisor_hostname'] |
| vm_state = vm['OS-EXT-STS:vm_state'] |
| if vm_hv not in nova_vms: |
| nova_vms[vm_hv] = [] |
| nova_vms[vm_hv].append({"id": vm_id, "name": vm_iname, "state": vm_state}) |
| rev = {} |
| lsdup = [] |
| for hv in hypervisors: |
| for vm in hypervisors[hv]: |
| if not vm['id'] in rev: |
| rev[vm['id']] = [hv+"(%s)"%vm['state']] |
| else: |
| rev[vm['id']].append(hv+"(%s)"%vm['state']) |
| for vm_id in rev: |
| if len(rev[vm_id]) > 1: |
| print "Duplicate VM: %s on %s" % (vm_id, rev[vm_id]) |
| lsdup.append(vm_id) |
| for hv in hypervisors: |
| if hv not in nova_vms and len(hypervisors[hv]) > 0: |
| #print "WARN: hypervisor %s exists but nova doesn't know that it has following VMs:" % hv |
| for vm in hypervisors[hv]: |
| if not lookup_far(nova_vms, vm["id"]): |
| print "Nova doesn't know that vm %s is running on %s" %(vm["id"], hv) |
| continue |
| for vm in hypervisors[hv]: |
| report = "" |
| if not lookup_near(nova_vms[hv], vm['id']): |
| if vm['id'] in lsdup: |
| continue |
| report += "WARN: VM %s is on hypervisor %s" % (vm['id'], hv) |
| nova_hvs = lookup_far(nova_vms, vm["id"]) |
| if nova_hvs: |
| report += ", but nova thinks it is running on %s." % (str(nova_hvs)) |
| else: |
| report += ", but nova doesn't know about it." |
| report += " VM state is %s " % vm['state'] |
| if report: |
| print(report) |
| if lost_vms: |
| print("Lost VMs report (existing in virsh without an UUID and completely untracked in Openstack)") |
| for hv in lost_vms: |
| print(hv+":") |
| for vm in lost_vms[hv]: |
| print(vm) |