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
|
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
|
# pvc node flush
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@click.command(name='flush', short_help='Take a node out of service')
|
@click.command(name='flush', short_help='Take a node out of service')
|
||||||
@click.option(
|
@click.argument(
|
||||||
'-n', '--name', 'node_name', default=myhostname, show_default=True,
|
'node', default=myhostname
|
||||||
help='The PVC node to operate on.'
|
|
||||||
)
|
)
|
||||||
def flush_host(node_name):
|
def flush_host(node):
|
||||||
"""
|
"""
|
||||||
Take a node out of active service and migrate away all VMs.
|
Take NODE out of active service and migrate away all VMs. If unspecified, defaults to this host.
|
||||||
|
|
||||||
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!
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Open a Zookeeper connection
|
# Open a Zookeeper connection
|
||||||
|
@ -432,16 +386,16 @@ def flush_host(node_name):
|
||||||
|
|
||||||
# Verify node is valid
|
# Verify node is valid
|
||||||
try:
|
try:
|
||||||
zk.get('/nodes/{}'.format(node_name))
|
zk.get('/nodes/{}'.format(node))
|
||||||
except:
|
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)
|
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
|
# Add the new domain to Zookeeper
|
||||||
transaction = zk.transaction()
|
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()
|
results = transaction.commit()
|
||||||
|
|
||||||
# Close the Zookeeper connection
|
# Close the Zookeeper connection
|
||||||
|
@ -452,17 +406,12 @@ def flush_host(node_name):
|
||||||
# pvc node ready
|
# pvc node ready
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@click.command(name='ready', short_help='Restore node to service')
|
@click.command(name='ready', short_help='Restore node to service')
|
||||||
@click.option(
|
@click.argument(
|
||||||
'-n', '--name', 'node_name', default=myhostname, show_default=True,
|
'node', default=myhostname
|
||||||
help='The PVC node to operate on.'
|
|
||||||
)
|
)
|
||||||
def ready_host(node_name):
|
def ready_host(node):
|
||||||
"""
|
"""
|
||||||
Restore a host to active service and migrate back all VMs.
|
Restore NODE to active service and migrate back all VMs. If unspecified, defaults to this host.
|
||||||
|
|
||||||
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!
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Open a Zookeeper connection
|
# Open a Zookeeper connection
|
||||||
|
@ -470,16 +419,16 @@ def ready_host(node_name):
|
||||||
|
|
||||||
# Verify node is valid
|
# Verify node is valid
|
||||||
try:
|
try:
|
||||||
zk.get('/nodes/{}'.format(node_name))
|
zk.get('/nodes/{}'.format(node))
|
||||||
except:
|
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)
|
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
|
# Add the new domain to Zookeeper
|
||||||
transaction = zk.transaction()
|
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()
|
results = transaction.commit()
|
||||||
|
|
||||||
# Close the Zookeeper connection
|
# Close the Zookeeper connection
|
||||||
|
@ -490,17 +439,16 @@ def ready_host(node_name):
|
||||||
# pvc node info
|
# pvc node info
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@click.command(name='info', short_help='Show details of a node object')
|
@click.command(name='info', short_help='Show details of a node object')
|
||||||
@click.option(
|
@click.argument(
|
||||||
'-n', '--name', 'node_name',
|
'node', default=myhostname
|
||||||
help='Search for this name.'
|
|
||||||
)
|
)
|
||||||
@click.option(
|
@click.option(
|
||||||
'-l', '--long', 'long_output', is_flag=True, default=False,
|
'-l', '--long', 'long_output', is_flag=True, default=False,
|
||||||
help='Display more detailed information.'
|
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
|
# Open a Zookeeper connection
|
||||||
|
@ -508,16 +456,16 @@ def node_info(node_name, long_output):
|
||||||
|
|
||||||
# Verify node is valid
|
# Verify node is valid
|
||||||
try:
|
try:
|
||||||
zk.get('/nodes/{}'.format(node_name))
|
zk.get('/nodes/{}'.format(node))
|
||||||
except:
|
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)
|
exit(1)
|
||||||
|
|
||||||
# Get information about node in a pretty format
|
# Get information about node in a pretty format
|
||||||
information = getInformationFromNode(zk, node_name, long_output)
|
information = getInformationFromNode(zk, node, long_output)
|
||||||
|
|
||||||
if information == None:
|
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
|
return
|
||||||
|
|
||||||
click.echo(information)
|
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('{}Virtual machines on node:{}'.format(ansiiprint.bold(), ansiiprint.end()))
|
||||||
click.echo('')
|
click.echo('')
|
||||||
# List all VMs on this node
|
# List all VMs on this node
|
||||||
_vm_list(node_name)
|
get_vm_list(node)
|
||||||
|
|
||||||
# Close the Zookeeper connection
|
# Close the Zookeeper connection
|
||||||
stopZKConnection(zk)
|
stopZKConnection(zk)
|
||||||
|
@ -669,27 +617,21 @@ def vm():
|
||||||
# pvc vm define
|
# pvc vm define
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@click.command(name='define', short_help='Define a new virtual machine from a Libvirt XML file.')
|
@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(
|
@click.option(
|
||||||
'-t', '--hypervisor', 'target_hypervisor', default=myhostname, show_default=True,
|
'-t', '--hypervisor', 'target_hypervisor', default=myhostname, show_default=True,
|
||||||
help='The home hypervisor for this domain.'
|
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.
|
Define a new virtual machine from Libvirt XML configuration file CONFIG.
|
||||||
|
|
||||||
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!
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Open the XML file
|
# Open the XML file
|
||||||
with open(xml_config_file, 'r') as f_domxmlfile:
|
data = config.read()
|
||||||
data = f_domxmlfile.read()
|
config.close()
|
||||||
f_domxmlfile.close()
|
|
||||||
|
|
||||||
# Parse the XML data
|
# Parse the XML data
|
||||||
parsed_xml = lxml.objectify.fromstring(data)
|
parsed_xml = lxml.objectify.fromstring(data)
|
||||||
|
@ -717,42 +659,33 @@ def define_vm(xml_config_file, target_hypervisor):
|
||||||
# pvc vm undefine
|
# pvc vm undefine
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@click.command(name='undefine', short_help='Undefine and stop a virtual machine.')
|
@click.command(name='undefine', short_help='Undefine and stop a virtual machine.')
|
||||||
@click.option(
|
@click.argument(
|
||||||
'-n', '--name', 'dom_name',
|
'domain'
|
||||||
cls=MutuallyExclusiveOption,
|
|
||||||
mutually_exclusive=[{ 'function': 'dom_uuid', 'argument': '--uuid' }],
|
|
||||||
help='Search for this human-readable name.'
|
|
||||||
)
|
)
|
||||||
@click.option(
|
def undefine_vm(domain):
|
||||||
'-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):
|
|
||||||
"""
|
"""
|
||||||
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
|
# Ensure at least one search method is set
|
||||||
if dom_name == None and dom_uuid == None:
|
if domain == None:
|
||||||
click.echo("ERROR: You must specify either a `--name` or `--uuid` value.")
|
click.echo("ERROR: You must specify either a name or UUID value.")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Open a Zookeeper connection
|
# Open a Zookeeper connection
|
||||||
zk = startZKConnection(zk_host)
|
zk = startZKConnection(zk_host)
|
||||||
|
|
||||||
# If the --name value was passed, get the UUID
|
# Validate and obtain alternate passed value
|
||||||
if dom_name != None:
|
if validateUUID(domain):
|
||||||
|
dom_name = searchClusterByUUID(zk, domain)
|
||||||
dom_uuid = searchClusterByName(zk, dom_name)
|
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:
|
else:
|
||||||
message_name = dom_uuid
|
dom_uuid = searchClusterByName(zk, domain)
|
||||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(message_name))
|
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
|
return
|
||||||
|
|
||||||
current_vm_state = zk.get('/domains/{}/state'.format(dom_uuid))[0].decode('ascii')
|
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)
|
time.sleep(1)
|
||||||
|
|
||||||
# Gracefully terminate the class instances
|
# Gracefully terminate the class instances
|
||||||
|
click.echo('Deleting VM "{}" from nodes.'.format(dom_uuid))
|
||||||
zk.set('/domains/{}/state'.format(dom_uuid), 'delete'.encode('ascii'))
|
zk.set('/domains/{}/state'.format(dom_uuid), 'delete'.encode('ascii'))
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
# Delete the configurations
|
# Delete the configurations
|
||||||
|
@ -788,42 +722,28 @@ def undefine_vm(dom_name, dom_uuid):
|
||||||
# pvc vm start
|
# pvc vm start
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@click.command(name='start', short_help='Start up a defined virtual machine.')
|
@click.command(name='start', short_help='Start up a defined virtual machine.')
|
||||||
@click.option(
|
@click.argument(
|
||||||
'-n', '--name', 'dom_name',
|
'domain'
|
||||||
cls=MutuallyExclusiveOption,
|
|
||||||
mutually_exclusive=[{ 'function': 'dom_uuid', 'argument': '--uuid' }],
|
|
||||||
help='Search for this human-readable name.'
|
|
||||||
)
|
)
|
||||||
@click.option(
|
def start_vm(domain):
|
||||||
'-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):
|
|
||||||
"""
|
"""
|
||||||
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
|
# Open a Zookeeper connection
|
||||||
zk = startZKConnection(zk_host)
|
zk = startZKConnection(zk_host)
|
||||||
|
|
||||||
# If the --name value was passed, get the UUID
|
# Validate and obtain alternate passed value
|
||||||
if dom_name != None:
|
if validateUUID(domain):
|
||||||
|
dom_name = searchClusterByUUID(zk, domain)
|
||||||
dom_uuid = searchClusterByName(zk, dom_name)
|
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:
|
else:
|
||||||
message_name = dom_uuid
|
dom_uuid = searchClusterByName(zk, domain)
|
||||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(message_name))
|
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
|
return
|
||||||
|
|
||||||
# Set the VM to start
|
# Set the VM to start
|
||||||
|
@ -838,42 +758,28 @@ def start_vm(dom_name, dom_uuid):
|
||||||
# pvc vm restart
|
# pvc vm restart
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@click.command(name='restart', short_help='Restart virtual machine.')
|
@click.command(name='restart', short_help='Restart virtual machine.')
|
||||||
@click.option(
|
@click.argument(
|
||||||
'-n', '--name', 'dom_name',
|
'domain'
|
||||||
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.'
|
|
||||||
)
|
)
|
||||||
def restart_vm(dom_name, dom_uuid):
|
def restart_vm(dom_name, dom_uuid):
|
||||||
"""
|
"""
|
||||||
Restart a virtual machine on its configured hypervisor.
|
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
|
# Open a Zookeeper connection
|
||||||
zk = startZKConnection(zk_host)
|
zk = startZKConnection(zk_host)
|
||||||
|
|
||||||
# If the --name value was passed, get the UUID
|
# Validate and obtain alternate passed value
|
||||||
if dom_name != None:
|
if validateUUID(domain):
|
||||||
|
dom_name = searchClusterByUUID(zk, domain)
|
||||||
dom_uuid = searchClusterByName(zk, dom_name)
|
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:
|
else:
|
||||||
message_name = dom_uuid
|
dom_uuid = searchClusterByName(zk, domain)
|
||||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(message_name))
|
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
|
return
|
||||||
|
|
||||||
# Get state and verify we're OK to proceed
|
# Get state and verify we're OK to proceed
|
||||||
|
@ -894,42 +800,28 @@ def restart_vm(dom_name, dom_uuid):
|
||||||
# pvc vm shutdown
|
# pvc vm shutdown
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@click.command(name='shutdown', short_help='Gracefully shut down a running virtual machine.')
|
@click.command(name='shutdown', short_help='Gracefully shut down a running virtual machine.')
|
||||||
@click.option(
|
@click.argument(
|
||||||
'-n', '--name', 'dom_name',
|
'domain'
|
||||||
cls=MutuallyExclusiveOption,
|
|
||||||
mutually_exclusive=[{ 'function': 'dom_uuid', 'argument': '--uuid' }],
|
|
||||||
help='Search for this human-readable name.'
|
|
||||||
)
|
)
|
||||||
@click.option(
|
def shutdown_vm(domain):
|
||||||
'-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):
|
|
||||||
"""
|
"""
|
||||||
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
|
# Open a Zookeeper connection
|
||||||
zk = startZKConnection(zk_host)
|
zk = startZKConnection(zk_host)
|
||||||
|
|
||||||
# If the --name value was passed, get the UUID
|
# Validate and obtain alternate passed value
|
||||||
if dom_name != None:
|
if validateUUID(domain):
|
||||||
|
dom_name = searchClusterByUUID(zk, domain)
|
||||||
dom_uuid = searchClusterByName(zk, dom_name)
|
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:
|
else:
|
||||||
message_name = dom_uuid
|
dom_uuid = searchClusterByName(zk, domain)
|
||||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(message_name))
|
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
|
return
|
||||||
|
|
||||||
# Get state and verify we're OK to proceed
|
# Get state and verify we're OK to proceed
|
||||||
|
@ -950,42 +842,28 @@ def shutdown_vm(dom_name, dom_uuid):
|
||||||
# pvc vm stop
|
# pvc vm stop
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@click.command(name='stop', short_help='Forcibly halt a running virtual machine.')
|
@click.command(name='stop', short_help='Forcibly halt a running virtual machine.')
|
||||||
@click.option(
|
@click.argument(
|
||||||
'-n', '--name', 'dom_name',
|
'domain'
|
||||||
cls=MutuallyExclusiveOption,
|
|
||||||
mutually_exclusive=[{ 'function': 'dom_uuid', 'argument': '--uuid' }],
|
|
||||||
help='Search for this human-readable name.'
|
|
||||||
)
|
)
|
||||||
@click.option(
|
def stop_vm(domain):
|
||||||
'-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):
|
|
||||||
"""
|
"""
|
||||||
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
|
# Open a Zookeeper connection
|
||||||
zk = startZKConnection(zk_host)
|
zk = startZKConnection(zk_host)
|
||||||
|
|
||||||
# If the --name value was passed, get the UUID
|
# Validate and obtain alternate passed value
|
||||||
if dom_name != None:
|
if validateUUID(domain):
|
||||||
|
dom_name = searchClusterByUUID(zk, domain)
|
||||||
dom_uuid = searchClusterByName(zk, dom_name)
|
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:
|
else:
|
||||||
message_name = dom_uuid
|
dom_uuid = searchClusterByName(zk, domain)
|
||||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(message_name))
|
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
|
return
|
||||||
|
|
||||||
# Get state and verify we're OK to proceed
|
# Get state and verify we're OK to proceed
|
||||||
|
@ -1006,46 +884,32 @@ def stop_vm(dom_name, dom_uuid):
|
||||||
# pvc vm move
|
# pvc vm move
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@click.command(name='move', short_help='Permanently move a virtual machine to another node.')
|
@click.command(name='move', short_help='Permanently move a virtual machine to another node.')
|
||||||
@click.option(
|
@click.argument(
|
||||||
'-n', '--name', 'dom_name',
|
'domain'
|
||||||
cls=MutuallyExclusiveOption,
|
|
||||||
mutually_exclusive=[{ 'function': 'dom_uuid', 'argument': '--uuid' }],
|
|
||||||
help='Search for this human-readable name.'
|
|
||||||
)
|
)
|
||||||
@click.option(
|
@click.option(
|
||||||
'-u', '--uuid', 'dom_uuid',
|
'-t', '--hypervisor', 'target_hypervisor', default=None,
|
||||||
cls=MutuallyExclusiveOption,
|
help='The target hypervisor to migrate to. Autodetect based on most free RAM if unspecified.'
|
||||||
mutually_exclusive=[{ 'function': 'dom_name', 'argument': '--name' }],
|
|
||||||
help='Search for this UUID.'
|
|
||||||
)
|
)
|
||||||
@click.option(
|
def move_vm(domain, target_hypervisor):
|
||||||
'-t', '--target', 'target_hypervisor', default=None,
|
|
||||||
help='The target hypervisor to migrate to.'
|
|
||||||
)
|
|
||||||
def move_vm(dom_name, dom_uuid, 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
|
# Open a Zookeeper connection
|
||||||
zk = startZKConnection(zk_host)
|
zk = startZKConnection(zk_host)
|
||||||
|
|
||||||
# If the --name value was passed, get the UUID
|
# Validate and obtain alternate passed value
|
||||||
if dom_name != None:
|
if validateUUID(domain):
|
||||||
|
dom_name = searchClusterByUUID(zk, domain)
|
||||||
dom_uuid = searchClusterByName(zk, dom_name)
|
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:
|
else:
|
||||||
message_name = dom_uuid
|
dom_uuid = searchClusterByName(zk, domain)
|
||||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(message_name))
|
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
|
return
|
||||||
|
|
||||||
# Get state and verify we're OK to proceed
|
# 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')
|
hypervisor_list = zk.get_children('/nodes')
|
||||||
most_memfree = 0
|
most_memfree = 0
|
||||||
for hypervisor in hypervisor_list:
|
for hypervisor in hypervisor_list:
|
||||||
state = zk.get('/nodes/{}/state'.format(hypervisor))[0].decode('ascii')
|
daemon_state = zk.get('/nodes/{}/daemonstate'.format(hypervisor))[0].decode('ascii')
|
||||||
if state != 'start' or hypervisor == current_hypervisor:
|
domain_state = zk.get('/nodes/{}/domainstate'.format(hypervisor))[0].decode('ascii')
|
||||||
|
if daemon_state != 'run' or domain_state != 'ready' or hypervisor == current_hypervisor:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
memfree = int(zk.get('/nodes/{}/memfree'.format(hypervisor))[0].decode('ascii'))
|
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
|
# pvc vm migrate
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@click.command(name='migrate', short_help='Migrate a virtual machine to another node.')
|
@click.command(name='migrate', short_help='Migrate a virtual machine to another node.')
|
||||||
@click.option(
|
@click.argument(
|
||||||
'-n', '--name', 'dom_name',
|
'domain'
|
||||||
cls=MutuallyExclusiveOption,
|
|
||||||
mutually_exclusive=[{ 'function': 'dom_uuid', 'argument': '--uuid' }],
|
|
||||||
help='Search for this human-readable name.'
|
|
||||||
)
|
)
|
||||||
@click.option(
|
@click.option(
|
||||||
'-u', '--uuid', 'dom_uuid',
|
'-t', '--hypervisor', 'target_hypervisor', default=None,
|
||||||
cls=MutuallyExclusiveOption,
|
help='The target hypervisor to migrate to. Autodetect based on most free RAM if unspecified.'
|
||||||
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.'
|
|
||||||
)
|
)
|
||||||
@click.option(
|
@click.option(
|
||||||
'-f', '--force', 'force_migrate', is_flag=True, default=False,
|
'-f', '--force', 'force_migrate', is_flag=True, default=False,
|
||||||
help='Force migrate an already migrated VM.'
|
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
|
# Open a Zookeeper connection
|
||||||
zk = startZKConnection(zk_host)
|
zk = startZKConnection(zk_host)
|
||||||
|
|
||||||
# If the --name value was passed, get the UUID
|
# Validate and obtain alternate passed value
|
||||||
if dom_name != None:
|
if validateUUID(domain):
|
||||||
|
dom_name = searchClusterByUUID(zk, domain)
|
||||||
dom_uuid = searchClusterByName(zk, dom_name)
|
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:
|
else:
|
||||||
message_name = dom_uuid
|
dom_uuid = searchClusterByName(zk, domain)
|
||||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(message_name))
|
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
|
return
|
||||||
|
|
||||||
# Get state and verify we're OK to proceed
|
# 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
|
# pvc vm unmigrate
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@click.command(name='unmigrate', short_help='Restore a migrated virtual machine to its original node.')
|
@click.command(name='unmigrate', short_help='Restore a migrated virtual machine to its original node.')
|
||||||
@click.option(
|
@click.argument(
|
||||||
'-n', '--name', 'dom_name',
|
'domain'
|
||||||
cls=MutuallyExclusiveOption,
|
|
||||||
mutually_exclusive=[{ 'function': 'dom_uuid', 'argument': '--uuid' }],
|
|
||||||
help='Search for this human-readable name.'
|
|
||||||
)
|
)
|
||||||
@click.option(
|
def unmigrate_vm(domain):
|
||||||
'-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):
|
|
||||||
"""
|
"""
|
||||||
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
|
# Open a Zookeeper connection
|
||||||
zk = startZKConnection(zk_host)
|
zk = startZKConnection(zk_host)
|
||||||
|
|
||||||
# If the --name value was passed, get the UUID
|
# Validate and obtain alternate passed value
|
||||||
if dom_name != None:
|
if validateUUID(domain):
|
||||||
|
dom_name = searchClusterByUUID(zk, domain)
|
||||||
dom_uuid = searchClusterByName(zk, dom_name)
|
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:
|
else:
|
||||||
message_name = dom_uuid
|
dom_uuid = searchClusterByName(zk, domain)
|
||||||
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(message_name))
|
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
|
return
|
||||||
|
|
||||||
# Get state and verify we're OK to proceed
|
# Get state and verify we're OK to proceed
|
||||||
|
@ -1258,45 +1095,39 @@ def unmigrate_vm(dom_name, dom_uuid):
|
||||||
# pvc vm info
|
# pvc vm info
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@click.command(name='info', short_help='Show details of a VM object')
|
@click.command(name='info', short_help='Show details of a VM object')
|
||||||
@click.option(
|
@click.argument(
|
||||||
'-n', '--name', 'dom_name',
|
'domain'
|
||||||
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.option(
|
@click.option(
|
||||||
'-l', '--long', 'long_output', is_flag=True, default=False,
|
'-l', '--long', 'long_output', is_flag=True, default=False,
|
||||||
help='Display more detailed information.'
|
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
|
# Open a Zookeeper connection
|
||||||
if dom_name == None and dom_uuid == None:
|
|
||||||
click.echo("ERROR: You must specify either a `--name` or `--uuid` value.")
|
|
||||||
return
|
|
||||||
|
|
||||||
zk = startZKConnection(zk_host)
|
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)
|
dom_uuid = searchClusterByName(zk, dom_name)
|
||||||
if dom_uuid != None:
|
else:
|
||||||
|
dom_uuid = searchClusterByName(zk, domain)
|
||||||
dom_name = searchClusterByUUID(zk, dom_uuid)
|
dom_name = searchClusterByUUID(zk, dom_uuid)
|
||||||
|
|
||||||
information = getInformationFromXML(zk, dom_uuid, long_output)
|
if dom_uuid == None:
|
||||||
|
click.echo('ERROR: Could not find VM "{}" in the cluster!'.format(domain))
|
||||||
if information == None:
|
stopZKConnection(zk)
|
||||||
click.echo('ERROR: Could not find a domain matching that name or UUID.')
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Gather information from XML config and print it
|
||||||
|
information = getInformationFromXML(zk, dom_uuid, long_output)
|
||||||
click.echo(information)
|
click.echo(information)
|
||||||
|
|
||||||
|
# Close the Zookeeper connection
|
||||||
stopZKConnection(zk)
|
stopZKConnection(zk)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1309,10 +1140,10 @@ def vm_info(dom_name, dom_uuid, long_output):
|
||||||
help='Limit list to this hypervisor.'
|
help='Limit list to this hypervisor.'
|
||||||
)
|
)
|
||||||
def vm_list(hypervisor):
|
def vm_list(hypervisor):
|
||||||
_vm_list(hypervisor)
|
get_vm_list(hypervisor)
|
||||||
|
|
||||||
# Wrapped function to allow calling from `node info`
|
# Wrapped function to allow calling from `node info`
|
||||||
def _vm_list(hypervisor):
|
def get_vm_list(hypervisor):
|
||||||
"""
|
"""
|
||||||
List all virtual machines in the cluster.
|
List all virtual machines in the cluster.
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue