Skip to content

Commit 601d6be

Browse files
committed
Add support for new ContainerSpec parameters
Signed-off-by: Joffrey F <[email protected]>
1 parent 10ea65f commit 601d6be

File tree

10 files changed

+265
-50
lines changed

10 files changed

+265
-50
lines changed

docker/api/build.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,9 @@ def build(self, path=None, tag=None, quiet=False, fileobj=None,
237237
'extra_hosts was only introduced in API version 1.27'
238238
)
239239

240-
encoded_extra_hosts = [
241-
'{}:{}'.format(k, v) for k, v in extra_hosts.items()
242-
]
243-
params.update({'extrahosts': encoded_extra_hosts})
240+
if isinstance(extra_hosts, dict):
241+
extra_hosts = utils.format_extra_hosts(extra_hosts)
242+
params.update({'extrahosts': extra_hosts})
244243

245244
if context is not None:
246245
headers = {'Content-Type': 'application/tar'}

docker/api/service.py

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,45 +4,62 @@
44

55

66
def _check_api_features(version, task_template, update_config):
7+
8+
def raise_version_error(param, min_version):
9+
raise errors.InvalidVersion(
10+
'{} is not supported in API version < {}'.format(
11+
param, min_version
12+
)
13+
)
14+
715
if update_config is not None:
816
if utils.version_lt(version, '1.25'):
917
if 'MaxFailureRatio' in update_config:
10-
raise errors.InvalidVersion(
11-
'UpdateConfig.max_failure_ratio is not supported in'
12-
' API version < 1.25'
13-
)
18+
raise_version_error('UpdateConfig.max_failure_ratio', '1.25')
1419
if 'Monitor' in update_config:
15-
raise errors.InvalidVersion(
16-
'UpdateConfig.monitor is not supported in'
17-
' API version < 1.25'
18-
)
20+
raise_version_error('UpdateConfig.monitor', '1.25')
1921

2022
if task_template is not None:
2123
if 'ForceUpdate' in task_template and utils.version_lt(
2224
version, '1.25'):
23-
raise errors.InvalidVersion(
24-
'force_update is not supported in API version < 1.25'
25-
)
25+
raise_version_error('force_update', '1.25')
2626

2727
if task_template.get('Placement'):
2828
if utils.version_lt(version, '1.30'):
2929
if task_template['Placement'].get('Platforms'):
30-
raise errors.InvalidVersion(
31-
'Placement.platforms is not supported in'
32-
' API version < 1.30'
33-
)
34-
30+
raise_version_error('Placement.platforms', '1.30')
3531
if utils.version_lt(version, '1.27'):
3632
if task_template['Placement'].get('Preferences'):
37-
raise errors.InvalidVersion(
38-
'Placement.preferences is not supported in'
39-
' API version < 1.27'
40-
)
41-
if task_template.get('ContainerSpec', {}).get('TTY'):
33+
raise_version_error('Placement.preferences', '1.27')
34+
35+
if task_template.get('ContainerSpec'):
36+
container_spec = task_template.get('ContainerSpec')
37+
4238
if utils.version_lt(version, '1.25'):
43-
raise errors.InvalidVersion(
44-
'ContainerSpec.TTY is not supported in API version < 1.25'
45-
)
39+
if container_spec.get('TTY'):
40+
raise_version_error('ContainerSpec.tty', '1.25')
41+
if container_spec.get('Hostname') is not None:
42+
raise_version_error('ContainerSpec.hostname', '1.25')
43+
if container_spec.get('Hosts') is not None:
44+
raise_version_error('ContainerSpec.hosts', '1.25')
45+
if container_spec.get('Groups') is not None:
46+
raise_version_error('ContainerSpec.groups', '1.25')
47+
if container_spec.get('DNSConfig') is not None:
48+
raise_version_error('ContainerSpec.dns_config', '1.25')
49+
if container_spec.get('Healthcheck') is not None:
50+
raise_version_error('ContainerSpec.healthcheck', '1.25')
51+
52+
if utils.version_lt(version, '1.28'):
53+
if container_spec.get('ReadOnly') is not None:
54+
raise_version_error('ContainerSpec.dns_config', '1.28')
55+
if container_spec.get('StopSignal') is not None:
56+
raise_version_error('ContainerSpec.stop_signal', '1.28')
57+
58+
if utils.version_lt(version, '1.30'):
59+
if container_spec.get('Configs') is not None:
60+
raise_version_error('ContainerSpec.configs', '1.30')
61+
if container_spec.get('Privileges') is not None:
62+
raise_version_error('ContainerSpec.privileges', '1.30')
4663

4764

4865
class ServiceApiMixin(object):

docker/models/services.py

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,22 @@ def create(self, image, command=None, **kwargs):
147147
user (str): User to run commands as.
148148
workdir (str): Working directory for commands to run.
149149
tty (boolean): Whether a pseudo-TTY should be allocated.
150+
groups (:py:class:`list`): A list of additional groups that the
151+
container process will run as.
152+
open_stdin (boolean): Open ``stdin``
153+
read_only (boolean): Mount the container's root filesystem as read
154+
only.
155+
stop_signal (string): Set signal to stop the service's containers
156+
healthcheck (Healthcheck): Healthcheck
157+
configuration for this service.
158+
hosts (:py:class:`dict`): A set of host to IP mappings to add to
159+
the container's `hosts` file.
160+
dns_config (DNSConfig): Specification for DNS
161+
related configurations in resolver configuration file.
162+
configs (:py:class:`list`): List of :py:class:`ConfigReference`
163+
that will be exposed to the service.
164+
privileges (Privileges): Security options for the service's
165+
containers.
150166
151167
Returns:
152168
(:py:class:`Service`) The created service.
@@ -202,18 +218,27 @@ def list(self, **kwargs):
202218

203219
# kwargs to copy straight over to ContainerSpec
204220
CONTAINER_SPEC_KWARGS = [
205-
'image',
206-
'command',
207221
'args',
222+
'command',
223+
'configs',
224+
'dns_config',
208225
'env',
226+
'groups',
227+
'healthcheck',
209228
'hostname',
210-
'workdir',
211-
'user',
229+
'hosts',
230+
'image',
212231
'labels',
213232
'mounts',
214-
'stop_grace_period',
233+
'open_stdin',
234+
'privileges'
235+
'read_only',
215236
'secrets',
216-
'tty'
237+
'stop_grace_period',
238+
'stop_signal',
239+
'tty',
240+
'user',
241+
'workdir',
217242
]
218243

219244
# kwargs to copy straight over to TaskTemplate

docker/types/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
from .healthcheck import Healthcheck
44
from .networks import EndpointConfig, IPAMConfig, IPAMPool, NetworkingConfig
55
from .services import (
6-
ContainerSpec, DriverConfig, EndpointSpec, Mount, Placement, Resources,
7-
RestartPolicy, SecretReference, ServiceMode, TaskTemplate, UpdateConfig
6+
ConfigReference, ContainerSpec, DNSConfig, DriverConfig, EndpointSpec,
7+
Mount, Placement, Privileges, Resources, RestartPolicy, SecretReference,
8+
ServiceMode, TaskTemplate, UpdateConfig
89
)
910
from .swarm import SwarmSpec, SwarmExternalCA

docker/types/containers.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
from .. import errors
55
from ..utils.utils import (
66
convert_port_bindings, convert_tmpfs_mounts, convert_volume_binds,
7-
format_environment, normalize_links, parse_bytes, parse_devices,
8-
split_command, version_gte, version_lt,
7+
format_environment, format_extra_hosts, normalize_links, parse_bytes,
8+
parse_devices, split_command, version_gte, version_lt,
99
)
1010
from .base import DictType
1111
from .healthcheck import Healthcheck
@@ -257,10 +257,7 @@ def __init__(self, version, binds=None, port_bindings=None,
257257

258258
if extra_hosts is not None:
259259
if isinstance(extra_hosts, dict):
260-
extra_hosts = [
261-
'{0}:{1}'.format(k, v)
262-
for k, v in sorted(six.iteritems(extra_hosts))
263-
]
260+
extra_hosts = format_extra_hosts(extra_hosts)
264261

265262
self['ExtraHosts'] = extra_hosts
266263

docker/types/healthcheck.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,30 @@
44

55

66
class Healthcheck(DictType):
7+
"""
8+
Defines a healthcheck configuration for a container or service.
9+
10+
Args:
11+
12+
test (:py:class:`list` or str): Test to perform to determine
13+
container health. Possible values:
14+
- Empty list: Inherit healthcheck from parent image
15+
- ``["NONE"]``: Disable healthcheck
16+
- ``["CMD", args...]``: exec arguments directly.
17+
- ``["CMD-SHELL", command]``: RUn command in the system's
18+
default shell.
19+
If a string is provided, it will be used as a ``CMD-SHELL``
20+
command.
21+
interval (int): The time to wait between checks in nanoseconds. It
22+
should be 0 or at least 1000000 (1 ms).
23+
timeout (int): The time to wait before considering the check to
24+
have hung. It should be 0 or at least 1000000 (1 ms).
25+
retries (integer): The number of consecutive failures needed to
26+
consider a container as unhealthy.
27+
start_period (integer): Start period for the container to
28+
initialize before starting health-retries countdown in
29+
nanoseconds. It should be 0 or at least 1000000 (1 ms).
30+
"""
731
def __init__(self, **kwargs):
832
test = kwargs.get('test', kwargs.get('Test'))
933
if isinstance(test, six.string_types):

0 commit comments

Comments
 (0)