55import string
66import time
77import urlparse
8+ import base64
89
910from django .conf import settings
1011from docker import Client
120121 {
121122 "name": "$containername",
122123 "image": "quay.io/deisci/slugrunner:v2-alpha",
124+ "imagePullPolicy": "Always",
123125 "env": [
124126 {
125127 "name":"PORT",
140142 {
141143 "name":"DEIS_RELEASE",
142144 "value":"$appversion"
145+ },
146+ {
147+ "name": "DOCKERIMAGE",
148+ "value":"1"
149+ }
150+ ],
151+ "volumeMounts":[
152+ {
153+ "name":"minio-user",
154+ "mountPath":"/var/run/secrets/object/store",
155+ "readOnly":true
143156 }
144157 ]
145158 }
159+ ],
160+ "volumes":[
161+ {
162+ "name":"minio-user",
163+ "secret":{
164+ "secretName":"minio-user"
165+ }
166+ }
146167 ]
147168 }
148169 }
178199}
179200"""
180201
202+ SECRET_TEMPLATE = """\
203+ {
204+ "kind": "Secret",
205+ "apiVersion": "$version",
206+ "metadata": {
207+ "name": "minio-user",
208+ "namespace": "$id"
209+ },
210+ "type": "Opaque",
211+ "data":{
212+ "access-key-id": "$secretId",
213+ "access-secret-key": "$secretKey"
214+ }
215+ }
216+ """
217+
181218MATCH = re .compile (
182219 r'(?P<app>[a-z0-9-]+)_?(?P<version>v[0-9]+)?\.?(?P<c_type>[a-z-_]+)' )
183220
@@ -255,7 +292,8 @@ def _get_rc_(self, name, namespace):
255292 def deploy (self , name , image , command , ** kwargs ):
256293 logger .debug ('deploy {}, img {}, params {}, cmd "{}"' .format (name , image , kwargs , command ))
257294 app_name = kwargs .get ('aname' , {})
258- app_type = name .split ("." )[1 ]
295+ name = name .replace ('.' , '-' ).replace ('_' , '-' )
296+ app_type = name .split ('-' )[- 1 ]
259297 old_rc = self ._get_old_rc (app_name , app_type )
260298 new_rc = self ._create_rc (name , image , command , ** kwargs )
261299 old_temp_rc = old_rc
@@ -401,21 +439,16 @@ def _check_status(self, resp, app_name):
401439 def _create_rc (self , name , image , command , ** kwargs ):
402440 container_fullname = name
403441 app_name = kwargs .get ('aname' , {})
404- app_type = name .split ('. ' )[1 ]
442+ app_type = name .split ('- ' )[- 1 ]
405443 container_name = app_name + '-' + app_type
406- name = name .replace ('.' , '-' ).replace ('_' , '-' )
407444 args = command .split ()
408-
409- # First ensure that the namespace was created
410- url = self ._api ("/namespaces/{}" , app_name )
411- resp = self .session .get (url )
412- self ._check_status (resp , app_name )
413445 num = kwargs .get ('num' , {})
414446 imgurl = self .registry + "/" + image
415447 TEMPLATE = RCD_TEMPLATE
416448 shalen = len (image [image .index (":" )+ 5 :])
417- if image [image .index (":" )+ 1 :image .index (":" )+ 4 ] == "git" and shalen == 8 :
418- imgurl = "http://" + settings .S3EP + "/git/home/" + image + "/slug"
449+ git = image [image .index (":" )+ 1 :image .index (":" )+ 4 ]
450+ if git == "git" and shalen == 8 and app_type == 'web' :
451+ imgurl = "http://" + settings .S3EP + "/git/home/" + image + "/push/slug.tgz"
419452 TEMPLATE = RCB_TEMPLATE
420453 l = {
421454 "name" : name ,
@@ -462,24 +495,20 @@ def _create_rc(self, name, image, command, **kwargs):
462495 if not create and self ._get_rc_status (name , app_name ) == 404 :
463496 time .sleep (1 )
464497 continue
465-
466498 create = True
467499 rc = self ._get_rc_ (name , app_name )
468500 if ("observedGeneration" in rc ["status" ]
469501 and rc ["metadata" ]["generation" ] == rc ["status" ]["observedGeneration" ]):
470502 break
471503
472504 time .sleep (1 )
473-
474505 return resp .json ()
475506
476507 def create (self , name , image , command , ** kwargs ):
477508 """Create a container."""
478509 logger .debug ('create {}, img {}, params {}, cmd "{}"' .format (name , image , kwargs , command ))
479- self ._create_rc (name , image , command , ** kwargs )
480- image = self .registry + '/' + image
481- app_type = name .split ('.' )[1 ]
482510 name = name .replace ('.' , '-' ).replace ('_' , '-' )
511+ app_type = name .split ('-' )[- 1 ]
483512 app_name = kwargs .get ('aname' , {})
484513 try :
485514 # Make sure the router knows what to do with this
@@ -488,9 +517,12 @@ def create(self, name, image, command, **kwargs):
488517 # see http://docs.deis.io/en/latest/using_deis/process-types/#web-vs-cmd-process-types
489518 if app_type in ['web' , 'cmd' ]:
490519 data = {'metadata' : {'labels' : {'routable' : 'true' }}}
491-
520+ self ._create_namespace (app_name )
521+ self ._create_secret (app_name )
522+ self ._create_rc (name , image , command , ** kwargs )
492523 self ._create_service (name , app_name , app_type , data , image = image )
493- except :
524+ except Exception as e :
525+ logger .debug (e )
494526 self ._scale_app (name , 0 , app_name )
495527 self ._delete_rc (name , app_name )
496528 raise
@@ -503,35 +535,51 @@ def _get_service(self, name, namespace):
503535
504536 return response
505537
538+ def _create_secret (self , namespace ):
539+ secretId , secretKey = '' , ''
540+ with open ("/var/run/secrets/deis/minio/user/access-key-id" ) as the_file :
541+ secretId = the_file .read ()
542+ with open ("/var/run/secrets/deis/minio/user/access-secret-key" ) as the_file :
543+ secretKey = the_file .read ()
544+ Key , Id = base64 .b64encode (secretKey ), base64 .b64encode (secretId )
545+ l = {
546+ "version" : self .apiversion ,
547+ "id" : namespace ,
548+ "secretId" : Id ,
549+ "secretKey" : Key ,
550+ }
551+ template = json .loads (string .Template (SECRET_TEMPLATE ).substitute (l ))
552+ url = self ._api ("/namespaces/{}/secrets" , namespace )
553+ resp = self .session .post (url , json = template )
554+ if unhealthy (resp .status_code ):
555+ error (resp , 'failed to create secret in Namespace "{}"' , namespace )
556+
506557 def _create_service (self , name , app_name , app_type , data = {}, ** kwargs ):
507558 docker_cli = Client (version = "auto" )
559+ image = kwargs .get ('image' )
508560 try :
509- image = kwargs . get ( 'image' )
561+ image = self . registry + '/' + image
510562 # image already includes the tag, so we split it out here
511563 docker_cli .pull (image .rsplit (':' )[0 ], image .rsplit (':' )[1 ])
512564 image_info = docker_cli .inspect_image (image )
513565 port = int (image_info ['Config' ]['ExposedPorts' ].keys ()[0 ].split ("/" )[0 ])
514566 except :
515567 port = 5000
516-
517568 l = {
518569 "version" : self .apiversion ,
519570 "port" : port ,
520571 "type" : app_type ,
521572 "name" : app_name ,
522573 }
523-
524574 # Merge external data on to the prefined template
525575 template = json .loads (string .Template (SERVICE_TEMPLATE ).substitute (l ))
526576 data = dict_merge (template , data )
527-
528577 url = self ._api ("/namespaces/{}/services" , app_name )
529578 resp = self .session .post (url , json = data )
530579 if resp .status_code == 409 :
531580 srv = self ._get_service (app_name , app_name ).json ()
532581 if srv ['spec' ]['selector' ]['type' ] == 'web' :
533582 return
534-
535583 srv ['spec' ]['selector' ]['type' ] = app_type
536584 srv ['spec' ]['ports' ][0 ]['targetPort' ] = port
537585 resp2 = self ._update_service (app_name , app_name , srv )
0 commit comments