summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoffrey F <joffrey@docker.com>2015-02-11 14:02:21 -0800
committerJoffrey F <joffrey@docker.com>2015-02-11 14:02:21 -0800
commite2233fcee11e5d74b1849e502c78cc2eca841a7e (patch)
tree5b128569fa447cc7c928db0583ca3a02f304ee68
parentc5f4c7e7d2b8cd00b2c4505c2f4be940c373d187 (diff)
downloaddocker-py-e2233fcee11e5d74b1849e502c78cc2eca841a7e.tar.gz
* Moved _container_config to utils.create_container_configmemoryswap
* memswap_limit can now be provided as a string, similar to mem_limit
-rw-r--r--docker/client.py138
-rw-r--r--docker/utils/__init__.py3
-rw-r--r--docker/utils/utils.py140
3 files changed, 147 insertions, 134 deletions
diff --git a/docker/client.py b/docker/client.py
index 64ce54e..c7abd87 100644
--- a/docker/client.py
+++ b/docker/client.py
@@ -105,134 +105,6 @@ class Client(requests.Session):
return response.content
return response.text
- def _container_config(self, image, command, hostname=None, user=None,
- detach=False, stdin_open=False, tty=False,
- mem_limit=0, ports=None, environment=None, dns=None,
- volumes=None, volumes_from=None,
- network_disabled=False, entrypoint=None,
- cpu_shares=None, working_dir=None,
- domainname=None, memswap_limit=0, cpuset=None,
- host_config=None, mac_address=None):
- if isinstance(command, six.string_types):
- command = shlex.split(str(command))
- if isinstance(environment, dict):
- environment = [
- six.text_type('{0}={1}').format(k, v)
- for k, v in six.iteritems(environment)
- ]
-
- 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:
- port = port_definition
- proto = 'tcp'
- if isinstance(port_definition, tuple):
- if len(port_definition) == 2:
- proto = port_definition[1]
- port = port_definition[0]
- 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:
- volumes_dict[vol] = {}
- volumes = volumes_dict
-
- if volumes_from:
- if not isinstance(volumes_from, six.string_types):
- volumes_from = ','.join(volumes_from)
- else:
- # Force None, an empty list or dict causes client.start to fail
- volumes_from = None
-
- attach_stdin = False
- attach_stdout = False
- attach_stderr = False
- stdin_once = False
-
- if not detach:
- attach_stdout = True
- attach_stderr = True
-
- if stdin_open:
- attach_stdin = True
- stdin_once = True
-
- if utils.compare_version('1.10', self._version) >= 0:
- message = ('{0!r} parameter has no effect on create_container().'
- ' It has been moved to start()')
- if dns is not None:
- raise errors.DockerException(message.format('dns'))
- if volumes_from is not None:
- raise errors.DockerException(message.format('volumes_from'))
-
- return {
- 'Hostname': hostname,
- 'Domainname': domainname,
- 'ExposedPorts': ports,
- 'User': user,
- 'Tty': tty,
- 'OpenStdin': stdin_open,
- 'StdinOnce': stdin_once,
- 'Memory': mem_limit,
- 'AttachStdin': attach_stdin,
- 'AttachStdout': attach_stdout,
- 'AttachStderr': attach_stderr,
- 'Env': environment,
- 'Cmd': command,
- 'Dns': dns,
- 'Image': image,
- 'Volumes': volumes,
- 'VolumesFrom': volumes_from,
- 'NetworkDisabled': network_disabled,
- 'Entrypoint': entrypoint,
- 'CpuShares': cpu_shares,
- 'Cpuset': cpuset,
- 'WorkingDir': working_dir,
- 'MemorySwap': memswap_limit,
- 'HostConfig': host_config,
- 'MacAddress': mac_address
- }
-
def _post_json(self, url, data, **kwargs):
# Go <1.1 can't unserialize null to a string
# so we do this disgusting thing here.
@@ -547,11 +419,11 @@ class Client(requests.Session):
'host_config is not supported in API < 1.15'
)
- config = self._container_config(
- image, command, hostname, user, detach, stdin_open, tty, mem_limit,
- ports, environment, dns, volumes, volumes_from, network_disabled,
- entrypoint, cpu_shares, working_dir, domainname, memswap_limit,
- cpuset, host_config, mac_address
+ config = utils.create_container_config(
+ self._version, image, command, hostname, user, detach, stdin_open,
+ tty, mem_limit, ports, environment, dns, volumes, volumes_from,
+ network_disabled, entrypoint, cpu_shares, working_dir, domainname,
+ memswap_limit, cpuset, host_config, mac_address
)
return self.create_container_from_config(config, name)
diff --git a/docker/utils/__init__.py b/docker/utils/__init__.py
index af6c6aa..0731362 100644
--- a/docker/utils/__init__.py
+++ b/docker/utils/__init__.py
@@ -1,5 +1,6 @@
from .utils import (
compare_version, convert_port_bindings, convert_volume_binds,
mkbuildcontext, ping, tar, parse_repository_tag, parse_host,
- kwargs_from_env, convert_filters, create_host_config
+ kwargs_from_env, convert_filters, create_host_config,
+ create_container_config, parse_bytes
) # flake8: noqa
diff --git a/docker/utils/utils.py b/docker/utils/utils.py
index 36b3981..3e244a8 100644
--- a/docker/utils/utils.py
+++ b/docker/utils/utils.py
@@ -16,6 +16,7 @@ import io
import os
import os.path
import json
+import shlex
import tarfile
import tempfile
from distutils.version import StrictVersion
@@ -31,6 +32,12 @@ from .. import tls
DEFAULT_HTTP_HOST = "127.0.0.1"
DEFAULT_UNIX_SOCKET = "http+unix://var/run/docker.sock"
+BYTE_UNITS = {
+ 'b': 1,
+ 'k': 1024,
+ 'm': 1024 * 1024,
+ 'g': 1024 * 1024 * 1024
+}
def mkbuildcontext(dockerfile):
@@ -304,6 +311,41 @@ def datetime_to_timestamp(dt=datetime.now()):
return delta.seconds + delta.days * 24 * 3600
+def parse_bytes(s):
+ if len(s) == 0:
+ s = 0
+ else:
+ units = BYTE_UNITS
+ suffix = s[-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 = s
+ suffix = 'b'
+ else:
+ digits_part = s[:-1]
+
+ if suffix in units.keys() or suffix.isdigit():
+ try:
+ digits = int(digits_part)
+ except ValueError:
+ message = ('Failed converting the string value for'
+ 'memory ({0}) to a number.')
+ formatted_message = message.format(digits_part)
+ raise errors.DockerException(formatted_message)
+
+ s = digits * units[suffix]
+ else:
+ message = ('The specified value for memory'
+ ' ({0}) should specify the units. The postfix'
+ ' should be one of the `b` `k` `m` `g`'
+ ' characters')
+ raise errors.DockerException(message.format(s))
+
+ return s
+
+
def create_host_config(
binds=None, port_bindings=None, lxc_conf=None,
publish_all_ports=False, links=None, privileged=False,
@@ -392,3 +434,101 @@ def create_host_config(
host_config['LxcConf'] = lxc_conf
return host_config
+
+
+def create_container_config(
+ version, image, command, hostname=None, user=None, detach=False,
+ stdin_open=False, tty=False, mem_limit=0, ports=None, environment=None,
+ dns=None, volumes=None, volumes_from=None, network_disabled=False,
+ entrypoint=None, cpu_shares=None, working_dir=None, domainname=None,
+ memswap_limit=0, cpuset=None, host_config=None, mac_address=None
+):
+ if isinstance(command, six.string_types):
+ command = shlex.split(str(command))
+ if isinstance(environment, dict):
+ environment = [
+ six.text_type('{0}={1}').format(k, v)
+ for k, v in six.iteritems(environment)
+ ]
+
+ if isinstance(mem_limit, six.string_types):
+ mem_limit = parse_bytes(mem_limit)
+ if isinstance(memswap_limit, six.string_types):
+ memswap_limit = parse_bytes(memswap_limit)
+
+ if isinstance(ports, list):
+ exposed_ports = {}
+ for port_definition in ports:
+ port = port_definition
+ proto = 'tcp'
+ if isinstance(port_definition, tuple):
+ if len(port_definition) == 2:
+ proto = port_definition[1]
+ port = port_definition[0]
+ 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:
+ volumes_dict[vol] = {}
+ volumes = volumes_dict
+
+ if volumes_from:
+ if not isinstance(volumes_from, six.string_types):
+ volumes_from = ','.join(volumes_from)
+ else:
+ # Force None, an empty list or dict causes client.start to fail
+ volumes_from = None
+
+ attach_stdin = False
+ attach_stdout = False
+ attach_stderr = False
+ stdin_once = False
+
+ if not detach:
+ attach_stdout = True
+ attach_stderr = True
+
+ if stdin_open:
+ attach_stdin = True
+ stdin_once = True
+
+ if compare_version('1.10', version) >= 0:
+ message = ('{0!r} parameter has no effect on create_container().'
+ ' It has been moved to start()')
+ if dns is not None:
+ raise errors.DockerException(message.format('dns'))
+ if volumes_from is not None:
+ raise errors.DockerException(message.format('volumes_from'))
+
+ return {
+ 'Hostname': hostname,
+ 'Domainname': domainname,
+ 'ExposedPorts': ports,
+ 'User': user,
+ 'Tty': tty,
+ 'OpenStdin': stdin_open,
+ 'StdinOnce': stdin_once,
+ 'Memory': mem_limit,
+ 'AttachStdin': attach_stdin,
+ 'AttachStdout': attach_stdout,
+ 'AttachStderr': attach_stderr,
+ 'Env': environment,
+ 'Cmd': command,
+ 'Dns': dns,
+ 'Image': image,
+ 'Volumes': volumes,
+ 'VolumesFrom': volumes_from,
+ 'NetworkDisabled': network_disabled,
+ 'Entrypoint': entrypoint,
+ 'CpuShares': cpu_shares,
+ 'Cpuset': cpuset,
+ 'WorkingDir': working_dir,
+ 'MemorySwap': memswap_limit,
+ 'HostConfig': host_config,
+ 'MacAddress': mac_address
+ }