def kill(self, container_id, **kw): container = _get_container(container_id) check_policy_on_container(container.as_dict(), "container:kill") utils.validate_container_state(container, 'kill') LOG.debug('Calling compute.container_kill with %s signal %s' % (container.uuid, kw.get('signal', kw.get('signal')))) context = pecan.request.context compute_api = pecan.request.compute_api compute_api.container_kill(context, container, kw.get('signal')) pecan.response.status = 202
def put_archive(self, container_id, **kwargs): container = _get_container(container_id) check_policy_on_container(container.as_dict(), "container:put_archive") utils.validate_container_state(container, 'put_archive') LOG.debug('Calling compute.container_put_archive with %(uuid)s ' 'path %(path)s', {'uuid': container.uuid, 'path': kwargs['path']}) context = pecan.request.context compute_api = pecan.request.compute_api compute_api.container_put_archive(context, container, kwargs['path'], kwargs['data'])
def commit(self, container_id, **kwargs): container = _get_container(container_id) check_policy_on_container(container.as_dict(), "container:commit") utils.validate_container_state(container, 'commit') LOG.debug('Calling compute.container_commit %s ', container.uuid) context = pecan.request.context compute_api = pecan.request.compute_api pecan.response.status = 202 return compute_api.container_commit(context, container, kwargs.get('repository', None), kwargs.get('tag', None))
def execute_resize(self, container_id, exec_id, **kwargs): container = _get_container(container_id) check_policy_on_container(container.as_dict(), "container:execute_resize") utils.validate_container_state(container, 'execute_resize') LOG.debug('Calling tty resize used by exec %s', exec_id) context = pecan.request.context compute_api = pecan.request.compute_api return compute_api.container_exec_resize( context, container, exec_id, kwargs.get('h', None), kwargs.get('w', None))
def get_archive(self, container_id, **kw): container = _get_container(container_id) check_policy_on_container(container.as_dict(), "container:get_archive") utils.validate_container_state(container, 'get_archive') LOG.debug('Calling compute.container_get_archive with %s path %s' % (container.uuid, kw['path'])) context = pecan.request.context compute_api = pecan.request.compute_api data, stat = compute_api.container_get_archive(context, container, kw['path']) return {"data": data, "stat": stat}
def stats(self, container_ident): """Display stats snapshot of the container. :param container_ident: UUID or Name of a container. """ container = utils.get_container(container_ident) check_policy_on_container(container.as_dict(), "container:stats") utils.validate_container_state(container, 'stats') LOG.debug('Calling compute.container_stats with %s', container.uuid) context = pecan.request.context compute_api = pecan.request.compute_api return compute_api.container_stats(context, container)
def kill(self, container_id, **kwargs): container = _get_container(container_id) check_policy_on_container(container.as_dict(), "container:kill") utils.validate_container_state(container, 'kill') LOG.debug('Calling compute.container_kill with %(uuid)s ' 'signal %(signal)s', {'uuid': container.uuid, 'signal': kwargs.get('signal')}) context = pecan.request.context compute_api = pecan.request.compute_api compute_api.container_kill(context, container, kwargs.get('signal')) pecan.response.status = 202
def reboot(self, container_ident, timeout=None, **kwargs): """Reboot container. :param container_ident: UUID or Name of a container. """ container = utils.get_container(container_ident) check_policy_on_container(container.as_dict(), "container:reboot") utils.validate_container_state(container, 'reboot') LOG.debug('Calling compute.container_reboot with %s', container.uuid) context = pecan.request.context compute_api = pecan.request.compute_api compute_api.container_reboot(context, container, timeout) pecan.response.status = 202
def resize(self, container_ident, **kwargs): """Resize container. :param container_ident: UUID or Name of a container. """ container = utils.get_container(container_ident) check_policy_on_container(container.as_dict(), "container:resize") utils.validate_container_state(container, 'resize') LOG.debug('Calling tty resize with %s ', container.uuid) context = pecan.request.context compute_api = pecan.request.compute_api compute_api.container_resize(context, container, kwargs.get('h', None), kwargs.get('w', None))
def top(self, container_ident, ps_args=None): """Display the running processes inside the container. :param container_ident: UUID or Name of a container. :param ps_args: The args of the ps command. """ container = utils.get_container(container_ident) check_policy_on_container(container.as_dict(), "container:top") utils.validate_container_state(container, 'top') LOG.debug('Calling compute.container_top with %s', container.uuid) context = pecan.request.context compute_api = pecan.request.compute_api return compute_api.container_top(context, container, ps_args)
def unpause(self, container_ident, **kwargs): """Unpause container. :param container_ident: UUID or Name of a container. """ container = utils.get_container(container_ident) check_policy_on_container(container.as_dict(), "container:unpause") utils.validate_container_state(container, 'unpause') LOG.debug('Calling compute.container_unpause with %s', container.uuid) context = pecan.request.context compute_api = pecan.request.compute_api compute_api.container_unpause(context, container) pecan.response.status = 202
def attach(self, container_id): container = _get_container(container_id) check_policy_on_container(container.as_dict(), "container:attach") utils.validate_container_state(container, 'attach') LOG.debug('Checking the status for attach with %s', container.uuid) if container.interactive: context = pecan.request.context compute_api = pecan.request.compute_api url = compute_api.container_attach(context, container) return url msg = _("Container doesn't support to be attached, " "please check the interactive set properly") raise exception.NoInteractiveFlag(msg=msg)
def commit(self, container_ident, **kwargs): """Create a new image from a container's changes. :param container_ident: UUID or Name of a container. """ container = utils.get_container(container_ident) check_policy_on_container(container.as_dict(), "container:commit") utils.validate_container_state(container, 'commit') LOG.debug('Calling compute.container_commit %s ', container.uuid) context = pecan.request.context compute_api = pecan.request.compute_api pecan.response.status = 202 return compute_api.container_commit(context, container, kwargs.get('repository', None), kwargs.get('tag', None))
def execute_resize(self, container_ident, exec_id, **kwargs): """Resize the tty session used by the exec :param container_ident: UUID or Name of a container. :param exec_id: ID of a exec. """ container = utils.get_container(container_ident) check_policy_on_container(container.as_dict(), "container:execute_resize") utils.validate_container_state(container, 'execute_resize') LOG.debug('Calling tty resize used by exec %s', exec_id) context = pecan.request.context compute_api = pecan.request.compute_api return compute_api.container_exec_resize(context, container, exec_id, kwargs.get('h', None), kwargs.get('w', None))
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 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 put_archive(self, container_ident, **kwargs): """Insert a file/folder to container. Insert a file or folder to an existing container using a tar archive as source. :param container_ident: UUID or Name of a container. """ container = utils.get_container(container_ident) check_policy_on_container(container.as_dict(), "container:put_archive") utils.validate_container_state(container, 'put_archive') LOG.debug('Calling compute.container_put_archive with %(uuid)s ' 'path %(path)s', {'uuid': container.uuid, 'path': kwargs['path']}) context = pecan.request.context compute_api = pecan.request.compute_api compute_api.container_put_archive(context, container, kwargs['path'], kwargs['data'])
def get_archive(self, container_ident, **kwargs): """Retrieve a file/folder from a container Retrieve a file or folder from a container in the form of a tar archive. :param container_ident: UUID or Name of a container. """ container = utils.get_container(container_ident) check_policy_on_container(container.as_dict(), "container:get_archive") utils.validate_container_state(container, 'get_archive') LOG.debug('Calling compute.container_get_archive with %(uuid)s ' 'path %(path)s', {'uuid': container.uuid, 'path': kwargs['path']}) context = pecan.request.context compute_api = pecan.request.compute_api data, stat = compute_api.container_get_archive( context, container, kwargs['path']) return {"data": data, "stat": stat}
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 add_security_group(self, container_ident, **security_group): """Add security group to an existing container. :param container_ident: UUID or Name of a container. :param security_group: security_group to be added to container. """ container = utils.get_container(container_ident) check_policy_on_container(container.as_dict(), "container:add_security_group") utils.validate_container_state(container, 'add_security_group') # check if security group already presnt in container context = pecan.request.context compute_api = pecan.request.compute_api security_group_id = self._check_security_group(context, security_group) compute_api.add_security_group(context, container, security_group_id) pecan.response.status = 202
def rebuild(self, container_ident, **kwargs): """Rebuild container. :param container_ident: UUID or Name of a container. """ container = utils.get_container(container_ident) check_policy_on_container(container.as_dict(), "container:rebuild") utils.validate_container_state(container, 'rebuild') if kwargs.get('image'): container.image = kwargs.get('image') if kwargs.get('image_driver'): utils.validate_image_driver(kwargs.get('image_driver')) container.image_driver = kwargs.get('image_driver') LOG.debug('Calling compute.container_rebuild with %s', container.uuid) context = pecan.request.context compute_api = pecan.request.compute_api compute_api.container_rebuild(context, container) pecan.response.status = 202
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 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 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
def delete(self, container_ident, force=False, **kwargs): """Delete a container. :param container_ident: UUID or Name of a container. :param force: If True, allow to force delete the container. """ context = pecan.request.context if utils.is_all_tenants(kwargs): policy.enforce(context, "container:delete_all_tenants", action="container:delete_all_tenants") context.all_tenants = True container = utils.get_container(container_ident) 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) stop = kwargs.pop('stop', False) try: stop = strutils.bool_from_string(stop, strict=True) except ValueError: msg = _('Valid stop values are true, false, 0, 1, yes and no') raise exception.InvalidValue(msg) compute_api = pecan.request.compute_api if not force and not stop: utils.validate_container_state(container, 'delete') elif force and not stop: req_version = pecan.request.version min_version = versions.Version('', '', '', '1.7') if req_version >= min_version: policy.enforce(context, "container:delete_force", action="container:delete_force") utils.validate_container_state(container, 'delete_force') else: raise exception.InvalidParamInVersion(param='force', req_version=req_version, min_version=min_version) elif stop: req_version = pecan.request.version min_version = versions.Version('', '', '', '1.12') if req_version >= min_version: check_policy_on_container(container.as_dict(), "container:stop") utils.validate_container_state(container, 'delete_after_stop') if container.status == consts.RUNNING: LOG.debug( 'Calling compute.container_stop with %s ' 'before delete', container.uuid) compute_api.container_stop(context, container, 10) else: raise exception.InvalidParamInVersion(param='stop', req_version=req_version, min_version=min_version) container.status = consts.DELETING compute_api.container_delete(context, container, force) pecan.response.status = 204
def add_security_group(self, container_id, **security_group): """Add security group to an existing container. :param security_group: security_group to be added to container. """ container = _get_container(container_id) check_policy_on_container(container.as_dict(), "container:add_security_group") utils.validate_container_state(container, 'add_security_group') # check if security group already presnt in container if security_group['name'] in container.security_groups: msg = _("security_group %s already present in container") % \ security_group['name'] raise exception.InvalidValue(msg) context = pecan.request.context compute_api = pecan.request.compute_api container = compute_api.add_security_group(context, container, security_group['name']) pecan.response.status = 202
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 sterr: 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: 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 delete(self, container_ident, force=False, **kwargs): """Delete a container. :param container_ident: UUID or Name of a container. :param force: If True, allow to force delete the container. """ context = pecan.request.context if utils.is_all_projects(kwargs): policy.enforce(context, "container:delete_all_projects", action="container:delete_all_projects") context.all_projects = True container = utils.get_container(container_ident) check_policy_on_container(container.as_dict(), "container:delete") try: force = strutils.bool_from_string(force, strict=True) except ValueError: bools = ', '.join(strutils.TRUE_STRINGS + strutils.FALSE_STRINGS) raise exception.InvalidValue(_('Valid force values are: %s') % bools) stop = kwargs.pop('stop', False) try: stop = strutils.bool_from_string(stop, strict=True) except ValueError: bools = ', '.join(strutils.TRUE_STRINGS + strutils.FALSE_STRINGS) raise exception.InvalidValue(_('Valid stop values are: %s') % bools) compute_api = pecan.request.compute_api if not force and not stop: utils.validate_container_state(container, 'delete') elif force and not stop: api_utils.version_check('force', '1.7') policy.enforce(context, "container:delete_force", action="container:delete_force") utils.validate_container_state(container, 'delete_force') elif stop: api_utils.version_check('stop', '1.12') check_policy_on_container(container.as_dict(), "container:stop") utils.validate_container_state(container, 'delete_after_stop') if container.status == consts.RUNNING: LOG.debug('Calling compute.container_stop with %s ' 'before delete', container.uuid) compute_api.container_stop(context, container, 10) container.status = consts.DELETING if container.host: compute_api.container_delete(context, container, force) else: container.destroy(context) pecan.response.status = 204
def test_validate_container_state(self): container = Container(self.context, **db_utils.get_test_container()) container.status = 'Stopped' with self.assertRaisesRegex(exception.InvalidStateException, "%s" % container.uuid): utils.validate_container_state(container, 'stop') with self.assertRaisesRegex(exception.InvalidStateException, "%s" % container.uuid): utils.validate_container_state(container, 'pause') container.status = 'Running' with self.assertRaisesRegex(exception.InvalidStateException, "%s" % container.uuid): utils.validate_container_state(container, 'start') with self.assertRaisesRegex(exception.InvalidStateException, "%s" % container.uuid): utils.validate_container_state(container, 'unpause') with self.assertRaisesRegex(exception.InvalidStateException, "%s" % container.uuid): utils.validate_container_state(container, 'delete') self.assertIsNone(utils.validate_container_state(container, 'reboot')) container.status = 'Stopped' self.assertIsNone(utils.validate_container_state(container, 'reboot')) container.status = 'Running' self.assertIsNone(utils.validate_container_state(container, 'execute'))
def test_validate_container_state(self): container = Container(self.context, **db_utils.get_test_container()) container.status = 'Stopped' with self.assertRaisesRegex(exception.InvalidStateException, "%s" % container.uuid): utils.validate_container_state(container, 'stop') with self.assertRaisesRegex(exception.InvalidStateException, "%s" % container.uuid): utils.validate_container_state(container, 'pause') container.status = 'Running' with self.assertRaisesRegex(exception.InvalidStateException, "%s" % container.uuid): utils.validate_container_state(container, 'start') with self.assertRaisesRegex(exception.InvalidStateException, "%s" % container.uuid): utils.validate_container_state(container, 'unpause') with self.assertRaisesRegex(exception.InvalidStateException, "%s" % container.uuid): utils.validate_container_state(container, 'delete') self.assertIsNone(utils.validate_container_state( container, 'reboot')) container.status = 'Stopped' self.assertIsNone(utils.validate_container_state( container, 'reboot')) container.status = 'Running' self.assertIsNone(utils.validate_container_state( container, 'execute'))