diff --git a/services/director-v2/src/simcore_service_director_v2/modules/dynamic_sidecar/docker_api/_core.py b/services/director-v2/src/simcore_service_director_v2/modules/dynamic_sidecar/docker_api/_core.py index d47c22571728..60eeab3f9555 100644 --- a/services/director-v2/src/simcore_service_director_v2/modules/dynamic_sidecar/docker_api/_core.py +++ b/services/director-v2/src/simcore_service_director_v2/modules/dynamic_sidecar/docker_api/_core.py @@ -18,6 +18,7 @@ from models_library.services_enums import ServiceState from models_library.services_metadata_runtime import to_simcore_runtime_docker_label_key from servicelib.utils import logged_gather +from settings_library.docker_registry import RegistrySettings from starlette import status from tenacity import TryAgain, retry from tenacity.asyncio import AsyncRetrying @@ -99,6 +100,7 @@ def _to_snake_case(string: str) -> str: async def create_service_and_get_id( create_service_data: AioDockerServiceSpec | dict[str, Any], + registry_settings: RegistrySettings | None, ) -> ServiceId: # NOTE: ideally the argument should always be AioDockerServiceSpec # but for that we need get_dynamic_proxy_spec to return that type @@ -107,6 +109,13 @@ async def create_service_and_get_id( create_service_data, by_alias=True, exclude_unset=True ) kwargs = {_to_snake_case(k): v for k, v in kwargs.items()} + if registry_settings: + kwargs["auth"] = { + "username": registry_settings.REGISTRY_USER, + "password": registry_settings.REGISTRY_PW.get_secret_value(), + "serveraddress": registry_settings.resolved_registry_url, + } + kwargs["registry"] = registry_settings.resolved_registry_url logging.debug("Creating service with\n%s", json_dumps(kwargs, indent=1)) service_start_result = await client.services.create(**kwargs) diff --git a/services/director-v2/src/simcore_service_director_v2/modules/dynamic_sidecar/scheduler/_core/_event_create_sidecars.py b/services/director-v2/src/simcore_service_director_v2/modules/dynamic_sidecar/scheduler/_core/_event_create_sidecars.py index 6ea9efc4e370..594e0e754007 100644 --- a/services/director-v2/src/simcore_service_director_v2/modules/dynamic_sidecar/scheduler/_core/_event_create_sidecars.py +++ b/services/director-v2/src/simcore_service_director_v2/modules/dynamic_sidecar/scheduler/_core/_event_create_sidecars.py @@ -30,6 +30,7 @@ DynamicSidecarSettings, PlacementSettings, ) +from .....core.settings import AppSettings from .....models.dynamic_services_scheduler import NetworkId, SchedulerData from .....utils.db import get_repository from .....utils.dict_utils import nested_update @@ -93,32 +94,35 @@ async def _create_proxy_service( swarm_network_id: NetworkId, swarm_network_name: str, ): + app_settings: AppSettings = app.state.settings proxy_settings: DynamicSidecarProxySettings = ( app.state.settings.DYNAMIC_SERVICES.DYNAMIC_SIDECAR_PROXY_SETTINGS ) scheduler_data.proxy_admin_api_port = ( proxy_settings.DYNAMIC_SIDECAR_CADDY_ADMIN_API_PORT ) - dynamic_services_settings: DynamicServicesSettings = ( app.state.settings.DYNAMIC_SERVICES ) - dynamic_sidecar_proxy_create_service_params: dict[ - str, Any - ] = get_dynamic_proxy_spec( - scheduler_data=scheduler_data, - dynamic_services_settings=dynamic_services_settings, - dynamic_sidecar_network_id=dynamic_sidecar_network_id, - swarm_network_id=swarm_network_id, - swarm_network_name=swarm_network_name, + dynamic_sidecar_proxy_create_service_params: dict[str, Any] = ( + get_dynamic_proxy_spec( + scheduler_data=scheduler_data, + dynamic_services_settings=dynamic_services_settings, + dynamic_sidecar_network_id=dynamic_sidecar_network_id, + swarm_network_id=swarm_network_id, + swarm_network_name=swarm_network_name, + ) ) _logger.debug( "dynamic-sidecar-proxy create_service_params %s", json_dumps(dynamic_sidecar_proxy_create_service_params), ) - await create_service_and_get_id(dynamic_sidecar_proxy_create_service_params) + await create_service_and_get_id( + dynamic_sidecar_proxy_create_service_params, + app_settings.DIRECTOR_V2_DOCKER_HUB_REGISTRY, + ) class CreateSidecars(DynamicSchedulerEvent): @@ -156,6 +160,7 @@ async def action(cls, app: FastAPI, scheduler_data: SchedulerData) -> None: rabbitmq_client: RabbitMQClient = app.state.rabbitmq_client await rabbitmq_client.publish(message.channel_name, message) + app_settings: AppSettings = app.state.settings dynamic_sidecar_settings: DynamicSidecarSettings = ( app.state.settings.DYNAMIC_SERVICES.DYNAMIC_SIDECAR ) @@ -244,18 +249,20 @@ async def action(cls, app: FastAPI, scheduler_data: SchedulerData) -> None: # WARNING: do NOT log, this structure has secrets in the open # If you want to log, please use an obfuscator - dynamic_sidecar_service_spec_base: AioDockerServiceSpec = await get_dynamic_sidecar_spec( - scheduler_data=scheduler_data, - dynamic_sidecar_settings=dynamic_sidecar_settings, - dynamic_services_scheduler_settings=dynamic_services_scheduler_settings, - swarm_network_id=swarm_network_id, - settings=settings, - app_settings=app.state.settings, - hardware_info=scheduler_data.hardware_info, - has_quota_support=dynamic_services_scheduler_settings.DYNAMIC_SIDECAR_ENABLE_VOLUME_LIMITS, - metrics_collection_allowed=metrics_collection_allowed, - user_extra_properties=user_extra_properties, - rpc_client=rpc_client, + dynamic_sidecar_service_spec_base: AioDockerServiceSpec = ( + await get_dynamic_sidecar_spec( + scheduler_data=scheduler_data, + dynamic_sidecar_settings=dynamic_sidecar_settings, + dynamic_services_scheduler_settings=dynamic_services_scheduler_settings, + swarm_network_id=swarm_network_id, + settings=settings, + app_settings=app.state.settings, + hardware_info=scheduler_data.hardware_info, + has_quota_support=dynamic_services_scheduler_settings.DYNAMIC_SIDECAR_ENABLE_VOLUME_LIMITS, + metrics_collection_allowed=metrics_collection_allowed, + user_extra_properties=user_extra_properties, + rpc_client=rpc_client, + ) ) user_specific_service_spec = ( @@ -278,7 +285,8 @@ async def action(cls, app: FastAPI, scheduler_data: SchedulerData) -> None: ) await rabbitmq_client.publish(rabbit_message.channel_name, rabbit_message) dynamic_sidecar_id = await create_service_and_get_id( - dynamic_sidecar_service_final_spec + dynamic_sidecar_service_final_spec, + app_settings.DIRECTOR_V2_DOCKER_HUB_REGISTRY, ) # constrain service to the same node scheduler_data.dynamic_sidecar.docker_node_id = ( diff --git a/services/director-v2/tests/unit/with_dbs/test_modules_dynamic_sidecar_docker_api.py b/services/director-v2/tests/unit/with_dbs/test_modules_dynamic_sidecar_docker_api.py index 31cdb5519ce0..dbd4f4019132 100644 --- a/services/director-v2/tests/unit/with_dbs/test_modules_dynamic_sidecar_docker_api.py +++ b/services/director-v2/tests/unit/with_dbs/test_modules_dynamic_sidecar_docker_api.py @@ -453,7 +453,7 @@ async def test_create_service( cleanup_test_service_name: None, docker_swarm: None, ): - service_id = await docker_api.create_service_and_get_id(service_spec) + service_id = await docker_api.create_service_and_get_id(service_spec, None) assert service_id @@ -465,7 +465,7 @@ async def test_services_to_observe_exist( docker_swarm: None, ): service_id = await docker_api.create_service_and_get_id( - dynamic_sidecar_service_spec + dynamic_sidecar_service_spec, None ) assert service_id @@ -484,7 +484,7 @@ async def test_dynamic_sidecar_in_running_state_and_node_id_is_recovered( docker_swarm: None, ): service_id = await docker_api.create_service_and_get_id( - dynamic_sidecar_service_spec + dynamic_sidecar_service_spec, None ) assert service_id @@ -511,7 +511,7 @@ async def test_dynamic_sidecar_get_dynamic_sidecar_sate_fail_to_schedule( } service_id = await docker_api.create_service_and_get_id( - dynamic_sidecar_service_spec + dynamic_sidecar_service_spec, None ) assert service_id @@ -539,7 +539,9 @@ async def test_is_dynamic_sidecar_stack_missing( # start 2 fake services to emulate the dynamic-sidecar stack for dynamic_sidecar_stack in dynamic_sidecar_stack_specs: - service_id = await docker_api.create_service_and_get_id(dynamic_sidecar_stack) + service_id = await docker_api.create_service_and_get_id( + dynamic_sidecar_stack, None + ) assert service_id services_are_missing = await docker_api.is_dynamic_sidecar_stack_missing( @@ -562,7 +564,9 @@ async def test_are_sidecar_and_proxy_services_present( # start 2 fake services to emulate the dynamic-sidecar stack for dynamic_sidecar_stack in dynamic_sidecar_stack_specs: - service_id = await docker_api.create_service_and_get_id(dynamic_sidecar_stack) + service_id = await docker_api.create_service_and_get_id( + dynamic_sidecar_stack, None + ) assert service_id services_are_missing = await docker_api.are_sidecar_and_proxy_services_present( @@ -605,7 +609,9 @@ async def _count_services_in_stack( # start 2 fake services to emulate the dynamic-sidecar stack for dynamic_sidecar_stack in dynamic_sidecar_stack_specs: - service_id = await docker_api.create_service_and_get_id(dynamic_sidecar_stack) + service_id = await docker_api.create_service_and_get_id( + dynamic_sidecar_stack, None + ) assert service_id assert ( @@ -667,7 +673,9 @@ async def test_is_sidecar_running( # start 2 fake services to emulate the dynamic-sidecar stack for dynamic_sidecar_stack in dynamic_sidecar_stack_specs: - service_id = await docker_api.create_service_and_get_id(dynamic_sidecar_stack) + service_id = await docker_api.create_service_and_get_id( + dynamic_sidecar_stack, None + ) assert service_id async for attempt in AsyncRetrying(