Implement vCPU modification on the CLI
Adds functions for listing and setting the vCPU and topology values from the CLI, without editing the XML directly. References #101
This commit is contained in:
parent
5f5f4dd421
commit
03d4be79b7
|
@ -254,6 +254,133 @@ def vm_locks(config, vm):
|
||||||
return retstatus, response.json().get('message', '')
|
return retstatus, response.json().get('message', '')
|
||||||
|
|
||||||
|
|
||||||
|
def vm_vcpus_set(config, vm, vcpus, topology, restart):
|
||||||
|
"""
|
||||||
|
Set the vCPU count of the VM with topology
|
||||||
|
|
||||||
|
Calls vm_info to get the VM XML.
|
||||||
|
|
||||||
|
Calls vm_modify to set the VM XML.
|
||||||
|
"""
|
||||||
|
from lxml.objectify import fromstring
|
||||||
|
from lxml.etree import tostring
|
||||||
|
|
||||||
|
status, domain_information = vm_info(config, vm)
|
||||||
|
if not status:
|
||||||
|
return status, domain_information
|
||||||
|
|
||||||
|
xml = domain_information.get('xml', None)
|
||||||
|
if xml is None:
|
||||||
|
return False, "VM does not have a valid XML doccument."
|
||||||
|
|
||||||
|
try:
|
||||||
|
parsed_xml = fromstring(xml)
|
||||||
|
except Exception:
|
||||||
|
return False, 'ERROR: Failed to parse XML data.'
|
||||||
|
|
||||||
|
parsed_xml.vcpu._setText(str(vcpus))
|
||||||
|
parsed_xml.cpu.topology.set('sockets', str(topology[0]))
|
||||||
|
parsed_xml.cpu.topology.set('cores', str(topology[1]))
|
||||||
|
parsed_xml.cpu.topology.set('threads', str(topology[2]))
|
||||||
|
|
||||||
|
try:
|
||||||
|
new_xml = tostring(parsed_xml, pretty_print=True)
|
||||||
|
except Exception:
|
||||||
|
return False, 'ERROR: Failed to dump XML data.'
|
||||||
|
|
||||||
|
return vm_modify(config, vm, new_xml, restart)
|
||||||
|
|
||||||
|
|
||||||
|
def vm_vcpus_get(config, vm):
|
||||||
|
"""
|
||||||
|
Get the vCPU count of the VM
|
||||||
|
|
||||||
|
Calls vm_info to get VM XML.
|
||||||
|
|
||||||
|
Returns a tuple of (vcpus, (sockets, cores, threads))
|
||||||
|
"""
|
||||||
|
from lxml.objectify import fromstring
|
||||||
|
|
||||||
|
status, domain_information = vm_info(config, vm)
|
||||||
|
if not status:
|
||||||
|
return status, domain_information
|
||||||
|
|
||||||
|
xml = domain_information.get('xml', None)
|
||||||
|
if xml is None:
|
||||||
|
return False, "VM does not have a valid XML doccument."
|
||||||
|
|
||||||
|
try:
|
||||||
|
parsed_xml = fromstring(xml)
|
||||||
|
except Exception:
|
||||||
|
return False, 'ERROR: Failed to parse XML data.'
|
||||||
|
|
||||||
|
vm_vcpus = int(parsed_xml.vcpu.text)
|
||||||
|
vm_sockets = parsed_xml.cpu.topology.attrib.get('sockets')
|
||||||
|
vm_cores = parsed_xml.cpu.topology.attrib.get('cores')
|
||||||
|
vm_threads = parsed_xml.cpu.topology.attrib.get('threads')
|
||||||
|
|
||||||
|
return True, (vm_vcpus, (vm_sockets, vm_cores, vm_threads))
|
||||||
|
|
||||||
|
|
||||||
|
def format_vm_vcpus(config, name, vcpus):
|
||||||
|
"""
|
||||||
|
Format the output of a vCPU value in a nice table
|
||||||
|
"""
|
||||||
|
output_list = []
|
||||||
|
|
||||||
|
name_length = 5
|
||||||
|
_name_length = len(name) + 1
|
||||||
|
if _name_length > name_length:
|
||||||
|
name_length = _name_length
|
||||||
|
|
||||||
|
vcpus_length = 6
|
||||||
|
sockets_length = 8
|
||||||
|
cores_length = 6
|
||||||
|
threads_length = 8
|
||||||
|
|
||||||
|
output_list.append(
|
||||||
|
'{bold}{name: <{name_length}} \
|
||||||
|
{vcpus: <{vcpus_length}} \
|
||||||
|
{sockets: <{sockets_length}} \
|
||||||
|
{cores: <{cores_length}} \
|
||||||
|
{threads: <{threads_length}}{end_bold}'.format(
|
||||||
|
name_length=name_length,
|
||||||
|
vcpus_length=vcpus_length,
|
||||||
|
sockets_length=sockets_length,
|
||||||
|
cores_length=cores_length,
|
||||||
|
threads_length=threads_length,
|
||||||
|
bold=ansiprint.bold(),
|
||||||
|
end_bold=ansiprint.end(),
|
||||||
|
name='Name',
|
||||||
|
vcpus='vCPUs',
|
||||||
|
sockets='Sockets',
|
||||||
|
cores='Cores',
|
||||||
|
threads='Threads'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
output_list.append(
|
||||||
|
'{bold}{name: <{name_length}} \
|
||||||
|
{vcpus: <{vcpus_length}} \
|
||||||
|
{sockets: <{sockets_length}} \
|
||||||
|
{cores: <{cores_length}} \
|
||||||
|
{threads: <{threads_length}}{end_bold}'.format(
|
||||||
|
name_length=name_length,
|
||||||
|
vcpus_length=vcpus_length,
|
||||||
|
sockets_length=sockets_length,
|
||||||
|
cores_length=cores_length,
|
||||||
|
threads_length=threads_length,
|
||||||
|
bold=ansiprint.bold(),
|
||||||
|
end_bold=ansiprint.end(),
|
||||||
|
name=name,
|
||||||
|
vcpus=vcpus[0],
|
||||||
|
sockets=vcpus[1][0],
|
||||||
|
cores=vcpus[1][1],
|
||||||
|
threads=vcpus[1][2]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return '\n'.join(output_list)
|
||||||
|
|
||||||
|
|
||||||
def view_console_log(config, vm, lines=100):
|
def view_console_log(config, vm, lines=100):
|
||||||
"""
|
"""
|
||||||
Return console log lines from the API (and display them in a pager in the main CLI)
|
Return console log lines from the API (and display them in a pager in the main CLI)
|
||||||
|
|
|
@ -1036,6 +1036,72 @@ def vm_vcpu():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# pvc vm vcpu get
|
||||||
|
###############################################################################
|
||||||
|
@click.command(name='get', short_help='Get the current vCPU count of a virtual machine.')
|
||||||
|
@click.argument(
|
||||||
|
'domain'
|
||||||
|
)
|
||||||
|
@click.option(
|
||||||
|
'-r', '--raw', 'raw', is_flag=True, default=False,
|
||||||
|
help='Display the raw value only without formatting.'
|
||||||
|
)
|
||||||
|
@cluster_req
|
||||||
|
def vm_vcpu_get(domain, raw):
|
||||||
|
"""
|
||||||
|
Get the current vCPU count of the virtual machine DOMAIN.
|
||||||
|
"""
|
||||||
|
|
||||||
|
retcode, retmsg = pvc_vm.vm_vcpus_get(config, domain)
|
||||||
|
if not raw:
|
||||||
|
retmsg = pvc_vm.format_vm_vcpus(config, domain, retmsg)
|
||||||
|
else:
|
||||||
|
retmsg = retmsg[0] # Get only the first part of the tuple (vm_vcpus)
|
||||||
|
cleanup(retcode, retmsg)
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# pvc vm vcpu set
|
||||||
|
###############################################################################
|
||||||
|
@click.command(name='set', short_help='Set the vCPU count of a virtual machine.')
|
||||||
|
@click.argument(
|
||||||
|
'domain'
|
||||||
|
)
|
||||||
|
@click.argument(
|
||||||
|
'vcpus'
|
||||||
|
)
|
||||||
|
@click.option(
|
||||||
|
'-t', '--topology', 'topology', default=None,
|
||||||
|
help='Use an alternative topology for the vCPUs in the CSV form <sockets>,<cores>,<threads>. SxCxT must equal VCPUS.'
|
||||||
|
)
|
||||||
|
@click.option(
|
||||||
|
'-r', '--restart', 'restart', is_flag=True, default=False,
|
||||||
|
help='Immediately restart VM to apply new config.'
|
||||||
|
)
|
||||||
|
@cluster_req
|
||||||
|
def vm_vcpu_set(domain, vcpus, topology, restart):
|
||||||
|
"""
|
||||||
|
Set the vCPU count of the virtual machine DOMAIN to VCPUS.
|
||||||
|
|
||||||
|
By default, the topology of the vCPus is 1 socket, VCPUS cores per socket, 1 thread per core.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if topology is not None:
|
||||||
|
try:
|
||||||
|
sockets, cores, threads = topology.split(',')
|
||||||
|
if sockets * cores * threads != vcpus:
|
||||||
|
raise
|
||||||
|
except Exception:
|
||||||
|
cleanup(False, "The topology specified is not valid.")
|
||||||
|
topology = (sockets, cores, threads)
|
||||||
|
else:
|
||||||
|
topology = (1, vcpus, 1)
|
||||||
|
|
||||||
|
retcode, retmsg = pvc_vm.vm_vcpus_set(config, domain, vcpus, topology, restart)
|
||||||
|
cleanup(retcode, retmsg)
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# pvc vm memory
|
# pvc vm memory
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
@ -3898,8 +3964,8 @@ cli_node.add_command(node_unflush)
|
||||||
cli_node.add_command(node_info)
|
cli_node.add_command(node_info)
|
||||||
cli_node.add_command(node_list)
|
cli_node.add_command(node_list)
|
||||||
|
|
||||||
# vm_vcpu.add_command(vm_vcpu_get)
|
vm_vcpu.add_command(vm_vcpu_get)
|
||||||
# vm_vcpu.add_command(vm_vcpu_set)
|
vm_vcpu.add_command(vm_vcpu_set)
|
||||||
|
|
||||||
# vm_memory.add_command(vm_memory_get)
|
# vm_memory.add_command(vm_memory_get)
|
||||||
# vm_memory.add_command(vm_memory_set)
|
# vm_memory.add_command(vm_memory_set)
|
||||||
|
|
Loading…
Reference in New Issue