Skip to content

Commit

Permalink
Add support to edit max memory in Templates
Browse files Browse the repository at this point in the history
This patch changes the 'memory' parameter in API of Templates to:
memory: {current: XXX, maxmemory: YYY}
Other changes include:
* enable maxmemory edition
* remove max memory tests and limits
* keeps max memory limit to 1TiB
* changes templates.conf to suport max memory
* set default memory and maxmemory to 1024

Signed-off-by: Rodrigo Trujillo <[email protected]>
  • Loading branch information
Truja authored and alinefm committed Feb 23, 2016
1 parent 001bf5b commit a5a94ac
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 77 deletions.
34 changes: 22 additions & 12 deletions API.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,26 @@
}
}
}
},
"memory": {
"description": "Current memory and maximum memory values",
"type": "object",
"properties": {
"current": {
"description": "Memory (MB) for the template",
"type": "integer",
"minimum": 512,
"error": "KCHTMPL0013E"
},
"maxmemory": {
"description": "Maximum memory (MB) for the template",
"type": "integer",
"minimum": 512,
"error": "KCHTMPL0013E"
}
},
"additionalProperties": false,
"error": "KCHTMPL0030E"
}
},
"properties": {
Expand Down Expand Up @@ -452,12 +472,7 @@
"minLength": 1,
"error": "KCHTMPL0011E"
},
"memory": {
"description": "Memory (MB) for the template",
"type": "integer",
"minimum": 512,
"error": "KCHTMPL0013E"
},
"memory": { "$ref": "#/kimchitype/memory" },
"cdrom": {
"description": "Path for cdrom",
"type": "string",
Expand Down Expand Up @@ -629,12 +644,7 @@
"minLength": 1,
"error": "KCHTMPL0011E"
},
"memory": {
"description": "Memory (MB) for the template",
"type": "integer",
"minimum": 512,
"error": "KCHTMPL0013E"
},
"memory": { "$ref": "#/kimchitype/memory" },
"cdrom": {
"description": "Path for cdrom",
"type": "string",
Expand Down
18 changes: 14 additions & 4 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,11 @@ Represents a snapshot of the Virtual Machine's primary monitor.
* name: The name of the Template. Used to identify the Template in this API
* os_distro *(optional)*: The operating system distribution
* os_version *(optional)*: The version of the operating system distribution
* memory *(optional)*: The amount of memory assigned to the VM.
Default is 1024M.
* memory *(optional)*: The memory parameters of the template, specify one
or both. Default values are 1024MiB:
* current: The amount of memory that will be assigned to the VM.
* maxmemory: The maximum total of memory that the VM can have. Amount
over current will be used exclusively for memory hotplug
* cdrom *(optional)*: A volume name or URI to an ISO image.
* networks *(optional)*: list of networks will be assigned to the new VM.
Default is '[default]'
Expand Down Expand Up @@ -396,7 +399,11 @@ A interface represents available network interface on VM.
* icon: A URI to a PNG image representing this template
* os_distro: The operating system distribution
* os_version: The version of the operating system distribution
* memory: The amount of memory assigned to the VM in the unit of MB
* memory: The memory parameters of the template, that will be assigned to
the VM in the unit of MiB.
* current: The amount of memory that will be assigned to the VM.
* maxmemory: The maximum total of memory that the VM can have. Amount
over current will be used exclusively for memory hotplug
* cdrom: A volume name or URI to an ISO image
* storagepool: URI of the storagepool where template allocates vm storage.
* networks *(optional)*: list of networks will be assigned to the new VM.
Expand Down Expand Up @@ -439,7 +446,10 @@ A interface represents available network interface on VM.
* icon: A URI to a PNG image representing this template
* os_distro: The operating system distribution
* os_version: The version of the operating system distribution
* memory: The amount of memory assigned to the VM
* memory: The memory parameters of the template, specify one or both of:
* current: The amount of memory that will be assigned to the VM.
* maxmemory: The maximum total of memory that the VM can have. Amount
over current will be used exclusively for memory hotplug
* cdrom: A volume name or URI to an ISO image
* networks *(optional)*: list of networks will be assigned to the new VM.
* disks: An array of requested disks with the following optional fields
Expand Down
9 changes: 6 additions & 3 deletions i18n.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,13 @@
"KCHVM0068E": _("Unable to setup password-less login at remote host %(host)s using user %(user)s. Error: %(error)s"),
"KCHVM0069E": _("Password field must be a string."),
"KCHVM0070E": _("Error creating local host ssh rsa key of user 'root'."),
"KCHVM0071E": _("Memory value %(mem)s must be aligned to %(alignment)sMiB."),
"KCHVM0071E": _("%(param)s value (%(mem)sMiB) must be aligned to %(alignment)sMiB."),
"KCHVM0073E": _("Unable to update the following parameters while the VM is offline: %(params)s"),
"KCHVM0074E": _("Unable to update the following parameters while the VM is online: %(params)s"),

"KCHVM0076E": _("VM %(name)s must have serial and console defined to open a web serial console"),
"KCHVM0077E": _("Impossible to get the serial console of %(name)s"),
"KCHVM0078E": _("Memory or Maximum Memory value is higher than amount supported by the host: %(memHost)sMiB."),
"KCHVM0079E": _("Memory or Maximum Memory value is higher than maximum amount recommended: 1TiB"),

"KCHVMHDEV0001E": _("VM %(vmid)s does not contain directly assigned host device %(dev_name)s."),
"KCHVMHDEV0002E": _("The host device %(dev_name)s is not allowed to directly assign to VM."),
Expand Down Expand Up @@ -166,7 +167,7 @@
"KCHTMPL0010E": _("Template distribution must be a string"),
"KCHTMPL0011E": _("Template distribution version must be a string"),
"KCHTMPL0012E": _("The number of CPUs must be an integer greater than 0"),
"KCHTMPL0013E": _("Amount of memory (MB) must be an integer greater than 512"),
"KCHTMPL0013E": _("Amount of memory and maximum memory (MB) must be an integer greater than 512"),
"KCHTMPL0014E": _("Template CDROM must be a local or remote ISO file"),
"KCHTMPL0015E": _("Invalid storage pool URI %(value)s specified for template"),
"KCHTMPL0016E": _("Specify an ISO image as CDROM or a base image to create a template"),
Expand All @@ -182,6 +183,8 @@
"KCHTMPL0027E": _("Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, qcow2, qed, raw, vmdk, vpc."),
"KCHTMPL0028E": _("When setting template disks, following parameters are required: 'index', 'pool name', 'format', 'size' or 'volume' (for scsi/iscsi pools)"),
"KCHTMPL0029E": _("Disk format must be 'raw', for logical, iscsi, and scsi pools."),
"KCHTMPL0030E": _("Memory expects an object with one or both parameters: 'current' and 'maxmemory'"),
"KCHTMPL0031E": _("Memory value (%(mem)sMiB) must be equal or lesser than maximum memory value (%(maxmem)sMiB)"),

"KCHPOOL0001E": _("Storage pool %(name)s already exists"),
"KCHPOOL0002E": _("Storage pool %(name)s does not exist"),
Expand Down
64 changes: 60 additions & 4 deletions model/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import copy
import libvirt
import os
import platform
import psutil
import stat

from wok.exception import InvalidOperation, InvalidParameter
Expand All @@ -34,6 +36,12 @@
from wok.plugins.kimchi.vmtemplate import VMTemplate


# In PowerPC, memories must be aligned to 256 MiB
PPC_MEM_ALIGN = 256
# Max memory 1TB, in KiB
MAX_MEM_LIM = 1073741824


class TemplatesModel(object):
def __init__(self, **kargs):
self.objstore = kargs['objstore']
Expand Down Expand Up @@ -69,10 +77,8 @@ def create(self, params):
# Validate cpu info
t.cpuinfo_validate()

# Validate max memory
maxMem = (t._get_max_memory(t.info.get('memory')) >> 10)
if t.info.get('memory') > maxMem:
raise OperationFailed("KCHVM0041E", {'maxmem': str(maxMem)})
# Validate memory
t._validate_memory()

# Validate volumes
for disk in t.info.get('disks'):
Expand Down Expand Up @@ -180,6 +186,13 @@ def update(self, name, params):
cpu_info.update(new_cpu_info)
params['cpu_info'] = cpu_info

# Fix memory values, because method update does not work recursively
new_mem = params.get('memory')
if new_mem is not None:
params['memory'] = copy.copy(old_t.get('memory'))
params['memory'].update(new_mem)
validate_memory(params['memory'])

new_t.update(params)

for net_name in params.get(u'networks', []):
Expand All @@ -199,12 +212,55 @@ def update(self, name, params):
return ident


def validate_memory(memory):
#
# All checking are made in Mib, so, expects memory values in Mib
#
current = memory.get('current')
maxmem = memory.get('maxmemory')

# Check Host Memory
if hasattr(psutil, 'virtual_memory'):
host_memory = psutil.virtual_memory().total >> 10 >> 10
else:
host_memory = psutil.TOTAL_PHYMEM >> 10 >> 10

# Memories must be lesser than 1TB and the Host memory limit
if (current > (MAX_MEM_LIM >> 10)) or (maxmem > (MAX_MEM_LIM >> 10)):
raise InvalidParameter("KCHVM0079E")
if (current > host_memory) or (maxmem > host_memory):
raise InvalidParameter("KCHVM0078E", {'memHost': host_memory})

# Current memory cannot be greater than maxMemory
if current > maxmem:
raise InvalidParameter("KCHTMPL0031E",
{'mem': str(current),
'maxmem': str(maxmem)})

# make sure memory and Maxmemory are alingned in 256MiB in PowerPC
distro, _, _ = platform.linux_distribution()
if distro == "IBM_PowerKVM":
if current % PPC_MEM_ALIGN != 0:
raise InvalidParameter('KCHVM0071E',
{'param': "Memory",
'mem': str(current),
'alignment': str(PPC_MEM_ALIGN)})
elif maxmem % PPC_MEM_ALIGN != 0:
raise InvalidParameter('KCHVM0071E',
{'param': "Maximum Memory",
'mem': str(maxmem),
'alignment': str(PPC_MEM_ALIGN)})


class LibvirtVMTemplate(VMTemplate):
def __init__(self, args, scan=False, conn=None):
self.conn = conn
VMTemplate.__init__(self, args, scan)
self.set_cpu_info()

def _validate_memory(self):
validate_memory(self.info['memory'])

def cpuinfo_validate(self):
cpu_model = CPUInfoModel(conn=self.conn)

Expand Down
5 changes: 3 additions & 2 deletions model/vms.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@
from wok.plugins.kimchi.model.cpuinfo import CPUInfoModel
from wok.plugins.kimchi.model.featuretests import FeatureTests
from wok.plugins.kimchi.model.templates import TemplateModel
from wok.plugins.kimchi.model.templates import MAX_MEM_LIM, PPC_MEM_ALIGN
from wok.plugins.kimchi.model.utils import get_ascii_nonascii_name, get_vm_name
from wok.plugins.kimchi.model.utils import get_metadata_node
from wok.plugins.kimchi.model.utils import remove_metadata_node
from wok.plugins.kimchi.model.utils import set_metadata_node
from wok.plugins.kimchi.screenshot import VMScreenshot
from wok.plugins.kimchi.utils import template_name_from_uri
from wok.plugins.kimchi.vmtemplate import MAX_MEM_LIM, PPC_MEM_ALIGN
from wok.plugins.kimchi.xmlutils.cpu import get_cpu_xml, get_numa_xml
from wok.plugins.kimchi.xmlutils.cpu import get_topology_xml
from wok.plugins.kimchi.xmlutils.disk import get_vm_disk_info, get_vm_disks
Expand Down Expand Up @@ -256,7 +256,8 @@ def update(self, name, params):
if 'memory' in params and distro == "IBM_PowerKVM":
if params['memory'] % PPC_MEM_ALIGN != 0:
raise InvalidParameter('KCHVM0071E',
{'mem': str(params['memory']),
{'param': "Memory",
'mem': str(params['memory']),
'alignment': str(PPC_MEM_ALIGN)})

dom = self.get_vm(name, self.conn)
Expand Down
16 changes: 11 additions & 5 deletions osinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,13 @@ def _get_tmpl_defaults():
ConfigObj returns a dict like below when no changes were made in the
template configuration file (template.conf)
{'main': {}, 'storage': {'disk.0': {}}, 'processor': {}, 'graphics': {}}
{'main': {}, 'memory': {}, 'storage': {'disk.0': {}}, 'processor': {},
'graphics': {}}
The default values should be like below:
{'main': {'networks': ['default'], 'memory': '1024'},
{'main': {'networks': ['default']},
'memory': {'current': 1024, 'maxmemory': 1024},
'storage': { 'disk.0': {'format': 'qcow2', 'size': '10',
'pool': '/plugins/kimchi/storagepools/default'}},
'processor': {'vcpus': '1', 'maxvcpus': 1},
Expand All @@ -123,7 +125,8 @@ def _get_tmpl_defaults():
# Create dict with default values
tmpl_defaults = defaultdict(dict)
tmpl_defaults['main']['networks'] = ['default']
tmpl_defaults['main']['memory'] = _get_default_template_mem()
tmpl_defaults['memory'] = {'current': _get_default_template_mem(),
'maxmemory': _get_default_template_mem()}
tmpl_defaults['storage']['disk.0'] = {'size': 10, 'format': 'qcow2',
'pool': 'default'}
tmpl_defaults['processor']['vcpus'] = 1
Expand All @@ -145,8 +148,11 @@ def _get_tmpl_defaults():
'cdrom_bus': 'ide', 'cdrom_index': 2, 'mouse_bus': 'ps2'}

# Parse main section to get networks and memory values
main_section = default_config.pop('main')
defaults.update(main_section)
defaults.update(default_config.pop('main'))
defaults['memory'] = default_config.pop('memory')

defaults['memory']['current'] = int(defaults['memory']['current'])
defaults['memory']['maxmemory'] = int(defaults['memory']['maxmemory'])

# Parse storage section to get disks values
storage_section = default_config.pop('storage')
Expand Down
10 changes: 7 additions & 3 deletions template.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
#

[main]
# Memory in MB
#memory = 1024

# List of networks separated by comma
# Represents the virtual network interfaces to be assigned to guest
#networks = default,

[memory]
# Memory in MB
# current = 1024

# Maximum value of memory to be assigned to guest in MB
# maxmemory = 1024

[storage]

# Specify multiple [[disk.X]] sub-sections to add multiples disks to guest
Expand Down
Loading

0 comments on commit a5a94ac

Please sign in to comment.