diff options
Diffstat (limited to 'docker/api')
-rw-r--r-- | docker/api/build.py | 50 | ||||
-rw-r--r-- | docker/api/client.py | 27 | ||||
-rw-r--r-- | docker/api/container.py | 137 | ||||
-rw-r--r-- | docker/api/exec_api.py | 12 | ||||
-rw-r--r-- | docker/api/image.py | 50 | ||||
-rw-r--r-- | docker/api/network.py | 6 | ||||
-rw-r--r-- | docker/api/volume.py | 4 |
7 files changed, 79 insertions, 207 deletions
diff --git a/docker/api/build.py b/docker/api/build.py index 220c93f..56f1fcf 100644 --- a/docker/api/build.py +++ b/docker/api/build.py @@ -1,7 +1,6 @@ import json import logging import os -import re from .. import auth from .. import constants @@ -14,7 +13,7 @@ log = logging.getLogger(__name__) class BuildApiMixin(object): def build(self, path=None, tag=None, quiet=False, fileobj=None, - nocache=False, rm=False, stream=False, timeout=None, + nocache=False, rm=False, timeout=None, custom_context=False, encoding=None, pull=False, forcerm=False, dockerfile=None, container_limits=None, decode=False, buildargs=None, gzip=False, shmsize=None, @@ -67,9 +66,6 @@ class BuildApiMixin(object): rm (bool): Remove intermediate containers. The ``docker build`` command now defaults to ``--rm=true``, but we have kept the old default of `False` to preserve backward compatibility - stream (bool): *Deprecated for API version > 1.8 (always True)*. - Return a blocking generator you can iterate over to retrieve - build output as it happens timeout (int): HTTP timeout custom_context (bool): Optional if using ``fileobj`` encoding (str): The encoding for a stream. Set to ``gzip`` for @@ -154,17 +150,6 @@ class BuildApiMixin(object): ) encoding = 'gzip' if gzip else encoding - if utils.compare_version('1.8', self._version) >= 0: - stream = True - - if dockerfile and utils.compare_version('1.17', self._version) < 0: - raise errors.InvalidVersion( - 'dockerfile was only introduced in API version 1.17' - ) - - if utils.compare_version('1.19', self._version) < 0: - pull = 1 if pull else 0 - u = self._url('/build') params = { 't': tag, @@ -179,12 +164,7 @@ class BuildApiMixin(object): params.update(container_limits) if buildargs: - if utils.version_gte(self._version, '1.21'): - params.update({'buildargs': json.dumps(buildargs)}) - else: - raise errors.InvalidVersion( - 'buildargs was only introduced in API version 1.21' - ) + params.update({'buildargs': json.dumps(buildargs)}) if shmsize: if utils.version_gte(self._version, '1.22'): @@ -256,30 +236,21 @@ class BuildApiMixin(object): if encoding: headers['Content-Encoding'] = encoding - if utils.compare_version('1.9', self._version) >= 0: - self._set_auth_headers(headers) + self._set_auth_headers(headers) response = self._post( u, data=context, params=params, headers=headers, - stream=stream, + stream=True, timeout=timeout, ) if context is not None and not custom_context: context.close() - if stream: - return self._stream_helper(response, decode=decode) - else: - output = self._result(response) - srch = r'Successfully built ([0-9a-f]+)' - match = re.search(srch, output) - if not match: - return None, output - return match.group(1), output + return self._stream_helper(response, decode=decode) def _set_auth_headers(self, headers): log.debug('Looking for auth config') @@ -316,13 +287,8 @@ class BuildApiMixin(object): ) ) - if utils.compare_version('1.19', self._version) >= 0: - headers['X-Registry-Config'] = auth.encode_header( - auth_data - ) - else: - headers['X-Registry-Config'] = auth.encode_header({ - 'configs': auth_data - }) + headers['X-Registry-Config'] = auth.encode_header( + auth_data + ) else: log.debug('No auth config found') diff --git a/docker/api/client.py b/docker/api/client.py index 07bcfae..e69d143 100644 --- a/docker/api/client.py +++ b/docker/api/client.py @@ -1,6 +1,5 @@ import json import struct -import warnings from functools import partial import requests @@ -27,7 +26,7 @@ from ..constants import ( MINIMUM_DOCKER_API_VERSION ) from ..errors import ( - DockerException, TLSParameterError, + DockerException, InvalidVersion, TLSParameterError, create_api_error_from_http_exception ) from ..tls import TLSConfig @@ -160,11 +159,9 @@ class APIClient( ) ) if utils.version_lt(self._version, MINIMUM_DOCKER_API_VERSION): - warnings.warn( - 'The minimum API version supported is {}, but you are using ' - 'version {}. It is recommended you either upgrade Docker ' - 'Engine or use an older version of Docker SDK for ' - 'Python.'.format(MINIMUM_DOCKER_API_VERSION, self._version) + raise InvalidVersion( + 'API versions below {} are no longer supported by this ' + 'library.'.format(MINIMUM_DOCKER_API_VERSION) ) def _retrieve_server_version(self): @@ -353,17 +350,8 @@ class APIClient( break yield data - def _stream_raw_result_old(self, response): - ''' Stream raw output for API versions below 1.6 ''' - self._raise_for_status(response) - for line in response.iter_lines(chunk_size=1, - decode_unicode=True): - # filter out keep-alive new lines - if line: - yield line - def _stream_raw_result(self, response): - ''' Stream result for TTY-enabled container above API 1.6 ''' + ''' Stream result for TTY-enabled container ''' self._raise_for_status(response) for out in response.iter_content(chunk_size=1, decode_unicode=True): yield out @@ -419,11 +407,6 @@ class APIClient( return self._get_result_tty(stream, res, self._check_is_tty(container)) def _get_result_tty(self, stream, res, is_tty): - # Stream multi-plexing was only introduced in API v1.6. Anything - # before that needs old-style streaming. - if utils.compare_version('1.6', self._version) < 0: - return self._stream_raw_result_old(res) - # We should also use raw streaming (without keep-alives) # if we're dealing with a tty-enabled container. if is_tty: diff --git a/docker/api/container.py b/docker/api/container.py index 419ae44..152a08b 100644 --- a/docker/api/container.py +++ b/docker/api/container.py @@ -204,15 +204,13 @@ class ContainerApiMixin(object): return res def create_container(self, image, command=None, hostname=None, user=None, - detach=False, stdin_open=False, tty=False, - mem_limit=None, ports=None, environment=None, - dns=None, volumes=None, volumes_from=None, + detach=False, stdin_open=False, tty=False, ports=None, + environment=None, volumes=None, network_disabled=False, name=None, entrypoint=None, - cpu_shares=None, working_dir=None, domainname=None, - memswap_limit=None, cpuset=None, host_config=None, - mac_address=None, labels=None, volume_driver=None, - stop_signal=None, networking_config=None, - healthcheck=None, stop_timeout=None, runtime=None): + working_dir=None, domainname=None, host_config=None, + mac_address=None, labels=None, stop_signal=None, + networking_config=None, healthcheck=None, + stop_timeout=None, runtime=None): """ Creates a container. Parameters are similar to those for the ``docker run`` command except it doesn't support the attach options (``-a``). @@ -354,27 +352,17 @@ class ContainerApiMixin(object): return container ID stdin_open (bool): Keep STDIN open even if not attached tty (bool): Allocate a pseudo-TTY - mem_limit (float or str): Memory limit. Accepts float values (which - represent the memory limit of the created container in bytes) - or a string with a units identification char (``100000b``, - ``1000k``, ``128m``, ``1g``). If a string is specified without - a units character, bytes are assumed as an intended unit. ports (list of ints): A list of port numbers environment (dict or list): A dictionary or a list of strings in the following format ``["PASSWORD=xxx"]`` or ``{"PASSWORD": "xxx"}``. - dns (:py:class:`list`): DNS name servers. Deprecated since API - version 1.10. Use ``host_config`` instead. volumes (str or list): List of paths inside the container to use as volumes. - volumes_from (:py:class:`list`): List of container names or Ids to - get volumes from. network_disabled (bool): Disable networking name (str): A name for the container entrypoint (str or list): An entrypoint working_dir (str): Path to the working directory domainname (str): The domain name to use for the container - memswap_limit (int): host_config (dict): A dictionary created with :py:meth:`create_host_config`. mac_address (str): The Mac Address to assign the container @@ -382,7 +370,6 @@ class ContainerApiMixin(object): ``{"label1": "value1", "label2": "value2"}``) or a list of names of labels to set with empty values (e.g. ``["label1", "label2"]``) - volume_driver (str): The name of a volume driver/plugin. stop_signal (str): The stop signal to use to stop the container (e.g. ``SIGINT``). stop_timeout (int): Timeout to stop the container, in seconds. @@ -405,17 +392,12 @@ class ContainerApiMixin(object): if isinstance(volumes, six.string_types): volumes = [volumes, ] - if host_config and utils.compare_version('1.15', self._version) < 0: - raise errors.InvalidVersion( - 'host_config is not supported in API < 1.15' - ) - config = self.create_container_config( - image, command, hostname, user, detach, stdin_open, tty, mem_limit, - ports, dns, environment, volumes, volumes_from, - network_disabled, entrypoint, cpu_shares, working_dir, domainname, - memswap_limit, cpuset, host_config, mac_address, labels, - volume_driver, stop_signal, networking_config, healthcheck, + image, command, hostname, user, detach, stdin_open, tty, + ports, environment, volumes, + network_disabled, entrypoint, working_dir, domainname, + host_config, mac_address, labels, + stop_signal, networking_config, healthcheck, stop_timeout, runtime ) return self.create_container_from_config(config, name) @@ -681,7 +663,6 @@ class ContainerApiMixin(object): return self._stream_raw_result(res) @utils.check_resource('container') - @utils.minimum_version('1.20') def get_archive(self, container, path): """ Retrieve a file or folder from a container in the form of a tar @@ -786,59 +767,46 @@ class ContainerApiMixin(object): :py:class:`docker.errors.APIError` If the server returns an error. """ - if utils.compare_version('1.11', self._version) >= 0: - if follow is None: - follow = stream - params = {'stderr': stderr and 1 or 0, - 'stdout': stdout and 1 or 0, - 'timestamps': timestamps and 1 or 0, - 'follow': follow and 1 or 0, - } - if utils.compare_version('1.13', self._version) >= 0: - if tail != 'all' and (not isinstance(tail, int) or tail < 0): - tail = 'all' - params['tail'] = tail - - if since is not None: - if utils.version_lt(self._version, '1.19'): - raise errors.InvalidVersion( - 'since is not supported for API version < 1.19' - ) - if isinstance(since, datetime): - params['since'] = utils.datetime_to_timestamp(since) - elif (isinstance(since, int) and since > 0): - params['since'] = since - else: - raise errors.InvalidArgument( - 'since value should be datetime or positive int, ' - 'not {}'.format(type(since)) - ) - - if until is not None: - if utils.version_lt(self._version, '1.35'): - raise errors.InvalidVersion( - 'until is not supported for API version < 1.35' - ) - if isinstance(until, datetime): - params['until'] = utils.datetime_to_timestamp(until) - elif (isinstance(until, int) and until > 0): - params['until'] = until - else: - raise errors.InvalidArgument( - 'until value should be datetime or positive int, ' - 'not {}'.format(type(until)) - ) - - url = self._url("/containers/{0}/logs", container) - res = self._get(url, params=params, stream=stream) - return self._get_result(container, stream, res) - return self.attach( - container, - stdout=stdout, - stderr=stderr, - stream=stream, - logs=True - ) + if follow is None: + follow = stream + params = {'stderr': stderr and 1 or 0, + 'stdout': stdout and 1 or 0, + 'timestamps': timestamps and 1 or 0, + 'follow': follow and 1 or 0, + } + if tail != 'all' and (not isinstance(tail, int) or tail < 0): + tail = 'all' + params['tail'] = tail + + if since is not None: + if isinstance(since, datetime): + params['since'] = utils.datetime_to_timestamp(since) + elif (isinstance(since, int) and since > 0): + params['since'] = since + else: + raise errors.InvalidArgument( + 'since value should be datetime or positive int, ' + 'not {}'.format(type(since)) + ) + + if until is not None: + if utils.version_lt(self._version, '1.35'): + raise errors.InvalidVersion( + 'until is not supported for API version < 1.35' + ) + if isinstance(until, datetime): + params['until'] = utils.datetime_to_timestamp(until) + elif (isinstance(until, int) and until > 0): + params['until'] = until + else: + raise errors.InvalidArgument( + 'until value should be datetime or positive int, ' + 'not {}'.format(type(until)) + ) + + url = self._url("/containers/{0}/logs", container) + res = self._get(url, params=params, stream=stream) + return self._get_result(container, stream, res) @utils.check_resource('container') def pause(self, container): @@ -906,7 +874,6 @@ class ContainerApiMixin(object): return h_ports @utils.check_resource('container') - @utils.minimum_version('1.20') def put_archive(self, container, path, data): """ Insert a file or folder in an existing container using a tar archive as @@ -976,7 +943,6 @@ class ContainerApiMixin(object): ) self._raise_for_status(res) - @utils.minimum_version('1.17') @utils.check_resource('container') def rename(self, container, name): """ @@ -1073,7 +1039,6 @@ class ContainerApiMixin(object): res = self._post(url) self._raise_for_status(res) - @utils.minimum_version('1.17') @utils.check_resource('container') def stats(self, container, decode=None, stream=True): """ diff --git a/docker/api/exec_api.py b/docker/api/exec_api.py index d607461..986d87f 100644 --- a/docker/api/exec_api.py +++ b/docker/api/exec_api.py @@ -5,7 +5,6 @@ from .. import utils class ExecApiMixin(object): - @utils.minimum_version('1.15') @utils.check_resource('container') def exec_create(self, container, cmd, stdout=True, stderr=True, stdin=False, tty=False, privileged=False, user='', @@ -41,14 +40,6 @@ class ExecApiMixin(object): If the server returns an error. """ - if privileged and utils.version_lt(self._version, '1.19'): - raise errors.InvalidVersion( - 'Privileged exec is not supported in API < 1.19' - ) - if user and utils.version_lt(self._version, '1.19'): - raise errors.InvalidVersion( - 'User-specific exec is not supported in API < 1.19' - ) 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' @@ -88,7 +79,6 @@ class ExecApiMixin(object): res = self._post_json(url, data=data) return self._result(res, True) - @utils.minimum_version('1.16') def exec_inspect(self, exec_id): """ Return low-level information about an exec command. @@ -108,7 +98,6 @@ class ExecApiMixin(object): res = self._get(self._url("/exec/{0}/json", exec_id)) return self._result(res, True) - @utils.minimum_version('1.15') def exec_resize(self, exec_id, height=None, width=None): """ Resize the tty session used by the specified exec command. @@ -127,7 +116,6 @@ class ExecApiMixin(object): res = self._post(url, params=params) self._raise_for_status(res) - @utils.minimum_version('1.15') @utils.check_resource('exec_id') def exec_start(self, exec_id, detach=False, tty=False, stream=False, socket=False): diff --git a/docker/api/image.py b/docker/api/image.py index f37d2dd..fa832a3 100644 --- a/docker/api/image.py +++ b/docker/api/image.py @@ -54,8 +54,7 @@ class ImageApiMixin(object): res = self._get(self._url("/images/{0}/history", image)) return self._result(res, True) - def images(self, name=None, quiet=False, all=False, viz=False, - filters=None): + def images(self, name=None, quiet=False, all=False, filters=None): """ List images. Similar to the ``docker images`` command. @@ -76,10 +75,6 @@ class ImageApiMixin(object): :py:class:`docker.errors.APIError` If the server returns an error. """ - if viz: - if utils.compare_version('1.7', self._version) >= 0: - raise Exception('Viz output is not supported in API >= 1.7!') - return self._result(self._get(self._url("images/viz"))) params = { 'filter': name, 'only_ids': 1 if quiet else 0, @@ -226,19 +221,6 @@ class ImageApiMixin(object): ) @utils.check_resource('image') - def insert(self, image, url, path): - if utils.compare_version('1.12', self._version) >= 0: - raise errors.DeprecatedMethod( - 'insert is not available for API version >=1.12' - ) - api_url = self._url("/images/{0}/insert", image) - params = { - 'url': url, - 'path': path - } - return self._result(self._post(api_url, params=params)) - - @utils.check_resource('image') def inspect_image(self, image): """ Get detailed information about an image. Similar to the ``docker @@ -369,14 +351,13 @@ class ImageApiMixin(object): } headers = {} - if utils.version_gte(self._version, '1.5'): - if auth_config is None: - header = auth.get_config_header(self, registry) - if header: - headers['X-Registry-Auth'] = header - else: - log.debug('Sending supplied auth config') - headers['X-Registry-Auth'] = auth.encode_header(auth_config) + if auth_config is None: + header = auth.get_config_header(self, registry) + if header: + headers['X-Registry-Auth'] = header + else: + log.debug('Sending supplied auth config') + headers['X-Registry-Auth'] = auth.encode_header(auth_config) if platform is not None: if utils.version_lt(self._version, '1.32'): @@ -440,14 +421,13 @@ class ImageApiMixin(object): } headers = {} - if utils.compare_version('1.5', self._version) >= 0: - if auth_config is None: - header = auth.get_config_header(self, registry) - if header: - headers['X-Registry-Auth'] = header - else: - log.debug('Sending supplied auth config') - headers['X-Registry-Auth'] = auth.encode_header(auth_config) + if auth_config is None: + header = auth.get_config_header(self, registry) + if header: + headers['X-Registry-Auth'] = header + else: + log.debug('Sending supplied auth config') + headers['X-Registry-Auth'] = auth.encode_header(auth_config) response = self._post_json( u, None, headers=headers, stream=stream, params=params diff --git a/docker/api/network.py b/docker/api/network.py index 7977808..57ed8d3 100644 --- a/docker/api/network.py +++ b/docker/api/network.py @@ -5,7 +5,6 @@ from .. import utils class NetworkApiMixin(object): - @minimum_version('1.21') def networks(self, names=None, ids=None, filters=None): """ List networks. Similar to the ``docker networks ls`` command. @@ -38,7 +37,6 @@ class NetworkApiMixin(object): res = self._get(url, params=params) return self._result(res, json=True) - @minimum_version('1.21') def create_network(self, name, driver=None, options=None, ipam=None, check_duplicate=None, internal=False, labels=None, enable_ipv6=False, attachable=None, scope=None, @@ -175,7 +173,6 @@ class NetworkApiMixin(object): url = self._url('/networks/prune') return self._result(self._post(url, params=params), True) - @minimum_version('1.21') @check_resource('net_id') def remove_network(self, net_id): """ @@ -188,7 +185,6 @@ class NetworkApiMixin(object): res = self._delete(url) self._raise_for_status(res) - @minimum_version('1.21') @check_resource('net_id') def inspect_network(self, net_id, verbose=None, scope=None): """ @@ -216,7 +212,6 @@ class NetworkApiMixin(object): return self._result(res, json=True) @check_resource('container') - @minimum_version('1.21') def connect_container_to_network(self, container, net_id, ipv4_address=None, ipv6_address=None, aliases=None, links=None, @@ -253,7 +248,6 @@ class NetworkApiMixin(object): self._raise_for_status(res) @check_resource('container') - @minimum_version('1.21') def disconnect_container_from_network(self, container, net_id, force=False): """ diff --git a/docker/api/volume.py b/docker/api/volume.py index ce911c8..900a608 100644 --- a/docker/api/volume.py +++ b/docker/api/volume.py @@ -3,7 +3,6 @@ from .. import utils class VolumeApiMixin(object): - @utils.minimum_version('1.21') def volumes(self, filters=None): """ List volumes currently registered by the docker daemon. Similar to the @@ -37,7 +36,6 @@ class VolumeApiMixin(object): url = self._url('/volumes') return self._result(self._get(url, params=params), True) - @utils.minimum_version('1.21') def create_volume(self, name=None, driver=None, driver_opts=None, labels=None): """ @@ -90,7 +88,6 @@ class VolumeApiMixin(object): return self._result(self._post_json(url, data=data), True) - @utils.minimum_version('1.21') def inspect_volume(self, name): """ Retrieve volume info by name. @@ -138,7 +135,6 @@ class VolumeApiMixin(object): url = self._url('/volumes/prune') return self._result(self._post(url, params=params), True) - @utils.minimum_version('1.21') def remove_volume(self, name, force=False): """ Remove a volume. Similar to the ``docker volume rm`` command. |