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)
Esempio n. 2
0
    def post(self, **capsule_dict):
        """Create a new capsule.

        :param capsule_dict: a capsule within the request body.
        """
        context = pecan.request.context
        compute_api = pecan.request.compute_api
        policy.enforce(context, "capsule:create", action="capsule:create")

        # Abstract the capsule specification
        capsules_template = capsule_dict.get('template')

        spec_content, template_json = \
            utils.check_capsule_template(capsules_template)

        containers_spec, init_containers_spec = \
            utils.capsule_get_container_spec(spec_content)
        volumes_spec = utils.capsule_get_volume_spec(spec_content)

        # Create the capsule Object
        new_capsule = objects.Capsule(context, **capsule_dict)
        new_capsule.project_id = context.project_id
        new_capsule.user_id = context.user_id
        new_capsule.status = consts.PENDING
        new_capsule.create(context)
        new_capsule.volumes = []
        capsule_need_cpu = 0
        capsule_need_memory = 0
        container_volume_requests = []

        if spec_content.get('restart_policy'):
            capsule_restart_policy = spec_content.get('restart_policy')
        else:
            # NOTE(hongbin): this is deprecated but we need to maintain
            # backward-compatibility. Will remove this branch in the future.
            capsule_restart_policy = template_json.get('restart_policy',
                                                       'always')
        container_restart_policy = {
            "MaximumRetryCount": "0",
            "Name": capsule_restart_policy
        }
        new_capsule.restart_policy = capsule_restart_policy

        metadata_info = template_json.get('metadata', None)
        requested_networks_info = template_json.get('nets', [])
        requested_networks = \
            utils.build_requested_networks(context, requested_networks_info)

        if metadata_info:
            new_capsule.meta_name = metadata_info.get('name', None)
            new_capsule.meta_labels = metadata_info.get('labels', None)

        # create the capsule in DB so that it generates a 'id'
        new_capsule.save()

        extra_spec = {}
        az_info = template_json.get('availabilityZone')
        if az_info:
            extra_spec['availability_zone'] = az_info

        # Generate Object for infra container
        sandbox_container = objects.Container(context)
        sandbox_container.project_id = context.project_id
        sandbox_container.user_id = context.user_id
        name = self._generate_name_for_capsule_sandbox(new_capsule)
        sandbox_container.name = name
        sandbox_container.capsule_id = new_capsule.id
        sandbox_container.image = CONF.sandbox_image
        sandbox_container.image_driver = CONF.sandbox_image_driver
        sandbox_container.image_pull_policy = \
            CONF.sandbox_image_pull_policy
        sandbox_container.status = consts.CREATING
        sandbox_container.create(context)
        new_capsule.containers_uuids = [sandbox_container.uuid]
        new_capsule.init_containers_uuids = []

        merged_containers_spec = init_containers_spec + containers_spec
        for container_spec in merged_containers_spec:
            container_dict = container_spec
            container_dict['project_id'] = context.project_id
            container_dict['user_id'] = context.user_id
            name = self._generate_name_for_capsule_container(new_capsule)
            container_dict['name'] = name

            if container_dict.get('args') and container_dict.get('command'):
                container_dict['command'] = \
                    container_dict['command'] + container_dict['args']
                container_dict.pop('args')
            elif container_dict.get('args'):
                container_dict['command'] = container_dict['args']
                container_dict.pop('args')

            # NOTE(kevinz): Don't support port remapping, will find a
            # easy way to implement it.
            # if container need to open some port, just open it in container,
            # user can change the security group and getting access to port.
            if container_dict.get('ports'):
                container_dict.pop('ports')

            if container_dict.get('resources'):
                resources_list = container_dict.get('resources')
                allocation = resources_list.get('requests')
                if allocation.get('cpu'):
                    capsule_need_cpu += allocation.get('cpu')
                    container_dict['cpu'] = allocation.get('cpu')
                if allocation.get('memory'):
                    capsule_need_memory += allocation.get('memory')
                    container_dict['memory'] = str(allocation['memory'])
                container_dict.pop('resources')

            if container_dict.get('volumeMounts'):
                for volume in container_dict['volumeMounts']:
                    volume['container_name'] = name
                    container_volume_requests.append(volume)

            container_dict['status'] = consts.CREATING
            container_dict['interactive'] = True
            container_dict['capsule_id'] = new_capsule.id
            container_dict['restart_policy'] = container_restart_policy
            if container_spec in init_containers_spec:
                if capsule_restart_policy == "always":
                    container_restart_policy = {
                        "MaximumRetryCount": "10",
                        "Name": "on-failure"
                    }
                    container_dict['restart_policy'] = container_restart_policy
            utils.check_for_restart_policy(container_dict)
            new_container = objects.Container(context, **container_dict)
            new_container.create(context)
            new_capsule.containers_uuids.append(new_container.uuid)
            if container_spec in init_containers_spec:
                new_capsule.init_containers_uuids.append(new_container.uuid)

        # Deal with the volume support
        requested_volumes = \
            self._build_requested_volumes(context,
                                          volumes_spec,
                                          container_volume_requests,
                                          new_capsule)
        new_capsule.cpu = capsule_need_cpu
        new_capsule.memory = str(capsule_need_memory)
        new_capsule.save(context)
        compute_api.capsule_create(context, new_capsule, requested_networks,
                                   requested_volumes, extra_spec)
        # Set the HTTP Location Header
        pecan.response.location = link.build_url('capsules', new_capsule.uuid)

        pecan.response.status = 202
        return view.format_capsule(pecan.request.host_url, new_capsule,
                                   context)
Esempio n. 3
0
    def post(self, **capsule_dict):
        """Create a new capsule.

        :param capsule_dict: a capsule within the request body.
        """
        context = pecan.request.context
        compute_api = pecan.request.compute_api
        policy.enforce(context, "capsule:create",
                       action="capsule:create")
        capsules_spec = capsule_dict['spec']
        containers_spec = utils.check_capsule_template(capsules_spec)
        new_capsule = objects.Capsule(context, **capsule_dict)
        new_capsule.project_id = context.project_id
        new_capsule.user_id = context.user_id
        new_capsule.create(context)
        new_capsule.containers = []
        new_capsule.containers_uuids = []
        new_capsule.volumes = []
        capsule_need_cpu = 0
        capsule_need_memory = 0
        count = len(containers_spec)

        capsule_restart_policy = capsules_spec.get('restart_policy', 'always')

        metadata_info = capsules_spec.get('metadata', None)
        requested_networks = capsules_spec.get('nets', [])
        if metadata_info:
            new_capsule.meta_name = metadata_info.get('name', None)
            new_capsule.meta_labels = metadata_info.get('labels', None)

        # Generate Object for infra container
        sandbox_container = objects.Container(context)
        sandbox_container.project_id = context.project_id
        sandbox_container.user_id = context.user_id
        name = self._generate_name_for_capsule_sandbox(new_capsule)
        sandbox_container.name = name
        sandbox_container.create(context)
        new_capsule.containers.append(sandbox_container)
        new_capsule.containers_uuids.append(sandbox_container.uuid)

        for k in range(count):
            container_dict = containers_spec[k]
            container_dict['project_id'] = context.project_id
            container_dict['user_id'] = context.user_id
            name = self._generate_name_for_capsule_container(new_capsule)
            container_dict['name'] = name

            if container_dict.get('args') and container_dict.get('command'):
                container_dict = self._transfer_list_to_str(container_dict,
                                                            'command')
                container_dict = self._transfer_list_to_str(container_dict,
                                                            'args')
                container_dict['command'] = \
                    container_dict['command'] + ' ' + container_dict['args']
                container_dict.pop('args')
            elif container_dict.get('command'):
                container_dict = self._transfer_list_to_str(container_dict,
                                                            'command')
            elif container_dict.get('args'):
                container_dict = self._transfer_list_to_str(container_dict,
                                                            'args')
                container_dict['command'] = container_dict['args']
                container_dict.pop('args')

            # NOTE(kevinz): Don't support pod remapping, will find a
            # easy way to implement it.
            # if container need to open some port, just open it in container,
            # user can change the security group and getting access to port.
            if container_dict.get('ports'):
                container_dict.pop('ports')

            if container_dict.get('resources'):
                resources_list = container_dict.get('resources')
                allocation = resources_list.get('allocation')
                if allocation.get('cpu'):
                    capsule_need_cpu += allocation.get('cpu')
                    container_dict['cpu'] = allocation.get('cpu')
                if allocation.get('memory'):
                    capsule_need_memory += allocation.get('memory')
                    container_dict['memory'] = str(allocation['memory']) + 'M'
                container_dict.pop('resources')

            if capsule_restart_policy:
                container_dict['restart_policy'] = \
                    {"MaximumRetryCount": "0",
                     "Name": capsule_restart_policy}
                utils.check_for_restart_policy(container_dict)

            container_dict['status'] = consts.CREATING
            container_dict['interactive'] = True
            new_container = objects.Container(context, **container_dict)
            new_container.create(context)
            new_capsule.containers.append(new_container)
            new_capsule.containers_uuids.append(new_container.uuid)

        new_capsule.cpu = capsule_need_cpu
        new_capsule.memory = str(capsule_need_memory) + 'M'
        new_capsule.save(context)
        compute_api.capsule_create(context, new_capsule, requested_networks)
        # Set the HTTP Location Header
        pecan.response.location = link.build_url('capsules',
                                                 new_capsule.uuid)

        pecan.response.status = 202
        return view.format_capsule(pecan.request.host_url, new_capsule)
Esempio n. 4
0
    def _do_post(self, legacy_api_version=False, **capsule_dict):
        context = pecan.request.context
        compute_api = pecan.request.compute_api
        policy.enforce(context, "capsule:create",
                       action="capsule:create")

        # Abstract the capsule specification
        capsules_template = capsule_dict.get('template')

        spec_content, template_json = \
            check_capsule_template(capsules_template)

        containers_spec, init_containers_spec = \
            utils.capsule_get_container_spec(spec_content)
        volumes_spec = utils.capsule_get_volume_spec(spec_content)

        # Create the capsule Object
        new_capsule = objects.Capsule(context, **capsule_dict)
        new_capsule.project_id = context.project_id
        new_capsule.user_id = context.user_id
        new_capsule.status = consts.CREATING
        new_capsule.create(context)
        new_capsule.volumes = []
        capsule_need_cpu = 0
        capsule_need_memory = 0
        container_volume_requests = []

        if spec_content.get('restart_policy'):
            capsule_restart_policy = spec_content.get('restart_policy')
        else:
            # NOTE(hongbin): this is deprecated but we need to maintain
            # backward-compatibility. Will remove this branch in the future.
            capsule_restart_policy = template_json.get('restart_policy',
                                                       'always')
        container_restart_policy = {"MaximumRetryCount": "0",
                                    "Name": capsule_restart_policy}
        new_capsule.restart_policy = container_restart_policy

        metadata_info = template_json.get('metadata', None)
        requested_networks_info = template_json.get('nets', [])
        requested_networks = \
            utils.build_requested_networks(context, requested_networks_info)

        if metadata_info:
            new_capsule.name = metadata_info.get('name', None)
            new_capsule.labels = metadata_info.get('labels', None)

        # create the capsule in DB so that it generates a 'id'
        new_capsule.save()

        extra_spec = {}
        az_info = template_json.get('availabilityZone')
        if az_info:
            extra_spec['availability_zone'] = az_info

        new_capsule.image = CONF.sandbox_image
        new_capsule.image_driver = CONF.sandbox_image_driver

        # calculate capsule cpu/ram
        # 1. sum all cpu/ram of regular containers
        for container_dict in containers_spec:
            if not container_dict.get('resources'):
                continue
            allocation = container_dict['resources']['requests']
            if allocation.get('cpu'):
                capsule_need_cpu += allocation['cpu']
            if allocation.get('memory'):
                capsule_need_memory += allocation['memory']
        # 2. take the maximum of each init container
        for container_dict in init_containers_spec:
            if not container_dict.get('resources'):
                continue
            allocation = container_dict['resources']['requests']
            if allocation.get('cpu'):
                capsule_need_cpu = max(capsule_need_cpu, allocation['cpu'])
            if allocation.get('memory'):
                capsule_need_memory = max(capsule_need_memory,
                                          allocation['memory'])

        merged_containers_spec = init_containers_spec + containers_spec
        for container_spec in merged_containers_spec:
            if container_spec.get('image_pull_policy'):
                policy.enforce(context, "container:create:image_pull_policy",
                               action="container:create:image_pull_policy")
            container_dict = container_spec
            container_dict['project_id'] = context.project_id
            container_dict['user_id'] = context.user_id
            name = self._generate_name_for_capsule_container(new_capsule)
            container_dict['name'] = name

            if container_dict.get('args') and container_dict.get('command'):
                container_dict['command'] = \
                    container_dict['command'] + container_dict['args']
                container_dict.pop('args')
            elif container_dict.get('args'):
                container_dict['command'] = container_dict['args']
                container_dict.pop('args')

            if container_dict.get('ports'):
                exposed_ports = {}
                ports = container_dict.pop('ports')
                for port in ports:
                    container_port = "%s/%s" % (
                        port['containerPort'],
                        port.get('protocol', 'tcp').lower())
                    host_port = {}
                    exposed_ports[container_port] = host_port
                container_dict['exposed_ports'] = exposed_ports

            if container_dict.get('resources'):
                resources_list = container_dict.get('resources')
                allocation = resources_list.get('requests')
                if allocation.get('cpu'):
                    container_dict['cpu'] = allocation.get('cpu')
                if allocation.get('memory'):
                    container_dict['memory'] = str(allocation['memory'])
                container_dict.pop('resources')

            container_dict['image_pull_policy'] = (
                container_dict.get('image_pull_policy', 'always').lower())
            container_dict['status'] = consts.CREATING
            container_dict['interactive'] = True
            container_dict['capsule_id'] = new_capsule.id
            container_dict['restart_policy'] = container_restart_policy
            if container_spec in init_containers_spec:
                if capsule_restart_policy == "always":
                    container_restart_policy = {"MaximumRetryCount": "10",
                                                "Name": "on-failure"}
                    container_dict['restart_policy'] = container_restart_policy
                utils.check_for_restart_policy(container_dict)
                new_container = objects.CapsuleInitContainer(context,
                                                             **container_dict)
            else:
                utils.check_for_restart_policy(container_dict)
                new_container = objects.CapsuleContainer(context,
                                                         **container_dict)
            new_container.create(context)

            if container_dict.get('volumeMounts'):
                for volume in container_dict['volumeMounts']:
                    volume['container_uuid'] = new_container.uuid
                    container_volume_requests.append(volume)

        # Deal with the volume support
        requested_volumes = \
            self._build_requested_volumes(context,
                                          volumes_spec,
                                          container_volume_requests,
                                          new_capsule)
        new_capsule.cpu = capsule_need_cpu
        new_capsule.memory = str(capsule_need_memory)
        new_capsule.save(context)

        kwargs = {}
        kwargs['extra_spec'] = extra_spec
        kwargs['requested_networks'] = requested_networks
        kwargs['requested_volumes'] = requested_volumes
        kwargs['run'] = True
        compute_api.container_create(context, new_capsule, **kwargs)
        # Set the HTTP Location Header
        pecan.response.location = link.build_url('capsules',
                                                 new_capsule.uuid)

        pecan.response.status = 202
        return view.format_capsule(pecan.request.host_url, new_capsule,
                                   context,
                                   legacy_api_version=legacy_api_version)
Esempio n. 5
0
    def _do_post(self, legacy_api_version=False, **capsule_dict):
        context = pecan.request.context
        compute_api = pecan.request.compute_api
        policy.enforce(context, "capsule:create",
                       action="capsule:create")

        # Abstract the capsule specification
        capsules_template = capsule_dict.get('template')

        spec_content, template_json = \
            check_capsule_template(capsules_template)

        containers_spec, init_containers_spec = \
            utils.capsule_get_container_spec(spec_content)
        volumes_spec = utils.capsule_get_volume_spec(spec_content)

        # Create the capsule Object
        new_capsule = objects.Capsule(context, **capsule_dict)
        new_capsule.project_id = context.project_id
        new_capsule.user_id = context.user_id
        new_capsule.status = consts.CREATING
        new_capsule.create(context)
        new_capsule.volumes = []
        capsule_need_cpu = 0
        capsule_need_memory = 0
        container_volume_requests = []

        if spec_content.get('restart_policy'):
            capsule_restart_policy = spec_content.get('restart_policy')
        else:
            # NOTE(hongbin): this is deprecated but we need to maintain
            # backward-compatibility. Will remove this branch in the future.
            capsule_restart_policy = template_json.get('restart_policy',
                                                       'always')
        container_restart_policy = {"MaximumRetryCount": "0",
                                    "Name": capsule_restart_policy}
        new_capsule.restart_policy = container_restart_policy

        metadata_info = template_json.get('metadata', None)
        requested_networks_info = template_json.get('nets', [])
        requested_networks = \
            utils.build_requested_networks(context, requested_networks_info)

        if metadata_info:
            new_capsule.name = metadata_info.get('name', None)
            new_capsule.labels = metadata_info.get('labels', None)

        # create the capsule in DB so that it generates a 'id'
        new_capsule.save()

        extra_spec = {}
        az_info = template_json.get('availabilityZone')
        if az_info:
            extra_spec['availability_zone'] = az_info

        new_capsule.image = CONF.sandbox_image
        new_capsule.image_driver = CONF.sandbox_image_driver

        merged_containers_spec = init_containers_spec + containers_spec
        for container_spec in merged_containers_spec:
            if container_spec.get('image_pull_policy'):
                policy.enforce(context, "container:create:image_pull_policy",
                               action="container:create:image_pull_policy")
            container_dict = container_spec
            container_dict['project_id'] = context.project_id
            container_dict['user_id'] = context.user_id
            name = self._generate_name_for_capsule_container(new_capsule)
            container_dict['name'] = name

            if container_dict.get('args') and container_dict.get('command'):
                container_dict['command'] = \
                    container_dict['command'] + container_dict['args']
                container_dict.pop('args')
            elif container_dict.get('args'):
                container_dict['command'] = container_dict['args']
                container_dict.pop('args')

            # NOTE(kevinz): Don't support port remapping, will find a
            # easy way to implement it.
            # if container need to open some port, just open it in container,
            # user can change the security group and getting access to port.
            if container_dict.get('ports'):
                container_dict.pop('ports')

            if container_dict.get('resources'):
                resources_list = container_dict.get('resources')
                allocation = resources_list.get('requests')
                if allocation.get('cpu'):
                    capsule_need_cpu += allocation.get('cpu')
                    container_dict['cpu'] = allocation.get('cpu')
                if allocation.get('memory'):
                    capsule_need_memory += allocation.get('memory')
                    container_dict['memory'] = str(allocation['memory'])
                container_dict.pop('resources')

            container_dict['image_pull_policy'] = (
                container_dict.get('image_pull_policy', 'always').lower())
            container_dict['status'] = consts.CREATING
            container_dict['interactive'] = True
            container_dict['capsule_id'] = new_capsule.id
            container_dict['restart_policy'] = container_restart_policy
            if container_spec in init_containers_spec:
                if capsule_restart_policy == "always":
                    container_restart_policy = {"MaximumRetryCount": "10",
                                                "Name": "on-failure"}
                    container_dict['restart_policy'] = container_restart_policy
                utils.check_for_restart_policy(container_dict)
                new_container = objects.CapsuleInitContainer(context,
                                                             **container_dict)
            else:
                utils.check_for_restart_policy(container_dict)
                new_container = objects.CapsuleContainer(context,
                                                         **container_dict)
            new_container.create(context)

            if container_dict.get('volumeMounts'):
                for volume in container_dict['volumeMounts']:
                    volume['container_uuid'] = new_container.uuid
                    container_volume_requests.append(volume)

        # Deal with the volume support
        requested_volumes = \
            self._build_requested_volumes(context,
                                          volumes_spec,
                                          container_volume_requests,
                                          new_capsule)
        new_capsule.cpu = capsule_need_cpu
        new_capsule.memory = str(capsule_need_memory)
        new_capsule.save(context)

        kwargs = {}
        kwargs['extra_spec'] = extra_spec
        kwargs['requested_networks'] = requested_networks
        kwargs['requested_volumes'] = requested_volumes
        kwargs['run'] = True
        compute_api.container_create(context, new_capsule, **kwargs)
        # Set the HTTP Location Header
        pecan.response.location = link.build_url('capsules',
                                                 new_capsule.uuid)

        pecan.response.status = 202
        return view.format_capsule(pecan.request.host_url, new_capsule,
                                   context,
                                   legacy_api_version=legacy_api_version)