Give extended privileges to the container
Change-Id: Ifdeb97e92ac6d7b21aa91641c38c8af62d9d8d56 Implements: blueprint support-zun-create-privileged
This commit is contained in:
parent
6b80d2a59f
commit
416aa62b82
@ -361,6 +361,18 @@ class ContainersController(base.Controller):
|
|||||||
|
|
||||||
requested_volumes = self._build_requested_volumes(context, mounts)
|
requested_volumes = self._build_requested_volumes(context, mounts)
|
||||||
|
|
||||||
|
privileged = container_dict.pop('privileged', None)
|
||||||
|
if privileged is not None:
|
||||||
|
api_utils.version_check('privileged', '1.21')
|
||||||
|
policy.enforce(context, "container:create:privileged",
|
||||||
|
action="container:create:privileged")
|
||||||
|
try:
|
||||||
|
container_dict['privileged'] = strutils.bool_from_string(
|
||||||
|
privileged, strict=True)
|
||||||
|
except ValueError:
|
||||||
|
raise exception.InvalidValue(_('privileged values are: '
|
||||||
|
'true, false, True, False'))
|
||||||
|
|
||||||
# Valiadtion accepts 'None' so need to convert it to None
|
# Valiadtion accepts 'None' so need to convert it to None
|
||||||
if container_dict.get('image_driver'):
|
if container_dict.get('image_driver'):
|
||||||
container_dict['image_driver'] = api_utils.string_or_none(
|
container_dict['image_driver'] = api_utils.string_or_none(
|
||||||
|
@ -37,6 +37,7 @@ _legacy_container_properties = {
|
|||||||
'disk': parameter_types.disk,
|
'disk': parameter_types.disk,
|
||||||
'availability_zone': parameter_types.availability_zone,
|
'availability_zone': parameter_types.availability_zone,
|
||||||
'auto_heal': parameter_types.boolean,
|
'auto_heal': parameter_types.boolean,
|
||||||
|
'privileged': parameter_types.boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
legacy_container_create = {
|
legacy_container_create = {
|
||||||
|
@ -47,6 +47,7 @@ _basic_keys = (
|
|||||||
'hostname',
|
'hostname',
|
||||||
'disk',
|
'disk',
|
||||||
'auto_heal',
|
'auto_heal',
|
||||||
|
'privileged',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,10 +53,11 @@ REST_API_VERSION_HISTORY = """REST API Version History:
|
|||||||
* 1.18 - Modify the response of network list
|
* 1.18 - Modify the response of network list
|
||||||
* 1.19 - Intoduce container resize API
|
* 1.19 - Intoduce container resize API
|
||||||
* 1.20 - Convert type of 'command' from string to list
|
* 1.20 - Convert type of 'command' from string to list
|
||||||
|
* 1.21 - Add support privileged
|
||||||
"""
|
"""
|
||||||
|
|
||||||
BASE_VER = '1.1'
|
BASE_VER = '1.1'
|
||||||
CURRENT_MAX_VER = '1.20'
|
CURRENT_MAX_VER = '1.21'
|
||||||
|
|
||||||
|
|
||||||
class Version(object):
|
class Version(object):
|
||||||
|
@ -172,3 +172,8 @@ user documentation.
|
|||||||
----
|
----
|
||||||
|
|
||||||
Convert type of 'command' from string to list
|
Convert type of 'command' from string to list
|
||||||
|
|
||||||
|
1.21
|
||||||
|
----
|
||||||
|
|
||||||
|
Support privileged container
|
||||||
|
@ -15,6 +15,7 @@ from oslo_policy import policy
|
|||||||
ROLE_ADMIN = 'role:admin'
|
ROLE_ADMIN = 'role:admin'
|
||||||
RULE_ADMIN_OR_OWNER = 'is_admin:True or project_id:%(project_id)s'
|
RULE_ADMIN_OR_OWNER = 'is_admin:True or project_id:%(project_id)s'
|
||||||
RULE_ADMIN_API = 'rule:context_is_admin'
|
RULE_ADMIN_API = 'rule:context_is_admin'
|
||||||
|
RULE_DENY_EVERYBODY = 'rule:deny_everybody'
|
||||||
|
|
||||||
rules = [
|
rules = [
|
||||||
policy.RuleDefault(
|
policy.RuleDefault(
|
||||||
@ -28,7 +29,11 @@ rules = [
|
|||||||
policy.RuleDefault(
|
policy.RuleDefault(
|
||||||
name='admin_api',
|
name='admin_api',
|
||||||
check_str=RULE_ADMIN_API
|
check_str=RULE_ADMIN_API
|
||||||
)
|
),
|
||||||
|
policy.RuleDefault(
|
||||||
|
name="deny_everybody",
|
||||||
|
check_str="!",
|
||||||
|
description="Default rule for deny everybody."),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,6 +39,19 @@ rules = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=CONTAINER % 'create:privileged',
|
||||||
|
check_str=base.RULE_DENY_EVERYBODY,
|
||||||
|
description=('Create a new privileged container.'
|
||||||
|
'Warning: the privileged container has a big security '
|
||||||
|
'risk so be caution if you want to enable this feature'),
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/containers',
|
||||||
|
'method': 'POST'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=CONTAINER % 'delete',
|
name=CONTAINER % 'delete',
|
||||||
check_str=base.RULE_ADMIN_OR_OWNER,
|
check_str=base.RULE_ADMIN_OR_OWNER,
|
||||||
|
@ -271,6 +271,7 @@ class DockerDriver(driver.ContainerDriver):
|
|||||||
runtime = container.runtime or CONF.container_runtime
|
runtime = container.runtime or CONF.container_runtime
|
||||||
|
|
||||||
host_config = {}
|
host_config = {}
|
||||||
|
host_config['privileged'] = container.privileged
|
||||||
host_config['runtime'] = runtime
|
host_config['runtime'] = runtime
|
||||||
host_config['binds'] = binds
|
host_config['binds'] = binds
|
||||||
kwargs['volumes'] = [b['bind'] for b in binds.values()]
|
kwargs['volumes'] = [b['bind'] for b in binds.values()]
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
# 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 privileged to container
|
||||||
|
|
||||||
|
Revision ID: 105626c4f972
|
||||||
|
Revises: 3e80bbfd8da7
|
||||||
|
Create Date: 2018-07-26 15:05:10.567715
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '105626c4f972'
|
||||||
|
down_revision = '3e80bbfd8da7'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
op.add_column('container',
|
||||||
|
sa.Column('privileged', sa.Boolean(),
|
||||||
|
nullable=True))
|
@ -170,6 +170,7 @@ class Container(Base):
|
|||||||
capsule_id = Column(Integer,
|
capsule_id = Column(Integer,
|
||||||
ForeignKey('capsule.id', ondelete='CASCADE'))
|
ForeignKey('capsule.id', ondelete='CASCADE'))
|
||||||
started_at = Column(DateTime)
|
started_at = Column(DateTime)
|
||||||
|
privileged = Column(Boolean, default=False)
|
||||||
|
|
||||||
|
|
||||||
class VolumeMapping(Base):
|
class VolumeMapping(Base):
|
||||||
|
@ -63,7 +63,8 @@ class Container(base.ZunPersistentObject, base.ZunObject):
|
|||||||
# Version 1.31: Add 'started_at' attribute
|
# Version 1.31: Add 'started_at' attribute
|
||||||
# Version 1.32: Add 'exec_instances' attribute
|
# Version 1.32: Add 'exec_instances' attribute
|
||||||
# Version 1.33: Change 'command' to List type
|
# Version 1.33: Change 'command' to List type
|
||||||
VERSION = '1.33'
|
# Version 1.34: Add privileged to container
|
||||||
|
VERSION = '1.34'
|
||||||
|
|
||||||
fields = {
|
fields = {
|
||||||
'id': fields.IntegerField(),
|
'id': fields.IntegerField(),
|
||||||
@ -105,6 +106,7 @@ class Container(base.ZunPersistentObject, base.ZunObject):
|
|||||||
'started_at': fields.DateTimeField(tzinfo_aware=False, nullable=True),
|
'started_at': fields.DateTimeField(tzinfo_aware=False, nullable=True),
|
||||||
'exec_instances': fields.ListOfObjectsField('ExecInstance',
|
'exec_instances': fields.ListOfObjectsField('ExecInstance',
|
||||||
nullable=True),
|
nullable=True),
|
||||||
|
'privileged': fields.BooleanField(nullable=True),
|
||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -26,7 +26,7 @@ from zun.tests.unit.db import base
|
|||||||
|
|
||||||
|
|
||||||
PATH_PREFIX = '/v1'
|
PATH_PREFIX = '/v1'
|
||||||
CURRENT_VERSION = "container 1.20"
|
CURRENT_VERSION = "container 1.21"
|
||||||
|
|
||||||
|
|
||||||
class FunctionalTest(base.DbTestCase):
|
class FunctionalTest(base.DbTestCase):
|
||||||
|
@ -28,7 +28,7 @@ class TestRootController(api_base.FunctionalTest):
|
|||||||
'default_version':
|
'default_version':
|
||||||
{'id': 'v1',
|
{'id': 'v1',
|
||||||
'links': [{'href': 'http://localhost/v1/', 'rel': 'self'}],
|
'links': [{'href': 'http://localhost/v1/', 'rel': 'self'}],
|
||||||
'max_version': '1.20',
|
'max_version': '1.21',
|
||||||
'min_version': '1.1',
|
'min_version': '1.1',
|
||||||
'status': 'CURRENT'},
|
'status': 'CURRENT'},
|
||||||
'description': 'Zun is an OpenStack project which '
|
'description': 'Zun is an OpenStack project which '
|
||||||
@ -37,7 +37,7 @@ class TestRootController(api_base.FunctionalTest):
|
|||||||
'versions': [{'id': 'v1',
|
'versions': [{'id': 'v1',
|
||||||
'links': [{'href': 'http://localhost/v1/',
|
'links': [{'href': 'http://localhost/v1/',
|
||||||
'rel': 'self'}],
|
'rel': 'self'}],
|
||||||
'max_version': '1.20',
|
'max_version': '1.21',
|
||||||
'min_version': '1.1',
|
'min_version': '1.1',
|
||||||
'status': 'CURRENT'}]}
|
'status': 'CURRENT'}]}
|
||||||
|
|
||||||
|
@ -135,6 +135,7 @@ class TestDockerDriver(base.DriverTestCase):
|
|||||||
host_config['binds'] = {}
|
host_config['binds'] = {}
|
||||||
host_config['network_mode'] = 'fake-network'
|
host_config['network_mode'] = 'fake-network'
|
||||||
host_config['storage_opt'] = {'size': '20G'}
|
host_config['storage_opt'] = {'size': '20G'}
|
||||||
|
host_config['privileged'] = False
|
||||||
self.mock_docker.create_host_config.assert_called_once_with(
|
self.mock_docker.create_host_config.assert_called_once_with(
|
||||||
**host_config)
|
**host_config)
|
||||||
|
|
||||||
@ -201,6 +202,7 @@ class TestDockerDriver(base.DriverTestCase):
|
|||||||
host_config['binds'] = {}
|
host_config['binds'] = {}
|
||||||
host_config['network_mode'] = 'fake-network'
|
host_config['network_mode'] = 'fake-network'
|
||||||
host_config['storage_opt'] = {'size': '20G'}
|
host_config['storage_opt'] = {'size': '20G'}
|
||||||
|
host_config['privileged'] = False
|
||||||
self.mock_docker.create_host_config.assert_called_once_with(
|
self.mock_docker.create_host_config.assert_called_once_with(
|
||||||
**host_config)
|
**host_config)
|
||||||
|
|
||||||
@ -265,6 +267,7 @@ class TestDockerDriver(base.DriverTestCase):
|
|||||||
host_config['binds'] = {}
|
host_config['binds'] = {}
|
||||||
host_config['network_mode'] = 'fake-network'
|
host_config['network_mode'] = 'fake-network'
|
||||||
host_config['storage_opt'] = {'size': '20G'}
|
host_config['storage_opt'] = {'size': '20G'}
|
||||||
|
host_config['privileged'] = False
|
||||||
self.mock_docker.create_host_config.assert_called_once_with(
|
self.mock_docker.create_host_config.assert_called_once_with(
|
||||||
**host_config)
|
**host_config)
|
||||||
|
|
||||||
|
@ -102,6 +102,7 @@ def get_test_container(**kwargs):
|
|||||||
'auto_heal': kwargs.get('auto_heal', False),
|
'auto_heal': kwargs.get('auto_heal', False),
|
||||||
'capsule_id': kwargs.get('capsule_id', 42),
|
'capsule_id': kwargs.get('capsule_id', 42),
|
||||||
'started_at': kwargs.get('started_at'),
|
'started_at': kwargs.get('started_at'),
|
||||||
|
'privileged': kwargs.get('privileged', False),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -344,7 +344,7 @@ class TestObject(test_base.TestCase, _TestObject):
|
|||||||
# For more information on object version testing, read
|
# For more information on object version testing, read
|
||||||
# https://docs.openstack.org/zun/latest/
|
# https://docs.openstack.org/zun/latest/
|
||||||
object_data = {
|
object_data = {
|
||||||
'Container': '1.33-5eac0a995f25329ca566fdddde45c759',
|
'Container': '1.34-22c46c6ae571b83295c3dac74fe8772f',
|
||||||
'VolumeMapping': '1.1-50df6202f7846a136a91444c38eba841',
|
'VolumeMapping': '1.1-50df6202f7846a136a91444c38eba841',
|
||||||
'Image': '1.1-330e6205c80b99b59717e1cfc6a79935',
|
'Image': '1.1-330e6205c80b99b59717e1cfc6a79935',
|
||||||
'MyObj': '1.0-34c4b1aadefd177b13f9a2f894cc23cd',
|
'MyObj': '1.0-34c4b1aadefd177b13f9a2f894cc23cd',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user