def test_split_port_with_protocol(self): for protocol in ['tcp', 'udp', 'sctp']: internal_port, external_port = split_port( "127.0.0.1:1000:2000/" + protocol ) assert internal_port == ["2000/" + protocol] assert external_port == [("127.0.0.1", "1000")]
def build_container_ports(container_options, options): ports = [] all_ports = container_options.get("ports", []) + options.get("expose", []) for port_range in all_ports: internal_range, _ = split_port(port_range) for port in internal_range: port = str(port) if "/" in port: port = tuple(port.split("/")) ports.append(port) return ports
def build_container_ports(container_ports, options): ports = [] all_ports = container_ports + options.get('expose', []) for port_range in all_ports: internal_range, _ = split_port(port_range) for port in internal_range: port = str(port) if '/' in port: port = tuple(port.split('/')) ports.append(port) return ports
def make_port_specs(service_dict): ports = [] internal_ports = [ internal_port for port_def in service_dict.get('ports', []) for internal_port in split_port(port_def)[0] ] internal_ports += service_dict.get('expose', []) for internal_port in internal_ports: spec = make_port_spec(internal_port) if spec not in ports: ports.append(spec) return ports
def has_host_port(binding): _, external_bindings = split_port(binding) # there are no external bindings if external_bindings is None: return False # we only need to check the first binding from the range external_binding = external_bindings[0] # non-tuple binding means there is a host port specified if not isinstance(external_binding, tuple): return True # extract actual host port from tuple of (host_ip, host_port) _, host_port = external_binding if host_port is not None: return True return False
def test_port_and_range_invalid(self): with pytest.raises(ValueError): split_port("0.0.0.0:1000:2000-2002/tcp")
def test_host_only_with_colon(self): with pytest.raises(ValueError): split_port("localhost:")
def test_port_and_range_invalid(self): self.assertRaises(ValueError, lambda: split_port("0.0.0.0:1000:2000-2002/tcp"))
def test_split_port_empty_string(self): with pytest.raises(ValueError): split_port("")
def _get_container_create_options(self, override_options, number, one_off=False, previous_container=None): add_config_hash = not one_off and not override_options container_options = dict((k, self.options[k]) for k in DOCKER_CONFIG_KEYS if k in self.options) container_options.update(override_options) if self.custom_container_name() and not one_off: container_options["name"] = self.custom_container_name() elif not container_options.get("name"): container_options["name"] = self.get_container_name(number, one_off) if "detach" not in container_options: container_options["detach"] = True # If a qualified hostname was given, split it into an # unqualified hostname and a domainname unless domainname # was also given explicitly. This matches the behavior of # the official Docker CLI in that scenario. if ( "hostname" in container_options and "domainname" not in container_options and "." in container_options["hostname"] ): parts = container_options["hostname"].partition(".") container_options["hostname"] = parts[0] container_options["domainname"] = parts[2] if "ports" in container_options or "expose" in self.options: ports = [] all_ports = container_options.get("ports", []) + self.options.get("expose", []) for port_range in all_ports: internal_range, _ = split_port(port_range) for port in internal_range: port = str(port) if "/" in port: port = tuple(port.split("/")) ports.append(port) container_options["ports"] = ports override_options["binds"] = merge_volume_bindings(container_options.get("volumes") or [], previous_container) if "volumes" in container_options: container_options["volumes"] = dict((v.internal, {}) for v in container_options["volumes"]) container_options["environment"] = merge_environment( self.options.get("environment"), override_options.get("environment") ) if previous_container: container_options["environment"]["affinity:container"] = "=" + previous_container.id container_options["image"] = self.image_name container_options["labels"] = build_container_labels( container_options.get("labels", {}), self.labels(one_off=one_off), number, self.config_hash if add_config_hash else None, ) # Delete options which are only used when starting for key in DOCKER_START_KEYS: container_options.pop(key, None) container_options["host_config"] = self._get_container_host_config(override_options, one_off=one_off) return container_options
def test_split_port_with_host_port(self): internal_port, external_port = split_port("1000:2000") self.assertEqual(internal_port, ["2000"]) self.assertEqual(external_port, ["1000"])
def test_split_port_empty_string(self): self.assertRaises(ValueError, lambda: split_port(""))
def test_split_port_invalid(self): self.assertRaises(ValueError, lambda: split_port("0.0.0.0:1000:2000:tcp"))
def test_non_matching_length_port_ranges(self): self.assertRaises( ValueError, lambda: split_port("0.0.0.0:1000-1010:2000-2002/tcp"))
def test_split_port_range_with_protocol(self): internal_port, external_port = split_port( "127.0.0.1:1000-1001:2000-2001/udp") self.assertEqual(internal_port, ["2000/udp", "2001/udp"]) self.assertEqual(external_port, [("127.0.0.1", "1000"), ("127.0.0.1", "1001")])
def test_split_port_range_no_host_port(self): internal_port, external_port = split_port("2000-2001") self.assertEqual(internal_port, ["2000", "2001"]) self.assertEqual(external_port, None)
def test_split_port_range_with_host_port(self): internal_port, external_port = split_port("1000-1001:2000-2001") self.assertEqual(internal_port, ["2000", "2001"]) self.assertEqual(external_port, ["1000", "1001"])
def test_port_only_with_colon(self): self.assertRaises(ValueError, lambda: split_port(":80"))
def test_split_port_with_ipv6_address(self): internal_port, external_port = split_port( "2001:abcd:ef00::2:1000:2000") self.assertEqual(internal_port, ["2000"]) self.assertEqual(external_port, [("2001:abcd:ef00::2", "1000")])
def test_host_only_with_colon(self): self.assertRaises(ValueError, lambda: split_port("localhost:"))
def format_ports(instance): try: split_port(instance) except ValueError as e: raise ValidationError(six.text_type(e)) return True
def test_split_port_non_string(self): assert split_port(1243) == (['1243'], None)
def format_ports(instance): try: split_port(instance) except ValueError: return False return True
def test_split_port_with_host_ip(self): internal_port, external_port = split_port("127.0.0.1:1000:2000") assert internal_port == ["2000"] assert external_port == [("127.0.0.1", "1000")]
def test_split_port_with_protocol(self): for protocol in ['tcp', 'udp', 'sctp']: internal_port, external_port = split_port("127.0.0.1:1000:2000/" + protocol) assert internal_port == ["2000/" + protocol] assert external_port == [("127.0.0.1", "1000")]
def test_non_matching_length_port_ranges(self): with pytest.raises(ValueError): split_port("0.0.0.0:1000-1010:2000-2002/tcp")
def test_split_port_range_with_host_ip_no_port(self): internal_port, external_port = split_port("127.0.0.1::2000-2001") assert internal_port == ["2000", "2001"] assert external_port == [("127.0.0.1", None), ("127.0.0.1", None)]
def test_port_only_with_colon(self): with pytest.raises(ValueError): split_port(":80")
def test_split_port_with_host_port(self): internal_port, external_port = split_port("1000:2000") assert internal_port == ["2000"] assert external_port == ["1000"]
def test_with_no_container_port(self): with pytest.raises(ValueError): split_port("localhost:80:")
def test_split_port_random_port_range_with_host_port(self): internal_port, external_port = split_port("1000-1001:2000") assert internal_port == ["2000"] assert external_port == ["1000-1001"]
def test_split_port_with_host_ip(self): internal_port, external_port = split_port("127.0.0.1:1000:2000") self.assertEqual(internal_port, ["2000"]) self.assertEqual(external_port, [("127.0.0.1", "1000")])
def test_split_port_no_host_port(self): internal_port, external_port = split_port("2000") assert internal_port == ["2000"] assert external_port is None
def test_with_no_container_port(self): self.assertRaises(ValueError, lambda: split_port("localhost:80:"))
def test_split_port_range_no_host_port(self): internal_port, external_port = split_port("2000-2001") assert internal_port == ["2000", "2001"] assert external_port is None
def _get_container_create_options(self, override_options, number, one_off=False, previous_container=None): add_config_hash = (not one_off and not override_options) container_options = dict((k, self.options[k]) for k in DOCKER_CONFIG_KEYS if k in self.options) container_options.update(override_options) if self.custom_container_name() and not one_off: container_options['name'] = self.custom_container_name() elif not container_options.get('name'): container_options['name'] = self.get_container_name( number, one_off) if 'detach' not in container_options: container_options['detach'] = True # If a qualified hostname was given, split it into an # unqualified hostname and a domainname unless domainname # was also given explicitly. This matches the behavior of # the official Docker CLI in that scenario. if ('hostname' in container_options and 'domainname' not in container_options and '.' in container_options['hostname']): parts = container_options['hostname'].partition('.') container_options['hostname'] = parts[0] container_options['domainname'] = parts[2] if 'ports' in container_options or 'expose' in self.options: ports = [] all_ports = container_options.get('ports', []) + self.options.get( 'expose', []) for port_range in all_ports: internal_range, _ = split_port(port_range) for port in internal_range: port = str(port) if '/' in port: port = tuple(port.split('/')) ports.append(port) container_options['ports'] = ports override_options['binds'] = merge_volume_bindings( container_options.get('volumes') or [], previous_container) if 'volumes' in container_options: container_options['volumes'] = dict( (v.internal, {}) for v in container_options['volumes']) container_options['environment'] = merge_environment( self.options.get('environment'), override_options.get('environment')) if previous_container: container_options['environment']['affinity:container'] = ( '=' + previous_container.id) container_options['image'] = self.image_name container_options['labels'] = build_container_labels( container_options.get('labels', {}), self.labels(one_off=one_off), number, self.config_hash if add_config_hash else None) # Delete options which are only used when starting for key in DOCKER_START_KEYS: container_options.pop(key, None) container_options['host_config'] = self._get_container_host_config( override_options, one_off=one_off) return container_options
def _get_container_create_options( self, override_options, number, one_off=False, previous_container=None): add_config_hash = (not one_off and not override_options) container_options = dict( (k, self.options[k]) for k in DOCKER_CONFIG_KEYS if k in self.options) container_options.update(override_options) if self.custom_container_name() and not one_off: container_options['name'] = self.custom_container_name() elif not container_options.get('name'): container_options['name'] = self.get_container_name(number, one_off) if 'detach' not in container_options: container_options['detach'] = True # If a qualified hostname was given, split it into an # unqualified hostname and a domainname unless domainname # was also given explicitly. This matches the behavior of # the official Docker CLI in that scenario. if ('hostname' in container_options and 'domainname' not in container_options and '.' in container_options['hostname']): parts = container_options['hostname'].partition('.') container_options['hostname'] = parts[0] container_options['domainname'] = parts[2] if 'hostname' not in container_options and self.use_networking: container_options['hostname'] = self.name if 'ports' in container_options or 'expose' in self.options: ports = [] all_ports = container_options.get('ports', []) + self.options.get('expose', []) for port_range in all_ports: internal_range, _ = split_port(port_range) for port in internal_range: port = str(port) if '/' in port: port = tuple(port.split('/')) ports.append(port) container_options['ports'] = ports override_options['binds'] = merge_volume_bindings( container_options.get('volumes') or [], previous_container) if 'volumes' in container_options: container_options['volumes'] = dict( (parse_volume_spec(v).internal, {}) for v in container_options['volumes']) container_options['environment'] = merge_environment( self.options.get('environment'), override_options.get('environment')) if previous_container: container_options['environment']['affinity:container'] = ('=' + previous_container.id) container_options['image'] = self.image_name container_options['labels'] = build_container_labels( container_options.get('labels', {}), self.labels(one_off=one_off), number, self.config_hash if add_config_hash else None) # Delete options which are only used when starting for key in DOCKER_START_KEYS: container_options.pop(key, None) container_options['host_config'] = self._get_container_host_config( override_options, one_off=one_off) return container_options
def test_split_port_range_with_protocol(self): internal_port, external_port = split_port( "127.0.0.1:1000-1001:2000-2001/udp") assert internal_port == ["2000/udp", "2001/udp"] assert external_port == [("127.0.0.1", "1000"), ("127.0.0.1", "1001")]
def test_split_port_range_with_host_ip_no_port(self): internal_port, external_port = split_port("127.0.0.1::2000-2001") self.assertEqual(internal_port, ["2000", "2001"]) self.assertEqual(external_port, [("127.0.0.1", None), ("127.0.0.1", None)])
def test_split_port_with_ipv6_address(self): internal_port, external_port = split_port( "2001:abcd:ef00::2:1000:2000") assert internal_port == ["2000"] assert external_port == [("2001:abcd:ef00::2", "1000")]
def test_split_port_invalid(self): with pytest.raises(ValueError): split_port("0.0.0.0:1000:2000:tcp")
def test_split_port_invalid_protocol(self): with pytest.raises(ValueError): split_port("0.0.0.0:1000:2000/ftp")
def test_non_matching_length_port_ranges(self): self.assertRaises( ValueError, lambda: split_port("0.0.0.0:1000-1010:2000-2002/tcp") )