Martin Pavlásek has uploaded a new change for review. Change subject: Separate constants from rules to collector, read it from XML ......................................................................
Separate constants from rules to collector, read it from XML Rules usually contain certain constants that is applied on all VMs. This patch enables to read this values from <qos> metadata element of XML definition of libvirt domain. These values from XML has precedence to hardcoded in collecter/plugin. Change-Id: I6c16d29f6e1d541808d9c1f4051c3de0cc746098 Signed-off-by: Martin Pavlasek <mpavl...@redhat.com> --- M mom/Collectors/Collector.py M mom/Collectors/GuestMemory.py M mom/HypervisorInterfaces/libvirtInterface.py 3 files changed, 101 insertions(+), 21 deletions(-) git pull ssh://gerrit.ovirt.org:29418/mom refs/changes/88/34688/1 diff --git a/mom/Collectors/Collector.py b/mom/Collectors/Collector.py index ed1d7bb..1c13f51 100644 --- a/mom/Collectors/Collector.py +++ b/mom/Collectors/Collector.py @@ -59,6 +59,47 @@ """ return set() + @staticmethod + def getConstants(): + """ + Some rules may contain constants (tresholds etc.), this method provide + these as dict. These values can be present in file with rules itself, + or can be read from XML definition of libirt domain from <qos> element + (inside <metadata>). + Return: dict of constants, that can be "injected" into rules. + """ + return {} + + def _collect_const_fields(self): + """ + Values are used only if hypervisor isn't able to provide its own values. + """ + + # do not anything if collector doesn't provide any constants + if not self.const_fiels: + return {} + + logger = logging.getLogger('mom.Collector._collect_const_fields') + ret_fields = {} + metadata_xml = self.hypervisor_iface.getXMLQoSMetadata(self.uuid) + hv_consts = self.getConstants() + for k, v in self.const_fiels.iteritems(): + if v: + ret_fields[k] = v + else: + try: + hv_field = self.hypervisor_iface.getXMLElementValue( \ + metadata_xml, k) + self.const_fiels[k] = float(hv_field) + logger.debug('Using default value %s for %s provided '\ + 'by XML of VM.' % (hv_consts[k], k)) + except IndexError as e: + logger.warning('Using default value %s for %s from ' + 'collector plugin.' % (hv_consts[k], k)) + self.const_fiels[k] = hv_consts[k] + ret_fields[k] = self.const_fiels[k] + return ret_fields + def get_collectors(config_str, properties, global_config): """ Initialize a set of new Collector instances for a Monitor. diff --git a/mom/Collectors/GuestMemory.py b/mom/Collectors/GuestMemory.py index ff8547c..2044c44 100644 --- a/mom/Collectors/GuestMemory.py +++ b/mom/Collectors/GuestMemory.py @@ -17,13 +17,25 @@ from mom.Collectors.Collector import * from mom.HypervisorInterfaces.HypervisorInterface import * - class GuestMemory(Collector): """ This Collector uses hypervisor interface to collect guest memory statistics """ - def getFields(self=None): - return self.hypervisor_iface.getStatsFields() + + @staticmethod + def getConstants(): + """ + These keys are necessary for balloning rules, values are used only if + hypervisor isn't able to provide its own values. + """ + return {'min_guest_free_percent': 0.2, + 'max_balloon_change_percent': 0.05, + 'min_balloon_change_percent': 0.0025} + + def getFields(self): + fields = self.hypervisor_iface.getStatsFields() + fields.update(self.getConstants().keys()) + return fields def getOptionalFields(self=None): return set(["swap_total", "swap_usage"]) @@ -34,6 +46,7 @@ self.logger = logging.getLogger('mom.Collectors.GuestMemory') self.hypervisor_iface.startVmMemoryStats(self.uuid) self.memstats_available = True + self.const_fiels = {}.fromkeys(self.getConstants().keys()) def stats_error(self, msg): """ @@ -47,6 +60,9 @@ def collect(self): try: stat = self.hypervisor_iface.getVmMemoryStats(self.uuid) + constants = self._collect_const_fields() + stat.update(constants) + self.logger.debug('Using these constant fields: %s' % constants) except HypervisorInterfaceError, e: self.stats_error('getVmMemoryStats() error: %s' % e.message) # We don't raise a CollectionError here because a different diff --git a/mom/HypervisorInterfaces/libvirtInterface.py b/mom/HypervisorInterfaces/libvirtInterface.py index 641dd24..4ccab04 100644 --- a/mom/HypervisorInterfaces/libvirtInterface.py +++ b/mom/HypervisorInterfaces/libvirtInterface.py @@ -247,40 +247,63 @@ 'balloon_min': self._getGuaranteedMemory(domain) } return ret - def getVmCpuTuneInfo(self, uuid): - ret = {} + def getXMLQoSMetadata(self, uuid): + """XML definition of domain can contain also <metadata> element. + it is used as storage of QoS settings.""" domain = self._getDomainFromUUID(uuid) - - # Get the user selection for vcpuLimit from the metadata - metadataCpuLimit = None try: - metadataCpuLimit = domain.metadata( + metadata = domain.metadata( libvirt.VIR_DOMAIN_METADATA_ELEMENT, _METADATA_VM_TUNE_URI, 0) except libvirt.libvirtError as e: if e.get_error_code() != libvirt.VIR_ERR_NO_DOMAIN_METADATA: self.logger.error("Failed to retrieve QoS metadata") + return False - if metadataCpuLimit: - metadataCpuLimitXML = _domParseStr(metadataCpuLimit) - nodeList = \ - metadataCpuLimitXML.getElementsByTagName('vcpuLimit') - ret['vcpu_user_limit'] = nodeList[0].childNodes[0].data - else: - ret['vcpu_user_limit'] = 100 + metadataXML = _domParseStr(metadata) + return metadataXML + + @staticmethod + def getXMLElementValue(xml, element): + nodeList = xml.getElementsByTagName(element) + return nodeList[0].childNodes[0].data + + def getVmCpuTuneInfo(self, uuid): + # List of provided keys: + # vcpu_user_limit, vcpu_quota, vcpu_count, vcpu_period + + # Default values + defaults = { + 'vcpu_user_limit': 100, + 'vcpu_quota': 0, + 'vcpu_period': 0, + } + ret = {} + domain = self._getDomainFromUUID(uuid) + metadata_xml = self.getXMLQoSMetadata(uuid) + + # Get the user selection for vcpuLimit from the metadata + key = 'vcpu_user_limit' + try: + ret[key] = \ + self.getXMLElementValue(metadata_xml, 'vcpuLimit') + except IndexError: + ret[key] = defaults[key] # Retrieve the current cpu tuning params ret.update(domain.schedulerParameters()) - if ret['vcpu_quota'] == None: - ret['vcpu_quota'] = 0 + key = 'vcpu_quota' + if ret[key] == None: + ret[key] = defaults[key] - if ret['vcpu_period'] == None: - ret['vcpu_period'] = 0 + key = 'vcpu_period' + if ret[key] == None: + ret[key] = defaults[key] # Get the number of vcpus vcpuCount = domain.vcpusFlags(libvirt.VIR_DOMAIN_VCPU_CURRENT) if vcpuCount != -1: - ret['vcpu_count'] = vcpuCount + ret['vcpu_count'] = vcpuCount else: self.logger.error('Failed to get VM cpu count') return None -- To view, visit http://gerrit.ovirt.org/34688 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6c16d29f6e1d541808d9c1f4051c3de0cc746098 Gerrit-PatchSet: 1 Gerrit-Project: mom Gerrit-Branch: master Gerrit-Owner: Martin Pavlásek <mpavl...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches