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