7
7
from dataclasses import dataclass
8
8
from datetime import UTC , datetime
9
9
from math import floor
10
- from pathlib import Path
10
+ from pathlib import PurePosixPath
11
11
from typing import Any
12
12
from urllib .parse import urljoin , urlparse
13
13
55
55
Authentication ,
56
56
AuthenticationType ,
57
57
Culling ,
58
+ DataSource ,
58
59
ExtraContainer ,
59
60
ExtraVolume ,
60
61
ExtraVolumeMount ,
64
65
Resources ,
65
66
SecretAsVolume ,
66
67
SecretAsVolumeItem ,
67
- SecretRef ,
68
+ SecretRefKey ,
69
+ SecretRefWhole ,
68
70
Session ,
69
71
SessionEnvItem ,
70
72
State ,
86
88
from renku_data_services .project .db import ProjectRepository
87
89
from renku_data_services .repositories .db import GitRepositoriesRepository
88
90
from renku_data_services .session .db import SessionRepository
91
+ from renku_data_services .storage .db import StorageV2Repository
89
92
90
93
91
94
@dataclass (kw_only = True )
@@ -415,7 +418,7 @@ async def launch_notebook_helper(
415
418
if lfs_auto_fetch is not None :
416
419
parsed_server_options .lfs_auto_fetch = lfs_auto_fetch
417
420
418
- image_work_dir = image_repo .image_workdir (parsed_image ) or Path ("/" )
421
+ image_work_dir = image_repo .image_workdir (parsed_image ) or PurePosixPath ("/" )
419
422
mount_path = image_work_dir / "work"
420
423
421
424
server_work_dir = mount_path / gl_project_path
@@ -430,7 +433,7 @@ async def launch_notebook_helper(
430
433
cstorage .model_dump (),
431
434
user = user ,
432
435
project_id = gl_project_id ,
433
- work_dir = server_work_dir . absolute () ,
436
+ work_dir = server_work_dir ,
434
437
config = nb_config ,
435
438
internal_gitlab_user = internal_gitlab_user ,
436
439
)
@@ -774,6 +777,7 @@ class NotebooksNewBP(CustomBlueprint):
774
777
project_repo : ProjectRepository
775
778
session_repo : SessionRepository
776
779
rp_repo : ResourcePoolRepository
780
+ storage_repo : StorageV2Repository
777
781
778
782
def start (self ) -> BlueprintFactoryResponse :
779
783
"""Start a session with the new operator."""
@@ -805,17 +809,49 @@ async def _handler(
805
809
parsed_server_options = await self .nb_config .crc_validator .validate_class_storage (
806
810
user , resource_class_id , body .disk_storage
807
811
)
808
- work_dir = Path ( "/home/jovyan/work" )
812
+ work_dir = environment . working_directory
809
813
user_secrets : K8sUserSecrets | None = None
810
814
# if body.user_secrets:
811
815
# user_secrets = K8sUserSecrets(
812
816
# name=server_name,
813
817
# user_secret_ids=body.user_secrets.user_secret_ids,
814
818
# mount_path=body.user_secrets.mount_path,
815
819
# )
816
- cloud_storage : list [RCloneStorage ] = []
820
+ cloud_storages_db = await self .storage_repo .get_storage (
821
+ user = user , project_id = project .id , include_secrets = True
822
+ )
823
+ cloud_storage : dict [str , RCloneStorage ] = {
824
+ str (s .storage_id ): RCloneStorage (
825
+ source_path = s .source_path ,
826
+ mount_folder = (work_dir / s .target_path ).as_posix (),
827
+ configuration = s .configuration .model_dump (mode = "python" ),
828
+ readonly = s .readonly ,
829
+ config = self .nb_config ,
830
+ name = s .name ,
831
+ )
832
+ for s in cloud_storages_db
833
+ }
834
+ cloud_storage_request : dict [str , RCloneStorage ] = {
835
+ s .storage_id : RCloneStorage (
836
+ source_path = s .source_path ,
837
+ mount_folder = (work_dir / s .target_path ).as_posix (),
838
+ configuration = s .configuration ,
839
+ readonly = s .readonly ,
840
+ config = self .nb_config ,
841
+ name = None ,
842
+ )
843
+ for s in body .cloudstorage or []
844
+ if s .storage_id is not None
845
+ }
846
+ # NOTE: Check the cloud storage in the request body and if any match
847
+ # then overwrite the projects cloud storages
848
+ # NOTE: Cloud storages in the session launch request body that are not form the DB are ignored
849
+ for csr_id , csr in cloud_storage_request .items ():
850
+ if csr_id in cloud_storage :
851
+ cloud_storage [csr_id ] = csr
817
852
# repositories = [Repository(i.url, branch=i.branch, commit_sha=i.commit_sha) for i in body.repositories]
818
853
repositories = [Repository (url = i ) for i in project .repositories ]
854
+ secrets_to_create : list [V1Secret ] = []
819
855
server = Renku2UserServer (
820
856
user = user ,
821
857
image = image ,
@@ -825,7 +861,7 @@ async def _handler(
825
861
server_options = parsed_server_options ,
826
862
environment_variables = {},
827
863
user_secrets = user_secrets ,
828
- cloudstorage = cloud_storage ,
864
+ cloudstorage = [ i for i in cloud_storage . values ()] ,
829
865
k8s_client = self .nb_config .k8s_v2_client ,
830
866
workspace_mount_path = work_dir ,
831
867
work_dir = work_dir ,
@@ -835,6 +871,14 @@ async def _handler(
835
871
is_image_private = False ,
836
872
internal_gitlab_user = internal_gitlab_user ,
837
873
)
874
+ # Generate the cloud starge secrets
875
+ data_sources : list [DataSource ] = []
876
+ for ics , cs in enumerate (cloud_storage .values ()):
877
+ secret_name = f"{ server_name } -ds-{ ics } "
878
+ secrets_to_create .append (cs .secret (secret_name , server .k8s_client .preferred_namespace ))
879
+ data_sources .append (
880
+ DataSource (mountPath = cs .mount_folder , secretRef = SecretRefWhole (name = secret_name , adopt = True ))
881
+ )
838
882
cert_init , cert_vols = init_containers .certificates_container (self .nb_config )
839
883
session_init_containers = [InitContainer .model_validate (self .nb_config .k8s_v2_client .sanitize (cert_init ))]
840
884
extra_volumes = [ExtraVolume .model_validate (self .nb_config .k8s_v2_client .sanitize (i )) for i in cert_vols ]
@@ -868,7 +912,6 @@ async def _handler(
868
912
metadata = Metadata (name = server_name , annotations = annotations ),
869
913
spec = AmaltheaSessionSpec (
870
914
codeRepositories = [],
871
- dataSources = [],
872
915
hibernated = False ,
873
916
session = Session (
874
917
image = image ,
@@ -915,13 +958,14 @@ async def _handler(
915
958
type = AuthenticationType .oauth2proxy
916
959
if isinstance (user , AuthenticatedAPIUser )
917
960
else AuthenticationType .token ,
918
- secretRef = SecretRef (name = server_name , key = "auth" , adopt = True ),
961
+ secretRef = SecretRefKey (name = server_name , key = "auth" , adopt = True ),
919
962
extraVolumeMounts = [
920
963
ExtraVolumeMount (name = "renku-authorized-emails" , mountPath = "/authorized_emails" )
921
964
]
922
965
if isinstance (user , AuthenticatedAPIUser )
923
966
else [],
924
967
),
968
+ dataSources = data_sources ,
925
969
),
926
970
)
927
971
parsed_proxy_url = urlparse (urljoin (server .server_url + "/" , "oauth2" ))
@@ -952,12 +996,14 @@ async def _handler(
952
996
"verbose" : True ,
953
997
}
954
998
)
955
- secret = V1Secret (metadata = V1ObjectMeta (name = server_name ), string_data = secret_data )
956
- secret = await self .nb_config .k8s_v2_client .create_secret (secret )
999
+ secrets_to_create .append (V1Secret (metadata = V1ObjectMeta (name = server_name ), string_data = secret_data ))
1000
+ for s in secrets_to_create :
1001
+ await self .nb_config .k8s_v2_client .create_secret (s )
957
1002
try :
958
1003
manifest = await self .nb_config .k8s_v2_client .create_server (manifest , user .id )
959
1004
except Exception :
960
- await self .nb_config .k8s_v2_client .delete_secret (secret .metadata .name )
1005
+ for s in secrets_to_create :
1006
+ await self .nb_config .k8s_v2_client .delete_secret (s .metadata .name )
961
1007
raise errors .ProgrammingError (message = "Could not start the amalthea session" )
962
1008
963
1009
return json (manifest .as_apispec ().model_dump (mode = "json" , exclude_none = True ), 201 )
@@ -1074,6 +1120,6 @@ async def _handler(
1074
1120
query : apispec .SessionsSessionIdLogsGetParametersQuery ,
1075
1121
) -> HTTPResponse :
1076
1122
logs = await self .nb_config .k8s_v2_client .get_server_logs (session_id , user .id , query .max_lines )
1077
- return json (apispec .SessionLogsResponse .model_validate (logs ).model_dump_json (exclude_none = True ))
1123
+ return json (apispec .SessionLogsResponse .model_validate (logs ).model_dump (exclude_none = True ))
1078
1124
1079
1125
return "/sessions/<session_id>/logs" , ["GET" ], _handler
0 commit comments