Noam Slomianko has uploaded a new change for review.

Change subject: External Scheduler: Add memory example
......................................................................

External Scheduler: Add memory example

Adds a comprihensive example of a memory filter.
Filter stages:
- finds the host with the least amount of free memory
- checks what is the maximum vm size it can pass to
  the other hosts without overloading them
- find a vm it can pass that is small enough to
  run on one of the other servers, but trying to find one
  that will solve the overutilization in one migration

Change-Id: I1b4a41064631912f5624723327a2ff5ebf158d5c
Signed-off-by: Noam Slomianko <nslom...@redhat.com>
---
A plugins/examples/host_memory_balance.py
1 file changed, 138 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-scheduler-proxy 
refs/changes/34/19934/1

diff --git a/plugins/examples/host_memory_balance.py 
b/plugins/examples/host_memory_balance.py
new file mode 100644
index 0000000..1f2f910
--- /dev/null
+++ b/plugins/examples/host_memory_balance.py
@@ -0,0 +1,138 @@
+from ovirtsdk.xml import params
+from ovirtsdk.api import API
+import sys
+
+
+class host_memory_balance():
+    '''moves a vm from a host with to many'''
+
+    #What are the values this module will accept, used to present
+    #the user with options
+    properties_validation = 'minimum_host_memory=[0-9]*'
+
+    def _get_connection(self):
+        #open a connection to the rest api
+        connection = None
+        try:
+            connection = API(url='http://host:port',
+                             username='user@domain', password='')
+        except BaseException as ex:
+            #letting the external proxy know there was an error
+            print >> sys.stderr, ex
+            return None
+
+        return connection
+
+    def _get_hosts(self, host_ids, connection):
+        #get all the hosts with the given ids
+        engine_hosts = connection.hosts.list(
+            query=" or ".join(["id=%s" % u for u in host_ids]))
+
+        return engine_hosts
+
+    def getFreeMemory(host):
+        try:
+            return 
host.get_statistics().get('memory.free').get_values().get_value()[0].get_datum()
+        except:
+            return -1
+
+    def filterHosts(self, engine_hosts, minimum_host_memory):
+        '''return the most overloaded host, and a list of under utilized 
hosts'''
+        over_loaded_host = None
+        white_listed_hosts = []
+        for engine_host in engine_hosts:
+            if(engine_host):
+                free_memory = self.getFreeMemory(engine_host)
+                if(free_memory <= 0):
+                    continue
+                if free_memory > minimum_host_memory:
+                        white_listed_hosts.append(engine_host)
+                        continue
+                    #take the host with least amount of free memory
+                if not over_loaded_host or \
+                        self.getFreeMemory(over_loaded_host) \
+                        > free_memory:
+                        over_loaded_host = engine_host
+        return over_loaded_host, white_listed_hosts
+
+    def getMaximumVmMemory(self, hosts, minimum_host_memory):
+        '''the maximum amount of memory that a migrated vm can have
+        without sending the other hosts over the threshold'''
+        maximum_vm_memory = 0
+        for host in hosts:
+            available_memory = self.getFreeMemory(host) - minimum_host_memory
+
+            available_memory = min(available_memory,
+                                   host.get_max_scheduling_memory())
+            if available_memory > maximum_vm_memory:
+                maximum_vm_memory = available_memory
+
+        return maximum_vm_memory
+
+    def getBestVmForMigration(self, vms, maximum_vm_memory, memory_delta):
+        selected_vm = None
+        largest_valid_vm = None
+        for vm in vms:
+                if vm.memory > maximum_vm_memory:
+                    continue
+                if vm.memory > memory_delta:
+                    if (not selected_vm) or (vm.memory < selected_vm.memmory):
+                        selected_vm = vm
+                if (not largest_valid_vm) or (largest_valid_vm.memory < 
vm.memory):
+                    largest_valid_vm = vm
+
+        #not even one vm is valid
+        if not largest_valid_vm:
+            return
+
+        #no vm will be enough to take the host under the threshold,
+        #pick the largest valid one
+        if not selected_vm:
+            selected_vm = largest_valid_vm
+
+        return selected_vm
+
+    def do_balance(self, hosts_ids, args_map):
+        conn = self._get_connection()
+        if conn is None:
+            return
+
+        #get our parameters from the map with default of 500MB
+        minimum_host_memory = long(args_map.get('minimum_host_memory',
+                                                1024*1024*500))
+
+        #get all the hosts with the given ids
+        engine_hosts = self._get_hosts(hosts_ids, conn)
+
+        over_loaded_host, white_listed_hosts = \
+            self.filterHosts(engine_hosts, minimum_host_memory)
+
+        if(not over_loaded_host):
+            return
+
+        maximum_vm_memory = self.getMaximumVmMemory(white_listed_hosts,
+                                               minimum_host_memory)
+
+        selected_vm = None
+        largest_valid_vm = None
+        #amount of memory the host is missing
+        memory_delta = \
+            minimum_host_memory - \
+            self.getFreeMemory(over_loaded_host)
+
+        #pick the vm with minimum amount of memory that will bring the host
+        #above the required threshold and is smaller then the maximum available
+        #memory in the white list hosts
+        #(e.i will not make them become over loaded)
+        host_vms = conn.vms.list('host=' + over_loaded_host.name)
+        if not host_vms:
+            return
+
+        selected_vm = self.getBestVmForMigration(host_vms, maximum_vm_memory,
+                                                 memory_delta)
+        # try another host?
+        if not selected_vm:
+            return
+
+        white_listed_hosts_ids = [host.id for host in white_listed_hosts]
+        print (selected_vm.id, white_listed_hosts_ids)
\ No newline at end of file


-- 
To view, visit http://gerrit.ovirt.org/19934
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I1b4a41064631912f5624723327a2ff5ebf158d5c
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-scheduler-proxy
Gerrit-Branch: master
Gerrit-Owner: Noam Slomianko <nslom...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to