Major usability tweaks to client; use arguments instead of options for the main argument of each command and remove mutual exclusivity options
This commit is contained in:
parent
23f5434159
commit
4881a93758
497
pvc.py
497
pvc.py
|
@ -345,47 +345,6 @@ def searchClusterByName(zk, name):
|
|||
return uuid
|
||||
|
||||
|
||||
#
|
||||
# Allow mutually exclusive options in Click
|
||||
#
|
||||
class MutuallyExclusiveOption(click.Option):
|
||||
def __init__(self, *args, **kwargs):
|
||||
meargs = kwargs.pop('mutually_exclusive', [])
|
||||
_me_arg = []
|
||||
_me_func = []
|
||||
|
||||
for arg in meargs:
|
||||
_me_arg.append(arg['argument'])
|
||||
_me_func.append(arg['function'])
|
||||
|
||||
self.me_arg = set(_me_arg)
|
||||
self.me_func = set(_me_func)
|
||||
|
||||
help = kwargs.get('help', '')
|
||||
if self.me_func:
|
||||
ex_str = ', '.join(self.me_arg)
|
||||
kwargs['help'] = help + (
|
||||
' Mutually exclusive with `' + ex_str + '`.'
|
||||
)
|
||||
|
||||
super(MutuallyExclusiveOption, self).__init__(*args, **kwargs)
|
||||
|
||||
def handle_parse_result(self, ctx, opts, args):
|
||||
if self.me_func.intersection(opts) and self.name in opts:
|
||||
raise click.UsageError(
|
||||
"Illegal usage: `{}` is mutually exclusive with "
|
||||
"arguments `{}`.".format(
|
||||
self.opts[-1],
|
||||
', '.join(self.me_arg)
|
||||
)
|
||||
)
|
||||
|
||||
return super(MutuallyExclusiveOption, self).handle_parse_result(
|
||||
ctx,
|
||||
opts,
|
||||
args
|
||||
)
|
||||
|
||||
########################
|
||||
########################
|
||||
## ##
|
||||
|
@ -414,17 +373,12 @@ def node():
|
|||
# pvc node flush
|
||||
###############################################################################
|
||||
@click.command(name='flush', short_help='Take a node out of service')
|
||||
@click.option(
|
||||
'-n', '--name', 'node_name', default=myhostname, show_default=True,
|
||||
help='The PVC node to operate on.'
|
||||
@click.argument(
|
||||
'node', default=myhostname
|
||||
)
|
||||
def flush_host(node_name):
|
||||
def flush_host(node):
|
||||
"""
|
||||
Take a node out of active service and migrate away all VMs.
|
||||
|
||||
Notes:
|
||||
|
||||
* The '--name' option defaults to the current host if not set, which is likely not what you want when running this command from a remote host!
|
||||
Take NODE out of active service and migrate away all VMs. If unspecified, defaults to this host.
|
||||
"""
|
||||
|
||||
# Open a Zookeeper connection
|
||||
|
@ -432,16 +386,16 @@ def flush_host(node_name):
|
|||
|
||||
# Verify node is valid
|
||||
try:
|
||||
zk.get('/nodes/{}'.format(node_name))
|
||||
zk.get('/nodes/{}'.format(node))
|
||||
except:
|
||||
click.echo('ERROR: No node named {} is present in the cluster.'.format(node_name))
|
||||
click.echo('ERROR: No node named {} is present in the cluster.'.format(node))
|
||||
exit(1)
|
||||
|
||||
click.echo('Flushing hypervisor {} of running VMs.'.format(node_name))
|
||||
click.echo('Flushing hypervisor {} of running VMs.'.format(node))
|
||||
|
||||
# Add the new domain to Zookeeper
|
||||
transaction = zk.transaction()
|
||||
transaction.set_data('/nodes/{}/domainstate'.format(node_name), 'flush'.encode('ascii'))
|
||||
transaction.set_data('/nodes/{}/domainstate'.format(node), 'flush'.encode('ascii'))
|
||||
results = transaction.commit()
|
||||
|
||||
# Close the Zookeeper connection
|
||||
|
@ -452,17 +406,12 @@ def flush_host(node_name):
|
|||
# pvc node ready
|
||||
###############################################################################
|
||||
@click.command(name='ready', short_help='Restore node to service')
|
||||
@click.option(
|
||||
'-n', '--name', 'node_name', default=myhostname, show_default=True,
|
||||
help='The PVC node to operate on.'
|
||||
@click.argument(
|
||||
'node', default=myhostname
|
||||
)
|
||||
def ready_host(node_name):
|
||||
def ready_host(node):
|
||||
"""
|
||||
Restore a host to active service and migrate back all VMs.
|
||||
|
||||
Notes:
|
||||
|
||||
* The '--name' option defaults to the current host if not set, which is likely not what you want when running this command from a remote host!
|
||||
Restore NODE to active service and migrate back all VMs. If unspecified, defaults to this host.
|
||||
"""
|
||||
|
||||
# Open a Zookeeper connection
|
||||
|
@ -470,16 +419,16 @@ def ready_host(node_name):
|
|||
|
||||
# Verify node is valid
|
||||
try:
|
||||
zk.get('/nodes/{}'.format(node_name))
|
||||
zk.get('/nodes/{}'.format(node))
|
||||
except:
|
||||
click.echo('ERROR: No node named {} is present in the cluster.'.format(node_name))
|
||||
click.echo('ERROR: No node named {} is present in the cluster.'.format(node))
|
||||
exit(1)
|
||||
|
||||
click.echo('Restoring hypervisor {} to active service.'.format(node_name))
|
||||
click.echo('Restoring hypervisor {} to active service.'.format(node))
|
||||
|
||||
# Add the new domain to Zookeeper
|
||||
transaction = zk.transaction()
|
||||
transaction.set_data('/nodes/{}/domainstate'.format(node_name), 'unflush'.encode('ascii'))
|
||||
transaction.set_data('/nodes/{}/domainstate'.format(node), 'unflush'.encode('ascii'))
|
||||
results = transaction.commit()
|
||||
|
||||
# Close the Zookeeper connection
|
||||
|
@ -490,17 +439,16 @@ def ready_host(node_name):
|
|||
# pvc node info
|
||||
###############################################################################
|
||||
@click.command(name='info', short_help='Show details of a node object')
|
||||
@click.option(
|
||||
'-n', '--name', 'node_name',
|
||||
help='Search for this name.'
|
||||
@click.argument(
|
||||
'node', default=myhostname
|
||||
)
|
||||
@click.option(
|
||||
'-l', '--long', 'long_output', is_flag=True, default=False,
|
||||
help='Display more detailed information.'
|
||||
)
|
||||
def node_info(node_name, long_output):
|
||||
def node_info(node, long_output):
|
||||
"""
|
||||
Search the cluster for a node's information.
|
||||
Show information about node NODE. If unspecified, defaults to this host.
|
||||
"""
|
||||
|
||||
# Open a Zookeeper connection
|
||||
|
@ -508,16 +456,16 @@ def node_info(node_name, long_output):
|
|||
|
||||
# Verify node is valid
|
||||
try:
|
||||
zk.get('/nodes/{}'.format(node_name))
|
||||
zk.get('/nodes/{}'.format(node))
|
||||
except:
|
||||
click.echo('ERROR: No node named {} is present in the cluster.'.format(node_name))
|
||||
click.echo('ERROR: No node named {} is present in the cluster.'.format(node))
|
||||
exit(1)
|
||||
|
||||
# Get information about node in a pretty format
|
||||
information = getInformationFromNode(zk, node_name, long_output)
|
||||
information = getInformationFromNode(zk, node, long_output)
|
||||
|
||||
if information == None:
|
||||
click.echo('ERROR: Could not find a domain matching that name or UUID.')
|
||||
click.echo('ERROR: Could not find a node matching that name.')
|
||||
return
|
||||
|
||||
click.echo(information)
|
||||
|
@ -527,7 +475,7 @@ def node_info(node_name, long_output):
|
|||
click.echo('{}Virtual machines on node:{}'.format(ansiiprint.bold(), ansiiprint.end()))
|
||||
click.echo('')
|
||||
# List all VMs on this node
|
||||
_vm_list(node_name)
|
||||
get_vm_list(node)
|
||||
|
||||
# Close the Zookeeper connection
|
||||
stopZKConnection(zk)
|
||||
|
@ -669,27 +617,21 @@ def vm():
|
|||
# pvc vm define
|
||||
###############################################################################
|
||||
@click.command(name='define', short_help='Define a new virtual machine from a Libvirt XML file.')
|
||||
@click.option(
|
||||
'-x', '--xml', 'xml_config_file',
|
||||
help='The XML config file to define the domain from.'
|
||||
)
|
||||
@click.option(
|
||||
'-t', '--hypervisor', 'target_hypervisor', default=myhostname, show_default=True,
|
||||
help='The home hypervisor for this domain.'
|
||||
)
|
||||
def define_vm(xml_config_file, target_hypervisor):
|
||||
@click.argument(
|
||||
'config', type=click.File()
|
||||
)
|
||||
def define_vm(config, target_hypervisor):
|
||||
"""
|
||||
Define a new virtual machine from a Libvirt XML configuration file.
|
||||
|
||||
Notes:
|
||||
|
||||
* The '--hypervisor' option defaults to the current host if not set, which is likely not what you want when running this command from a remote host!
|
||||
Define a new virtual machine from Libvirt XML configuration file CONFIG.
|
||||
"""
|
||||
|
||||
# Open the XML file
|
||||
with open(xml_config_file, 'r') as f_domxmlfile:
|
||||
data = f_domxmlfile.read()
|
||||
f_domxmlfile.close()
|
||||
data = config.read()
|
||||
config.close()
|
||||
|
||||
# Parse the XML data
|
||||
parsed_xml = lxml.objectify.fromstring(data)
|
||||
|
@ -717,42 +659,33 @@ def define_vm(xml_config_file, target_hypervisor):
|
|||
# pvc vm undefine
|
||||
###############################################################################
|
||||
@click.command(name='undefine', short_help='Undefine and stop a virtual machine.')
|
||||
@click.option(
|
||||
'-n', '--name', 'dom_name',
|
||||
cls=MutuallyExclusiveOption,
|
||||
mutually_exclusive=[{ 'function': 'dom_uuid', 'argument': '--uuid' }],
|
||||
help='Search for this human-readable name.'
|
||||
@click.argument(
|
||||
'domain'
|
||||
)
|
||||
@click.option(
|
||||
'-u', '--uuid', 'dom_uuid',
|
||||
cls=MutuallyExclusiveOption,
|
||||
mutually_exclusive=[{ 'function': 'dom_name', 'argument': '--name' }],
|
||||
help='Search for this UUID.'
|
||||
)
|
||||
def undefine_vm(dom_name, dom_uuid):
|
||||
def undefine_vm(domain):
|
||||
"""
|
||||
Stop a virtual machine and remove it from the cluster database.
|
||||
Stop virtual machine DOMAIN and remove it from the cluster database. DOMAIN may be a UUID or name.
|
||||
"""
|
||||
|
||||
# Ensure at least one search method is set
|
||||
if dom_name == None and dom_uuid == None:
|
||||
click.echo("ERROR: You must specify either a `--name` or `--uuid` value.")
|
||||
if domain == None:
|
||||
click.echo("ERROR: You must specify either a name or UUID value.")
|
||||
return
|
||||
|
||||
# Open a Zookeeper connection
|
||||
zk = startZKConnection(zk_host)
|
||||
|
||||
# If the --name value was passed, get the UUID
|
||||
if dom_name != None:
|
||||
# Validate and obtain alternate passed value
|
||||
if validateUUID(domain):
|
||||
dom_name = searchClusterByUUID(zk, domain)
|
||||
dom_uuid = searchClusterByName(zk, dom_name)
|
||||
|
||||
# Verify we got a result or abort
|
||||
if not validateUUID(dom_uuid):
|
||||
if dom_name != None:
|
||||
message_name = dom_name
|
||||
else:
|
||||
message_name = dom_uuid
|
||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(message_name))
|
||||
dom_uuid = searchClusterByName(zk, domain)
|
||||
dom_name = searchClusterByUUID(zk, dom_uuid)
|
||||
|
||||
if dom_uuid == None:
|
||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(domain))
|
||||
stopZKConnection(zk)
|
||||
return
|
||||
|
||||
current_vm_state = zk.get('/domains/{}/state'.format(dom_uuid))[0].decode('ascii')
|
||||
|
@ -768,6 +701,7 @@ def undefine_vm(dom_name, dom_uuid):
|
|||
time.sleep(1)
|
||||
|
||||
# Gracefully terminate the class instances
|
||||
click.echo('Deleting VM "{}" from nodes.'.format(dom_uuid))
|
||||
zk.set('/domains/{}/state'.format(dom_uuid), 'delete'.encode('ascii'))
|
||||
time.sleep(5)
|
||||
# Delete the configurations
|
||||
|
@ -788,42 +722,28 @@ def undefine_vm(dom_name, dom_uuid):
|
|||
# pvc vm start
|
||||
###############################################################################
|
||||
@click.command(name='start', short_help='Start up a defined virtual machine.')
|
||||
@click.option(
|
||||
'-n', '--name', 'dom_name',
|
||||
cls=MutuallyExclusiveOption,
|
||||
mutually_exclusive=[{ 'function': 'dom_uuid', 'argument': '--uuid' }],
|
||||
help='Search for this human-readable name.'
|
||||
@click.argument(
|
||||
'domain'
|
||||
)
|
||||
@click.option(
|
||||
'-u', '--uuid', 'dom_uuid',
|
||||
cls=MutuallyExclusiveOption,
|
||||
mutually_exclusive=[{ 'function': 'dom_name', 'argument': '--name' }],
|
||||
help='Search for this UUID.'
|
||||
)
|
||||
def start_vm(dom_name, dom_uuid):
|
||||
def start_vm(domain):
|
||||
"""
|
||||
Start up a virtual machine on its configured hypervisor.
|
||||
Start virtual machine DOMAIN on its configured hypervisor. DOMAIN may be a UUID or name.
|
||||
"""
|
||||
|
||||
# Ensure at least one search method is set
|
||||
if dom_name == None and dom_uuid == None:
|
||||
click.echo("ERROR: You must specify either a `--name` or `--uuid` value.")
|
||||
return
|
||||
|
||||
# Open a Zookeeper connection
|
||||
zk = startZKConnection(zk_host)
|
||||
|
||||
# If the --name value was passed, get the UUID
|
||||
if dom_name != None:
|
||||
# Validate and obtain alternate passed value
|
||||
if validateUUID(domain):
|
||||
dom_name = searchClusterByUUID(zk, domain)
|
||||
dom_uuid = searchClusterByName(zk, dom_name)
|
||||
|
||||
# Verify we got a result or abort
|
||||
if not validateUUID(dom_uuid):
|
||||
if dom_name != None:
|
||||
message_name = dom_name
|
||||
else:
|
||||
message_name = dom_uuid
|
||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(message_name))
|
||||
dom_uuid = searchClusterByName(zk, domain)
|
||||
dom_name = searchClusterByUUID(zk, dom_uuid)
|
||||
|
||||
if dom_uuid == None:
|
||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(domain))
|
||||
stopZKConnection(zk)
|
||||
return
|
||||
|
||||
# Set the VM to start
|
||||
|
@ -838,42 +758,28 @@ def start_vm(dom_name, dom_uuid):
|
|||
# pvc vm restart
|
||||
###############################################################################
|
||||
@click.command(name='restart', short_help='Restart virtual machine.')
|
||||
@click.option(
|
||||
'-n', '--name', 'dom_name',
|
||||
cls=MutuallyExclusiveOption,
|
||||
mutually_exclusive=[{ 'function': 'dom_uuid', 'argument': '--uuid' }],
|
||||
help='Search for this human-readable name.'
|
||||
)
|
||||
@click.option(
|
||||
'-u', '--uuid', 'dom_uuid',
|
||||
cls=MutuallyExclusiveOption,
|
||||
mutually_exclusive=[{ 'function': 'dom_name', 'argument': '--name' }],
|
||||
help='Search for this UUID.'
|
||||
@click.argument(
|
||||
'domain'
|
||||
)
|
||||
def restart_vm(dom_name, dom_uuid):
|
||||
"""
|
||||
Restart a virtual machine on its configured hypervisor.
|
||||
"""
|
||||
|
||||
# Ensure at least one search method is set
|
||||
if dom_name == None and dom_uuid == None:
|
||||
click.echo("ERROR: You must specify either a `--name` or `--uuid` value.")
|
||||
return
|
||||
|
||||
# Open a Zookeeper connection
|
||||
zk = startZKConnection(zk_host)
|
||||
|
||||
# If the --name value was passed, get the UUID
|
||||
if dom_name != None:
|
||||
# Validate and obtain alternate passed value
|
||||
if validateUUID(domain):
|
||||
dom_name = searchClusterByUUID(zk, domain)
|
||||
dom_uuid = searchClusterByName(zk, dom_name)
|
||||
|
||||
# Verify we got a result or abort
|
||||
if not validateUUID(dom_uuid):
|
||||
if dom_name != None:
|
||||
message_name = dom_name
|
||||
else:
|
||||
message_name = dom_uuid
|
||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(message_name))
|
||||
dom_uuid = searchClusterByName(zk, domain)
|
||||
dom_name = searchClusterByUUID(zk, dom_uuid)
|
||||
|
||||
if dom_uuid == None:
|
||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(domain))
|
||||
stopZKConnection(zk)
|
||||
return
|
||||
|
||||
# Get state and verify we're OK to proceed
|
||||
|
@ -894,42 +800,28 @@ def restart_vm(dom_name, dom_uuid):
|
|||
# pvc vm shutdown
|
||||
###############################################################################
|
||||
@click.command(name='shutdown', short_help='Gracefully shut down a running virtual machine.')
|
||||
@click.option(
|
||||
'-n', '--name', 'dom_name',
|
||||
cls=MutuallyExclusiveOption,
|
||||
mutually_exclusive=[{ 'function': 'dom_uuid', 'argument': '--uuid' }],
|
||||
help='Search for this human-readable name.'
|
||||
@click.argument(
|
||||
'domain'
|
||||
)
|
||||
@click.option(
|
||||
'-u', '--uuid', 'dom_uuid',
|
||||
cls=MutuallyExclusiveOption,
|
||||
mutually_exclusive=[{ 'function': 'dom_name', 'argument': '--name' }],
|
||||
help='Search for this UUID.'
|
||||
)
|
||||
def shutdown_vm(dom_name, dom_uuid):
|
||||
def shutdown_vm(domain):
|
||||
"""
|
||||
Gracefully shut down a running virtual machine.
|
||||
Gracefully shut down virtual machine DOMAIN. DOMAIN may be a UUID or name.
|
||||
"""
|
||||
|
||||
# Ensure at least one search method is set
|
||||
if dom_name == None and dom_uuid == None:
|
||||
click.echo("ERROR: You must specify either a `--name` or `--uuid` value.")
|
||||
return
|
||||
|
||||
# Open a Zookeeper connection
|
||||
zk = startZKConnection(zk_host)
|
||||
|
||||
# If the --name value was passed, get the UUID
|
||||
if dom_name != None:
|
||||
# Validate and obtain alternate passed value
|
||||
if validateUUID(domain):
|
||||
dom_name = searchClusterByUUID(zk, domain)
|
||||
dom_uuid = searchClusterByName(zk, dom_name)
|
||||
|
||||
# Verify we got a result or abort
|
||||
if not validateUUID(dom_uuid):
|
||||
if dom_name != None:
|
||||
message_name = dom_name
|
||||
else:
|
||||
message_name = dom_uuid
|
||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(message_name))
|
||||
dom_uuid = searchClusterByName(zk, domain)
|
||||
dom_name = searchClusterByUUID(zk, dom_uuid)
|
||||
|
||||
if dom_uuid == None:
|
||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(domain))
|
||||
stopZKConnection(zk)
|
||||
return
|
||||
|
||||
# Get state and verify we're OK to proceed
|
||||
|
@ -950,42 +842,28 @@ def shutdown_vm(dom_name, dom_uuid):
|
|||
# pvc vm stop
|
||||
###############################################################################
|
||||
@click.command(name='stop', short_help='Forcibly halt a running virtual machine.')
|
||||
@click.option(
|
||||
'-n', '--name', 'dom_name',
|
||||
cls=MutuallyExclusiveOption,
|
||||
mutually_exclusive=[{ 'function': 'dom_uuid', 'argument': '--uuid' }],
|
||||
help='Search for this human-readable name.'
|
||||
@click.argument(
|
||||
'domain'
|
||||
)
|
||||
@click.option(
|
||||
'-u', '--uuid', 'dom_uuid',
|
||||
cls=MutuallyExclusiveOption,
|
||||
mutually_exclusive=[{ 'function': 'dom_name', 'argument': '--name' }],
|
||||
help='Search for this UUID.'
|
||||
)
|
||||
def stop_vm(dom_name, dom_uuid):
|
||||
def stop_vm(domain):
|
||||
"""
|
||||
Forcibly halt (destroy) a running virtual machine.
|
||||
Forcibly halt (destroy) running virtual machine DOMAIN. DOMAIN may be a UUID or name.
|
||||
"""
|
||||
|
||||
# Ensure at least one search method is set
|
||||
if dom_name == None and dom_uuid == None:
|
||||
click.echo("ERROR: You must specify either a `--name` or `--uuid` value.")
|
||||
return
|
||||
|
||||
# Open a Zookeeper connection
|
||||
zk = startZKConnection(zk_host)
|
||||
|
||||
# If the --name value was passed, get the UUID
|
||||
if dom_name != None:
|
||||
# Validate and obtain alternate passed value
|
||||
if validateUUID(domain):
|
||||
dom_name = searchClusterByUUID(zk, domain)
|
||||
dom_uuid = searchClusterByName(zk, dom_name)
|
||||
|
||||
# Verify we got a result or abort
|
||||
if not validateUUID(dom_uuid):
|
||||
if dom_name != None:
|
||||
message_name = dom_name
|
||||
else:
|
||||
message_name = dom_uuid
|
||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(message_name))
|
||||
dom_uuid = searchClusterByName(zk, domain)
|
||||
dom_name = searchClusterByUUID(zk, dom_uuid)
|
||||
|
||||
if dom_uuid == None:
|
||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(domain))
|
||||
stopZKConnection(zk)
|
||||
return
|
||||
|
||||
# Get state and verify we're OK to proceed
|
||||
|
@ -1006,46 +884,32 @@ def stop_vm(dom_name, dom_uuid):
|
|||
# pvc vm move
|
||||
###############################################################################
|
||||
@click.command(name='move', short_help='Permanently move a virtual machine to another node.')
|
||||
@click.option(
|
||||
'-n', '--name', 'dom_name',
|
||||
cls=MutuallyExclusiveOption,
|
||||
mutually_exclusive=[{ 'function': 'dom_uuid', 'argument': '--uuid' }],
|
||||
help='Search for this human-readable name.'
|
||||
@click.argument(
|
||||
'domain'
|
||||
)
|
||||
@click.option(
|
||||
'-u', '--uuid', 'dom_uuid',
|
||||
cls=MutuallyExclusiveOption,
|
||||
mutually_exclusive=[{ 'function': 'dom_name', 'argument': '--name' }],
|
||||
help='Search for this UUID.'
|
||||
'-t', '--hypervisor', 'target_hypervisor', default=None,
|
||||
help='The target hypervisor to migrate to. Autodetect based on most free RAM if unspecified.'
|
||||
)
|
||||
@click.option(
|
||||
'-t', '--target', 'target_hypervisor', default=None,
|
||||
help='The target hypervisor to migrate to.'
|
||||
)
|
||||
def move_vm(dom_name, dom_uuid, target_hypervisor):
|
||||
def move_vm(domain, target_hypervisor):
|
||||
"""
|
||||
Permanently move a virtual machine, via live migration if running and possible, to another hypervisor node.
|
||||
Permanently move virtual machine DOMAIN, via live migration if running and possible, to another hypervisor node. DOMAIN may be a UUID or name.
|
||||
"""
|
||||
|
||||
# Ensure at least one search method is set
|
||||
if dom_name == None and dom_uuid == None:
|
||||
click.echo("ERROR: You must specify either a `--name` or `--uuid` value.")
|
||||
return
|
||||
|
||||
# Open a Zookeeper connection
|
||||
zk = startZKConnection(zk_host)
|
||||
|
||||
# If the --name value was passed, get the UUID
|
||||
if dom_name != None:
|
||||
# Validate and obtain alternate passed value
|
||||
if validateUUID(domain):
|
||||
dom_name = searchClusterByUUID(zk, domain)
|
||||
dom_uuid = searchClusterByName(zk, dom_name)
|
||||
|
||||
# Verify we got a result or abort
|
||||
if not validateUUID(dom_uuid):
|
||||
if dom_name != None:
|
||||
message_name = dom_name
|
||||
else:
|
||||
message_name = dom_uuid
|
||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(message_name))
|
||||
dom_uuid = searchClusterByName(zk, domain)
|
||||
dom_name = searchClusterByUUID(zk, dom_uuid)
|
||||
|
||||
if dom_uuid == None:
|
||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(domain))
|
||||
stopZKConnection(zk)
|
||||
return
|
||||
|
||||
# Get state and verify we're OK to proceed
|
||||
|
@ -1061,8 +925,9 @@ def move_vm(dom_name, dom_uuid, target_hypervisor):
|
|||
hypervisor_list = zk.get_children('/nodes')
|
||||
most_memfree = 0
|
||||
for hypervisor in hypervisor_list:
|
||||
state = zk.get('/nodes/{}/state'.format(hypervisor))[0].decode('ascii')
|
||||
if state != 'start' or hypervisor == current_hypervisor:
|
||||
daemon_state = zk.get('/nodes/{}/daemonstate'.format(hypervisor))[0].decode('ascii')
|
||||
domain_state = zk.get('/nodes/{}/domainstate'.format(hypervisor))[0].decode('ascii')
|
||||
if daemon_state != 'run' or domain_state != 'ready' or hypervisor == current_hypervisor:
|
||||
continue
|
||||
|
||||
memfree = int(zk.get('/nodes/{}/memfree'.format(hypervisor))[0].decode('ascii'))
|
||||
|
@ -1097,50 +962,36 @@ def move_vm(dom_name, dom_uuid, target_hypervisor):
|
|||
# pvc vm migrate
|
||||
###############################################################################
|
||||
@click.command(name='migrate', short_help='Migrate a virtual machine to another node.')
|
||||
@click.option(
|
||||
'-n', '--name', 'dom_name',
|
||||
cls=MutuallyExclusiveOption,
|
||||
mutually_exclusive=[{ 'function': 'dom_uuid', 'argument': '--uuid' }],
|
||||
help='Search for this human-readable name.'
|
||||
@click.argument(
|
||||
'domain'
|
||||
)
|
||||
@click.option(
|
||||
'-u', '--uuid', 'dom_uuid',
|
||||
cls=MutuallyExclusiveOption,
|
||||
mutually_exclusive=[{ 'function': 'dom_name', 'argument': '--name' }],
|
||||
help='Search for this UUID.'
|
||||
)
|
||||
@click.option(
|
||||
'-t', '--target', 'target_hypervisor', default=None,
|
||||
help='The target hypervisor to migrate to.'
|
||||
'-t', '--hypervisor', 'target_hypervisor', default=None,
|
||||
help='The target hypervisor to migrate to. Autodetect based on most free RAM if unspecified.'
|
||||
)
|
||||
@click.option(
|
||||
'-f', '--force', 'force_migrate', is_flag=True, default=False,
|
||||
help='Force migrate an already migrated VM.'
|
||||
)
|
||||
def migrate_vm(dom_name, dom_uuid, target_hypervisor, force_migrate):
|
||||
def migrate_vm(domain, target_hypervisor, force_migrate):
|
||||
"""
|
||||
Migrate a running virtual machine, via live migration if possible, to another hypervisor node.
|
||||
Migrate running virtual machine DOMAIN, via live migration if possible, to another hypervisor node. DOMAIN may be a UUID or name.
|
||||
"""
|
||||
|
||||
# Ensure at least one search method is set
|
||||
if dom_name == None and dom_uuid == None:
|
||||
click.echo("ERROR: You must specify either a `--name` or `--uuid` value.")
|
||||
return
|
||||
|
||||
# Open a Zookeeper connection
|
||||
zk = startZKConnection(zk_host)
|
||||
|
||||
# If the --name value was passed, get the UUID
|
||||
if dom_name != None:
|
||||
# Validate and obtain alternate passed value
|
||||
if validateUUID(domain):
|
||||
dom_name = searchClusterByUUID(zk, domain)
|
||||
dom_uuid = searchClusterByName(zk, dom_name)
|
||||
|
||||
# Verify we got a result or abort
|
||||
if not validateUUID(dom_uuid):
|
||||
if dom_name != None:
|
||||
message_name = dom_name
|
||||
else:
|
||||
message_name = dom_uuid
|
||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(message_name))
|
||||
dom_uuid = searchClusterByName(zk, domain)
|
||||
dom_name = searchClusterByUUID(zk, dom_uuid)
|
||||
|
||||
if dom_uuid == None:
|
||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(domain))
|
||||
stopZKConnection(zk)
|
||||
return
|
||||
|
||||
# Get state and verify we're OK to proceed
|
||||
|
@ -1193,42 +1044,28 @@ def migrate_vm(dom_name, dom_uuid, target_hypervisor, force_migrate):
|
|||
# pvc vm unmigrate
|
||||
###############################################################################
|
||||
@click.command(name='unmigrate', short_help='Restore a migrated virtual machine to its original node.')
|
||||
@click.option(
|
||||
'-n', '--name', 'dom_name',
|
||||
cls=MutuallyExclusiveOption,
|
||||
mutually_exclusive=[{ 'function': 'dom_uuid', 'argument': '--uuid' }],
|
||||
help='Search for this human-readable name.'
|
||||
@click.argument(
|
||||
'domain'
|
||||
)
|
||||
@click.option(
|
||||
'-u', '--uuid', 'dom_uuid',
|
||||
cls=MutuallyExclusiveOption,
|
||||
mutually_exclusive=[{ 'function': 'dom_name', 'argument': '--name' }],
|
||||
help='Search for this UUID.'
|
||||
)
|
||||
def unmigrate_vm(dom_name, dom_uuid):
|
||||
def unmigrate_vm(domain):
|
||||
"""
|
||||
Restore a previously migrated virtual machine, via live migration if possible, to its original hypervisor node.
|
||||
Restore previously migrated virtual machine DOMAIN, via live migration if possible, to its original hypervisor node. DOMAIN may be a UUID or name.
|
||||
"""
|
||||
|
||||
# Ensure at least one search method is set
|
||||
if dom_name == None and dom_uuid == None:
|
||||
click.echo("ERROR: You must specify either a `--name` or `--uuid` value.")
|
||||
return
|
||||
|
||||
# Open a Zookeeper connection
|
||||
zk = startZKConnection(zk_host)
|
||||
|
||||
# If the --name value was passed, get the UUID
|
||||
if dom_name != None:
|
||||
# Validate and obtain alternate passed value
|
||||
if validateUUID(domain):
|
||||
dom_name = searchClusterByUUID(zk, domain)
|
||||
dom_uuid = searchClusterByName(zk, dom_name)
|
||||
|
||||
# Verify we got a result or abort
|
||||
if not validateUUID(dom_uuid):
|
||||
if dom_name != None:
|
||||
message_name = dom_name
|
||||
else:
|
||||
message_name = dom_uuid
|
||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(message_name))
|
||||
dom_uuid = searchClusterByName(zk, domain)
|
||||
dom_name = searchClusterByUUID(zk, dom_uuid)
|
||||
|
||||
if dom_uuid == None:
|
||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(domain))
|
||||
stopZKConnection(zk)
|
||||
return
|
||||
|
||||
# Get state and verify we're OK to proceed
|
||||
|
@ -1258,45 +1095,39 @@ def unmigrate_vm(dom_name, dom_uuid):
|
|||
# pvc vm info
|
||||
###############################################################################
|
||||
@click.command(name='info', short_help='Show details of a VM object')
|
||||
@click.option(
|
||||
'-n', '--name', 'dom_name',
|
||||
cls=MutuallyExclusiveOption,
|
||||
mutually_exclusive=[{ 'function': 'dom_uuid', 'argument': '--uuid' }],
|
||||
help='Search for this human-readable name.'
|
||||
)
|
||||
@click.option(
|
||||
'-u', '--uuid', 'dom_uuid',
|
||||
cls=MutuallyExclusiveOption,
|
||||
mutually_exclusive=[{ 'function': 'dom_name', 'argument': '--name' }],
|
||||
help='Search for this UUID.'
|
||||
@click.argument(
|
||||
'domain'
|
||||
)
|
||||
@click.option(
|
||||
'-l', '--long', 'long_output', is_flag=True, default=False,
|
||||
help='Display more detailed information.'
|
||||
)
|
||||
def vm_info(dom_name, dom_uuid, long_output):
|
||||
def vm_info(domain, long_output):
|
||||
"""
|
||||
Search the cluster for a virtual machine's information.
|
||||
Show information about virtual machine DOMAIN. DOMAIN may be a UUID or name.
|
||||
"""
|
||||
|
||||
# Ensure at least one search method is set
|
||||
if dom_name == None and dom_uuid == None:
|
||||
click.echo("ERROR: You must specify either a `--name` or `--uuid` value.")
|
||||
return
|
||||
|
||||
# Open a Zookeeper connection
|
||||
zk = startZKConnection(zk_host)
|
||||
if dom_name != None:
|
||||
|
||||
# Validate and obtain alternate passed value
|
||||
if validateUUID(domain):
|
||||
dom_name = searchClusterByUUID(zk, domain)
|
||||
dom_uuid = searchClusterByName(zk, dom_name)
|
||||
if dom_uuid != None:
|
||||
else:
|
||||
dom_uuid = searchClusterByName(zk, domain)
|
||||
dom_name = searchClusterByUUID(zk, dom_uuid)
|
||||
|
||||
information = getInformationFromXML(zk, dom_uuid, long_output)
|
||||
|
||||
if information == None:
|
||||
click.echo('ERROR: Could not find a domain matching that name or UUID.')
|
||||
if dom_uuid == None:
|
||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(domain))
|
||||
stopZKConnection(zk)
|
||||
return
|
||||
|
||||
# Gather information from XML config and print it
|
||||
information = getInformationFromXML(zk, dom_uuid, long_output)
|
||||
click.echo(information)
|
||||
|
||||
# Close the Zookeeper connection
|
||||
stopZKConnection(zk)
|
||||
|
||||
|
||||
|
@ -1309,10 +1140,10 @@ def vm_info(dom_name, dom_uuid, long_output):
|
|||
help='Limit list to this hypervisor.'
|
||||
)
|
||||
def vm_list(hypervisor):
|
||||
_vm_list(hypervisor)
|
||||
get_vm_list(hypervisor)
|
||||
|
||||
# Wrapped function to allow calling from `node info`
|
||||
def _vm_list(hypervisor):
|
||||
def get_vm_list(hypervisor):
|
||||
"""
|
||||
List all virtual machines in the cluster.
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue