CORD-2741 Remove Scheduler code from core
Change-Id: I4769469da4cc7d127a9fe63e25a729ada4d88098
diff --git a/xos/core/models/service.py b/xos/core/models/service.py
index b03ac70..3a6d57b 100644
--- a/xos/core/models/service.py
+++ b/xos/core/models/service.py
@@ -16,122 +16,6 @@
from xos.exceptions import *
from service_decl import *
-class Scheduler(object):
- # XOS Scheduler Abstract Base Class
- # Used to implement schedulers that pick which node to put instances on
-
- def __init__(self, slice):
- self.slice = slice
-
- def pick(self):
- # this method should return a tuple (node, parent)
- # node is the node to instantiate on
- # parent is for container_vm instances only, and is the VM that will
- # hold the container
-
- raise Exception("Abstract Base")
-
-
-class LeastLoadedNodeScheduler(Scheduler):
- # This scheduler always return the node with the fewest number of
- # instances.
-
- def __init__(self, slice, label=None):
- super(LeastLoadedNodeScheduler, self).__init__(slice)
- self.label = label
-
- def pick(self):
- from core.models import Node
-
- # start with all nodes
- nodes = Node.objects.all()
-
- # if a label is set, then filter by label
- if self.label:
- nodes = nodes.filter(nodelabels__name=self.label)
-
- # if slice.default_node is set, then filter by default_node
- if self.slice.default_node:
- nodes = nodes.filter(name = self.slice.default_node)
-
- # convert to list
- nodes = list(nodes)
-
- # sort so that we pick the least-loaded node
- nodes = sorted(nodes, key=lambda node: node.instances.all().count())
-
- if not nodes:
- raise Exception(
- "LeastLoadedNodeScheduler: No suitable nodes to pick from")
-
- # TODO: logic to filter nodes by which nodes are up, and which
- # nodes the slice can instantiate on.
-# nodes = sorted(nodes, key=lambda node: node.instances.all().count())
- return [nodes[0], None]
-
-
-class ContainerVmScheduler(Scheduler):
- # This scheduler picks a VM in the slice with the fewest containers inside
- # of it. If no VMs are suitable, then it creates a VM.
-
- MAX_VM_PER_CONTAINER = 10
-
- def __init__(self, slice):
- super(ContainerVmScheduler, self).__init__(slice)
-
- @property
- def image(self):
- from core.models import Image
-
- # If slice has default_image set then use it
- if self.slice.default_image:
- return self.slice.default_image
-
- raise XOSProgrammingError("Please set a default image for %s" % self.slice.name)
-
- def make_new_instance(self):
- from core.models import Instance, Flavor
-
- flavors = Flavor.objects.filter(name="m1.small")
- if not flavors:
- raise XOSConfigurationError("No m1.small flavor")
-
- (node, parent) = LeastLoadedNodeScheduler(self.slice).pick()
-
- instance = Instance(slice=self.slice,
- node=node,
- image=self.image,
- creator=self.slice.creator,
- deployment=node.site_deployment.deployment,
- flavor=flavors[0],
- isolation="vm",
- parent=parent)
- instance.save()
- # We rely on a special naming convention to identify the VMs that will
- # hole containers.
- instance.name = "%s-outer-%s" % (instance.slice.name, instance.id)
- instance.save()
- return instance
-
- def pick(self):
- from core.models import Instance, Flavor
-
- for vm in self.slice.instances.filter(isolation="vm"):
- avail_vms = []
- if (vm.name.startswith("%s-outer-" % self.slice.name)):
- container_count = Instance.objects.filter(parent=vm).count()
- if (container_count < self.MAX_VM_PER_CONTAINER):
- avail_vms.append((vm, container_count))
- # sort by least containers-per-vm
- avail_vms = sorted(avail_vms, key=lambda x: x[1])
- print "XXX", avail_vms
- if avail_vms:
- instance = avail_vms[0][0]
- return (instance.node, instance)
-
- instance = self.make_new_instance()
- return (instance.node, instance)
-
class Service(Service_decl):
class Meta:
proxy = True
diff --git a/xos/core/models/tenantwithcontainer.py b/xos/core/models/tenantwithcontainer.py
index f6b73b4..63abcb2 100644
--- a/xos/core/models/tenantwithcontainer.py
+++ b/xos/core/models/tenantwithcontainer.py
@@ -62,100 +62,6 @@
raise XOSProgrammingError("Please set a default image for %s" % self.slice.name)
- def save_instance(self, instance):
- # Override this function to do custom pre-save or post-save processing,
- # such as creating ports for containers.
- instance.save()
-
- def pick_least_loaded_instance_in_slice(self, slices, image):
- for slice in slices:
- if slice.instances.all().count() > 0:
- for instance in slice.instances.all():
- if instance.image != image:
- continue
- # Pick the first instance that has lesser than 5 tenants
- if self.count_of_tenants_of_an_instance(instance) < 5:
- return instance
- return None
-
- # TODO: Ideally the tenant count for an instance should be maintained using a
- # many-to-one relationship attribute, however this model being proxy, it does
- # not permit any new attributes to be defined. Find if any better solutions
- def count_of_tenants_of_an_instance(self, instance):
- tenant_count = 0
- for tenant in self.__class__.objects.all():
- if tenant.get_attribute("instance_id", None) == instance.id:
- tenant_count += 1
- return tenant_count
-
- def manage_container(self):
- from core.models import Instance, Flavor
-
- if self.deleted:
- return
-
- if (self.instance is not None) and (self.instance.image != self.image):
- self.instance.delete()
- self.instance = None
-
- if self.instance is None:
- if not self.provider_service.slices.count():
- raise XOSConfigurationError("The service has no slices")
-
- new_instance_created = False
- instance = None
- if self.get_attribute("use_same_instance_for_multiple_tenants", default=False):
- # Find if any existing instances can be used for this tenant
- slices = self.provider_service.slices.all()
- instance = self.pick_least_loaded_instance_in_slice(slices, self.image)
-
- if not instance:
- slice = self.provider_service.slices.all()[0]
-
- flavor = slice.default_flavor
- if not flavor:
- flavors = Flavor.objects.filter(name="m1.small")
- if not flavors:
- raise XOSConfigurationError("No m1.small flavor")
- flavor = flavors[0]
-
- if slice.default_isolation == "container_vm":
- (node, parent) = ContainerVmScheduler(slice).pick()
- else:
- (node, parent) = LeastLoadedNodeScheduler(slice).pick()
-
- instance = Instance(slice=slice,
- node=node,
- image=self.image,
- creator=self.creator,
- deployment=node.site_deployment.deployment,
- flavor=flavor,
- isolation=slice.default_isolation,
- parent=parent)
- self.save_instance(instance)
- new_instance_created = True
-
- try:
- self.instance = instance
- super(TenantWithContainer, self).save()
- except:
- if new_instance_created:
- instance.delete()
- raise
-
- def cleanup_container(self):
- if self.instance:
- if self.get_attribute("use_same_instance_for_multiple_tenants", default=False):
- # Delete the instance only if this is last tenant in that
- # instance
- tenant_count = self.count_of_tenants_of_an_instance(
- self.instance)
- if tenant_count == 0:
- self.instance.delete()
- else:
- self.instance.delete()
- self.instance = None
-
def save(self, *args, **kwargs):
if (not self.creator) and (hasattr(self, "caller")) and (self.caller):
self.creator = self.caller