1313import requests
1414from requests_toolbelt import user_agent
1515from .utils import dict_merge
16+ from retrying import retry
1617
1718from deis import __version__ as deis_version
1819
@@ -347,7 +348,22 @@ def __init__(self):
347348 def deploy (self , namespace , name , image , command , ** kwargs ): # noqa
348349 logger .debug ('deploy {}, img {}, params {}, cmd "{}"' .format (name , image , kwargs , command ))
349350 app_type = kwargs .get ('app_type' )
351+ build_type = kwargs .get ('build_type' )
350352 routable = kwargs .get ('routable' , False )
353+ port = None
354+
355+ try :
356+ if routable :
357+ if build_type == "buildpack" :
358+ logger .debug ("Using default port 5000 for build pack app {}" .format (name ))
359+ port = 5000
360+ else :
361+ port = self ._get_port (image )
362+ if port is None :
363+ raise Exception ("Expose a port or make the app non routable by changing"
364+ " the process type" )
365+ except Exception as e :
366+ raise KubeException ('{} (scheduler::deploy): {}' .format (name , e ))
351367
352368 # Fetch old RC and create the new one for a release
353369 old_rc = self ._get_old_rc (namespace , app_type )
@@ -425,9 +441,9 @@ def deploy(self, namespace, name, image, command, **kwargs): # noqa
425441 # Make sure the application is routable and uses the correct port
426442 # Done after the fact to let initial deploy settle before routing
427443 # traffic to the application
428- self ._update_application_service (namespace , name , app_type , image , routable )
444+ self ._update_application_service (namespace , name , app_type , port , routable )
429445
430- def _update_application_service (self , namespace , name , app_type , image , routable = False ):
446+ def _update_application_service (self , namespace , name , app_type , port , routable = False ):
431447 """Update application service with all the various required information"""
432448 try :
433449 # Fetch service
@@ -444,10 +460,6 @@ def _update_application_service(self, namespace, name, app_type, image, routable
444460
445461 # Find if target port exists already, update / create as required
446462 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
451463 for pos , item in enumerate (service ['spec' ]['ports' ]):
452464 if item ['port' ] == 80 and port != item ['targetPort' ]:
453465 # port 80 is the only one we care about right now
@@ -689,18 +701,18 @@ def resolve_state(self, pod):
689701
690702 return states .get (pod_state , pod_state )
691703
704+ @retry (stop_max_attempt_number = 3 , wait_fixed = 1000 )
692705 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-
706+ # try thrice to find the port before raising exception as docker-py is flaky
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 ])
704716 return port
705717
706718 def _api (self , tmpl , * args ):
@@ -1199,8 +1211,11 @@ def _default_buildpack_readiness_probe(self, delay=30, timeout=5, period_seconds
11991211 '''
12001212 def _default_dockerapp_readiness_probe (self , image , delay = 5 , timeout = 5 , period_seconds = 5 ,
12011213 success_threshold = 1 , failure_threshold = 1 ):
1202- port = self ._get_port (image )
1203- if port is None :
1214+ try :
1215+ port = self ._get_port (image )
1216+ if port is None :
1217+ return None
1218+ except Exception :
12041219 return None
12051220 readinessprobe = {
12061221 'readinessProbe' : {
0 commit comments