11import json
22import logging
33from collections import deque
4- from typing import Any , Deque , Dict , List , Optional , cast
4+ from typing import Any , Optional , cast
55
66from models_library .boot_options import BootOption , EnvVarKey
77from models_library .service_settings_labels import (
3333log = logging .getLogger (__name__ )
3434
3535
36- def _parse_mount_settings (settings : List [ Dict ]) -> List [ Dict ]:
36+ def _parse_mount_settings (settings : list [ dict ]) -> list [ dict ]:
3737 mounts = []
3838 for s in settings :
3939 log .debug ("Retrieved mount settings %s" , s )
@@ -57,7 +57,7 @@ def _parse_mount_settings(settings: List[Dict]) -> List[Dict]:
5757 return mounts
5858
5959
60- def _parse_env_settings (settings : List [str ]) -> Dict :
60+ def _parse_env_settings (settings : list [str ]) -> dict :
6161 envs = {}
6262 for s in settings :
6363 log .debug ("Retrieved env settings %s" , s )
@@ -76,7 +76,7 @@ def _parse_env_settings(settings: List[str]) -> Dict:
7676# TODO: PC->ANE: i tend to agree with pylint, perhaps we can refactor this together
7777def update_service_params_from_settings (
7878 labels_service_settings : SimcoreServiceSettingsLabel ,
79- create_service_params : Dict [str , Any ],
79+ create_service_params : dict [str , Any ],
8080) -> None :
8181 for param in labels_service_settings :
8282 param : SimcoreServiceSettingLabelEntry = param
@@ -143,7 +143,7 @@ def update_service_params_from_settings(
143143 )
144144 elif param .name == "mount" :
145145 log .debug ("Found mount parameter %s" , param .value )
146- mount_settings : List [ Dict ] = _parse_mount_settings (param .value )
146+ mount_settings : list [ dict ] = _parse_mount_settings (param .value )
147147 if mount_settings :
148148 create_service_params ["task_template" ]["ContainerSpec" ][
149149 "Mounts"
@@ -175,7 +175,7 @@ async def _extract_osparc_involved_service_labels(
175175 service_key : str ,
176176 service_tag : str ,
177177 service_labels : SimcoreServiceLabels ,
178- ) -> Dict [str , SimcoreServiceLabels ]:
178+ ) -> dict [str , SimcoreServiceLabels ]:
179179 """
180180 Returns all the involved oSPARC services from the provided service labels.
181181
@@ -188,13 +188,13 @@ async def _extract_osparc_involved_service_labels(
188188 # initialize with existing labels
189189 # stores labels mapped by image_name service:tag
190190 _default_key = _assemble_key (service_key = service_key , service_tag = service_tag )
191- docker_image_name_by_services : Dict [str , SimcoreServiceLabels ] = {
191+ docker_image_name_by_services : dict [str , SimcoreServiceLabels ] = {
192192 _default_key : service_labels
193193 }
194194 # maps form image_name to compose_spec key
195- reverse_mapping : Dict [str , str ] = {_default_key : DEFAULT_SINGLE_SERVICE_NAME }
195+ reverse_mapping : dict [str , str ] = {_default_key : DEFAULT_SINGLE_SERVICE_NAME }
196196
197- def remap_to_compose_spec_key () -> Dict [str , str ]:
197+ def remap_to_compose_spec_key () -> dict [str , str ]:
198198 # remaps from image_name as key to compose_spec key
199199 return {reverse_mapping [k ]: v for k , v in docker_image_name_by_services .items ()}
200200
@@ -252,27 +252,27 @@ def remap_to_compose_spec_key() -> Dict[str, str]:
252252 return remap_to_compose_spec_key ()
253253
254254
255- def _add_compose_destination_container_to_settings_entries (
256- settings : SimcoreServiceSettingsLabel , destination_container : str
257- ) -> List [SimcoreServiceSettingLabelEntry ]:
255+ def _add_compose_destination_containers_to_settings_entries (
256+ settings : SimcoreServiceSettingsLabel , destination_containers : list [ str ]
257+ ) -> list [SimcoreServiceSettingLabelEntry ]:
258258 def _inject_destination_container (
259259 item : SimcoreServiceSettingLabelEntry ,
260260 ) -> SimcoreServiceSettingLabelEntry :
261261 # pylint: disable=protected-access
262- item ._destination_container = destination_container
262+ item ._destination_containers = destination_containers
263263 return item
264264
265265 return [_inject_destination_container (x ) for x in settings ]
266266
267267
268268def _merge_resources_in_settings (
269- settings : Deque [SimcoreServiceSettingLabelEntry ],
269+ settings : deque [SimcoreServiceSettingLabelEntry ],
270270 service_resources : ServiceResourcesDict ,
271- ) -> Deque [SimcoreServiceSettingLabelEntry ]:
271+ ) -> deque [SimcoreServiceSettingLabelEntry ]:
272272 """All oSPARC services which have defined resource requirements will be added"""
273273 log .debug ("MERGING\n %s\n AND\n %s" , f"{ settings = } " , f"{ service_resources } " )
274274
275- result : Deque [SimcoreServiceSettingLabelEntry ] = deque ()
275+ result : deque [SimcoreServiceSettingLabelEntry ] = deque ()
276276
277277 for entry in settings :
278278 entry : SimcoreServiceSettingLabelEntry = entry
@@ -343,14 +343,14 @@ def _merge_resources_in_settings(
343343
344344
345345def _patch_target_service_into_env_vars (
346- settings : Deque [SimcoreServiceSettingLabelEntry ],
347- ) -> Deque [SimcoreServiceSettingLabelEntry ]:
346+ settings : deque [SimcoreServiceSettingLabelEntry ],
347+ ) -> deque [SimcoreServiceSettingLabelEntry ]:
348348 """NOTE: this method will modify settings in place"""
349349
350- def _format_env_var (env_var : str , destination_container : str ) -> str :
350+ def _format_env_var (env_var : str , destination_container : list [ str ] ) -> str :
351351 var_name , var_payload = env_var .split ("=" )
352352 json_encoded = json .dumps (
353- dict (destination_container = destination_container , env_var = var_payload )
353+ dict (destination_containers = destination_container , env_var = var_payload )
354354 )
355355 return f"{ var_name } ={ json_encoded } "
356356
@@ -361,21 +361,21 @@ def _format_env_var(env_var: str, destination_container: str) -> str:
361361 list_of_env_vars = entry .value if entry .value else []
362362
363363 # pylint: disable=protected-access
364- destination_container = entry ._destination_container
364+ destination_containers : list [ str ] = entry ._destination_containers
365365
366366 # transforms settings defined environment variables
367367 # from `ENV_VAR=PAYLOAD`
368- # to `ENV_VAR={"destination_container": "destination_container", "env_var": "PAYLOAD"}`
368+ # to `ENV_VAR={"destination_container": [ "destination_container"] , "env_var": "PAYLOAD"}`
369369 entry .value = [
370- _format_env_var (x , destination_container ) for x in list_of_env_vars
370+ _format_env_var (x , destination_containers ) for x in list_of_env_vars
371371 ]
372372
373373 return settings
374374
375375
376376def _get_boot_options (
377377 service_labels : SimcoreServiceLabels ,
378- ) -> Optional [Dict [EnvVarKey , BootOption ]]:
378+ ) -> Optional [dict [EnvVarKey , BootOption ]]:
379379 as_dict = service_labels .dict ()
380380 boot_options_encoded = as_dict .get ("io.simcore.boot-options" , None )
381381 if boot_options_encoded is None :
@@ -387,11 +387,11 @@ def _get_boot_options(
387387
388388
389389def _assemble_env_vars_for_boot_options (
390- boot_options : Dict [EnvVarKey , BootOption ],
391- service_user_selection_boot_options : Dict [EnvVarKey , str ],
390+ boot_options : dict [EnvVarKey , BootOption ],
391+ service_user_selection_boot_options : dict [EnvVarKey , str ],
392392) -> SimcoreServiceSettingsLabel :
393393
394- env_vars : Deque [str ] = deque ()
394+ env_vars : deque [str ] = deque ()
395395 for env_var_key , boot_option in boot_options .items ():
396396 # fetch value selected by the user or use default if not present
397397 value = service_user_selection_boot_options .get (
@@ -411,7 +411,7 @@ def _assemble_env_vars_for_boot_options(
411411
412412async def get_labels_for_involved_services (
413413 director_v0_client : DirectorV0Client , service_key : str , service_tag : str
414- ) -> Dict [str , SimcoreServiceLabels ]:
414+ ) -> dict [str , SimcoreServiceLabels ]:
415415 simcore_service_labels : SimcoreServiceLabels = (
416416 await director_v0_client .get_service_labels (
417417 service = ServiceKeyVersion (key = service_key , version = service_tag )
@@ -424,7 +424,7 @@ async def get_labels_for_involved_services(
424424 # paths_mapping express how to map dynamic-sidecar paths to the compose-spec volumes
425425 # where the service expects to find its certain folders
426426
427- labels_for_involved_services : Dict [
427+ labels_for_involved_services : dict [
428428 str , SimcoreServiceLabels
429429 ] = await _extract_osparc_involved_service_labels (
430430 director_v0_client = director_v0_client ,
@@ -440,7 +440,7 @@ async def merge_settings_before_use(
440440 director_v0_client : DirectorV0Client ,
441441 service_key : str ,
442442 service_tag : str ,
443- service_user_selection_boot_options : Dict [EnvVarKey , str ],
443+ service_user_selection_boot_options : dict [EnvVarKey , str ],
444444 service_resources : ServiceResourcesDict ,
445445) -> SimcoreServiceSettingsLabel :
446446 labels_for_involved_services = await get_labels_for_involved_services (
@@ -449,34 +449,36 @@ async def merge_settings_before_use(
449449 service_tag = service_tag ,
450450 )
451451
452- # merge the settings from the all the involved services
453- settings : Deque [SimcoreServiceSettingLabelEntry ] = deque () # TODO: fix typing here
454- for compose_spec_key , service_labels in labels_for_involved_services .items ():
455- service_settings : SimcoreServiceSettingsLabel = cast (
456- SimcoreServiceSettingsLabel , service_labels .settings
457- )
452+ settings : deque [SimcoreServiceSettingLabelEntry ] = deque () # TODO: fix typing here
458453
459- settings .extend (
460- # inject compose spec key, used to target container specific services
461- _add_compose_destination_container_to_settings_entries (
462- settings = service_settings , destination_container = compose_spec_key
463- )
464- )
465-
466- # inject boot options as env vars
454+ boot_options_settings_env_vars : Optional [SimcoreServiceSettingsLabel ] = None
455+ # search for boot options first and inject to all containers
456+ for compose_spec_key , service_labels in labels_for_involved_services .items ():
467457 labels_boot_options = _get_boot_options (service_labels )
468458 if labels_boot_options :
469- # create a new setting from SimcoreServiceSettingsLabel as env var to pass to target container
459+ # create a new setting from SimcoreServiceSettingsLabel as env var
470460 boot_options_settings_env_vars = _assemble_env_vars_for_boot_options (
471461 labels_boot_options , service_user_selection_boot_options
472462 )
473463 settings .extend (
474- # inject compose spec key, used to target container specific services
475- _add_compose_destination_container_to_settings_entries (
464+ _add_compose_destination_containers_to_settings_entries (
476465 settings = boot_options_settings_env_vars ,
477- destination_container = compose_spec_key ,
466+ destination_containers = list ( labels_for_involved_services . keys ()) ,
478467 )
479468 )
469+ break
470+
471+ # merge the settings from the all the involved services
472+ for compose_spec_key , service_labels in labels_for_involved_services .items ():
473+ service_settings : SimcoreServiceSettingsLabel = cast (
474+ SimcoreServiceSettingsLabel , service_labels .settings
475+ )
476+ settings .extend (
477+ # inject compose spec key, used to target container specific services
478+ _add_compose_destination_containers_to_settings_entries (
479+ settings = service_settings , destination_containers = [compose_spec_key ]
480+ )
481+ )
480482
481483 settings = _merge_resources_in_settings (settings , service_resources )
482484 settings = _patch_target_service_into_env_vars (settings )
0 commit comments