Kaydet (Commit) cf050d28 authored tarafından Joffrey F's avatar Joffrey F

Implemented complete parse_host method to handle all accepted values of Client's…

Implemented complete parse_host method to handle all accepted values of Client's base_url. Unit tests
üst 91702191
......@@ -39,16 +39,9 @@ class Client(requests.Session):
def __init__(self, base_url=None, version=DEFAULT_DOCKER_API_VERSION,
timeout=DEFAULT_TIMEOUT_SECONDS):
super(Client, self).__init__()
if base_url is None:
base_url = "http+unix://var/run/docker.sock"
if 'unix:///' in base_url:
base_url = utils.parse_host(base_url)
if 'http+unix:///' in base_url:
base_url = base_url.replace('unix:/', 'unix:')
if base_url.startswith('unix:'):
base_url = "http+" + base_url
if base_url.startswith('tcp:'):
base_url = base_url.replace('tcp:', 'http:')
if base_url.endswith('/'):
base_url = base_url[:-1]
self.base_url = base_url
self._version = version
self._timeout = timeout
......
from .utils import (
compare_version, convert_port_bindings, convert_volume_binds,
mkbuildcontext, ping, tar, parse_repository_tag
mkbuildcontext, ping, tar, parse_repository_tag, parse_host
) # flake8: noqa
......@@ -20,6 +20,11 @@ from distutils.version import StrictVersion
import requests
import six
from .. import errors
DEFAULT_HTTP_HOST = "127.0.0.1"
DEFAULT_UNIX_SOCKET = "http+unix://var/run/docker.sock"
def mkbuildcontext(dockerfile):
f = tempfile.NamedTemporaryFile()
......@@ -139,9 +144,69 @@ def parse_repository_tag(repo):
column_index = repo.rfind(':')
if column_index < 0:
return repo, None
tag = repo[column_index+1:]
tag = repo[column_index + 1:]
slash_index = tag.find('/')
if slash_index < 0:
return repo[:column_index], tag
return repo, None
# Based on utils.go:ParseHost http://tinyurl.com/nkahcfh
# fd:// protocol unsupported (for obvious reasons)
# Added support for http and https
# Protocol translation: tcp -> http, unix -> http+unix
def parse_host(addr):
proto = "http+unix"
host = DEFAULT_HTTP_HOST
port = None
if not addr or addr.strip() == 'unix://':
return DEFAULT_UNIX_SOCKET
addr = addr.strip()
if addr.startswith('http://'):
addr = addr.replace('http://', 'tcp://')
if addr == 'tcp://':
raise errors.DockerException("Invalid bind address format: %s" % addr)
elif addr.startswith('unix://'):
addr = addr[7:]
elif addr.startswith('tcp://'):
proto = "http"
addr = addr[6:]
elif addr.startswith('https://'):
proto = "https"
addr = addr[8:]
elif addr.startswith('fd://'):
raise errors.DockerException("fd protocol is not implemented")
else:
if "://" in addr:
raise errors.DockerException(
"Invalid bind address protocol: %s" % addr
)
proto = "http"
if proto != "http+unix" and ":" in addr:
host_parts = addr.split(':')
if len(host_parts) != 2:
raise errors.DockerException(
"Invalid bind address format: %s" % addr
)
if host_parts[0]:
host = host_parts[0]
try:
port = int(host_parts[1])
except Exception:
raise errors.DockerException(
"Invalid port: %s", addr
)
elif proto in ("http", "https") and ':' not in addr:
raise errors.DockerException("Bind address needs a port: %s" % addr)
else:
host = addr
if proto == "http+unix":
return "%s://%s" % (proto, host)
return "%s://%s:%d" % (proto, host, port)
import unittest
from docker.utils import parse_repository_tag
from docker.errors import DockerException
from docker.utils import parse_repository_tag, parse_host
class UtilsTest(unittest.TestCase):
longMessage = True
def test_parse_repository_tag(self):
self.assertEqual(parse_repository_tag("root"),
......@@ -19,6 +21,37 @@ class UtilsTest(unittest.TestCase):
self.assertEqual(parse_repository_tag("url:5000/repo:tag"),
("url:5000/repo", "tag"))
def test_parse_host(self):
invalid_hosts = [
'0.0.0.0',
'tcp://',
'udp://127.0.0.1',
'udp://127.0.0.1:2375',
]
valid_hosts = {
'0.0.0.1:5555': 'http://0.0.0.1:5555',
':6666': 'http://127.0.0.1:6666',
'tcp://:7777': 'http://127.0.0.1:7777',
'http://:7777': 'http://127.0.0.1:7777',
'https://kokia.jp:2375': 'https://kokia.jp:2375',
'': 'http+unix://var/run/docker.sock',
None: 'http+unix://var/run/docker.sock',
'unix:///var/run/docker.sock': 'http+unix:///var/run/docker.sock',
'unix://': 'http+unix://var/run/docker.sock'
}
for host in invalid_hosts:
try:
parsed = parse_host(host)
self.fail('Expected to fail but success: %s -> %s' % (
host, parsed
))
except DockerException:
pass
for host, expected in valid_hosts.items():
self.assertEqual(parse_host(host), expected, msg=host)
if __name__ == '__main__':
unittest.main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment