Beispiel #1
0
 def transform(key, value):
     if key not in _basic_keys:
         return
     # strip the key if it is not allowed by policy
     policy_action = policies.CAPSULE % ('get:%s' % key)
     if not context.can(policy_action, fatal=False, might_not_exist=True):
         return
     if key == 'uuid':
         yield ('uuid', value)
         yield ('links', [link.make_link(
             'self', url, 'capsules', value),
             link.make_link(
                 'bookmark', url,
                 'capsules', value,
                 bookmark=True)])
         if legacy_api_version:
             yield('volumes_info', {})
             yield('containers_uuids', [])
             yield('init_containers_uuids', [])
             yield('capsule_version', '')
     elif key == 'init_containers':
         containers = []
         for c in capsule.init_containers:
             container = containers_view.format_container(
                 context, None, c)
             containers.append(container)
         yield ('init_containers', containers)
     elif key == 'containers':
         containers = []
         for c in capsule.containers:
             container = containers_view.format_container(
                 context, None, c)
             containers.append(container)
         yield ('containers', containers)
     elif key == 'name':
         if legacy_api_version:
             yield('meta_name', value)
         else:
             yield(key, value)
     elif key == 'labels':
         if legacy_api_version:
             yield('meta_labels', value)
         else:
             yield(key, value)
     elif key == 'restart_policy':
         if legacy_api_version:
             if 'Name' in value:
                 yield(key, value['Name'])
         else:
             yield(key, value)
     else:
         yield (key, value)
Beispiel #2
0
    def patch(self, container_id, **kwargs):
        """Update an existing container.

        :param patch: a json PATCH document to apply to this container.
        """
        context = pecan.request.context
        container = _get_container(container_id)
        check_policy_on_container(container.as_dict(), "container:update")
        try:
            patch = kwargs.get('patch')
            container_dict = container.as_dict()
            new_container_fields = api_utils.apply_jsonpatch(
                container_dict, patch)
        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        # Update only the fields that have changed
        for field in objects.Container.fields:
            try:
                patch_val = new_container_fields[field]
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if getattr(container, field) != patch_val:
                setattr(container, field, patch_val)

        container.save(context)
        return view.format_container(pecan.request.host_url, container)
Beispiel #3
0
 def convert_with_links(rpc_containers, limit, url=None,
                        expand=False, **kwargs):
     collection = ContainerCollection()
     collection.containers = \
         [view.format_container(url, p) for p in rpc_containers]
     collection.next = collection.get_next(limit, url=url, **kwargs)
     return collection
Beispiel #4
0
    def get_one(self, container_id):
        """Retrieve information about the given container.

        :param container_ident: UUID or name of a container.
        """
        container = _get_container(container_id)
        check_policy_on_container(container.as_dict(), "container:get")
        context = pecan.request.context
        compute_api = pecan.request.compute_api
        container = compute_api.container_show(context, container)
        return view.format_container(pecan.request.host_url, container)
Beispiel #5
0
    def rename(self, container_id, name):
        """rename an existing container.

        :param patch: a json PATCH document to apply to this container.
        """
        container = _get_container(container_id)
        check_policy_on_container(container.as_dict(), "container:rename")
        if container.name == name:
            raise exception.Conflict('The new name for the container is the '
                                     'same as the old name.')
        container.name = name
        context = pecan.request.context
        container.save(context)
        return view.format_container(pecan.request.host_url, container)
Beispiel #6
0
    def get_one(self, container_id, **kwargs):
        """Retrieve information about the given container.

        :param container_ident: UUID or name of a container.
        """
        context = pecan.request.context
        if is_all_tenants(kwargs):
            policy.enforce(context, "container:get_one_all_tenants",
                           action="container:get_one_all_tenants")
            context.all_tenants = True
        container = _get_container(container_id)
        check_policy_on_container(container.as_dict(), "container:get_one")
        compute_api = pecan.request.compute_api
        container = compute_api.container_show(context, container)
        return view.format_container(pecan.request.host_url, container)
Beispiel #7
0
    def patch(self, container_id, **patch):
        """Update an existing container.

        :param patch: a json PATCH document to apply to this container.
        """
        container = _get_container(container_id)
        check_policy_on_container(container.as_dict(), "container:update")
        utils.validate_container_state(container, 'update')
        if 'memory' in patch:
            patch['memory'] = str(patch['memory']) + 'M'
        if 'cpu' in patch:
            patch['cpu'] = float(patch['cpu'])
        context = pecan.request.context
        compute_api = pecan.request.compute_api
        container = compute_api.container_update(context, container, patch)
        return view.format_container(pecan.request.host_url, container)
Beispiel #8
0
    def rename(self, container_ident, name):
        """Rename an existing container.

        :param container_ident: UUID or Name of a container.
        :param name: a new name for this container.
        """
        container = utils.get_container(container_ident)
        check_policy_on_container(container.as_dict(), "container:rename")
        if container.name == name:
            raise exception.Conflict('The new name for the container is the '
                                     'same as the old name.')
        container.name = name
        context = pecan.request.context
        container.save(context)
        return view.format_container(context, pecan.request.host_url,
                                     container)
Beispiel #9
0
    def post(self, run=False, **container_dict):
        """Create a new container.

        :param run: if true, starts the container
        :param container: a container within the request body.
        """
        context = pecan.request.context
        compute_api = pecan.request.compute_api
        policy.enforce(context, "container:create", action="container:create")
        # NOTE(mkrai): Intent here is to check the existence of image
        # before proceeding to create container. If image is not found,
        # container create will fail with 400 status.
        images = compute_api.image_search(context, container_dict['image'],
                                          True)
        if not images:
            raise exception.ImageNotFound(container_dict['image'])
        container_dict['project_id'] = context.project_id
        container_dict['user_id'] = context.user_id
        name = container_dict.get('name') or \
            self._generate_name_for_container()
        container_dict['name'] = name
        if container_dict.get('memory'):
            container_dict['memory'] = \
                str(container_dict['memory']) + 'M'
        container_dict['status'] = fields.ContainerStatus.CREATING
        new_container = objects.Container(context, **container_dict)
        new_container.create(context)

        try:
            run = strutils.bool_from_string(run, strict=True)
        except ValueError:
            msg = _('Valid run values are true, false, 0, 1, yes and no')
            raise exception.InvalidValue(msg)

        if run:
            compute_api.container_run(context, new_container)
        else:
            compute_api.container_create(context, new_container)
        # Set the HTTP Location Header
        pecan.response.location = link.build_url('containers',
                                                 new_container.uuid)
        pecan.response.status = 202
        return view.format_container(pecan.request.host_url, new_container)
Beispiel #10
0
    def resize_container(self, container_ident, **kwargs):
        """Resize an existing container.

        :param container_ident: UUID or name of a container.
        :param kwargs: cpu/memory to be updated.
        """
        container = utils.get_container(container_ident)
        check_policy_on_container(container.as_dict(),
                                  "container:resize_container")
        utils.validate_container_state(container, 'resize_container')
        if 'memory' in kwargs:
            kwargs['memory'] = str(kwargs['memory'])
        if 'cpu' in kwargs:
            kwargs['cpu'] = float(kwargs['cpu'])
        context = pecan.request.context
        compute_api = pecan.request.compute_api
        compute_api.resize_container(context, container, kwargs)
        pecan.response.status = 202
        return view.format_container(context, pecan.request.host_url,
                                     container)
Beispiel #11
0
 def transform(key, value):
     if key not in _basic_keys:
         return
     if key == 'uuid':
         yield ('uuid', value)
         yield ('links', [
             link.make_link('self', url, 'capsules', value),
             link.make_link('bookmark',
                            url,
                            'capsules',
                            value,
                            bookmark=True)
         ])
         if legacy_api_version:
             yield ('volumes_info', {})
             yield ('containers_uuids', [])
             yield ('init_containers_uuids', [])
             yield ('capsule_version', '')
     elif key == 'containers':
         containers = []
         for c in capsule.containers:
             container = containers_view.format_container(context, None, c)
             containers.append(container)
         yield ('containers', containers)
     elif key == 'name':
         if legacy_api_version:
             yield ('meta_name', value)
         else:
             yield (key, value)
     elif key == 'labels':
         if legacy_api_version:
             yield ('meta_labels', value)
         else:
             yield (key, value)
     elif key == 'restart_policy':
         if legacy_api_version:
             yield (key, value['Name'])
         else:
             yield (key, value)
     else:
         yield (key, value)
Beispiel #12
0
    def get_one(self, container_ident, **kwargs):
        """Retrieve information about the given container.

        :param container_ident: UUID or name of a container.
        """
        context = pecan.request.context
        if utils.is_all_projects(kwargs):
            policy.enforce(context, "container:get_one_all_projects",
                           action="container:get_one_all_projects")
            context.all_projects = True
        container = utils.get_container(container_ident)
        check_policy_on_container(container.as_dict(), "container:get_one")
        if container.host:
            compute_api = pecan.request.compute_api
            try:
                container = compute_api.container_show(context, container)
            except exception.ContainerHostNotUp:
                raise exception.ServerNotUsable

        return view.format_container(context, pecan.request.host_url,
                                     container)
Beispiel #13
0
 def transform(key, value):
     if key not in _basic_keys:
         return
     if key == 'uuid':
         yield ('uuid', value)
         yield ('links', [
             link.make_link('self', url, 'capsules', value),
             link.make_link('bookmark',
                            url,
                            'capsules',
                            value,
                            bookmark=True)
         ])
     elif key == 'containers':
         containers = []
         for c in value:
             container = containers_view.format_container(context, None, c)
             containers.append(container)
         yield ('containers', containers)
     else:
         yield (key, value)
    def post(self, run=False, **container_dict):
        """Create or run a new container.

        :param run: if true, starts the container
        :param container_dict: a container within the request body.
        """
        context = pecan.request.context
        compute_api = pecan.request.compute_api
        policy.enforce(context, "container:create", action="container:create")

        if container_dict.get('security_groups'):
            # remove duplicate security_groups from list
            container_dict['security_groups'] = list(
                set(container_dict.get('security_groups')))
            for index, sg in enumerate(container_dict['security_groups']):
                security_group_id = self._check_security_group(
                    context, {'name': sg})
                container_dict['security_groups'][index] = security_group_id

        try:
            run = strutils.bool_from_string(run, strict=True)
            container_dict['interactive'] = strutils.bool_from_string(
                container_dict.get('interactive', False), strict=True)
        except ValueError:
            raise exception.InvalidValue(
                _('Valid run or interactive values '
                  'are: true, false, True, False'))

        auto_remove = container_dict.pop('auto_remove', None)
        if auto_remove is not None:
            req_version = pecan.request.version
            min_version = versions.Version('', '', '', '1.3')
            if req_version >= min_version:
                try:
                    container_dict['auto_remove'] = strutils.bool_from_string(
                        auto_remove, strict=True)
                except ValueError:
                    raise exception.InvalidValue(
                        _('Auto_remove values are: '
                          'true, false, True, False'))
            else:
                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:
            req_version = pecan.request.version
            min_version = versions.Version('', '', '', '1.5')
            if req_version >= min_version:
                container_dict['runtime'] = runtime
            else:
                raise exception.InvalidParamInVersion(param='runtime',
                                                      req_version=req_version,
                                                      min_version=min_version)

        hostname = container_dict.pop('hostname', None)
        if hostname is not None:
            req_version = pecan.request.version
            min_version = versions.Version('', '', '', '1.9')
            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 = utils.build_requested_networks(context, nets)
        pci_req = self._create_pci_requests_for_sriov_ports(
            context, requested_networks)

        mounts = container_dict.pop('mounts', [])
        if mounts:
            req_version = pecan.request.version
            min_version = versions.Version('', '', '', '1.11')
            if req_version < min_version:
                raise exception.InvalidParamInVersion(param='mounts',
                                                      req_version=req_version,
                                                      min_version=min_version)

        requested_volumes = self._build_requested_volumes(context, mounts)

        # 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(
                container_dict.get('image_driver'))

        container_dict['project_id'] = context.project_id
        container_dict['user_id'] = context.user_id
        name = container_dict.get('name') or \
            self._generate_name_for_container()
        container_dict['name'] = name
        if container_dict.get('memory'):
            container_dict['memory'] = \
                str(container_dict['memory']) + 'M'
        if container_dict.get('restart_policy'):
            utils.check_for_restart_policy(container_dict)

        container_dict['status'] = consts.CREATING
        extra_spec = {}
        extra_spec['hints'] = container_dict.get('hints', None)
        extra_spec['pci_requests'] = pci_req
        new_container = objects.Container(context, **container_dict)
        new_container.create(context)

        kwargs = {}
        kwargs['extra_spec'] = extra_spec
        kwargs['requested_networks'] = requested_networks
        kwargs['requested_volumes'] = requested_volumes
        if pci_req.requests:
            kwargs['pci_requests'] = pci_req
        kwargs['run'] = run
        compute_api.container_create(context, new_container, **kwargs)
        # Set the HTTP Location Header
        pecan.response.location = link.build_url('containers',
                                                 new_container.uuid)
        pecan.response.status = 202
        return view.format_container(pecan.request.host_url, new_container)
Beispiel #15
0
    def post(self, run=False, **container_dict):
        """Create a new container.

        :param run: if true, starts the container
        :param container_dict: a container within the request body.
        """
        context = pecan.request.context
        compute_api = pecan.request.compute_api
        policy.enforce(context, "container:create",
                       action="container:create")

        # remove duplicate security_groups from list
        if container_dict.get('security_groups'):
            container_dict['security_groups'] = list(
                set(container_dict.get('security_groups')))
        try:
            run = strutils.bool_from_string(run, strict=True)
            container_dict['interactive'] = strutils.bool_from_string(
                container_dict.get('interactive', False), strict=True)
        except ValueError:
            msg = _('Valid run or interactive value is ''true'', '
                    '"false", True, False, "True" and "False"')
            raise exception.InvalidValue(msg)

        requested_networks = container_dict.get('nets', [])

        # 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(
                container_dict.get('image_driver'))

        # NOTE(mkrai): Intent here is to check the existence of image
        # before proceeding to create container. If image is not found,
        # container create will fail with 400 status.
        images = compute_api.image_search(context, container_dict['image'],
                                          container_dict.get('image_driver'),
                                          True)
        if not images:
            raise exception.ImageNotFound(image=container_dict['image'])
        container_dict['project_id'] = context.project_id
        container_dict['user_id'] = context.user_id
        name = container_dict.get('name') or \
            self._generate_name_for_container()
        container_dict['name'] = name
        if container_dict.get('memory'):
            container_dict['memory'] = \
                str(container_dict['memory']) + 'M'
        if container_dict.get('restart_policy'):
            self._check_for_restart_policy(container_dict)

        auto_remove = container_dict.pop('auto_remove', None)
        if auto_remove is not None:
            req_version = pecan.request.version
            min_version = versions.Version('', '', '', '1.3')
            if req_version >= min_version:
                try:
                    container_dict['auto_remove'] = strutils.bool_from_string(
                        auto_remove, strict=True)
                except ValueError:
                    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)

        container_dict['status'] = consts.CREATING
        extra_spec = container_dict.get('hints', None)
        new_container = objects.Container(context, **container_dict)
        new_container.create(context)

        if run:
            compute_api.container_run(context, new_container, extra_spec,
                                      requested_networks)
        else:
            compute_api.container_create(context, new_container, extra_spec,
                                         requested_networks)
        # Set the HTTP Location Header
        pecan.response.location = link.build_url('containers',
                                                 new_container.uuid)
        pecan.response.status = 202
        return view.format_container(pecan.request.host_url, new_container)