diff --git a/.zuul.yaml b/.zuul.yaml index d59aa51c8..5816b04b2 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -29,7 +29,7 @@ test-config: $TEMPEST_CONFIG: container_service: - min_microversion: 1.39 + min_microversion: '1.40' post-config: $ZUN_CONF: docker: diff --git a/api-ref/source/containers.inc b/api-ref/source/containers.inc index 8dddecd90..c0f3c1736 100644 --- a/api-ref/source/containers.inc +++ b/api-ref/source/containers.inc @@ -62,6 +62,7 @@ Request - healthcheck: healthcheck-request - exposed_ports: exposed_ports - host: requested_host + - entrypoint: entrypoint-request Request Example ---------------- @@ -106,6 +107,7 @@ Response - disk: disk - registry_id: registry_id - cpu_policy: cpu_policy + - entrypoint: entrypoint Response Example @@ -184,6 +186,7 @@ Response - disk: disk - registry_id: registry_id - cpu_policy: cpu_policy + - entrypoint: entrypoint Response Example ---------------- @@ -253,6 +256,7 @@ Response - disk: disk - registry_id: registry_id - cpu_policy: cpu_policy + - entrypoint: entrypoint Response Example ---------------- @@ -460,6 +464,7 @@ Return new container with updated attributes. - disk: disk - registry_id: registry_id - cpu_policy: cpu_policy + - entrypoint: entrypoint Response Example ---------------- @@ -757,6 +762,7 @@ Response - disk: disk - registry_id: registry_id - cpu_policy: cpu_policy + - entrypoint: entrypoint Response Example ---------------- diff --git a/api-ref/source/parameters.yaml b/api-ref/source/parameters.yaml index be9e667e7..bc2e37ba1 100644 --- a/api-ref/source/parameters.yaml +++ b/api-ref/source/parameters.yaml @@ -829,6 +829,18 @@ enable_cpu_pinning: in: body required: true type: object +entrypoint: + description: | + The entrypoint which overwrites the default ENTRYPOINT of the image. + in: body + required: true + type: string +entrypoint-request: + description: | + The entrypoint which overwrites the default ENTRYPOINT of the image. + in: body + required: false + type: string environment: description: | The environment variables to set in the container. diff --git a/releasenotes/notes/support-entrypoint-option-5127ab5044025380.yaml b/releasenotes/notes/support-entrypoint-option-5127ab5044025380.yaml new file mode 100644 index 000000000..4c7800f48 --- /dev/null +++ b/releasenotes/notes/support-entrypoint-option-5127ab5044025380.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Add support for specifying entrypoint with the container + which is used to overwrite the entrypoint of the docker image. diff --git a/zun/api/controllers/v1/containers.py b/zun/api/controllers/v1/containers.py index 0b6a4e145..3dc0850e5 100644 --- a/zun/api/controllers/v1/containers.py +++ b/zun/api/controllers/v1/containers.py @@ -285,7 +285,7 @@ class ContainersController(base.Controller): def post(self, run=False, **container_dict): return self._do_post(run, **container_dict) - @base.Controller.api_version("1.39") # noqa + @base.Controller.api_version("1.39", "1.39") # noqa @pecan.expose('json') @api_utils.enforce_content_types(['application/json']) @exception.wrap_pecan_controller_exception @@ -294,6 +294,15 @@ class ContainersController(base.Controller): def post(self, run=False, **container_dict): return self._do_post(run, **container_dict) + @base.Controller.api_version("1.40") # noqa + @pecan.expose('json') + @api_utils.enforce_content_types(['application/json']) + @exception.wrap_pecan_controller_exception + @validation.validate_query_param(pecan.request, schema.query_param_create) + @validation.validated(schema.container_create_v140) + def post(self, run=False, **container_dict): + return self._do_post(run, **container_dict) + def _do_post(self, run=False, **container_dict): """Create or run a new container. diff --git a/zun/api/controllers/v1/schemas/containers.py b/zun/api/controllers/v1/schemas/containers.py index 523a0d13b..74022b0de 100644 --- a/zun/api/controllers/v1/schemas/containers.py +++ b/zun/api/controllers/v1/schemas/containers.py @@ -73,6 +73,10 @@ container_create = { container_create_v139 = copy.deepcopy(container_create) container_create_v139['properties']['host'] = parameter_types.hostname +# Add entrypoint in container +container_create_v140 = copy.deepcopy(container_create_v139) +container_create_v140['properties']['entrypoint'] = parameter_types.entrypoint + query_param_rename = { 'type': 'object', 'properties': { diff --git a/zun/api/controllers/v1/schemas/parameter_types.py b/zun/api/controllers/v1/schemas/parameter_types.py index 04db0f805..370b6dd1b 100644 --- a/zun/api/controllers/v1/schemas/parameter_types.py +++ b/zun/api/controllers/v1/schemas/parameter_types.py @@ -85,6 +85,10 @@ command_list = { 'type': ['array', 'null'] } +entrypoint = { + 'type': ['string', 'null'] +} + auto_remove = { 'type': ['boolean', 'null'] } diff --git a/zun/api/controllers/v1/views/containers_view.py b/zun/api/controllers/v1/views/containers_view.py index 02c82c478..634dd6f04 100644 --- a/zun/api/controllers/v1/views/containers_view.py +++ b/zun/api/controllers/v1/views/containers_view.py @@ -51,6 +51,7 @@ _basic_keys = ( 'healthcheck', 'cpu_policy', 'registry_id', + 'entrypoint', ) diff --git a/zun/api/controllers/versions.py b/zun/api/controllers/versions.py index c8976ec67..dc7945428 100644 --- a/zun/api/controllers/versions.py +++ b/zun/api/controllers/versions.py @@ -72,10 +72,11 @@ REST_API_VERSION_HISTORY = """REST API Version History: * 1.37 - Add 'tty' and 'stdin' to capsule * 1.38 - Add 'annotations' to capsule * 1.39 - Support requested host on container creation + * 1.40 - Add support for specifying entrypoint of the image """ BASE_VER = '1.1' -CURRENT_MAX_VER = '1.39' +CURRENT_MAX_VER = '1.40' class Version(object): diff --git a/zun/api/rest_api_version_history.rst b/zun/api/rest_api_version_history.rst index a535c25ce..3a232e2ca 100644 --- a/zun/api/rest_api_version_history.rst +++ b/zun/api/rest_api_version_history.rst @@ -299,3 +299,9 @@ user documentation. Add 'host' parameter on POST /v1/containers. This field is used to request a host to run the container. + +1.40 +---- + + Add 'entrypoint' parameter on POST /v1/containers. + This field is used to overwrite the default ENTRYPOINT of the image. diff --git a/zun/container/docker/driver.py b/zun/container/docker/driver.py index a15a80703..625af239b 100644 --- a/zun/container/docker/driver.py +++ b/zun/container/docker/driver.py @@ -265,6 +265,7 @@ class DockerDriver(driver.BaseDriver, driver.ContainerDriver, 'tty': container.tty, 'stdin_open': container.interactive, 'hostname': container.hostname, + 'entrypoint': container.entrypoint, } if not self._is_runtime_supported(): @@ -1253,6 +1254,7 @@ class DockerDriver(driver.BaseDriver, driver.ContainerDriver, 'labels': container.labels, 'tty': container.tty, 'stdin_open': container.interactive, + 'entrypoint': container.entrypoint, } host_config = {} diff --git a/zun/db/sqlalchemy/alembic/versions/f979327df44b_add_entrypoint_to_container.py b/zun/db/sqlalchemy/alembic/versions/f979327df44b_add_entrypoint_to_container.py new file mode 100644 index 000000000..fb4f6189f --- /dev/null +++ b/zun/db/sqlalchemy/alembic/versions/f979327df44b_add_entrypoint_to_container.py @@ -0,0 +1,40 @@ +# 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. + +"""add-entrypoint-to-container + +Revision ID: f979327df44b +Revises: 74c97dca93d0 +Create Date: 2020-03-30 03:19:01.080873 + +""" + +# revision identifiers, used by Alembic. +revision = 'f979327df44b' +down_revision = '74c97dca93d0' +branch_labels = None +depends_on = None + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('container', schema=None) as batch_op: + batch_op.add_column( + sa.Column( + 'entrypoint', + sa.String(length=255), + nullable=True)) + + # ### end Alembic commands ### diff --git a/zun/db/sqlalchemy/models.py b/zun/db/sqlalchemy/models.py index 2b6491e39..4d0e3abc8 100644 --- a/zun/db/sqlalchemy/models.py +++ b/zun/db/sqlalchemy/models.py @@ -184,6 +184,7 @@ class Container(Base): server_default=str(consts.TYPE_CONTAINER)) annotations = Column(MediumText()) cni_metadata = Column(MediumText()) + entrypoint = Column(String(255)) class VolumeMapping(Base): diff --git a/zun/objects/container.py b/zun/objects/container.py index 1d1df738e..2ef913a51 100644 --- a/zun/objects/container.py +++ b/zun/objects/container.py @@ -107,6 +107,7 @@ class ContainerBase(base.ZunPersistentObject, base.ZunObject): 'registry': fields.ObjectField("Registry", nullable=True), 'annotations': z_fields.JsonField(nullable=True), 'cni_metadata': z_fields.JsonField(nullable=True), + 'entrypoint': fields.StringField(nullable=True), } # should be redefined in subclasses @@ -421,7 +422,8 @@ class Container(ContainerBase): # Version 1.41: Add 'annotations' attributes # Version 1.42: Remove 'meta' attribute # Version 1.43: Add 'cni_metadata' attribute - VERSION = '1.43' + # Version 1.44: Add 'entrypoint' attribute + VERSION = '1.44' container_type = consts.TYPE_CONTAINER diff --git a/zun/tests/unit/api/base.py b/zun/tests/unit/api/base.py index 2d91eca17..0a3e93e5b 100644 --- a/zun/tests/unit/api/base.py +++ b/zun/tests/unit/api/base.py @@ -28,7 +28,7 @@ from zun.tests.unit.db import base PATH_PREFIX = '/v1' -CURRENT_VERSION = "container 1.39" +CURRENT_VERSION = "container 1.40" class FunctionalTest(base.DbTestCase): diff --git a/zun/tests/unit/api/controllers/test_root.py b/zun/tests/unit/api/controllers/test_root.py index 4de42692d..55d7a99aa 100644 --- a/zun/tests/unit/api/controllers/test_root.py +++ b/zun/tests/unit/api/controllers/test_root.py @@ -28,7 +28,7 @@ class TestRootController(api_base.FunctionalTest): 'default_version': {'id': 'v1', 'links': [{'href': 'http://localhost/v1/', 'rel': 'self'}], - 'max_version': '1.39', + 'max_version': '1.40', 'min_version': '1.1', 'status': 'CURRENT'}, 'description': 'Zun is an OpenStack project which ' @@ -37,7 +37,7 @@ class TestRootController(api_base.FunctionalTest): 'versions': [{'id': 'v1', 'links': [{'href': 'http://localhost/v1/', 'rel': 'self'}], - 'max_version': '1.39', + 'max_version': '1.40', 'min_version': '1.1', 'status': 'CURRENT'}]} diff --git a/zun/tests/unit/container/docker/test_docker_driver.py b/zun/tests/unit/container/docker/test_docker_driver.py index 56e42fc5a..f60f3e17b 100644 --- a/zun/tests/unit/container/docker/test_docker_driver.py +++ b/zun/tests/unit/container/docker/test_docker_driver.py @@ -150,6 +150,7 @@ class TestDockerDriver(base.DriverTestCase): 'name': '%sea8e2a25-2901-438d-8157-de7ffd68d051' % consts.NAME_PREFIX, 'command': ['fake_command'], + 'entrypoint': 'fake_entrypoint', 'environment': {'key1': 'val1', 'key2': 'val2'}, 'working_dir': '/home/ubuntu', 'labels': {'key1': 'val1', 'key2': 'val2'}, @@ -223,6 +224,7 @@ class TestDockerDriver(base.DriverTestCase): 'name': '%sea8e2a25-2901-438d-8157-de7ffd68d051' % consts.NAME_PREFIX, 'command': ['fake_command'], + 'entrypoint': 'fake_entrypoint', 'environment': {'key1': 'val1', 'key2': 'val2'}, 'working_dir': '/home/ubuntu', 'labels': {'key1': 'val1', 'key2': 'val2'}, @@ -294,6 +296,7 @@ class TestDockerDriver(base.DriverTestCase): 'name': '%sea8e2a25-2901-438d-8157-de7ffd68d051' % consts.NAME_PREFIX, 'command': ['fake_command'], + 'entrypoint': 'fake_entrypoint', 'environment': {'key1': 'val1', 'key2': 'val2'}, 'working_dir': '/home/ubuntu', 'labels': {'key1': 'val1', 'key2': 'val2'}, diff --git a/zun/tests/unit/db/utils.py b/zun/tests/unit/db/utils.py index 57e82e32b..3f1ed030f 100644 --- a/zun/tests/unit/db/utils.py +++ b/zun/tests/unit/db/utils.py @@ -103,6 +103,7 @@ def get_test_container(**kwargs): 'capsule_id': kwargs.get('capsule_id', 33), 'annotations': kwargs.get('annotations', '{"key": "val"}'), 'cni_metadata': kwargs.get('cni_metadata', '{"key": "val"}'), + 'entrypoint': kwargs.get('entrypoint', 'fake_entrypoint'), } diff --git a/zun/tests/unit/objects/test_objects.py b/zun/tests/unit/objects/test_objects.py index 794c9e396..4f4f31b51 100644 --- a/zun/tests/unit/objects/test_objects.py +++ b/zun/tests/unit/objects/test_objects.py @@ -344,10 +344,10 @@ class TestObject(test_base.TestCase, _TestObject): # For more information on object version testing, read # https://docs.openstack.org/zun/latest/ object_data = { - 'Capsule': '1.4-66281771e65f95e6e79c604b59b7e3a3', - 'CapsuleContainer': '1.4-ab82355ff19b201307c59a5b17ecc32d', - 'CapsuleInitContainer': '1.4-ab82355ff19b201307c59a5b17ecc32d', - 'Container': '1.43-bdd6b22fc8d6d1bb8518ed807e8e7b90', + 'Capsule': '1.4-85456b38adcac18d823e86e19c71bdf0', + 'CapsuleContainer': '1.4-0ca5d5683474b1288a9e3bcea7e4f1d3', + 'CapsuleInitContainer': '1.4-0ca5d5683474b1288a9e3bcea7e4f1d3', + 'Container': '1.44-9734f84e52fc04abd0a7e206f398e15b', 'Cpuset': '1.0-06c4e6335683c18b87e2e54080f8c341', 'Volume': '1.0-034768f2f5c5e89acb5ee45c6d3f3403', 'VolumeMapping': '1.5-57febc66526185a75a744637e7a387c7',