Skip to content

Commit f17b96b

Browse files
authored
♻️ Is638/dynamic sidecar refactors tests (round 3) (ITISFoundation#3154)
1 parent 89cf160 commit f17b96b

21 files changed

+616
-627
lines changed

services/dynamic-sidecar/.env-devel

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
# environs in Dockerfile ----------------
77
SC_BOOT_MODE=local-development
8-
8+
DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR="/tmp/dy-volumes"
99

1010
# service specific required vars
1111
DYNAMIC_SIDECAR_COMPOSE_NAMESPACE=dev-namespace
@@ -28,4 +28,4 @@ S3_ENDPOINT=MINIO
2828
S3_ACCESS_KEY=mocked
2929
S3_SECRET_KEY=mocked
3030
S3_BUCKET_NAME=mocked
31-
R_CLONE_PROVIDER=MINIO
31+
R_CLONE_PROVIDER=MINIO

services/dynamic-sidecar/Dockerfile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ ENV PYTHONDONTWRITEBYTECODE=1 \
4545
ENV PATH="${VIRTUAL_ENV}/bin:$PATH"
4646
# directory where dynamic-sidecar stores creates and shares
4747
# volumes between itself and the spawned containers
48-
ENV DY_VOLUMES="/dy-volumes"
48+
ENV DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR="/dy-volumes"
4949

5050
# rclone installation
5151
ARG R_CLONE_VERSION="1.58.0"
@@ -70,7 +70,7 @@ RUN apt-get update &&\
7070
# NOTE: python virtualenv is used here such that installed
7171
# packages may be moved to production image easily by copying the venv
7272
RUN python -m venv ${VIRTUAL_ENV}
73-
RUN mkdir -p ${DY_VOLUMES}
73+
RUN mkdir -p ${DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR}
7474

7575
RUN pip install --upgrade --no-cache-dir \
7676
pip~=22.0 \
@@ -124,7 +124,7 @@ WORKDIR /home/scu
124124

125125
# Starting from clean base image, copies pre-installed virtualenv from prod-only-deps
126126
COPY --chown=scu:scu --from=prod-only-deps ${VIRTUAL_ENV} ${VIRTUAL_ENV}
127-
COPY --chown=scu:scu --from=prod-only-deps ${DY_VOLUMES} ${DY_VOLUMES}
127+
COPY --chown=scu:scu --from=prod-only-deps ${DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR} ${DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR}
128128

129129
# Copies booting scripts
130130
COPY --chown=scu:scu services/dynamic-sidecar/docker services/dynamic-sidecar/docker
@@ -157,7 +157,7 @@ ENV SC_BUILD_TARGET=development
157157
WORKDIR /devel
158158

159159
RUN chown -R scu:scu ${VIRTUAL_ENV}
160-
RUN chown -R scu:scu ${DY_VOLUMES}
160+
RUN chown -R scu:scu ${DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR}
161161

162162
EXPOSE 8000
163163
EXPOSE 3000

services/dynamic-sidecar/docker/entrypoint.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,16 +98,16 @@ fi
9898
# Change ownership of volumes mount directory
9999
# directories are empty at this point
100100
# each individual subdirectory is a unique volume
101-
chown --verbose --recursive "$SC_USER_NAME":"$GROUPNAME" "${DY_VOLUMES}"
101+
chown --verbose --recursive "$SC_USER_NAME":"$GROUPNAME" "${DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR}"
102102
# Allow owner and group to edit write and execute
103103
# files from all the subdirectories
104104
# When the service access files downloaded by the dynamic-sidecar
105105
# it uses group permissions
106-
chmod --verbose --recursive 774 "${DY_VOLUMES}"
106+
chmod --verbose --recursive 774 "${DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR}"
107107

108108
echo "$INFO Starting $* ..."
109109
echo " $SC_USER_NAME rights : $(id "$SC_USER_NAME")"
110110
echo " local dir : $(ls -al)"
111-
echo " volumes dir : $(ls -al "${DY_VOLUMES}")"
111+
echo " volumes dir : $(ls -al "${DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR}")"
112112

113113
exec gosu "$SC_USER_NAME" "$@"

services/dynamic-sidecar/src/simcore_service_dynamic_sidecar/cli.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import typer
55
from settings_library.utils_cli import create_settings_command
6-
from simcore_service_dynamic_sidecar.core.application import create_basic_app
6+
from simcore_service_dynamic_sidecar.core.application import create_base_app
77

88
from ._meta import PROJECT_NAME
99
from .core.settings import DynamicSidecarSettings
@@ -18,7 +18,7 @@
1818
@main.command()
1919
def openapi():
2020
"""Prints OpenAPI specifications in json format"""
21-
app = create_basic_app()
21+
app = create_base_app()
2222
typer.secho(json.dumps(app.openapi(), indent=2))
2323

2424

services/dynamic-sidecar/src/simcore_service_dynamic_sidecar/core/application.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from ..models.domains.shared_store import SharedStore
1010
from ..models.schemas.application_health import ApplicationHealth
1111
from ..modules.directory_watcher import setup_directory_watcher
12-
from ..modules.mounted_fs import setup_mounted_fs
12+
from ..modules.mounted_fs import MountedVolumes, setup_mounted_fs
1313
from .docker_logs import setup_background_log_fetcher
1414
from .error_handlers import http_error_handler, node_not_found_error_handler
1515
from .errors import BaseDynamicSidecarError
@@ -45,7 +45,7 @@ def setup_logger(settings: DynamicSidecarSettings):
4545
logging.root.setLevel(settings.log_level)
4646

4747

48-
def create_basic_app() -> FastAPI:
48+
def create_base_app() -> FastAPI:
4949
# settings
5050
settings = DynamicSidecarSettings.create_from_envs()
5151
setup_logger(settings)
@@ -71,7 +71,7 @@ def create_app():
7171
needed in other requests and used to share data.
7272
"""
7373

74-
app = create_basic_app()
74+
app = create_base_app()
7575

7676
# MODULES SETUP --------------
7777

@@ -114,3 +114,23 @@ async def _on_shutdown() -> None:
114114
app.add_event_handler("shutdown", _on_shutdown)
115115

116116
return app
117+
118+
119+
class AppState:
120+
def __init__(self, app: FastAPI):
121+
self._app = app
122+
123+
@property
124+
def settings(self) -> DynamicSidecarSettings:
125+
assert isinstance(self._app.state.settings, DynamicSidecarSettings) # nosec
126+
return self._app.state.settings
127+
128+
@property
129+
def mounted_volumes(self) -> MountedVolumes:
130+
assert isinstance(self._app.state.mounted_volumes, MountedVolumes) # nosec
131+
return self._app.state.mounted_volumes
132+
133+
@property
134+
def shared_store(self) -> SharedStore:
135+
assert isinstance(self._app.state.shared_store, SharedStore) # nosec
136+
return self._app.state.shared_store

services/dynamic-sidecar/src/simcore_service_dynamic_sidecar/core/settings.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,24 @@ class DynamicSidecarSettings(BaseCustomSettings, MixinLoggingSettings):
2323
description="boot mode helps determine if in development mode or normal operation",
2424
)
2525

26+
DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR: Path = Field(
27+
...,
28+
description="Base directory where dynamic-sidecar stores creates "
29+
"and shares volumes between itself and the spawned containers. "
30+
"It is used as a mount directory for the director-v2."
31+
"Sidecar must have r/w permissions in this folder.",
32+
)
33+
2634
# LOGGING
27-
LOG_LEVEL: str = Field("WARNING")
35+
LOG_LEVEL: str = Field(default="WARNING")
2836

2937
# SERVICE SERVER (see : https://www.uvicorn.org/settings/)
3038
DYNAMIC_SIDECAR_HOST: str = Field(
31-
"0.0.0.0", # nosec
39+
default="0.0.0.0", # nosec
3240
description="host where to bind the application on which to serve",
3341
)
3442
DYNAMIC_SIDECAR_PORT: PortInt = Field(
35-
8000, description="port where the server will be currently serving"
43+
default=8000, description="port where the server will be currently serving"
3644
)
3745

3846
DYNAMIC_SIDECAR_COMPOSE_NAMESPACE: str = Field(
@@ -44,28 +52,29 @@ class DynamicSidecarSettings(BaseCustomSettings, MixinLoggingSettings):
4452
)
4553

4654
DYNAMIC_SIDECAR_MAX_COMBINED_CONTAINER_NAME_LENGTH: PositiveInt = Field(
47-
63, description="the container name which will be used as hostname"
55+
default=63, description="the container name which will be used as hostname"
4856
)
4957

5058
DYNAMIC_SIDECAR_STOP_AND_REMOVE_TIMEOUT: PositiveInt = Field(
51-
5,
59+
default=5,
5260
description=(
5361
"When receiving SIGTERM the process has 10 seconds to cleanup its children "
5462
"forcing our children to stop in 5 seconds in all cases"
5563
),
5664
)
5765

5866
DEBUG: bool = Field(
59-
False,
67+
default=False,
6068
description="If set to True the application will boot into debug mode",
6169
)
6270

6371
DYNAMIC_SIDECAR_REMOTE_DEBUG_PORT: PortInt = Field(
64-
3000, description="ptsvd remote debugger starting port"
72+
default=3000, description="ptsvd remote debugger starting port"
6573
)
6674

6775
DYNAMIC_SIDECAR_DOCKER_COMPOSE_DOWN_TIMEOUT: PositiveInt = Field(
68-
15, description="used during shutdown when containers swapend will be removed"
76+
default=15,
77+
description="used during shutdown when containers swapend will be removed",
6978
)
7079

7180
DY_SIDECAR_PATH_INPUTS: Path = Field(

services/dynamic-sidecar/src/simcore_service_dynamic_sidecar/models/domains/shared_store.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
class SharedStore(BaseModel):
77
compose_spec: Optional[str] = Field(
8-
None, description="stores the stringified compose spec"
8+
default=None, description="stores the stringified compose spec"
99
)
1010
container_names: list[str] = Field(
11-
[], description="stores the container names from the compose_spec"
11+
default_factory=list,
12+
description="stores the container names from the compose_spec",
1213
)

services/dynamic-sidecar/src/simcore_service_dynamic_sidecar/models/schemas/application_health.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
class ApplicationHealth(BaseModel):
77
is_healthy: bool = Field(
8-
True, description="returns True if the service sis running correctly"
8+
default=True, description="returns True if the service sis running correctly"
99
)
1010
error_message: Optional[str] = Field(
11-
None, description="in case of error this gets set"
11+
default=None, description="in case of error this gets set"
1212
)

services/dynamic-sidecar/src/simcore_service_dynamic_sidecar/modules/mounted_fs.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99

1010
from ..core.docker_utils import get_volume_by_label
1111

12-
DY_VOLUMES = Path("/dy-volumes")
13-
1412

1513
def _ensure_path(path: Path) -> Path:
1614
path.mkdir(parents=True, exist_ok=True)
@@ -41,12 +39,14 @@ def __init__(
4139
state_paths: list[Path],
4240
state_exclude: list[str],
4341
compose_namespace: str,
42+
dy_volumes: Path,
4443
) -> None:
4544
self.inputs_path: Path = inputs_path
4645
self.outputs_path: Path = outputs_path
4746
self.state_paths: list[Path] = state_paths
4847
self.state_exclude: list[str] = state_exclude
4948
self.compose_namespace = compose_namespace
49+
self._dy_volumes = dy_volumes
5050

5151
self._ensure_directories()
5252

@@ -65,15 +65,15 @@ def volume_name_state_paths(self) -> Generator[str, None, None]:
6565

6666
@cached_property
6767
def disk_inputs_path(self) -> Path:
68-
return _ensure_path(DY_VOLUMES / self.inputs_path.relative_to("/"))
68+
return _ensure_path(self._dy_volumes / self.inputs_path.relative_to("/"))
6969

7070
@cached_property
7171
def disk_outputs_path(self) -> Path:
72-
return _ensure_path(DY_VOLUMES / self.outputs_path.relative_to("/"))
72+
return _ensure_path(self._dy_volumes / self.outputs_path.relative_to("/"))
7373

7474
def disk_state_paths(self) -> Iterator[Path]:
7575
for state_path in self.state_paths:
76-
yield _ensure_path(DY_VOLUMES / state_path.relative_to("/"))
76+
yield _ensure_path(self._dy_volumes / state_path.relative_to("/"))
7777

7878
def all_disk_paths(self) -> Iterator[Path]:
7979
# PC: keeps iterator to follow same style as disk_state_paths but IMO it is overreaching
@@ -86,7 +86,7 @@ def _ensure_directories(self) -> None:
8686
Creates the directories on its file system,
8787
these will be mounted elsewere.
8888
"""
89-
_ensure_path(DY_VOLUMES)
89+
_ensure_path(self._dy_volumes)
9090
self.disk_inputs_path # pylint:disable= pointless-statement
9191
self.disk_outputs_path # pylint:disable= pointless-statement
9292
set(self.disk_state_paths())
@@ -129,6 +129,7 @@ def setup_mounted_fs(app: FastAPI) -> MountedVolumes:
129129
state_paths=settings.DY_SIDECAR_STATE_PATHS,
130130
state_exclude=settings.DY_SIDECAR_STATE_EXCLUDE,
131131
compose_namespace=settings.DYNAMIC_SIDECAR_COMPOSE_NAMESPACE,
132+
dy_volumes=settings.DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR,
132133
)
133134

134135
return app.state.mounted_volumes

0 commit comments

Comments
 (0)