Move get_available_network to API layer
In before, if there is no network available, users don't know what is wrong until the container is scheduled to a compute node and fail. This commit moves the searching of neutron net to zun-api so that users will receive an error response earlier if the request is invalid. Change-Id: Ic9fd47c6e4aff4131ebaad73a3bed0f51eeb118c Related-Bug: #1702581
This commit is contained in:
@@ -33,6 +33,7 @@ from zun.common import name_generator
|
||||
from zun.common import policy
|
||||
from zun.common import utils
|
||||
from zun.common import validation
|
||||
from zun.network import neutron
|
||||
from zun import objects
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@@ -234,7 +235,8 @@ class ContainersController(base.Controller):
|
||||
'"false", True, False, "True" and "False"')
|
||||
raise exception.InvalidValue(msg)
|
||||
|
||||
requested_networks = container_dict.get('nets', [])
|
||||
nets = container_dict.get('nets', [])
|
||||
requested_networks = self._build_requested_networks(context, nets)
|
||||
|
||||
# Valiadtion accepts 'None' so need to convert it to None
|
||||
if container_dict.get('image_driver'):
|
||||
@@ -296,6 +298,20 @@ class ContainersController(base.Controller):
|
||||
pecan.response.status = 202
|
||||
return view.format_container(pecan.request.host_url, new_container)
|
||||
|
||||
def _build_requested_networks(self, context, nets):
|
||||
requested_networks = []
|
||||
if not nets:
|
||||
# Find an available neutron net and create docker network by
|
||||
# wrapping the neutron net.
|
||||
neutron_api = neutron.NeutronAPI(context)
|
||||
neutron_net = neutron_api.get_available_network()
|
||||
requested_networks.append({'network': neutron_net['id'],
|
||||
'port': '',
|
||||
'v4-fixed-ip': '',
|
||||
'v6-fixed-ip': ''})
|
||||
|
||||
return requested_networks
|
||||
|
||||
def _check_security_group(self, context, security_group, container):
|
||||
if security_group.get("uuid"):
|
||||
security_group_id = security_group.get("uuid")
|
||||
|
||||
@@ -147,7 +147,8 @@ class Manager(periodic_task.PeriodicTasks):
|
||||
rt = self._get_resource_tracker()
|
||||
with rt.container_claim(context, container, container.host,
|
||||
limits):
|
||||
container = self.driver.create(context, container, image)
|
||||
container = self.driver.create(context, container, image,
|
||||
requested_networks)
|
||||
self._update_task_state(context, container, None)
|
||||
return container
|
||||
except exception.DockerError as e:
|
||||
|
||||
@@ -20,7 +20,6 @@ from docker import errors
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import timeutils
|
||||
|
||||
from zun.common import clients
|
||||
from zun.common import consts
|
||||
from zun.common import exception
|
||||
from zun.common.i18n import _
|
||||
@@ -106,7 +105,7 @@ class DockerDriver(driver.ContainerDriver):
|
||||
with docker_utils.docker_client() as docker:
|
||||
return docker.images(repo, quiet)
|
||||
|
||||
def create(self, context, container, image, requested_networks=None):
|
||||
def create(self, context, container, image, requested_networks):
|
||||
sandbox_id = container.get_sandbox_id()
|
||||
network_standalone = False if sandbox_id else True
|
||||
|
||||
@@ -116,14 +115,9 @@ class DockerDriver(driver.ContainerDriver):
|
||||
image = container.image
|
||||
LOG.debug('Creating container with image %(image)s name %(name)s',
|
||||
{'image': image, 'name': name})
|
||||
if requested_networks is None:
|
||||
if network_standalone:
|
||||
network = self._provision_network(context, container,
|
||||
network_api)
|
||||
requested_networks = [{'network': network['Name'],
|
||||
'port': '',
|
||||
'v4-fixed-ip': '',
|
||||
'v6-fixed-ip': ''}]
|
||||
if network_standalone:
|
||||
self._provision_network(context, network_api,
|
||||
requested_networks)
|
||||
|
||||
kwargs = {
|
||||
'name': self.get_container_name(container),
|
||||
@@ -170,16 +164,10 @@ class DockerDriver(driver.ContainerDriver):
|
||||
container.save(context)
|
||||
return container
|
||||
|
||||
def _provision_network(self, context, container, network_api):
|
||||
LOG.debug('Creating networks for container with image %(image)s '
|
||||
'name %(name)s',
|
||||
{'image': container.image, 'name': container.name})
|
||||
# Find an available neutron net and create docker network by
|
||||
# wrapping the neutron net.
|
||||
neutron_net = self._get_available_network(context)
|
||||
network = self._get_or_create_docker_network(
|
||||
context, network_api, neutron_net['id'])
|
||||
return network
|
||||
def _provision_network(self, context, network_api, requested_networks):
|
||||
for rq_network in requested_networks:
|
||||
self._get_or_create_docker_network(
|
||||
context, network_api, rq_network['network'])
|
||||
|
||||
def _setup_network_for_container(self, context, container,
|
||||
requested_networks, network_api):
|
||||
@@ -191,10 +179,11 @@ class DockerDriver(driver.ContainerDriver):
|
||||
network_api.disconnect_container_from_network(container, 'bridge')
|
||||
addresses = {}
|
||||
for network in requested_networks:
|
||||
network_name = network['network']
|
||||
docker_net_name = self._get_docker_network_name(
|
||||
context, network['network'])
|
||||
addrs = network_api.connect_container_to_network(
|
||||
container, network_name, security_groups=security_group_ids)
|
||||
addresses[network_name] = addrs
|
||||
container, docker_net_name, security_groups=security_group_ids)
|
||||
addresses[docker_net_name] = addrs
|
||||
|
||||
return addresses
|
||||
|
||||
@@ -641,17 +630,11 @@ class DockerDriver(driver.ContainerDriver):
|
||||
value = six.text_type(value)
|
||||
return value.encode('utf-8')
|
||||
|
||||
def create_sandbox(self, context, container, image='kubernetes/pause',
|
||||
requested_networks=None):
|
||||
def create_sandbox(self, context, container, requested_networks,
|
||||
image='kubernetes/pause'):
|
||||
with docker_utils.docker_client() as docker:
|
||||
network_api = zun_network.api(context=context, docker_api=docker)
|
||||
if not requested_networks:
|
||||
network = self._provision_network(context, container,
|
||||
network_api)
|
||||
requested_networks = [{'network': network['Name'],
|
||||
'port': '',
|
||||
'v4-fixed-ip': '',
|
||||
'v6-fixed-ip': ''}]
|
||||
self._provision_network(context, network_api, requested_networks)
|
||||
name = self.get_sandbox_name(container)
|
||||
sandbox = docker.create_container(image, name=name,
|
||||
hostname=name[:63])
|
||||
@@ -668,21 +651,12 @@ class DockerDriver(driver.ContainerDriver):
|
||||
docker.start(sandbox['Id'])
|
||||
return sandbox['Id']
|
||||
|
||||
def _get_available_network(self, context):
|
||||
neutron = clients.OpenStackClients(context).neutron()
|
||||
search_opts = {'tenant_id': context.project_id, 'shared': False}
|
||||
nets = neutron.list_networks(**search_opts).get('networks', [])
|
||||
if not nets:
|
||||
raise exception.ZunException(_(
|
||||
"There is no neutron network available"))
|
||||
nets.sort(key=lambda x: x['created_at'])
|
||||
return nets[0]
|
||||
|
||||
def _get_or_create_docker_network(self, context, network_api,
|
||||
neutron_net_id):
|
||||
# Append project_id to the network name to avoid name collision
|
||||
# across projects.
|
||||
docker_net_name = neutron_net_id + '-' + context.project_id
|
||||
docker_net_name = self._get_docker_network_name(context,
|
||||
neutron_net_id)
|
||||
docker_networks = network_api.list_networks(names=[docker_net_name])
|
||||
if not docker_networks:
|
||||
network_api.create_network(neutron_net_id=neutron_net_id,
|
||||
@@ -690,7 +664,10 @@ class DockerDriver(driver.ContainerDriver):
|
||||
docker_networks = network_api.list_networks(
|
||||
names=[docker_net_name])
|
||||
|
||||
return docker_networks[0]
|
||||
def _get_docker_network_name(self, context, neutron_net_id):
|
||||
# Append project_id to the network name to avoid name collision
|
||||
# across projects.
|
||||
return neutron_net_id + '-' + context.project_id
|
||||
|
||||
def delete_sandbox(self, context, container):
|
||||
sandbox_id = container.get_sandbox_id()
|
||||
|
||||
@@ -60,7 +60,7 @@ def load_container_driver(container_driver=None):
|
||||
class ContainerDriver(object):
|
||||
"""Base class for container drivers."""
|
||||
|
||||
def create(self, context, container, sandbox_name=None):
|
||||
def create(self, context, container, **kwargs):
|
||||
"""Create a container."""
|
||||
raise NotImplementedError()
|
||||
|
||||
@@ -149,7 +149,7 @@ class ContainerDriver(object):
|
||||
"""Display stats of the container."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def create_sandbox(self, context, container, **kwargs):
|
||||
def create_sandbox(self, context, *args, **kwargs):
|
||||
"""Create a sandbox."""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
31
zun/network/neutron.py
Normal file
31
zun/network/neutron.py
Normal file
@@ -0,0 +1,31 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from zun.common import clients
|
||||
from zun.common import exception
|
||||
from zun.common.i18n import _
|
||||
|
||||
|
||||
class NeutronAPI(object):
|
||||
|
||||
def __init__(self, context):
|
||||
self.context = context
|
||||
|
||||
def get_available_network(self):
|
||||
neutron = clients.OpenStackClients(self.context).neutron()
|
||||
search_opts = {'tenant_id': self.context.project_id, 'shared': False}
|
||||
nets = neutron.list_networks(**search_opts).get('networks', [])
|
||||
if not nets:
|
||||
raise exception.Conflict(_(
|
||||
"There is no neutron network available"))
|
||||
nets.sort(key=lambda x: x['created_at'])
|
||||
return nets[0]
|
||||
@@ -25,9 +25,11 @@ from zun.tests.unit.objects import utils as obj_utils
|
||||
|
||||
|
||||
class TestContainerController(api_base.FunctionalTest):
|
||||
@patch('zun.network.neutron.NeutronAPI.get_available_network')
|
||||
@patch('zun.compute.api.API.container_run')
|
||||
@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_neutron_get_network):
|
||||
mock_container_run.side_effect = lambda x, y, z, v: y
|
||||
|
||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||
@@ -39,6 +41,7 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
|
||||
self.assertEqual(202, response.status_int)
|
||||
self.assertTrue(mock_container_run.called)
|
||||
mock_neutron_get_network.assert_called_once()
|
||||
|
||||
@patch('zun.compute.api.API.container_run')
|
||||
@patch('zun.compute.api.API.image_search')
|
||||
@@ -52,10 +55,12 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
self.app.post('/v1/containers?run=xyz', params=params,
|
||||
content_type='application/json')
|
||||
|
||||
@patch('zun.network.neutron.NeutronAPI.get_available_network')
|
||||
@patch('zun.compute.rpcapi.API.container_run')
|
||||
@patch('zun.compute.rpcapi.API.image_search')
|
||||
def test_run_container_with_false(self, mock_search,
|
||||
mock_container_run):
|
||||
mock_container_run,
|
||||
mock_neutron_get_network):
|
||||
mock_container_run.side_effect = lambda x, y, z, v: y
|
||||
|
||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||
@@ -66,6 +71,7 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
content_type='application/json')
|
||||
self.assertEqual(202, response.status_int)
|
||||
self.assertFalse(mock_container_run.called)
|
||||
mock_neutron_get_network.assert_called_once()
|
||||
|
||||
@patch('zun.compute.rpcapi.API.container_run')
|
||||
@patch('zun.compute.rpcapi.API.image_search')
|
||||
@@ -79,9 +85,11 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
params=params, content_type='application/json')
|
||||
self.assertTrue(mock_container_run.not_called)
|
||||
|
||||
@patch('zun.network.neutron.NeutronAPI.get_available_network')
|
||||
@patch('zun.compute.api.API.container_create')
|
||||
@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_neutron_get_network):
|
||||
mock_container_create.side_effect = lambda x, y, z, v: y
|
||||
|
||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||
@@ -93,6 +101,7 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
|
||||
self.assertEqual(202, response.status_int)
|
||||
self.assertTrue(mock_container_create.called)
|
||||
mock_neutron_get_network.assert_called_once()
|
||||
|
||||
@patch('zun.compute.api.API.container_create')
|
||||
def test_create_container_image_not_specified(self, mock_container_create):
|
||||
@@ -107,10 +116,12 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
content_type='application/json')
|
||||
self.assertTrue(mock_container_create.not_called)
|
||||
|
||||
@patch('zun.network.neutron.NeutronAPI.get_available_network')
|
||||
@patch('zun.compute.api.API.container_create')
|
||||
@patch('zun.compute.api.API.image_search')
|
||||
def test_create_container_image_not_found(self, mock_search,
|
||||
mock_container_create):
|
||||
mock_container_create,
|
||||
mock_neutron_get_network):
|
||||
mock_container_create.side_effect = lambda x, y, z, v: y
|
||||
mock_search.side_effect = exception.ImageNotFound()
|
||||
|
||||
@@ -119,11 +130,14 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertEqual(404, response.status_int)
|
||||
self.assertFalse(mock_container_create.called)
|
||||
mock_neutron_get_network.assert_called_once()
|
||||
|
||||
@patch('zun.network.neutron.NeutronAPI.get_available_network')
|
||||
@patch('zun.compute.api.API.container_create')
|
||||
@patch('zun.compute.api.API.image_search')
|
||||
def test_create_container_set_project_id_and_user_id(
|
||||
self, mock_search, mock_container_create):
|
||||
self, mock_search, mock_container_create,
|
||||
mock_neutron_get_network):
|
||||
def _create_side_effect(cnxt, container, extra_spec, networks):
|
||||
self.assertEqual(self.context.project_id, container.project_id)
|
||||
self.assertEqual(self.context.user_id, container.user_id)
|
||||
@@ -136,11 +150,14 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
self.app.post('/v1/containers/',
|
||||
params=params,
|
||||
content_type='application/json')
|
||||
mock_neutron_get_network.assert_called_once()
|
||||
|
||||
@patch('zun.network.neutron.NeutronAPI.get_available_network')
|
||||
@patch('zun.compute.api.API.container_create')
|
||||
@patch('zun.compute.api.API.image_search')
|
||||
def test_create_container_resp_has_status_reason(self, mock_search,
|
||||
mock_container_create):
|
||||
mock_container_create,
|
||||
mock_neutron_get_network):
|
||||
mock_container_create.side_effect = lambda x, y, z, v: y
|
||||
# Create a container with a command
|
||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||
@@ -151,7 +168,9 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
content_type='application/json')
|
||||
self.assertEqual(202, response.status_int)
|
||||
self.assertIn('status_reason', response.json.keys())
|
||||
mock_neutron_get_network.assert_called_once()
|
||||
|
||||
@patch('zun.network.neutron.NeutronAPI.get_available_network')
|
||||
@patch('zun.compute.api.API.container_show')
|
||||
@patch('zun.compute.api.API.container_create')
|
||||
@patch('zun.compute.api.API.container_delete')
|
||||
@@ -159,7 +178,8 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
def test_create_container_with_command(self, mock_search,
|
||||
mock_container_delete,
|
||||
mock_container_create,
|
||||
mock_container_show):
|
||||
mock_container_show,
|
||||
mock_neutron_get_network):
|
||||
mock_container_create.side_effect = lambda x, y, z, v: y
|
||||
# Create a container with a command
|
||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||
@@ -200,13 +220,16 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
c = response.json['containers']
|
||||
self.assertEqual(0, len(c))
|
||||
self.assertTrue(mock_container_create.called)
|
||||
mock_neutron_get_network.assert_called_once()
|
||||
|
||||
@patch('zun.network.neutron.NeutronAPI.get_available_network')
|
||||
@patch('zun.compute.api.API.container_show')
|
||||
@patch('zun.compute.api.API.container_create')
|
||||
@patch('zun.compute.api.API.image_search')
|
||||
def test_create_container_without_memory(self, mock_search,
|
||||
mock_container_create,
|
||||
mock_container_show):
|
||||
mock_container_show,
|
||||
mock_neutron_get_network):
|
||||
mock_container_create.side_effect = lambda x, y, z, v: y
|
||||
# Create a container with a command
|
||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||
@@ -231,13 +254,16 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
self.assertIsNone(c.get('memory'))
|
||||
self.assertEqual({"key1": "val1", "key2": "val2"},
|
||||
c.get('environment'))
|
||||
mock_neutron_get_network.assert_called_once()
|
||||
|
||||
@patch('zun.network.neutron.NeutronAPI.get_available_network')
|
||||
@patch('zun.compute.api.API.container_show')
|
||||
@patch('zun.compute.api.API.container_create')
|
||||
@patch('zun.compute.api.API.image_search')
|
||||
def test_create_container_without_environment(self, mock_search,
|
||||
mock_container_create,
|
||||
mock_container_show):
|
||||
mock_container_show,
|
||||
mock_neutron_get_network):
|
||||
mock_container_create.side_effect = lambda x, y, z, v: y
|
||||
# Create a container with a command
|
||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||
@@ -260,13 +286,16 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
self.assertEqual('Stopped', c.get('status'))
|
||||
self.assertEqual('512M', c.get('memory'))
|
||||
self.assertEqual({}, c.get('environment'))
|
||||
mock_neutron_get_network.assert_called_once()
|
||||
|
||||
@patch('zun.network.neutron.NeutronAPI.get_available_network')
|
||||
@patch('zun.compute.api.API.container_show')
|
||||
@patch('zun.compute.api.API.container_create')
|
||||
@patch('zun.compute.api.API.image_search')
|
||||
def test_create_container_without_name(self, mock_search,
|
||||
mock_container_create,
|
||||
mock_container_show):
|
||||
mock_container_show,
|
||||
mock_neutron_get_network):
|
||||
# No name param
|
||||
mock_container_create.side_effect = lambda x, y, z, v: y
|
||||
params = ('{"image": "ubuntu", "command": "env", "memory": "512",'
|
||||
@@ -290,7 +319,9 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
self.assertEqual('512M', c.get('memory'))
|
||||
self.assertEqual({"key1": "val1", "key2": "val2"},
|
||||
c.get('environment'))
|
||||
mock_neutron_get_network.assert_called_once()
|
||||
|
||||
@patch('zun.network.neutron.NeutronAPI.get_available_network')
|
||||
@patch('zun.compute.rpcapi.API.container_show')
|
||||
@patch('zun.compute.rpcapi.API.container_create')
|
||||
@patch('zun.compute.api.API.image_search')
|
||||
@@ -298,7 +329,8 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
self,
|
||||
mock_search,
|
||||
mock_container_create,
|
||||
mock_container_show):
|
||||
mock_container_show,
|
||||
mock_neutron_get_network):
|
||||
mock_container_create.side_effect = lambda x, y, z, v: y
|
||||
# Create a container with a command
|
||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||
@@ -324,7 +356,9 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
self.assertEqual('512M', c.get('memory'))
|
||||
self.assertEqual({"Name": "no", "MaximumRetryCount": "0"},
|
||||
c.get('restart_policy'))
|
||||
mock_neutron_get_network.assert_called_once()
|
||||
|
||||
@patch('zun.network.neutron.NeutronAPI.get_available_network')
|
||||
@patch('zun.compute.rpcapi.API.container_show')
|
||||
@patch('zun.compute.rpcapi.API.container_create')
|
||||
@patch('zun.compute.api.API.image_search')
|
||||
@@ -332,7 +366,8 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
self,
|
||||
mock_search,
|
||||
mock_container_create,
|
||||
mock_container_show):
|
||||
mock_container_show,
|
||||
mock_neutron_get_network):
|
||||
mock_container_create.side_effect = lambda x, y, z, v: y
|
||||
# Create a container with a command
|
||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||
@@ -358,7 +393,9 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
self.assertEqual('512M', c.get('memory'))
|
||||
self.assertEqual({"Name": "no", "MaximumRetryCount": "0"},
|
||||
c.get('restart_policy'))
|
||||
mock_neutron_get_network.assert_called_once()
|
||||
|
||||
@patch('zun.network.neutron.NeutronAPI.get_available_network')
|
||||
@patch('zun.compute.rpcapi.API.container_show')
|
||||
@patch('zun.compute.rpcapi.API.container_create')
|
||||
@patch('zun.compute.api.API.image_search')
|
||||
@@ -366,7 +403,8 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
self,
|
||||
mock_search,
|
||||
mock_container_create,
|
||||
mock_container_show):
|
||||
mock_container_show,
|
||||
mock_neutron_get_network):
|
||||
mock_container_create.side_effect = lambda x, y, z, v: y
|
||||
# Create a container with a command
|
||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||
@@ -391,7 +429,9 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
self.assertEqual('512M', c.get('memory'))
|
||||
self.assertEqual({"Name": "no", "MaximumRetryCount": "0"},
|
||||
c.get('restart_policy'))
|
||||
mock_neutron_get_network.assert_called_once()
|
||||
|
||||
@patch('zun.network.neutron.NeutronAPI.get_available_network')
|
||||
@patch('zun.compute.rpcapi.API.container_show')
|
||||
@patch('zun.compute.rpcapi.API.container_create')
|
||||
@patch('zun.compute.api.API.image_search')
|
||||
@@ -399,7 +439,8 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
self,
|
||||
mock_search,
|
||||
mock_container_create,
|
||||
mock_container_show):
|
||||
mock_container_show,
|
||||
mock_neutron_get_network):
|
||||
mock_container_create.side_effect = lambda x, y, z, v: y
|
||||
# Create a container with a command
|
||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||
@@ -425,7 +466,9 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
self.assertEqual('512M', c.get('memory'))
|
||||
self.assertEqual({"Name": "unless-stopped", "MaximumRetryCount": "0"},
|
||||
c.get('restart_policy'))
|
||||
mock_neutron_get_network.assert_called_once()
|
||||
|
||||
@patch('zun.network.neutron.NeutronAPI.get_available_network')
|
||||
@patch('zun.compute.rpcapi.API.container_show')
|
||||
@patch('zun.compute.rpcapi.API.container_create')
|
||||
@patch('zun.compute.api.API.image_search')
|
||||
@@ -433,7 +476,8 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
self,
|
||||
mock_search,
|
||||
mock_container_create,
|
||||
mock_container_show):
|
||||
mock_container_show,
|
||||
mock_neutron_get_network):
|
||||
mock_container_create.side_effect = lambda x, y, z, v: y
|
||||
# Create a container with a command
|
||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||
@@ -446,6 +490,7 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
params=params,
|
||||
content_type='application/json')
|
||||
self.assertTrue(mock_container_create.not_called)
|
||||
mock_neutron_get_network.assert_called_once()
|
||||
|
||||
@patch('zun.compute.rpcapi.API.container_create')
|
||||
@patch('zun.compute.rpcapi.API.image_search')
|
||||
@@ -1099,10 +1144,12 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
container_uuid, params)
|
||||
self.assertFalse(mock_container_kill.called)
|
||||
|
||||
@patch('zun.network.neutron.NeutronAPI.get_available_network')
|
||||
@patch('zun.compute.api.API.container_create')
|
||||
@patch('zun.compute.api.API.image_search')
|
||||
def test_create_container_resp_has_image_driver(self, mock_search,
|
||||
mock_container_create):
|
||||
mock_container_create,
|
||||
mock_neutron_get_network):
|
||||
mock_container_create.side_effect = lambda x, y, z, v: y
|
||||
# Create a container with a command
|
||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||
|
||||
@@ -67,7 +67,8 @@ class TestManager(base.TestCase):
|
||||
mock_save.assert_called_with(self.context)
|
||||
mock_pull.assert_any_call(self.context, container.image, 'latest',
|
||||
'always', 'glance')
|
||||
mock_create.assert_called_once_with(self.context, container, image)
|
||||
mock_create.assert_called_once_with(self.context, container, image,
|
||||
networks)
|
||||
|
||||
@mock.patch.object(Container, 'save')
|
||||
@mock.patch('zun.image.driver.pull_image')
|
||||
@@ -145,7 +146,8 @@ class TestManager(base.TestCase):
|
||||
mock_save.assert_called_with(self.context)
|
||||
mock_pull.assert_any_call(self.context, container.image, 'latest',
|
||||
'always', 'glance')
|
||||
mock_create.assert_called_once_with(self.context, container, image)
|
||||
mock_create.assert_called_once_with(self.context, container, image,
|
||||
networks)
|
||||
mock_start.assert_called_once_with(self.context, container)
|
||||
|
||||
@mock.patch.object(Container, 'save')
|
||||
@@ -233,7 +235,7 @@ class TestManager(base.TestCase):
|
||||
mock_pull.assert_any_call(self.context, container.image, 'latest',
|
||||
'always', 'glance')
|
||||
mock_create.assert_called_once_with(
|
||||
self.context, container, {'name': 'nginx', 'path': None})
|
||||
self.context, container, {'name': 'nginx', 'path': None}, networks)
|
||||
|
||||
@mock.patch.object(compute_node_tracker.ComputeNodeTracker,
|
||||
'remove_usage_from_container')
|
||||
|
||||
@@ -92,9 +92,8 @@ class TestDockerDriver(base.DriverTestCase):
|
||||
return_value={'Id': 'val1', 'key1': 'val2'})
|
||||
image = {'path': ''}
|
||||
mock_container = self.mock_default_container
|
||||
with mock.patch.object(self.driver, '_get_available_network'):
|
||||
result_container = self.driver.create(self.context, mock_container,
|
||||
image, None)
|
||||
result_container = self.driver.create(self.context, mock_container,
|
||||
image, [])
|
||||
host_config = {}
|
||||
host_config['mem_limit'] = '512m'
|
||||
host_config['cpu_quota'] = 100000
|
||||
@@ -334,10 +333,9 @@ class TestDockerDriver(base.DriverTestCase):
|
||||
return_value={'Id': 'val1', 'key1': 'val2'})
|
||||
mock_container = mock.MagicMock()
|
||||
requested_networks = []
|
||||
with mock.patch.object(self.driver, '_get_available_network'):
|
||||
result_sandbox_id = self.driver.create_sandbox(
|
||||
self.context, mock_container, 'kubernetes/pause',
|
||||
requested_networks=requested_networks)
|
||||
result_sandbox_id = self.driver.create_sandbox(
|
||||
self.context, mock_container, requested_networks,
|
||||
'kubernetes/pause')
|
||||
self.mock_docker.create_container.assert_called_once_with(
|
||||
'kubernetes/pause', name=sandbox_name, hostname=sandbox_name)
|
||||
self.assertEqual(result_sandbox_id, 'val1')
|
||||
@@ -354,11 +352,10 @@ class TestDockerDriver(base.DriverTestCase):
|
||||
self.mock_docker.create_container = mock.Mock(
|
||||
return_value={'Id': 'val1', 'key1': 'val2'})
|
||||
mock_container = mock.MagicMock()
|
||||
with mock.patch.object(self.driver, '_get_available_network'):
|
||||
requested_networks = []
|
||||
result_sandbox_id = self.driver.create_sandbox(
|
||||
self.context, mock_container, 'kubernetes/pause',
|
||||
requested_networks=requested_networks)
|
||||
requested_networks = []
|
||||
result_sandbox_id = self.driver.create_sandbox(
|
||||
self.context, mock_container, requested_networks,
|
||||
'kubernetes/pause')
|
||||
self.mock_docker.create_container.assert_called_once_with(
|
||||
'kubernetes/pause', name=sandbox_name, hostname=sandbox_name[:63])
|
||||
self.assertEqual(result_sandbox_id, 'val1')
|
||||
|
||||
Reference in New Issue
Block a user