mirror of https://github.com/docker/docker-py.git
				
				
				
			
						commit
						66495870de
					
				| 
						 | 
					@ -1,4 +1,6 @@
 | 
				
			||||||
FROM python:2.7
 | 
					ARG PYTHON_VERSION=2.7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FROM python:${PYTHON_VERSION}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN mkdir /src
 | 
					RUN mkdir /src
 | 
				
			||||||
WORKDIR /src
 | 
					WORKDIR /src
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,6 @@
 | 
				
			||||||
FROM python:3.5
 | 
					ARG PYTHON_VERSION=3.7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FROM python:${PYTHON_VERSION}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ARG uid=1000
 | 
					ARG uid=1000
 | 
				
			||||||
ARG gid=1000
 | 
					ARG gid=1000
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,6 @@
 | 
				
			||||||
FROM python:3.6
 | 
					ARG PYTHON_VERSION=3.7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FROM python:${PYTHON_VERSION}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN mkdir /src
 | 
					RUN mkdir /src
 | 
				
			||||||
WORKDIR /src
 | 
					WORKDIR /src
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,7 @@ def buildImages = { ->
 | 
				
			||||||
      imageNamePy3 = "${imageNameBase}:py3-${gitCommit()}"
 | 
					      imageNamePy3 = "${imageNameBase}:py3-${gitCommit()}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      buildImage(imageNamePy2, "-f tests/Dockerfile --build-arg PYTHON_VERSION=2.7 .", "py2.7")
 | 
					      buildImage(imageNamePy2, "-f tests/Dockerfile --build-arg PYTHON_VERSION=2.7 .", "py2.7")
 | 
				
			||||||
      buildImage(imageNamePy3, "-f tests/Dockerfile --build-arg PYTHON_VERSION=3.6 .", "py3.6")
 | 
					      buildImage(imageNamePy3, "-f tests/Dockerfile --build-arg PYTHON_VERSION=3.7 .", "py3.7")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -46,12 +46,14 @@ def getDockerVersions = { ->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def getAPIVersion = { engineVersion ->
 | 
					def getAPIVersion = { engineVersion ->
 | 
				
			||||||
  def versionMap = [
 | 
					  def versionMap = [
 | 
				
			||||||
    '17.06': '1.30', '17.12': '1.35', '18.02': '1.36', '18.03': '1.37',
 | 
					    '17.06': '1.30',
 | 
				
			||||||
    '18.06': '1.38', '18.09': '1.39'
 | 
					    '18.03': '1.37',
 | 
				
			||||||
 | 
					    '18.09': '1.39',
 | 
				
			||||||
 | 
					    '19.03': '1.40'
 | 
				
			||||||
  ]
 | 
					  ]
 | 
				
			||||||
  def result = versionMap[engineVersion.substring(0, 5)]
 | 
					  def result = versionMap[engineVersion.substring(0, 5)]
 | 
				
			||||||
  if (!result) {
 | 
					  if (!result) {
 | 
				
			||||||
    return '1.39'
 | 
					    return '1.40'
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return result
 | 
					  return result
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										4
									
								
								Makefile
								
								
								
								
							| 
						 | 
					@ -8,11 +8,11 @@ clean:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: build
 | 
					.PHONY: build
 | 
				
			||||||
build:
 | 
					build:
 | 
				
			||||||
	docker build -t docker-sdk-python -f tests/Dockerfile --build-arg PYTHON_VERSION=2.7 .
 | 
						docker build -t docker-sdk-python -f tests/Dockerfile --build-arg PYTHON_VERSION=2.7 --build-arg APT_MIRROR .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: build-py3
 | 
					.PHONY: build-py3
 | 
				
			||||||
build-py3:
 | 
					build-py3:
 | 
				
			||||||
	docker build -t docker-sdk-python3 -f tests/Dockerfile .
 | 
						docker build -t docker-sdk-python3 -f tests/Dockerfile --build-arg APT_MIRROR .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: build-docs
 | 
					.PHONY: build-docs
 | 
				
			||||||
build-docs:
 | 
					build-docs:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -308,7 +308,8 @@ class BuildApiMixin(object):
 | 
				
			||||||
            auth_data = self._auth_configs.get_all_credentials()
 | 
					            auth_data = self._auth_configs.get_all_credentials()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # See https://github.com/docker/docker-py/issues/1683
 | 
					            # See https://github.com/docker/docker-py/issues/1683
 | 
				
			||||||
            if auth.INDEX_URL not in auth_data and auth.INDEX_URL in auth_data:
 | 
					            if (auth.INDEX_URL not in auth_data and
 | 
				
			||||||
 | 
					                    auth.INDEX_NAME in auth_data):
 | 
				
			||||||
                auth_data[auth.INDEX_URL] = auth_data.get(auth.INDEX_NAME, {})
 | 
					                auth_data[auth.INDEX_URL] = auth_data.get(auth.INDEX_NAME, {})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            log.debug(
 | 
					            log.debug(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -174,7 +174,8 @@ class ContainerApiMixin(object):
 | 
				
			||||||
                - `exited` (int): Only containers with specified exit code
 | 
					                - `exited` (int): Only containers with specified exit code
 | 
				
			||||||
                - `status` (str): One of ``restarting``, ``running``,
 | 
					                - `status` (str): One of ``restarting``, ``running``,
 | 
				
			||||||
                    ``paused``, ``exited``
 | 
					                    ``paused``, ``exited``
 | 
				
			||||||
                - `label` (str): format either ``"key"`` or ``"key=value"``
 | 
					                - `label` (str|list): format either ``"key"``, ``"key=value"``
 | 
				
			||||||
 | 
					                    or a list of such.
 | 
				
			||||||
                - `id` (str): The id of the container.
 | 
					                - `id` (str): The id of the container.
 | 
				
			||||||
                - `name` (str): The name of the container.
 | 
					                - `name` (str): The name of the container.
 | 
				
			||||||
                - `ancestor` (str): Filter by container ancestor. Format of
 | 
					                - `ancestor` (str): Filter by container ancestor. Format of
 | 
				
			||||||
| 
						 | 
					@ -502,6 +503,7 @@ class ContainerApiMixin(object):
 | 
				
			||||||
                bytes) or a string with a units identification char
 | 
					                bytes) or a string with a units identification char
 | 
				
			||||||
                (``100000b``, ``1000k``, ``128m``, ``1g``). If a string is
 | 
					                (``100000b``, ``1000k``, ``128m``, ``1g``). If a string is
 | 
				
			||||||
                specified without a units character, bytes are assumed as an
 | 
					                specified without a units character, bytes are assumed as an
 | 
				
			||||||
 | 
					            mem_reservation (int or str): Memory soft limit.
 | 
				
			||||||
            mem_swappiness (int): Tune a container's memory swappiness
 | 
					            mem_swappiness (int): Tune a container's memory swappiness
 | 
				
			||||||
                behavior. Accepts number between 0 and 100.
 | 
					                behavior. Accepts number between 0 and 100.
 | 
				
			||||||
            memswap_limit (str or int): Maximum amount of memory + swap a
 | 
					            memswap_limit (str or int): Maximum amount of memory + swap a
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,7 +70,8 @@ class ImageApiMixin(object):
 | 
				
			||||||
            filters (dict): Filters to be processed on the image list.
 | 
					            filters (dict): Filters to be processed on the image list.
 | 
				
			||||||
                Available filters:
 | 
					                Available filters:
 | 
				
			||||||
                - ``dangling`` (bool)
 | 
					                - ``dangling`` (bool)
 | 
				
			||||||
                - ``label`` (str): format either ``key`` or ``key=value``
 | 
					                - `label` (str|list): format either ``"key"``, ``"key=value"``
 | 
				
			||||||
 | 
					                    or a list of such.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            (dict or list): A list if ``quiet=True``, otherwise a dict.
 | 
					            (dict or list): A list if ``quiet=True``, otherwise a dict.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,7 @@ from .. import utils
 | 
				
			||||||
class NetworkApiMixin(object):
 | 
					class NetworkApiMixin(object):
 | 
				
			||||||
    def networks(self, names=None, ids=None, filters=None):
 | 
					    def networks(self, names=None, ids=None, filters=None):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        List networks. Similar to the ``docker networks ls`` command.
 | 
					        List networks. Similar to the ``docker network ls`` command.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Args:
 | 
					        Args:
 | 
				
			||||||
            names (:py:class:`list`): List of names to filter by
 | 
					            names (:py:class:`list`): List of names to filter by
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,8 @@ class NetworkApiMixin(object):
 | 
				
			||||||
            filters (dict): Filters to be processed on the network list.
 | 
					            filters (dict): Filters to be processed on the network list.
 | 
				
			||||||
                Available filters:
 | 
					                Available filters:
 | 
				
			||||||
                - ``driver=[<driver-name>]`` Matches a network's driver.
 | 
					                - ``driver=[<driver-name>]`` Matches a network's driver.
 | 
				
			||||||
                - ``label=[<key>]`` or ``label=[<key>=<value>]``.
 | 
					                - ``label=[<key>]``, ``label=[<key>=<value>]`` or a list of
 | 
				
			||||||
 | 
					                    such.
 | 
				
			||||||
                - ``type=["custom"|"builtin"]`` Filters networks by type.
 | 
					                - ``type=["custom"|"builtin"]`` Filters networks by type.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -135,8 +135,9 @@ class ServiceApiMixin(object):
 | 
				
			||||||
                of the service. Default: ``None``
 | 
					                of the service. Default: ``None``
 | 
				
			||||||
            rollback_config (RollbackConfig): Specification for the rollback
 | 
					            rollback_config (RollbackConfig): Specification for the rollback
 | 
				
			||||||
                strategy of the service. Default: ``None``
 | 
					                strategy of the service. Default: ``None``
 | 
				
			||||||
            networks (:py:class:`list`): List of network names or IDs to attach
 | 
					            networks (:py:class:`list`): List of network names or IDs or
 | 
				
			||||||
                the service to. Default: ``None``.
 | 
					                :py:class:`~docker.types.NetworkAttachmentConfig` to attach the
 | 
				
			||||||
 | 
					                service to. Default: ``None``.
 | 
				
			||||||
            endpoint_spec (EndpointSpec): Properties that can be configured to
 | 
					            endpoint_spec (EndpointSpec): Properties that can be configured to
 | 
				
			||||||
                access and load balance a service. Default: ``None``.
 | 
					                access and load balance a service. Default: ``None``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -383,8 +384,9 @@ class ServiceApiMixin(object):
 | 
				
			||||||
                of the service. Default: ``None``.
 | 
					                of the service. Default: ``None``.
 | 
				
			||||||
            rollback_config (RollbackConfig): Specification for the rollback
 | 
					            rollback_config (RollbackConfig): Specification for the rollback
 | 
				
			||||||
                strategy of the service. Default: ``None``
 | 
					                strategy of the service. Default: ``None``
 | 
				
			||||||
            networks (:py:class:`list`): List of network names or IDs to attach
 | 
					            networks (:py:class:`list`): List of network names or IDs or
 | 
				
			||||||
                the service to. Default: ``None``.
 | 
					                :py:class:`~docker.types.NetworkAttachmentConfig` to attach the
 | 
				
			||||||
 | 
					                service to. Default: ``None``.
 | 
				
			||||||
            endpoint_spec (EndpointSpec): Properties that can be configured to
 | 
					            endpoint_spec (EndpointSpec): Properties that can be configured to
 | 
				
			||||||
                access and load balance a service. Default: ``None``.
 | 
					                access and load balance a service. Default: ``None``.
 | 
				
			||||||
            fetch_current_spec (boolean): Use the undefined settings from the
 | 
					            fetch_current_spec (boolean): Use the undefined settings from the
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -303,12 +303,14 @@ class AuthConfig(dict):
 | 
				
			||||||
                auth_data[k] = self._resolve_authconfig_credstore(
 | 
					                auth_data[k] = self._resolve_authconfig_credstore(
 | 
				
			||||||
                    k, self.creds_store
 | 
					                    k, self.creds_store
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
					                auth_data[convert_to_hostname(k)] = auth_data[k]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # credHelpers entries take priority over all others
 | 
					        # credHelpers entries take priority over all others
 | 
				
			||||||
        for reg, store_name in self.cred_helpers.items():
 | 
					        for reg, store_name in self.cred_helpers.items():
 | 
				
			||||||
            auth_data[reg] = self._resolve_authconfig_credstore(
 | 
					            auth_data[reg] = self._resolve_authconfig_credstore(
 | 
				
			||||||
                reg, store_name
 | 
					                reg, store_name
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					            auth_data[convert_to_hostname(reg)] = auth_data[reg]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return auth_data
 | 
					        return auth_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -618,7 +618,7 @@ class ContainerCollection(Collection):
 | 
				
			||||||
                (``100000b``, ``1000k``, ``128m``, ``1g``). If a string is
 | 
					                (``100000b``, ``1000k``, ``128m``, ``1g``). If a string is
 | 
				
			||||||
                specified without a units character, bytes are assumed as an
 | 
					                specified without a units character, bytes are assumed as an
 | 
				
			||||||
                intended unit.
 | 
					                intended unit.
 | 
				
			||||||
            mem_reservation (int or str): Memory soft limit
 | 
					            mem_reservation (int or str): Memory soft limit.
 | 
				
			||||||
            mem_swappiness (int): Tune a container's memory swappiness
 | 
					            mem_swappiness (int): Tune a container's memory swappiness
 | 
				
			||||||
                behavior. Accepts number between 0 and 100.
 | 
					                behavior. Accepts number between 0 and 100.
 | 
				
			||||||
            memswap_limit (str or int): Maximum amount of memory + swap a
 | 
					            memswap_limit (str or int): Maximum amount of memory + swap a
 | 
				
			||||||
| 
						 | 
					@ -900,7 +900,8 @@ class ContainerCollection(Collection):
 | 
				
			||||||
                - `exited` (int): Only containers with specified exit code
 | 
					                - `exited` (int): Only containers with specified exit code
 | 
				
			||||||
                - `status` (str): One of ``restarting``, ``running``,
 | 
					                - `status` (str): One of ``restarting``, ``running``,
 | 
				
			||||||
                    ``paused``, ``exited``
 | 
					                    ``paused``, ``exited``
 | 
				
			||||||
                - `label` (str): format either ``"key"`` or ``"key=value"``
 | 
					                - `label` (str|list): format either ``"key"``, ``"key=value"``
 | 
				
			||||||
 | 
					                    or a list of such.
 | 
				
			||||||
                - `id` (str): The id of the container.
 | 
					                - `id` (str): The id of the container.
 | 
				
			||||||
                - `name` (str): The name of the container.
 | 
					                - `name` (str): The name of the container.
 | 
				
			||||||
                - `ancestor` (str): Filter by container ancestor. Format of
 | 
					                - `ancestor` (str): Filter by container ancestor. Format of
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -350,7 +350,8 @@ class ImageCollection(Collection):
 | 
				
			||||||
            filters (dict): Filters to be processed on the image list.
 | 
					            filters (dict): Filters to be processed on the image list.
 | 
				
			||||||
                Available filters:
 | 
					                Available filters:
 | 
				
			||||||
                - ``dangling`` (bool)
 | 
					                - ``dangling`` (bool)
 | 
				
			||||||
                - ``label`` (str): format either ``key`` or ``key=value``
 | 
					                - `label` (str|list): format either ``"key"``, ``"key=value"``
 | 
				
			||||||
 | 
					                    or a list of such.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            (list of :py:class:`Image`): The images.
 | 
					            (list of :py:class:`Image`): The images.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -190,7 +190,8 @@ class NetworkCollection(Collection):
 | 
				
			||||||
            filters (dict): Filters to be processed on the network list.
 | 
					            filters (dict): Filters to be processed on the network list.
 | 
				
			||||||
                Available filters:
 | 
					                Available filters:
 | 
				
			||||||
                - ``driver=[<driver-name>]`` Matches a network's driver.
 | 
					                - ``driver=[<driver-name>]`` Matches a network's driver.
 | 
				
			||||||
                - ``label=[<key>]`` or ``label=[<key>=<value>]``.
 | 
					                - `label` (str|list): format either ``"key"``, ``"key=value"``
 | 
				
			||||||
 | 
					                    or a list of such.
 | 
				
			||||||
                - ``type=["custom"|"builtin"]`` Filters networks by type.
 | 
					                - ``type=["custom"|"builtin"]`` Filters networks by type.
 | 
				
			||||||
            greedy (bool): Fetch more details for each network individually.
 | 
					            greedy (bool): Fetch more details for each network individually.
 | 
				
			||||||
                You might want this to get the containers attached to them.
 | 
					                You might want this to get the containers attached to them.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -178,11 +178,12 @@ class ServiceCollection(Collection):
 | 
				
			||||||
                ``source:target:options``, where options is either
 | 
					                ``source:target:options``, where options is either
 | 
				
			||||||
                ``ro`` or ``rw``.
 | 
					                ``ro`` or ``rw``.
 | 
				
			||||||
            name (str): Name to give to the service.
 | 
					            name (str): Name to give to the service.
 | 
				
			||||||
            networks (list of str): List of network names or IDs to attach
 | 
					            networks (:py:class:`list`): List of network names or IDs or
 | 
				
			||||||
                the service to. Default: ``None``.
 | 
					                :py:class:`~docker.types.NetworkAttachmentConfig` to attach the
 | 
				
			||||||
 | 
					                service to. Default: ``None``.
 | 
				
			||||||
            resources (Resources): Resource limits and reservations.
 | 
					            resources (Resources): Resource limits and reservations.
 | 
				
			||||||
            restart_policy (RestartPolicy): Restart policy for containers.
 | 
					            restart_policy (RestartPolicy): Restart policy for containers.
 | 
				
			||||||
            secrets (list of :py:class:`docker.types.SecretReference`): List
 | 
					            secrets (list of :py:class:`~docker.types.SecretReference`): List
 | 
				
			||||||
                of secrets accessible to containers for this service.
 | 
					                of secrets accessible to containers for this service.
 | 
				
			||||||
            stop_grace_period (int): Amount of time to wait for
 | 
					            stop_grace_period (int): Amount of time to wait for
 | 
				
			||||||
                containers to terminate before forcefully killing them.
 | 
					                containers to terminate before forcefully killing them.
 | 
				
			||||||
| 
						 | 
					@ -205,8 +206,9 @@ class ServiceCollection(Collection):
 | 
				
			||||||
                the container's `hosts` file.
 | 
					                the container's `hosts` file.
 | 
				
			||||||
            dns_config (DNSConfig): Specification for DNS
 | 
					            dns_config (DNSConfig): Specification for DNS
 | 
				
			||||||
                related configurations in resolver configuration file.
 | 
					                related configurations in resolver configuration file.
 | 
				
			||||||
            configs (:py:class:`list`): List of :py:class:`ConfigReference`
 | 
					            configs (:py:class:`list`): List of
 | 
				
			||||||
                that will be exposed to the service.
 | 
					                :py:class:`~docker.types.ConfigReference` that will be exposed
 | 
				
			||||||
 | 
					                to the service.
 | 
				
			||||||
            privileges (Privileges): Security options for the service's
 | 
					            privileges (Privileges): Security options for the service's
 | 
				
			||||||
                containers.
 | 
					                containers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,6 @@ from .services import (
 | 
				
			||||||
    ConfigReference, ContainerSpec, DNSConfig, DriverConfig, EndpointSpec,
 | 
					    ConfigReference, ContainerSpec, DNSConfig, DriverConfig, EndpointSpec,
 | 
				
			||||||
    Mount, Placement, PlacementPreference, Privileges, Resources,
 | 
					    Mount, Placement, PlacementPreference, Privileges, Resources,
 | 
				
			||||||
    RestartPolicy, RollbackConfig, SecretReference, ServiceMode, TaskTemplate,
 | 
					    RestartPolicy, RollbackConfig, SecretReference, ServiceMode, TaskTemplate,
 | 
				
			||||||
    UpdateConfig
 | 
					    UpdateConfig, NetworkAttachmentConfig
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from .swarm import SwarmSpec, SwarmExternalCA
 | 
					from .swarm import SwarmSpec, SwarmExternalCA
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,8 +26,8 @@ class TaskTemplate(dict):
 | 
				
			||||||
        placement (Placement): Placement instructions for the scheduler.
 | 
					        placement (Placement): Placement instructions for the scheduler.
 | 
				
			||||||
            If a list is passed instead, it is assumed to be a list of
 | 
					            If a list is passed instead, it is assumed to be a list of
 | 
				
			||||||
            constraints as part of a :py:class:`Placement` object.
 | 
					            constraints as part of a :py:class:`Placement` object.
 | 
				
			||||||
        networks (:py:class:`list`): List of network names or IDs to attach
 | 
					        networks (:py:class:`list`): List of network names or IDs or
 | 
				
			||||||
            the containers to.
 | 
					            :py:class:`NetworkAttachmentConfig` to attach the service to.
 | 
				
			||||||
        force_update (int): A counter that triggers an update even if no
 | 
					        force_update (int): A counter that triggers an update even if no
 | 
				
			||||||
            relevant parameters have been changed.
 | 
					            relevant parameters have been changed.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
| 
						 | 
					@ -770,3 +770,21 @@ class Privileges(dict):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if len(selinux_context) > 0:
 | 
					        if len(selinux_context) > 0:
 | 
				
			||||||
            self['SELinuxContext'] = selinux_context
 | 
					            self['SELinuxContext'] = selinux_context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NetworkAttachmentConfig(dict):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					        Network attachment options for a service.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Args:
 | 
				
			||||||
 | 
					            target (str): The target network for attachment.
 | 
				
			||||||
 | 
					                Can be a network name or ID.
 | 
				
			||||||
 | 
					            aliases (:py:class:`list`): A list of discoverable alternate names
 | 
				
			||||||
 | 
					                for the service.
 | 
				
			||||||
 | 
					            options (:py:class:`dict`): Driver attachment options for the
 | 
				
			||||||
 | 
					                network target.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    def __init__(self, target, aliases=None, options=None):
 | 
				
			||||||
 | 
					        self['Target'] = target
 | 
				
			||||||
 | 
					        self['Aliases'] = aliases
 | 
				
			||||||
 | 
					        self['DriverOpts'] = options
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,2 +1,2 @@
 | 
				
			||||||
version = "4.0.2"
 | 
					version = "4.1.0"
 | 
				
			||||||
version_info = tuple([int(d) for d in version.split("-")[0].split(".")])
 | 
					version_info = tuple([int(d) for d in version.split("-")[0].split(".")])
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -142,6 +142,7 @@ Configuration types
 | 
				
			||||||
.. autoclass:: IPAMPool
 | 
					.. autoclass:: IPAMPool
 | 
				
			||||||
.. autoclass:: LogConfig
 | 
					.. autoclass:: LogConfig
 | 
				
			||||||
.. autoclass:: Mount
 | 
					.. autoclass:: Mount
 | 
				
			||||||
 | 
					.. autoclass:: NetworkAttachmentConfig
 | 
				
			||||||
.. autoclass:: Placement
 | 
					.. autoclass:: Placement
 | 
				
			||||||
.. autoclass:: PlacementPreference
 | 
					.. autoclass:: PlacementPreference
 | 
				
			||||||
.. autoclass:: Privileges
 | 
					.. autoclass:: Privileges
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,27 @@
 | 
				
			||||||
Change log
 | 
					Change log
 | 
				
			||||||
==========
 | 
					==========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					4.1.0
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[List of PRs / issues for this release](https://github.com/docker/docker-py/milestone/61?closed=1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Bugfixes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Correct `INDEX_URL` logic in build.py _set_auth_headers
 | 
				
			||||||
 | 
					- Fix for empty auth keys in config.json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Features
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Add `NetworkAttachmentConfig` for service create/update
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Miscellaneous
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Bump pytest to 4.3.1
 | 
				
			||||||
 | 
					- Adjust `--platform` tests for changes in docker engine
 | 
				
			||||||
 | 
					- Update credentials-helpers to v0.6.3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
4.0.2
 | 
					4.0.2
 | 
				
			||||||
-----
 | 
					-----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,2 +1,5 @@
 | 
				
			||||||
[pytest]
 | 
					[pytest]
 | 
				
			||||||
addopts = --tb=short -rxs
 | 
					addopts = --tb=short -rxs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					junit_suite_name = docker-py
 | 
				
			||||||
 | 
					junit_family = xunit2
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
coverage==4.5.2
 | 
					coverage==4.5.2
 | 
				
			||||||
flake8==3.6.0
 | 
					flake8==3.6.0
 | 
				
			||||||
mock==1.0.1
 | 
					mock==1.0.1
 | 
				
			||||||
pytest==4.1.0
 | 
					pytest==4.3.1
 | 
				
			||||||
pytest-cov==2.6.1
 | 
					pytest-cov==2.6.1
 | 
				
			||||||
pytest-timeout==1.3.3
 | 
					pytest-timeout==1.3.3
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,11 @@
 | 
				
			||||||
ARG PYTHON_VERSION=3.6
 | 
					ARG PYTHON_VERSION=3.7
 | 
				
			||||||
FROM python:$PYTHON_VERSION-jessie
 | 
					
 | 
				
			||||||
 | 
					FROM python:${PYTHON_VERSION}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ARG APT_MIRROR
 | 
				
			||||||
 | 
					RUN sed -ri "s/(httpredir|deb).debian.org/${APT_MIRROR:-deb.debian.org}/g" /etc/apt/sources.list \
 | 
				
			||||||
 | 
					 && sed -ri "s/(security).debian.org/${APT_MIRROR:-security.debian.org}/g" /etc/apt/sources.list
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN apt-get update && apt-get -y install \
 | 
					RUN apt-get update && apt-get -y install \
 | 
				
			||||||
    gnupg2 \
 | 
					    gnupg2 \
 | 
				
			||||||
    pass \
 | 
					    pass \
 | 
				
			||||||
| 
						 | 
					@ -8,9 +14,9 @@ RUN apt-get update && apt-get -y install \
 | 
				
			||||||
COPY ./tests/gpg-keys /gpg-keys
 | 
					COPY ./tests/gpg-keys /gpg-keys
 | 
				
			||||||
RUN gpg2 --import gpg-keys/secret
 | 
					RUN gpg2 --import gpg-keys/secret
 | 
				
			||||||
RUN gpg2 --import-ownertrust gpg-keys/ownertrust
 | 
					RUN gpg2 --import-ownertrust gpg-keys/ownertrust
 | 
				
			||||||
RUN yes | pass init $(gpg2 --no-auto-check-trustdb --list-secret-keys | grep ^sec | cut -d/ -f2 | cut -d" " -f1)
 | 
					RUN yes | pass init $(gpg2 --no-auto-check-trustdb --list-secret-key | awk '/^sec/{getline; $1=$1; print}')
 | 
				
			||||||
RUN gpg2 --check-trustdb
 | 
					RUN gpg2 --check-trustdb
 | 
				
			||||||
ARG CREDSTORE_VERSION=v0.6.0
 | 
					ARG CREDSTORE_VERSION=v0.6.3
 | 
				
			||||||
RUN curl -sSL -o /opt/docker-credential-pass.tar.gz \
 | 
					RUN curl -sSL -o /opt/docker-credential-pass.tar.gz \
 | 
				
			||||||
    https://github.com/docker/docker-credential-helpers/releases/download/$CREDSTORE_VERSION/docker-credential-pass-$CREDSTORE_VERSION-amd64.tar.gz && \
 | 
					    https://github.com/docker/docker-credential-helpers/releases/download/$CREDSTORE_VERSION/docker-credential-pass-$CREDSTORE_VERSION-amd64.tar.gz && \
 | 
				
			||||||
    tar -xf /opt/docker-credential-pass.tar.gz -O > /usr/local/bin/docker-credential-pass && \
 | 
					    tar -xf /opt/docker-credential-pass.tar.gz -O > /usr/local/bin/docker-credential-pass && \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,6 @@
 | 
				
			||||||
FROM python:2.7
 | 
					ARG PYTHON_VERSION=2.7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FROM python:${PYTHON_VERSION}
 | 
				
			||||||
RUN mkdir /tmp/certs
 | 
					RUN mkdir /tmp/certs
 | 
				
			||||||
VOLUME /certs
 | 
					VOLUME /certs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,7 @@ from docker.utils.proxy import ProxyConfig
 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
import six
 | 
					import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .base import BaseAPIIntegrationTest, BUSYBOX
 | 
					from .base import BaseAPIIntegrationTest, TEST_IMG
 | 
				
			||||||
from ..helpers import random_name, requires_api_version, requires_experimental
 | 
					from ..helpers import random_name, requires_api_version, requires_experimental
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -277,7 +277,7 @@ class BuildTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        # Set up pingable endpoint on custom network
 | 
					        # Set up pingable endpoint on custom network
 | 
				
			||||||
        network = self.client.create_network(random_name())['Id']
 | 
					        network = self.client.create_network(random_name())['Id']
 | 
				
			||||||
        self.tmp_networks.append(network)
 | 
					        self.tmp_networks.append(network)
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, 'top')
 | 
					        container = self.client.create_container(TEST_IMG, 'top')
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
        self.client.start(container)
 | 
					        self.client.start(container)
 | 
				
			||||||
        self.client.connect_container_to_network(
 | 
					        self.client.connect_container_to_network(
 | 
				
			||||||
| 
						 | 
					@ -448,8 +448,10 @@ class BuildTest(BaseAPIIntegrationTest):
 | 
				
			||||||
            for _ in stream:
 | 
					            for _ in stream:
 | 
				
			||||||
                pass
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert excinfo.value.status_code == 400
 | 
					        # Some API versions incorrectly returns 500 status; assert 4xx or 5xx
 | 
				
			||||||
        assert 'invalid platform' in excinfo.exconly()
 | 
					        assert excinfo.value.is_error()
 | 
				
			||||||
 | 
					        assert 'unknown operating system' in excinfo.exconly() \
 | 
				
			||||||
 | 
					               or 'invalid platform' in excinfo.exconly()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_build_out_of_context_dockerfile(self):
 | 
					    def test_build_out_of_context_dockerfile(self):
 | 
				
			||||||
        base_dir = tempfile.mkdtemp()
 | 
					        base_dir = tempfile.mkdtemp()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,7 @@ from ..helpers import assert_cat_socket_detached_with_keys
 | 
				
			||||||
from ..helpers import ctrl_with
 | 
					from ..helpers import ctrl_with
 | 
				
			||||||
from ..helpers import requires_api_version
 | 
					from ..helpers import requires_api_version
 | 
				
			||||||
from .base import BaseAPIIntegrationTest
 | 
					from .base import BaseAPIIntegrationTest
 | 
				
			||||||
from .base import BUSYBOX
 | 
					from .base import TEST_IMG
 | 
				
			||||||
from docker.constants import IS_WINDOWS_PLATFORM
 | 
					from docker.constants import IS_WINDOWS_PLATFORM
 | 
				
			||||||
from docker.utils.socket import next_frame_header
 | 
					from docker.utils.socket import next_frame_header
 | 
				
			||||||
from docker.utils.socket import read_exactly
 | 
					from docker.utils.socket import read_exactly
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,7 @@ class ListContainersTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_list_containers(self):
 | 
					    def test_list_containers(self):
 | 
				
			||||||
        res0 = self.client.containers(all=True)
 | 
					        res0 = self.client.containers(all=True)
 | 
				
			||||||
        size = len(res0)
 | 
					        size = len(res0)
 | 
				
			||||||
        res1 = self.client.create_container(BUSYBOX, 'true')
 | 
					        res1 = self.client.create_container(TEST_IMG, 'true')
 | 
				
			||||||
        assert 'Id' in res1
 | 
					        assert 'Id' in res1
 | 
				
			||||||
        self.client.start(res1['Id'])
 | 
					        self.client.start(res1['Id'])
 | 
				
			||||||
        self.tmp_containers.append(res1['Id'])
 | 
					        self.tmp_containers.append(res1['Id'])
 | 
				
			||||||
| 
						 | 
					@ -44,13 +44,13 @@ class ListContainersTest(BaseAPIIntegrationTest):
 | 
				
			||||||
class CreateContainerTest(BaseAPIIntegrationTest):
 | 
					class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create(self):
 | 
					    def test_create(self):
 | 
				
			||||||
        res = self.client.create_container(BUSYBOX, 'true')
 | 
					        res = self.client.create_container(TEST_IMG, 'true')
 | 
				
			||||||
        assert 'Id' in res
 | 
					        assert 'Id' in res
 | 
				
			||||||
        self.tmp_containers.append(res['Id'])
 | 
					        self.tmp_containers.append(res['Id'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_with_host_pid_mode(self):
 | 
					    def test_create_with_host_pid_mode(self):
 | 
				
			||||||
        ctnr = self.client.create_container(
 | 
					        ctnr = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'true', host_config=self.client.create_host_config(
 | 
					            TEST_IMG, 'true', host_config=self.client.create_host_config(
 | 
				
			||||||
                pid_mode='host', network_mode='none'
 | 
					                pid_mode='host', network_mode='none'
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_with_links(self):
 | 
					    def test_create_with_links(self):
 | 
				
			||||||
        res0 = self.client.create_container(
 | 
					        res0 = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'cat',
 | 
					            TEST_IMG, 'cat',
 | 
				
			||||||
            detach=True, stdin_open=True,
 | 
					            detach=True, stdin_open=True,
 | 
				
			||||||
            environment={'FOO': '1'})
 | 
					            environment={'FOO': '1'})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,7 +75,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        self.client.start(container1_id)
 | 
					        self.client.start(container1_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        res1 = self.client.create_container(
 | 
					        res1 = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'cat',
 | 
					            TEST_IMG, 'cat',
 | 
				
			||||||
            detach=True, stdin_open=True,
 | 
					            detach=True, stdin_open=True,
 | 
				
			||||||
            environment={'FOO': '1'})
 | 
					            environment={'FOO': '1'})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -94,7 +94,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        link_env_prefix2 = link_alias2.upper()
 | 
					        link_env_prefix2 = link_alias2.upper()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        res2 = self.client.create_container(
 | 
					        res2 = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'env', host_config=self.client.create_host_config(
 | 
					            TEST_IMG, 'env', host_config=self.client.create_host_config(
 | 
				
			||||||
                links={link_path1: link_alias1, link_path2: link_alias2},
 | 
					                links={link_path1: link_alias1, link_path2: link_alias2},
 | 
				
			||||||
                network_mode='bridge'
 | 
					                network_mode='bridge'
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
| 
						 | 
					@ -114,7 +114,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_with_restart_policy(self):
 | 
					    def test_create_with_restart_policy(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['sleep', '2'],
 | 
					            TEST_IMG, ['sleep', '2'],
 | 
				
			||||||
            host_config=self.client.create_host_config(
 | 
					            host_config=self.client.create_host_config(
 | 
				
			||||||
                restart_policy={"Name": "always", "MaximumRetryCount": 0},
 | 
					                restart_policy={"Name": "always", "MaximumRetryCount": 0},
 | 
				
			||||||
                network_mode='none'
 | 
					                network_mode='none'
 | 
				
			||||||
| 
						 | 
					@ -133,21 +133,21 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        vol_names = ['foobar_vol0', 'foobar_vol1']
 | 
					        vol_names = ['foobar_vol0', 'foobar_vol1']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        res0 = self.client.create_container(
 | 
					        res0 = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'true', name=vol_names[0]
 | 
					            TEST_IMG, 'true', name=vol_names[0]
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        container1_id = res0['Id']
 | 
					        container1_id = res0['Id']
 | 
				
			||||||
        self.tmp_containers.append(container1_id)
 | 
					        self.tmp_containers.append(container1_id)
 | 
				
			||||||
        self.client.start(container1_id)
 | 
					        self.client.start(container1_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        res1 = self.client.create_container(
 | 
					        res1 = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'true', name=vol_names[1]
 | 
					            TEST_IMG, 'true', name=vol_names[1]
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        container2_id = res1['Id']
 | 
					        container2_id = res1['Id']
 | 
				
			||||||
        self.tmp_containers.append(container2_id)
 | 
					        self.tmp_containers.append(container2_id)
 | 
				
			||||||
        self.client.start(container2_id)
 | 
					        self.client.start(container2_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        res = self.client.create_container(
 | 
					        res = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'cat', detach=True, stdin_open=True,
 | 
					            TEST_IMG, 'cat', detach=True, stdin_open=True,
 | 
				
			||||||
            host_config=self.client.create_host_config(
 | 
					            host_config=self.client.create_host_config(
 | 
				
			||||||
                volumes_from=vol_names, network_mode='none'
 | 
					                volumes_from=vol_names, network_mode='none'
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
| 
						 | 
					@ -161,7 +161,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def create_container_readonly_fs(self):
 | 
					    def create_container_readonly_fs(self):
 | 
				
			||||||
        ctnr = self.client.create_container(
 | 
					        ctnr = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['mkdir', '/shrine'],
 | 
					            TEST_IMG, ['mkdir', '/shrine'],
 | 
				
			||||||
            host_config=self.client.create_host_config(
 | 
					            host_config=self.client.create_host_config(
 | 
				
			||||||
                read_only=True, network_mode='none'
 | 
					                read_only=True, network_mode='none'
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
| 
						 | 
					@ -173,7 +173,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert res != 0
 | 
					        assert res != 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def create_container_with_name(self):
 | 
					    def create_container_with_name(self):
 | 
				
			||||||
        res = self.client.create_container(BUSYBOX, 'true', name='foobar')
 | 
					        res = self.client.create_container(TEST_IMG, 'true', name='foobar')
 | 
				
			||||||
        assert 'Id' in res
 | 
					        assert 'Id' in res
 | 
				
			||||||
        self.tmp_containers.append(res['Id'])
 | 
					        self.tmp_containers.append(res['Id'])
 | 
				
			||||||
        inspect = self.client.inspect_container(res['Id'])
 | 
					        inspect = self.client.inspect_container(res['Id'])
 | 
				
			||||||
| 
						 | 
					@ -182,7 +182,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def create_container_privileged(self):
 | 
					    def create_container_privileged(self):
 | 
				
			||||||
        res = self.client.create_container(
 | 
					        res = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'true', host_config=self.client.create_host_config(
 | 
					            TEST_IMG, 'true', host_config=self.client.create_host_config(
 | 
				
			||||||
                privileged=True, network_mode='none'
 | 
					                privileged=True, network_mode='none'
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -208,7 +208,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_create_with_mac_address(self):
 | 
					    def test_create_with_mac_address(self):
 | 
				
			||||||
        mac_address_expected = "02:42:ac:11:00:0a"
 | 
					        mac_address_expected = "02:42:ac:11:00:0a"
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['sleep', '60'], mac_address=mac_address_expected)
 | 
					            TEST_IMG, ['sleep', '60'], mac_address=mac_address_expected)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -220,7 +220,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_group_id_ints(self):
 | 
					    def test_group_id_ints(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'id -G',
 | 
					            TEST_IMG, 'id -G',
 | 
				
			||||||
            host_config=self.client.create_host_config(group_add=[1000, 1001])
 | 
					            host_config=self.client.create_host_config(group_add=[1000, 1001])
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
| 
						 | 
					@ -236,7 +236,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_group_id_strings(self):
 | 
					    def test_group_id_strings(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'id -G', host_config=self.client.create_host_config(
 | 
					            TEST_IMG, 'id -G', host_config=self.client.create_host_config(
 | 
				
			||||||
                group_add=['1000', '1001']
 | 
					                group_add=['1000', '1001']
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -259,7 +259,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['true'],
 | 
					            TEST_IMG, ['true'],
 | 
				
			||||||
            host_config=self.client.create_host_config(log_config=log_config)
 | 
					            host_config=self.client.create_host_config(log_config=log_config)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(container['Id'])
 | 
					        self.tmp_containers.append(container['Id'])
 | 
				
			||||||
| 
						 | 
					@ -281,7 +281,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        with pytest.raises(docker.errors.APIError) as excinfo:
 | 
					        with pytest.raises(docker.errors.APIError) as excinfo:
 | 
				
			||||||
            # raises an internal server error 500
 | 
					            # raises an internal server error 500
 | 
				
			||||||
            container = self.client.create_container(
 | 
					            container = self.client.create_container(
 | 
				
			||||||
                BUSYBOX, ['true'], host_config=self.client.create_host_config(
 | 
					                TEST_IMG, ['true'], host_config=self.client.create_host_config(
 | 
				
			||||||
                    log_config=log_config
 | 
					                    log_config=log_config
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
| 
						 | 
					@ -296,7 +296,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['true'],
 | 
					            TEST_IMG, ['true'],
 | 
				
			||||||
            host_config=self.client.create_host_config(log_config=log_config)
 | 
					            host_config=self.client.create_host_config(log_config=log_config)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(container['Id'])
 | 
					        self.tmp_containers.append(container['Id'])
 | 
				
			||||||
| 
						 | 
					@ -315,7 +315,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['true'],
 | 
					            TEST_IMG, ['true'],
 | 
				
			||||||
            host_config=self.client.create_host_config(log_config=log_config)
 | 
					            host_config=self.client.create_host_config(log_config=log_config)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(container['Id'])
 | 
					        self.tmp_containers.append(container['Id'])
 | 
				
			||||||
| 
						 | 
					@ -329,7 +329,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_with_memory_constraints_with_str(self):
 | 
					    def test_create_with_memory_constraints_with_str(self):
 | 
				
			||||||
        ctnr = self.client.create_container(
 | 
					        ctnr = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'true',
 | 
					            TEST_IMG, 'true',
 | 
				
			||||||
            host_config=self.client.create_host_config(
 | 
					            host_config=self.client.create_host_config(
 | 
				
			||||||
                memswap_limit='1G',
 | 
					                memswap_limit='1G',
 | 
				
			||||||
                mem_limit='700M'
 | 
					                mem_limit='700M'
 | 
				
			||||||
| 
						 | 
					@ -347,7 +347,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_with_memory_constraints_with_int(self):
 | 
					    def test_create_with_memory_constraints_with_int(self):
 | 
				
			||||||
        ctnr = self.client.create_container(
 | 
					        ctnr = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'true',
 | 
					            TEST_IMG, 'true',
 | 
				
			||||||
            host_config=self.client.create_host_config(mem_swappiness=40)
 | 
					            host_config=self.client.create_host_config(mem_swappiness=40)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        assert 'Id' in ctnr
 | 
					        assert 'Id' in ctnr
 | 
				
			||||||
| 
						 | 
					@ -361,7 +361,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_with_environment_variable_no_value(self):
 | 
					    def test_create_with_environment_variable_no_value(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX,
 | 
					            TEST_IMG,
 | 
				
			||||||
            ['echo'],
 | 
					            ['echo'],
 | 
				
			||||||
            environment={'Foo': None, 'Other': 'one', 'Blank': ''},
 | 
					            environment={'Foo': None, 'Other': 'one', 'Blank': ''},
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -378,7 +378,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX,
 | 
					            TEST_IMG,
 | 
				
			||||||
            ['echo'],
 | 
					            ['echo'],
 | 
				
			||||||
            host_config=self.client.create_host_config(
 | 
					            host_config=self.client.create_host_config(
 | 
				
			||||||
                tmpfs=tmpfs))
 | 
					                tmpfs=tmpfs))
 | 
				
			||||||
| 
						 | 
					@ -390,7 +390,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    @requires_api_version('1.24')
 | 
					    @requires_api_version('1.24')
 | 
				
			||||||
    def test_create_with_isolation(self):
 | 
					    def test_create_with_isolation(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['echo'], host_config=self.client.create_host_config(
 | 
					            TEST_IMG, ['echo'], host_config=self.client.create_host_config(
 | 
				
			||||||
                isolation='default'
 | 
					                isolation='default'
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -404,7 +404,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
            auto_remove=True
 | 
					            auto_remove=True
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['echo', 'test'], host_config=host_config
 | 
					            TEST_IMG, ['echo', 'test'], host_config=host_config
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(container['Id'])
 | 
					        self.tmp_containers.append(container['Id'])
 | 
				
			||||||
        config = self.client.inspect_container(container)
 | 
					        config = self.client.inspect_container(container)
 | 
				
			||||||
| 
						 | 
					@ -413,7 +413,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    @requires_api_version('1.25')
 | 
					    @requires_api_version('1.25')
 | 
				
			||||||
    def test_create_with_stop_timeout(self):
 | 
					    def test_create_with_stop_timeout(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['echo', 'test'], stop_timeout=25
 | 
					            TEST_IMG, ['echo', 'test'], stop_timeout=25
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(container['Id'])
 | 
					        self.tmp_containers.append(container['Id'])
 | 
				
			||||||
        config = self.client.inspect_container(container)
 | 
					        config = self.client.inspect_container(container)
 | 
				
			||||||
| 
						 | 
					@ -426,7 +426,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
            storage_opt={'size': '120G'}
 | 
					            storage_opt={'size': '120G'}
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['echo', 'test'], host_config=host_config
 | 
					            TEST_IMG, ['echo', 'test'], host_config=host_config
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
        config = self.client.inspect_container(container)
 | 
					        config = self.client.inspect_container(container)
 | 
				
			||||||
| 
						 | 
					@ -437,7 +437,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    @requires_api_version('1.25')
 | 
					    @requires_api_version('1.25')
 | 
				
			||||||
    def test_create_with_init(self):
 | 
					    def test_create_with_init(self):
 | 
				
			||||||
        ctnr = self.client.create_container(
 | 
					        ctnr = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'true',
 | 
					            TEST_IMG, 'true',
 | 
				
			||||||
            host_config=self.client.create_host_config(
 | 
					            host_config=self.client.create_host_config(
 | 
				
			||||||
                init=True
 | 
					                init=True
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
| 
						 | 
					@ -451,7 +451,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
                       reason='CONFIG_RT_GROUP_SCHED isn\'t enabled')
 | 
					                       reason='CONFIG_RT_GROUP_SCHED isn\'t enabled')
 | 
				
			||||||
    def test_create_with_cpu_rt_options(self):
 | 
					    def test_create_with_cpu_rt_options(self):
 | 
				
			||||||
        ctnr = self.client.create_container(
 | 
					        ctnr = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'true', host_config=self.client.create_host_config(
 | 
					            TEST_IMG, 'true', host_config=self.client.create_host_config(
 | 
				
			||||||
                cpu_rt_period=1000, cpu_rt_runtime=500
 | 
					                cpu_rt_period=1000, cpu_rt_runtime=500
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -464,7 +464,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_create_with_device_cgroup_rules(self):
 | 
					    def test_create_with_device_cgroup_rules(self):
 | 
				
			||||||
        rule = 'c 7:128 rwm'
 | 
					        rule = 'c 7:128 rwm'
 | 
				
			||||||
        ctnr = self.client.create_container(
 | 
					        ctnr = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'cat /sys/fs/cgroup/devices/devices.list',
 | 
					            TEST_IMG, 'cat /sys/fs/cgroup/devices/devices.list',
 | 
				
			||||||
            host_config=self.client.create_host_config(
 | 
					            host_config=self.client.create_host_config(
 | 
				
			||||||
                device_cgroup_rules=[rule]
 | 
					                device_cgroup_rules=[rule]
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
| 
						 | 
					@ -477,7 +477,7 @@ class CreateContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_with_uts_mode(self):
 | 
					    def test_create_with_uts_mode(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['echo'], host_config=self.client.create_host_config(
 | 
					            TEST_IMG, ['echo'], host_config=self.client.create_host_config(
 | 
				
			||||||
                uts_mode='host'
 | 
					                uts_mode='host'
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -501,7 +501,7 @@ class VolumeBindTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.run_with_volume(
 | 
					        self.run_with_volume(
 | 
				
			||||||
            False,
 | 
					            False,
 | 
				
			||||||
            BUSYBOX,
 | 
					            TEST_IMG,
 | 
				
			||||||
            ['touch', os.path.join(self.mount_dest, self.filename)],
 | 
					            ['touch', os.path.join(self.mount_dest, self.filename)],
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -509,7 +509,7 @@ class VolumeBindTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        container = self.run_with_volume(
 | 
					        container = self.run_with_volume(
 | 
				
			||||||
            False,
 | 
					            False,
 | 
				
			||||||
            BUSYBOX,
 | 
					            TEST_IMG,
 | 
				
			||||||
            ['ls', self.mount_dest],
 | 
					            ['ls', self.mount_dest],
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        logs = self.client.logs(container)
 | 
					        logs = self.client.logs(container)
 | 
				
			||||||
| 
						 | 
					@ -523,12 +523,12 @@ class VolumeBindTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_create_with_binds_ro(self):
 | 
					    def test_create_with_binds_ro(self):
 | 
				
			||||||
        self.run_with_volume(
 | 
					        self.run_with_volume(
 | 
				
			||||||
            False,
 | 
					            False,
 | 
				
			||||||
            BUSYBOX,
 | 
					            TEST_IMG,
 | 
				
			||||||
            ['touch', os.path.join(self.mount_dest, self.filename)],
 | 
					            ['touch', os.path.join(self.mount_dest, self.filename)],
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        container = self.run_with_volume(
 | 
					        container = self.run_with_volume(
 | 
				
			||||||
            True,
 | 
					            True,
 | 
				
			||||||
            BUSYBOX,
 | 
					            TEST_IMG,
 | 
				
			||||||
            ['ls', self.mount_dest],
 | 
					            ['ls', self.mount_dest],
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        logs = self.client.logs(container)
 | 
					        logs = self.client.logs(container)
 | 
				
			||||||
| 
						 | 
					@ -547,7 +547,7 @@ class VolumeBindTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        host_config = self.client.create_host_config(mounts=[mount])
 | 
					        host_config = self.client.create_host_config(mounts=[mount])
 | 
				
			||||||
        container = self.run_container(
 | 
					        container = self.run_container(
 | 
				
			||||||
            BUSYBOX, ['ls', self.mount_dest],
 | 
					            TEST_IMG, ['ls', self.mount_dest],
 | 
				
			||||||
            host_config=host_config
 | 
					            host_config=host_config
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        assert container
 | 
					        assert container
 | 
				
			||||||
| 
						 | 
					@ -566,7 +566,7 @@ class VolumeBindTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        host_config = self.client.create_host_config(mounts=[mount])
 | 
					        host_config = self.client.create_host_config(mounts=[mount])
 | 
				
			||||||
        container = self.run_container(
 | 
					        container = self.run_container(
 | 
				
			||||||
            BUSYBOX, ['ls', self.mount_dest],
 | 
					            TEST_IMG, ['ls', self.mount_dest],
 | 
				
			||||||
            host_config=host_config
 | 
					            host_config=host_config
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        assert container
 | 
					        assert container
 | 
				
			||||||
| 
						 | 
					@ -585,7 +585,7 @@ class VolumeBindTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        host_config = self.client.create_host_config(mounts=[mount])
 | 
					        host_config = self.client.create_host_config(mounts=[mount])
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['true'], host_config=host_config,
 | 
					            TEST_IMG, ['true'], host_config=host_config,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        assert container
 | 
					        assert container
 | 
				
			||||||
        inspect_data = self.client.inspect_container(container)
 | 
					        inspect_data = self.client.inspect_container(container)
 | 
				
			||||||
| 
						 | 
					@ -631,7 +631,7 @@ class ArchiveTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_get_file_archive_from_container(self):
 | 
					    def test_get_file_archive_from_container(self):
 | 
				
			||||||
        data = 'The Maid and the Pocket Watch of Blood'
 | 
					        data = 'The Maid and the Pocket Watch of Blood'
 | 
				
			||||||
        ctnr = self.client.create_container(
 | 
					        ctnr = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'sh -c "echo {0} > /vol1/data.txt"'.format(data),
 | 
					            TEST_IMG, 'sh -c "echo {0} > /vol1/data.txt"'.format(data),
 | 
				
			||||||
            volumes=['/vol1']
 | 
					            volumes=['/vol1']
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(ctnr)
 | 
					        self.tmp_containers.append(ctnr)
 | 
				
			||||||
| 
						 | 
					@ -650,7 +650,7 @@ class ArchiveTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_get_file_stat_from_container(self):
 | 
					    def test_get_file_stat_from_container(self):
 | 
				
			||||||
        data = 'The Maid and the Pocket Watch of Blood'
 | 
					        data = 'The Maid and the Pocket Watch of Blood'
 | 
				
			||||||
        ctnr = self.client.create_container(
 | 
					        ctnr = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'sh -c "echo -n {0} > /vol1/data.txt"'.format(data),
 | 
					            TEST_IMG, 'sh -c "echo -n {0} > /vol1/data.txt"'.format(data),
 | 
				
			||||||
            volumes=['/vol1']
 | 
					            volumes=['/vol1']
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(ctnr)
 | 
					        self.tmp_containers.append(ctnr)
 | 
				
			||||||
| 
						 | 
					@ -668,7 +668,7 @@ class ArchiveTest(BaseAPIIntegrationTest):
 | 
				
			||||||
            test_file.write(data)
 | 
					            test_file.write(data)
 | 
				
			||||||
            test_file.seek(0)
 | 
					            test_file.seek(0)
 | 
				
			||||||
            ctnr = self.client.create_container(
 | 
					            ctnr = self.client.create_container(
 | 
				
			||||||
                BUSYBOX,
 | 
					                TEST_IMG,
 | 
				
			||||||
                'cat {0}'.format(
 | 
					                'cat {0}'.format(
 | 
				
			||||||
                    os.path.join('/vol1/', os.path.basename(test_file.name))
 | 
					                    os.path.join('/vol1/', os.path.basename(test_file.name))
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
| 
						 | 
					@ -690,7 +690,7 @@ class ArchiveTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        dirs = ['foo', 'bar']
 | 
					        dirs = ['foo', 'bar']
 | 
				
			||||||
        base = helpers.make_tree(dirs, files)
 | 
					        base = helpers.make_tree(dirs, files)
 | 
				
			||||||
        ctnr = self.client.create_container(
 | 
					        ctnr = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'ls -p /vol1', volumes=['/vol1']
 | 
					            TEST_IMG, 'ls -p /vol1', volumes=['/vol1']
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(ctnr)
 | 
					        self.tmp_containers.append(ctnr)
 | 
				
			||||||
        with docker.utils.tar(base) as test_tar:
 | 
					        with docker.utils.tar(base) as test_tar:
 | 
				
			||||||
| 
						 | 
					@ -711,7 +711,7 @@ class RenameContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_rename_container(self):
 | 
					    def test_rename_container(self):
 | 
				
			||||||
        version = self.client.version()['Version']
 | 
					        version = self.client.version()['Version']
 | 
				
			||||||
        name = 'hong_meiling'
 | 
					        name = 'hong_meiling'
 | 
				
			||||||
        res = self.client.create_container(BUSYBOX, 'true')
 | 
					        res = self.client.create_container(TEST_IMG, 'true')
 | 
				
			||||||
        assert 'Id' in res
 | 
					        assert 'Id' in res
 | 
				
			||||||
        self.tmp_containers.append(res['Id'])
 | 
					        self.tmp_containers.append(res['Id'])
 | 
				
			||||||
        self.client.rename(res, name)
 | 
					        self.client.rename(res, name)
 | 
				
			||||||
| 
						 | 
					@ -725,7 +725,7 @@ class RenameContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class StartContainerTest(BaseAPIIntegrationTest):
 | 
					class StartContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_start_container(self):
 | 
					    def test_start_container(self):
 | 
				
			||||||
        res = self.client.create_container(BUSYBOX, 'true')
 | 
					        res = self.client.create_container(TEST_IMG, 'true')
 | 
				
			||||||
        assert 'Id' in res
 | 
					        assert 'Id' in res
 | 
				
			||||||
        self.tmp_containers.append(res['Id'])
 | 
					        self.tmp_containers.append(res['Id'])
 | 
				
			||||||
        self.client.start(res['Id'])
 | 
					        self.client.start(res['Id'])
 | 
				
			||||||
| 
						 | 
					@ -741,7 +741,7 @@ class StartContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
            assert inspect['State']['ExitCode'] == 0
 | 
					            assert inspect['State']['ExitCode'] == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_start_container_with_dict_instead_of_id(self):
 | 
					    def test_start_container_with_dict_instead_of_id(self):
 | 
				
			||||||
        res = self.client.create_container(BUSYBOX, 'true')
 | 
					        res = self.client.create_container(TEST_IMG, 'true')
 | 
				
			||||||
        assert 'Id' in res
 | 
					        assert 'Id' in res
 | 
				
			||||||
        self.tmp_containers.append(res['Id'])
 | 
					        self.tmp_containers.append(res['Id'])
 | 
				
			||||||
        self.client.start(res)
 | 
					        self.client.start(res)
 | 
				
			||||||
| 
						 | 
					@ -769,7 +769,7 @@ class StartContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
            'true && echo "Night of Nights"'
 | 
					            'true && echo "Night of Nights"'
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
        for cmd in commands:
 | 
					        for cmd in commands:
 | 
				
			||||||
            container = self.client.create_container(BUSYBOX, cmd)
 | 
					            container = self.client.create_container(TEST_IMG, cmd)
 | 
				
			||||||
            id = container['Id']
 | 
					            id = container['Id']
 | 
				
			||||||
            self.client.start(id)
 | 
					            self.client.start(id)
 | 
				
			||||||
            self.tmp_containers.append(id)
 | 
					            self.tmp_containers.append(id)
 | 
				
			||||||
| 
						 | 
					@ -779,7 +779,7 @@ class StartContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class WaitTest(BaseAPIIntegrationTest):
 | 
					class WaitTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_wait(self):
 | 
					    def test_wait(self):
 | 
				
			||||||
        res = self.client.create_container(BUSYBOX, ['sleep', '3'])
 | 
					        res = self.client.create_container(TEST_IMG, ['sleep', '3'])
 | 
				
			||||||
        id = res['Id']
 | 
					        id = res['Id']
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
| 
						 | 
					@ -792,7 +792,7 @@ class WaitTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert inspect['State']['ExitCode'] == exitcode
 | 
					        assert inspect['State']['ExitCode'] == exitcode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_wait_with_dict_instead_of_id(self):
 | 
					    def test_wait_with_dict_instead_of_id(self):
 | 
				
			||||||
        res = self.client.create_container(BUSYBOX, ['sleep', '3'])
 | 
					        res = self.client.create_container(TEST_IMG, ['sleep', '3'])
 | 
				
			||||||
        id = res['Id']
 | 
					        id = res['Id']
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
        self.client.start(res)
 | 
					        self.client.start(res)
 | 
				
			||||||
| 
						 | 
					@ -806,13 +806,13 @@ class WaitTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @requires_api_version('1.30')
 | 
					    @requires_api_version('1.30')
 | 
				
			||||||
    def test_wait_with_condition(self):
 | 
					    def test_wait_with_condition(self):
 | 
				
			||||||
        ctnr = self.client.create_container(BUSYBOX, 'true')
 | 
					        ctnr = self.client.create_container(TEST_IMG, 'true')
 | 
				
			||||||
        self.tmp_containers.append(ctnr)
 | 
					        self.tmp_containers.append(ctnr)
 | 
				
			||||||
        with pytest.raises(requests.exceptions.ConnectionError):
 | 
					        with pytest.raises(requests.exceptions.ConnectionError):
 | 
				
			||||||
            self.client.wait(ctnr, condition='removed', timeout=1)
 | 
					            self.client.wait(ctnr, condition='removed', timeout=1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ctnr = self.client.create_container(
 | 
					        ctnr = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['sleep', '3'],
 | 
					            TEST_IMG, ['sleep', '3'],
 | 
				
			||||||
            host_config=self.client.create_host_config(auto_remove=True)
 | 
					            host_config=self.client.create_host_config(auto_remove=True)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(ctnr)
 | 
					        self.tmp_containers.append(ctnr)
 | 
				
			||||||
| 
						 | 
					@ -826,7 +826,7 @@ class LogsTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_logs(self):
 | 
					    def test_logs(self):
 | 
				
			||||||
        snippet = 'Flowering Nights (Sakuya Iyazoi)'
 | 
					        snippet = 'Flowering Nights (Sakuya Iyazoi)'
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'echo {0}'.format(snippet)
 | 
					            TEST_IMG, 'echo {0}'.format(snippet)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
| 
						 | 
					@ -840,7 +840,7 @@ class LogsTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        snippet = '''Line1
 | 
					        snippet = '''Line1
 | 
				
			||||||
Line2'''
 | 
					Line2'''
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'echo "{0}"'.format(snippet)
 | 
					            TEST_IMG, 'echo "{0}"'.format(snippet)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
| 
						 | 
					@ -853,7 +853,7 @@ Line2'''
 | 
				
			||||||
    def test_logs_streaming_and_follow(self):
 | 
					    def test_logs_streaming_and_follow(self):
 | 
				
			||||||
        snippet = 'Flowering Nights (Sakuya Iyazoi)'
 | 
					        snippet = 'Flowering Nights (Sakuya Iyazoi)'
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'echo {0}'.format(snippet)
 | 
					            TEST_IMG, 'echo {0}'.format(snippet)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
| 
						 | 
					@ -873,7 +873,7 @@ Line2'''
 | 
				
			||||||
    def test_logs_streaming_and_follow_and_cancel(self):
 | 
					    def test_logs_streaming_and_follow_and_cancel(self):
 | 
				
			||||||
        snippet = 'Flowering Nights (Sakuya Iyazoi)'
 | 
					        snippet = 'Flowering Nights (Sakuya Iyazoi)'
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'sh -c "echo \\"{0}\\" && sleep 3"'.format(snippet)
 | 
					            TEST_IMG, 'sh -c "echo \\"{0}\\" && sleep 3"'.format(snippet)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
| 
						 | 
					@ -891,7 +891,7 @@ Line2'''
 | 
				
			||||||
    def test_logs_with_dict_instead_of_id(self):
 | 
					    def test_logs_with_dict_instead_of_id(self):
 | 
				
			||||||
        snippet = 'Flowering Nights (Sakuya Iyazoi)'
 | 
					        snippet = 'Flowering Nights (Sakuya Iyazoi)'
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'echo {0}'.format(snippet)
 | 
					            TEST_IMG, 'echo {0}'.format(snippet)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
| 
						 | 
					@ -904,7 +904,7 @@ Line2'''
 | 
				
			||||||
    def test_logs_with_tail_0(self):
 | 
					    def test_logs_with_tail_0(self):
 | 
				
			||||||
        snippet = 'Flowering Nights (Sakuya Iyazoi)'
 | 
					        snippet = 'Flowering Nights (Sakuya Iyazoi)'
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'echo "{0}"'.format(snippet)
 | 
					            TEST_IMG, 'echo "{0}"'.format(snippet)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
| 
						 | 
					@ -918,7 +918,7 @@ Line2'''
 | 
				
			||||||
    def test_logs_with_until(self):
 | 
					    def test_logs_with_until(self):
 | 
				
			||||||
        snippet = 'Shanghai Teahouse (Hong Meiling)'
 | 
					        snippet = 'Shanghai Teahouse (Hong Meiling)'
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'echo "{0}"'.format(snippet)
 | 
					            TEST_IMG, 'echo "{0}"'.format(snippet)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
| 
						 | 
					@ -933,7 +933,7 @@ Line2'''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DiffTest(BaseAPIIntegrationTest):
 | 
					class DiffTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_diff(self):
 | 
					    def test_diff(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, ['touch', '/test'])
 | 
					        container = self.client.create_container(TEST_IMG, ['touch', '/test'])
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
| 
						 | 
					@ -946,7 +946,7 @@ class DiffTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert test_diff[0]['Kind'] == 1
 | 
					        assert test_diff[0]['Kind'] == 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_diff_with_dict_instead_of_id(self):
 | 
					    def test_diff_with_dict_instead_of_id(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, ['touch', '/test'])
 | 
					        container = self.client.create_container(TEST_IMG, ['touch', '/test'])
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
| 
						 | 
					@ -961,7 +961,7 @@ class DiffTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class StopTest(BaseAPIIntegrationTest):
 | 
					class StopTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_stop(self):
 | 
					    def test_stop(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, ['sleep', '9999'])
 | 
					        container = self.client.create_container(TEST_IMG, ['sleep', '9999'])
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
| 
						 | 
					@ -973,7 +973,7 @@ class StopTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert state['Running'] is False
 | 
					        assert state['Running'] is False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_stop_with_dict_instead_of_id(self):
 | 
					    def test_stop_with_dict_instead_of_id(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, ['sleep', '9999'])
 | 
					        container = self.client.create_container(TEST_IMG, ['sleep', '9999'])
 | 
				
			||||||
        assert 'Id' in container
 | 
					        assert 'Id' in container
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(container)
 | 
					        self.client.start(container)
 | 
				
			||||||
| 
						 | 
					@ -988,7 +988,7 @@ class StopTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class KillTest(BaseAPIIntegrationTest):
 | 
					class KillTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_kill(self):
 | 
					    def test_kill(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, ['sleep', '9999'])
 | 
					        container = self.client.create_container(TEST_IMG, ['sleep', '9999'])
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
| 
						 | 
					@ -1002,7 +1002,7 @@ class KillTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert state['Running'] is False
 | 
					        assert state['Running'] is False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_kill_with_dict_instead_of_id(self):
 | 
					    def test_kill_with_dict_instead_of_id(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, ['sleep', '9999'])
 | 
					        container = self.client.create_container(TEST_IMG, ['sleep', '9999'])
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
| 
						 | 
					@ -1016,7 +1016,7 @@ class KillTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert state['Running'] is False
 | 
					        assert state['Running'] is False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_kill_with_signal(self):
 | 
					    def test_kill_with_signal(self):
 | 
				
			||||||
        id = self.client.create_container(BUSYBOX, ['sleep', '60'])
 | 
					        id = self.client.create_container(TEST_IMG, ['sleep', '60'])
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
        self.client.kill(
 | 
					        self.client.kill(
 | 
				
			||||||
| 
						 | 
					@ -1033,7 +1033,7 @@ class KillTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert state['Running'] is False, state
 | 
					        assert state['Running'] is False, state
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_kill_with_signal_name(self):
 | 
					    def test_kill_with_signal_name(self):
 | 
				
			||||||
        id = self.client.create_container(BUSYBOX, ['sleep', '60'])
 | 
					        id = self.client.create_container(TEST_IMG, ['sleep', '60'])
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
        self.client.kill(id, signal='SIGKILL')
 | 
					        self.client.kill(id, signal='SIGKILL')
 | 
				
			||||||
| 
						 | 
					@ -1048,7 +1048,7 @@ class KillTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert state['Running'] is False, state
 | 
					        assert state['Running'] is False, state
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_kill_with_signal_integer(self):
 | 
					    def test_kill_with_signal_integer(self):
 | 
				
			||||||
        id = self.client.create_container(BUSYBOX, ['sleep', '60'])
 | 
					        id = self.client.create_container(TEST_IMG, ['sleep', '60'])
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
        self.client.kill(id, signal=9)
 | 
					        self.client.kill(id, signal=9)
 | 
				
			||||||
| 
						 | 
					@ -1077,7 +1077,7 @@ class PortTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['sleep', '60'], ports=ports,
 | 
					            TEST_IMG, ['sleep', '60'], ports=ports,
 | 
				
			||||||
            host_config=self.client.create_host_config(
 | 
					            host_config=self.client.create_host_config(
 | 
				
			||||||
                port_bindings=port_bindings, network_mode='bridge'
 | 
					                port_bindings=port_bindings, network_mode='bridge'
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
| 
						 | 
					@ -1104,7 +1104,7 @@ class PortTest(BaseAPIIntegrationTest):
 | 
				
			||||||
class ContainerTopTest(BaseAPIIntegrationTest):
 | 
					class ContainerTopTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_top(self):
 | 
					    def test_top(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['sleep', '60']
 | 
					            TEST_IMG, ['sleep', '60']
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
| 
						 | 
					@ -1124,7 +1124,7 @@ class ContainerTopTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    def test_top_with_psargs(self):
 | 
					    def test_top_with_psargs(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['sleep', '60'])
 | 
					            TEST_IMG, ['sleep', '60'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1140,7 +1140,7 @@ class ContainerTopTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RestartContainerTest(BaseAPIIntegrationTest):
 | 
					class RestartContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_restart(self):
 | 
					    def test_restart(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, ['sleep', '9999'])
 | 
					        container = self.client.create_container(TEST_IMG, ['sleep', '9999'])
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
| 
						 | 
					@ -1159,7 +1159,7 @@ class RestartContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        self.client.kill(id)
 | 
					        self.client.kill(id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_restart_with_low_timeout(self):
 | 
					    def test_restart_with_low_timeout(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, ['sleep', '9999'])
 | 
					        container = self.client.create_container(TEST_IMG, ['sleep', '9999'])
 | 
				
			||||||
        self.client.start(container)
 | 
					        self.client.start(container)
 | 
				
			||||||
        self.client.timeout = 3
 | 
					        self.client.timeout = 3
 | 
				
			||||||
        self.client.restart(container, timeout=1)
 | 
					        self.client.restart(container, timeout=1)
 | 
				
			||||||
| 
						 | 
					@ -1168,7 +1168,7 @@ class RestartContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        self.client.kill(container)
 | 
					        self.client.kill(container)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_restart_with_dict_instead_of_id(self):
 | 
					    def test_restart_with_dict_instead_of_id(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, ['sleep', '9999'])
 | 
					        container = self.client.create_container(TEST_IMG, ['sleep', '9999'])
 | 
				
			||||||
        assert 'Id' in container
 | 
					        assert 'Id' in container
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(container)
 | 
					        self.client.start(container)
 | 
				
			||||||
| 
						 | 
					@ -1190,7 +1190,7 @@ class RestartContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RemoveContainerTest(BaseAPIIntegrationTest):
 | 
					class RemoveContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_remove(self):
 | 
					    def test_remove(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, ['true'])
 | 
					        container = self.client.create_container(TEST_IMG, ['true'])
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
        self.client.wait(id)
 | 
					        self.client.wait(id)
 | 
				
			||||||
| 
						 | 
					@ -1200,7 +1200,7 @@ class RemoveContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert len(res) == 0
 | 
					        assert len(res) == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_remove_with_dict_instead_of_id(self):
 | 
					    def test_remove_with_dict_instead_of_id(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, ['true'])
 | 
					        container = self.client.create_container(TEST_IMG, ['true'])
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
        self.client.wait(id)
 | 
					        self.client.wait(id)
 | 
				
			||||||
| 
						 | 
					@ -1212,7 +1212,7 @@ class RemoveContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AttachContainerTest(BaseAPIIntegrationTest):
 | 
					class AttachContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_run_container_streaming(self):
 | 
					    def test_run_container_streaming(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, '/bin/sh',
 | 
					        container = self.client.create_container(TEST_IMG, '/bin/sh',
 | 
				
			||||||
                                                 detach=True, stdin_open=True)
 | 
					                                                 detach=True, stdin_open=True)
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
| 
						 | 
					@ -1224,7 +1224,7 @@ class AttachContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        line = 'hi there and stuff and things, words!'
 | 
					        line = 'hi there and stuff and things, words!'
 | 
				
			||||||
        # `echo` appends CRLF, `printf` doesn't
 | 
					        # `echo` appends CRLF, `printf` doesn't
 | 
				
			||||||
        command = "printf '{0}'".format(line)
 | 
					        command = "printf '{0}'".format(line)
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, command,
 | 
					        container = self.client.create_container(TEST_IMG, command,
 | 
				
			||||||
                                                 detach=True, tty=False)
 | 
					                                                 detach=True, tty=False)
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1242,7 +1242,7 @@ class AttachContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_attach_no_stream(self):
 | 
					    def test_attach_no_stream(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'echo hello'
 | 
					            TEST_IMG, 'echo hello'
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
        self.client.start(container)
 | 
					        self.client.start(container)
 | 
				
			||||||
| 
						 | 
					@ -1257,7 +1257,7 @@ class AttachContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
                       reason='Flaky test on TLS')
 | 
					                       reason='Flaky test on TLS')
 | 
				
			||||||
    def test_attach_stream_and_cancel(self):
 | 
					    def test_attach_stream_and_cancel(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'sh -c "sleep 2 && echo hello && sleep 60"',
 | 
					            TEST_IMG, 'sh -c "sleep 2 && echo hello && sleep 60"',
 | 
				
			||||||
            tty=True
 | 
					            tty=True
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
| 
						 | 
					@ -1275,7 +1275,7 @@ class AttachContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_detach_with_default(self):
 | 
					    def test_detach_with_default(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'cat',
 | 
					            TEST_IMG, 'cat',
 | 
				
			||||||
            detach=True, stdin_open=True, tty=True
 | 
					            detach=True, stdin_open=True, tty=True
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
| 
						 | 
					@ -1294,7 +1294,7 @@ class AttachContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        self.client._general_configs['detachKeys'] = 'ctrl-p'
 | 
					        self.client._general_configs['detachKeys'] = 'ctrl-p'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'cat',
 | 
					            TEST_IMG, 'cat',
 | 
				
			||||||
            detach=True, stdin_open=True, tty=True
 | 
					            detach=True, stdin_open=True, tty=True
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
| 
						 | 
					@ -1311,7 +1311,7 @@ class AttachContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        self.client._general_configs['detachKeys'] = 'ctrl-p'
 | 
					        self.client._general_configs['detachKeys'] = 'ctrl-p'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'cat',
 | 
					            TEST_IMG, 'cat',
 | 
				
			||||||
            detach=True, stdin_open=True, tty=True
 | 
					            detach=True, stdin_open=True, tty=True
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
| 
						 | 
					@ -1327,7 +1327,7 @@ class AttachContainerTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PauseTest(BaseAPIIntegrationTest):
 | 
					class PauseTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_pause_unpause(self):
 | 
					    def test_pause_unpause(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, ['sleep', '9999'])
 | 
					        container = self.client.create_container(TEST_IMG, ['sleep', '9999'])
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
        self.client.start(container)
 | 
					        self.client.start(container)
 | 
				
			||||||
| 
						 | 
					@ -1358,9 +1358,9 @@ class PruneTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    @requires_api_version('1.25')
 | 
					    @requires_api_version('1.25')
 | 
				
			||||||
    def test_prune_containers(self):
 | 
					    def test_prune_containers(self):
 | 
				
			||||||
        container1 = self.client.create_container(
 | 
					        container1 = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['sh', '-c', 'echo hello > /data.txt']
 | 
					            TEST_IMG, ['sh', '-c', 'echo hello > /data.txt']
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        container2 = self.client.create_container(BUSYBOX, ['sleep', '9999'])
 | 
					        container2 = self.client.create_container(TEST_IMG, ['sleep', '9999'])
 | 
				
			||||||
        self.client.start(container1)
 | 
					        self.client.start(container1)
 | 
				
			||||||
        self.client.start(container2)
 | 
					        self.client.start(container2)
 | 
				
			||||||
        self.client.wait(container1)
 | 
					        self.client.wait(container1)
 | 
				
			||||||
| 
						 | 
					@ -1373,7 +1373,7 @@ class PruneTest(BaseAPIIntegrationTest):
 | 
				
			||||||
class GetContainerStatsTest(BaseAPIIntegrationTest):
 | 
					class GetContainerStatsTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_get_container_stats_no_stream(self):
 | 
					    def test_get_container_stats_no_stream(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['sleep', '60'],
 | 
					            TEST_IMG, ['sleep', '60'],
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
        self.client.start(container)
 | 
					        self.client.start(container)
 | 
				
			||||||
| 
						 | 
					@ -1387,7 +1387,7 @@ class GetContainerStatsTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def test_get_container_stats_stream(self):
 | 
					        def test_get_container_stats_stream(self):
 | 
				
			||||||
            container = self.client.create_container(
 | 
					            container = self.client.create_container(
 | 
				
			||||||
                BUSYBOX, ['sleep', '60'],
 | 
					                TEST_IMG, ['sleep', '60'],
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            self.tmp_containers.append(container)
 | 
					            self.tmp_containers.append(container)
 | 
				
			||||||
            self.client.start(container)
 | 
					            self.client.start(container)
 | 
				
			||||||
| 
						 | 
					@ -1405,7 +1405,7 @@ class ContainerUpdateTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        old_mem_limit = 400 * 1024 * 1024
 | 
					        old_mem_limit = 400 * 1024 * 1024
 | 
				
			||||||
        new_mem_limit = 300 * 1024 * 1024
 | 
					        new_mem_limit = 300 * 1024 * 1024
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'top', host_config=self.client.create_host_config(
 | 
					            TEST_IMG, 'top', host_config=self.client.create_host_config(
 | 
				
			||||||
                mem_limit=old_mem_limit
 | 
					                mem_limit=old_mem_limit
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -1426,7 +1426,7 @@ class ContainerUpdateTest(BaseAPIIntegrationTest):
 | 
				
			||||||
            'Name': 'on-failure'
 | 
					            'Name': 'on-failure'
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['sleep', '60'],
 | 
					            TEST_IMG, ['sleep', '60'],
 | 
				
			||||||
            host_config=self.client.create_host_config(
 | 
					            host_config=self.client.create_host_config(
 | 
				
			||||||
                restart_policy=old_restart_policy
 | 
					                restart_policy=old_restart_policy
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
| 
						 | 
					@ -1450,7 +1450,7 @@ class ContainerCPUTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_container_cpu_shares(self):
 | 
					    def test_container_cpu_shares(self):
 | 
				
			||||||
        cpu_shares = 512
 | 
					        cpu_shares = 512
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'ls', host_config=self.client.create_host_config(
 | 
					            TEST_IMG, 'ls', host_config=self.client.create_host_config(
 | 
				
			||||||
                cpu_shares=cpu_shares
 | 
					                cpu_shares=cpu_shares
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -1462,7 +1462,7 @@ class ContainerCPUTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_container_cpuset(self):
 | 
					    def test_container_cpuset(self):
 | 
				
			||||||
        cpuset_cpus = "0,1"
 | 
					        cpuset_cpus = "0,1"
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'ls', host_config=self.client.create_host_config(
 | 
					            TEST_IMG, 'ls', host_config=self.client.create_host_config(
 | 
				
			||||||
                cpuset_cpus=cpuset_cpus
 | 
					                cpuset_cpus=cpuset_cpus
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -1474,7 +1474,7 @@ class ContainerCPUTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    @requires_api_version('1.25')
 | 
					    @requires_api_version('1.25')
 | 
				
			||||||
    def test_create_with_runtime(self):
 | 
					    def test_create_with_runtime(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['echo', 'test'], runtime='runc'
 | 
					            TEST_IMG, ['echo', 'test'], runtime='runc'
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(container['Id'])
 | 
					        self.tmp_containers.append(container['Id'])
 | 
				
			||||||
        config = self.client.inspect_container(container)
 | 
					        config = self.client.inspect_container(container)
 | 
				
			||||||
| 
						 | 
					@ -1485,7 +1485,7 @@ class LinkTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_remove_link(self):
 | 
					    def test_remove_link(self):
 | 
				
			||||||
        # Create containers
 | 
					        # Create containers
 | 
				
			||||||
        container1 = self.client.create_container(
 | 
					        container1 = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'cat', detach=True, stdin_open=True
 | 
					            TEST_IMG, 'cat', detach=True, stdin_open=True
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        container1_id = container1['Id']
 | 
					        container1_id = container1['Id']
 | 
				
			||||||
        self.tmp_containers.append(container1_id)
 | 
					        self.tmp_containers.append(container1_id)
 | 
				
			||||||
| 
						 | 
					@ -1497,7 +1497,7 @@ class LinkTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        link_alias = 'mylink'
 | 
					        link_alias = 'mylink'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        container2 = self.client.create_container(
 | 
					        container2 = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'cat', host_config=self.client.create_host_config(
 | 
					            TEST_IMG, 'cat', host_config=self.client.create_host_config(
 | 
				
			||||||
                links={link_path: link_alias}
 | 
					                links={link_path: link_alias}
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@ from ..helpers import assert_cat_socket_detached_with_keys
 | 
				
			||||||
from ..helpers import ctrl_with
 | 
					from ..helpers import ctrl_with
 | 
				
			||||||
from ..helpers import requires_api_version
 | 
					from ..helpers import requires_api_version
 | 
				
			||||||
from .base import BaseAPIIntegrationTest
 | 
					from .base import BaseAPIIntegrationTest
 | 
				
			||||||
from .base import BUSYBOX
 | 
					from .base import TEST_IMG
 | 
				
			||||||
from docker.utils.proxy import ProxyConfig
 | 
					from docker.utils.proxy import ProxyConfig
 | 
				
			||||||
from docker.utils.socket import next_frame_header
 | 
					from docker.utils.socket import next_frame_header
 | 
				
			||||||
from docker.utils.socket import read_exactly
 | 
					from docker.utils.socket import read_exactly
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@ class ExecTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'cat', detach=True, stdin_open=True,
 | 
					            TEST_IMG, 'cat', detach=True, stdin_open=True,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.client.start(container)
 | 
					        self.client.start(container)
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
| 
						 | 
					@ -48,7 +48,7 @@ class ExecTest(BaseAPIIntegrationTest):
 | 
				
			||||||
            assert item in output
 | 
					            assert item in output
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_execute_command(self):
 | 
					    def test_execute_command(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, 'cat',
 | 
					        container = self.client.create_container(TEST_IMG, 'cat',
 | 
				
			||||||
                                                 detach=True, stdin_open=True)
 | 
					                                                 detach=True, stdin_open=True)
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
| 
						 | 
					@ -61,7 +61,7 @@ class ExecTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert exec_log == b'hello\n'
 | 
					        assert exec_log == b'hello\n'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_exec_command_string(self):
 | 
					    def test_exec_command_string(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, 'cat',
 | 
					        container = self.client.create_container(TEST_IMG, 'cat',
 | 
				
			||||||
                                                 detach=True, stdin_open=True)
 | 
					                                                 detach=True, stdin_open=True)
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
| 
						 | 
					@ -74,7 +74,7 @@ class ExecTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert exec_log == b'hello world\n'
 | 
					        assert exec_log == b'hello world\n'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_exec_command_as_user(self):
 | 
					    def test_exec_command_as_user(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, 'cat',
 | 
					        container = self.client.create_container(TEST_IMG, 'cat',
 | 
				
			||||||
                                                 detach=True, stdin_open=True)
 | 
					                                                 detach=True, stdin_open=True)
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
| 
						 | 
					@ -87,7 +87,7 @@ class ExecTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert exec_log == b'postgres\n'
 | 
					        assert exec_log == b'postgres\n'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_exec_command_as_root(self):
 | 
					    def test_exec_command_as_root(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, 'cat',
 | 
					        container = self.client.create_container(TEST_IMG, 'cat',
 | 
				
			||||||
                                                 detach=True, stdin_open=True)
 | 
					                                                 detach=True, stdin_open=True)
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
| 
						 | 
					@ -100,7 +100,7 @@ class ExecTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert exec_log == b'root\n'
 | 
					        assert exec_log == b'root\n'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_exec_command_streaming(self):
 | 
					    def test_exec_command_streaming(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, 'cat',
 | 
					        container = self.client.create_container(TEST_IMG, 'cat',
 | 
				
			||||||
                                                 detach=True, stdin_open=True)
 | 
					                                                 detach=True, stdin_open=True)
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
| 
						 | 
					@ -115,7 +115,7 @@ class ExecTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert res == b'hello\nworld\n'
 | 
					        assert res == b'hello\nworld\n'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_exec_start_socket(self):
 | 
					    def test_exec_start_socket(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, 'cat',
 | 
					        container = self.client.create_container(TEST_IMG, 'cat',
 | 
				
			||||||
                                                 detach=True, stdin_open=True)
 | 
					                                                 detach=True, stdin_open=True)
 | 
				
			||||||
        container_id = container['Id']
 | 
					        container_id = container['Id']
 | 
				
			||||||
        self.client.start(container_id)
 | 
					        self.client.start(container_id)
 | 
				
			||||||
| 
						 | 
					@ -137,7 +137,7 @@ class ExecTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert data.decode('utf-8') == line
 | 
					        assert data.decode('utf-8') == line
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_exec_start_detached(self):
 | 
					    def test_exec_start_detached(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, 'cat',
 | 
					        container = self.client.create_container(TEST_IMG, 'cat',
 | 
				
			||||||
                                                 detach=True, stdin_open=True)
 | 
					                                                 detach=True, stdin_open=True)
 | 
				
			||||||
        container_id = container['Id']
 | 
					        container_id = container['Id']
 | 
				
			||||||
        self.client.start(container_id)
 | 
					        self.client.start(container_id)
 | 
				
			||||||
| 
						 | 
					@ -152,7 +152,7 @@ class ExecTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert response == ""
 | 
					        assert response == ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_exec_inspect(self):
 | 
					    def test_exec_inspect(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, 'cat',
 | 
					        container = self.client.create_container(TEST_IMG, 'cat',
 | 
				
			||||||
                                                 detach=True, stdin_open=True)
 | 
					                                                 detach=True, stdin_open=True)
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
| 
						 | 
					@ -167,7 +167,7 @@ class ExecTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @requires_api_version('1.25')
 | 
					    @requires_api_version('1.25')
 | 
				
			||||||
    def test_exec_command_with_env(self):
 | 
					    def test_exec_command_with_env(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, 'cat',
 | 
					        container = self.client.create_container(TEST_IMG, 'cat',
 | 
				
			||||||
                                                 detach=True, stdin_open=True)
 | 
					                                                 detach=True, stdin_open=True)
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
| 
						 | 
					@ -182,7 +182,7 @@ class ExecTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    @requires_api_version('1.35')
 | 
					    @requires_api_version('1.35')
 | 
				
			||||||
    def test_exec_command_with_workdir(self):
 | 
					    def test_exec_command_with_workdir(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'cat', detach=True, stdin_open=True
 | 
					            TEST_IMG, 'cat', detach=True, stdin_open=True
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
        self.client.start(container)
 | 
					        self.client.start(container)
 | 
				
			||||||
| 
						 | 
					@ -193,7 +193,7 @@ class ExecTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_detach_with_default(self):
 | 
					    def test_detach_with_default(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'cat', detach=True, stdin_open=True
 | 
					            TEST_IMG, 'cat', detach=True, stdin_open=True
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
| 
						 | 
					@ -212,7 +212,7 @@ class ExecTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_detach_with_config_file(self):
 | 
					    def test_detach_with_config_file(self):
 | 
				
			||||||
        self.client._general_configs['detachKeys'] = 'ctrl-p'
 | 
					        self.client._general_configs['detachKeys'] = 'ctrl-p'
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'cat', detach=True, stdin_open=True
 | 
					            TEST_IMG, 'cat', detach=True, stdin_open=True
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
| 
						 | 
					@ -226,24 +226,6 @@ class ExecTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert_cat_socket_detached_with_keys(sock, [ctrl_with('p')])
 | 
					        assert_cat_socket_detached_with_keys(sock, [ctrl_with('p')])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_detach_with_arg(self):
 | 
					 | 
				
			||||||
        self.client._general_configs['detachKeys'] = 'ctrl-p'
 | 
					 | 
				
			||||||
        container = self.client.create_container(
 | 
					 | 
				
			||||||
            BUSYBOX, 'cat', detach=True, stdin_open=True
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
        id = container['Id']
 | 
					 | 
				
			||||||
        self.client.start(id)
 | 
					 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        exec_id = self.client.exec_create(
 | 
					 | 
				
			||||||
            id, 'cat',
 | 
					 | 
				
			||||||
            stdin=True, tty=True, detach_keys='ctrl-x', stdout=True
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
        sock = self.client.exec_start(exec_id, tty=True, socket=True)
 | 
					 | 
				
			||||||
        self.addCleanup(sock.close)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        assert_cat_socket_detached_with_keys(sock, [ctrl_with('x')])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ExecDemuxTest(BaseAPIIntegrationTest):
 | 
					class ExecDemuxTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    cmd = 'sh -c "{}"'.format(' ; '.join([
 | 
					    cmd = 'sh -c "{}"'.format(' ; '.join([
 | 
				
			||||||
| 
						 | 
					@ -259,7 +241,7 @@ class ExecDemuxTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def setUp(self):
 | 
					    def setUp(self):
 | 
				
			||||||
        super(ExecDemuxTest, self).setUp()
 | 
					        super(ExecDemuxTest, self).setUp()
 | 
				
			||||||
        self.container = self.client.create_container(
 | 
					        self.container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'cat', detach=True, stdin_open=True
 | 
					            TEST_IMG, 'cat', detach=True, stdin_open=True
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.client.start(self.container)
 | 
					        self.client.start(self.container)
 | 
				
			||||||
        self.tmp_containers.append(self.container)
 | 
					        self.tmp_containers.append(self.container)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
from .base import BaseAPIIntegrationTest, BUSYBOX
 | 
					from .base import BaseAPIIntegrationTest, TEST_IMG
 | 
				
			||||||
from .. import helpers
 | 
					from .. import helpers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SECOND = 1000000000
 | 
					SECOND = 1000000000
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@ class HealthcheckTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    @helpers.requires_api_version('1.24')
 | 
					    @helpers.requires_api_version('1.24')
 | 
				
			||||||
    def test_healthcheck_shell_command(self):
 | 
					    def test_healthcheck_shell_command(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'top', healthcheck=dict(test='echo "hello world"'))
 | 
					            TEST_IMG, 'top', healthcheck=dict(test='echo "hello world"'))
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        res = self.client.inspect_container(container)
 | 
					        res = self.client.inspect_container(container)
 | 
				
			||||||
| 
						 | 
					@ -27,7 +27,7 @@ class HealthcheckTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    @helpers.requires_api_version('1.24')
 | 
					    @helpers.requires_api_version('1.24')
 | 
				
			||||||
    def test_healthcheck_passes(self):
 | 
					    def test_healthcheck_passes(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'top', healthcheck=dict(
 | 
					            TEST_IMG, 'top', healthcheck=dict(
 | 
				
			||||||
                test="true",
 | 
					                test="true",
 | 
				
			||||||
                interval=1 * SECOND,
 | 
					                interval=1 * SECOND,
 | 
				
			||||||
                timeout=1 * SECOND,
 | 
					                timeout=1 * SECOND,
 | 
				
			||||||
| 
						 | 
					@ -40,7 +40,7 @@ class HealthcheckTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    @helpers.requires_api_version('1.24')
 | 
					    @helpers.requires_api_version('1.24')
 | 
				
			||||||
    def test_healthcheck_fails(self):
 | 
					    def test_healthcheck_fails(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'top', healthcheck=dict(
 | 
					            TEST_IMG, 'top', healthcheck=dict(
 | 
				
			||||||
                test="false",
 | 
					                test="false",
 | 
				
			||||||
                interval=1 * SECOND,
 | 
					                interval=1 * SECOND,
 | 
				
			||||||
                timeout=1 * SECOND,
 | 
					                timeout=1 * SECOND,
 | 
				
			||||||
| 
						 | 
					@ -53,7 +53,7 @@ class HealthcheckTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    @helpers.requires_api_version('1.29')
 | 
					    @helpers.requires_api_version('1.29')
 | 
				
			||||||
    def test_healthcheck_start_period(self):
 | 
					    def test_healthcheck_start_period(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'top', healthcheck=dict(
 | 
					            TEST_IMG, 'top', healthcheck=dict(
 | 
				
			||||||
                test="echo 'x' >> /counter.txt && "
 | 
					                test="echo 'x' >> /counter.txt && "
 | 
				
			||||||
                     "test `cat /counter.txt | wc -l` -ge 3",
 | 
					                     "test `cat /counter.txt | wc -l` -ge 3",
 | 
				
			||||||
                interval=1 * SECOND,
 | 
					                interval=1 * SECOND,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,7 @@ from six.moves import socketserver
 | 
				
			||||||
import docker
 | 
					import docker
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ..helpers import requires_api_version, requires_experimental
 | 
					from ..helpers import requires_api_version, requires_experimental
 | 
				
			||||||
from .base import BaseAPIIntegrationTest, BUSYBOX
 | 
					from .base import BaseAPIIntegrationTest, TEST_IMG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ListImagesTest(BaseAPIIntegrationTest):
 | 
					class ListImagesTest(BaseAPIIntegrationTest):
 | 
				
			||||||
| 
						 | 
					@ -69,13 +69,15 @@ class PullImageTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        with pytest.raises(docker.errors.APIError) as excinfo:
 | 
					        with pytest.raises(docker.errors.APIError) as excinfo:
 | 
				
			||||||
            self.client.pull('hello-world', platform='foobar')
 | 
					            self.client.pull('hello-world', platform='foobar')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert excinfo.value.status_code == 500
 | 
					        # Some API versions incorrectly returns 500 status; assert 4xx or 5xx
 | 
				
			||||||
        assert 'invalid platform' in excinfo.exconly()
 | 
					        assert excinfo.value.is_error()
 | 
				
			||||||
 | 
					        assert 'unknown operating system' in excinfo.exconly() \
 | 
				
			||||||
 | 
					               or 'invalid platform' in excinfo.exconly()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CommitTest(BaseAPIIntegrationTest):
 | 
					class CommitTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_commit(self):
 | 
					    def test_commit(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, ['touch', '/test'])
 | 
					        container = self.client.create_container(TEST_IMG, ['touch', '/test'])
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
| 
						 | 
					@ -88,13 +90,13 @@ class CommitTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert img['Container'].startswith(id)
 | 
					        assert img['Container'].startswith(id)
 | 
				
			||||||
        assert 'ContainerConfig' in img
 | 
					        assert 'ContainerConfig' in img
 | 
				
			||||||
        assert 'Image' in img['ContainerConfig']
 | 
					        assert 'Image' in img['ContainerConfig']
 | 
				
			||||||
        assert BUSYBOX == img['ContainerConfig']['Image']
 | 
					        assert TEST_IMG == img['ContainerConfig']['Image']
 | 
				
			||||||
        busybox_id = self.client.inspect_image(BUSYBOX)['Id']
 | 
					        busybox_id = self.client.inspect_image(TEST_IMG)['Id']
 | 
				
			||||||
        assert 'Parent' in img
 | 
					        assert 'Parent' in img
 | 
				
			||||||
        assert img['Parent'] == busybox_id
 | 
					        assert img['Parent'] == busybox_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_commit_with_changes(self):
 | 
					    def test_commit_with_changes(self):
 | 
				
			||||||
        cid = self.client.create_container(BUSYBOX, ['touch', '/test'])
 | 
					        cid = self.client.create_container(TEST_IMG, ['touch', '/test'])
 | 
				
			||||||
        self.tmp_containers.append(cid)
 | 
					        self.tmp_containers.append(cid)
 | 
				
			||||||
        self.client.start(cid)
 | 
					        self.client.start(cid)
 | 
				
			||||||
        img_id = self.client.commit(
 | 
					        img_id = self.client.commit(
 | 
				
			||||||
| 
						 | 
					@ -110,7 +112,7 @@ class CommitTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RemoveImageTest(BaseAPIIntegrationTest):
 | 
					class RemoveImageTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_remove(self):
 | 
					    def test_remove(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, ['touch', '/test'])
 | 
					        container = self.client.create_container(TEST_IMG, ['touch', '/test'])
 | 
				
			||||||
        id = container['Id']
 | 
					        id = container['Id']
 | 
				
			||||||
        self.client.start(id)
 | 
					        self.client.start(id)
 | 
				
			||||||
        self.tmp_containers.append(id)
 | 
					        self.tmp_containers.append(id)
 | 
				
			||||||
| 
						 | 
					@ -317,7 +319,7 @@ class PruneImagesTest(BaseAPIIntegrationTest):
 | 
				
			||||||
            pass
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Ensure busybox does not get pruned
 | 
					        # Ensure busybox does not get pruned
 | 
				
			||||||
        ctnr = self.client.create_container(BUSYBOX, ['sleep', '9999'])
 | 
					        ctnr = self.client.create_container(TEST_IMG, ['sleep', '9999'])
 | 
				
			||||||
        self.tmp_containers.append(ctnr)
 | 
					        self.tmp_containers.append(ctnr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.client.pull('hello-world', tag='latest')
 | 
					        self.client.pull('hello-world', tag='latest')
 | 
				
			||||||
| 
						 | 
					@ -341,7 +343,7 @@ class SaveLoadImagesTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    @requires_api_version('1.23')
 | 
					    @requires_api_version('1.23')
 | 
				
			||||||
    def test_get_image_load_image(self):
 | 
					    def test_get_image_load_image(self):
 | 
				
			||||||
        with tempfile.TemporaryFile() as f:
 | 
					        with tempfile.TemporaryFile() as f:
 | 
				
			||||||
            stream = self.client.get_image(BUSYBOX)
 | 
					            stream = self.client.get_image(TEST_IMG)
 | 
				
			||||||
            for chunk in stream:
 | 
					            for chunk in stream:
 | 
				
			||||||
                f.write(chunk)
 | 
					                f.write(chunk)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -349,7 +351,7 @@ class SaveLoadImagesTest(BaseAPIIntegrationTest):
 | 
				
			||||||
            result = self.client.load_image(f.read())
 | 
					            result = self.client.load_image(f.read())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        success = False
 | 
					        success = False
 | 
				
			||||||
        result_line = 'Loaded image: {}\n'.format(BUSYBOX)
 | 
					        result_line = 'Loaded image: {}\n'.format(TEST_IMG)
 | 
				
			||||||
        for data in result:
 | 
					        for data in result:
 | 
				
			||||||
            print(data)
 | 
					            print(data)
 | 
				
			||||||
            if 'stream' in data:
 | 
					            if 'stream' in data:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,7 @@ from docker.types import IPAMConfig, IPAMPool
 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ..helpers import random_name, requires_api_version
 | 
					from ..helpers import random_name, requires_api_version
 | 
				
			||||||
from .base import BaseAPIIntegrationTest, BUSYBOX
 | 
					from .base import BaseAPIIntegrationTest, TEST_IMG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestNetworks(BaseAPIIntegrationTest):
 | 
					class TestNetworks(BaseAPIIntegrationTest):
 | 
				
			||||||
| 
						 | 
					@ -92,7 +92,7 @@ class TestNetworks(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_connect_and_disconnect_container(self):
 | 
					    def test_connect_and_disconnect_container(self):
 | 
				
			||||||
        net_name, net_id = self.create_network()
 | 
					        net_name, net_id = self.create_network()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, 'top')
 | 
					        container = self.client.create_container(TEST_IMG, 'top')
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
        self.client.start(container)
 | 
					        self.client.start(container)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,7 +119,7 @@ class TestNetworks(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_connect_and_force_disconnect_container(self):
 | 
					    def test_connect_and_force_disconnect_container(self):
 | 
				
			||||||
        net_name, net_id = self.create_network()
 | 
					        net_name, net_id = self.create_network()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, 'top')
 | 
					        container = self.client.create_container(TEST_IMG, 'top')
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
        self.client.start(container)
 | 
					        self.client.start(container)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -144,7 +144,7 @@ class TestNetworks(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_connect_with_aliases(self):
 | 
					    def test_connect_with_aliases(self):
 | 
				
			||||||
        net_name, net_id = self.create_network()
 | 
					        net_name, net_id = self.create_network()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, 'top')
 | 
					        container = self.client.create_container(TEST_IMG, 'top')
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
        self.client.start(container)
 | 
					        self.client.start(container)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -161,7 +161,7 @@ class TestNetworks(BaseAPIIntegrationTest):
 | 
				
			||||||
        net_name, net_id = self.create_network()
 | 
					        net_name, net_id = self.create_network()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            image=BUSYBOX,
 | 
					            image=TEST_IMG,
 | 
				
			||||||
            command='top',
 | 
					            command='top',
 | 
				
			||||||
            host_config=self.client.create_host_config(network_mode=net_name),
 | 
					            host_config=self.client.create_host_config(network_mode=net_name),
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -181,7 +181,7 @@ class TestNetworks(BaseAPIIntegrationTest):
 | 
				
			||||||
        net_name, net_id = self.create_network()
 | 
					        net_name, net_id = self.create_network()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            image=BUSYBOX,
 | 
					            image=TEST_IMG,
 | 
				
			||||||
            command='top',
 | 
					            command='top',
 | 
				
			||||||
            host_config=self.client.create_host_config(
 | 
					            host_config=self.client.create_host_config(
 | 
				
			||||||
                network_mode=net_name,
 | 
					                network_mode=net_name,
 | 
				
			||||||
| 
						 | 
					@ -211,7 +211,7 @@ class TestNetworks(BaseAPIIntegrationTest):
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            image=BUSYBOX, command='top',
 | 
					            image=TEST_IMG, command='top',
 | 
				
			||||||
            host_config=self.client.create_host_config(network_mode=net_name),
 | 
					            host_config=self.client.create_host_config(network_mode=net_name),
 | 
				
			||||||
            networking_config=self.client.create_networking_config({
 | 
					            networking_config=self.client.create_networking_config({
 | 
				
			||||||
                net_name: self.client.create_endpoint_config(
 | 
					                net_name: self.client.create_endpoint_config(
 | 
				
			||||||
| 
						 | 
					@ -237,7 +237,7 @@ class TestNetworks(BaseAPIIntegrationTest):
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            image=BUSYBOX, command='top',
 | 
					            image=TEST_IMG, command='top',
 | 
				
			||||||
            host_config=self.client.create_host_config(network_mode=net_name),
 | 
					            host_config=self.client.create_host_config(network_mode=net_name),
 | 
				
			||||||
            networking_config=self.client.create_networking_config({
 | 
					            networking_config=self.client.create_networking_config({
 | 
				
			||||||
                net_name: self.client.create_endpoint_config(
 | 
					                net_name: self.client.create_endpoint_config(
 | 
				
			||||||
| 
						 | 
					@ -257,7 +257,7 @@ class TestNetworks(BaseAPIIntegrationTest):
 | 
				
			||||||
    @requires_api_version('1.24')
 | 
					    @requires_api_version('1.24')
 | 
				
			||||||
    def test_create_with_linklocal_ips(self):
 | 
					    def test_create_with_linklocal_ips(self):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, 'top',
 | 
					            TEST_IMG, 'top',
 | 
				
			||||||
            networking_config=self.client.create_networking_config(
 | 
					            networking_config=self.client.create_networking_config(
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    'bridge': self.client.create_endpoint_config(
 | 
					                    'bridge': self.client.create_endpoint_config(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,7 @@ import six
 | 
				
			||||||
from ..helpers import (
 | 
					from ..helpers import (
 | 
				
			||||||
    force_leave_swarm, requires_api_version, requires_experimental
 | 
					    force_leave_swarm, requires_api_version, requires_experimental
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from .base import BaseAPIIntegrationTest, BUSYBOX
 | 
					from .base import BaseAPIIntegrationTest, TEST_IMG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ServiceTest(BaseAPIIntegrationTest):
 | 
					class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
| 
						 | 
					@ -60,7 +60,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
            name = self.get_service_name()
 | 
					            name = self.get_service_name()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(
 | 
					        container_spec = docker.types.ContainerSpec(
 | 
				
			||||||
            BUSYBOX, ['echo', 'hello']
 | 
					            TEST_IMG, ['echo', 'hello']
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        return name, self.client.create_service(
 | 
					        return name, self.client.create_service(
 | 
				
			||||||
| 
						 | 
					@ -156,7 +156,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_service_custom_log_driver(self):
 | 
					    def test_create_service_custom_log_driver(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(
 | 
					        container_spec = docker.types.ContainerSpec(
 | 
				
			||||||
            BUSYBOX, ['echo', 'hello']
 | 
					            TEST_IMG, ['echo', 'hello']
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        log_cfg = docker.types.DriverConfig('none')
 | 
					        log_cfg = docker.types.DriverConfig('none')
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(
 | 
					        task_tmpl = docker.types.TaskTemplate(
 | 
				
			||||||
| 
						 | 
					@ -174,7 +174,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_create_service_with_volume_mount(self):
 | 
					    def test_create_service_with_volume_mount(self):
 | 
				
			||||||
        vol_name = self.get_service_name()
 | 
					        vol_name = self.get_service_name()
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(
 | 
					        container_spec = docker.types.ContainerSpec(
 | 
				
			||||||
            BUSYBOX, ['ls'],
 | 
					            TEST_IMG, ['ls'],
 | 
				
			||||||
            mounts=[
 | 
					            mounts=[
 | 
				
			||||||
                docker.types.Mount(target='/test', source=vol_name)
 | 
					                docker.types.Mount(target='/test', source=vol_name)
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
| 
						 | 
					@ -194,7 +194,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert mount['Type'] == 'volume'
 | 
					        assert mount['Type'] == 'volume'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_service_with_resources_constraints(self):
 | 
					    def test_create_service_with_resources_constraints(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
        resources = docker.types.Resources(
 | 
					        resources = docker.types.Resources(
 | 
				
			||||||
            cpu_limit=4000000, mem_limit=3 * 1024 * 1024 * 1024,
 | 
					            cpu_limit=4000000, mem_limit=3 * 1024 * 1024 * 1024,
 | 
				
			||||||
            cpu_reservation=3500000, mem_reservation=2 * 1024 * 1024 * 1024
 | 
					            cpu_reservation=3500000, mem_reservation=2 * 1024 * 1024 * 1024
 | 
				
			||||||
| 
						 | 
					@ -214,7 +214,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _create_service_with_generic_resources(self, generic_resources):
 | 
					    def _create_service_with_generic_resources(self, generic_resources):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        resources = docker.types.Resources(
 | 
					        resources = docker.types.Resources(
 | 
				
			||||||
            generic_resources=generic_resources
 | 
					            generic_resources=generic_resources
 | 
				
			||||||
| 
						 | 
					@ -265,7 +265,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
                self._create_service_with_generic_resources(test_input)
 | 
					                self._create_service_with_generic_resources(test_input)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_service_with_update_config(self):
 | 
					    def test_create_service_with_update_config(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        update_config = docker.types.UpdateConfig(
 | 
					        update_config = docker.types.UpdateConfig(
 | 
				
			||||||
            parallelism=10, delay=5, failure_action='pause'
 | 
					            parallelism=10, delay=5, failure_action='pause'
 | 
				
			||||||
| 
						 | 
					@ -283,7 +283,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @requires_api_version('1.28')
 | 
					    @requires_api_version('1.28')
 | 
				
			||||||
    def test_create_service_with_failure_action_rollback(self):
 | 
					    def test_create_service_with_failure_action_rollback(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        update_config = docker.types.UpdateConfig(failure_action='rollback')
 | 
					        update_config = docker.types.UpdateConfig(failure_action='rollback')
 | 
				
			||||||
        name = self.get_service_name()
 | 
					        name = self.get_service_name()
 | 
				
			||||||
| 
						 | 
					@ -314,7 +314,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @requires_api_version('1.28')
 | 
					    @requires_api_version('1.28')
 | 
				
			||||||
    def test_create_service_with_rollback_config(self):
 | 
					    def test_create_service_with_rollback_config(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        rollback_cfg = docker.types.RollbackConfig(
 | 
					        rollback_cfg = docker.types.RollbackConfig(
 | 
				
			||||||
            parallelism=10, delay=5, failure_action='pause',
 | 
					            parallelism=10, delay=5, failure_action='pause',
 | 
				
			||||||
| 
						 | 
					@ -334,7 +334,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert rollback_cfg['MaxFailureRatio'] == rc['MaxFailureRatio']
 | 
					        assert rollback_cfg['MaxFailureRatio'] == rc['MaxFailureRatio']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_service_with_restart_policy(self):
 | 
					    def test_create_service_with_restart_policy(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
        policy = docker.types.RestartPolicy(
 | 
					        policy = docker.types.RestartPolicy(
 | 
				
			||||||
            docker.types.RestartPolicy.condition_types.ANY,
 | 
					            docker.types.RestartPolicy.condition_types.ANY,
 | 
				
			||||||
            delay=5, max_attempts=5
 | 
					            delay=5, max_attempts=5
 | 
				
			||||||
| 
						 | 
					@ -357,7 +357,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
            'dockerpytest_2', driver='overlay', ipam={'Driver': 'default'}
 | 
					            'dockerpytest_2', driver='overlay', ipam={'Driver': 'default'}
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_networks.append(net2['Id'])
 | 
					        self.tmp_networks.append(net2['Id'])
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        name = self.get_service_name()
 | 
					        name = self.get_service_name()
 | 
				
			||||||
        svc_id = self.client.create_service(
 | 
					        svc_id = self.client.create_service(
 | 
				
			||||||
| 
						 | 
					@ -371,9 +371,38 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
            {'Target': net1['Id']}, {'Target': net2['Id']}
 | 
					            {'Target': net1['Id']}, {'Target': net2['Id']}
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_create_service_with_network_attachment_config(self):
 | 
				
			||||||
 | 
					        network = self.client.create_network(
 | 
				
			||||||
 | 
					            'dockerpytest_1', driver='overlay', ipam={'Driver': 'default'}
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.tmp_networks.append(network['Id'])
 | 
				
			||||||
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
 | 
					        network_config = docker.types.NetworkAttachmentConfig(
 | 
				
			||||||
 | 
					            target='dockerpytest_1',
 | 
				
			||||||
 | 
					            aliases=['dockerpytest_1_alias'],
 | 
				
			||||||
 | 
					            options={
 | 
				
			||||||
 | 
					                'foo': 'bar'
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        task_tmpl = docker.types.TaskTemplate(
 | 
				
			||||||
 | 
					            container_spec,
 | 
				
			||||||
 | 
					            networks=[network_config]
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        name = self.get_service_name()
 | 
				
			||||||
 | 
					        svc_id = self.client.create_service(
 | 
				
			||||||
 | 
					            task_tmpl, name=name
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        svc_info = self.client.inspect_service(svc_id)
 | 
				
			||||||
 | 
					        assert 'Networks' in svc_info['Spec']['TaskTemplate']
 | 
				
			||||||
 | 
					        service_networks_info = svc_info['Spec']['TaskTemplate']['Networks']
 | 
				
			||||||
 | 
					        assert len(service_networks_info) == 1
 | 
				
			||||||
 | 
					        assert service_networks_info[0]['Target'] == network['Id']
 | 
				
			||||||
 | 
					        assert service_networks_info[0]['Aliases'] == ['dockerpytest_1_alias']
 | 
				
			||||||
 | 
					        assert service_networks_info[0]['DriverOpts'] == {'foo': 'bar'}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_service_with_placement(self):
 | 
					    def test_create_service_with_placement(self):
 | 
				
			||||||
        node_id = self.client.nodes()[0]['ID']
 | 
					        node_id = self.client.nodes()[0]['ID']
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(
 | 
					        task_tmpl = docker.types.TaskTemplate(
 | 
				
			||||||
            container_spec, placement=['node.id=={}'.format(node_id)]
 | 
					            container_spec, placement=['node.id=={}'.format(node_id)]
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -386,7 +415,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_service_with_placement_object(self):
 | 
					    def test_create_service_with_placement_object(self):
 | 
				
			||||||
        node_id = self.client.nodes()[0]['ID']
 | 
					        node_id = self.client.nodes()[0]['ID']
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
        placemt = docker.types.Placement(
 | 
					        placemt = docker.types.Placement(
 | 
				
			||||||
            constraints=['node.id=={}'.format(node_id)]
 | 
					            constraints=['node.id=={}'.format(node_id)]
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -401,7 +430,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @requires_api_version('1.30')
 | 
					    @requires_api_version('1.30')
 | 
				
			||||||
    def test_create_service_with_placement_platform(self):
 | 
					    def test_create_service_with_placement_platform(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
        placemt = docker.types.Placement(platforms=[('x86_64', 'linux')])
 | 
					        placemt = docker.types.Placement(platforms=[('x86_64', 'linux')])
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(
 | 
					        task_tmpl = docker.types.TaskTemplate(
 | 
				
			||||||
            container_spec, placement=placemt
 | 
					            container_spec, placement=placemt
 | 
				
			||||||
| 
						 | 
					@ -414,7 +443,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @requires_api_version('1.27')
 | 
					    @requires_api_version('1.27')
 | 
				
			||||||
    def test_create_service_with_placement_preferences(self):
 | 
					    def test_create_service_with_placement_preferences(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
        placemt = docker.types.Placement(preferences=[
 | 
					        placemt = docker.types.Placement(preferences=[
 | 
				
			||||||
            {'Spread': {'SpreadDescriptor': 'com.dockerpy.test'}}
 | 
					            {'Spread': {'SpreadDescriptor': 'com.dockerpy.test'}}
 | 
				
			||||||
        ])
 | 
					        ])
 | 
				
			||||||
| 
						 | 
					@ -429,7 +458,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @requires_api_version('1.27')
 | 
					    @requires_api_version('1.27')
 | 
				
			||||||
    def test_create_service_with_placement_preferences_tuple(self):
 | 
					    def test_create_service_with_placement_preferences_tuple(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
        placemt = docker.types.Placement(preferences=(
 | 
					        placemt = docker.types.Placement(preferences=(
 | 
				
			||||||
            ('spread', 'com.dockerpy.test'),
 | 
					            ('spread', 'com.dockerpy.test'),
 | 
				
			||||||
        ))
 | 
					        ))
 | 
				
			||||||
| 
						 | 
					@ -443,7 +472,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert svc_info['Spec']['TaskTemplate']['Placement'] == placemt
 | 
					        assert svc_info['Spec']['TaskTemplate']['Placement'] == placemt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_service_with_endpoint_spec(self):
 | 
					    def test_create_service_with_endpoint_spec(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        name = self.get_service_name()
 | 
					        name = self.get_service_name()
 | 
				
			||||||
        endpoint_spec = docker.types.EndpointSpec(ports={
 | 
					        endpoint_spec = docker.types.EndpointSpec(ports={
 | 
				
			||||||
| 
						 | 
					@ -473,7 +502,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @requires_api_version('1.32')
 | 
					    @requires_api_version('1.32')
 | 
				
			||||||
    def test_create_service_with_endpoint_spec_host_publish_mode(self):
 | 
					    def test_create_service_with_endpoint_spec_host_publish_mode(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        name = self.get_service_name()
 | 
					        name = self.get_service_name()
 | 
				
			||||||
        endpoint_spec = docker.types.EndpointSpec(ports={
 | 
					        endpoint_spec = docker.types.EndpointSpec(ports={
 | 
				
			||||||
| 
						 | 
					@ -493,7 +522,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_service_with_env(self):
 | 
					    def test_create_service_with_env(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(
 | 
					        container_spec = docker.types.ContainerSpec(
 | 
				
			||||||
            BUSYBOX, ['true'], env={'DOCKER_PY_TEST': 1}
 | 
					            TEST_IMG, ['true'], env={'DOCKER_PY_TEST': 1}
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(
 | 
					        task_tmpl = docker.types.TaskTemplate(
 | 
				
			||||||
            container_spec,
 | 
					            container_spec,
 | 
				
			||||||
| 
						 | 
					@ -509,7 +538,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @requires_api_version('1.29')
 | 
					    @requires_api_version('1.29')
 | 
				
			||||||
    def test_create_service_with_update_order(self):
 | 
					    def test_create_service_with_update_order(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        update_config = docker.types.UpdateConfig(
 | 
					        update_config = docker.types.UpdateConfig(
 | 
				
			||||||
            parallelism=10, delay=5, order='start-first'
 | 
					            parallelism=10, delay=5, order='start-first'
 | 
				
			||||||
| 
						 | 
					@ -528,7 +557,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    @requires_api_version('1.25')
 | 
					    @requires_api_version('1.25')
 | 
				
			||||||
    def test_create_service_with_tty(self):
 | 
					    def test_create_service_with_tty(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(
 | 
					        container_spec = docker.types.ContainerSpec(
 | 
				
			||||||
            BUSYBOX, ['true'], tty=True
 | 
					            TEST_IMG, ['true'], tty=True
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(
 | 
					        task_tmpl = docker.types.TaskTemplate(
 | 
				
			||||||
            container_spec,
 | 
					            container_spec,
 | 
				
			||||||
| 
						 | 
					@ -545,7 +574,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    @requires_api_version('1.25')
 | 
					    @requires_api_version('1.25')
 | 
				
			||||||
    def test_create_service_with_tty_dict(self):
 | 
					    def test_create_service_with_tty_dict(self):
 | 
				
			||||||
        container_spec = {
 | 
					        container_spec = {
 | 
				
			||||||
            'Image': BUSYBOX,
 | 
					            'Image': TEST_IMG,
 | 
				
			||||||
            'Command': ['true'],
 | 
					            'Command': ['true'],
 | 
				
			||||||
            'TTY': True
 | 
					            'TTY': True
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -561,7 +590,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_service_global_mode(self):
 | 
					    def test_create_service_global_mode(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(
 | 
					        container_spec = docker.types.ContainerSpec(
 | 
				
			||||||
            BUSYBOX, ['echo', 'hello']
 | 
					            TEST_IMG, ['echo', 'hello']
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        name = self.get_service_name()
 | 
					        name = self.get_service_name()
 | 
				
			||||||
| 
						 | 
					@ -574,7 +603,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_service_replicated_mode(self):
 | 
					    def test_create_service_replicated_mode(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(
 | 
					        container_spec = docker.types.ContainerSpec(
 | 
				
			||||||
            BUSYBOX, ['echo', 'hello']
 | 
					            TEST_IMG, ['echo', 'hello']
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        name = self.get_service_name()
 | 
					        name = self.get_service_name()
 | 
				
			||||||
| 
						 | 
					@ -767,7 +796,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
            search=['local'], options=['debug']
 | 
					            search=['local'], options=['debug']
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(
 | 
					        container_spec = docker.types.ContainerSpec(
 | 
				
			||||||
            BUSYBOX, ['sleep', '999'], dns_config=dns_config
 | 
					            TEST_IMG, ['sleep', '999'], dns_config=dns_config
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        name = self.get_service_name()
 | 
					        name = self.get_service_name()
 | 
				
			||||||
| 
						 | 
					@ -787,7 +816,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
            start_period=3 * second, interval=int(second / 2),
 | 
					            start_period=3 * second, interval=int(second / 2),
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(
 | 
					        container_spec = docker.types.ContainerSpec(
 | 
				
			||||||
            BUSYBOX, ['sleep', '999'], healthcheck=hc
 | 
					            TEST_IMG, ['sleep', '999'], healthcheck=hc
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        name = self.get_service_name()
 | 
					        name = self.get_service_name()
 | 
				
			||||||
| 
						 | 
					@ -804,7 +833,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    @requires_api_version('1.28')
 | 
					    @requires_api_version('1.28')
 | 
				
			||||||
    def test_create_service_with_readonly(self):
 | 
					    def test_create_service_with_readonly(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(
 | 
					        container_spec = docker.types.ContainerSpec(
 | 
				
			||||||
            BUSYBOX, ['sleep', '999'], read_only=True
 | 
					            TEST_IMG, ['sleep', '999'], read_only=True
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        name = self.get_service_name()
 | 
					        name = self.get_service_name()
 | 
				
			||||||
| 
						 | 
					@ -818,7 +847,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    @requires_api_version('1.28')
 | 
					    @requires_api_version('1.28')
 | 
				
			||||||
    def test_create_service_with_stop_signal(self):
 | 
					    def test_create_service_with_stop_signal(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(
 | 
					        container_spec = docker.types.ContainerSpec(
 | 
				
			||||||
            BUSYBOX, ['sleep', '999'], stop_signal='SIGINT'
 | 
					            TEST_IMG, ['sleep', '999'], stop_signal='SIGINT'
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        name = self.get_service_name()
 | 
					        name = self.get_service_name()
 | 
				
			||||||
| 
						 | 
					@ -836,7 +865,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_create_service_with_privileges(self):
 | 
					    def test_create_service_with_privileges(self):
 | 
				
			||||||
        priv = docker.types.Privileges(selinux_disable=True)
 | 
					        priv = docker.types.Privileges(selinux_disable=True)
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(
 | 
					        container_spec = docker.types.ContainerSpec(
 | 
				
			||||||
            BUSYBOX, ['sleep', '999'], privileges=priv
 | 
					            TEST_IMG, ['sleep', '999'], privileges=priv
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        name = self.get_service_name()
 | 
					        name = self.get_service_name()
 | 
				
			||||||
| 
						 | 
					@ -992,7 +1021,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert labels['container.label'] == 'SampleLabel'
 | 
					        assert labels['container.label'] == 'SampleLabel'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_update_service_with_defaults_update_config(self):
 | 
					    def test_update_service_with_defaults_update_config(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        update_config = docker.types.UpdateConfig(
 | 
					        update_config = docker.types.UpdateConfig(
 | 
				
			||||||
            parallelism=10, delay=5, failure_action='pause'
 | 
					            parallelism=10, delay=5, failure_action='pause'
 | 
				
			||||||
| 
						 | 
					@ -1031,7 +1060,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
            'dockerpytest_2', driver='overlay', ipam={'Driver': 'default'}
 | 
					            'dockerpytest_2', driver='overlay', ipam={'Driver': 'default'}
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.tmp_networks.append(net2['Id'])
 | 
					        self.tmp_networks.append(net2['Id'])
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        name = self.get_service_name()
 | 
					        name = self.get_service_name()
 | 
				
			||||||
        svc_id = self.client.create_service(
 | 
					        svc_id = self.client.create_service(
 | 
				
			||||||
| 
						 | 
					@ -1070,7 +1099,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_update_service_with_defaults_endpoint_spec(self):
 | 
					    def test_update_service_with_defaults_endpoint_spec(self):
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(BUSYBOX, ['true'])
 | 
					        container_spec = docker.types.ContainerSpec(TEST_IMG, ['true'])
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        name = self.get_service_name()
 | 
					        name = self.get_service_name()
 | 
				
			||||||
        endpoint_spec = docker.types.EndpointSpec(ports={
 | 
					        endpoint_spec = docker.types.EndpointSpec(ports={
 | 
				
			||||||
| 
						 | 
					@ -1134,7 +1163,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
            start_period=3 * second, interval=int(second / 2),
 | 
					            start_period=3 * second, interval=int(second / 2),
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(
 | 
					        container_spec = docker.types.ContainerSpec(
 | 
				
			||||||
            BUSYBOX, ['sleep', '999'], healthcheck=hc
 | 
					            TEST_IMG, ['sleep', '999'], healthcheck=hc
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
        name = self.get_service_name()
 | 
					        name = self.get_service_name()
 | 
				
			||||||
| 
						 | 
					@ -1149,7 +1178,7 @@ class ServiceTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        container_spec = docker.types.ContainerSpec(
 | 
					        container_spec = docker.types.ContainerSpec(
 | 
				
			||||||
            BUSYBOX, ['sleep', '999'], healthcheck={}
 | 
					            TEST_IMG, ['sleep', '999'], healthcheck={}
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
					        task_tmpl = docker.types.TaskTemplate(container_spec)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -250,5 +250,6 @@ class SwarmTest(BaseAPIIntegrationTest):
 | 
				
			||||||
        assert key_1['UnlockKey'] != key_2['UnlockKey']
 | 
					        assert key_1['UnlockKey'] != key_2['UnlockKey']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @requires_api_version('1.30')
 | 
					    @requires_api_version('1.30')
 | 
				
			||||||
 | 
					    @pytest.mark.xfail(reason='Can fail if eth0 has multiple IP addresses')
 | 
				
			||||||
    def test_init_swarm_data_path_addr(self):
 | 
					    def test_init_swarm_data_path_addr(self):
 | 
				
			||||||
        assert self.init_swarm(data_path_addr='eth0')
 | 
					        assert self.init_swarm(data_path_addr='eth0')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@ import docker
 | 
				
			||||||
from .. import helpers
 | 
					from .. import helpers
 | 
				
			||||||
from docker.utils import kwargs_from_env
 | 
					from docker.utils import kwargs_from_env
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BUSYBOX = 'alpine:3.9.3'  # FIXME: this should probably be renamed
 | 
					TEST_IMG = 'alpine:3.10'
 | 
				
			||||||
TEST_API_VERSION = os.environ.get('DOCKER_TEST_API_VERSION')
 | 
					TEST_API_VERSION = os.environ.get('DOCKER_TEST_API_VERSION')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,7 +108,7 @@ class BaseAPIIntegrationTest(BaseIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return container
 | 
					        return container
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def create_and_start(self, image=BUSYBOX, command='top', **kwargs):
 | 
					    def create_and_start(self, image=TEST_IMG, command='top', **kwargs):
 | 
				
			||||||
        container = self.client.create_container(
 | 
					        container = self.client.create_container(
 | 
				
			||||||
            image=image, command=command, **kwargs)
 | 
					            image=image, command=command, **kwargs)
 | 
				
			||||||
        self.tmp_containers.append(container)
 | 
					        self.tmp_containers.append(container)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,7 @@ import docker.errors
 | 
				
			||||||
from docker.utils import kwargs_from_env
 | 
					from docker.utils import kwargs_from_env
 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .base import BUSYBOX
 | 
					from .base import TEST_IMG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pytest.fixture(autouse=True, scope='session')
 | 
					@pytest.fixture(autouse=True, scope='session')
 | 
				
			||||||
| 
						 | 
					@ -15,15 +15,15 @@ def setup_test_session():
 | 
				
			||||||
    warnings.simplefilter('error')
 | 
					    warnings.simplefilter('error')
 | 
				
			||||||
    c = docker.APIClient(version='auto', **kwargs_from_env())
 | 
					    c = docker.APIClient(version='auto', **kwargs_from_env())
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        c.inspect_image(BUSYBOX)
 | 
					        c.inspect_image(TEST_IMG)
 | 
				
			||||||
    except docker.errors.NotFound:
 | 
					    except docker.errors.NotFound:
 | 
				
			||||||
        print("\npulling {0}".format(BUSYBOX), file=sys.stderr)
 | 
					        print("\npulling {0}".format(TEST_IMG), file=sys.stderr)
 | 
				
			||||||
        for data in c.pull(BUSYBOX, stream=True, decode=True):
 | 
					        for data in c.pull(TEST_IMG, stream=True, decode=True):
 | 
				
			||||||
            status = data.get("status")
 | 
					            status = data.get("status")
 | 
				
			||||||
            progress = data.get("progress")
 | 
					            progress = data.get("progress")
 | 
				
			||||||
            detail = "{0} - {1}".format(status, progress)
 | 
					            detail = "{0} - {1}".format(status, progress)
 | 
				
			||||||
            print(detail, file=sys.stderr)
 | 
					            print(detail, file=sys.stderr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Double make sure we now have busybox
 | 
					        # Double make sure we now have busybox
 | 
				
			||||||
        c.inspect_image(BUSYBOX)
 | 
					        c.inspect_image(TEST_IMG)
 | 
				
			||||||
    c.close()
 | 
					    c.close()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,11 @@
 | 
				
			||||||
from docker.errors import APIError
 | 
					from docker.errors import APIError
 | 
				
			||||||
from .base import BaseAPIIntegrationTest, BUSYBOX
 | 
					from .base import BaseAPIIntegrationTest, TEST_IMG
 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ErrorsTest(BaseAPIIntegrationTest):
 | 
					class ErrorsTest(BaseAPIIntegrationTest):
 | 
				
			||||||
    def test_api_error_parses_json(self):
 | 
					    def test_api_error_parses_json(self):
 | 
				
			||||||
        container = self.client.create_container(BUSYBOX, ['sleep', '10'])
 | 
					        container = self.client.create_container(TEST_IMG, ['sleep', '10'])
 | 
				
			||||||
        self.client.start(container['Id'])
 | 
					        self.client.start(container['Id'])
 | 
				
			||||||
        with pytest.raises(APIError) as cm:
 | 
					        with pytest.raises(APIError) as cm:
 | 
				
			||||||
            self.client.remove_container(container['Id'])
 | 
					            self.client.remove_container(container['Id'])
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@ import tempfile
 | 
				
			||||||
import docker
 | 
					import docker
 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .base import BaseIntegrationTest, BUSYBOX, TEST_API_VERSION
 | 
					from .base import BaseIntegrationTest, TEST_IMG, TEST_API_VERSION
 | 
				
			||||||
from ..helpers import random_name
 | 
					from ..helpers import random_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,8 +72,8 @@ class ImageCollectionTest(BaseIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_pull_with_tag(self):
 | 
					    def test_pull_with_tag(self):
 | 
				
			||||||
        client = docker.from_env(version=TEST_API_VERSION)
 | 
					        client = docker.from_env(version=TEST_API_VERSION)
 | 
				
			||||||
        image = client.images.pull('alpine', tag='3.3')
 | 
					        image = client.images.pull('alpine', tag='3.10')
 | 
				
			||||||
        assert 'alpine:3.3' in image.attrs['RepoTags']
 | 
					        assert 'alpine:3.10' in image.attrs['RepoTags']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_pull_with_sha(self):
 | 
					    def test_pull_with_sha(self):
 | 
				
			||||||
        image_ref = (
 | 
					        image_ref = (
 | 
				
			||||||
| 
						 | 
					@ -97,7 +97,7 @@ class ImageCollectionTest(BaseIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_and_load(self):
 | 
					    def test_save_and_load(self):
 | 
				
			||||||
        client = docker.from_env(version=TEST_API_VERSION)
 | 
					        client = docker.from_env(version=TEST_API_VERSION)
 | 
				
			||||||
        image = client.images.get(BUSYBOX)
 | 
					        image = client.images.get(TEST_IMG)
 | 
				
			||||||
        with tempfile.TemporaryFile() as f:
 | 
					        with tempfile.TemporaryFile() as f:
 | 
				
			||||||
            stream = image.save()
 | 
					            stream = image.save()
 | 
				
			||||||
            for chunk in stream:
 | 
					            for chunk in stream:
 | 
				
			||||||
| 
						 | 
					@ -111,7 +111,7 @@ class ImageCollectionTest(BaseIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_and_load_repo_name(self):
 | 
					    def test_save_and_load_repo_name(self):
 | 
				
			||||||
        client = docker.from_env(version=TEST_API_VERSION)
 | 
					        client = docker.from_env(version=TEST_API_VERSION)
 | 
				
			||||||
        image = client.images.get(BUSYBOX)
 | 
					        image = client.images.get(TEST_IMG)
 | 
				
			||||||
        additional_tag = random_name()
 | 
					        additional_tag = random_name()
 | 
				
			||||||
        image.tag(additional_tag)
 | 
					        image.tag(additional_tag)
 | 
				
			||||||
        self.tmp_imgs.append(additional_tag)
 | 
					        self.tmp_imgs.append(additional_tag)
 | 
				
			||||||
| 
						 | 
					@ -131,7 +131,7 @@ class ImageCollectionTest(BaseIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_save_name_error(self):
 | 
					    def test_save_name_error(self):
 | 
				
			||||||
        client = docker.from_env(version=TEST_API_VERSION)
 | 
					        client = docker.from_env(version=TEST_API_VERSION)
 | 
				
			||||||
        image = client.images.get(BUSYBOX)
 | 
					        image = client.images.get(TEST_IMG)
 | 
				
			||||||
        with pytest.raises(docker.errors.InvalidArgument):
 | 
					        with pytest.raises(docker.errors.InvalidArgument):
 | 
				
			||||||
            image.save(named='sakuya/izayoi')
 | 
					            image.save(named='sakuya/izayoi')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@ import random
 | 
				
			||||||
import docker
 | 
					import docker
 | 
				
			||||||
import six
 | 
					import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .base import BaseAPIIntegrationTest, BUSYBOX
 | 
					from .base import BaseAPIIntegrationTest, TEST_IMG
 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,7 @@ class TestRegressions(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_542_truncate_ids_client_side(self):
 | 
					    def test_542_truncate_ids_client_side(self):
 | 
				
			||||||
        self.client.start(
 | 
					        self.client.start(
 | 
				
			||||||
            self.client.create_container(BUSYBOX, ['true'])
 | 
					            self.client.create_container(TEST_IMG, ['true'])
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        result = self.client.containers(all=True, trunc=True)
 | 
					        result = self.client.containers(all=True, trunc=True)
 | 
				
			||||||
        assert len(result[0]['Id']) == 12
 | 
					        assert len(result[0]['Id']) == 12
 | 
				
			||||||
| 
						 | 
					@ -30,12 +30,12 @@ class TestRegressions(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_649_handle_timeout_value_none(self):
 | 
					    def test_649_handle_timeout_value_none(self):
 | 
				
			||||||
        self.client.timeout = None
 | 
					        self.client.timeout = None
 | 
				
			||||||
        ctnr = self.client.create_container(BUSYBOX, ['sleep', '2'])
 | 
					        ctnr = self.client.create_container(TEST_IMG, ['sleep', '2'])
 | 
				
			||||||
        self.client.start(ctnr)
 | 
					        self.client.start(ctnr)
 | 
				
			||||||
        self.client.stop(ctnr)
 | 
					        self.client.stop(ctnr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_715_handle_user_param_as_int_value(self):
 | 
					    def test_715_handle_user_param_as_int_value(self):
 | 
				
			||||||
        ctnr = self.client.create_container(BUSYBOX, ['id', '-u'], user=1000)
 | 
					        ctnr = self.client.create_container(TEST_IMG, ['id', '-u'], user=1000)
 | 
				
			||||||
        self.client.start(ctnr)
 | 
					        self.client.start(ctnr)
 | 
				
			||||||
        self.client.wait(ctnr)
 | 
					        self.client.wait(ctnr)
 | 
				
			||||||
        logs = self.client.logs(ctnr)
 | 
					        logs = self.client.logs(ctnr)
 | 
				
			||||||
| 
						 | 
					@ -47,7 +47,7 @@ class TestRegressions(BaseAPIIntegrationTest):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        tcp_port, udp_port = random.sample(range(9999, 32000), 2)
 | 
					        tcp_port, udp_port = random.sample(range(9999, 32000), 2)
 | 
				
			||||||
        ctnr = self.client.create_container(
 | 
					        ctnr = self.client.create_container(
 | 
				
			||||||
            BUSYBOX, ['sleep', '9999'], ports=[2000, (2000, 'udp')],
 | 
					            TEST_IMG, ['sleep', '9999'], ports=[2000, (2000, 'udp')],
 | 
				
			||||||
            host_config=self.client.create_host_config(
 | 
					            host_config=self.client.create_host_config(
 | 
				
			||||||
                port_bindings={'2000/tcp': tcp_port, '2000/udp': udp_port}
 | 
					                port_bindings={'2000/tcp': tcp_port, '2000/udp': udp_port}
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -530,11 +530,21 @@ class CredstoreTest(unittest.TestCase):
 | 
				
			||||||
                'Password': 'izayoi',
 | 
					                'Password': 'izayoi',
 | 
				
			||||||
                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
					                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            'gensokyo.jp': {
 | 
				
			||||||
 | 
					                'Username': 'sakuya',
 | 
				
			||||||
 | 
					                'Password': 'izayoi',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            'https://default.com/v2': {
 | 
					            'https://default.com/v2': {
 | 
				
			||||||
                'Username': 'user',
 | 
					                'Username': 'user',
 | 
				
			||||||
                'Password': 'hunter2',
 | 
					                'Password': 'hunter2',
 | 
				
			||||||
                'ServerAddress': 'https://default.com/v2',
 | 
					                'ServerAddress': 'https://default.com/v2',
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            'default.com': {
 | 
				
			||||||
 | 
					                'Username': 'user',
 | 
				
			||||||
 | 
					                'Password': 'hunter2',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://default.com/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_get_all_credentials_with_empty_credhelper(self):
 | 
					    def test_get_all_credentials_with_empty_credhelper(self):
 | 
				
			||||||
| 
						 | 
					@ -548,11 +558,21 @@ class CredstoreTest(unittest.TestCase):
 | 
				
			||||||
                'Password': 'izayoi',
 | 
					                'Password': 'izayoi',
 | 
				
			||||||
                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
					                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            'gensokyo.jp': {
 | 
				
			||||||
 | 
					                'Username': 'sakuya',
 | 
				
			||||||
 | 
					                'Password': 'izayoi',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            'https://default.com/v2': {
 | 
					            'https://default.com/v2': {
 | 
				
			||||||
                'Username': 'user',
 | 
					                'Username': 'user',
 | 
				
			||||||
                'Password': 'hunter2',
 | 
					                'Password': 'hunter2',
 | 
				
			||||||
                'ServerAddress': 'https://default.com/v2',
 | 
					                'ServerAddress': 'https://default.com/v2',
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            'default.com': {
 | 
				
			||||||
 | 
					                'Username': 'user',
 | 
				
			||||||
 | 
					                'Password': 'hunter2',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://default.com/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            'registry1.io': None,
 | 
					            'registry1.io': None,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -571,11 +591,21 @@ class CredstoreTest(unittest.TestCase):
 | 
				
			||||||
                'Password': 'izayoi',
 | 
					                'Password': 'izayoi',
 | 
				
			||||||
                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
					                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            'gensokyo.jp': {
 | 
				
			||||||
 | 
					                'Username': 'sakuya',
 | 
				
			||||||
 | 
					                'Password': 'izayoi',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            'https://default.com/v2': {
 | 
					            'https://default.com/v2': {
 | 
				
			||||||
                'Username': 'user',
 | 
					                'Username': 'user',
 | 
				
			||||||
                'Password': 'hunter2',
 | 
					                'Password': 'hunter2',
 | 
				
			||||||
                'ServerAddress': 'https://default.com/v2',
 | 
					                'ServerAddress': 'https://default.com/v2',
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            'default.com': {
 | 
				
			||||||
 | 
					                'Username': 'user',
 | 
				
			||||||
 | 
					                'Password': 'hunter2',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://default.com/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_get_all_credentials_with_auths_entries(self):
 | 
					    def test_get_all_credentials_with_auths_entries(self):
 | 
				
			||||||
| 
						 | 
					@ -591,11 +621,21 @@ class CredstoreTest(unittest.TestCase):
 | 
				
			||||||
                'Password': 'izayoi',
 | 
					                'Password': 'izayoi',
 | 
				
			||||||
                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
					                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            'gensokyo.jp': {
 | 
				
			||||||
 | 
					                'Username': 'sakuya',
 | 
				
			||||||
 | 
					                'Password': 'izayoi',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            'https://default.com/v2': {
 | 
					            'https://default.com/v2': {
 | 
				
			||||||
                'Username': 'user',
 | 
					                'Username': 'user',
 | 
				
			||||||
                'Password': 'hunter2',
 | 
					                'Password': 'hunter2',
 | 
				
			||||||
                'ServerAddress': 'https://default.com/v2',
 | 
					                'ServerAddress': 'https://default.com/v2',
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            'default.com': {
 | 
				
			||||||
 | 
					                'Username': 'user',
 | 
				
			||||||
 | 
					                'Password': 'hunter2',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://default.com/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            'registry1.io': {
 | 
					            'registry1.io': {
 | 
				
			||||||
                'ServerAddress': 'registry1.io',
 | 
					                'ServerAddress': 'registry1.io',
 | 
				
			||||||
                'Username': 'reimu',
 | 
					                'Username': 'reimu',
 | 
				
			||||||
| 
						 | 
					@ -603,6 +643,62 @@ class CredstoreTest(unittest.TestCase):
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_get_all_credentials_with_empty_auths_entry(self):
 | 
				
			||||||
 | 
					        self.authconfig.add_auth('default.com', {})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assert self.authconfig.get_all_credentials() == {
 | 
				
			||||||
 | 
					            'https://gensokyo.jp/v2': {
 | 
				
			||||||
 | 
					                'Username': 'sakuya',
 | 
				
			||||||
 | 
					                'Password': 'izayoi',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            'gensokyo.jp': {
 | 
				
			||||||
 | 
					                'Username': 'sakuya',
 | 
				
			||||||
 | 
					                'Password': 'izayoi',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            'https://default.com/v2': {
 | 
				
			||||||
 | 
					                'Username': 'user',
 | 
				
			||||||
 | 
					                'Password': 'hunter2',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://default.com/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            'default.com': {
 | 
				
			||||||
 | 
					                'Username': 'user',
 | 
				
			||||||
 | 
					                'Password': 'hunter2',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://default.com/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_get_all_credentials_credstore_overrides_auth_entry(self):
 | 
				
			||||||
 | 
					        self.authconfig.add_auth('default.com', {
 | 
				
			||||||
 | 
					            'Username': 'shouldnotsee',
 | 
				
			||||||
 | 
					            'Password': 'thisentry',
 | 
				
			||||||
 | 
					            'ServerAddress': 'https://default.com/v2',
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assert self.authconfig.get_all_credentials() == {
 | 
				
			||||||
 | 
					            'https://gensokyo.jp/v2': {
 | 
				
			||||||
 | 
					                'Username': 'sakuya',
 | 
				
			||||||
 | 
					                'Password': 'izayoi',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            'gensokyo.jp': {
 | 
				
			||||||
 | 
					                'Username': 'sakuya',
 | 
				
			||||||
 | 
					                'Password': 'izayoi',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            'https://default.com/v2': {
 | 
				
			||||||
 | 
					                'Username': 'user',
 | 
				
			||||||
 | 
					                'Password': 'hunter2',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://default.com/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            'default.com': {
 | 
				
			||||||
 | 
					                'Username': 'user',
 | 
				
			||||||
 | 
					                'Password': 'hunter2',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://default.com/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_get_all_credentials_helpers_override_default(self):
 | 
					    def test_get_all_credentials_helpers_override_default(self):
 | 
				
			||||||
        self.authconfig['credHelpers'] = {
 | 
					        self.authconfig['credHelpers'] = {
 | 
				
			||||||
            'https://default.com/v2': 'truesecret',
 | 
					            'https://default.com/v2': 'truesecret',
 | 
				
			||||||
| 
						 | 
					@ -616,11 +712,21 @@ class CredstoreTest(unittest.TestCase):
 | 
				
			||||||
                'Password': 'izayoi',
 | 
					                'Password': 'izayoi',
 | 
				
			||||||
                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
					                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            'gensokyo.jp': {
 | 
				
			||||||
 | 
					                'Username': 'sakuya',
 | 
				
			||||||
 | 
					                'Password': 'izayoi',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            'https://default.com/v2': {
 | 
					            'https://default.com/v2': {
 | 
				
			||||||
                'Username': 'reimu',
 | 
					                'Username': 'reimu',
 | 
				
			||||||
                'Password': 'hakurei',
 | 
					                'Password': 'hakurei',
 | 
				
			||||||
                'ServerAddress': 'https://default.com/v2',
 | 
					                'ServerAddress': 'https://default.com/v2',
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            'default.com': {
 | 
				
			||||||
 | 
					                'Username': 'reimu',
 | 
				
			||||||
 | 
					                'Password': 'hakurei',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://default.com/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_get_all_credentials_3_sources(self):
 | 
					    def test_get_all_credentials_3_sources(self):
 | 
				
			||||||
| 
						 | 
					@ -642,11 +748,21 @@ class CredstoreTest(unittest.TestCase):
 | 
				
			||||||
                'Password': 'izayoi',
 | 
					                'Password': 'izayoi',
 | 
				
			||||||
                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
					                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            'gensokyo.jp': {
 | 
				
			||||||
 | 
					                'Username': 'sakuya',
 | 
				
			||||||
 | 
					                'Password': 'izayoi',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://gensokyo.jp/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            'https://default.com/v2': {
 | 
					            'https://default.com/v2': {
 | 
				
			||||||
                'Username': 'user',
 | 
					                'Username': 'user',
 | 
				
			||||||
                'Password': 'hunter2',
 | 
					                'Password': 'hunter2',
 | 
				
			||||||
                'ServerAddress': 'https://default.com/v2',
 | 
					                'ServerAddress': 'https://default.com/v2',
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            'default.com': {
 | 
				
			||||||
 | 
					                'Username': 'user',
 | 
				
			||||||
 | 
					                'Password': 'hunter2',
 | 
				
			||||||
 | 
					                'ServerAddress': 'https://default.com/v2',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            'registry1.io': {
 | 
					            'registry1.io': {
 | 
				
			||||||
                'ServerAddress': 'registry1.io',
 | 
					                'ServerAddress': 'registry1.io',
 | 
				
			||||||
                'Username': 'reimu',
 | 
					                'Username': 'reimu',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue