@@ -204,23 +204,64 @@ def _init_static_images(self, base_image_name):
204204 )
205205
206206 def _assign_static_build_dependencies (self , helm_values ):
207+ static_consumers = {}
207208 for static_img_dockerfile in self .static_images :
208209 key = os .path .basename (static_img_dockerfile )
209210 if key in helm_values [KEY_TASK_IMAGES ]:
210211 dependencies = guess_build_dependencies_from_dockerfile (
211212 f"{ static_img_dockerfile } " )
212213 for dep in dependencies :
214+ if dep in self .exclude and dep in helm_values [KEY_TASK_IMAGES ] and key not in self .exclude :
215+ static_consumers .setdefault (dep , set ()).add (key )
213216 if dep in self .base_images and dep not in helm_values [KEY_TASK_IMAGES ]:
214217 helm_values [KEY_TASK_IMAGES ][dep ] = self .base_images [dep ]
215218 # helm_values.setdefault(KEY_TASK_IMAGES_BUILD, {})[dep] = {
216219 # 'context': os.path.relpath(static_img_dockerfile, self.dest_deployment_path.parent),
217220 # 'dockerfile': 'Dockerfile',
218221 # }
219222
220- for image_name in list (helm_values [KEY_TASK_IMAGES ].keys ()):
221- if image_name in self .exclude :
222- del helm_values [KEY_TASK_IMAGES ][image_name ]
223- # del helm_values[KEY_TASK_IMAGES_BUILD][image_name]
223+ self ._prune_excluded_task_images (helm_values , extra_consumers = static_consumers )
224+
225+ def _get_excluded_task_image_consumers (self , values ):
226+ """Return reverse dependencies for excluded task images from app build deps."""
227+ task_images = values .get (KEY_TASK_IMAGES , {})
228+ apps = values .get (KEY_APPS , {})
229+ consumers = {}
230+
231+ for app_name , app_values in apps .items ():
232+ if app_name in self .exclude :
233+ continue
234+ build_dependencies = app_values .get (KEY_HARNESS , {}).get ('dependencies' , {}).get ('build' , [])
235+ if not build_dependencies :
236+ continue
237+ for dep in build_dependencies :
238+ if dep in self .exclude and dep in task_images :
239+ consumers .setdefault (dep , set ()).add (app_name )
240+
241+ return consumers
242+
243+ def _prune_excluded_task_images (self , values , extra_consumers = None ):
244+ """Exclude task images only when no non-excluded image still depends on them."""
245+ task_images = values .get (KEY_TASK_IMAGES , {})
246+ if not task_images :
247+ return
248+
249+ consumers = self ._get_excluded_task_image_consumers (values )
250+ if extra_consumers :
251+ for image_name , image_consumers in extra_consumers .items ():
252+ consumers .setdefault (image_name , set ()).update (image_consumers )
253+
254+ for image_name in list (task_images .keys ()):
255+ if image_name not in self .exclude :
256+ continue
257+ used_by = sorted (consumers .get (image_name , set ()))
258+ if used_by :
259+ logging .warning (
260+ "Image %s was excluded but is still required by non-excluded builds: %s. Keeping it." ,
261+ image_name , ", " .join (used_by )
262+ )
263+ continue
264+ del task_images [image_name ]
224265
225266 def _init_base_images (self , base_image_name ):
226267 """Initialize base images (infrastructure/base-images/) with root context."""
@@ -600,6 +641,7 @@ def validate_dependencies(values):
600641 all_apps = {a for a in values ["apps" ]}
601642 for app in all_apps :
602643 app_values = values ["apps" ][app ]
644+ app_task_images = set (app_values .get (KEY_TASK_IMAGES , {}))
603645 if 'dependencies' in app_values [KEY_HARNESS ]:
604646 soft_dependencies = {
605647 d for d in app_values [KEY_HARNESS ]['dependencies' ]['soft' ]}
@@ -617,9 +659,9 @@ def validate_dependencies(values):
617659 build_dependencies = {
618660 d for d in app_values [KEY_HARNESS ]['dependencies' ]['build' ]}
619661
662+ available_builds = set (values .get (KEY_TASK_IMAGES , {})) | all_apps | app_task_images
620663 not_found = {
621- d for d in build_dependencies if d not in values [KEY_TASK_IMAGES ]}
622- not_found = {d for d in not_found if d not in all_apps }
664+ d for d in build_dependencies if d not in available_builds }
623665 if not_found :
624666 raise ValuesValidationException (
625667 f"Bad build dependencies specified for application { app } : { ',' .join (not_found )} not found as built image" )
@@ -629,8 +671,10 @@ def validate_dependencies(values):
629671
630672 not_found = {d for d in service_dependencies if d not in all_apps }
631673 if not_found :
632- raise ValuesValidationException (
633- f"Bad service application dependencies specified for application { app } : { ',' .join (not_found )} " )
674+ logging .warning (
675+ f"Service proxy (use_services) dependencies for application { app } are not deployed: "
676+ f"{ ',' .join (not_found )} . Proxies to these services will not be created."
677+ )
634678
635679
636680def collect_apps_helm_templates (search_root , dest_helm_chart_path , templates_path = HELM_PATH , exclude = (), include = None , envs = ()):
0 commit comments