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

Reply via email to