summaryrefslogtreecommitdiff
path: root/docker
diff options
context:
space:
mode:
authorSVN-Git Migration <python-modules-team@lists.alioth.debian.org>2015-10-08 11:55:18 -0700
committerSVN-Git Migration <python-modules-team@lists.alioth.debian.org>2015-10-08 11:55:18 -0700
commit8aa3dbb1e6082c40bb1493e773afa08e509393f3 (patch)
tree159e0071a4b50b449325c853975cf17a5e66c185 /docker
parent8249d930db0bed8e32f05ce1a74acef7d74494fa (diff)
Imported Upstream version 0.5.0
Diffstat (limited to 'docker')
-rw-r--r--docker/auth/auth.py18
-rw-r--r--docker/client.py88
-rw-r--r--docker/ssladapter/ssladapter.py20
-rw-r--r--docker/utils/utils.py27
-rw-r--r--docker/version.py2
5 files changed, 125 insertions, 30 deletions
diff --git a/docker/auth/auth.py b/docker/auth/auth.py
index 0bd386d..c13eed4 100644
--- a/docker/auth/auth.py
+++ b/docker/auth/auth.py
@@ -34,17 +34,22 @@ def swap_protocol(url):
return url
-def expand_registry_url(hostname):
+def expand_registry_url(hostname, insecure=False):
if hostname.startswith('http:') or hostname.startswith('https:'):
if '/' not in hostname[9:]:
hostname = hostname + '/v1/'
return hostname
if utils.ping('https://' + hostname + '/v1/_ping'):
return 'https://' + hostname + '/v1/'
- return 'http://' + hostname + '/v1/'
+ elif insecure:
+ return 'http://' + hostname + '/v1/'
+ else:
+ raise errors.DockerException(
+ "HTTPS endpoint unresponsive and insecure mode isn't enabled."
+ )
-def resolve_repository_name(repo_name):
+def resolve_repository_name(repo_name, insecure=False):
if '://' in repo_name:
raise errors.InvalidRepository(
'Repository name cannot contain a scheme ({0})'.format(repo_name))
@@ -56,11 +61,12 @@ def resolve_repository_name(repo_name):
raise errors.InvalidRepository(
'Invalid repository name ({0})'.format(repo_name))
- if 'index.docker.io' in parts[0]:
+ if 'index.docker.io' in parts[0] or 'registry.hub.docker.com' in parts[0]:
raise errors.InvalidRepository(
- 'Invalid repository name, try "{0}" instead'.format(parts[1]))
+ 'Invalid repository name, try "{0}" instead'.format(parts[1])
+ )
- return expand_registry_url(parts[0]), parts[1]
+ return expand_registry_url(parts[0], insecure), parts[1]
def resolve_authconfig(authconfig, registry=None):
diff --git a/docker/client.py b/docker/client.py
index 0a12b66..49e85dd 100644
--- a/docker/client.py
+++ b/docker/client.py
@@ -13,6 +13,7 @@
# limitations under the License.
import json
+import os
import re
import shlex
import struct
@@ -110,6 +111,41 @@ class Client(requests.Session):
'{0}={1}'.format(k, v) for k, v in environment.items()
]
+ if isinstance(mem_limit, six.string_types):
+ if len(mem_limit) == 0:
+ mem_limit = 0
+ else:
+ units = {'b': 1,
+ 'k': 1024,
+ 'm': 1024 * 1024,
+ 'g': 1024 * 1024 * 1024}
+ suffix = mem_limit[-1].lower()
+
+ # Check if the variable is a string representation of an int
+ # without a units part. Assuming that the units are bytes.
+ if suffix.isdigit():
+ digits_part = mem_limit
+ suffix = 'b'
+ else:
+ digits_part = mem_limit[:-1]
+
+ if suffix in units.keys() or suffix.isdigit():
+ try:
+ digits = int(digits_part)
+ except ValueError:
+ message = ('Failed converting the string value for'
+ ' mem_limit ({0}) to a number.')
+ formatted_message = message.format(digits_part)
+ raise errors.DockerException(formatted_message)
+
+ mem_limit = digits * units[suffix]
+ else:
+ message = ('The specified value for mem_limit parameter'
+ ' ({0}) should specify the units. The postfix'
+ ' should be one of the `b` `k` `m` `g`'
+ ' characters')
+ raise errors.DockerException(message.format(mem_limit))
+
if isinstance(ports, list):
exposed_ports = {}
for port_definition in ports:
@@ -122,6 +158,9 @@ class Client(requests.Session):
exposed_ports['{0}/{1}'.format(port, proto)] = {}
ports = exposed_ports
+ if isinstance(volumes, six.string_types):
+ volumes = [volumes, ]
+
if isinstance(volumes, list):
volumes_dict = {}
for vol in volumes:
@@ -356,7 +395,12 @@ class Client(requests.Session):
'git://', 'github.com/')):
remote = path
else:
- context = utils.tar(path)
+ dockerignore = os.path.join(path, '.dockerignore')
+ exclude = None
+ if os.path.exists(dockerignore):
+ with open(dockerignore, 'r') as f:
+ exclude = list(filter(bool, f.read().split('\n')))
+ context = utils.tar(path, exclude=exclude)
if utils.compare_version('1.8', self._version) >= 0:
stream = True
@@ -459,6 +503,9 @@ class Client(requests.Session):
cpu_shares=None, working_dir=None, domainname=None,
memswap_limit=0):
+ if isinstance(volumes, six.string_types):
+ volumes = [volumes, ]
+
config = self._container_config(
image, command, hostname, user, detach, stdin_open, tty, mem_limit,
ports, environment, dns, volumes, volumes_from, network_disabled,
@@ -666,10 +713,13 @@ class Client(requests.Session):
return h_ports
- def pull(self, repository, tag=None, stream=False):
+ def pull(self, repository, tag=None, stream=False,
+ insecure_registry=False):
if not tag:
repository, tag = utils.parse_repository_tag(repository)
- registry, repo_name = auth.resolve_repository_name(repository)
+ registry, repo_name = auth.resolve_repository_name(
+ repository, insecure=insecure_registry
+ )
if repo_name.count(":") == 1:
repository, tag = repository.rsplit(":", 1)
@@ -700,9 +750,17 @@ class Client(requests.Session):
else:
return self._result(response)
- def push(self, repository, stream=False):
- registry, repo_name = auth.resolve_repository_name(repository)
+ def push(self, repository, tag=None, stream=False,
+ insecure_registry=False):
+ if not tag:
+ repository, tag = utils.parse_repository_tag(repository)
+ registry, repo_name = auth.resolve_repository_name(
+ repository, insecure=insecure_registry
+ )
u = self._url("/images/{0}/push".format(repository))
+ params = {
+ 'tag': tag
+ }
headers = {}
if utils.compare_version('1.5', self._version) >= 0:
@@ -718,9 +776,10 @@ class Client(requests.Session):
if authcfg:
headers['X-Registry-Auth'] = auth.encode_header(authcfg)
- response = self._post_json(u, None, headers=headers, stream=stream)
+ response = self._post_json(u, None, headers=headers,
+ stream=stream, params=params)
else:
- response = self._post_json(u, None, stream=stream)
+ response = self._post_json(u, None, stream=stream, params=params)
return stream and self._stream_helper(response) \
or self._result(response)
@@ -753,7 +812,8 @@ class Client(requests.Session):
def start(self, container, binds=None, port_bindings=None, lxc_conf=None,
publish_all_ports=False, links=None, privileged=False,
- dns=None, dns_search=None, volumes_from=None, network_mode=None):
+ dns=None, dns_search=None, volumes_from=None, network_mode=None,
+ restart_policy=None, cap_add=None, cap_drop=None):
if isinstance(container, dict):
container = container.get('Id')
@@ -806,13 +866,21 @@ class Client(requests.Session):
if volumes_from is not None:
warnings.warn(warning_message.format('volumes_from'),
DeprecationWarning)
-
if dns_search:
start_config['DnsSearch'] = dns_search
if network_mode:
start_config['NetworkMode'] = network_mode
+ if restart_policy:
+ start_config['RestartPolicy'] = restart_policy
+
+ if cap_add:
+ start_config['CapAdd'] = cap_add
+
+ if cap_drop:
+ start_config['CapDrop'] = cap_drop
+
url = self._url("/containers/{0}/start".format(container))
res = self._post_json(url, data=start_config)
self._raise_for_status(res)
@@ -832,7 +900,7 @@ class Client(requests.Session):
params = {'t': timeout}
url = self._url("/containers/{0}/stop".format(container))
res = self._post(url, params=params,
- timeout=max(timeout, self._timeout))
+ timeout=(timeout + self._timeout))
self._raise_for_status(res)
def tag(self, image, repository, tag=None, force=False):
diff --git a/docker/ssladapter/ssladapter.py b/docker/ssladapter/ssladapter.py
index 99dc36a..a4c11de 100644
--- a/docker/ssladapter/ssladapter.py
+++ b/docker/ssladapter/ssladapter.py
@@ -21,13 +21,13 @@ class SSLAdapter(HTTPAdapter):
def init_poolmanager(self, connections, maxsize, block=False):
urllib_ver = urllib3.__version__.split('-')[0]
- if urllib3 and urllib_ver != 'dev' and \
- StrictVersion(urllib_ver) <= StrictVersion('1.5'):
- self.poolmanager = PoolManager(num_pools=connections,
- maxsize=maxsize,
- block=block)
- else:
- self.poolmanager = PoolManager(num_pools=connections,
- maxsize=maxsize,
- block=block,
- ssl_version=self.ssl_version)
+ kwargs = {
+ 'num_pools': connections,
+ 'maxsize': maxsize,
+ 'block': block
+ }
+ if urllib3 and urllib_ver == 'dev' and \
+ StrictVersion(urllib_ver) > StrictVersion('1.5'):
+ kwargs['ssl_version'] = self.ssl_version
+
+ self.poolmanager = PoolManager(**kwargs)
diff --git a/docker/utils/utils.py b/docker/utils/utils.py
index f741ee2..fb05a1e 100644
--- a/docker/utils/utils.py
+++ b/docker/utils/utils.py
@@ -13,9 +13,11 @@
# limitations under the License.
import io
+import os
import tarfile
import tempfile
from distutils.version import StrictVersion
+from fnmatch import fnmatch
import requests
import six
@@ -47,10 +49,29 @@ def mkbuildcontext(dockerfile):
return f
-def tar(path):
+def fnmatch_any(relpath, patterns):
+ return any([fnmatch(relpath, pattern) for pattern in patterns])
+
+
+def tar(path, exclude=None):
f = tempfile.NamedTemporaryFile()
t = tarfile.open(mode='w', fileobj=f)
- t.add(path, arcname='.')
+ for dirpath, dirnames, filenames in os.walk(path):
+ relpath = os.path.relpath(dirpath, path)
+ if relpath == '.':
+ relpath = ''
+ if exclude is None:
+ fnames = filenames
+ else:
+ dirnames[:] = [d for d in dirnames
+ if not fnmatch_any(os.path.join(relpath, d),
+ exclude)]
+ fnames = [name for name in filenames
+ if not fnmatch_any(os.path.join(relpath, name),
+ exclude)]
+ for name in fnames:
+ arcname = os.path.join(relpath, name)
+ t.add(os.path.join(path, arcname), arcname=arcname)
t.close()
f.seek(0)
return f
@@ -80,7 +101,7 @@ def compare_version(v1, v2):
def ping(url):
try:
- res = requests.get(url)
+ res = requests.get(url, timeout=3)
except Exception:
return False
else:
diff --git a/docker/version.py b/docker/version.py
index 5140fa1..819a300 100644
--- a/docker/version.py
+++ b/docker/version.py
@@ -1 +1 @@
-version = "0.4.0"
+version = "0.5.0"