mirror of https://github.com/docker/docker-py.git
* Moved _container_config to utils.create_container_config
* memswap_limit can now be provided as a string, similar to mem_limit
This commit is contained in:
parent
c5f4c7e7d2
commit
e2233fcee1
138
docker/client.py
138
docker/client.py
|
@ -105,134 +105,6 @@ class Client(requests.Session):
|
||||||
return response.content
|
return response.content
|
||||||
return response.text
|
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):
|
def _post_json(self, url, data, **kwargs):
|
||||||
# Go <1.1 can't unserialize null to a string
|
# Go <1.1 can't unserialize null to a string
|
||||||
# so we do this disgusting thing here.
|
# so we do this disgusting thing here.
|
||||||
|
@ -547,11 +419,11 @@ class Client(requests.Session):
|
||||||
'host_config is not supported in API < 1.15'
|
'host_config is not supported in API < 1.15'
|
||||||
)
|
)
|
||||||
|
|
||||||
config = self._container_config(
|
config = utils.create_container_config(
|
||||||
image, command, hostname, user, detach, stdin_open, tty, mem_limit,
|
self._version, image, command, hostname, user, detach, stdin_open,
|
||||||
ports, environment, dns, volumes, volumes_from, network_disabled,
|
tty, mem_limit, ports, environment, dns, volumes, volumes_from,
|
||||||
entrypoint, cpu_shares, working_dir, domainname, memswap_limit,
|
network_disabled, entrypoint, cpu_shares, working_dir, domainname,
|
||||||
cpuset, host_config, mac_address
|
memswap_limit, cpuset, host_config, mac_address
|
||||||
)
|
)
|
||||||
return self.create_container_from_config(config, name)
|
return self.create_container_from_config(config, name)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from .utils import (
|
from .utils import (
|
||||||
compare_version, convert_port_bindings, convert_volume_binds,
|
compare_version, convert_port_bindings, convert_volume_binds,
|
||||||
mkbuildcontext, ping, tar, parse_repository_tag, parse_host,
|
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
|
) # flake8: noqa
|
||||||
|
|
|
@ -16,6 +16,7 @@ import io
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import json
|
import json
|
||||||
|
import shlex
|
||||||
import tarfile
|
import tarfile
|
||||||
import tempfile
|
import tempfile
|
||||||
from distutils.version import StrictVersion
|
from distutils.version import StrictVersion
|
||||||
|
@ -31,6 +32,12 @@ from .. import tls
|
||||||
|
|
||||||
DEFAULT_HTTP_HOST = "127.0.0.1"
|
DEFAULT_HTTP_HOST = "127.0.0.1"
|
||||||
DEFAULT_UNIX_SOCKET = "http+unix://var/run/docker.sock"
|
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):
|
def mkbuildcontext(dockerfile):
|
||||||
|
@ -304,6 +311,41 @@ def datetime_to_timestamp(dt=datetime.now()):
|
||||||
return delta.seconds + delta.days * 24 * 3600
|
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(
|
def create_host_config(
|
||||||
binds=None, port_bindings=None, lxc_conf=None,
|
binds=None, port_bindings=None, lxc_conf=None,
|
||||||
publish_all_ports=False, links=None, privileged=False,
|
publish_all_ports=False, links=None, privileged=False,
|
||||||
|
@ -392,3 +434,101 @@ def create_host_config(
|
||||||
host_config['LxcConf'] = lxc_conf
|
host_config['LxcConf'] = lxc_conf
|
||||||
|
|
||||||
return host_config
|
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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue