Add support for IPv6 docker host connections.

Signed-off-by: Joffrey F <joffrey@docker.com>
This commit is contained in:
Joffrey F 2016-07-27 18:42:14 -07:00
parent 2d3bda84de
commit 723d144db5
2 changed files with 27 additions and 21 deletions

View File

@ -22,8 +22,8 @@ import tarfile
import tempfile import tempfile
import warnings import warnings
from distutils.version import StrictVersion from distutils.version import StrictVersion
from fnmatch import fnmatch
from datetime import datetime from datetime import datetime
from fnmatch import fnmatch
import requests import requests
import six import six
@ -33,6 +33,10 @@ from .. import errors
from .. import tls from .. import tls
from .types import Ulimit, LogConfig from .types import Ulimit, LogConfig
if six.PY2:
from urllib import splitnport
else:
from urllib.parse import splitnport
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"
@ -387,7 +391,6 @@ def parse_repository_tag(repo_name):
# Protocol translation: tcp -> http, unix -> http+unix # Protocol translation: tcp -> http, unix -> http+unix
def parse_host(addr, is_win32=False, tls=False): def parse_host(addr, is_win32=False, tls=False):
proto = "http+unix" proto = "http+unix"
host = DEFAULT_HTTP_HOST
port = None port = None
path = '' path = ''
@ -427,32 +430,27 @@ def parse_host(addr, is_win32=False, tls=False):
) )
proto = "https" if tls else "http" proto = "https" if tls else "http"
if proto != "http+unix" and ":" in addr: if proto in ("http", "https"):
host_parts = addr.split(':') address_parts = addr.split('/', 1)
if len(host_parts) != 2: host = address_parts[0]
raise errors.DockerException( if len(address_parts) == 2:
"Invalid bind address format: {0}".format(addr) path = '/' + address_parts[1]
) host, port = splitnport(host)
if host_parts[0]:
host = host_parts[0]
port = host_parts[1] if port is None:
if '/' in port:
port, path = port.split('/', 1)
path = '/{0}'.format(path)
try:
port = int(port)
except Exception:
raise errors.DockerException( raise errors.DockerException(
"Invalid port: {0}".format(addr) "Invalid port: {0}".format(addr)
) )
elif proto in ("http", "https") and ':' not in addr: if not host:
raise errors.DockerException( host = DEFAULT_HTTP_HOST
"Bind address needs a port: {0}".format(addr))
else: else:
host = addr host = addr
if proto in ("http", "https") and port == -1:
raise errors.DockerException(
"Bind address needs a port: {0}".format(addr))
if proto == "http+unix" or proto == 'npipe': if proto == "http+unix" or proto == 'npipe':
return "{0}://{1}".format(proto, host) return "{0}://{1}".format(proto, host)
return "{0}://{1}:{2}{3}".format(proto, host, port, path) return "{0}://{1}:{2}{3}".format(proto, host, port, path)

View File

@ -404,10 +404,18 @@ class ParseHostTest(base.BaseTestCase):
'https://kokia.jp:2375': 'https://kokia.jp:2375', 'https://kokia.jp:2375': 'https://kokia.jp:2375',
'unix:///var/run/docker.sock': 'http+unix:///var/run/docker.sock', 'unix:///var/run/docker.sock': 'http+unix:///var/run/docker.sock',
'unix://': 'http+unix://var/run/docker.sock', 'unix://': 'http+unix://var/run/docker.sock',
'12.234.45.127:2375/docker/engine': (
'http://12.234.45.127:2375/docker/engine'
),
'somehost.net:80/service/swarm': ( 'somehost.net:80/service/swarm': (
'http://somehost.net:80/service/swarm' 'http://somehost.net:80/service/swarm'
), ),
'npipe:////./pipe/docker_engine': 'npipe:////./pipe/docker_engine', 'npipe:////./pipe/docker_engine': 'npipe:////./pipe/docker_engine',
'[fd12::82d1]:2375': 'http://[fd12::82d1]:2375',
'https://[fd12:5672::12aa]:1090': 'https://[fd12:5672::12aa]:1090',
'[fd12::82d1]:2375/docker/engine': (
'http://[fd12::82d1]:2375/docker/engine'
),
} }
for host in invalid_hosts: for host in invalid_hosts:
@ -415,7 +423,7 @@ class ParseHostTest(base.BaseTestCase):
parse_host(host, None) parse_host(host, None)
for host, expected in valid_hosts.items(): for host, expected in valid_hosts.items():
self.assertEqual(parse_host(host, None), expected, msg=host) assert parse_host(host, None) == expected
def test_parse_host_empty_value(self): def test_parse_host_empty_value(self):
unix_socket = 'http+unix://var/run/docker.sock' unix_socket = 'http+unix://var/run/docker.sock'