parent
eb23488486
commit
f91e210f1a
121
pvc.py
121
pvc.py
|
@ -354,20 +354,27 @@ def verifyNode(zk_conn, node):
|
|||
click.echo('ERROR: No node named "{}" is present in the cluster.'.format(node))
|
||||
exit(1)
|
||||
|
||||
#
|
||||
# Find a migration target
|
||||
#
|
||||
def findTargetHypervisor(zk_conn, search_field, dom_uuid):
|
||||
if search_field == 'mem':
|
||||
return findTargetHypervisorMem(zk_conn, dom_uuid)
|
||||
if search_field == 'load':
|
||||
return findTargetHypervisorLoad(zk_conn, dom_uuid)
|
||||
if search_field == 'vcpus':
|
||||
return findTargetHypervisorVCPUs(zk_conn, dom_uuid)
|
||||
if search_field == 'vms':
|
||||
return findTargetHypervisorVMs(zk_conn, dom_uuid)
|
||||
return None
|
||||
|
||||
def findTargetHypervisorMem(zk_conn, dom_uuid):
|
||||
# Find a target node
|
||||
most_allocfree = 0
|
||||
target_hypervisor = None
|
||||
|
||||
hypervisor_list = zkhandler.listchildren(zk_conn, '/nodes')
|
||||
# Get the list of valid target hypervisors
|
||||
def getHypervisors(zk_conn, dom_uuid):
|
||||
valid_hypervisor_list = {}
|
||||
full_hypervisor_list = zkhandler.listchildren(zk_conn, '/nodes')
|
||||
current_hypervisor = zkhandler.readdata(zk_conn, '/domains/{}/hypervisor'.format(dom_uuid))
|
||||
|
||||
for hypervisor in hypervisor_list:
|
||||
for hypervisor in full_hypervisor_list:
|
||||
daemon_state = zkhandler.readdata(zk_conn, '/nodes/{}/daemonstate'.format(hypervisor))
|
||||
domain_state = zkhandler.readdata(zk_conn, '/nodes/{}/domainstate'.format(hypervisor))
|
||||
|
||||
|
@ -376,7 +383,18 @@ def findTargetHypervisorMem(zk_conn, dom_uuid):
|
|||
|
||||
if daemon_state != 'run' or domain_state != 'ready':
|
||||
continue
|
||||
|
||||
valid_hypervisor_list.append(hypervisor)
|
||||
|
||||
return full_hypervisor_list
|
||||
|
||||
# via free memory (relative to allocated memory)
|
||||
def findTargetHypervisorMem(zk_conn, dom_uuid):
|
||||
most_allocfree = 0
|
||||
target_hypervisor = None
|
||||
|
||||
hypervisor_list = getHypervisors(zk_conn, dom_uuid)
|
||||
for hypervisor in hypervisor_list:
|
||||
memalloc = int(zkhandler.readdata(zk_conn, '/nodes/{}/memalloc'.format(hypervisor)))
|
||||
memused = int(zkhandler.readdata(zk_conn, '/nodes/{}/memused'.format(hypervisor)))
|
||||
memfree = int(zkhandler.readdata(zk_conn, '/nodes/{}/memfree'.format(hypervisor)))
|
||||
|
@ -389,6 +407,51 @@ def findTargetHypervisorMem(zk_conn, dom_uuid):
|
|||
|
||||
return target_hypervisor
|
||||
|
||||
# via load average
|
||||
def findTargetHypervisorLoad(zk_conn, dom_uuid):
|
||||
least_load = 9999
|
||||
target_hypervisor = None
|
||||
|
||||
hypervisor_list = getHypervisors(zk_conn, dom_uuid)
|
||||
for hypervisor in hypervisor_list:
|
||||
load = int(zkhandler.readdata(zk_conn, '/nodes/{}/load'.format(hypervisor)))
|
||||
|
||||
if load < least_load:
|
||||
least_load = load
|
||||
target_hypevisor = hypervisor
|
||||
|
||||
return target_hypervisor
|
||||
|
||||
# via total vCPUs
|
||||
def findTargetHypervisorVCPUs(zk_conn, dom_uuid):
|
||||
least_vcpus = 9999
|
||||
target_hypervisor = None
|
||||
|
||||
hypervisor_list = getHypervisors(zk_conn, dom_uuid)
|
||||
for hypervisor in hypervisor_list:
|
||||
vcpus = int(zkhandler.readdata(zk_conn, '/nodes/{}/vcpualloc'.format(hypervisor)))
|
||||
|
||||
if vcpus < least_vcpus:
|
||||
least_vcpus = vcpus
|
||||
target_hypervisor = hypervisor
|
||||
|
||||
return target_hypervisor
|
||||
|
||||
# via total VMs
|
||||
def findTargetHypervisorVMs(zk_conn, dom_uuid):
|
||||
least_vms = 9999
|
||||
target_hypervisor = None
|
||||
|
||||
hypervisor_list = getHypervisors(zk_conn, dom_uuid)
|
||||
for hypervisor in hypervisor_list:
|
||||
vms = int(zkhandler.readdata(zk_conn, '/nodes/{}/domainscount'.format(hypervisor)))
|
||||
|
||||
if vms < least_vms:
|
||||
least_vms = vms
|
||||
target_hypervisor = hypervisor
|
||||
|
||||
return target_hypervisor
|
||||
|
||||
|
||||
########################
|
||||
########################
|
||||
|
@ -680,13 +743,18 @@ def vm():
|
|||
###############################################################################
|
||||
@click.command(name='define', short_help='Define a new virtual machine from a Libvirt XML file.')
|
||||
@click.option(
|
||||
'-t', '--hypervisor', 'target_hypervisor', default=myhostname, show_default=True,
|
||||
help='The home hypervisor for this domain.'
|
||||
'-t', '--hypervisor', 'target_hypervisor',
|
||||
help='The home hypervisor for this domain; autoselects if unspecified.'
|
||||
)
|
||||
@click.option(
|
||||
'-s', '--selector', 'selector', default='mem',
|
||||
type=click.Choice(['mem','load','vcpus','vms']),
|
||||
help='Method to determine the optimal target hypervisor automatically.'
|
||||
)
|
||||
@click.argument(
|
||||
'config', type=click.File()
|
||||
)
|
||||
def define_vm(config, target_hypervisor):
|
||||
def define_vm(config, target_hypervisor, selector):
|
||||
"""
|
||||
Define a new virtual machine from Libvirt XML configuration file CONFIG.
|
||||
"""
|
||||
|
@ -704,6 +772,9 @@ def define_vm(config, target_hypervisor):
|
|||
# Open a Zookeeper connection
|
||||
zk_conn = startZKConnection(zk_host)
|
||||
|
||||
if target_hypervisor == None:
|
||||
target_hypervisor = findTargetHypervisor(zk_conn, selector, dom_uuid)
|
||||
|
||||
# Verify node is valid
|
||||
verifyNode(zk_conn, target_hypervisor)
|
||||
|
||||
|
@ -956,7 +1027,12 @@ def stop_vm(domain):
|
|||
'-t', '--hypervisor', 'target_hypervisor', default=None,
|
||||
help='The target hypervisor to migrate to. Autodetect based on most free RAM if unspecified.'
|
||||
)
|
||||
def move_vm(domain, target_hypervisor):
|
||||
@click.option(
|
||||
'-s', '--selector', 'selector', default='mem',
|
||||
type=click.Choice(['mem','load','vcpus','vms']),
|
||||
help='Method to determine the optimal target hypervisor automatically.'
|
||||
)
|
||||
def move_vm(domain, target_hypervisor, selector):
|
||||
"""
|
||||
Permanently move virtual machine DOMAIN, via live migration if running and possible, to another hypervisor node. DOMAIN may be a UUID or name.
|
||||
"""
|
||||
|
@ -980,7 +1056,7 @@ def move_vm(domain, target_hypervisor):
|
|||
current_hypervisor = zk_conn.get('/domains/{}/hypervisor'.format(dom_uuid))[0].decode('ascii')
|
||||
|
||||
if target_hypervisor == None:
|
||||
target_hypervisor = findTargetHypervisor(zk_conn, 'mem', dom_uuid)
|
||||
target_hypervisor = findTargetHypervisor(zk_conn, selector, dom_uuid)
|
||||
else:
|
||||
if target_hypervisor == current_hypervisor:
|
||||
click.echo('ERROR: The VM "{}" is already running on hypervisor "{}".'.format(dom_uuid, current_hypervisor))
|
||||
|
@ -1019,11 +1095,16 @@ def move_vm(domain, target_hypervisor):
|
|||
'-t', '--hypervisor', 'target_hypervisor', default=None,
|
||||
help='The target hypervisor to migrate to. Autodetect based on most free RAM if unspecified.'
|
||||
)
|
||||
@click.option(
|
||||
'-s', '--selector', 'selector', default='mem',
|
||||
type=click.Choice(['mem','load','vcpus','vms']),
|
||||
help='Method to determine the optimal target hypervisor automatically.'
|
||||
)
|
||||
@click.option(
|
||||
'-f', '--force', 'force_migrate', is_flag=True, default=False,
|
||||
help='Force migrate an already migrated VM.'
|
||||
)
|
||||
def migrate_vm(domain, target_hypervisor, force_migrate):
|
||||
def migrate_vm(domain, target_hypervisor, selector, force_migrate):
|
||||
"""
|
||||
Temporarily migrate running virtual machine DOMAIN, via live migration if possible, to another hypervisor node. DOMAIN may be a UUID or name. If DOMAIN is not running, it will be started on the target node.
|
||||
"""
|
||||
|
@ -1062,19 +1143,7 @@ def migrate_vm(domain, target_hypervisor, force_migrate):
|
|||
return
|
||||
|
||||
if target_hypervisor == None:
|
||||
# Determine the best hypervisor to migrate the VM to based on active memory usage
|
||||
hypervisor_list = zk_conn.get_children('/nodes')
|
||||
most_memfree = 0
|
||||
for hypervisor in hypervisor_list:
|
||||
daemon_state = zk_conn.get('/nodes/{}/daemonstate'.format(hypervisor))[0].decode('ascii')
|
||||
domain_state = zk_conn.get('/nodes/{}/domainstate'.format(hypervisor))[0].decode('ascii')
|
||||
if daemon_state != 'run' or domain_state != 'ready' or hypervisor == current_hypervisor:
|
||||
continue
|
||||
|
||||
memfree = int(zk_conn.get('/nodes/{}/memfree'.format(hypervisor))[0].decode('ascii'))
|
||||
if memfree > most_memfree:
|
||||
most_memfree = memfree
|
||||
target_hypervisor = hypervisor
|
||||
target_hypervisor = findTargetHypervisor(zk_conn, selector, dom_uuid)
|
||||
else:
|
||||
if target_hypervisor == current_hypervisor:
|
||||
click.echo('ERROR: The VM "{}" is already running on hypervisor "{}".'.format(dom_uuid, current_hypervisor))
|
||||
|
|
Loading…
Reference in New Issue