Skip to content

Commit fdc72ca

Browse files
author
Keerthan Mala
committed
fix(port): retry a fixed number of times to find the port
1 parent 370c21a commit fdc72ca

1 file changed

Lines changed: 40 additions & 20 deletions

File tree

rootfs/scheduler/__init__.py

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,22 @@ def __init__(self):
347347
def deploy(self, namespace, name, image, command, **kwargs): # noqa
348348
logger.debug('deploy {}, img {}, params {}, cmd "{}"'.format(name, image, kwargs, command))
349349
app_type = kwargs.get('app_type')
350+
build_type = kwargs.get('build_type')
350351
routable = kwargs.get('routable', False)
352+
port = None
353+
354+
try:
355+
if routable:
356+
if build_type == "buildpack":
357+
logger.debug("Using default port 5000 for build pack app {}".format(name))
358+
port = 5000
359+
else:
360+
port = self._get_port(image)
361+
if port is None:
362+
raise Exception("Expose a port or make the app non routable by changing"
363+
" the process type")
364+
except Exception as e:
365+
raise KubeException('{} (scheduler::deploy): {}'.format(name, e))
351366

352367
# Fetch old RC and create the new one for a release
353368
old_rc = self._get_old_rc(namespace, app_type)
@@ -425,9 +440,9 @@ def deploy(self, namespace, name, image, command, **kwargs): # noqa
425440
# Make sure the application is routable and uses the correct port
426441
# Done after the fact to let initial deploy settle before routing
427442
# traffic to the application
428-
self._update_application_service(namespace, name, app_type, image, routable)
443+
self._update_application_service(namespace, name, app_type, port, routable)
429444

430-
def _update_application_service(self, namespace, name, app_type, image, routable=False):
445+
def _update_application_service(self, namespace, name, app_type, port, routable=False):
431446
"""Update application service with all the various required information"""
432447
try:
433448
# Fetch service
@@ -444,10 +459,6 @@ def _update_application_service(self, namespace, name, app_type, image, routable
444459

445460
# Find if target port exists already, update / create as required
446461
if routable:
447-
port = self._get_port(image)
448-
if port is None:
449-
logger.debug("Failed to find port for Docker image {}, defaulting to 5000".format(image)) # noqa
450-
port = 5000
451462
for pos, item in enumerate(service['spec']['ports']):
452463
if item['port'] == 80 and port != item['targetPort']:
453464
# port 80 is the only one we care about right now
@@ -690,18 +701,24 @@ def resolve_state(self, pod):
690701
return states.get(pod_state, pod_state)
691702

692703
def _get_port(self, image):
693-
try:
694-
image = self.registry + '/' + image
695-
repo = image.split(":")
696-
# image already includes the tag, so we split it out here
697-
docker_cli = Client(version="auto")
698-
docker_cli.pull(repo[0]+":"+repo[1], tag=repo[2], insecure_registry=True)
699-
image_info = docker_cli.inspect_image(image)
700-
port = int(list(image_info['Config']['ExposedPorts'].keys())[0].split("/")[0])
701-
except Exception:
702-
port = None
703-
704-
return port
704+
# try thrice to find the port before raising exception as docker-py is flaky
705+
for i in range(3):
706+
try:
707+
imagepath = self.registry + '/' + image
708+
repo = imagepath.split(":")
709+
# image already includes the tag, so we split it out here
710+
docker_cli = Client(version="auto")
711+
docker_cli.pull(repo[0]+":"+repo[1], tag=repo[2], insecure_registry=True)
712+
image_info = docker_cli.inspect_image(imagepath)
713+
if 'ExposedPorts' not in image_info['Config']:
714+
return None
715+
port = int(list(image_info['Config']['ExposedPorts'].keys())[0].split("/")[0])
716+
return port
717+
except Exception:
718+
if i == 2:
719+
raise
720+
else:
721+
continue
705722

706723
def _api(self, tmpl, *args):
707724
"""Return a fully-qualified Kubernetes API URL from a string template with args."""
@@ -1199,8 +1216,11 @@ def _default_buildpack_readiness_probe(self, delay=30, timeout=5, period_seconds
11991216
'''
12001217
def _default_dockerapp_readiness_probe(self, image, delay=5, timeout=5, period_seconds=5,
12011218
success_threshold=1, failure_threshold=1):
1202-
port = self._get_port(image)
1203-
if port is None:
1219+
try:
1220+
port = self._get_port(image)
1221+
if port is None:
1222+
return None
1223+
except Exception:
12041224
return None
12051225
readinessprobe = {
12061226
'readinessProbe': {

0 commit comments

Comments
 (0)