def logs(self, container_ident, stdout=True, stderr=True, timestamps=False, tail='all', since=None): """Get logs of the given container. :param container_ident: UUID or Name of a container. :param stdout: Get standard output if True. :param stderr: Get standard error if True. :param timestamps: Show timestamps. :param tail: Number of lines to show from the end of the logs. (default: get all logs) :param since: Show logs since a given datetime or integer epoch (in seconds). """ container = utils.get_container(container_ident) check_policy_on_container(container.as_dict(), "container:logs") utils.validate_container_state(container, 'logs') try: stdout = strutils.bool_from_string(stdout, strict=True) stderr = strutils.bool_from_string(stderr, strict=True) timestamps = strutils.bool_from_string(timestamps, strict=True) except ValueError: bools = ', '.join(strutils.TRUE_STRINGS + strutils.FALSE_STRINGS) raise exception.InvalidValue(_('Valid stdout, stderr and ' 'timestamps values are: %s') % bools) LOG.debug('Calling compute.container_logs with %s', container.uuid) context = pecan.request.context compute_api = pecan.request.compute_api return compute_api.container_logs(context, container, stdout, stderr, timestamps, tail, since)
def delete(self, container_id, force=False, **kwargs): """Delete a container. :param container_ident: UUID or Name of a container. """ LOG.debug('v 1.7 Storagerate delete xxx container_id=%s, kwargs=%s', container_id, kwargs) context = pecan.request.context if is_all_tenants(kwargs): policy.enforce(context, "storagerate:delete_all_tenants", action="storagerate:delete_all_tenants") context.all_tenants = True container = _get_container(container_id) check_policy_on_container(container.as_dict(), "storagerate:delete") try: force = strutils.bool_from_string(force, strict=True) except ValueError: msg = _('Valid force values are true, false, 0, 1, yes and no') raise exception.InvalidValue(msg) if not force: utils.validate_container_state(container, 'delete') else: utils.validate_container_state(container, 'delete_force') policy.enforce(context, "storagerate:delete_force", action="storagerate:delete_force") compute_api = pecan.request.compute_api compute_api.storagerate_delete(context, container, force) pecan.response.status = 204
def logs(self, container_id, stdout=True, stderr=True, timestamps=False, tail='all', since=None): container = _get_container(container_id) check_policy_on_container(container.as_dict(), "container:logs") utils.validate_container_state(container, 'logs') try: stdout = strutils.bool_from_string(stdout, strict=True) stderr = strutils.bool_from_string(stderr, strict=True) timestamps = strutils.bool_from_string(timestamps, strict=True) except ValueError: msg = _('Valid stdout, stderr and timestamps values are ' 'true' ', ' '"false", True, False, 0 and 1, yes and no') raise exception.InvalidValue(msg) LOG.debug('Calling compute.container_logs with %s' % container.uuid) context = pecan.request.context compute_api = pecan.request.compute_api return compute_api.container_logs(context, container, stdout, stderr, timestamps, tail, since)
def validate(cls, value): if value is None: return elif isinstance(value, datetime.datetime): return value raise exception.InvalidValue(value=value, type=cls.type_name)
def execute(self, container_ident, run=True, interactive=False, **kwargs): """Execute command in a running container. :param container_ident: UUID or Name of a container. :param run: If True, execute run. :param interactive: Keep STDIN open and allocate a pseudo-TTY for interactive. """ container = utils.get_container(container_ident) check_policy_on_container(container.as_dict(), "container:execute") utils.validate_container_state(container, 'execute') try: run = strutils.bool_from_string(run, strict=True) interactive = strutils.bool_from_string(interactive, strict=True) except ValueError: msg = _('Valid run values are true, false, 0, 1, yes and no') raise exception.InvalidValue(msg) LOG.debug( 'Calling compute.container_exec with %(uuid)s command ' '%(command)s', { 'uuid': container.uuid, 'command': kwargs['command'] }) context = pecan.request.context compute_api = pecan.request.compute_api return compute_api.container_exec(context, container, kwargs['command'], run, interactive)
def validate(cls, value): if value is None: return None if not isinstance(value, six.string_types): raise exception.InvalidValue(value=value, type=cls.type_name) return value
def validate(cls, value, pattern=None): if value is None: return value super(NameType, cls).validate(value, min_length=2, max_length=255) match = pattern.match(value) if match: return value else: message = _('%s does not match [a-zA-Z0-9][a-zA-Z0-9_.-]') % value raise exception.InvalidValue(message)
def is_all_tenants(search_opts): all_tenants = search_opts.get('all_tenants') if all_tenants: try: all_tenants = strutils.bool_from_string(all_tenants, True) except ValueError as err: raise exception.InvalidValue(six.text_type(err)) else: all_tenants = False return all_tenants
def validate(cls, value, name=None, values=None): if value is None: return None if value.lower() not in set(values): message = _( "%(name)s should be one of: %(values)s") % { 'name': name, 'values': ', '.join([six.text_type(v) for v in values])} raise exception.InvalidValue(message) else: return value.lower()
def validate(cls, value): if value is None: return None if not isinstance(value, float): try: value = float(value) except Exception: LOG.exception('Failed to convert value to float') raise exception.InvalidValue(value=value, type=cls.type_name) return value
def is_all_projects(search_opts): all_projects = search_opts.get('all_projects') if all_projects: try: all_projects = strutils.bool_from_string(all_projects, True) except ValueError: bools = ', '.join(strutils.TRUE_STRINGS + strutils.FALSE_STRINGS) raise exception.InvalidValue( _('Valid all_projects values are: %s') % bools) else: all_projects = False return all_projects
def search(self, image, exact_match=False): context = pecan.request.context policy.enforce(context, "image:search", action="image:search") LOG.debug('Calling compute.image_search with %s' % image) try: exact_match = strutils.bool_from_string(exact_match, strict=True) except ValueError: msg = _("Valid exact_match values are true," " false, 0, 1, yes and no") raise exception.InvalidValue(msg) return pecan.request.compute_api.image_search(context, image, exact_match)
def validate(cls, value, default=None): if value is None: value = default if not isinstance(value, bool): try: value = strutils.bool_from_string(value, strict=True) except Exception: LOG.exception('Failed to convert value to bool') raise exception.InvalidValue(value=value, type=cls.type_name) return value
def validate(self, value): if value is None: return None if not isinstance(value, self.user_class): try: value = self.user_class(**value) except Exception: LOG.exception('Failed to validate received value') raise exception.InvalidValue(value=value, type=self.type_name) return value
def container_create(self, context, new_container, extra_spec, requested_networks, requested_volumes, run, pci_requests=None): try: host_state = self._schedule_container(context, new_container, extra_spec) except exception.NoValidHost: new_container.status = consts.ERROR new_container.status_reason = _( "There are not enough hosts available.") new_container.save(context) return except Exception: new_container.status = consts.ERROR new_container.status_reason = _("Unexpected exception occurred.") new_container.save(context) raise # 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. if CONF.api.enable_image_validation: try: images = self.rpcapi.image_search( context, new_container.image, new_container.image_driver, True, new_container.registry, host_state['host']) if not images: raise exception.ImageNotFound(image=new_container.image) if len(images) > 1: raise exception.Conflict('Multiple images exist with same ' 'name. Please use the container ' 'uuid instead.') except exception.OperationNotSupported: LOG.info("Skip validation since search is not supported for " "image '%(image)s' and image driver '%(driver)s'.", {'image': new_container.image, 'driver': new_container.image_driver}) except exception.ReferenceInvalidFormat: raise exception.InvalidValue(_("The format of image name '%s' " "is invalid.") % new_container.image) except Exception as e: LOG.warning("Skip validation since image search failed with " "unexpected exception: %s", str(e)) self._record_action_start(context, new_container, container_actions.CREATE) self.rpcapi.container_create(context, host_state['host'], new_container, host_state['limits'], requested_networks, requested_volumes, run, pci_requests)
def validate(cls, value, minimum=None, maximum=None): if value is None: return None if not isinstance(value, six.integer_types): try: value = int(value) except Exception: LOG.exception('Failed to convert value to int') raise exception.InvalidValue(value=value, type=cls.type_name) if minimum is not None and value < minimum: message = _("Integer '%(value)s' is smaller than " "'%(min)d'.") % {'value': value, 'min': minimum} raise exception.InvalidValue(message=message) if maximum is not None and value > maximum: message = _("Integer '%(value)s' is large than " "'%(max)d'.") % {'value': value, 'max': maximum} raise exception.InvalidValue(message=message) return value
def _check_for_restart_policy(self, container_dict): """Check for restart policy input""" restart_policy = container_dict.get('restart_policy') if not restart_policy: return name = restart_policy.get('Name') num = restart_policy.setdefault('MaximumRetryCount', '0') count = int(num) if name in ['unless-stopped', 'always']: if count != 0: msg = _("maximum retry count not valid with restart " "policy of %s") % name raise exception.InvalidValue(msg) elif name in ['no']: container_dict.get('restart_policy')['MaximumRetryCount'] = '0'
def _update_forced_down(self, context, body): """Set or unset forced_down flag for the service""" try: forced_down = strutils.bool_from_string(body['forced_down'], True) except ValueError as err: raise exception.InvalidValue(six.text_type(err)) self._update(context, body['host'], body['binary'], {"forced_down": forced_down}) res = { 'service': { 'host': body['host'], 'binary': body['binary'], 'forced_down': forced_down }, } return res
def execute(self, container_id, run=True, interactive=False, **kw): container = _get_container(container_id) check_policy_on_container(container.as_dict(), "container:execute") utils.validate_container_state(container, 'execute') try: run = strutils.bool_from_string(run, strict=True) interactive = strutils.bool_from_string(interactive, strict=True) except ValueError: msg = _('Valid run values are true, false, 0, 1, yes and no') raise exception.InvalidValue(msg) LOG.debug('Calling compute.container_exec with %s command %s' % (container.uuid, kw['command'])) context = pecan.request.context compute_api = pecan.request.compute_api return compute_api.container_exec(context, container, kw['command'], run, interactive)
def validate(cls, value): if value is None: return elif value.isdigit(): return value elif (value.isalnum() and value[:-1].isdigit() and value[-1] in VALID_UNITS.keys()): return int(value[:-1]) * VALID_UNITS[value[-1]] else: LOG.exception('Failed to validate image size') message = _(""" size must be either integer or string of below format. <integer><memory_unit> memory_unit must be 'k','b','m','g' in both cases""") raise exception.InvalidValue(message=message, value=value, type=cls.type_name)
def validate(cls, value): if value is None: return elif value.isdigit() and int(value) >= MIN_MEMORY_SIZE: return value elif (value.isalnum() and value[:-1].isdigit() and value[-1] in VALID_UNITS.keys()): if int(value[:-1]) * VALID_UNITS[value[-1]] >= MIN_MEMORY_SIZE: return value LOG.exception('Failed to validate container memory value') message = """ memory must be either integer or string of below format. <integer><memory_unit> memory_unit must be 'k','b','m','g' in both cases""" raise exception.InvalidValue(message=message, value=value, type=cls.type_name)
def _check_security_group(self, context, security_group): neutron_api = neutron.NeutronAPI(context) try: return neutron_api.find_resourceid_by_name_or_id( 'security_group', security_group['name'], context.project_id) except n_exc.NeutronClientNoUniqueMatch as e: msg = _("Multiple security group matches found for name " "%(name)s, use an ID to be more specific.") % { 'name': security_group['name']} raise exception.Conflict(msg) except n_exc.NeutronClientException as e: if e.status_code == 404: msg = _("Security group %(name)s not found.") % { 'name': security_group['name']} raise exception.InvalidValue(msg) else: raise
def search(self, image, image_driver=None, exact_match=False): context = pecan.request.context policy.enforce(context, "image:search", action="image:search") LOG.debug('Calling compute.image_search with %s', image) try: exact_match = strutils.bool_from_string(exact_match, strict=True) except ValueError: bools = ', '.join(strutils.TRUE_STRINGS + strutils.FALSE_STRINGS) raise exception.InvalidValue( _('Valid exact_match values are: %s') % bools) # Valiadtion accepts 'None' so need to convert it to None if image_driver: image_driver = api_utils.string_or_none(image_driver) return pecan.request.compute_api.image_search(context, image, image_driver, exact_match)
def search(self, image, image_driver=None, exact_match=False): context = pecan.request.context policy.enforce(context, "image:search", action="image:search") LOG.debug('Calling compute.image_search with %s', image) try: exact_match = strutils.bool_from_string(exact_match, strict=True) except ValueError: msg = _("Valid exact_match values are true," " false, 0, 1, yes and no") raise exception.InvalidValue(msg) # Valiadtion accepts 'None' so need to convert it to None if image_driver: image_driver = api_utils.string_or_none(image_driver) return pecan.request.compute_api.image_search(context, image, image_driver, exact_match)
def _update_forced_down(self, context, body): """Set or unset forced_down flag for the service""" try: forced_down = strutils.bool_from_string(body['forced_down'], True) except ValueError: bools = ', '.join(strutils.TRUE_STRINGS + strutils.FALSE_STRINGS) raise exception.InvalidValue( _('Valid forced_down values are: %s') % bools) self._update(context, body['host'], body['binary'], {"forced_down": forced_down}) res = { 'service': { 'host': body['host'], 'binary': body['binary'], 'forced_down': forced_down }, } return res
def _get_containers_collection(self, **kwargs): context = pecan.request.context if utils.is_all_projects(kwargs): policy.enforce(context, "container:get_all_all_projects", action="container:get_all_all_projects") context.all_projects = True kwargs.pop('all_projects', None) limit = api_utils.validate_limit(kwargs.pop('limit', None)) sort_dir = api_utils.validate_sort_dir(kwargs.pop('sort_dir', 'asc')) sort_key = kwargs.pop('sort_key', 'id') resource_url = kwargs.pop('resource_url', None) expand = kwargs.pop('expand', None) container_allowed_filters = ['name', 'image', 'project_id', 'user_id', 'memory', 'host', 'task_state', 'status', 'auto_remove'] filters = {} for filter_key in container_allowed_filters: if filter_key in kwargs: policy_action = policies.CONTAINER % ('get_one:' + filter_key) context.can(policy_action, might_not_exist=True) filter_value = kwargs.pop(filter_key) filters[filter_key] = filter_value marker_obj = None marker = kwargs.pop('marker', None) if marker: marker_obj = objects.Container.get_by_uuid(context, marker) if kwargs: unknown_params = [str(k) for k in kwargs] msg = _("Unknown parameters: %s") % ", ".join(unknown_params) raise exception.InvalidValue(msg) containers = objects.Container.list(context, limit, marker_obj, sort_key, sort_dir, filters=filters) return ContainerCollection.convert_with_links(containers, limit, url=resource_url, expand=expand, sort_key=sort_key, sort_dir=sort_dir)
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 delete(self, container_id, force=False): """Delete a container. :param container_ident: UUID or Name of a container. """ container = _get_container(container_id) check_policy_on_container(container.as_dict(), "container:delete") try: force = strutils.bool_from_string(force, strict=True) except ValueError: msg = _('Valid force values are true, false, 0, 1, yes and no') raise exception.InvalidValue(msg) if not force: utils.validate_container_state(container, 'delete') context = pecan.request.context compute_api = pecan.request.compute_api compute_api.container_delete(context, container, force) container.destroy(context) pecan.response.status = 204
def _get_registries_collection(self, **kwargs): context = pecan.request.context if utils.is_all_projects(kwargs): policy_action = policies.REGISTRY % 'get_all_all_projects' policy.enforce(context, policy_action, action=policy_action) context.all_projects = True kwargs.pop('all_projects', None) limit = api_utils.validate_limit(kwargs.pop('limit', None)) sort_dir = api_utils.validate_sort_dir(kwargs.pop('sort_dir', 'asc')) sort_key = kwargs.pop('sort_key', 'id') resource_url = kwargs.pop('resource_url', None) registry_allowed_filters = [ 'name', 'domain', 'username', 'project_id', 'user_id' ] filters = {} for filter_key in registry_allowed_filters: if filter_key in kwargs: policy_action = policies.REGISTRY % ('get_one:' + filter_key) context.can(policy_action, might_not_exist=True) filter_value = kwargs.pop(filter_key) filters[filter_key] = filter_value marker_obj = None marker = kwargs.pop('marker', None) if marker: marker_obj = objects.Registry.get_by_uuid(context, marker) if kwargs: unknown_params = [str(k) for k in kwargs] msg = _("Unknown parameters: %s") % ", ".join(unknown_params) raise exception.InvalidValue(msg) registries = objects.Registry.list(context, limit, marker_obj, sort_key, sort_dir, filters=filters) return RegistryCollection.convert_with_links(registries, limit, url=resource_url, sort_key=sort_key, sort_dir=sort_dir)
def remove_security_group(self, container_ident, **security_group): """Remove security group from an existing container. :param container_ident: UUID or Name of a container. :param security_group: security_group to be removed from container. """ container = utils.get_container(container_ident) check_policy_on_container( container.as_dict(), "container:remove_security_group") utils.validate_container_state(container, 'remove_security_group') context = pecan.request.context compute_api = pecan.request.compute_api security_group_id = self._check_security_group(context, security_group) if security_group_id not in container.security_groups: msg = _("Security group %(id)s was not added to container.") % { 'id': security_group_id} raise exception.InvalidValue(msg) compute_api.remove_security_group(context, container, security_group_id) pecan.response.status = 202