Bring hostname option back
Zun already had this option before, but had to remove due to the Conflict Exception (relate to sandbox). At this time, we made sandbox optional. Therefore, if use_sandbox option is False, we can use hostname option. If it is True, raise the Exception to let user know. This option will help us to implement the blueprint internal-dns-resolution. Change-Id: I2f8826fc66e94c0d4452ff32e3bc17700ef6b668 Closes-Bug: #1716849
This commit is contained in:
parent
179225b5ae
commit
2057b668bf
@ -49,6 +49,7 @@ Request
|
||||
- security_groups: security_groups
|
||||
- nets: nets
|
||||
- runtime: runtime
|
||||
- hostname: hostname
|
||||
|
||||
Request Example
|
||||
----------------
|
||||
|
@ -134,9 +134,8 @@ host_list:
|
||||
type: array
|
||||
hostname:
|
||||
description: |
|
||||
The host where container is running.
|
||||
The hostname of container.
|
||||
in: body
|
||||
required: true
|
||||
type: string
|
||||
id_s:
|
||||
description: |
|
||||
|
@ -27,5 +27,6 @@
|
||||
"port": "890699a9-4690-4bd6-8b70-3a9c1be77ecb"
|
||||
}
|
||||
],
|
||||
"runtime": "runc"
|
||||
"runtime": "runc",
|
||||
"hostname": "testhost"
|
||||
}
|
||||
|
@ -34,5 +34,6 @@
|
||||
"command": "/bin/sh -c 'echo hello'",
|
||||
"cpu": 2.0,
|
||||
"interactive": false,
|
||||
"runtime": "runc"
|
||||
"runtime": "runc",
|
||||
"hostname": "testhost"
|
||||
}
|
||||
|
@ -252,12 +252,9 @@ class ContainersController(base.Controller):
|
||||
msg = _('Auto_remove value are true or false')
|
||||
raise exception.InvalidValue(msg)
|
||||
else:
|
||||
msg = _('Invalid param auto_remove because current request '
|
||||
'version is %(req_version)s. Auto_remove is only '
|
||||
'supported from version %(min_version)s') % \
|
||||
{'req_version': req_version,
|
||||
'min_version': min_version}
|
||||
raise exception.InvalidParam(msg)
|
||||
raise exception.InvalidParamInVersion(param='auto_remove',
|
||||
req_version=req_version,
|
||||
min_version=min_version)
|
||||
|
||||
runtime = container_dict.pop('runtime', None)
|
||||
if runtime is not None:
|
||||
@ -266,12 +263,26 @@ class ContainersController(base.Controller):
|
||||
if req_version >= min_version:
|
||||
container_dict['runtime'] = runtime
|
||||
else:
|
||||
msg = _('Invalid param runtime because current request '
|
||||
'version is %(req_version)s. `runtime` is only '
|
||||
'supported from version %(min_version)s') % \
|
||||
{'req_version': req_version,
|
||||
'min_version': min_version}
|
||||
raise exception.InvalidParam(msg)
|
||||
raise exception.InvalidParamInVersion(param='runtime',
|
||||
req_version=req_version,
|
||||
min_version=min_version)
|
||||
|
||||
hostname = container_dict.pop('hostname', None)
|
||||
if hostname is not None:
|
||||
if CONF.use_sandbox:
|
||||
raise exception.ConflictOptions(
|
||||
'Cannot set container\'s hostname when use sandbox. '
|
||||
'Because with sandbox, network_mode will be set, it '
|
||||
'is incompatible with legacy network (hostname).')
|
||||
req_version = pecan.request.version
|
||||
min_version = versions.Version('', '', '', '1.9')
|
||||
container_dict['hostname'] = hostname
|
||||
if req_version >= min_version:
|
||||
container_dict['hostname'] = hostname
|
||||
else:
|
||||
raise exception.InvalidParamInVersion(param='hostname',
|
||||
req_version=req_version,
|
||||
min_version=min_version)
|
||||
|
||||
nets = container_dict.get('nets', [])
|
||||
requested_networks = self._build_requested_networks(context, nets)
|
||||
|
@ -31,7 +31,8 @@ _container_properties = {
|
||||
'security_groups': parameter_types.security_groups,
|
||||
'hints': parameter_types.hints,
|
||||
'nets': parameter_types.nets,
|
||||
'runtime': parameter_types.runtime
|
||||
'runtime': parameter_types.runtime,
|
||||
'hostname': parameter_types.hostname,
|
||||
}
|
||||
|
||||
container_create = {
|
||||
|
@ -40,7 +40,8 @@ _basic_keys = (
|
||||
'image_driver',
|
||||
'security_groups',
|
||||
'auto_remove',
|
||||
'runtime'
|
||||
'runtime',
|
||||
'hostname',
|
||||
)
|
||||
|
||||
|
||||
|
@ -41,10 +41,11 @@ REST_API_VERSION_HISTORY = """REST API Version History:
|
||||
* 1.6 - Support detach network from a container
|
||||
* 1.7 - Disallow non-admin users to force delete containers
|
||||
* 1.8 - Support attach a network to a container
|
||||
* 1.9 - Add support set container's hostname
|
||||
"""
|
||||
|
||||
BASE_VER = '1.1'
|
||||
CURRENT_MAX_VER = '1.8'
|
||||
CURRENT_MAX_VER = '1.9'
|
||||
|
||||
|
||||
class Version(object):
|
||||
|
@ -76,3 +76,9 @@ user documentation.
|
||||
|
||||
Add attach a network to a container.
|
||||
Users can use this api to attach a neutron network to a container.
|
||||
|
||||
1.9
|
||||
---
|
||||
Add a new attribute 'hostname' to the request to create a container.
|
||||
Users can use this attribute to specify container's hostname.
|
||||
|
||||
|
@ -313,6 +313,10 @@ class Conflict(ZunException):
|
||||
code = 409
|
||||
|
||||
|
||||
class ConflictOptions(Conflict):
|
||||
message = _('Conflicting options.')
|
||||
|
||||
|
||||
class InvalidState(Conflict):
|
||||
message = _("Invalid resource state.")
|
||||
|
||||
@ -323,8 +327,10 @@ class InvalidParameterValue(Invalid):
|
||||
message = _("%(err)s")
|
||||
|
||||
|
||||
class InvalidParam(Invalid):
|
||||
message = _('Invalid param %(param)s')
|
||||
class InvalidParamInVersion(Invalid):
|
||||
message = _('Invalid param %(param)s because current request '
|
||||
'version is %(req_version)s. %(param)s is only '
|
||||
'supported from version %(min_version)s')
|
||||
|
||||
|
||||
class PatchError(Invalid):
|
||||
|
@ -122,6 +122,12 @@ environment = {
|
||||
},
|
||||
}
|
||||
|
||||
hostname = {
|
||||
'type': ['string', 'null'],
|
||||
'minLength': 2,
|
||||
'maxLength': 63
|
||||
}
|
||||
|
||||
runtime = {
|
||||
'type': ['string', 'null'],
|
||||
}
|
||||
|
@ -132,6 +132,7 @@ class DockerDriver(driver.ContainerDriver):
|
||||
'labels': container.labels,
|
||||
'tty': container.interactive,
|
||||
'stdin_open': container.interactive,
|
||||
'hostname': container.hostname,
|
||||
}
|
||||
|
||||
runtime = container.runtime if container.runtime\
|
||||
@ -396,8 +397,9 @@ class DockerDriver(driver.ContainerDriver):
|
||||
container.command = command_str
|
||||
|
||||
def _populate_hostname_and_ports(self, container, config):
|
||||
# populate hostname
|
||||
container.hostname = config.get('Hostname')
|
||||
# populate hostname only when container.hostname wasn't set
|
||||
if container.hostname is None:
|
||||
container.hostname = config.get('Hostname')
|
||||
# populate ports
|
||||
ports = []
|
||||
exposed_ports = config.get('ExposedPorts')
|
||||
|
@ -17,7 +17,7 @@ import webtest
|
||||
from zun.api import app
|
||||
from zun.tests.unit.api import base as api_base
|
||||
|
||||
CURRENT_VERSION = "container 1.8"
|
||||
CURRENT_VERSION = "container 1.9"
|
||||
|
||||
|
||||
class TestRootController(api_base.FunctionalTest):
|
||||
@ -27,7 +27,7 @@ class TestRootController(api_base.FunctionalTest):
|
||||
'default_version':
|
||||
{'id': 'v1',
|
||||
'links': [{'href': 'http://localhost/v1/', 'rel': 'self'}],
|
||||
'max_version': '1.8',
|
||||
'max_version': '1.9',
|
||||
'min_version': '1.1',
|
||||
'status': 'CURRENT'},
|
||||
'description': 'Zun is an OpenStack project which '
|
||||
@ -35,7 +35,7 @@ class TestRootController(api_base.FunctionalTest):
|
||||
'versions': [{'id': 'v1',
|
||||
'links': [{'href': 'http://localhost/v1/',
|
||||
'rel': 'self'}],
|
||||
'max_version': '1.8',
|
||||
'max_version': '1.9',
|
||||
'min_version': '1.1',
|
||||
'status': 'CURRENT'}]}
|
||||
|
||||
|
@ -23,7 +23,7 @@ from zun.tests.unit.api import base as api_base
|
||||
from zun.tests.unit.db import utils
|
||||
from zun.tests.unit.objects import utils as obj_utils
|
||||
|
||||
CURRENT_VERSION = "container 1.8"
|
||||
CURRENT_VERSION = "container 1.9"
|
||||
|
||||
|
||||
class TestContainerController(api_base.FunctionalTest):
|
||||
@ -108,6 +108,41 @@ class TestContainerController(api_base.FunctionalTest):
|
||||
params=params, content_type='application/json',
|
||||
headers=api_version)
|
||||
|
||||
def test_run_container_with_hostname_wrong_api_version(self):
|
||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||
'"command": "env", "memory": "512",'
|
||||
'"environment": {"key1": "val1", "key2": "val2"},'
|
||||
'"hostname": "testhost"}')
|
||||
headers = {"OpenStack-API-Version": "container 1.7",
|
||||
"Accept": "application/json"}
|
||||
with self.assertRaisesRegex(AppError,
|
||||
"Invalid param hostname"):
|
||||
self.app.post('/v1/containers?run=true',
|
||||
params=params, content_type='application/json',
|
||||
headers=headers)
|
||||
|
||||
@patch('zun.network.neutron.NeutronAPI.get_available_network')
|
||||
@patch('zun.compute.api.API.container_create')
|
||||
@patch('zun.compute.api.API.image_search')
|
||||
def test_run_container_with_hostname_successfully(
|
||||
self, mock_search,
|
||||
mock_container_create,
|
||||
mock_neutron_get_network):
|
||||
params = ('{"name": "MyDocker", "image": "ubuntu",'
|
||||
'"command": "env", "memory": "512",'
|
||||
'"environment": {"key1": "val1", "key2": "val2"},'
|
||||
'"hostname": "testhost"}')
|
||||
api_version = {"OpenStack-API-Version": CURRENT_VERSION}
|
||||
response = self.app.post('/v1/containers?run=true',
|
||||
params=params,
|
||||
content_type='application/json',
|
||||
headers=api_version)
|
||||
|
||||
self.assertEqual(202, response.status_int)
|
||||
self.assertTrue(mock_container_create.called)
|
||||
self.assertTrue(mock_container_create.call_args[1]['run'] is True)
|
||||
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')
|
||||
|
@ -111,6 +111,7 @@ class TestDockerDriver(base.DriverTestCase):
|
||||
'host_config': {'Id1': 'val1', 'key2': 'val2'},
|
||||
'stdin_open': True,
|
||||
'tty': True,
|
||||
'hostname': 'testhost',
|
||||
}
|
||||
self.mock_docker.create_container.assert_called_once_with(
|
||||
image['repo'] + ":" + image['tag'], **kwargs)
|
||||
|
Loading…
x
Reference in New Issue
Block a user