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