| import six |
| |
| from .. import errors |
| from ..utils.utils import ( |
| convert_port_bindings, convert_tmpfs_mounts, convert_volume_binds, |
| format_environment, format_extra_hosts, normalize_links, parse_bytes, |
| parse_devices, split_command, version_gte, version_lt, |
| ) |
| from .base import DictType |
| from .healthcheck import Healthcheck |
| |
| |
| class LogConfigTypesEnum(object): |
| _values = ( |
| 'json-file', |
| 'syslog', |
| 'journald', |
| 'gelf', |
| 'fluentd', |
| 'none' |
| ) |
| JSON, SYSLOG, JOURNALD, GELF, FLUENTD, NONE = _values |
| |
| |
| class LogConfig(DictType): |
| """ |
| Configure logging for a container, when provided as an argument to |
| :py:meth:`~docker.api.container.ContainerApiMixin.create_host_config`. |
| You may refer to the |
| `official logging driver documentation <https://docs.docker.com/config/containers/logging/configure/>`_ |
| for more information. |
| |
| Args: |
| type (str): Indicate which log driver to use. A set of valid drivers |
| is provided as part of the :py:attr:`LogConfig.types` |
| enum. Other values may be accepted depending on the engine version |
| and available logging plugins. |
| config (dict): A driver-dependent configuration dictionary. Please |
| refer to the driver's documentation for a list of valid config |
| keys. |
| |
| Example: |
| |
| >>> from docker.types import LogConfig |
| >>> lc = LogConfig(type=LogConfig.types.JSON, config={ |
| ... 'max-size': '1g', |
| ... 'labels': 'production_status,geo' |
| ... }) |
| >>> hc = client.create_host_config(log_config=lc) |
| >>> container = client.create_container('busybox', 'true', |
| ... host_config=hc) |
| >>> client.inspect_container(container)['HostConfig']['LogConfig'] |
| {'Type': 'json-file', 'Config': {'labels': 'production_status,geo', 'max-size': '1g'}} |
| """ # noqa: E501 |
| types = LogConfigTypesEnum |
| |
| def __init__(self, **kwargs): |
| log_driver_type = kwargs.get('type', kwargs.get('Type')) |
| config = kwargs.get('config', kwargs.get('Config')) or {} |
| |
| if config and not isinstance(config, dict): |
| raise ValueError("LogConfig.config must be a dictionary") |
| |
| super(LogConfig, self).__init__({ |
| 'Type': log_driver_type, |
| 'Config': config |
| }) |
| |
| @property |
| def type(self): |
| return self['Type'] |
| |
| @type.setter |
| def type(self, value): |
| self['Type'] = value |
| |
| @property |
| def config(self): |
| return self['Config'] |
| |
| def set_config_value(self, key, value): |
| """ Set a the value for ``key`` to ``value`` inside the ``config`` |
| dict. |
| """ |
| self.config[key] = value |
| |
| def unset_config(self, key): |
| """ Remove the ``key`` property from the ``config`` dict. """ |
| if key in self.config: |
| del self.config[key] |
| |
| |
| class Ulimit(DictType): |
| """ |
| Create a ulimit declaration to be used with |
| :py:meth:`~docker.api.container.ContainerApiMixin.create_host_config`. |
| |
| Args: |
| |
| name (str): Which ulimit will this apply to. The valid names can be |
| found in '/etc/security/limits.conf' on a gnu/linux system. |
| soft (int): The soft limit for this ulimit. Optional. |
| hard (int): The hard limit for this ulimit. Optional. |
| |
| Example: |
| |
| >>> nproc_limit = docker.types.Ulimit(name='nproc', soft=1024) |
| >>> hc = client.create_host_config(ulimits=[nproc_limit]) |
| >>> container = client.create_container( |
| 'busybox', 'true', host_config=hc |
| ) |
| >>> client.inspect_container(container)['HostConfig']['Ulimits'] |
| [{'Name': 'nproc', 'Hard': 0, 'Soft': 1024}] |
| |
| """ |
| def __init__(self, **kwargs): |
| name = kwargs.get('name', kwargs.get('Name')) |
| soft = kwargs.get('soft', kwargs.get('Soft')) |
| hard = kwargs.get('hard', kwargs.get('Hard')) |
| if not isinstance(name, six.string_types): |
| raise ValueError("Ulimit.name must be a string") |
| if soft and not isinstance(soft, int): |
| raise ValueError("Ulimit.soft must be an integer") |
| if hard and not isinstance(hard, int): |
| raise ValueError("Ulimit.hard must be an integer") |
| super(Ulimit, self).__init__({ |
| 'Name': name, |
| 'Soft': soft, |
| 'Hard': hard |
| }) |
| |
| @property |
| def name(self): |
| return self['Name'] |
| |
| @name.setter |
| def name(self, value): |
| self['Name'] = value |
| |
| @property |
| def soft(self): |
| return self.get('Soft') |
| |
| @soft.setter |
| def soft(self, value): |
| self['Soft'] = value |
| |
| @property |
| def hard(self): |
| return self.get('Hard') |
| |
| @hard.setter |
| def hard(self, value): |
| self['Hard'] = value |
| |
| |
| class DeviceRequest(DictType): |
| """ |
| Create a device request to be used with |
| :py:meth:`~docker.api.container.ContainerApiMixin.create_host_config`. |
| |
| Args: |
| |
| driver (str): Which driver to use for this device. Optional. |
| count (int): Number or devices to request. Optional. |
| Set to -1 to request all available devices. |
| device_ids (list): List of strings for device IDs. Optional. |
| Set either ``count`` or ``device_ids``. |
| capabilities (list): List of lists of strings to request |
| capabilities. Optional. The global list acts like an OR, |
| and the sub-lists are AND. The driver will try to satisfy |
| one of the sub-lists. |
| Available capabilities for the ``nvidia`` driver can be found |
| `here <https://github.com/NVIDIA/nvidia-container-runtime>`_. |
| options (dict): Driver-specific options. Optional. |
| """ |
| |
| def __init__(self, **kwargs): |
| driver = kwargs.get('driver', kwargs.get('Driver')) |
| count = kwargs.get('count', kwargs.get('Count')) |
| device_ids = kwargs.get('device_ids', kwargs.get('DeviceIDs')) |
| capabilities = kwargs.get('capabilities', kwargs.get('Capabilities')) |
| options = kwargs.get('options', kwargs.get('Options')) |
| |
| if driver is None: |
| driver = '' |
| elif not isinstance(driver, six.string_types): |
| raise ValueError('DeviceRequest.driver must be a string') |
| if count is None: |
| count = 0 |
| elif not isinstance(count, int): |
| raise ValueError('DeviceRequest.count must be an integer') |
| if device_ids is None: |
| device_ids = [] |
| elif not isinstance(device_ids, list): |
| raise ValueError('DeviceRequest.device_ids must be a list') |
| if capabilities is None: |
| capabilities = [] |
| elif not isinstance(capabilities, list): |
| raise ValueError('DeviceRequest.capabilities must be a list') |
| if options is None: |
| options = {} |
| elif not isinstance(options, dict): |
| raise ValueError('DeviceRequest.options must be a dict') |
| |
| super(DeviceRequest, self).__init__({ |
| 'Driver': driver, |
| 'Count': count, |
| 'DeviceIDs': device_ids, |
| 'Capabilities': capabilities, |
| 'Options': options |
| }) |
| |
| @property |
| def driver(self): |
| return self['Driver'] |
| |
| @driver.setter |
| def driver(self, value): |
| self['Driver'] = value |
| |
| @property |
| def count(self): |
| return self['Count'] |
| |
| @count.setter |
| def count(self, value): |
| self['Count'] = value |
| |
| @property |
| def device_ids(self): |
| return self['DeviceIDs'] |
| |
| @device_ids.setter |
| def device_ids(self, value): |
| self['DeviceIDs'] = value |
| |
| @property |
| def capabilities(self): |
| return self['Capabilities'] |
| |
| @capabilities.setter |
| def capabilities(self, value): |
| self['Capabilities'] = value |
| |
| @property |
| def options(self): |
| return self['Options'] |
| |
| @options.setter |
| def options(self, value): |
| self['Options'] = value |
| |
| |
| class HostConfig(dict): |
| def __init__(self, version, 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, restart_policy=None, |
| cap_add=None, cap_drop=None, devices=None, extra_hosts=None, |
| read_only=None, pid_mode=None, ipc_mode=None, |
| security_opt=None, ulimits=None, log_config=None, |
| mem_limit=None, memswap_limit=None, mem_reservation=None, |
| kernel_memory=None, mem_swappiness=None, cgroup_parent=None, |
| group_add=None, cpu_quota=None, cpu_period=None, |
| blkio_weight=None, blkio_weight_device=None, |
| device_read_bps=None, device_write_bps=None, |
| device_read_iops=None, device_write_iops=None, |
| oom_kill_disable=False, shm_size=None, sysctls=None, |
| tmpfs=None, oom_score_adj=None, dns_opt=None, cpu_shares=None, |
| cpuset_cpus=None, userns_mode=None, uts_mode=None, |
| pids_limit=None, isolation=None, auto_remove=False, |
| storage_opt=None, init=None, init_path=None, |
| volume_driver=None, cpu_count=None, cpu_percent=None, |
| nano_cpus=None, cpuset_mems=None, runtime=None, mounts=None, |
| cpu_rt_period=None, cpu_rt_runtime=None, |
| device_cgroup_rules=None, device_requests=None): |
| |
| if mem_limit is not None: |
| self['Memory'] = parse_bytes(mem_limit) |
| |
| if memswap_limit is not None: |
| self['MemorySwap'] = parse_bytes(memswap_limit) |
| |
| if mem_reservation: |
| self['MemoryReservation'] = parse_bytes(mem_reservation) |
| |
| if kernel_memory: |
| self['KernelMemory'] = parse_bytes(kernel_memory) |
| |
| if mem_swappiness is not None: |
| if not isinstance(mem_swappiness, int): |
| raise host_config_type_error( |
| 'mem_swappiness', mem_swappiness, 'int' |
| ) |
| |
| self['MemorySwappiness'] = mem_swappiness |
| |
| if shm_size is not None: |
| if isinstance(shm_size, six.string_types): |
| shm_size = parse_bytes(shm_size) |
| |
| self['ShmSize'] = shm_size |
| |
| if pid_mode: |
| if version_lt(version, '1.24') and pid_mode != 'host': |
| raise host_config_value_error('pid_mode', pid_mode) |
| self['PidMode'] = pid_mode |
| |
| if ipc_mode: |
| self['IpcMode'] = ipc_mode |
| |
| if privileged: |
| self['Privileged'] = privileged |
| |
| if oom_kill_disable: |
| self['OomKillDisable'] = oom_kill_disable |
| |
| if oom_score_adj: |
| if version_lt(version, '1.22'): |
| raise host_config_version_error('oom_score_adj', '1.22') |
| if not isinstance(oom_score_adj, int): |
| raise host_config_type_error( |
| 'oom_score_adj', oom_score_adj, 'int' |
| ) |
| self['OomScoreAdj'] = oom_score_adj |
| |
| if publish_all_ports: |
| self['PublishAllPorts'] = publish_all_ports |
| |
| if read_only is not None: |
| self['ReadonlyRootfs'] = read_only |
| |
| if dns_search: |
| self['DnsSearch'] = dns_search |
| |
| if network_mode == 'host' and port_bindings: |
| raise host_config_incompatible_error( |
| 'network_mode', 'host', 'port_bindings' |
| ) |
| self['NetworkMode'] = network_mode or 'default' |
| |
| if restart_policy: |
| if not isinstance(restart_policy, dict): |
| raise host_config_type_error( |
| 'restart_policy', restart_policy, 'dict' |
| ) |
| |
| self['RestartPolicy'] = restart_policy |
| |
| if cap_add: |
| self['CapAdd'] = cap_add |
| |
| if cap_drop: |
| self['CapDrop'] = cap_drop |
| |
| if devices: |
| self['Devices'] = parse_devices(devices) |
| |
| if group_add: |
| self['GroupAdd'] = [six.text_type(grp) for grp in group_add] |
| |
| if dns is not None: |
| self['Dns'] = dns |
| |
| if dns_opt is not None: |
| self['DnsOptions'] = dns_opt |
| |
| if security_opt is not None: |
| if not isinstance(security_opt, list): |
| raise host_config_type_error( |
| 'security_opt', security_opt, 'list' |
| ) |
| |
| self['SecurityOpt'] = security_opt |
| |
| if sysctls: |
| if not isinstance(sysctls, dict): |
| raise host_config_type_error('sysctls', sysctls, 'dict') |
| self['Sysctls'] = {} |
| for k, v in six.iteritems(sysctls): |
| self['Sysctls'][k] = six.text_type(v) |
| |
| if volumes_from is not None: |
| if isinstance(volumes_from, six.string_types): |
| volumes_from = volumes_from.split(',') |
| |
| self['VolumesFrom'] = volumes_from |
| |
| if binds is not None: |
| self['Binds'] = convert_volume_binds(binds) |
| |
| if port_bindings is not None: |
| self['PortBindings'] = convert_port_bindings(port_bindings) |
| |
| if extra_hosts is not None: |
| if isinstance(extra_hosts, dict): |
| extra_hosts = format_extra_hosts(extra_hosts) |
| |
| self['ExtraHosts'] = extra_hosts |
| |
| if links is not None: |
| self['Links'] = normalize_links(links) |
| |
| if isinstance(lxc_conf, dict): |
| formatted = [] |
| for k, v in six.iteritems(lxc_conf): |
| formatted.append({'Key': k, 'Value': str(v)}) |
| lxc_conf = formatted |
| |
| if lxc_conf is not None: |
| self['LxcConf'] = lxc_conf |
| |
| if cgroup_parent is not None: |
| self['CgroupParent'] = cgroup_parent |
| |
| if ulimits is not None: |
| if not isinstance(ulimits, list): |
| raise host_config_type_error('ulimits', ulimits, 'list') |
| self['Ulimits'] = [] |
| for lmt in ulimits: |
| if not isinstance(lmt, Ulimit): |
| lmt = Ulimit(**lmt) |
| self['Ulimits'].append(lmt) |
| |
| if log_config is not None: |
| if not isinstance(log_config, LogConfig): |
| if not isinstance(log_config, dict): |
| raise host_config_type_error( |
| 'log_config', log_config, 'LogConfig' |
| ) |
| log_config = LogConfig(**log_config) |
| |
| self['LogConfig'] = log_config |
| |
| if cpu_quota: |
| if not isinstance(cpu_quota, int): |
| raise host_config_type_error('cpu_quota', cpu_quota, 'int') |
| self['CpuQuota'] = cpu_quota |
| |
| if cpu_period: |
| if not isinstance(cpu_period, int): |
| raise host_config_type_error('cpu_period', cpu_period, 'int') |
| self['CpuPeriod'] = cpu_period |
| |
| if cpu_shares: |
| if not isinstance(cpu_shares, int): |
| raise host_config_type_error('cpu_shares', cpu_shares, 'int') |
| |
| self['CpuShares'] = cpu_shares |
| |
| if cpuset_cpus: |
| self['CpusetCpus'] = cpuset_cpus |
| |
| if cpuset_mems: |
| if not isinstance(cpuset_mems, str): |
| raise host_config_type_error( |
| 'cpuset_mems', cpuset_mems, 'str' |
| ) |
| self['CpusetMems'] = cpuset_mems |
| |
| if cpu_rt_period: |
| if version_lt(version, '1.25'): |
| raise host_config_version_error('cpu_rt_period', '1.25') |
| |
| if not isinstance(cpu_rt_period, int): |
| raise host_config_type_error( |
| 'cpu_rt_period', cpu_rt_period, 'int' |
| ) |
| self['CPURealtimePeriod'] = cpu_rt_period |
| |
| if cpu_rt_runtime: |
| if version_lt(version, '1.25'): |
| raise host_config_version_error('cpu_rt_runtime', '1.25') |
| |
| if not isinstance(cpu_rt_runtime, int): |
| raise host_config_type_error( |
| 'cpu_rt_runtime', cpu_rt_runtime, 'int' |
| ) |
| self['CPURealtimeRuntime'] = cpu_rt_runtime |
| |
| if blkio_weight: |
| if not isinstance(blkio_weight, int): |
| raise host_config_type_error( |
| 'blkio_weight', blkio_weight, 'int' |
| ) |
| if version_lt(version, '1.22'): |
| raise host_config_version_error('blkio_weight', '1.22') |
| self["BlkioWeight"] = blkio_weight |
| |
| if blkio_weight_device: |
| if not isinstance(blkio_weight_device, list): |
| raise host_config_type_error( |
| 'blkio_weight_device', blkio_weight_device, 'list' |
| ) |
| if version_lt(version, '1.22'): |
| raise host_config_version_error('blkio_weight_device', '1.22') |
| self["BlkioWeightDevice"] = blkio_weight_device |
| |
| if device_read_bps: |
| if not isinstance(device_read_bps, list): |
| raise host_config_type_error( |
| 'device_read_bps', device_read_bps, 'list' |
| ) |
| if version_lt(version, '1.22'): |
| raise host_config_version_error('device_read_bps', '1.22') |
| self["BlkioDeviceReadBps"] = device_read_bps |
| |
| if device_write_bps: |
| if not isinstance(device_write_bps, list): |
| raise host_config_type_error( |
| 'device_write_bps', device_write_bps, 'list' |
| ) |
| if version_lt(version, '1.22'): |
| raise host_config_version_error('device_write_bps', '1.22') |
| self["BlkioDeviceWriteBps"] = device_write_bps |
| |
| if device_read_iops: |
| if not isinstance(device_read_iops, list): |
| raise host_config_type_error( |
| 'device_read_iops', device_read_iops, 'list' |
| ) |
| if version_lt(version, '1.22'): |
| raise host_config_version_error('device_read_iops', '1.22') |
| self["BlkioDeviceReadIOps"] = device_read_iops |
| |
| if device_write_iops: |
| if not isinstance(device_write_iops, list): |
| raise host_config_type_error( |
| 'device_write_iops', device_write_iops, 'list' |
| ) |
| if version_lt(version, '1.22'): |
| raise host_config_version_error('device_write_iops', '1.22') |
| self["BlkioDeviceWriteIOps"] = device_write_iops |
| |
| if tmpfs: |
| if version_lt(version, '1.22'): |
| raise host_config_version_error('tmpfs', '1.22') |
| self["Tmpfs"] = convert_tmpfs_mounts(tmpfs) |
| |
| if userns_mode: |
| if version_lt(version, '1.23'): |
| raise host_config_version_error('userns_mode', '1.23') |
| |
| if userns_mode != "host": |
| raise host_config_value_error("userns_mode", userns_mode) |
| self['UsernsMode'] = userns_mode |
| |
| if uts_mode: |
| if uts_mode != "host": |
| raise host_config_value_error("uts_mode", uts_mode) |
| self['UTSMode'] = uts_mode |
| |
| if pids_limit: |
| if not isinstance(pids_limit, int): |
| raise host_config_type_error('pids_limit', pids_limit, 'int') |
| if version_lt(version, '1.23'): |
| raise host_config_version_error('pids_limit', '1.23') |
| self["PidsLimit"] = pids_limit |
| |
| if isolation: |
| if not isinstance(isolation, six.string_types): |
| raise host_config_type_error('isolation', isolation, 'string') |
| if version_lt(version, '1.24'): |
| raise host_config_version_error('isolation', '1.24') |
| self['Isolation'] = isolation |
| |
| if auto_remove: |
| if version_lt(version, '1.25'): |
| raise host_config_version_error('auto_remove', '1.25') |
| self['AutoRemove'] = auto_remove |
| |
| if storage_opt is not None: |
| if version_lt(version, '1.24'): |
| raise host_config_version_error('storage_opt', '1.24') |
| self['StorageOpt'] = storage_opt |
| |
| if init is not None: |
| if version_lt(version, '1.25'): |
| raise host_config_version_error('init', '1.25') |
| self['Init'] = init |
| |
| if init_path is not None: |
| if version_lt(version, '1.25'): |
| raise host_config_version_error('init_path', '1.25') |
| |
| if version_gte(version, '1.29'): |
| # https://github.com/moby/moby/pull/32470 |
| raise host_config_version_error('init_path', '1.29', False) |
| self['InitPath'] = init_path |
| |
| if volume_driver is not None: |
| self['VolumeDriver'] = volume_driver |
| |
| if cpu_count: |
| if not isinstance(cpu_count, int): |
| raise host_config_type_error('cpu_count', cpu_count, 'int') |
| if version_lt(version, '1.25'): |
| raise host_config_version_error('cpu_count', '1.25') |
| |
| self['CpuCount'] = cpu_count |
| |
| if cpu_percent: |
| if not isinstance(cpu_percent, int): |
| raise host_config_type_error('cpu_percent', cpu_percent, 'int') |
| if version_lt(version, '1.25'): |
| raise host_config_version_error('cpu_percent', '1.25') |
| |
| self['CpuPercent'] = cpu_percent |
| |
| if nano_cpus: |
| if not isinstance(nano_cpus, six.integer_types): |
| raise host_config_type_error('nano_cpus', nano_cpus, 'int') |
| if version_lt(version, '1.25'): |
| raise host_config_version_error('nano_cpus', '1.25') |
| |
| self['NanoCpus'] = nano_cpus |
| |
| if runtime: |
| if version_lt(version, '1.25'): |
| raise host_config_version_error('runtime', '1.25') |
| self['Runtime'] = runtime |
| |
| if mounts is not None: |
| if version_lt(version, '1.30'): |
| raise host_config_version_error('mounts', '1.30') |
| self['Mounts'] = mounts |
| |
| if device_cgroup_rules is not None: |
| if version_lt(version, '1.28'): |
| raise host_config_version_error('device_cgroup_rules', '1.28') |
| if not isinstance(device_cgroup_rules, list): |
| raise host_config_type_error( |
| 'device_cgroup_rules', device_cgroup_rules, 'list' |
| ) |
| self['DeviceCgroupRules'] = device_cgroup_rules |
| |
| if device_requests is not None: |
| if version_lt(version, '1.40'): |
| raise host_config_version_error('device_requests', '1.40') |
| if not isinstance(device_requests, list): |
| raise host_config_type_error( |
| 'device_requests', device_requests, 'list' |
| ) |
| self['DeviceRequests'] = [] |
| for req in device_requests: |
| if not isinstance(req, DeviceRequest): |
| req = DeviceRequest(**req) |
| self['DeviceRequests'].append(req) |
| |
| |
| def host_config_type_error(param, param_value, expected): |
| error_msg = 'Invalid type for {0} param: expected {1} but found {2}' |
| return TypeError(error_msg.format(param, expected, type(param_value))) |
| |
| |
| def host_config_version_error(param, version, less_than=True): |
| operator = '<' if less_than else '>' |
| error_msg = '{0} param is not supported in API versions {1} {2}' |
| return errors.InvalidVersion(error_msg.format(param, operator, version)) |
| |
| |
| def host_config_value_error(param, param_value): |
| error_msg = 'Invalid value for {0} param: {1}' |
| return ValueError(error_msg.format(param, param_value)) |
| |
| |
| def host_config_incompatible_error(param, param_value, incompatible_param): |
| error_msg = '\"{1}\" {0} is incompatible with {2}' |
| return errors.InvalidArgument( |
| error_msg.format(param, param_value, incompatible_param) |
| ) |
| |
| |
| class ContainerConfig(dict): |
| def __init__( |
| self, version, image, command, hostname=None, user=None, detach=False, |
| stdin_open=False, tty=False, ports=None, environment=None, |
| volumes=None, network_disabled=False, entrypoint=None, |
| working_dir=None, domainname=None, host_config=None, mac_address=None, |
| labels=None, stop_signal=None, networking_config=None, |
| healthcheck=None, stop_timeout=None, runtime=None |
| ): |
| |
| if stop_timeout is not None and version_lt(version, '1.25'): |
| raise errors.InvalidVersion( |
| 'stop_timeout was only introduced in API version 1.25' |
| ) |
| |
| if healthcheck is not None: |
| if version_lt(version, '1.24'): |
| raise errors.InvalidVersion( |
| 'Health options were only introduced in API version 1.24' |
| ) |
| |
| if version_lt(version, '1.29') and 'StartPeriod' in healthcheck: |
| raise errors.InvalidVersion( |
| 'healthcheck start period was introduced in API ' |
| 'version 1.29' |
| ) |
| |
| if isinstance(command, six.string_types): |
| command = split_command(command) |
| |
| if isinstance(entrypoint, six.string_types): |
| entrypoint = split_command(entrypoint) |
| |
| if isinstance(environment, dict): |
| environment = format_environment(environment) |
| |
| if isinstance(labels, list): |
| labels = dict((lbl, six.text_type('')) for lbl in labels) |
| |
| 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 healthcheck and isinstance(healthcheck, dict): |
| healthcheck = Healthcheck(**healthcheck) |
| |
| 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 |
| |
| self.update({ |
| 'Hostname': hostname, |
| 'Domainname': domainname, |
| 'ExposedPorts': ports, |
| 'User': six.text_type(user) if user is not None else None, |
| 'Tty': tty, |
| 'OpenStdin': stdin_open, |
| 'StdinOnce': stdin_once, |
| 'AttachStdin': attach_stdin, |
| 'AttachStdout': attach_stdout, |
| 'AttachStderr': attach_stderr, |
| 'Env': environment, |
| 'Cmd': command, |
| 'Image': image, |
| 'Volumes': volumes, |
| 'NetworkDisabled': network_disabled, |
| 'Entrypoint': entrypoint, |
| 'WorkingDir': working_dir, |
| 'HostConfig': host_config, |
| 'NetworkingConfig': networking_config, |
| 'MacAddress': mac_address, |
| 'Labels': labels, |
| 'StopSignal': stop_signal, |
| 'Healthcheck': healthcheck, |
| 'StopTimeout': stop_timeout, |
| 'Runtime': runtime |
| }) |