Skip to content

Instantly share code, notes, and snippets.

@nbeguier
Created October 10, 2018 15:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nbeguier/47173566e9bfdba9fc5494460f67d5e6 to your computer and use it in GitHub Desktop.
Save nbeguier/47173566e9bfdba9fc5494460f67d5e6 to your computer and use it in GitHub Desktop.
check_scheduling.py
#!/usr/bin/env python3
#-*- coding: utf-8 -*-
""" Check scheduling on nebula for a service """
# Standard library imports
from __future__ import print_function
from sys import argv
# Third party library imports
from pyone import OneServer
def usage():
"""
Display usage
"""
print('Usage: %s ENV VM_PREFIX' % argv[0])
print('')
print('Ex: %s prd service_1' % argv[0])
print('Ex: %s stg service_2' % argv[0])
print('Ex: %s stg all # For all services' % argv[0])
exit(1)
try:
ENV = argv[1]
VM_PREFIX = argv[2]
except IndexError:
usage()
if ENV == 'stg':
ONE = OneServer("http://lb-opennebula.domain.net:2633/RPC2", session="guest:guest")
else:
ONE = OneServer("http://lb-opennebula.staging.domain.net:2633/RPC2", session="guest:guest")
SERVICES_LIST = list()
def generate_services_list():
"""
Generate a list of all VM name
"""
for one_vm in ONE.vmpool.info(-2, -1, -1, -1).VM:
if one_vm.NAME not in SERVICES_LIST:
SERVICES_LIST.append(one_vm.NAME)
class Checker(object):
"""
Main Checker class.
"""
def __init__(self, service_name):
"""
Init file.
"""
self.service_name = service_name
self.vmid_list = list()
self.clusterid_list = list()
self.hostid_list = list()
self.host_dict = dict()
self.full_host_list = list()
self.host_vm_list = list()
def generate_list(self):
"""
Generates a list a VM ID
"""
for one_vm in ONE.vmpool.info(-2, -1, -1, -1).VM:
if one_vm.NAME == self.service_name:
self.vmid_list.append(one_vm.ID)
def check_cluster_ha(self, verbose=True):
"""
Checks if there is HA with the cluster
"""
cluster_dict = dict()
for vmid in self.vmid_list:
try:
cluster_id = ONE.vm.info(vmid).TEMPLATE['NIC']['CLUSTER_ID']
except TypeError:
cluster_id = ONE.vm.info(vmid).TEMPLATE['NIC'][0]['CLUSTER_ID']
if cluster_id in cluster_dict:
cluster_dict[cluster_id] += 1
else:
cluster_dict[cluster_id] = 1
self.clusterid_list.append(int(cluster_id))
cluster_ok = True
for cluster_id in cluster_dict:
if cluster_dict[cluster_id] != len(self.vmid_list) / len(cluster_dict):
cluster_ok = False
if cluster_ok:
cluster_status = 'OK'
else:
cluster_status = 'KO'
if verbose:
print("--------------------")
print("-- CLUSTER : %s --" % cluster_status)
print("--------------------")
print("Number of Cluster : %s" % len(cluster_dict))
if not cluster_ok:
print("Cluster check : ERROR : %s" % cluster_dict)
return cluster_ok
def check_host_ha(self, verbose=True):
"""
Checks if there is HA with the hosts
"""
if verbose:
print("")
print("----------------")
print("-- HOSTS --")
print("----------------")
for vmid in self.vmid_list:
for cluster_id in self.clusterid_list:
for host_id in ONE.cluster.info(cluster_id).HOSTS.ID:
if vmid in ONE.host.info(host_id).VMS.ID:
self.host_vm_list.append((host_id, vmid))
if host_id in self.host_dict:
self.host_dict[host_id] += 1
else:
self.host_dict[host_id] = 1
self.hostid_list.append(int(host_id))
elif host_id not in self.host_dict:
self.host_dict[host_id] = 0
# Detect free hosts
free_hosts = list()
for host_id in self.host_dict:
if self.host_dict[host_id] == 0:
free_hosts.append(host_id)
# Detect full hosts
nb_full_hosts = 0
for host_id in self.host_dict:
if self.host_dict[host_id] > 1:
if verbose:
print("Host %s has %s VM of the same type !" % (host_id, self.host_dict[host_id]))
nb_full_hosts += 1
self.full_host_list.append(host_id)
if nb_full_hosts > 0:
if verbose:
print("Host check : WARNING")
print("These hosts are free : %s" % free_hosts)
return False
if verbose:
print("Host check : OK")
return True
def migrating_host(self):
"""
This function allows to migrate host
"""
print("")
print("--------------------")
print("-- MIGRATION --")
print("--------------------")
old_host_id = int(input("Host to free %s: " % self.full_host_list))
old_host_cluster_id = ONE.host.info(old_host_id).CLUSTER_ID
if self.host_dict[old_host_id] == 0:
print("Host ID %s have no VM %s." % (old_host_id, self.service_name))
return False
elif self.host_dict[old_host_id] < 2:
print("Host ID %s have %s VMs %s." % (old_host_id, self.host_dict[old_host_id], self.service_name))
return False
print("")
print("VMs on this host :")
vcpu = 0
memory = 0
disk = 0
last_vm_id = ''
for host_id, vm_id in self.host_vm_list:
if host_id == old_host_id:
vcpu = int(ONE.vm.info(vm_id).TEMPLATE['VCPU'])
memory = int(ONE.vm.info(vm_id).TEMPLATE['MEMORY'])
try:
disk = int(ONE.vm.info(vm_id).TEMPLATE['DISK']['SIZE'])
except TypeError:
disk = 0
for disk_content in ONE.vm.info(vm_id).TEMPLATE['DISK']:
disk += int(disk_content['SIZE'])
last_vm_id = vm_id
print('{vm_id: %s-%s, vcpu: %s, memory_MB: %s, disk_MB: %s}' % (
self.service_name,
vm_id,
vcpu,
memory,
disk))
# LIST AVAILABLE HOSTS
print("")
print("Candidate :")
at_least_one_host = False
for host_id in self.host_dict:
if self.host_dict[host_id] == 0 and old_host_cluster_id == ONE.host.info(host_id).CLUSTER_ID:
cpu_left = int((ONE.host.info(host_id).HOST_SHARE.MAX_CPU - ONE.host.info(host_id).HOST_SHARE.CPU_USAGE)/100)
memory_left = int((ONE.host.info(host_id).HOST_SHARE.MAX_MEM - ONE.host.info(host_id).HOST_SHARE.MEM_USAGE)/1024)
disk_left = int(ONE.host.info(host_id).HOST_SHARE.FREE_DISK)
if cpu_left >= vcpu and memory_left >= memory and disk_left >= disk:
at_least_one_host = True
print('{host_id: %s, free_cpu: %s, free_memory_MB: %s, free_disk_MB: %s}' % (
host_id,
cpu_left,
memory_left,
disk_left))
if not at_least_one_host:
print("No hosts are available on this cluster...")
return False
else:
print("")
new_host_id = int(input("New host ID for VM ID %s: " % last_vm_id))
print("")
print('Migrating "%s-%s" service from host %s to host %s...' % (
self.service_name,
last_vm_id,
old_host_id,
new_host_id))
# TODO : Migration
# For now, it's just an output.
# We need to implement a login to permit the migration.
return True
if __name__ == '__main__':
if VM_PREFIX != 'all':
CHECK = Checker(VM_PREFIX)
CHECK.generate_list()
CHECK_CLUSTER = CHECK.check_cluster_ha()
CHECK_HOST = CHECK.check_host_ha()
if not CHECK_HOST:
CHECK.migrating_host()
if not CHECK_HOST or not CHECK_CLUSTER:
exit(1)
exit(0)
else:
generate_services_list()
for service in SERVICES_LIST:
CHECK = Checker(service)
CHECK.generate_list()
CHECK_CLUSTER = CHECK.check_cluster_ha(verbose=False)
CHECK_HOST = CHECK.check_host_ha(verbose=False)
if not CHECK_HOST or not CHECK_CLUSTER:
print("Service %s : ERROR" % service)
else:
print("Service %s : OK" % service)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment