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