Merge "Give extended privileges to the container"

This commit is contained in:
Zuul 2018-08-06 05:21:17 +00:00 committed by Gerrit Code Review
commit 99816f5d23
16 changed files with 88 additions and 7 deletions

View File

@ -361,6 +361,18 @@ class ContainersController(base.Controller):
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
if container_dict.get('image_driver'):
container_dict['image_driver'] = api_utils.string_or_none(

View File

@ -37,6 +37,7 @@ _legacy_container_properties = {
'disk': parameter_types.disk,
'availability_zone': parameter_types.availability_zone,
'auto_heal': parameter_types.boolean,
'privileged': parameter_types.boolean,
}
legacy_container_create = {

View File

@ -47,6 +47,7 @@ _basic_keys = (
'hostname',
'disk',
'auto_heal',
'privileged',
)

View File

@ -53,10 +53,11 @@ REST_API_VERSION_HISTORY = """REST API Version History:
* 1.18 - Modify the response of network list
* 1.19 - Intoduce container resize API
* 1.20 - Convert type of 'command' from string to list
* 1.21 - Add support privileged
"""
BASE_VER = '1.1'
CURRENT_MAX_VER = '1.20'
CURRENT_MAX_VER = '1.21'
class Version(object):

View File

@ -172,3 +172,8 @@ user documentation.
----
Convert type of 'command' from string to list
1.21
----
Support privileged container

View File

@ -15,6 +15,7 @@ from oslo_policy import policy
ROLE_ADMIN = 'role:admin'
RULE_ADMIN_OR_OWNER = 'is_admin:True or project_id:%(project_id)s'
RULE_ADMIN_API = 'rule:context_is_admin'
RULE_DENY_EVERYBODY = 'rule:deny_everybody'
rules = [
policy.RuleDefault(
@ -28,7 +29,11 @@ rules = [
policy.RuleDefault(
name='admin_api',
check_str=RULE_ADMIN_API
)
),
policy.RuleDefault(
name="deny_everybody",
check_str="!",
description="Default rule for deny everybody."),
]

View File

@ -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(
name=CONTAINER % 'delete',
check_str=base.RULE_ADMIN_OR_OWNER,

View File

@ -271,6 +271,7 @@ class DockerDriver(driver.ContainerDriver):
runtime = container.runtime or CONF.container_runtime
host_config = {}
host_config['privileged'] = container.privileged
host_config['runtime'] = runtime
host_config['binds'] = binds
kwargs['volumes'] = [b['bind'] for b in binds.values()]

View File

@ -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))

View File

@ -170,6 +170,7 @@ class Container(Base):
capsule_id = Column(Integer,
ForeignKey('capsule.id', ondelete='CASCADE'))
started_at = Column(DateTime)
privileged = Column(Boolean, default=False)
class VolumeMapping(Base):

View File

@ -63,7 +63,8 @@ class Container(base.ZunPersistentObject, base.ZunObject):
# Version 1.31: Add 'started_at' attribute
# Version 1.32: Add 'exec_instances' attribute
# Version 1.33: Change 'command' to List type
VERSION = '1.33'
# Version 1.34: Add privileged to container
VERSION = '1.34'
fields = {
'id': fields.IntegerField(),
@ -105,6 +106,7 @@ class Container(base.ZunPersistentObject, base.ZunObject):
'started_at': fields.DateTimeField(tzinfo_aware=False, nullable=True),
'exec_instances': fields.ListOfObjectsField('ExecInstance',
nullable=True),
'privileged': fields.BooleanField(nullable=True),
}
@staticmethod

View File

@ -26,7 +26,7 @@ from zun.tests.unit.db import base
PATH_PREFIX = '/v1'
CURRENT_VERSION = "container 1.20"
CURRENT_VERSION = "container 1.21"
class FunctionalTest(base.DbTestCase):

View File

@ -28,7 +28,7 @@ class TestRootController(api_base.FunctionalTest):
'default_version':
{'id': 'v1',
'links': [{'href': 'http://localhost/v1/', 'rel': 'self'}],
'max_version': '1.20',
'max_version': '1.21',
'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.20',
'max_version': '1.21',
'min_version': '1.1',
'status': 'CURRENT'}]}

View File

@ -135,6 +135,7 @@ class TestDockerDriver(base.DriverTestCase):
host_config['binds'] = {}
host_config['network_mode'] = 'fake-network'
host_config['storage_opt'] = {'size': '20G'}
host_config['privileged'] = False
self.mock_docker.create_host_config.assert_called_once_with(
**host_config)
@ -201,6 +202,7 @@ class TestDockerDriver(base.DriverTestCase):
host_config['binds'] = {}
host_config['network_mode'] = 'fake-network'
host_config['storage_opt'] = {'size': '20G'}
host_config['privileged'] = False
self.mock_docker.create_host_config.assert_called_once_with(
**host_config)
@ -265,6 +267,7 @@ class TestDockerDriver(base.DriverTestCase):
host_config['binds'] = {}
host_config['network_mode'] = 'fake-network'
host_config['storage_opt'] = {'size': '20G'}
host_config['privileged'] = False
self.mock_docker.create_host_config.assert_called_once_with(
**host_config)

View File

@ -102,6 +102,7 @@ def get_test_container(**kwargs):
'auto_heal': kwargs.get('auto_heal', False),
'capsule_id': kwargs.get('capsule_id', 42),
'started_at': kwargs.get('started_at'),
'privileged': kwargs.get('privileged', False),
}

View File

@ -344,7 +344,7 @@ class TestObject(test_base.TestCase, _TestObject):
# For more information on object version testing, read
# https://docs.openstack.org/zun/latest/
object_data = {
'Container': '1.33-5eac0a995f25329ca566fdddde45c759',
'Container': '1.34-22c46c6ae571b83295c3dac74fe8772f',
'VolumeMapping': '1.1-50df6202f7846a136a91444c38eba841',
'Image': '1.1-330e6205c80b99b59717e1cfc6a79935',
'MyObj': '1.0-34c4b1aadefd177b13f9a2f894cc23cd',