X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/0ea1f67f70f942c4732f2269e31c3ddb7d63fc9e..17ac6b9f8462d63b1162a96f4c182ccc29217c5c:/sdk/python/arvados/keep.py diff --git a/sdk/python/arvados/keep.py b/sdk/python/arvados/keep.py index 778b90912c..db7835be37 100644 --- a/sdk/python/arvados/keep.py +++ b/sdk/python/arvados/keep.py @@ -9,8 +9,10 @@ import Queue import re import socket import ssl +import sys import threading import timer +import urlparse import arvados import arvados.config as config @@ -22,6 +24,17 @@ _logger = logging.getLogger('arvados.keep') global_client_object = None +# Monkey patch TCP constants when not available (apple). Values sourced from: +# http://www.opensource.apple.com/source/xnu/xnu-2422.115.4/bsd/netinet/tcp.h +if sys.platform == 'darwin': + if not hasattr(socket, 'TCP_KEEPALIVE'): + socket.TCP_KEEPALIVE = 0x010 + if not hasattr(socket, 'TCP_KEEPINTVL'): + socket.TCP_KEEPINTVL = 0x101 + if not hasattr(socket, 'TCP_KEEPCNT'): + socket.TCP_KEEPCNT = 0x102 + + class KeepLocator(object): EPOCH_DATETIME = datetime.datetime.utcfromtimestamp(0) HINT_RE = re.compile(r'^[A-Z][A-Za-z0-9@_-]+$') @@ -299,7 +312,9 @@ class KeepClient(object): """Because pycurl doesn't have CURLOPT_TCP_KEEPALIVE""" s = socket.socket(family, socktype, protocol) s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) - s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 75) + # Will throw invalid protocol error on mac. This test prevents that. + if hasattr(socket, 'TCP_KEEPIDLE'): + s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 75) s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 75) return s @@ -621,8 +636,9 @@ class KeepClient(object): :proxy: If specified, this KeepClient will send requests to this Keep proxy. Otherwise, KeepClient will fall back to the setting of the - ARVADOS_KEEP_PROXY configuration setting. If you want to ensure - KeepClient does not use a proxy, pass in an empty string. + ARVADOS_KEEP_SERVICES or ARVADOS_KEEP_PROXY configuration settings. + If you want to KeepClient does not use a proxy, pass in an empty + string. :timeout: The initial timeout (in seconds) for HTTP requests to Keep @@ -665,7 +681,10 @@ class KeepClient(object): """ self.lock = threading.Lock() if proxy is None: - proxy = config.get('ARVADOS_KEEP_PROXY') + if config.get('ARVADOS_KEEP_SERVICES'): + proxy = config.get('ARVADOS_KEEP_SERVICES') + else: + proxy = config.get('ARVADOS_KEEP_PROXY') if api_token is None: if api_client is None: api_token = config.get('ARVADOS_API_TOKEN') @@ -696,15 +715,21 @@ class KeepClient(object): self.num_retries = num_retries self.max_replicas_per_service = None if proxy: - if not proxy.endswith('/'): - proxy += '/' + proxy_uris = proxy.split() + for i in range(len(proxy_uris)): + if not proxy_uris[i].endswith('/'): + proxy_uris[i] += '/' + # URL validation + url = urlparse.urlparse(proxy_uris[i]) + if not (url.scheme and url.netloc): + raise arvados.errors.ArgumentError("Invalid proxy URI: {}".format(proxy_uris[i])) self.api_token = api_token self._gateway_services = {} self._keep_services = [{ - 'uuid': 'proxy', + 'uuid': "00000-bi6l4-%015d" % idx, 'service_type': 'proxy', - '_service_root': proxy, - }] + '_service_root': uri, + } for idx, uri in enumerate(proxy_uris)] self._writable_services = self._keep_services self.using_proxy = True self._static_services_list = True