mirror of https://github.com/docker/docker-py.git
Add support for new ContainerSpec parameters
Signed-off-by: Joffrey F <joffrey@docker.com>
This commit is contained in:
parent
10ea65f5ab
commit
601d6be526
|
@ -237,10 +237,9 @@ class BuildApiMixin(object):
|
||||||
'extra_hosts was only introduced in API version 1.27'
|
'extra_hosts was only introduced in API version 1.27'
|
||||||
)
|
)
|
||||||
|
|
||||||
encoded_extra_hosts = [
|
if isinstance(extra_hosts, dict):
|
||||||
'{}:{}'.format(k, v) for k, v in extra_hosts.items()
|
extra_hosts = utils.format_extra_hosts(extra_hosts)
|
||||||
]
|
params.update({'extrahosts': extra_hosts})
|
||||||
params.update({'extrahosts': encoded_extra_hosts})
|
|
||||||
|
|
||||||
if context is not None:
|
if context is not None:
|
||||||
headers = {'Content-Type': 'application/tar'}
|
headers = {'Content-Type': 'application/tar'}
|
||||||
|
|
|
@ -4,45 +4,62 @@ from ..types import ServiceMode
|
||||||
|
|
||||||
|
|
||||||
def _check_api_features(version, task_template, update_config):
|
def _check_api_features(version, task_template, update_config):
|
||||||
|
|
||||||
|
def raise_version_error(param, min_version):
|
||||||
|
raise errors.InvalidVersion(
|
||||||
|
'{} is not supported in API version < {}'.format(
|
||||||
|
param, min_version
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if update_config is not None:
|
if update_config is not None:
|
||||||
if utils.version_lt(version, '1.25'):
|
if utils.version_lt(version, '1.25'):
|
||||||
if 'MaxFailureRatio' in update_config:
|
if 'MaxFailureRatio' in update_config:
|
||||||
raise errors.InvalidVersion(
|
raise_version_error('UpdateConfig.max_failure_ratio', '1.25')
|
||||||
'UpdateConfig.max_failure_ratio is not supported in'
|
|
||||||
' API version < 1.25'
|
|
||||||
)
|
|
||||||
if 'Monitor' in update_config:
|
if 'Monitor' in update_config:
|
||||||
raise errors.InvalidVersion(
|
raise_version_error('UpdateConfig.monitor', '1.25')
|
||||||
'UpdateConfig.monitor is not supported in'
|
|
||||||
' API version < 1.25'
|
|
||||||
)
|
|
||||||
|
|
||||||
if task_template is not None:
|
if task_template is not None:
|
||||||
if 'ForceUpdate' in task_template and utils.version_lt(
|
if 'ForceUpdate' in task_template and utils.version_lt(
|
||||||
version, '1.25'):
|
version, '1.25'):
|
||||||
raise errors.InvalidVersion(
|
raise_version_error('force_update', '1.25')
|
||||||
'force_update is not supported in API version < 1.25'
|
|
||||||
)
|
|
||||||
|
|
||||||
if task_template.get('Placement'):
|
if task_template.get('Placement'):
|
||||||
if utils.version_lt(version, '1.30'):
|
if utils.version_lt(version, '1.30'):
|
||||||
if task_template['Placement'].get('Platforms'):
|
if task_template['Placement'].get('Platforms'):
|
||||||
raise errors.InvalidVersion(
|
raise_version_error('Placement.platforms', '1.30')
|
||||||
'Placement.platforms is not supported in'
|
|
||||||
' API version < 1.30'
|
|
||||||
)
|
|
||||||
|
|
||||||
if utils.version_lt(version, '1.27'):
|
if utils.version_lt(version, '1.27'):
|
||||||
if task_template['Placement'].get('Preferences'):
|
if task_template['Placement'].get('Preferences'):
|
||||||
raise errors.InvalidVersion(
|
raise_version_error('Placement.preferences', '1.27')
|
||||||
'Placement.preferences is not supported in'
|
|
||||||
' API version < 1.27'
|
if task_template.get('ContainerSpec'):
|
||||||
)
|
container_spec = task_template.get('ContainerSpec')
|
||||||
if task_template.get('ContainerSpec', {}).get('TTY'):
|
|
||||||
if utils.version_lt(version, '1.25'):
|
if utils.version_lt(version, '1.25'):
|
||||||
raise errors.InvalidVersion(
|
if container_spec.get('TTY'):
|
||||||
'ContainerSpec.TTY is not supported in API version < 1.25'
|
raise_version_error('ContainerSpec.tty', '1.25')
|
||||||
)
|
if container_spec.get('Hostname') is not None:
|
||||||
|
raise_version_error('ContainerSpec.hostname', '1.25')
|
||||||
|
if container_spec.get('Hosts') is not None:
|
||||||
|
raise_version_error('ContainerSpec.hosts', '1.25')
|
||||||
|
if container_spec.get('Groups') is not None:
|
||||||
|
raise_version_error('ContainerSpec.groups', '1.25')
|
||||||
|
if container_spec.get('DNSConfig') is not None:
|
||||||
|
raise_version_error('ContainerSpec.dns_config', '1.25')
|
||||||
|
if container_spec.get('Healthcheck') is not None:
|
||||||
|
raise_version_error('ContainerSpec.healthcheck', '1.25')
|
||||||
|
|
||||||
|
if utils.version_lt(version, '1.28'):
|
||||||
|
if container_spec.get('ReadOnly') is not None:
|
||||||
|
raise_version_error('ContainerSpec.dns_config', '1.28')
|
||||||
|
if container_spec.get('StopSignal') is not None:
|
||||||
|
raise_version_error('ContainerSpec.stop_signal', '1.28')
|
||||||
|
|
||||||
|
if utils.version_lt(version, '1.30'):
|
||||||
|
if container_spec.get('Configs') is not None:
|
||||||
|
raise_version_error('ContainerSpec.configs', '1.30')
|
||||||
|
if container_spec.get('Privileges') is not None:
|
||||||
|
raise_version_error('ContainerSpec.privileges', '1.30')
|
||||||
|
|
||||||
|
|
||||||
class ServiceApiMixin(object):
|
class ServiceApiMixin(object):
|
||||||
|
|
|
@ -147,6 +147,22 @@ class ServiceCollection(Collection):
|
||||||
user (str): User to run commands as.
|
user (str): User to run commands as.
|
||||||
workdir (str): Working directory for commands to run.
|
workdir (str): Working directory for commands to run.
|
||||||
tty (boolean): Whether a pseudo-TTY should be allocated.
|
tty (boolean): Whether a pseudo-TTY should be allocated.
|
||||||
|
groups (:py:class:`list`): A list of additional groups that the
|
||||||
|
container process will run as.
|
||||||
|
open_stdin (boolean): Open ``stdin``
|
||||||
|
read_only (boolean): Mount the container's root filesystem as read
|
||||||
|
only.
|
||||||
|
stop_signal (string): Set signal to stop the service's containers
|
||||||
|
healthcheck (Healthcheck): Healthcheck
|
||||||
|
configuration for this service.
|
||||||
|
hosts (:py:class:`dict`): A set of host to IP mappings to add to
|
||||||
|
the container's `hosts` file.
|
||||||
|
dns_config (DNSConfig): Specification for DNS
|
||||||
|
related configurations in resolver configuration file.
|
||||||
|
configs (:py:class:`list`): List of :py:class:`ConfigReference`
|
||||||
|
that will be exposed to the service.
|
||||||
|
privileges (Privileges): Security options for the service's
|
||||||
|
containers.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
(:py:class:`Service`) The created service.
|
(:py:class:`Service`) The created service.
|
||||||
|
@ -202,18 +218,27 @@ class ServiceCollection(Collection):
|
||||||
|
|
||||||
# kwargs to copy straight over to ContainerSpec
|
# kwargs to copy straight over to ContainerSpec
|
||||||
CONTAINER_SPEC_KWARGS = [
|
CONTAINER_SPEC_KWARGS = [
|
||||||
'image',
|
|
||||||
'command',
|
|
||||||
'args',
|
'args',
|
||||||
|
'command',
|
||||||
|
'configs',
|
||||||
|
'dns_config',
|
||||||
'env',
|
'env',
|
||||||
|
'groups',
|
||||||
|
'healthcheck',
|
||||||
'hostname',
|
'hostname',
|
||||||
'workdir',
|
'hosts',
|
||||||
'user',
|
'image',
|
||||||
'labels',
|
'labels',
|
||||||
'mounts',
|
'mounts',
|
||||||
'stop_grace_period',
|
'open_stdin',
|
||||||
|
'privileges'
|
||||||
|
'read_only',
|
||||||
'secrets',
|
'secrets',
|
||||||
'tty'
|
'stop_grace_period',
|
||||||
|
'stop_signal',
|
||||||
|
'tty',
|
||||||
|
'user',
|
||||||
|
'workdir',
|
||||||
]
|
]
|
||||||
|
|
||||||
# kwargs to copy straight over to TaskTemplate
|
# kwargs to copy straight over to TaskTemplate
|
||||||
|
|
|
@ -3,7 +3,8 @@ from .containers import ContainerConfig, HostConfig, LogConfig, Ulimit
|
||||||
from .healthcheck import Healthcheck
|
from .healthcheck import Healthcheck
|
||||||
from .networks import EndpointConfig, IPAMConfig, IPAMPool, NetworkingConfig
|
from .networks import EndpointConfig, IPAMConfig, IPAMPool, NetworkingConfig
|
||||||
from .services import (
|
from .services import (
|
||||||
ContainerSpec, DriverConfig, EndpointSpec, Mount, Placement, Resources,
|
ConfigReference, ContainerSpec, DNSConfig, DriverConfig, EndpointSpec,
|
||||||
RestartPolicy, SecretReference, ServiceMode, TaskTemplate, UpdateConfig
|
Mount, Placement, Privileges, Resources, RestartPolicy, SecretReference,
|
||||||
|
ServiceMode, TaskTemplate, UpdateConfig
|
||||||
)
|
)
|
||||||
from .swarm import SwarmSpec, SwarmExternalCA
|
from .swarm import SwarmSpec, SwarmExternalCA
|
||||||
|
|
|
@ -4,8 +4,8 @@ import warnings
|
||||||
from .. import errors
|
from .. import errors
|
||||||
from ..utils.utils import (
|
from ..utils.utils import (
|
||||||
convert_port_bindings, convert_tmpfs_mounts, convert_volume_binds,
|
convert_port_bindings, convert_tmpfs_mounts, convert_volume_binds,
|
||||||
format_environment, normalize_links, parse_bytes, parse_devices,
|
format_environment, format_extra_hosts, normalize_links, parse_bytes,
|
||||||
split_command, version_gte, version_lt,
|
parse_devices, split_command, version_gte, version_lt,
|
||||||
)
|
)
|
||||||
from .base import DictType
|
from .base import DictType
|
||||||
from .healthcheck import Healthcheck
|
from .healthcheck import Healthcheck
|
||||||
|
@ -257,10 +257,7 @@ class HostConfig(dict):
|
||||||
|
|
||||||
if extra_hosts is not None:
|
if extra_hosts is not None:
|
||||||
if isinstance(extra_hosts, dict):
|
if isinstance(extra_hosts, dict):
|
||||||
extra_hosts = [
|
extra_hosts = format_extra_hosts(extra_hosts)
|
||||||
'{0}:{1}'.format(k, v)
|
|
||||||
for k, v in sorted(six.iteritems(extra_hosts))
|
|
||||||
]
|
|
||||||
|
|
||||||
self['ExtraHosts'] = extra_hosts
|
self['ExtraHosts'] = extra_hosts
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,30 @@ import six
|
||||||
|
|
||||||
|
|
||||||
class Healthcheck(DictType):
|
class Healthcheck(DictType):
|
||||||
|
"""
|
||||||
|
Defines a healthcheck configuration for a container or service.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
|
||||||
|
test (:py:class:`list` or str): Test to perform to determine
|
||||||
|
container health. Possible values:
|
||||||
|
- Empty list: Inherit healthcheck from parent image
|
||||||
|
- ``["NONE"]``: Disable healthcheck
|
||||||
|
- ``["CMD", args...]``: exec arguments directly.
|
||||||
|
- ``["CMD-SHELL", command]``: RUn command in the system's
|
||||||
|
default shell.
|
||||||
|
If a string is provided, it will be used as a ``CMD-SHELL``
|
||||||
|
command.
|
||||||
|
interval (int): The time to wait between checks in nanoseconds. It
|
||||||
|
should be 0 or at least 1000000 (1 ms).
|
||||||
|
timeout (int): The time to wait before considering the check to
|
||||||
|
have hung. It should be 0 or at least 1000000 (1 ms).
|
||||||
|
retries (integer): The number of consecutive failures needed to
|
||||||
|
consider a container as unhealthy.
|
||||||
|
start_period (integer): Start period for the container to
|
||||||
|
initialize before starting health-retries countdown in
|
||||||
|
nanoseconds. It should be 0 or at least 1000000 (1 ms).
|
||||||
|
"""
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
test = kwargs.get('test', kwargs.get('Test'))
|
test = kwargs.get('test', kwargs.get('Test'))
|
||||||
if isinstance(test, six.string_types):
|
if isinstance(test, six.string_types):
|
||||||
|
|
|
@ -3,7 +3,8 @@ import six
|
||||||
from .. import errors
|
from .. import errors
|
||||||
from ..constants import IS_WINDOWS_PLATFORM
|
from ..constants import IS_WINDOWS_PLATFORM
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
check_resource, format_environment, parse_bytes, split_command
|
check_resource, format_environment, format_extra_hosts, parse_bytes,
|
||||||
|
split_command,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,13 +85,31 @@ class ContainerSpec(dict):
|
||||||
:py:class:`~docker.types.Mount` class for details.
|
:py:class:`~docker.types.Mount` class for details.
|
||||||
stop_grace_period (int): Amount of time to wait for the container to
|
stop_grace_period (int): Amount of time to wait for the container to
|
||||||
terminate before forcefully killing it.
|
terminate before forcefully killing it.
|
||||||
secrets (list of py:class:`SecretReference`): List of secrets to be
|
secrets (:py:class:`list`): List of :py:class:`SecretReference` to be
|
||||||
made available inside the containers.
|
made available inside the containers.
|
||||||
tty (boolean): Whether a pseudo-TTY should be allocated.
|
tty (boolean): Whether a pseudo-TTY should be allocated.
|
||||||
|
groups (:py:class:`list`): A list of additional groups that the
|
||||||
|
container process will run as.
|
||||||
|
open_stdin (boolean): Open ``stdin``
|
||||||
|
read_only (boolean): Mount the container's root filesystem as read
|
||||||
|
only.
|
||||||
|
stop_signal (string): Set signal to stop the service's containers
|
||||||
|
healthcheck (Healthcheck): Healthcheck
|
||||||
|
configuration for this service.
|
||||||
|
hosts (:py:class:`dict`): A set of host to IP mappings to add to
|
||||||
|
the container's `hosts` file.
|
||||||
|
dns_config (DNSConfig): Specification for DNS
|
||||||
|
related configurations in resolver configuration file.
|
||||||
|
configs (:py:class:`list`): List of :py:class:`ConfigReference` that
|
||||||
|
will be exposed to the service.
|
||||||
|
privileges (Privileges): Security options for the service's containers.
|
||||||
"""
|
"""
|
||||||
def __init__(self, image, command=None, args=None, hostname=None, env=None,
|
def __init__(self, image, command=None, args=None, hostname=None, env=None,
|
||||||
workdir=None, user=None, labels=None, mounts=None,
|
workdir=None, user=None, labels=None, mounts=None,
|
||||||
stop_grace_period=None, secrets=None, tty=None):
|
stop_grace_period=None, secrets=None, tty=None, groups=None,
|
||||||
|
open_stdin=None, read_only=None, stop_signal=None,
|
||||||
|
healthcheck=None, hosts=None, dns_config=None, configs=None,
|
||||||
|
privileges=None):
|
||||||
self['Image'] = image
|
self['Image'] = image
|
||||||
|
|
||||||
if isinstance(command, six.string_types):
|
if isinstance(command, six.string_types):
|
||||||
|
@ -109,8 +128,17 @@ class ContainerSpec(dict):
|
||||||
self['Dir'] = workdir
|
self['Dir'] = workdir
|
||||||
if user is not None:
|
if user is not None:
|
||||||
self['User'] = user
|
self['User'] = user
|
||||||
|
if groups is not None:
|
||||||
|
self['Groups'] = groups
|
||||||
|
if stop_signal is not None:
|
||||||
|
self['StopSignal'] = stop_signal
|
||||||
|
if stop_grace_period is not None:
|
||||||
|
self['StopGracePeriod'] = stop_grace_period
|
||||||
if labels is not None:
|
if labels is not None:
|
||||||
self['Labels'] = labels
|
self['Labels'] = labels
|
||||||
|
if hosts is not None:
|
||||||
|
self['Hosts'] = format_extra_hosts(hosts)
|
||||||
|
|
||||||
if mounts is not None:
|
if mounts is not None:
|
||||||
parsed_mounts = []
|
parsed_mounts = []
|
||||||
for mount in mounts:
|
for mount in mounts:
|
||||||
|
@ -120,16 +148,30 @@ class ContainerSpec(dict):
|
||||||
# If mount already parsed
|
# If mount already parsed
|
||||||
parsed_mounts.append(mount)
|
parsed_mounts.append(mount)
|
||||||
self['Mounts'] = parsed_mounts
|
self['Mounts'] = parsed_mounts
|
||||||
if stop_grace_period is not None:
|
|
||||||
self['StopGracePeriod'] = stop_grace_period
|
|
||||||
|
|
||||||
if secrets is not None:
|
if secrets is not None:
|
||||||
if not isinstance(secrets, list):
|
if not isinstance(secrets, list):
|
||||||
raise TypeError('secrets must be a list')
|
raise TypeError('secrets must be a list')
|
||||||
self['Secrets'] = secrets
|
self['Secrets'] = secrets
|
||||||
|
|
||||||
|
if configs is not None:
|
||||||
|
if not isinstance(configs, list):
|
||||||
|
raise TypeError('configs must be a list')
|
||||||
|
self['Configs'] = configs
|
||||||
|
|
||||||
|
if dns_config is not None:
|
||||||
|
self['DNSConfig'] = dns_config
|
||||||
|
if privileges is not None:
|
||||||
|
self['Privileges'] = privileges
|
||||||
|
if healthcheck is not None:
|
||||||
|
self['Healthcheck'] = healthcheck
|
||||||
|
|
||||||
if tty is not None:
|
if tty is not None:
|
||||||
self['TTY'] = tty
|
self['TTY'] = tty
|
||||||
|
if open_stdin is not None:
|
||||||
|
self['OpenStdin'] = open_stdin
|
||||||
|
if read_only is not None:
|
||||||
|
self['ReadOnly'] = read_only
|
||||||
|
|
||||||
|
|
||||||
class Mount(dict):
|
class Mount(dict):
|
||||||
|
@ -487,6 +529,34 @@ class SecretReference(dict):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigReference(dict):
|
||||||
|
"""
|
||||||
|
Config reference to be used as part of a :py:class:`ContainerSpec`.
|
||||||
|
Describes how a config is made accessible inside the service's
|
||||||
|
containers.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config_id (string): Config's ID
|
||||||
|
config_name (string): Config's name as defined at its creation.
|
||||||
|
filename (string): Name of the file containing the config. Defaults
|
||||||
|
to the config's name if not specified.
|
||||||
|
uid (string): UID of the config file's owner. Default: 0
|
||||||
|
gid (string): GID of the config file's group. Default: 0
|
||||||
|
mode (int): File access mode inside the container. Default: 0o444
|
||||||
|
"""
|
||||||
|
@check_resource('config_id')
|
||||||
|
def __init__(self, config_id, config_name, filename=None, uid=None,
|
||||||
|
gid=None, mode=0o444):
|
||||||
|
self['ConfigName'] = config_name
|
||||||
|
self['ConfigID'] = config_id
|
||||||
|
self['File'] = {
|
||||||
|
'Name': filename or config_name,
|
||||||
|
'UID': uid or '0',
|
||||||
|
'GID': gid or '0',
|
||||||
|
'Mode': mode
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Placement(dict):
|
class Placement(dict):
|
||||||
"""
|
"""
|
||||||
Placement constraints to be used as part of a :py:class:`TaskTemplate`
|
Placement constraints to be used as part of a :py:class:`TaskTemplate`
|
||||||
|
@ -510,3 +580,75 @@ class Placement(dict):
|
||||||
self['Platforms'].append({
|
self['Platforms'].append({
|
||||||
'Architecture': plat[0], 'OS': plat[1]
|
'Architecture': plat[0], 'OS': plat[1]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
class DNSConfig(dict):
|
||||||
|
"""
|
||||||
|
Specification for DNS related configurations in resolver configuration
|
||||||
|
file (``resolv.conf``). Part of a :py:class:`ContainerSpec` definition.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
nameservers (:py:class:`list`): The IP addresses of the name
|
||||||
|
servers.
|
||||||
|
search (:py:class:`list`): A search list for host-name lookup.
|
||||||
|
options (:py:class:`list`): A list of internal resolver variables
|
||||||
|
to be modified (e.g., ``debug``, ``ndots:3``, etc.).
|
||||||
|
"""
|
||||||
|
def __init__(self, nameservers=None, search=None, options=None):
|
||||||
|
self['Nameservers'] = nameservers
|
||||||
|
self['Search'] = search
|
||||||
|
self['Options'] = options
|
||||||
|
|
||||||
|
|
||||||
|
class Privileges(dict):
|
||||||
|
"""
|
||||||
|
Security options for a service's containers.
|
||||||
|
Part of a :py:class:`ContainerSpec` definition.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
credentialspec_file (str): Load credential spec from this file.
|
||||||
|
The file is read by the daemon, and must be present in the
|
||||||
|
CredentialSpecs subdirectory in the docker data directory,
|
||||||
|
which defaults to ``C:\ProgramData\Docker\`` on Windows.
|
||||||
|
Can not be combined with credentialspec_registry.
|
||||||
|
|
||||||
|
credentialspec_registry (str): Load credential spec from this value
|
||||||
|
in the Windows registry. The specified registry value must be
|
||||||
|
located in: ``HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion
|
||||||
|
\Virtualization\Containers\CredentialSpecs``.
|
||||||
|
Can not be combined with credentialspec_file.
|
||||||
|
|
||||||
|
selinux_disable (boolean): Disable SELinux
|
||||||
|
selinux_user (string): SELinux user label
|
||||||
|
selinux_role (string): SELinux role label
|
||||||
|
selinux_type (string): SELinux type label
|
||||||
|
selinux_level (string): SELinux level label
|
||||||
|
"""
|
||||||
|
def __init__(self, credentialspec_file=None, credentialspec_registry=None,
|
||||||
|
selinux_disable=None, selinux_user=None, selinux_role=None,
|
||||||
|
selinux_type=None, selinux_level=None):
|
||||||
|
credential_spec = {}
|
||||||
|
if credentialspec_registry is not None:
|
||||||
|
credential_spec['Registry'] = credentialspec_registry
|
||||||
|
if credentialspec_file is not None:
|
||||||
|
credential_spec['File'] = credentialspec_file
|
||||||
|
|
||||||
|
if len(credential_spec) > 1:
|
||||||
|
raise errors.InvalidArgument(
|
||||||
|
'credentialspec_file and credentialspec_registry are mutually'
|
||||||
|
' exclusive'
|
||||||
|
)
|
||||||
|
|
||||||
|
selinux_context = {
|
||||||
|
'Disable': selinux_disable,
|
||||||
|
'User': selinux_user,
|
||||||
|
'Role': selinux_role,
|
||||||
|
'Type': selinux_type,
|
||||||
|
'Level': selinux_level,
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(credential_spec) > 0:
|
||||||
|
self['CredentialSpec'] = credential_spec
|
||||||
|
|
||||||
|
if len(selinux_context) > 0:
|
||||||
|
self['SELinuxContext'] = selinux_context
|
||||||
|
|
|
@ -8,6 +8,6 @@ from .utils import (
|
||||||
create_host_config, parse_bytes, ping_registry, parse_env_file, version_lt,
|
create_host_config, parse_bytes, ping_registry, parse_env_file, version_lt,
|
||||||
version_gte, decode_json_header, split_command, create_ipam_config,
|
version_gte, decode_json_header, split_command, create_ipam_config,
|
||||||
create_ipam_pool, parse_devices, normalize_links, convert_service_networks,
|
create_ipam_pool, parse_devices, normalize_links, convert_service_networks,
|
||||||
format_environment, create_archive
|
format_environment, create_archive, format_extra_hosts
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -564,6 +564,12 @@ def format_environment(environment):
|
||||||
return [format_env(*var) for var in six.iteritems(environment)]
|
return [format_env(*var) for var in six.iteritems(environment)]
|
||||||
|
|
||||||
|
|
||||||
|
def format_extra_hosts(extra_hosts):
|
||||||
|
return [
|
||||||
|
'{}:{}'.format(k, v) for k, v in sorted(six.iteritems(extra_hosts))
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def create_host_config(self, *args, **kwargs):
|
def create_host_config(self, *args, **kwargs):
|
||||||
raise errors.DeprecatedMethod(
|
raise errors.DeprecatedMethod(
|
||||||
'utils.create_host_config has been removed. Please use a '
|
'utils.create_host_config has been removed. Please use a '
|
||||||
|
|
|
@ -122,13 +122,17 @@ Configuration types
|
||||||
|
|
||||||
.. py:module:: docker.types
|
.. py:module:: docker.types
|
||||||
|
|
||||||
.. autoclass:: IPAMConfig
|
.. autoclass:: ConfigReference
|
||||||
.. autoclass:: IPAMPool
|
|
||||||
.. autoclass:: ContainerSpec
|
.. autoclass:: ContainerSpec
|
||||||
|
.. autoclass:: DNSConfig
|
||||||
.. autoclass:: DriverConfig
|
.. autoclass:: DriverConfig
|
||||||
.. autoclass:: EndpointSpec
|
.. autoclass:: EndpointSpec
|
||||||
|
.. autoclass:: Healthcheck
|
||||||
|
.. autoclass:: IPAMConfig
|
||||||
|
.. autoclass:: IPAMPool
|
||||||
.. autoclass:: Mount
|
.. autoclass:: Mount
|
||||||
.. autoclass:: Placement
|
.. autoclass:: Placement
|
||||||
|
.. autoclass:: Privileges
|
||||||
.. autoclass:: Resources
|
.. autoclass:: Resources
|
||||||
.. autoclass:: RestartPolicy
|
.. autoclass:: RestartPolicy
|
||||||
.. autoclass:: SecretReference
|
.. autoclass:: SecretReference
|
||||||
|
|
Loading…
Reference in New Issue