1111import requests
1212import string
1313import time
14+ import uuid
1415from urllib .parse import urljoin
1516
1617from django .conf import settings
2526from api .models .release import Release
2627from api .models .tls import TLS
2728from api .models .appsettings import AppSettings
29+ from api .models .volume import Volume
2830from api .utils import generate_app_name , async_run
2931from scheduler import KubeHTTPException , KubeException
3032
@@ -497,7 +499,7 @@ def scale(self, user, structure): # noqa
497499 def _scale_pods (self , scale_types ):
498500 release = self .release_set .filter (failed = False ).latest ()
499501 app_settings = self .appsettings_set .latest ()
500-
502+ volumes = Volume . objects . filter ( app = self , path__isnull = False )
501503 # use slugrunner image for app if buildpack app otherwise use normal image
502504 if release .build .type == 'buildpack' :
503505 image = next (filter (lambda item : item ['name' ] == release .build .stack ,
@@ -507,7 +509,8 @@ def _scale_pods(self, scale_types):
507509
508510 tasks = []
509511 for scale_type , replicas in scale_types .items ():
510- data = self ._gather_app_settings (release , app_settings , scale_type , replicas ) # noqa
512+ scale_type_volumes = [_ for _ in volumes if scale_type in _ .path .keys ()]
513+ data = self ._gather_app_settings (release , app_settings , scale_type , replicas , volumes = scale_type_volumes ) # noqa
511514
512515 # gather all proc types to be deployed
513516 tasks .append (
@@ -577,9 +580,11 @@ def deploy(self, release, force_deploy=False, rollback_on_failure=True): # noqa
577580
578581 # deploy application to k8s. Also handles initial scaling
579582 app_settings = self .appsettings_set .latest ()
583+ volumes = self .volume_set .all ()
580584 deploys = {}
581585 for scale_type , replicas in self .structure .items ():
582- deploys [scale_type ] = self ._gather_app_settings (release , app_settings , scale_type , replicas ) # noqa
586+ volumes = [_ for _ in volumes if scale_type in _ .path .keys ()]
587+ deploys [scale_type ] = self ._gather_app_settings (release , app_settings , scale_type , replicas , volumes = volumes ) # noqa
583588
584589 # Sort deploys so routable comes first
585590 deploys = OrderedDict (sorted (deploys .items (), key = lambda d : d [1 ].get ('routable' )))
@@ -798,7 +803,7 @@ def logs(self, log_lines=str(settings.LOG_LINES)):
798803 # cast content to string since it comes as bytes via the requests object
799804 return str (r .content .decode ('utf-8' ))
800805
801- def run (self , user , command ):
806+ def run (self , user , command , volumes = None ):
802807 def pod_name (size = 5 , chars = string .ascii_lowercase + string .digits ):
803808 return '' .join (random .choice (chars ) for _ in range (size ))
804809
@@ -814,8 +819,13 @@ def pod_name(size=5, chars=string.ascii_lowercase + string.digits):
814819 settings .SLUGRUNNER_IMAGES ))['image' ]
815820 else :
816821 image = release .image
817-
818- data = self ._gather_app_settings (release , app_settings , process_type = 'run' , replicas = 1 )
822+ volume_list = []
823+ if volumes :
824+ volume_objs = Volume .objects .filter (app = release .app , name__in = volumes .keys ())
825+ for _ in volume_objs :
826+ _ .path ["{}-{}" .format (self .app .id , str (uuid .uuid4 ())[:7 ])] = volumes .get (_ .name , None ) # noqa
827+ volume_list .append (_ )
828+ data = self ._gather_app_settings (release , app_settings , process_type = 'run' , replicas = 1 , volumes = volume_list ) # noqa
819829
820830 # create application config and build the pod manifest
821831 self .set_application_config (release )
@@ -1076,7 +1086,7 @@ def _get_private_registry_config(self, image, registry=None):
10761086 })
10771087 return docker_config , name , True
10781088
1079- def _gather_app_settings (self , release , app_settings , process_type , replicas ):
1089+ def _gather_app_settings (self , release , app_settings , process_type , replicas , volumes = None ):
10801090 """
10811091 Gathers all required information needed in one easy place for passing into
10821092 the Kubernetes client to deploy an application
@@ -1116,6 +1126,15 @@ def _gather_app_settings(self, release, app_settings, process_type, replicas):
11161126 healthcheck = config .get_healthcheck ().get (process_type , {})
11171127 if not healthcheck and process_type in ['web' , 'cmd' ]:
11181128 healthcheck = config .get_healthcheck ().get ('web/cmd' , {})
1129+ volumes_info = [{
1130+ "name" : _ .name ,
1131+ "claimName" : _ .name ,
1132+ } for _ in volumes ] if volumes else []
1133+
1134+ volume_mounts_info = [{
1135+ "name" : _ .name ,
1136+ "mount_path" : _ .path .get (process_type ),
1137+ } for _ in volumes ] if volumes else []
11191138
11201139 return {
11211140 'memory' : config .memory ,
@@ -1140,6 +1159,8 @@ def _gather_app_settings(self, release, app_settings, process_type, replicas):
11401159 'pod_termination_grace_period_each' : config .termination_grace_period ,
11411160 'image_pull_secret_name' : image_pull_secret_name ,
11421161 'image_pull_policy' : image_pull_policy ,
1162+ 'volumes' : volumes_info ,
1163+ 'volume_mounts' : volume_mounts_info ,
11431164 }
11441165
11451166 def set_application_config (self , release ):
0 commit comments