123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- from .. import errors
- from .. import utils
- from ..types import CancellableStream
-
-
- class ExecApiMixin:
- @utils.check_resource('container')
- def exec_create(self, container, cmd, stdout=True, stderr=True,
- stdin=False, tty=False, privileged=False, user='',
- environment=None, workdir=None, detach_keys=None):
- """
- Sets up an exec instance in a running container.
-
- Args:
- container (str): Target container where exec instance will be
- created
- cmd (str or list): Command to be executed
- stdout (bool): Attach to stdout. Default: ``True``
- stderr (bool): Attach to stderr. Default: ``True``
- stdin (bool): Attach to stdin. Default: ``False``
- tty (bool): Allocate a pseudo-TTY. Default: False
- privileged (bool): Run as privileged.
- user (str): User to execute command as. Default: root
- environment (dict or list): A dictionary or a list of strings in
- the following format ``["PASSWORD=xxx"]`` or
- ``{"PASSWORD": "xxx"}``.
- workdir (str): Path to working directory for this exec session
- detach_keys (str): Override the key sequence for detaching
- a container. Format is a single character `[a-Z]`
- or `ctrl-<value>` where `<value>` is one of:
- `a-z`, `@`, `^`, `[`, `,` or `_`.
- ~/.docker/config.json is used by default.
-
- Returns:
- (dict): A dictionary with an exec ``Id`` key.
-
- Raises:
- :py:class:`docker.errors.APIError`
- If the server returns an error.
- """
-
- if environment is not None and utils.version_lt(self._version, '1.25'):
- raise errors.InvalidVersion(
- 'Setting environment for exec is not supported in API < 1.25'
- )
-
- if isinstance(cmd, str):
- cmd = utils.split_command(cmd)
-
- if isinstance(environment, dict):
- environment = utils.utils.format_environment(environment)
-
- data = {
- 'Container': container,
- 'User': user,
- 'Privileged': privileged,
- 'Tty': tty,
- 'AttachStdin': stdin,
- 'AttachStdout': stdout,
- 'AttachStderr': stderr,
- 'Cmd': cmd,
- 'Env': environment,
- }
-
- if workdir is not None:
- if utils.version_lt(self._version, '1.35'):
- raise errors.InvalidVersion(
- 'workdir is not supported for API version < 1.35'
- )
- data['WorkingDir'] = workdir
-
- if detach_keys:
- data['detachKeys'] = detach_keys
- elif 'detachKeys' in self._general_configs:
- data['detachKeys'] = self._general_configs['detachKeys']
-
- url = self._url('/containers/{0}/exec', container)
- res = self._post_json(url, data=data)
- return self._result(res, True)
-
- def exec_inspect(self, exec_id):
- """
- Return low-level information about an exec command.
-
- Args:
- exec_id (str): ID of the exec instance
-
- Returns:
- (dict): Dictionary of values returned by the endpoint.
-
- Raises:
- :py:class:`docker.errors.APIError`
- If the server returns an error.
- """
- if isinstance(exec_id, dict):
- exec_id = exec_id.get('Id')
- res = self._get(self._url("/exec/{0}/json", exec_id))
- return self._result(res, True)
-
- def exec_resize(self, exec_id, height=None, width=None):
- """
- Resize the tty session used by the specified exec command.
-
- Args:
- exec_id (str): ID of the exec instance
- height (int): Height of tty session
- width (int): Width of tty session
- """
-
- if isinstance(exec_id, dict):
- exec_id = exec_id.get('Id')
-
- params = {'h': height, 'w': width}
- url = self._url("/exec/{0}/resize", exec_id)
- res = self._post(url, params=params)
- self._raise_for_status(res)
-
- @utils.check_resource('exec_id')
- def exec_start(self, exec_id, detach=False, tty=False, stream=False,
- socket=False, demux=False):
- """
- Start a previously set up exec instance.
-
- Args:
- exec_id (str): ID of the exec instance
- detach (bool): If true, detach from the exec command.
- Default: False
- tty (bool): Allocate a pseudo-TTY. Default: False
- stream (bool): Return response data progressively as an iterator
- of strings, rather than a single string.
- socket (bool): Return the connection socket to allow custom
- read/write operations. Must be closed by the caller when done.
- demux (bool): Return stdout and stderr separately
-
- Returns:
-
- (generator or str or tuple): If ``stream=True``, a generator
- yielding response chunks. If ``socket=True``, a socket object for
- the connection. A string containing response data otherwise. If
- ``demux=True``, a tuple with two elements of type byte: stdout and
- stderr.
-
- Raises:
- :py:class:`docker.errors.APIError`
- If the server returns an error.
- """
- # we want opened socket if socket == True
-
- data = {
- 'Tty': tty,
- 'Detach': detach
- }
-
- headers = {} if detach else {
- 'Connection': 'Upgrade',
- 'Upgrade': 'tcp'
- }
-
- res = self._post_json(
- self._url('/exec/{0}/start', exec_id),
- headers=headers,
- data=data,
- stream=True
- )
- if detach:
- try:
- return self._result(res)
- finally:
- res.close()
- if socket:
- return self._get_raw_response_socket(res)
-
- output = self._read_from_socket(res, stream, tty=tty, demux=demux)
- if stream:
- return CancellableStream(output, res)
- else:
- return output
|