Skip to content

Commit 668e858

Browse files
committed
feat: allow overrides to env vars on session start
1 parent f9d171b commit 668e858

5 files changed

Lines changed: 69 additions & 7 deletions

File tree

components/renku_data_services/notebooks/api.spec.yaml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,27 @@ components:
419419
- anonymous
420420
- registered
421421
type: object
422+
EnvVariableOverrides:
423+
description: Environment variable overrides for the session pod
424+
type: array
425+
items:
426+
$ref: "#/components/schemas/EnvVarOverride"
427+
EnvVarOverride:
428+
description: Override an env variable defined in the session launcher
429+
type: object
430+
properties:
431+
name:
432+
type: string
433+
maxLength: 256
434+
# based on https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_235
435+
pattern: "^[a-zA-Z_][a-zA-Z0-9_]*$"
436+
example: MY_VAR
437+
value:
438+
type: string
439+
maxLength: 500
440+
required:
441+
- name
442+
- value
422443
ErrorResponse:
423444
type: object
424445
properties:
@@ -865,6 +886,8 @@ components:
865886
type: integer
866887
cloudstorage:
867888
$ref: "#/components/schemas/SessionCloudStoragePostList"
889+
env_variable_overrides:
890+
$ref: "#/components/schemas/EnvVariableOverrides"
868891
required:
869892
- launcher_id
870893
type: object

components/renku_data_services/notebooks/apispec.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# generated by datamodel-codegen:
22
# filename: api.spec.yaml
3-
# timestamp: 2025-03-19T10:21:13+00:00
3+
# timestamp: 2025-04-17T14:26:28+00:00
44

55
from __future__ import annotations
66

@@ -34,6 +34,13 @@ class DefaultCullingThresholds(BaseAPISpec):
3434
registered: CullingThreshold
3535

3636

37+
class EnvVarOverride(BaseAPISpec):
38+
name: str = Field(
39+
..., examples=["MY_VAR"], max_length=256, pattern="^[a-zA-Z_][a-zA-Z0-9_]*$"
40+
)
41+
value: str = Field(..., max_length=500)
42+
43+
3744
class Error(BaseAPISpec):
3845
code: int = Field(..., examples=[1404], gt=0)
3946
detail: Optional[str] = Field(
@@ -384,6 +391,9 @@ class SessionPostRequest(BaseAPISpec):
384391
)
385392
resource_class_id: Optional[int] = None
386393
cloudstorage: Optional[List[SessionCloudStoragePost]] = None
394+
env_variable_overrides: Optional[List[EnvVarOverride]] = Field(
395+
None, description="Environment variable overrides for the session pod"
396+
)
387397

388398

389399
class SessionResponse(BaseAPISpec):

components/renku_data_services/notebooks/blueprints.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@
3333
get_extra_containers,
3434
get_extra_init_containers,
3535
get_gitlab_image_pull_secret,
36+
get_launcher_env_variables,
3637
patch_session,
3738
request_dc_secret_creation,
3839
request_session_secret_creation,
3940
requires_image_pull_secret,
4041
resources_from_resource_class,
42+
verify_launcher_env_variable_overrides,
4143
)
4244
from renku_data_services.notebooks.crs import (
4345
AmaltheaSessionSpec,
@@ -377,6 +379,8 @@ async def _handler(
377379

378380
secrets_to_create.append(auth_secret)
379381

382+
# Raise an error if there are invalid environment variables in the request body
383+
verify_launcher_env_variable_overrides(launcher, body)
380384
env = [
381385
SessionEnvItem(name="RENKU_BASE_URL_PATH", value=base_server_path),
382386
SessionEnvItem(name="RENKU_BASE_URL", value=base_server_url),
@@ -386,12 +390,9 @@ async def _handler(
386390
SessionEnvItem(name="RENKU_SESSION_PORT", value=f"{environment.port}"),
387391
SessionEnvItem(name="RENKU_WORKING_DIR", value=work_dir.as_posix()),
388392
]
389-
if launcher.env_variables:
390-
env.extend(
391-
SessionEnvItem(name=env_var.name, value=env_var.value)
392-
for env_var in launcher.env_variables
393-
if env_var.value
394-
)
393+
launcher_env_variables = get_launcher_env_variables(launcher, body)
394+
if launcher_env_variables:
395+
env.extend(launcher_env_variables)
395396

396397
manifest = AmaltheaSessionV1Alpha1(
397398
metadata=Metadata(name=server_name, annotations=annotations),

components/renku_data_services/notebooks/core_sessions.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
Resources,
4545
SecretAsVolume,
4646
SecretAsVolumeItem,
47+
SessionEnvItem,
4748
State,
4849
)
4950
from renku_data_services.notebooks.models import ExtraSecret
@@ -53,6 +54,7 @@
5354
)
5455
from renku_data_services.project.db import ProjectRepository
5556
from renku_data_services.project.models import Project, SessionSecret
57+
from renku_data_services.session.models import SessionLauncher
5658
from renku_data_services.users.db import UserRepo
5759
from renku_data_services.utils.cryptography import get_encryption_key
5860

@@ -311,6 +313,29 @@ async def request_dc_secret_creation(
311313
)
312314

313315

316+
def get_launcher_env_variables(launcher: SessionLauncher, body: apispec.SessionPostRequest) -> list[SessionEnvItem]:
317+
"""Get the environment variables from the launcher, with overrides from the request."""
318+
output: list[SessionEnvItem] = []
319+
env_overrides = {i.name: i.value for i in body.env_variable_overrides or []}
320+
for env in launcher.env_variables or []:
321+
if env.name in env_overrides:
322+
output.append(SessionEnvItem(name=env.name, value=env_overrides[env.name]))
323+
else:
324+
output.append(SessionEnvItem(name=env.name, value=env.value))
325+
return output
326+
327+
328+
def verify_launcher_env_variable_overrides(launcher: SessionLauncher, body: apispec.SessionPostRequest) -> None:
329+
"""Raise an error if there are env variables that are not defined in the launcher."""
330+
env_overrides = {i.name: i.value for i in body.env_variable_overrides or []}
331+
known_env_names = {i.name for i in launcher.env_variables or []}
332+
unknown_env_names = set(env_overrides.keys()) - known_env_names
333+
if unknown_env_names:
334+
message = f"""The following environment variables are not defined in the session launcher: {unknown_env_names}.
335+
Please remove them from the launch request or add them to the session launcher."""
336+
raise errors.ValidationError(message=message)
337+
338+
314339
async def request_session_secret_creation(
315340
user: AuthenticatedAPIUser | AnonymousAPIUser,
316341
nb_config: NotebooksConfig,

test/bases/renku_data_services/data_api/test_sessions.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,9 @@ async def test_starting_session_anonymous(
11081108
"name": "test",
11091109
"port": 8888,
11101110
},
1111+
env_variables=[
1112+
{"name": "TEST_ENV_VAR", "value": "some-random-value-1234"},
1113+
],
11111114
)
11121115
launcher_id = launcher["id"]
11131116
project_id = project["id"]

0 commit comments

Comments
 (0)