def get_one(self, container_ident, request_ident, **kwargs): """Retrieve information about the action.""" context = pecan.request.context policy.enforce(context, "container:actions", action="container:actions") container = utils.get_container(container_ident) action = objects.ContainerAction.get_by_request_id( context, container.uuid, request_ident) if action is None: raise exception.ResourceNotFound(name="Action", id=request_ident) action_id = action.id if CONF.database.backend == 'etcd': # etcd using action.uuid get the unique action instead of action.id action_id = action.uuid action = self._format_action(action) show_traceback = False if policy.enforce(context, "container:action:events", do_raise=False, action="container:action:events"): show_traceback = True events_raw = objects.ContainerActionEvent.get_by_action(context, action_id) action['events'] = [self._format_event(evt, show_traceback) for evt in events_raw] return action
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: 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 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: bools = ', '.join(strutils.TRUE_STRINGS + strutils.FALSE_STRINGS) raise exception.InvalidValue( _('Valid run or interactive ' 'values are: %s') % bools) 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 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 network_list(self, container_ident): """Retrieve a list of networks of the container. :param container_ident: UUID or Name of a container. """ container = utils.get_container(container_ident) container_networks = self._get_container_networks(container) return {'networks': container_networks}
def get_all(self, container_ident, **kwargs): """Retrieve a list of container actions.""" context = pecan.request.context policy.enforce(context, "container:actions", action="container:actions") container = utils.get_container(container_ident) actions_raw = objects.ContainerAction.get_by_container_uuid( context, container.uuid) actions = [self._format_action(action) for action in actions_raw] return {"containerActions": actions}
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 network_attach(self, container_ident, **kwargs): """Attach a network to 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:network_attach") context = pecan.request.context compute_api = pecan.request.compute_api requested_networks = utils.build_requested_networks(context, [kwargs]) compute_api.network_attach(context, container, requested_networks[0])
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 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 network_attach(self, container_ident, **kwargs): """Attach a network to 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:network_attach") context = pecan.request.context compute_api = pecan.request.compute_api neutron_api = neutron.NeutronAPI(context) neutron_net = neutron_api.get_neutron_network(kwargs.get('network')) compute_api.network_attach(context, container, neutron_net['id'])
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 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 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 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 rename(self, container_ident, name): """Rename an existing container. :param container_ident: UUID or Name of a container. :param patch: a json PATCH document to apply to 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(pecan.request.host_url, container)
def kill(self, container_ident, **kwargs): """Kill a running container. :param container_ident: UUID or Name of a container. """ container = utils.get_container(container_ident) 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 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 patch(self, container_ident, **patch): """Update an existing container. :param container_ident: UUID or name of a container. :param patch: a json PATCH document to apply to this container. """ container = utils.get_container(container_ident) 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 attach(self, container_ident): """Attach to a running container. :param container_ident: UUID or Name of a container. """ container = utils.get_container(container_ident) 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 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_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_tenants(kwargs): policy.enforce(context, "container:get_one_all_tenants", action="container:get_one_all_tenants") context.all_tenants = True container = utils.get_container(container_ident) check_policy_on_container(container.as_dict(), "container:get_one") compute_api = pecan.request.compute_api container = compute_api.container_show(context, container) if not context.is_admin: del container.host return view.format_container(pecan.request.host_url, container)
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 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 network_detach(self, container_ident, **kwargs): """Detach a network from 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:network_detach") context = pecan.request.context compute_api = pecan.request.compute_api neutron_api = neutron.NeutronAPI(context) if kwargs.get('port'): port = neutron_api.get_neutron_port(kwargs['port']) net_id = port['network_id'] else: network = neutron_api.get_neutron_network(kwargs.get('network')) net_id = network['id'] compute_api.network_detach(context, container, net_id) pecan.response.status = 202
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 get_one(self, capsule_ident): """Retrieve information about the given capsule. :param capsule_ident: UUID or name of a capsule. """ capsule = _get_capsule(capsule_ident) check_policy_on_capsule(capsule.as_dict(), "capsule:get") context = pecan.request.context compute_api = pecan.request.compute_api sandbox = utils.get_container(capsule.containers_uuids[0]) try: container = compute_api.container_show(context, sandbox) capsule.status = container.status capsule.save(context) except Exception as e: LOG.exception(("Error while show capsule %(uuid)s: " "%(e)s."), {'uuid': capsule.uuid, 'e': e}) capsule.status = consts.UNKNOWN return view.format_capsule(pecan.request.host_url, capsule)
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 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