Skip to content

Commit

Permalink
Merge pull request #2187 from docker/3.6.0-release
Browse files Browse the repository at this point in the history
3.6.0 release
  • Loading branch information
shin- authored Nov 28, 2018
2 parents 7cc0a1b + 24ed2f3 commit d74bfa6
Show file tree
Hide file tree
Showing 36 changed files with 643 additions and 186 deletions.
9 changes: 8 additions & 1 deletion docker/api/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,14 @@ def process_dockerfile(dockerfile, path):
abs_dockerfile = dockerfile
if not os.path.isabs(dockerfile):
abs_dockerfile = os.path.join(path, dockerfile)

if constants.IS_WINDOWS_PLATFORM and path.startswith(
constants.WINDOWS_LONGPATH_PREFIX):
abs_dockerfile = '{}{}'.format(
constants.WINDOWS_LONGPATH_PREFIX,
os.path.normpath(
abs_dockerfile[len(constants.WINDOWS_LONGPATH_PREFIX):]
)
)
if (os.path.splitdrive(path)[0] != os.path.splitdrive(abs_dockerfile)[0] or
os.path.relpath(abs_dockerfile, path).startswith('..')):
# Dockerfile not in context - read data to insert into tar later
Expand Down
19 changes: 19 additions & 0 deletions docker/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@
except ImportError:
pass

try:
from ..transport import SSHAdapter
except ImportError:
pass


class APIClient(
requests.Session,
Expand Down Expand Up @@ -141,6 +146,18 @@ def __init__(self, base_url=None, version=None,
)
self.mount('http+docker://', self._custom_adapter)
self.base_url = 'http+docker://localnpipe'
elif base_url.startswith('ssh://'):
try:
self._custom_adapter = SSHAdapter(
base_url, timeout, pool_connections=num_pools
)
except NameError:
raise DockerException(
'Install paramiko package to enable ssh:// support'
)
self.mount('http+docker://ssh', self._custom_adapter)
self._unmount('http://', 'https://')
self.base_url = 'http+docker://ssh'
else:
# Use SSLAdapter for the ability to specify SSL version
if isinstance(tls, TLSConfig):
Expand Down Expand Up @@ -279,6 +296,8 @@ def _get_raw_response_socket(self, response):
self._raise_for_status(response)
if self.base_url == "http+docker://localnpipe":
sock = response.raw._fp.fp.raw.sock
elif self.base_url.startswith('http+docker://ssh'):
sock = response.raw._fp.fp.channel
elif six.PY3:
sock = response.raw._fp.fp.raw
if self.base_url.startswith("https://"):
Expand Down
46 changes: 30 additions & 16 deletions docker/api/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,16 +473,12 @@ def create_host_config(self, *args, **kwargs):
signals and reaps processes
init_path (str): Path to the docker-init binary
ipc_mode (str): Set the IPC mode for the container.
isolation (str): Isolation technology to use. Default: `None`.
links (dict or list of tuples): Either a dictionary mapping name
to alias or as a list of ``(name, alias)`` tuples.
log_config (dict): Logging configuration, as a dictionary with
keys:
- ``type`` The logging driver name.
- ``config`` A dictionary of configuration for the logging
driver.
isolation (str): Isolation technology to use. Default: ``None``.
links (dict): Mapping of links using the
``{'container': 'alias'}`` format. The alias is optional.
Containers declared in this dict will be linked to the new
container using the provided alias. Default: ``None``.
log_config (LogConfig): Logging configuration
lxc_conf (dict): LXC config.
mem_limit (float or str): Memory limit. Accepts float values
(which represent the memory limit of the created container in
Expand Down Expand Up @@ -543,7 +539,7 @@ def create_host_config(self, *args, **kwargs):
}
ulimits (:py:class:`list`): Ulimits to set inside the container,
as a list of dicts.
as a list of :py:class:`docker.types.Ulimit` instances.
userns_mode (str): Sets the user namespace mode for the container
when user namespace remapping option is enabled. Supported
values are: ``host``
Expand Down Expand Up @@ -611,9 +607,10 @@ def create_endpoint_config(self, *args, **kwargs):
aliases (:py:class:`list`): A list of aliases for this endpoint.
Names in that list can be used within the network to reach the
container. Defaults to ``None``.
links (:py:class:`list`): A list of links for this endpoint.
Containers declared in this list will be linked to this
container. Defaults to ``None``.
links (dict): Mapping of links for this endpoint using the
``{'container': 'alias'}`` format. The alias is optional.
Containers declared in this dict will be linked to this
container using the provided alias. Defaults to ``None``.
ipv4_address (str): The IP address of this container on the
network, using the IPv4 protocol. Defaults to ``None``.
ipv6_address (str): The IP address of this container on the
Expand All @@ -628,7 +625,7 @@ def create_endpoint_config(self, *args, **kwargs):
>>> endpoint_config = client.create_endpoint_config(
aliases=['web', 'app'],
links=['app_db'],
links={'app_db': 'db', 'another': None},
ipv4_address='132.65.0.123'
)
Expand Down Expand Up @@ -697,6 +694,18 @@ def get_archive(self, container, path, chunk_size=DEFAULT_DATA_CHUNK_SIZE):
Raises:
:py:class:`docker.errors.APIError`
If the server returns an error.
Example:
>>> c = docker.APIClient()
>>> f = open('./sh_bin.tar', 'wb')
>>> bits, stat = c.get_archive(container, '/bin/sh')
>>> print(stat)
{'name': 'sh', 'size': 1075464, 'mode': 493,
'mtime': '2018-10-01T15:37:48-07:00', 'linkTarget': ''}
>>> for chunk in bits:
... f.write(chunk)
>>> f.close()
"""
params = {
'path': path
Expand Down Expand Up @@ -1074,7 +1083,8 @@ def stats(self, container, decode=None, stream=True):
Args:
container (str): The container to stream statistics from
decode (bool): If set to true, stream will be decoded into dicts
on the fly. False by default.
on the fly. Only applicable if ``stream`` is True.
False by default.
stream (bool): If set to false, only the current stats will be
returned instead of a stream. True by default.
Expand All @@ -1088,6 +1098,10 @@ def stats(self, container, decode=None, stream=True):
return self._stream_helper(self._get(url, stream=True),
decode=decode)
else:
if decode:
raise errors.InvalidArgument(
"decode is only available in conjuction with stream=True"
)
return self._result(self._get(url, params={'stream': False}),
json=True)

Expand Down
5 changes: 3 additions & 2 deletions docker/api/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def get_image(self, image, chunk_size=DEFAULT_DATA_CHUNK_SIZE):
Example:
>>> image = cli.get_image("busybox:latest")
>>> f = open('/tmp/busybox-latest.tar', 'w')
>>> f = open('/tmp/busybox-latest.tar', 'wb')
>>> for chunk in image:
>>> f.write(chunk)
>>> f.close()
Expand Down Expand Up @@ -334,7 +334,8 @@ def pull(self, repository, tag=None, stream=False, auth_config=None,
Args:
repository (str): The repository to pull
tag (str): The tag to pull
stream (bool): Stream the output as a generator
stream (bool): Stream the output as a generator. Make sure to
consume the generator, otherwise pull might get cancelled.
auth_config (dict): Override the credentials that
:py:meth:`~docker.api.daemon.DaemonApiMixin.login` has set for
this request. ``auth_config`` should contain the ``username``
Expand Down
3 changes: 2 additions & 1 deletion docker/api/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ def inspect_service(self, service, insert_defaults=None):
into the service inspect output.
Returns:
``True`` if successful.
(dict): A dictionary of the server-side representation of the
service, including all relevant properties.
Raises:
:py:class:`docker.errors.APIError`
Expand Down
2 changes: 1 addition & 1 deletion docker/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ def load_config(config_path=None, config_dict=None):
return res

log.debug(
"Couldn't find auth-related section ; attempting to interpret"
"Couldn't find auth-related section ; attempting to interpret "
"as auth-only file"
)
return {'auths': parse_auth(config_dict)}
Expand Down
1 change: 1 addition & 0 deletions docker/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'is deprecated and non-functional. Please remove it.'

IS_WINDOWS_PLATFORM = (sys.platform == 'win32')
WINDOWS_LONGPATH_PREFIX = '\\\\?\\'

DEFAULT_USER_AGENT = "docker-sdk-python/{0}".format(version)
DEFAULT_NUM_POOLS = 25
Expand Down
39 changes: 26 additions & 13 deletions docker/models/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@


class Container(Model):

""" Local representation of a container object. Detailed configuration may
be accessed through the :py:attr:`attrs` attribute. Note that local
attributes are cached; users may call :py:meth:`reload` to
query the Docker daemon for the current properties, causing
:py:attr:`attrs` to be refreshed.
"""
@property
def name(self):
"""
Expand Down Expand Up @@ -228,6 +233,17 @@ def get_archive(self, path, chunk_size=DEFAULT_DATA_CHUNK_SIZE):
Raises:
:py:class:`docker.errors.APIError`
If the server returns an error.
Example:
>>> f = open('./sh_bin.tar', 'wb')
>>> bits, stat = container.get_archive('/bin/sh')
>>> print(stat)
{'name': 'sh', 'size': 1075464, 'mode': 493,
'mtime': '2018-10-01T15:37:48-07:00', 'linkTarget': ''}
>>> for chunk in bits:
... f.write(chunk)
>>> f.close()
"""
return self.client.api.get_archive(self.id, path, chunk_size)

Expand Down Expand Up @@ -380,7 +396,8 @@ def stats(self, **kwargs):
Args:
decode (bool): If set to true, stream will be decoded into dicts
on the fly. False by default.
on the fly. Only applicable if ``stream`` is True.
False by default.
stream (bool): If set to false, only the current stats will be
returned instead of a stream. True by default.
Expand Down Expand Up @@ -574,15 +591,11 @@ def run(self, image, command=None, stdout=True, stderr=False,
``{"label1": "value1", "label2": "value2"}``) or a list of
names of labels to set with empty values (e.g.
``["label1", "label2"]``)
links (dict or list of tuples): Either a dictionary mapping name
to alias or as a list of ``(name, alias)`` tuples.
log_config (dict): Logging configuration, as a dictionary with
keys:
- ``type`` The logging driver name.
- ``config`` A dictionary of configuration for the logging
driver.
links (dict): Mapping of links using the
``{'container': 'alias'}`` format. The alias is optional.
Containers declared in this dict will be linked to the new
container using the provided alias. Default: ``None``.
log_config (LogConfig): Logging configuration.
mac_address (str): MAC address to assign to the container.
mem_limit (int or str): Memory limit. Accepts float values
(which represent the memory limit of the created container in
Expand Down Expand Up @@ -691,8 +704,8 @@ def run(self, image, command=None, stdout=True, stderr=False,
}
tty (bool): Allocate a pseudo-TTY.
ulimits (:py:class:`list`): Ulimits to set inside the container, as
a list of dicts.
ulimits (:py:class:`list`): Ulimits to set inside the container,
as a list of :py:class:`docker.types.Ulimit` instances.
user (str or int): Username or UID to run commands as inside the
container.
userns_mode (str): Sets the user namespace mode for the container
Expand Down
39 changes: 35 additions & 4 deletions docker/models/images.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import itertools
import re
import warnings

import six

Expand Down Expand Up @@ -59,14 +60,20 @@ def history(self):
"""
return self.client.api.history(self.id)

def save(self, chunk_size=DEFAULT_DATA_CHUNK_SIZE):
def save(self, chunk_size=DEFAULT_DATA_CHUNK_SIZE, named=False):
"""
Get a tarball of an image. Similar to the ``docker save`` command.
Args:
chunk_size (int): The generator will return up to that much data
per iteration, but may return less. If ``None``, data will be
streamed as it is received. Default: 2 MB
named (str or bool): If ``False`` (default), the tarball will not
retain repository and tag information for this image. If set
to ``True``, the first tag in the :py:attr:`~tags` list will
be used to identify the image. Alternatively, any element of
the :py:attr:`~tags` list can be used as an argument to use
that specific tag as the saved identifier.
Returns:
(generator): A stream of raw archive data.
Expand All @@ -78,12 +85,22 @@ def save(self, chunk_size=DEFAULT_DATA_CHUNK_SIZE):
Example:
>>> image = cli.get_image("busybox:latest")
>>> f = open('/tmp/busybox-latest.tar', 'w')
>>> f = open('/tmp/busybox-latest.tar', 'wb')
>>> for chunk in image:
>>> f.write(chunk)
>>> f.close()
"""
return self.client.api.get_image(self.id, chunk_size)
img = self.id
if named:
img = self.tags[0] if self.tags else img
if isinstance(named, six.string_types):
if named not in self.tags:
raise InvalidArgument(
"{} is not a valid tag for this image".format(named)
)
img = named

return self.client.api.get_image(img, chunk_size)

def tag(self, repository, tag=None, **kwargs):
"""
Expand Down Expand Up @@ -409,7 +426,21 @@ def pull(self, repository, tag=None, **kwargs):
if not tag:
repository, tag = parse_repository_tag(repository)

self.client.api.pull(repository, tag=tag, **kwargs)
if 'stream' in kwargs:
warnings.warn(
'`stream` is not a valid parameter for this method'
' and will be overridden'
)
del kwargs['stream']

pull_log = self.client.api.pull(
repository, tag=tag, stream=True, **kwargs
)
for _ in pull_log:
# We don't do anything with the logs, but we need
# to keep the connection alive and wait for the image
# to be pulled.
pass
if tag:
return self.get('{0}{2}{1}'.format(
repository, tag, '@' if tag.startswith('sha256:') else ':'
Expand Down
5 changes: 5 additions & 0 deletions docker/transport/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@
from .npipesocket import NpipeSocket
except ImportError:
pass

try:
from .sshconn import SSHAdapter
except ImportError:
pass
4 changes: 0 additions & 4 deletions docker/transport/npipesocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,6 @@ def detach(self):
def dup(self):
return NpipeSocket(self._handle)

@check_closed
def fileno(self):
return int(self._handle)

def getpeername(self):
return self._address

Expand Down
Loading

0 comments on commit d74bfa6

Please sign in to comment.