Add scheduler hint
Add scheduler hint for server side. Change-Id: Ia612b3585efc74a9d52432ce790897447514c05e
This commit is contained in:
parent
8d4325f829
commit
478e72dd74
@ -252,13 +252,14 @@ class ContainersController(base.Controller):
|
|||||||
if container_dict.get('restart_policy'):
|
if container_dict.get('restart_policy'):
|
||||||
self._check_for_restart_policy(container_dict)
|
self._check_for_restart_policy(container_dict)
|
||||||
container_dict['status'] = consts.CREATING
|
container_dict['status'] = consts.CREATING
|
||||||
|
extra_spec = container_dict.get('hints', None)
|
||||||
new_container = objects.Container(context, **container_dict)
|
new_container = objects.Container(context, **container_dict)
|
||||||
new_container.create(context)
|
new_container.create(context)
|
||||||
|
|
||||||
if run:
|
if run:
|
||||||
compute_api.container_run(context, new_container)
|
compute_api.container_run(context, new_container, extra_spec)
|
||||||
else:
|
else:
|
||||||
compute_api.container_create(context, new_container)
|
compute_api.container_create(context, new_container, extra_spec)
|
||||||
# Set the HTTP Location Header
|
# Set the HTTP Location Header
|
||||||
pecan.response.location = link.build_url('containers',
|
pecan.response.location = link.build_url('containers',
|
||||||
new_container.uuid)
|
new_container.uuid)
|
||||||
|
@ -27,7 +27,8 @@ _container_properties = {
|
|||||||
'restart_policy': parameter_types.restart_policy,
|
'restart_policy': parameter_types.restart_policy,
|
||||||
'interactive': parameter_types.boolean,
|
'interactive': parameter_types.boolean,
|
||||||
'image_driver': parameter_types.image_driver,
|
'image_driver': parameter_types.image_driver,
|
||||||
'security_groups': parameter_types.security_groups
|
'security_groups': parameter_types.security_groups,
|
||||||
|
'hints': parameter_types.hints
|
||||||
}
|
}
|
||||||
|
|
||||||
container_create = {
|
container_create = {
|
||||||
|
@ -101,6 +101,10 @@ labels = {
|
|||||||
'type': ['object', 'null']
|
'type': ['object', 'null']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hints = {
|
||||||
|
'type': ['object', 'null']
|
||||||
|
}
|
||||||
|
|
||||||
environment = {
|
environment = {
|
||||||
'type': ['object', 'null']
|
'type': ['object', 'null']
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,9 @@ class API(object):
|
|||||||
self.scheduler_client = scheduler_client.SchedulerClient()
|
self.scheduler_client = scheduler_client.SchedulerClient()
|
||||||
super(API, self).__init__()
|
super(API, self).__init__()
|
||||||
|
|
||||||
def container_create(self, context, new_container):
|
def container_create(self, context, new_container, extra_spec):
|
||||||
try:
|
try:
|
||||||
self._schedule_container(context, new_container)
|
self._schedule_container(context, new_container, extra_spec)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
new_container.status = consts.ERROR
|
new_container.status = consts.ERROR
|
||||||
new_container.status_reason = str(exc)
|
new_container.status_reason = str(exc)
|
||||||
@ -39,9 +39,9 @@ class API(object):
|
|||||||
|
|
||||||
self.rpcapi.container_create(context, new_container)
|
self.rpcapi.container_create(context, new_container)
|
||||||
|
|
||||||
def container_run(self, context, new_container):
|
def container_run(self, context, new_container, extra_spec):
|
||||||
try:
|
try:
|
||||||
self._schedule_container(context, new_container)
|
self._schedule_container(context, new_container, extra_spec)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
new_container.status = consts.ERROR
|
new_container.status = consts.ERROR
|
||||||
new_container.status_reason = str(exc)
|
new_container.status_reason = str(exc)
|
||||||
@ -50,9 +50,10 @@ class API(object):
|
|||||||
|
|
||||||
self.rpcapi.container_run(context, new_container)
|
self.rpcapi.container_run(context, new_container)
|
||||||
|
|
||||||
def _schedule_container(self, context, new_container):
|
def _schedule_container(self, context, new_container, extra_spec):
|
||||||
dests = self.scheduler_client.select_destinations(context,
|
dests = self.scheduler_client.select_destinations(context,
|
||||||
[new_container])
|
[new_container],
|
||||||
|
extra_spec)
|
||||||
new_container.host = dests[0]['host']
|
new_container.host = dests[0]['host']
|
||||||
new_container.save(context)
|
new_container.save(context)
|
||||||
|
|
||||||
|
@ -23,11 +23,11 @@ LOG = logging.getLogger(__name__)
|
|||||||
|
|
||||||
class BaseFilter(object):
|
class BaseFilter(object):
|
||||||
"""Base class for all filter classes."""
|
"""Base class for all filter classes."""
|
||||||
def _filter_one(self, obj, container):
|
def _filter_one(self, obj, container, extra_spec):
|
||||||
"""Return True if it passes the filter, False otherwise."""
|
"""Return True if it passes the filter, False otherwise."""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def filter_all(self, filter_obj_list, container):
|
def filter_all(self, filter_obj_list, container, extra_spec):
|
||||||
"""Yield objects that pass the filter.
|
"""Yield objects that pass the filter.
|
||||||
|
|
||||||
Can be overridden in a subclass, if you need to base filtering
|
Can be overridden in a subclass, if you need to base filtering
|
||||||
@ -35,7 +35,7 @@ class BaseFilter(object):
|
|||||||
_filter_one() to filter a single object.
|
_filter_one() to filter a single object.
|
||||||
"""
|
"""
|
||||||
for obj in filter_obj_list:
|
for obj in filter_obj_list:
|
||||||
if self._filter_one(obj, container):
|
if self._filter_one(obj, container, extra_spec):
|
||||||
yield obj
|
yield obj
|
||||||
|
|
||||||
# Set to true in a subclass if a filter only needs to be run once
|
# Set to true in a subclass if a filter only needs to be run once
|
||||||
@ -61,7 +61,8 @@ class BaseFilterHandler(loadables.BaseLoader):
|
|||||||
This class should be subclassed where one needs to use filters.
|
This class should be subclassed where one needs to use filters.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_filtered_objects(self, filters, objs, container, index=0):
|
def get_filtered_objects(self, filters, objs, container, extra_spec,
|
||||||
|
index=0):
|
||||||
list_objs = list(objs)
|
list_objs = list(objs)
|
||||||
LOG.debug("Starting with %d host(s)", len(list_objs))
|
LOG.debug("Starting with %d host(s)", len(list_objs))
|
||||||
part_filter_results = []
|
part_filter_results = []
|
||||||
@ -71,7 +72,7 @@ class BaseFilterHandler(loadables.BaseLoader):
|
|||||||
if filter_.run_filter_for_index(index):
|
if filter_.run_filter_for_index(index):
|
||||||
cls_name = filter_.__class__.__name__
|
cls_name = filter_.__class__.__name__
|
||||||
start_count = len(list_objs)
|
start_count = len(list_objs)
|
||||||
objs = filter_.filter_all(list_objs, container)
|
objs = filter_.filter_all(list_objs, container, extra_spec)
|
||||||
if objs is None:
|
if objs is None:
|
||||||
LOG.debug("Filter %s says to stop filtering", cls_name)
|
LOG.debug("Filter %s says to stop filtering", cls_name)
|
||||||
return
|
return
|
||||||
|
@ -33,7 +33,7 @@ class ChanceScheduler(driver.Scheduler):
|
|||||||
|
|
||||||
return random.choice(hosts)
|
return random.choice(hosts)
|
||||||
|
|
||||||
def select_destinations(self, context, containers):
|
def select_destinations(self, context, containers, extra_spec):
|
||||||
"""Selects random destinations."""
|
"""Selects random destinations."""
|
||||||
dests = []
|
dests = []
|
||||||
for container in containers:
|
for container in containers:
|
||||||
|
@ -29,8 +29,8 @@ class SchedulerClient(object):
|
|||||||
scheduler_driver,
|
scheduler_driver,
|
||||||
invoke_on_load=True).driver
|
invoke_on_load=True).driver
|
||||||
|
|
||||||
def select_destinations(self, context, containers):
|
def select_destinations(self, context, containers, extra_spec):
|
||||||
return self.driver.select_destinations(context, containers)
|
return self.driver.select_destinations(context, containers, extra_spec)
|
||||||
|
|
||||||
def update_resource(self, node):
|
def update_resource(self, node):
|
||||||
node.save()
|
node.save()
|
||||||
|
@ -47,6 +47,6 @@ class Scheduler(object):
|
|||||||
"""Must override select_destinations method.
|
"""Must override select_destinations method.
|
||||||
|
|
||||||
:return: A list of dicts with 'host', 'nodename' and 'limits' as keys
|
:return: A list of dicts with 'host', 'nodename' and 'limits' as keys
|
||||||
that satisfies the request_spec and filter_properties.
|
that satisfies the extra_spec and filter_properties.
|
||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
@ -40,25 +40,26 @@ class FilterScheduler(driver.Scheduler):
|
|||||||
self.filter_obj_map = {}
|
self.filter_obj_map = {}
|
||||||
self.enabled_filters = self._choose_host_filters(self._load_filters())
|
self.enabled_filters = self._choose_host_filters(self._load_filters())
|
||||||
|
|
||||||
def _schedule(self, context, container):
|
def _schedule(self, context, container, extra_spec):
|
||||||
"""Picks a host according to filters."""
|
"""Picks a host according to filters."""
|
||||||
hosts = self.hosts_up(context)
|
hosts = self.hosts_up(context)
|
||||||
nodes = objects.ComputeNode.list(context)
|
nodes = objects.ComputeNode.list(context)
|
||||||
nodes = [node for node in nodes if node.hostname in hosts]
|
nodes = [node for node in nodes if node.hostname in hosts]
|
||||||
nodes = self.filter_handler.get_filtered_objects(self.enabled_filters,
|
nodes = self.filter_handler.get_filtered_objects(self.enabled_filters,
|
||||||
nodes,
|
nodes,
|
||||||
container)
|
container,
|
||||||
|
extra_spec)
|
||||||
if not nodes:
|
if not nodes:
|
||||||
msg = _("Is the appropriate service running?")
|
msg = _("Is the appropriate service running?")
|
||||||
raise exception.NoValidHost(reason=msg)
|
raise exception.NoValidHost(reason=msg)
|
||||||
|
|
||||||
return random.choice(nodes)
|
return random.choice(nodes)
|
||||||
|
|
||||||
def select_destinations(self, context, containers):
|
def select_destinations(self, context, containers, extra_spec):
|
||||||
"""Selects destinations by filters."""
|
"""Selects destinations by filters."""
|
||||||
dests = []
|
dests = []
|
||||||
for container in containers:
|
for container in containers:
|
||||||
node = self._schedule(context, container)
|
node = self._schedule(context, container, extra_spec)
|
||||||
host_state = dict(host=node.hostname, nodename=None, limits=None)
|
host_state = dict(host=node.hostname, nodename=None, limits=None)
|
||||||
dests.append(host_state)
|
dests.append(host_state)
|
||||||
|
|
||||||
|
@ -18,11 +18,11 @@ from zun.scheduler import base_filters
|
|||||||
|
|
||||||
class BaseHostFilter(base_filters.BaseFilter):
|
class BaseHostFilter(base_filters.BaseFilter):
|
||||||
"""Base class for host filters."""
|
"""Base class for host filters."""
|
||||||
def _filter_one(self, obj, filter_properties):
|
def _filter_one(self, obj, filter_properties, extra_spec):
|
||||||
"""Return True if the object passes the filter, otherwise False."""
|
"""Return True if the object passes the filter, otherwise False."""
|
||||||
return self.host_passes(obj, filter_properties)
|
return self.host_passes(obj, filter_properties, extra_spec)
|
||||||
|
|
||||||
def host_passes(self, host_state, filter_properties):
|
def host_passes(self, host_state, filter_properties, extra_spec):
|
||||||
"""Return True if the HostState passes the filter,otherwise False.
|
"""Return True if the HostState passes the filter,otherwise False.
|
||||||
|
|
||||||
Override this in a subclass.
|
Override this in a subclass.
|
||||||
|
@ -25,7 +25,7 @@ class CPUFilter(filters.BaseHostFilter):
|
|||||||
|
|
||||||
run_filter_once_per_request = True
|
run_filter_once_per_request = True
|
||||||
|
|
||||||
def host_passes(self, host_state, container):
|
def host_passes(self, host_state, container, extra_spec):
|
||||||
cpu_free = host_state.cpus - host_state.cpu_used
|
cpu_free = host_state.cpus - host_state.cpu_used
|
||||||
if not container.cpu:
|
if not container.cpu:
|
||||||
return True
|
return True
|
||||||
|
@ -26,7 +26,7 @@ class NoopFilter(filters.BaseHostFilter):
|
|||||||
# Host state does not change within a request
|
# Host state does not change within a request
|
||||||
run_filter_once_per_request = True
|
run_filter_once_per_request = True
|
||||||
|
|
||||||
def host_passes(self, host_state, container):
|
def host_passes(self, host_state, container, extra_spec):
|
||||||
"""Noop filter for now"""
|
"""Noop filter for now"""
|
||||||
|
|
||||||
# Depend on the objects.NodeInfo of below patch to filter node,
|
# Depend on the objects.NodeInfo of below patch to filter node,
|
||||||
|
@ -25,7 +25,7 @@ class RamFilter(filters.BaseHostFilter):
|
|||||||
|
|
||||||
run_filter_once_per_request = True
|
run_filter_once_per_request = True
|
||||||
|
|
||||||
def host_passes(self, host_state, container):
|
def host_passes(self, host_state, container, extra_spec):
|
||||||
if not container.memory:
|
if not container.memory:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
@patch('zun.compute.api.API.container_run')
|
@patch('zun.compute.api.API.container_run')
|
||||||
@patch('zun.compute.api.API.image_search')
|
@patch('zun.compute.api.API.image_search')
|
||||||
def test_run_container(self, mock_search, mock_container_run):
|
def test_run_container(self, mock_search, mock_container_run):
|
||||||
mock_container_run.side_effect = lambda x, y: y
|
mock_container_run.side_effect = lambda x, y, z: y
|
||||||
|
|
||||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||||
'"command": "env", "memory": "512",'
|
'"command": "env", "memory": "512",'
|
||||||
@ -56,7 +56,7 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
@patch('zun.compute.rpcapi.API.image_search')
|
@patch('zun.compute.rpcapi.API.image_search')
|
||||||
def test_run_container_with_false(self, mock_search,
|
def test_run_container_with_false(self, mock_search,
|
||||||
mock_container_run):
|
mock_container_run):
|
||||||
mock_container_run.side_effect = lambda x, y: y
|
mock_container_run.side_effect = lambda x, y, z: y
|
||||||
|
|
||||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||||
'"command": "env", "memory": "512",'
|
'"command": "env", "memory": "512",'
|
||||||
@ -82,7 +82,7 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
@patch('zun.compute.api.API.container_create')
|
@patch('zun.compute.api.API.container_create')
|
||||||
@patch('zun.compute.api.API.image_search')
|
@patch('zun.compute.api.API.image_search')
|
||||||
def test_create_container(self, mock_search, mock_container_create):
|
def test_create_container(self, mock_search, mock_container_create):
|
||||||
mock_container_create.side_effect = lambda x, y: y
|
mock_container_create.side_effect = lambda x, y, z: y
|
||||||
|
|
||||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||||
'"command": "env", "memory": "512",'
|
'"command": "env", "memory": "512",'
|
||||||
@ -111,7 +111,7 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
@patch('zun.compute.api.API.image_search')
|
@patch('zun.compute.api.API.image_search')
|
||||||
def test_create_container_image_not_found(self, mock_search,
|
def test_create_container_image_not_found(self, mock_search,
|
||||||
mock_container_create):
|
mock_container_create):
|
||||||
mock_container_create.side_effect = lambda x, y: y
|
mock_container_create.side_effect = lambda x, y, z: y
|
||||||
mock_search.side_effect = exception.ImageNotFound()
|
mock_search.side_effect = exception.ImageNotFound()
|
||||||
|
|
||||||
params = {"name": "MyDocker", "image": "not-found"}
|
params = {"name": "MyDocker", "image": "not-found"}
|
||||||
@ -124,7 +124,7 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
@patch('zun.compute.api.API.image_search')
|
@patch('zun.compute.api.API.image_search')
|
||||||
def test_create_container_set_project_id_and_user_id(
|
def test_create_container_set_project_id_and_user_id(
|
||||||
self, mock_search, mock_container_create):
|
self, mock_search, mock_container_create):
|
||||||
def _create_side_effect(cnxt, container):
|
def _create_side_effect(cnxt, container, extra_spec):
|
||||||
self.assertEqual(self.context.project_id, container.project_id)
|
self.assertEqual(self.context.project_id, container.project_id)
|
||||||
self.assertEqual(self.context.user_id, container.user_id)
|
self.assertEqual(self.context.user_id, container.user_id)
|
||||||
return container
|
return container
|
||||||
@ -141,7 +141,7 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
@patch('zun.compute.api.API.image_search')
|
@patch('zun.compute.api.API.image_search')
|
||||||
def test_create_container_resp_has_status_reason(self, mock_search,
|
def test_create_container_resp_has_status_reason(self, mock_search,
|
||||||
mock_container_create):
|
mock_container_create):
|
||||||
mock_container_create.side_effect = lambda x, y: y
|
mock_container_create.side_effect = lambda x, y, z: y
|
||||||
# Create a container with a command
|
# Create a container with a command
|
||||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||||
'"command": "env", "memory": "512",'
|
'"command": "env", "memory": "512",'
|
||||||
@ -160,7 +160,7 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
mock_container_delete,
|
mock_container_delete,
|
||||||
mock_container_create,
|
mock_container_create,
|
||||||
mock_container_show):
|
mock_container_show):
|
||||||
mock_container_create.side_effect = lambda x, y: y
|
mock_container_create.side_effect = lambda x, y, z: y
|
||||||
# Create a container with a command
|
# Create a container with a command
|
||||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||||
'"command": "env", "memory": "512",'
|
'"command": "env", "memory": "512",'
|
||||||
@ -201,7 +201,7 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
def test_create_container_without_memory(self, mock_search,
|
def test_create_container_without_memory(self, mock_search,
|
||||||
mock_container_create,
|
mock_container_create,
|
||||||
mock_container_show):
|
mock_container_show):
|
||||||
mock_container_create.side_effect = lambda x, y: y
|
mock_container_create.side_effect = lambda x, y, z: y
|
||||||
# Create a container with a command
|
# Create a container with a command
|
||||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||||
'"command": "env",'
|
'"command": "env",'
|
||||||
@ -232,7 +232,7 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
def test_create_container_without_environment(self, mock_search,
|
def test_create_container_without_environment(self, mock_search,
|
||||||
mock_container_create,
|
mock_container_create,
|
||||||
mock_container_show):
|
mock_container_show):
|
||||||
mock_container_create.side_effect = lambda x, y: y
|
mock_container_create.side_effect = lambda x, y, z: y
|
||||||
# Create a container with a command
|
# Create a container with a command
|
||||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||||
'"command": "env", "memory": "512"}')
|
'"command": "env", "memory": "512"}')
|
||||||
@ -262,7 +262,7 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
mock_container_create,
|
mock_container_create,
|
||||||
mock_container_show):
|
mock_container_show):
|
||||||
# No name param
|
# No name param
|
||||||
mock_container_create.side_effect = lambda x, y: y
|
mock_container_create.side_effect = lambda x, y, z: y
|
||||||
params = ('{"image": "ubuntu", "command": "env", "memory": "512",'
|
params = ('{"image": "ubuntu", "command": "env", "memory": "512",'
|
||||||
'"environment": {"key1": "val1", "key2": "val2"}}')
|
'"environment": {"key1": "val1", "key2": "val2"}}')
|
||||||
response = self.app.post('/v1/containers/',
|
response = self.app.post('/v1/containers/',
|
||||||
@ -293,7 +293,7 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
mock_search,
|
mock_search,
|
||||||
mock_container_create,
|
mock_container_create,
|
||||||
mock_container_show):
|
mock_container_show):
|
||||||
mock_container_create.side_effect = lambda x, y: y
|
mock_container_create.side_effect = lambda x, y, z: y
|
||||||
# Create a container with a command
|
# Create a container with a command
|
||||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||||
'"command": "env", "memory": "512",'
|
'"command": "env", "memory": "512",'
|
||||||
@ -327,7 +327,7 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
mock_search,
|
mock_search,
|
||||||
mock_container_create,
|
mock_container_create,
|
||||||
mock_container_show):
|
mock_container_show):
|
||||||
mock_container_create.side_effect = lambda x, y: y
|
mock_container_create.side_effect = lambda x, y, z: y
|
||||||
# Create a container with a command
|
# Create a container with a command
|
||||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||||
'"command": "env", "memory": "512",'
|
'"command": "env", "memory": "512",'
|
||||||
@ -361,7 +361,7 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
mock_search,
|
mock_search,
|
||||||
mock_container_create,
|
mock_container_create,
|
||||||
mock_container_show):
|
mock_container_show):
|
||||||
mock_container_create.side_effect = lambda x, y: y
|
mock_container_create.side_effect = lambda x, y, z: y
|
||||||
# Create a container with a command
|
# Create a container with a command
|
||||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||||
'"command": "env", "memory": "512",'
|
'"command": "env", "memory": "512",'
|
||||||
@ -394,7 +394,7 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
mock_search,
|
mock_search,
|
||||||
mock_container_create,
|
mock_container_create,
|
||||||
mock_container_show):
|
mock_container_show):
|
||||||
mock_container_create.side_effect = lambda x, y: y
|
mock_container_create.side_effect = lambda x, y, z: y
|
||||||
# Create a container with a command
|
# Create a container with a command
|
||||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||||
'"command": "env", "memory": "512",'
|
'"command": "env", "memory": "512",'
|
||||||
@ -428,7 +428,7 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
mock_search,
|
mock_search,
|
||||||
mock_container_create,
|
mock_container_create,
|
||||||
mock_container_show):
|
mock_container_show):
|
||||||
mock_container_create.side_effect = lambda x, y: y
|
mock_container_create.side_effect = lambda x, y, z: y
|
||||||
# Create a container with a command
|
# Create a container with a command
|
||||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||||
'"command": "env", "memory": "512",'
|
'"command": "env", "memory": "512",'
|
||||||
@ -1030,7 +1030,7 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
@patch('zun.compute.api.API.image_search')
|
@patch('zun.compute.api.API.image_search')
|
||||||
def test_create_container_resp_has_image_driver(self, mock_search,
|
def test_create_container_resp_has_image_driver(self, mock_search,
|
||||||
mock_container_create):
|
mock_container_create):
|
||||||
mock_container_create.side_effect = lambda x, y: y
|
mock_container_create.side_effect = lambda x, y, z: y
|
||||||
# Create a container with a command
|
# Create a container with a command
|
||||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||||
'"command": "env", "memory": "512",'
|
'"command": "env", "memory": "512",'
|
||||||
|
@ -29,7 +29,8 @@ class TestCPUFilter(base.TestCase):
|
|||||||
host = objects.ComputeNode(self.context)
|
host = objects.ComputeNode(self.context)
|
||||||
host.cpus = 8
|
host.cpus = 8
|
||||||
host.cpu_used = 0.0
|
host.cpu_used = 0.0
|
||||||
self.assertTrue(self.filt_cls.host_passes(host, container))
|
extra_spec = {}
|
||||||
|
self.assertTrue(self.filt_cls.host_passes(host, container, extra_spec))
|
||||||
|
|
||||||
def test_cpu_filter_fail(self):
|
def test_cpu_filter_fail(self):
|
||||||
self.filt_cls = cpu_filter.CPUFilter()
|
self.filt_cls = cpu_filter.CPUFilter()
|
||||||
@ -38,4 +39,6 @@ class TestCPUFilter(base.TestCase):
|
|||||||
host = objects.ComputeNode(self.context)
|
host = objects.ComputeNode(self.context)
|
||||||
host.cpus = 5
|
host.cpus = 5
|
||||||
host.cpu_used = 2.0
|
host.cpu_used = 2.0
|
||||||
self.assertFalse(self.filt_cls.host_passes(host, container))
|
extra_spec = {}
|
||||||
|
self.assertFalse(self.filt_cls.host_passes(host, container,
|
||||||
|
extra_spec))
|
||||||
|
@ -29,7 +29,8 @@ class TestRamFilter(base.TestCase):
|
|||||||
host = objects.ComputeNode(self.context)
|
host = objects.ComputeNode(self.context)
|
||||||
host.mem_total = 1024 * 128
|
host.mem_total = 1024 * 128
|
||||||
host.mem_used = 1024
|
host.mem_used = 1024
|
||||||
self.assertTrue(self.filt_cls.host_passes(host, container))
|
extra_spec = {}
|
||||||
|
self.assertTrue(self.filt_cls.host_passes(host, container, extra_spec))
|
||||||
|
|
||||||
def test_ram_filter_fail(self):
|
def test_ram_filter_fail(self):
|
||||||
self.filt_cls = ram_filter.RamFilter()
|
self.filt_cls = ram_filter.RamFilter()
|
||||||
@ -38,4 +39,6 @@ class TestRamFilter(base.TestCase):
|
|||||||
host = objects.ComputeNode(self.context)
|
host = objects.ComputeNode(self.context)
|
||||||
host.mem_total = 1024 * 128
|
host.mem_total = 1024 * 128
|
||||||
host.mem_used = 1024 * 127
|
host.mem_used = 1024 * 127
|
||||||
self.assertFalse(self.filt_cls.host_passes(host, container))
|
extra_spec = {}
|
||||||
|
self.assertFalse(self.filt_cls.host_passes(host, container,
|
||||||
|
extra_spec))
|
||||||
|
@ -29,8 +29,8 @@ class BaseFilterTestCase(base.TestCase):
|
|||||||
filter_obj_list = ['obj1', 'obj2', 'obj3']
|
filter_obj_list = ['obj1', 'obj2', 'obj3']
|
||||||
container = {}
|
container = {}
|
||||||
base_filter = base_filters.BaseFilter()
|
base_filter = base_filters.BaseFilter()
|
||||||
|
extra_spec = {}
|
||||||
result = base_filter.filter_all(filter_obj_list, container)
|
result = base_filter.filter_all(filter_obj_list, container, extra_spec)
|
||||||
self.assertTrue(inspect.isgenerator(result))
|
self.assertTrue(inspect.isgenerator(result))
|
||||||
self.assertEqual(['obj1', 'obj3'], list(result))
|
self.assertEqual(['obj1', 'obj3'], list(result))
|
||||||
|
|
||||||
|
@ -37,7 +37,9 @@ class ChanceSchedulerTestCase(base.TestCase):
|
|||||||
|
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
containers = [objects.Container(self.context, **test_container)]
|
containers = [objects.Container(self.context, **test_container)]
|
||||||
dests = self.driver_cls().select_destinations(self.context, containers)
|
extra_spec = {}
|
||||||
|
dests = self.driver_cls().select_destinations(self.context, containers,
|
||||||
|
extra_spec)
|
||||||
|
|
||||||
self.assertEqual(1, len(dests))
|
self.assertEqual(1, len(dests))
|
||||||
(host, node) = (dests[0]['host'], dests[0]['nodename'])
|
(host, node) = (dests[0]['host'], dests[0]['nodename'])
|
||||||
@ -56,6 +58,7 @@ class ChanceSchedulerTestCase(base.TestCase):
|
|||||||
mock_hosts_up.side_effect = _return_no_host
|
mock_hosts_up.side_effect = _return_no_host
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
containers = [objects.Container(self.context, **test_container)]
|
containers = [objects.Container(self.context, **test_container)]
|
||||||
|
extra_spec = {}
|
||||||
self.assertRaises(exception.NoValidHost,
|
self.assertRaises(exception.NoValidHost,
|
||||||
self.driver_cls().select_destinations, self.context,
|
self.driver_cls().select_destinations, self.context,
|
||||||
containers)
|
containers, extra_spec)
|
||||||
|
@ -42,6 +42,6 @@ class SchedulerClientTestCase(base.TestCase):
|
|||||||
@mock.patch('zun.scheduler.chance_scheduler.ChanceScheduler'
|
@mock.patch('zun.scheduler.chance_scheduler.ChanceScheduler'
|
||||||
'.select_destinations')
|
'.select_destinations')
|
||||||
def test_select_destinations(self, mock_select_destinations):
|
def test_select_destinations(self, mock_select_destinations):
|
||||||
fake_args = ['ctxt', 'fake_containers']
|
fake_args = ['ctxt', 'fake_containers', 'fake_extra_spec']
|
||||||
self.client.select_destinations(*fake_args)
|
self.client.select_destinations(*fake_args)
|
||||||
mock_select_destinations.assert_called_once_with(*fake_args)
|
mock_select_destinations.assert_called_once_with(*fake_args)
|
||||||
|
@ -82,7 +82,9 @@ class FilterSchedulerTestCase(base.TestCase):
|
|||||||
nodes = [node1, node2, node3, node4]
|
nodes = [node1, node2, node3, node4]
|
||||||
mock_compute_list.return_value = nodes
|
mock_compute_list.return_value = nodes
|
||||||
mock_random_choice.side_effect = [node3]
|
mock_random_choice.side_effect = [node3]
|
||||||
dests = self.driver.select_destinations(self.context, containers)
|
extra_spec = {}
|
||||||
|
dests = self.driver.select_destinations(self.context, containers,
|
||||||
|
extra_spec)
|
||||||
|
|
||||||
self.assertEqual(1, len(dests))
|
self.assertEqual(1, len(dests))
|
||||||
(host, node) = (dests[0]['host'], dests[0]['nodename'])
|
(host, node) = (dests[0]['host'], dests[0]['nodename'])
|
||||||
@ -107,6 +109,7 @@ class FilterSchedulerTestCase(base.TestCase):
|
|||||||
mock_list_by_binary.side_effect = _return_services
|
mock_list_by_binary.side_effect = _return_services
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
containers = [objects.Container(self.context, **test_container)]
|
containers = [objects.Container(self.context, **test_container)]
|
||||||
|
extra_spec = {}
|
||||||
self.assertRaises(exception.NoValidHost,
|
self.assertRaises(exception.NoValidHost,
|
||||||
self.driver.select_destinations, self.context,
|
self.driver.select_destinations, self.context,
|
||||||
containers)
|
containers, extra_spec)
|
||||||
|
Loading…
Reference in New Issue
Block a user