Hello community, here is the log from the commit of package python-docker for openSUSE:Factory checked in at 2018-10-31 13:12:32 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-docker (Old) and /work/SRC/openSUSE:Factory/.python-docker.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-docker" Wed Oct 31 13:12:32 2018 rev:9 rq:643580 version:3.5.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-docker/python-docker.changes 2018-08-31 10:46:19.187338373 +0200 +++ /work/SRC/openSUSE:Factory/.python-docker.new/python-docker.changes 2018-10-31 13:12:41.463555402 +0100 @@ -1,0 +2,8 @@ +Sat Oct 20 15:33:00 UTC 2018 - Arun Persaud <[email protected]> + +- update to version 3.5.1: + * Bumped version of pyOpenSSL in requirements.txt and setup.py to + prevent installation of a vulnerable version + * Docs fixes + +------------------------------------------------------------------- @@ -5,0 +14,26 @@ + +------------------------------------------------------------------- +Sat Aug 11 16:13:17 UTC 2018 - [email protected] + +- specfile: + * updated requirement python-docker-pycreds to 0.3.0 + +- update to version 3.5.0: + * Deprecation warning + + Support for Python 3.3 will be dropped in the 4.0.0 release + * Features + + Updated dependencies to ensure support for Python 3.7 + environments + + Added support for the uts_mode parameter in HostConfig + + The UpdateConfig constructor now allows rollback as a valid + value for failure_action + + Added support for rollback_config in APIClient.create_service, + APIClient.update_service, DockerClient.services.create and + Service.update. + * Bugfixes + + Credential helpers are now properly leveraged by the build + method + + Fixed a bug that caused placement preferences to be ignored when + provided to DockerClient.services.create + + Fixed a bug that caused a user value of 0 to be ignored in + APIClient.create_container and DockerClient.containers.create Old: ---- docker-3.4.1.tar.gz New: ---- docker-3.5.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-docker.spec ++++++ --- /var/tmp/diff_new_pack.Q1lRj4/_old 2018-10-31 13:12:44.803552167 +0100 +++ /var/tmp/diff_new_pack.Q1lRj4/_new 2018-10-31 13:12:44.807552164 +0100 @@ -12,26 +12,21 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define oldpython python Name: python-docker -Version: 3.4.1 +Version: 3.5.1 Release: 0 Summary: Docker API Client License: Apache-2.0 Group: System/Management URL: https://github.com/docker/docker-py Source0: https://files.pythonhosted.org/packages/source/d/docker/docker-%{version}.tar.gz -%if 0%{?suse_version} < 1320 -BuildRequires: %{oldpython} -BuildRequires: %{python_module backports.ssl_match_hostname >= 3.5} -BuildRequires: python3 -%endif -BuildRequires: %{python_module docker-pycreds >= 0.2.3} +BuildRequires: %{python_module docker-pycreds >= 0.3.0} BuildRequires: %{python_module mock} BuildRequires: %{python_module pip} BuildRequires: %{python_module pytest >= 2.9.1} @@ -43,7 +38,7 @@ BuildRequires: %{python_module websocket-client >= 0.32.0} BuildRequires: fdupes BuildRequires: python-rpm-macros -Requires: python-docker-pycreds >= 0.2.3 +Requires: python-docker-pycreds >= 0.3.0 Requires: python-requests >= 2.14.2 Requires: python-six >= 1.4.0 Requires: python-websocket-client >= 0.32.0 @@ -51,6 +46,11 @@ Obsoletes: python-docker-py < %{version} Provides: python-docker-py = %{version} BuildArch: noarch +%if 0%{?suse_version} < 1320 +BuildRequires: %{oldpython} +BuildRequires: %{python_module backports.ssl_match_hostname >= 3.5} +BuildRequires: python3 +%endif %ifpython2 Requires: %{oldpython}-backports.ssl_match_hostname >= 3.5 Requires: %{oldpython}-ipaddress >= 1.0.16 @@ -80,8 +80,9 @@ %files %{python_files} %license LICENSE %doc README.md -%dir %{python_sitelib}/* +%dir %{python_sitelib}/docker +%dir %{python_sitelib}/docker-%{version}-*.egg-info %{python_sitelib}/docker/* -%{python_sitelib}/*egg-info/* +%{python_sitelib}/docker*egg-info/* %changelog ++++++ docker-3.4.1.tar.gz -> docker-3.5.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/PKG-INFO new/docker-3.5.1/PKG-INFO --- old/docker-3.4.1/PKG-INFO 2018-06-29 21:43:11.000000000 +0200 +++ new/docker-3.5.1/PKG-INFO 2018-10-18 00:04:10.000000000 +0200 @@ -1,10 +1,10 @@ -Metadata-Version: 1.1 +Metadata-Version: 2.1 Name: docker -Version: 3.4.1 +Version: 3.5.1 Summary: A Python library for the Docker Engine API. Home-page: https://github.com/docker/docker-py -Author: Joffrey F -Author-email: [email protected] +Maintainer: Joffrey F +Maintainer-email: [email protected] License: Apache License 2.0 Description: Docker SDK for Python ===================== @@ -114,5 +114,7 @@ Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 Classifier: Topic :: Utilities Classifier: License :: OSI Approved :: Apache Software License +Provides-Extra: tls diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/docker/api/build.py new/docker-3.5.1/docker/api/build.py --- old/docker-3.4.1/docker/api/build.py 2018-06-29 20:29:12.000000000 +0200 +++ new/docker-3.5.1/docker/api/build.py 2018-08-21 19:56:12.000000000 +0200 @@ -293,20 +293,28 @@ # Send the full auth configuration (if any exists), since the build # could use any (or all) of the registries. if self._auth_configs: + auth_cfgs = self._auth_configs auth_data = {} - if self._auth_configs.get('credsStore'): + if auth_cfgs.get('credsStore'): # Using a credentials store, we need to retrieve the # credentials for each registry listed in the config.json file # Matches CLI behavior: https://github.com/docker/docker/blob/ # 67b85f9d26f1b0b2b240f2d794748fac0f45243c/cliconfig/ # credentials/native_store.go#L68-L83 - for registry in self._auth_configs.get('auths', {}).keys(): + for registry in auth_cfgs.get('auths', {}).keys(): auth_data[registry] = auth.resolve_authconfig( - self._auth_configs, registry, + auth_cfgs, registry, credstore_env=self.credstore_env, ) else: - auth_data = self._auth_configs.get('auths', {}).copy() + for registry in auth_cfgs.get('credHelpers', {}).keys(): + auth_data[registry] = auth.resolve_authconfig( + auth_cfgs, registry, + credstore_env=self.credstore_env + ) + for registry, creds in auth_cfgs.get('auths', {}).items(): + if registry not in auth_data: + auth_data[registry] = creds # See https://github.com/docker/docker-py/issues/1683 if auth.INDEX_NAME in auth_data: auth_data[auth.INDEX_URL] = auth_data[auth.INDEX_NAME] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/docker/api/container.py new/docker-3.5.1/docker/api/container.py --- old/docker-3.4.1/docker/api/container.py 2018-06-29 21:01:35.000000000 +0200 +++ new/docker-3.5.1/docker/api/container.py 2018-10-18 00:03:50.000000000 +0200 @@ -465,7 +465,7 @@ dns_opt (:py:class:`list`): Additional options to be added to the container's ``resolv.conf`` file dns_search (:py:class:`list`): DNS search domains. - extra_hosts (dict): Addtional hostnames to resolve inside the + extra_hosts (dict): Additional hostnames to resolve inside the container, as a mapping of hostname to IP address. group_add (:py:class:`list`): List of additional group names and/or IDs that the container process will run as. @@ -547,6 +547,8 @@ userns_mode (str): Sets the user namespace mode for the container when user namespace remapping option is enabled. Supported values are: ``host`` + uts_mode (str): Sets the UTS namespace mode for the container. + Supported values are: ``host`` volumes_from (:py:class:`list`): List of container names or IDs to get volumes from. runtime (str): Runtime to use with this container. @@ -763,16 +765,16 @@ Args: container (str): The container to get logs from - stdout (bool): Get ``STDOUT`` - stderr (bool): Get ``STDERR`` - stream (bool): Stream the response - timestamps (bool): Show timestamps + stdout (bool): Get ``STDOUT``. Default ``True`` + stderr (bool): Get ``STDERR``. Default ``True`` + stream (bool): Stream the response. Default ``False`` + timestamps (bool): Show timestamps. Default ``False`` tail (str or int): Output specified number of lines at the end of logs. Either an integer of number of lines or the string ``all``. Default ``all`` since (datetime or int): Show logs since a given datetime or integer epoch (in seconds) - follow (bool): Follow log output + follow (bool): Follow log output. Default ``False`` until (datetime or int): Show logs that occurred before the given datetime or integer epoch (in seconds) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/docker/api/mixin.py new/docker-3.5.1/docker/api/mixin.py --- old/docker-3.4.1/docker/api/mixin.py 1970-01-01 01:00:00.000000000 +0100 +++ new/docker-3.5.1/docker/api/mixin.py 2018-08-18 02:47:04.000000000 +0200 @@ -0,0 +1,57 @@ +from typing import Any, Dict, Iterable, List, Optional, Union + +import requests + +from ..constants import DEFAULT_DOCKER_API_VERSION, DEFAULT_TIMEOUT_SECONDS + +class BaseMixin(object): + base_url: str = '' + credstore_env: Optional[Dict[str, str]] = None + timeout: int = DEFAULT_TIMEOUT_SECONDS + _auth_configs: Dict[str, Dict] + _general_configs: Dict[str, Dict] + _version: str = DEFAULT_DOCKER_API_VERSION + + def _url(self, pathfmt: str, *args, **kwargs) -> str: + raise NotImplemented + + def _post(self, url: str, **kwargs) -> requests.Response: + raise NotImplemented + + def _get(self, url: str, **kwargs) -> requests.Response: + raise NotImplemented + + def _put(self, url: str, **kwargs) -> requests.Response: + raise NotImplemented + + def _delete(self, url: str, **kwargs) -> requests.Response: + raise NotImplemented + + def _post_json(self, url: str, data: Optional[Union[Dict[str, Any], List[Any]]], **kwargs) -> requests.Response: + raise NotImplemented + + def _raise_for_status(self, response: requests.Response) -> None: + raise NotImplemented + + def _result(self, response: requests.Response, json: bool=False, binary: bool=False) -> Any: + raise NotImplemented + + def _stream_helper(self, response: requests.Response, decode: bool = False) -> Iterable: + raise NotImplemented + + def _get_raw_response_socket(self, response: requests.Response) -> Iterable: + raise NotImplemented + + def _read_from_socket( + self, + response: requests.Response, + stream: bool, + tty: bool = False) -> Union[Iterable[bytes], bytes]: + raise NotImplemented + + def _stream_raw_result( + self, + response: requests.Response, + chunk_size: int = 1, + decode: bool = True) -> Iterable[bytes]: + raise NotImplemented diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/docker/api/service.py new/docker-3.5.1/docker/api/service.py --- old/docker-3.4.1/docker/api/service.py 2018-03-20 09:47:00.000000000 +0100 +++ new/docker-3.5.1/docker/api/service.py 2018-08-21 19:56:12.000000000 +0200 @@ -2,7 +2,8 @@ from ..types import ServiceMode -def _check_api_features(version, task_template, update_config, endpoint_spec): +def _check_api_features(version, task_template, update_config, endpoint_spec, + rollback_config): def raise_version_error(param, min_version): raise errors.InvalidVersion( @@ -18,10 +19,24 @@ if 'Monitor' in update_config: raise_version_error('UpdateConfig.monitor', '1.25') + if utils.version_lt(version, '1.28'): + if update_config.get('FailureAction') == 'rollback': + raise_version_error( + 'UpdateConfig.failure_action rollback', '1.28' + ) + if utils.version_lt(version, '1.29'): if 'Order' in update_config: raise_version_error('UpdateConfig.order', '1.29') + if rollback_config is not None: + if utils.version_lt(version, '1.28'): + raise_version_error('rollback_config', '1.28') + + if utils.version_lt(version, '1.29'): + if 'Order' in update_config: + raise_version_error('RollbackConfig.order', '1.29') + if endpoint_spec is not None: if utils.version_lt(version, '1.32') and 'Ports' in endpoint_spec: if any(p.get('PublishMode') for p in endpoint_spec['Ports']): @@ -99,7 +114,7 @@ def create_service( self, task_template, name=None, labels=None, mode=None, update_config=None, networks=None, endpoint_config=None, - endpoint_spec=None + endpoint_spec=None, rollback_config=None ): """ Create a service. @@ -114,6 +129,8 @@ or global). Defaults to replicated. update_config (UpdateConfig): Specification for the update strategy of the service. Default: ``None`` + rollback_config (RollbackConfig): Specification for the rollback + strategy of the service. Default: ``None`` networks (:py:class:`list`): List of network names or IDs to attach the service to. Default: ``None``. endpoint_spec (EndpointSpec): Properties that can be configured to @@ -129,7 +146,8 @@ """ _check_api_features( - self._version, task_template, update_config, endpoint_spec + self._version, task_template, update_config, endpoint_spec, + rollback_config ) url = self._url('/services/create') @@ -160,6 +178,9 @@ if update_config is not None: data['UpdateConfig'] = update_config + if rollback_config is not None: + data['RollbackConfig'] = rollback_config + return self._result( self._post_json(url, data=data, headers=headers), True ) @@ -336,7 +357,8 @@ def update_service(self, service, version, task_template=None, name=None, labels=None, mode=None, update_config=None, networks=None, endpoint_config=None, - endpoint_spec=None, fetch_current_spec=False): + endpoint_spec=None, fetch_current_spec=False, + rollback_config=None): """ Update a service. @@ -354,6 +376,8 @@ or global). Defaults to replicated. update_config (UpdateConfig): Specification for the update strategy of the service. Default: ``None``. + rollback_config (RollbackConfig): Specification for the rollback + strategy of the service. Default: ``None`` networks (:py:class:`list`): List of network names or IDs to attach the service to. Default: ``None``. endpoint_spec (EndpointSpec): Properties that can be configured to @@ -370,7 +394,8 @@ """ _check_api_features( - self._version, task_template, update_config, endpoint_spec + self._version, task_template, update_config, endpoint_spec, + rollback_config ) if fetch_current_spec: @@ -416,6 +441,11 @@ else: data['UpdateConfig'] = current.get('UpdateConfig') + if rollback_config is not None: + data['RollbackConfig'] = rollback_config + else: + data['RollbackConfig'] = current.get('RollbackConfig') + if networks is not None: converted_networks = utils.convert_service_networks(networks) if utils.version_lt(self._version, '1.25'): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/docker/models/containers.py new/docker-3.5.1/docker/models/containers.py --- old/docker-3.4.1/docker/models/containers.py 2018-06-29 20:29:09.000000000 +0200 +++ new/docker-3.5.1/docker/models/containers.py 2018-10-18 00:03:50.000000000 +0200 @@ -253,16 +253,16 @@ generator you can iterate over to retrieve log output as it happens. Args: - stdout (bool): Get ``STDOUT`` - stderr (bool): Get ``STDERR`` - stream (bool): Stream the response - timestamps (bool): Show timestamps + stdout (bool): Get ``STDOUT``. Default ``True`` + stderr (bool): Get ``STDERR``. Default ``True`` + stream (bool): Stream the response. Default ``False`` + timestamps (bool): Show timestamps. Default ``False`` tail (str or int): Output specified number of lines at the end of logs. Either an integer of number of lines or the string ``all``. Default ``all`` since (datetime or int): Show logs since a given datetime or integer epoch (in seconds) - follow (bool): Follow log output + follow (bool): Follow log output. Default ``False`` until (datetime or int): Show logs that occurred before the given datetime or integer epoch (in seconds) @@ -558,7 +558,7 @@ environment (dict or list): Environment variables to set inside the container, as a dictionary or a list of strings in the format ``["SOMEVARIABLE=xxx"]``. - extra_hosts (dict): Addtional hostnames to resolve inside the + extra_hosts (dict): Additional hostnames to resolve inside the container, as a mapping of hostname to IP address. group_add (:py:class:`list`): List of additional group names and/or IDs that the container process will run as. @@ -995,6 +995,7 @@ 'tmpfs', 'ulimits', 'userns_mode', + 'uts_mode', 'version', 'volumes_from', 'runtime' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/docker/models/images.py new/docker-3.5.1/docker/models/images.py --- old/docker-3.4.1/docker/models/images.py 2018-04-26 02:56:44.000000000 +0200 +++ new/docker-3.5.1/docker/models/images.py 2018-10-18 00:03:50.000000000 +0200 @@ -64,9 +64,9 @@ Get a tarball of an image. Similar to the ``docker save`` command. Args: - chunk_size (int): The number of bytes returned by each iteration - of the generator. If ``None``, data will be streamed as it is - received. Default: 2 MB + chunk_size (int): The generator will return up to that much data + per iteration, but may return less. If ``None``, data will be + streamed as it is received. Default: 2 MB Returns: (generator): A stream of raw archive data. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/docker/models/services.py new/docker-3.5.1/docker/models/services.py --- old/docker-3.4.1/docker/models/services.py 2018-06-29 20:29:12.000000000 +0200 +++ new/docker-3.5.1/docker/models/services.py 2018-10-18 00:03:50.000000000 +0200 @@ -1,6 +1,6 @@ import copy from docker.errors import create_unexpected_kwargs_error, InvalidArgument -from docker.types import TaskTemplate, ContainerSpec, ServiceMode +from docker.types import TaskTemplate, ContainerSpec, Placement, ServiceMode from .resource import Model, Collection @@ -42,7 +42,7 @@ ``label``, and ``desired-state``. Returns: - (:py:class:`list`): List of task dictionaries. + :py:class:`list`: List of task dictionaries. Raises: :py:class:`docker.errors.APIError` @@ -84,26 +84,27 @@ def logs(self, **kwargs): """ - Get log stream for the service. - Note: This method works only for services with the ``json-file`` - or ``journald`` logging drivers. - - Args: - details (bool): Show extra details provided to logs. - Default: ``False`` - follow (bool): Keep connection open to read logs as they are - sent by the Engine. Default: ``False`` - stdout (bool): Return logs from ``stdout``. Default: ``False`` - stderr (bool): Return logs from ``stderr``. Default: ``False`` - since (int): UNIX timestamp for the logs staring point. - Default: 0 - timestamps (bool): Add timestamps to every log line. - tail (string or int): Number of log lines to be returned, - counting from the current end of the logs. Specify an - integer or ``'all'`` to output all log lines. - Default: ``all`` + Get log stream for the service. + Note: This method works only for services with the ``json-file`` + or ``journald`` logging drivers. - Returns (generator): Logs for the service. + Args: + details (bool): Show extra details provided to logs. + Default: ``False`` + follow (bool): Keep connection open to read logs as they are + sent by the Engine. Default: ``False`` + stdout (bool): Return logs from ``stdout``. Default: ``False`` + stderr (bool): Return logs from ``stderr``. Default: ``False`` + since (int): UNIX timestamp for the logs staring point. + Default: 0 + timestamps (bool): Add timestamps to every log line. + tail (string or int): Number of log lines to be returned, + counting from the current end of the logs. Specify an + integer or ``'all'`` to output all log lines. + Default: ``all`` + + Returns: + generator: Logs for the service. """ is_tty = self.attrs['Spec']['TaskTemplate']['ContainerSpec'].get( 'TTY', False @@ -118,7 +119,7 @@ replicas (int): The number of containers that should be running. Returns: - ``True``if successful. + bool: ``True`` if successful. """ if 'Global' in self.attrs['Spec']['Mode'].keys(): @@ -134,7 +135,7 @@ Force update the service even if no changes require it. Returns: - ``True``if successful. + bool: ``True`` if successful. """ return self.update(force_update=True, fetch_current_spec=True) @@ -153,6 +154,9 @@ command (list of str or str): Command to run. args (list of str): Arguments to the command. constraints (list of str): Placement constraints. + preferences (list of str): Placement preferences. + platforms (list of tuple): A list of platforms constraints + expressed as ``(arch, os)`` tuples container_labels (dict): Labels to apply to the container. endpoint_spec (EndpointSpec): Properties that can be configured to access and load balance a service. Default: ``None``. @@ -180,6 +184,8 @@ containers to terminate before forcefully killing them. update_config (UpdateConfig): Specification for the update strategy of the service. Default: ``None`` + rollback_config (RollbackConfig): Specification for the rollback + strategy of the service. Default: ``None`` user (str): User to run commands as. workdir (str): Working directory for commands to run. tty (boolean): Whether a pseudo-TTY should be allocated. @@ -201,7 +207,7 @@ containers. Returns: - (:py:class:`Service`) The created service. + :py:class:`Service`: The created service. Raises: :py:class:`docker.errors.APIError` @@ -223,7 +229,7 @@ into the output. Returns: - (:py:class:`Service`): The service. + :py:class:`Service`: The service. Raises: :py:class:`docker.errors.NotFound` @@ -248,7 +254,7 @@ Default: ``None``. Returns: - (list of :py:class:`Service`): The services. + list of :py:class:`Service`: The services. Raises: :py:class:`docker.errors.APIError` @@ -302,6 +308,12 @@ 'endpoint_spec', ] +PLACEMENT_KWARGS = [ + 'constraints', + 'preferences', + 'platforms', +] + def _get_create_service_kwargs(func_name, kwargs): # Copy over things which can be copied directly @@ -321,10 +333,12 @@ if 'container_labels' in kwargs: container_spec_kwargs['labels'] = kwargs.pop('container_labels') - if 'constraints' in kwargs: - task_template_kwargs['placement'] = { - 'Constraints': kwargs.pop('constraints') - } + placement = {} + for key in copy.copy(kwargs): + if key in PLACEMENT_KWARGS: + placement[key] = kwargs.pop(key) + placement = Placement(**placement) + task_template_kwargs['placement'] = placement if 'log_driver' in kwargs: task_template_kwargs['log_driver'] = { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/docker/types/__init__.py new/docker-3.5.1/docker/types/__init__.py --- old/docker-3.4.1/docker/types/__init__.py 2018-03-30 01:25:27.000000000 +0200 +++ new/docker-3.5.1/docker/types/__init__.py 2018-08-10 02:24:32.000000000 +0200 @@ -5,7 +5,7 @@ from .networks import EndpointConfig, IPAMConfig, IPAMPool, NetworkingConfig from .services import ( ConfigReference, ContainerSpec, DNSConfig, DriverConfig, EndpointSpec, - Mount, Placement, Privileges, Resources, RestartPolicy, SecretReference, - ServiceMode, TaskTemplate, UpdateConfig + Mount, Placement, Privileges, Resources, RestartPolicy, RollbackConfig, + SecretReference, ServiceMode, TaskTemplate, UpdateConfig ) from .swarm import SwarmSpec, SwarmExternalCA diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/docker/types/containers.py new/docker-3.5.1/docker/types/containers.py --- old/docker-3.4.1/docker/types/containers.py 2018-06-29 20:29:09.000000000 +0200 +++ new/docker-3.5.1/docker/types/containers.py 2018-08-10 02:24:32.000000000 +0200 @@ -115,11 +115,11 @@ device_read_iops=None, device_write_iops=None, oom_kill_disable=False, shm_size=None, sysctls=None, tmpfs=None, oom_score_adj=None, dns_opt=None, cpu_shares=None, - cpuset_cpus=None, userns_mode=None, pids_limit=None, - isolation=None, auto_remove=False, storage_opt=None, - init=None, init_path=None, volume_driver=None, - cpu_count=None, cpu_percent=None, nano_cpus=None, - cpuset_mems=None, runtime=None, mounts=None, + cpuset_cpus=None, userns_mode=None, uts_mode=None, + pids_limit=None, isolation=None, auto_remove=False, + storage_opt=None, init=None, init_path=None, + volume_driver=None, cpu_count=None, cpu_percent=None, + nano_cpus=None, cpuset_mems=None, runtime=None, mounts=None, cpu_rt_period=None, cpu_rt_runtime=None, device_cgroup_rules=None): @@ -392,6 +392,11 @@ raise host_config_value_error("userns_mode", userns_mode) self['UsernsMode'] = userns_mode + if uts_mode: + if uts_mode != "host": + raise host_config_value_error("uts_mode", uts_mode) + self['UTSMode'] = uts_mode + if pids_limit: if not isinstance(pids_limit, int): raise host_config_type_error('pids_limit', pids_limit, 'int') @@ -573,7 +578,7 @@ 'Hostname': hostname, 'Domainname': domainname, 'ExposedPorts': ports, - 'User': six.text_type(user) if user else None, + 'User': six.text_type(user) if user is not None else None, 'Tty': tty, 'OpenStdin': stdin_open, 'StdinOnce': stdin_once, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/docker/types/services.py new/docker-3.5.1/docker/types/services.py --- old/docker-3.4.1/docker/types/services.py 2018-06-29 20:29:12.000000000 +0200 +++ new/docker-3.5.1/docker/types/services.py 2018-08-10 02:24:32.000000000 +0200 @@ -368,10 +368,11 @@ parallelism (int): Maximum number of tasks to be updated in one iteration (0 means unlimited parallelism). Default: 0. - delay (int): Amount of time between updates. + delay (int): Amount of time between updates, in nanoseconds. failure_action (string): Action to take if an updated task fails to run, or stops running during the update. Acceptable values are - ``continue`` and ``pause``. Default: ``continue`` + ``continue``, ``pause``, as well as ``rollback`` since API v1.28. + Default: ``continue`` monitor (int): Amount of time to monitor each updated task for failures, in nanoseconds. max_failure_ratio (float): The fraction of tasks that may fail during @@ -385,9 +386,9 @@ self['Parallelism'] = parallelism if delay is not None: self['Delay'] = delay - if failure_action not in ('pause', 'continue'): + if failure_action not in ('pause', 'continue', 'rollback'): raise errors.InvalidArgument( - 'failure_action must be either `pause` or `continue`.' + 'failure_action must be one of `pause`, `continue`, `rollback`' ) self['FailureAction'] = failure_action @@ -413,6 +414,30 @@ self['Order'] = order +class RollbackConfig(UpdateConfig): + """ + Used to specify the way containe rollbacks should be performed by a service + + Args: + parallelism (int): Maximum number of tasks to be rolled back in one + iteration (0 means unlimited parallelism). Default: 0 + delay (int): Amount of time between rollbacks, in nanoseconds. + failure_action (string): Action to take if a rolled back task fails to + run, or stops running during the rollback. Acceptable values are + ``continue``, ``pause`` or ``rollback``. + Default: ``continue`` + monitor (int): Amount of time to monitor each rolled back task for + failures, in nanoseconds. + max_failure_ratio (float): The fraction of tasks that may fail during + a rollback before the failure action is invoked, specified as a + floating point number between 0 and 1. Default: 0 + order (string): Specifies the order of operations when rolling out a + rolled back task. Either ``start_first`` or ``stop_first`` are + accepted. + """ + pass + + class RestartConditionTypesEnum(object): _values = ( 'none', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/docker/version.py new/docker-3.5.1/docker/version.py --- old/docker-3.4.1/docker/version.py 2018-06-29 21:01:35.000000000 +0200 +++ new/docker-3.5.1/docker/version.py 2018-10-18 00:03:50.000000000 +0200 @@ -1,2 +1,2 @@ -version = "3.4.1" +version = "3.5.1" version_info = tuple([int(d) for d in version.split("-")[0].split(".")]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/docker.egg-info/PKG-INFO new/docker-3.5.1/docker.egg-info/PKG-INFO --- old/docker-3.4.1/docker.egg-info/PKG-INFO 2018-06-29 21:43:11.000000000 +0200 +++ new/docker-3.5.1/docker.egg-info/PKG-INFO 2018-10-18 00:04:10.000000000 +0200 @@ -1,10 +1,10 @@ -Metadata-Version: 1.1 +Metadata-Version: 2.1 Name: docker -Version: 3.4.1 +Version: 3.5.1 Summary: A Python library for the Docker Engine API. Home-page: https://github.com/docker/docker-py -Author: Joffrey F -Author-email: [email protected] +Maintainer: Joffrey F +Maintainer-email: [email protected] License: Apache License 2.0 Description: Docker SDK for Python ===================== @@ -114,5 +114,7 @@ Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 Classifier: Topic :: Utilities Classifier: License :: OSI Approved :: Apache Software License +Provides-Extra: tls diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/docker.egg-info/SOURCES.txt new/docker-3.5.1/docker.egg-info/SOURCES.txt --- old/docker-3.4.1/docker.egg-info/SOURCES.txt 2018-06-29 21:43:11.000000000 +0200 +++ new/docker-3.5.1/docker.egg-info/SOURCES.txt 2018-10-18 00:04:10.000000000 +0200 @@ -17,6 +17,7 @@ docker.egg-info/SOURCES.txt docker.egg-info/dependency_links.txt docker.egg-info/not-zip-safe +docker.egg-info/pbr.json docker.egg-info/requires.txt docker.egg-info/top_level.txt docker/api/__init__.py @@ -27,6 +28,7 @@ docker/api/daemon.py docker/api/exec_api.py docker/api/image.py +docker/api/mixin.py docker/api/network.py docker/api/plugin.py docker/api/secret.py @@ -120,6 +122,7 @@ tests/unit/models_services_test.py tests/unit/ssladapter_test.py tests/unit/swarm_test.py +tests/unit/types_containers_test.py tests/unit/utils_build_test.py tests/unit/utils_config_test.py tests/unit/utils_json_stream_test.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/docker.egg-info/pbr.json new/docker-3.5.1/docker.egg-info/pbr.json --- old/docker-3.4.1/docker.egg-info/pbr.json 1970-01-01 01:00:00.000000000 +0100 +++ new/docker-3.5.1/docker.egg-info/pbr.json 2018-09-26 22:40:27.000000000 +0200 @@ -0,0 +1 @@ +{"is_release": false, "git_version": "2b10c37"} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/docker.egg-info/requires.txt new/docker-3.5.1/docker.egg-info/requires.txt --- old/docker-3.4.1/docker.egg-info/requires.txt 2018-06-29 21:43:11.000000000 +0200 +++ new/docker-3.5.1/docker.egg-info/requires.txt 2018-10-18 00:04:10.000000000 +0200 @@ -1,7 +1,7 @@ -requests!=2.18.0,>=2.14.2 six>=1.4.0 websocket-client>=0.32.0 docker-pycreds>=0.3.0 +requests!=2.18.0,>=2.14.2 [:python_version < "3.3"] ipaddress>=1.0.16 @@ -9,13 +9,16 @@ [:python_version < "3.5"] backports.ssl_match_hostname>=3.5 +[:python_version == "3.3"] +urllib3<1.23 + [:sys_platform == "win32" and python_version < "3.6"] pypiwin32==219 [:sys_platform == "win32" and python_version >= "3.6"] -pypiwin32==220 +pypiwin32==223 [tls] -pyOpenSSL>=0.14 +pyOpenSSL>=17.5.0 cryptography>=1.3.4 idna>=2.0.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/requirements.txt new/docker-3.5.1/requirements.txt --- old/docker-3.4.1/requirements.txt 2018-06-29 20:29:12.000000000 +0200 +++ new/docker-3.5.1/requirements.txt 2018-10-18 00:03:51.000000000 +0200 @@ -2,17 +2,19 @@ asn1crypto==0.22.0 backports.ssl-match-hostname==3.5.0.1 cffi==1.10.0 -cryptography==1.9 +cryptography==1.9; python_version == '3.3' +cryptography==2.3; python_version > '3.3' docker-pycreds==0.3.0 enum34==1.1.6 idna==2.5 ipaddress==1.0.18 packaging==16.8 pycparser==2.17 -pyOpenSSL==17.0.0 +pyOpenSSL==18.0.0 pyparsing==2.2.0 pypiwin32==219; sys_platform == 'win32' and python_version < '3.6' -pypiwin32==220; sys_platform == 'win32' and python_version >= '3.6' +pypiwin32==223; sys_platform == 'win32' and python_version >= '3.6' requests==2.14.2 six==1.10.0 websocket-client==0.40.0 +urllib3==1.21.1; python_version == '3.3' \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/setup.py new/docker-3.5.1/setup.py --- old/docker-3.4.1/setup.py 2018-06-29 20:29:12.000000000 +0200 +++ new/docker-3.5.1/setup.py 2018-10-18 00:03:51.000000000 +0200 @@ -10,10 +10,10 @@ SOURCE_DIR = os.path.join(ROOT_DIR) requirements = [ - 'requests >= 2.14.2, != 2.18.0', 'six >= 1.4.0', 'websocket-client >= 0.32.0', - 'docker-pycreds >= 0.3.0' + 'docker-pycreds >= 0.3.0', + 'requests >= 2.14.2, != 2.18.0', ] extras_require = { @@ -27,7 +27,10 @@ # Python 3.6 is only compatible with v220 ; Python < 3.5 is not supported # on v220 ; ALL versions are broken for v222 (as of 2018-01-26) ':sys_platform == "win32" and python_version < "3.6"': 'pypiwin32==219', - ':sys_platform == "win32" and python_version >= "3.6"': 'pypiwin32==220', + ':sys_platform == "win32" and python_version >= "3.6"': 'pypiwin32==223', + + # urllib3 drops support for Python 3.3 in 1.23 + ':python_version == "3.3"': 'urllib3 < 1.23', # If using docker-py over TLS, highly recommend this option is # pip-installed or pinned. @@ -37,7 +40,8 @@ # https://github.com/pypa/pip/issues/4391). Once that's fixed, instead of # installing the extra dependencies, install the following instead: # 'requests[security] >= 2.5.2, != 2.11.0, != 2.12.2' - 'tls': ['pyOpenSSL>=0.14', 'cryptography>=1.3.4', 'idna>=2.0.0'], + 'tls': ['pyOpenSSL>=17.5.0', 'cryptography>=1.3.4', 'idna>=2.0.0'], + } version = None @@ -81,6 +85,7 @@ 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', 'Topic :: Utilities', 'License :: OSI Approved :: Apache Software License', ], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/test-requirements.txt new/docker-3.5.1/test-requirements.txt --- old/docker-3.4.1/test-requirements.txt 2018-03-30 01:25:27.000000000 +0200 +++ new/docker-3.5.1/test-requirements.txt 2018-08-10 02:24:32.000000000 +0200 @@ -1,6 +1,7 @@ coverage==3.7.1 flake8==3.4.1 mock==1.0.1 -pytest==2.9.1 +pytest==2.9.1; python_version == '3.3' +pytest==3.6.3; python_version > '3.3' pytest-cov==2.1.0 pytest-timeout==1.2.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/tests/integration/api_container_test.py new/docker-3.5.1/tests/integration/api_container_test.py --- old/docker-3.4.1/tests/integration/api_container_test.py 2018-06-29 20:29:12.000000000 +0200 +++ new/docker-3.5.1/tests/integration/api_container_test.py 2018-08-10 02:24:32.000000000 +0200 @@ -490,6 +490,16 @@ self.client.start(ctnr) assert rule in self.client.logs(ctnr).decode('utf-8') + def test_create_with_uts_mode(self): + container = self.client.create_container( + BUSYBOX, ['echo'], host_config=self.client.create_host_config( + uts_mode='host' + ) + ) + self.tmp_containers.append(container) + config = self.client.inspect_container(container) + assert config['HostConfig']['UTSMode'] == 'host' + @pytest.mark.xfail( IS_WINDOWS_PLATFORM, reason='Test not designed for Windows platform' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/tests/integration/api_service_test.py new/docker-3.5.1/tests/integration/api_service_test.py --- old/docker-3.4.1/tests/integration/api_service_test.py 2018-03-20 09:47:00.000000000 +0100 +++ new/docker-3.5.1/tests/integration/api_service_test.py 2018-08-10 02:24:32.000000000 +0200 @@ -281,6 +281,20 @@ assert update_config['Delay'] == uc['Delay'] assert update_config['FailureAction'] == uc['FailureAction'] + @requires_api_version('1.28') + def test_create_service_with_failure_action_rollback(self): + container_spec = docker.types.ContainerSpec(BUSYBOX, ['true']) + task_tmpl = docker.types.TaskTemplate(container_spec) + update_config = docker.types.UpdateConfig(failure_action='rollback') + name = self.get_service_name() + svc_id = self.client.create_service( + task_tmpl, update_config=update_config, name=name + ) + svc_info = self.client.inspect_service(svc_id) + assert 'UpdateConfig' in svc_info['Spec'] + uc = svc_info['Spec']['UpdateConfig'] + assert update_config['FailureAction'] == uc['FailureAction'] + @requires_api_version('1.25') def test_create_service_with_update_config_monitor(self): container_spec = docker.types.ContainerSpec('busybox', ['true']) @@ -298,6 +312,27 @@ assert update_config['Monitor'] == uc['Monitor'] assert update_config['MaxFailureRatio'] == uc['MaxFailureRatio'] + @requires_api_version('1.28') + def test_create_service_with_rollback_config(self): + container_spec = docker.types.ContainerSpec(BUSYBOX, ['true']) + task_tmpl = docker.types.TaskTemplate(container_spec) + rollback_cfg = docker.types.RollbackConfig( + parallelism=10, delay=5, failure_action='pause', + monitor=300000000, max_failure_ratio=0.4 + ) + name = self.get_service_name() + svc_id = self.client.create_service( + task_tmpl, rollback_config=rollback_cfg, name=name + ) + svc_info = self.client.inspect_service(svc_id) + assert 'RollbackConfig' in svc_info['Spec'] + rc = svc_info['Spec']['RollbackConfig'] + assert rollback_cfg['Parallelism'] == rc['Parallelism'] + assert rollback_cfg['Delay'] == rc['Delay'] + assert rollback_cfg['FailureAction'] == rc['FailureAction'] + assert rollback_cfg['Monitor'] == rc['Monitor'] + assert rollback_cfg['MaxFailureRatio'] == rc['MaxFailureRatio'] + def test_create_service_with_restart_policy(self): container_spec = docker.types.ContainerSpec(BUSYBOX, ['true']) policy = docker.types.RestartPolicy( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/tests/unit/dockertypes_test.py new/docker-3.5.1/tests/unit/dockertypes_test.py --- old/docker-3.4.1/tests/unit/dockertypes_test.py 2018-06-29 20:29:09.000000000 +0200 +++ new/docker-3.5.1/tests/unit/dockertypes_test.py 2018-08-10 02:24:32.000000000 +0200 @@ -85,6 +85,12 @@ with pytest.raises(ValueError): create_host_config(version='1.23', userns_mode='host12') + def test_create_host_config_with_uts(self): + config = create_host_config(version='1.15', uts_mode='host') + assert config.get('UTSMode') == 'host' + with pytest.raises(ValueError): + create_host_config(version='1.15', uts_mode='host12') + def test_create_host_config_with_oom_score_adj(self): config = create_host_config(version='1.22', oom_score_adj=100) assert config.get('OomScoreAdj') == 100 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/tests/unit/models_containers_test.py new/docker-3.5.1/tests/unit/models_containers_test.py --- old/docker-3.4.1/tests/unit/models_containers_test.py 2018-06-29 20:29:09.000000000 +0200 +++ new/docker-3.5.1/tests/unit/models_containers_test.py 2018-08-10 02:24:32.000000000 +0200 @@ -95,6 +95,7 @@ ulimits=[{"Name": "nofile", "Soft": 1024, "Hard": 2048}], user='bob', userns_mode='host', + uts_mode='host', version='1.23', volume_driver='some_driver', volumes=[ @@ -174,6 +175,7 @@ 'Tmpfs': {'/blah': ''}, 'Ulimits': [{"Name": "nofile", "Soft": 1024, "Hard": 2048}], 'UsernsMode': 'host', + 'UTSMode': 'host', 'VolumesFrom': ['container'], }, healthcheck={'test': 'true'}, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/tests/unit/models_services_test.py new/docker-3.5.1/tests/unit/models_services_test.py --- old/docker-3.4.1/tests/unit/models_services_test.py 2018-02-01 03:21:26.000000000 +0100 +++ new/docker-3.5.1/tests/unit/models_services_test.py 2018-08-10 02:24:32.000000000 +0200 @@ -26,6 +26,8 @@ 'mounts': [{'some': 'mounts'}], 'stop_grace_period': 5, 'constraints': ['foo=bar'], + 'preferences': ['bar=baz'], + 'platforms': [('x86_64', 'linux')], }) task_template = kwargs.pop('task_template') @@ -41,7 +43,11 @@ 'ContainerSpec', 'Resources', 'RestartPolicy', 'Placement', 'LogDriver', 'Networks' ]) - assert task_template['Placement'] == {'Constraints': ['foo=bar']} + assert task_template['Placement'] == { + 'Constraints': ['foo=bar'], + 'Preferences': ['bar=baz'], + 'Platforms': [{'Architecture': 'x86_64', 'OS': 'linux'}], + } assert task_template['LogDriver'] == { 'Name': 'logdriver', 'Options': {'foo': 'bar'} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-3.4.1/tests/unit/types_containers_test.py new/docker-3.5.1/tests/unit/types_containers_test.py --- old/docker-3.4.1/tests/unit/types_containers_test.py 1970-01-01 01:00:00.000000000 +0100 +++ new/docker-3.5.1/tests/unit/types_containers_test.py 2018-08-10 02:24:32.000000000 +0200 @@ -0,0 +1,6 @@ +from docker.types.containers import ContainerConfig + + +def test_uid_0_is_not_elided(): + x = ContainerConfig(image='i', version='v', command='true', user=0) + assert x['User'] == '0'
