From 91a3e0b8c3d0da7fe6a1d4a4ba23e67572941d23 Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Mon, 10 Jul 2023 14:32:13 +0200 Subject: [PATCH 01/19] www subdomain --- applications/osb-portal/deploy/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/osb-portal/deploy/values.yaml b/applications/osb-portal/deploy/values.yaml index 487dad53..ffd00262 100644 --- a/applications/osb-portal/deploy/values.yaml +++ b/applications/osb-portal/deploy/values.yaml @@ -1,5 +1,5 @@ harness: - subdomain: app + subdomain: www secured: false deployment: auto: true From edb51f26a74e668ce6dd5ca6e660cddc72f7b9eb Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Mon, 10 Jul 2023 18:32:31 +0200 Subject: [PATCH 02/19] Fix resources not copied on ws creation --- .../server/workspaces/service/crud_service.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/applications/workspaces/server/workspaces/service/crud_service.py b/applications/workspaces/server/workspaces/service/crud_service.py index 89f46abf..8975fc23 100644 --- a/applications/workspaces/server/workspaces/service/crud_service.py +++ b/applications/workspaces/server/workspaces/service/crud_service.py @@ -188,6 +188,9 @@ def post(self, body): create_volume(name=self.get_pvc_name(workspace.id), size=self.get_workspace_volume_size(workspace)) + + for workspace_resource in workspace.resources: + WorkspaceresourceService.handle_resource_data(workspace_resource) return workspace def put(self, body, id_): @@ -453,10 +456,14 @@ def dict_to_dto(cls, d) -> WorkspaceResource: def post(self, body) -> WorkspaceResource: workspace_resource = super().post(body) - if workspace_resource.status == "p" and workspace_resource.origin: + self.handle_resource_data(workspace_resource) + return workspace_resource + + @staticmethod + def handle_resource_data(workspace_resource: WorkspaceResource) -> WorkspaceResource: + if workspace_resource.status == "p" and workspace_resource.origin: from workspaces.helpers.etl_helpers import copy_workspace_resource copy_workspace_resource(workspace_resource) - return workspace_resource def is_authorized(self, resource: WorkspaceResourceEntity): # A resource is authorized if belongs to an authorized workspace From def70edeeda9918430753bfabce5ebf66a8464b4 Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Mon, 10 Jul 2023 18:34:43 +0200 Subject: [PATCH 03/19] Fix empty workspaces list with unlogged user --- applications/osb-portal/src/pages/WorkspacesPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/osb-portal/src/pages/WorkspacesPage.tsx b/applications/osb-portal/src/pages/WorkspacesPage.tsx index f9ce7832..8b6bae0f 100644 --- a/applications/osb-portal/src/pages/WorkspacesPage.tsx +++ b/applications/osb-portal/src/pages/WorkspacesPage.tsx @@ -286,7 +286,7 @@ export const WorkspacesPage = (props: WorkspacesPageProps) => { - {workspaces?.length === 0 ? ( + {workspaces?.length === 0 && props.user ? ( Date: Tue, 11 Jul 2023 09:40:35 +0200 Subject: [PATCH 04/19] Fix resources not copied on ws creation --- .../server/workspaces/service/crud_service.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/applications/workspaces/server/workspaces/service/crud_service.py b/applications/workspaces/server/workspaces/service/crud_service.py index 8975fc23..cef0276e 100644 --- a/applications/workspaces/server/workspaces/service/crud_service.py +++ b/applications/workspaces/server/workspaces/service/crud_service.py @@ -181,16 +181,18 @@ def post(self, body): if 'user_id' not in body: body['user_id'] = keycloak_user_id() self.check_max_num_workspaces_per_user(body['user_id']) - for r in body.get("resources", []): - r.update({"origin": json.dumps(r.get("origin"))}) - workspace = Workspace.from_dict(body) # Validate + + workspace = super().post(body) + create_volume(name=self.get_pvc_name(workspace.id), size=self.get_workspace_volume_size(workspace)) - + + for workspace_resource in workspace.resources: WorkspaceresourceService.handle_resource_data(workspace_resource) + return workspace def put(self, body, id_): @@ -279,9 +281,12 @@ def to_dto(cls, workspace_entity: TWorkspaceEntity) -> Workspace: @classmethod def to_dao(cls, d: dict) -> TWorkspaceEntity: - + + resources = d.get("resources", []) + d["resources"] = [] workspace: TWorkspaceEntity = super().to_dao(d) workspace.tags = TagRepository().get_tags_daos(workspace.tags) + workspace.resources = [WorkspaceresourceService.to_dao(r) for r in resources] return workspace def get(self, id_): @@ -424,7 +429,8 @@ class WorkspaceresourceService(BaseModelService): @classmethod def to_dao(cls, ws_dict: dict) -> TWorkspaceResourceEntity: if "origin" in ws_dict: - ws_dict.update({"origin": json.dumps(ws_dict.get("origin"))}) + wro_dao_dict = dict(ws_dict.get("origin")) + ws_dict.update({"origin": json.dumps(wro_dao_dict)}) workspace_resource = super().to_dao(ws_dict) if not workspace_resource.resource_type or workspace_resource.resource_type == "u": From ac5c3209078c124bfb4d172c73c19d138df06d2a Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Tue, 11 Jul 2023 16:50:58 +0200 Subject: [PATCH 05/19] Fix resources dto mapping --- .../server/workspaces/service/crud_service.py | 14 +++++++++----- applications/workspaces/server/workspaces/utils.py | 12 +++++++++--- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/applications/workspaces/server/workspaces/service/crud_service.py b/applications/workspaces/server/workspaces/service/crud_service.py index cef0276e..231ff0d8 100644 --- a/applications/workspaces/server/workspaces/service/crud_service.py +++ b/applications/workspaces/server/workspaces/service/crud_service.py @@ -192,7 +192,7 @@ def post(self, body): for workspace_resource in workspace.resources: WorkspaceresourceService.handle_resource_data(workspace_resource) - + return workspace def put(self, body, id_): @@ -274,9 +274,13 @@ def search(self, page=1, per_page=20, *args, **kwargs) -> Pagination: @classmethod def to_dto(cls, workspace_entity: TWorkspaceEntity) -> Workspace: - workspace = super().to_dto(workspace_entity) - if not workspace.resources: - workspace.resources = [] + if not workspace_entity.resources: + workspace_entity.resources = [] + + workspace = cls.dict_to_dto(dao_entity2dict(workspace_entity)) + for resource in workspace_entity.resources: + resource.origin = json.loads(resource.origin) + workspace.resources = [WorkspaceresourceService.to_dto(r) for r in workspace_entity.resources] return workspace @classmethod @@ -443,7 +447,7 @@ def to_dao(cls, ws_dict: dict) -> TWorkspaceResourceEntity: @classmethod def dict_to_dto(cls, d) -> WorkspaceResource: - if 'origin' in d: + if 'origin' in d and isinstance(d['origin'], str): d['origin'] = json.loads(d['origin']) workspace_resource: WorkspaceResource = super().dict_to_dto(d) diff --git a/applications/workspaces/server/workspaces/utils.py b/applications/workspaces/server/workspaces/utils.py index 3a393e69..6c06661e 100644 --- a/applications/workspaces/server/workspaces/utils.py +++ b/applications/workspaces/server/workspaces/utils.py @@ -5,7 +5,7 @@ from cloudharness import log as logger from cloudharness.auth import AuthClient -from workspaces.models import WorkspaceResourceEntity, ResourceType +from workspaces.models import WorkspaceResourceEntity, ResourceType, WorkspaceEntity def get_keycloak_data(): @@ -27,18 +27,24 @@ def get_pvc_name(workspace_id): disallowed_class_types = ["BaseQuery", "type", "registry", "MetaData"] name_mappings = {WorkspaceResourceEntity.__name__: {"folder": "path"}} +exclude = { WorkspaceEntity.__name__: {"resources"} } def dao_entity2dict(obj): + disallowed_names = {name for name, value in getmembers( - type(obj)) if isinstance(value, FunctionType)} + type(obj)) if isinstance(value, FunctionType) or name in exclude.get(type(obj).__name__, ())} + result = {} for name in dir(obj): - if name[0] != "_" and name not in disallowed_names and hasattr(obj, name): + + if name not in disallowed_names and name[0] != "_" and hasattr(obj, name): val = getattr(obj, name) if not ismethod(val): clas = val.__class__.__name__ + if hasattr(val.__class__, "to_dict"): + val = val.__class__.to_dict(val) if clas == "InstrumentedList": val = list(dao_entity2dict(r) for r in val) if clas not in disallowed_class_types: From e89bd08fff5eb9b23db2b32e420300ba16716596 Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Tue, 11 Jul 2023 17:47:43 +0200 Subject: [PATCH 06/19] Fix get workspaces --- .../controllers/crud/base_model_controller.py | 3 +-- .../server/workspaces/service/crud_service.py | 25 ++++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/applications/workspaces/server/workspaces/controllers/crud/base_model_controller.py b/applications/workspaces/server/workspaces/controllers/crud/base_model_controller.py index 0d175a7e..a663b199 100644 --- a/applications/workspaces/server/workspaces/controllers/crud/base_model_controller.py +++ b/applications/workspaces/server/workspaces/controllers/crud/base_model_controller.py @@ -25,7 +25,6 @@ def search(self, page=1, per_page=20, *args, **kwargs): """ objects = self.service.search( page=page, per_page=per_page, *args, **kwargs) - obj_dicts = list(map(lambda obj: dao_entity2dict(obj), objects.items)) list_name = str(self.service.repository) list_name_plural = list_name[:-1] + \ list_name[-1:].replace("y", "ie") + "s" @@ -35,7 +34,7 @@ def search(self, page=1, per_page=20, *args, **kwargs): "number_of_pages": objects.pages, "total": objects.total }, - list_name_plural: obj_dicts, + list_name_plural: objects.items, } def post(self, body): diff --git a/applications/workspaces/server/workspaces/service/crud_service.py b/applications/workspaces/server/workspaces/service/crud_service.py index 231ff0d8..45552e11 100644 --- a/applications/workspaces/server/workspaces/service/crud_service.py +++ b/applications/workspaces/server/workspaces/service/crud_service.py @@ -31,7 +31,7 @@ from workspaces.service.user_quota_service import get_pvc_size, get_max_workspaces_for_user from workspaces.utils import dao_entity2dict, guess_resource_type - +from ..database import db def rm_null_values(dikt): tmp = {} @@ -104,7 +104,7 @@ def search(self, page=1, per_page=20, *args, **kwargs) -> Pagination: for obj in objects.items: self._calculated_fields_populate(obj) - return objects + return [self.to_dto(obj) for obj in objects.items] @classmethod def to_dao(cls, d: dict): @@ -260,27 +260,28 @@ def search(self, page=1, per_page=20, *args, **kwargs) -> Pagination: if current_user_id is not None: # Admins see all workspaces, non admin users can see only their own workspaces if not get_auth_client().user_has_realm_role(user_id=current_user_id, role="administrator"): - objects = self.repository.search( + paged_results = self.repository.search( page=page, per_page=per_page, user_id=current_user_id, *args, **kwargs) else: - objects = self.repository.search( + paged_results = self.repository.search( page=page, per_page=per_page, user_id=current_user_id, show_all=True, *args, **kwargs) else: - objects = self.repository.search( + paged_results = self.repository.search( page=page, per_page=per_page, *args, **kwargs) - for obj in objects.items: - self._calculated_fields_populate(obj) - return objects + with db.session.no_autoflush: + paged_results.items = [self.to_dto(w) for w in paged_results.items] + + for obj in paged_results.items: + self._calculated_fields_populate(obj) + return paged_results @classmethod def to_dto(cls, workspace_entity: TWorkspaceEntity) -> Workspace: - if not workspace_entity.resources: - workspace_entity.resources = [] - + workspace = cls.dict_to_dto(dao_entity2dict(workspace_entity)) for resource in workspace_entity.resources: resource.origin = json.loads(resource.origin) - workspace.resources = [WorkspaceresourceService.to_dto(r) for r in workspace_entity.resources] + workspace.resources = [WorkspaceresourceService.to_dto(r) for r in workspace_entity.resources] if workspace_entity.resources else [] return workspace @classmethod From a442eb6a580813229c76f9819eae98f20950e60a Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Tue, 11 Jul 2023 18:54:41 +0200 Subject: [PATCH 07/19] fix crud backend issues --- .../workspaces/server/workspaces/service/crud_service.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/applications/workspaces/server/workspaces/service/crud_service.py b/applications/workspaces/server/workspaces/service/crud_service.py index 45552e11..13d4693a 100644 --- a/applications/workspaces/server/workspaces/service/crud_service.py +++ b/applications/workspaces/server/workspaces/service/crud_service.py @@ -104,7 +104,8 @@ def search(self, page=1, per_page=20, *args, **kwargs) -> Pagination: for obj in objects.items: self._calculated_fields_populate(obj) - return [self.to_dto(obj) for obj in objects.items] + objects.items = [self.to_dto(obj) for obj in objects.items] + return objects @classmethod def to_dao(cls, d: dict): @@ -354,7 +355,7 @@ def user(self, workspace): def delete(self, id): resource_repository = WorkspaceResourceRepository() - workspace = super().get(id) + workspace = self.repository.get(id) for resource in workspace.resources: logger.debug("deleting resource %s", resource.id) From e35e859c052b48745af6120c42830103f1ea490b Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Tue, 11 Jul 2023 19:29:26 +0200 Subject: [PATCH 08/19] Update netpyne --- applications/netpyne/Dockerfile | 2 +- .../workspaces/server/workspaces/service/crud_service.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/netpyne/Dockerfile b/applications/netpyne/Dockerfile index e7891f19..2d24a4d4 100644 --- a/applications/netpyne/Dockerfile +++ b/applications/netpyne/Dockerfile @@ -2,7 +2,7 @@ FROM node:14 as jsbuild ENV REPO=https://github.com/MetaCell/NetPyNE-UI.git ENV BRANCH_TAG=release/1.0.0-notebook-fix ENV FOLDER=netpyne -RUN echo "no-cache 2023-7-6-3" +RUN echo "no-cache 2023-7-11" RUN git clone $REPO -b $BRANCH_TAG $FOLDER RUN rm -Rf .git diff --git a/applications/workspaces/server/workspaces/service/crud_service.py b/applications/workspaces/server/workspaces/service/crud_service.py index 13d4693a..41135cc9 100644 --- a/applications/workspaces/server/workspaces/service/crud_service.py +++ b/applications/workspaces/server/workspaces/service/crud_service.py @@ -329,7 +329,7 @@ def get(self, id_): WorkspaceResource.from_dict( { "id": -1, - "name": "Importing resources into workspace", + "name": "Refreshing resources", "origin": {"path": fake_path}, "resource_type": ResourceType.U, "workspace_id": workspace.id, From d22d7aeb55866219a34d0fb0523125f4b4c5788f Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Wed, 12 Jul 2023 11:58:34 +0200 Subject: [PATCH 09/19] Delete ws fix --- .../workspaces/server/workspaces/service/crud_service.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/applications/workspaces/server/workspaces/service/crud_service.py b/applications/workspaces/server/workspaces/service/crud_service.py index 41135cc9..73c52e57 100644 --- a/applications/workspaces/server/workspaces/service/crud_service.py +++ b/applications/workspaces/server/workspaces/service/crud_service.py @@ -357,9 +357,10 @@ def delete(self, id): resource_repository = WorkspaceResourceRepository() workspace = self.repository.get(id) - for resource in workspace.resources: - logger.debug("deleting resource %s", resource.id) - resource_repository.delete(resource.id) + if workspace.resources: + for resource in workspace.resources: + logger.debug("deleting resource %s", resource.id) + resource_repository.delete(resource.id) logger.info("deleting workspace %s", id) super().delete(id) logger.info("deleted workspace %s", id) From 6ff9e55bc989b682ce768a4fa93adc9789c1a419 Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Wed, 12 Jul 2023 13:23:34 +0200 Subject: [PATCH 10/19] Fix Netpyne NYHeadModel download --- applications/netpyne/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/netpyne/Dockerfile b/applications/netpyne/Dockerfile index 2d24a4d4..e3906e25 100644 --- a/applications/netpyne/Dockerfile +++ b/applications/netpyne/Dockerfile @@ -79,7 +79,7 @@ RUN chown -R $NB_UID /opt/workspace/tutorials RUN ln -s /opt/workspace workspace RUN jupyter labextension disable @jupyterlab/hub-extension - +RUN wget --no-check-certificate -P $NP_LFPYKIT_HEAD_FILE https://www.parralab.org/nyhead/sa_nyhead.mat USER $NB_UID From a0566ee43722aa2888f2603e118878e6cb8f4b93 Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Wed, 12 Jul 2023 13:44:50 +0200 Subject: [PATCH 11/19] Fix Netpyne NYHeadModel download --- applications/netpyne/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/netpyne/Dockerfile b/applications/netpyne/Dockerfile index e3906e25..17f87785 100644 --- a/applications/netpyne/Dockerfile +++ b/applications/netpyne/Dockerfile @@ -79,7 +79,7 @@ RUN chown -R $NB_UID /opt/workspace/tutorials RUN ln -s /opt/workspace workspace RUN jupyter labextension disable @jupyterlab/hub-extension -RUN wget --no-check-certificate -P $NP_LFPYKIT_HEAD_FILE https://www.parralab.org/nyhead/sa_nyhead.mat +RUN wget --no-check-certificate -O $NP_LFPYKIT_HEAD_FILE https://www.parralab.org/nyhead/sa_nyhead.mat USER $NB_UID From a9b74a907be49067c04c4fc7710fe5665f306774 Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Fri, 14 Jul 2023 11:10:28 +0200 Subject: [PATCH 12/19] Small netpyne update --- applications/netpyne/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/netpyne/Dockerfile b/applications/netpyne/Dockerfile index 17f87785..ff605093 100644 --- a/applications/netpyne/Dockerfile +++ b/applications/netpyne/Dockerfile @@ -1,8 +1,8 @@ FROM node:14 as jsbuild ENV REPO=https://github.com/MetaCell/NetPyNE-UI.git -ENV BRANCH_TAG=release/1.0.0-notebook-fix +ENV BRANCH_TAG=release/1.0.0 ENV FOLDER=netpyne -RUN echo "no-cache 2023-7-11" +RUN echo "no-cache 2023-7-14" RUN git clone $REPO -b $BRANCH_TAG $FOLDER RUN rm -Rf .git From 81138aa28b7aa358640e5ced6cdfd0907613d81b Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Fri, 14 Jul 2023 15:42:53 +0200 Subject: [PATCH 13/19] #777 fix clone --- .../server/workspaces/service/crud_service.py | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/applications/workspaces/server/workspaces/service/crud_service.py b/applications/workspaces/server/workspaces/service/crud_service.py index 73c52e57..fea247b8 100644 --- a/applications/workspaces/server/workspaces/service/crud_service.py +++ b/applications/workspaces/server/workspaces/service/crud_service.py @@ -214,20 +214,16 @@ def clone(self, workspace_id): if workspace is None: raise Exception( f"Cannot clone workspace with id {workspace_id}: not found.") + workspace.user = None + workspace.id = None + workspace.name = f"Clone of {workspace.name}" + workspace.publicable = False + workspace.featured = False + workspace.timestamp_created = None + cloned = self.to_dao(workspace.to_dict()) + - cloned = dict( - name=f"Clone of {workspace['name']}", - tags=workspace['tags'], - user_id=user_id, - - description=workspace['description'], - publicable=False, - featured=False - ) - if workspace['thumbnail']: - cloned['thumbnail'] = workspace['thumbnail'] - - cloned = self.repository.post(cloned, do_post=False) + cloned = self.repository.post(cloned) create_volume(name=self.get_pvc_name(cloned.id), size=self.get_workspace_volume_size(workspace)) From a657aed02e764183b6b8ca104917c55c3c477ddd Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Fri, 14 Jul 2023 15:45:13 +0200 Subject: [PATCH 14/19] Fix iframe reference from www --- applications/osb-portal/src/utils.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/applications/osb-portal/src/utils.ts b/applications/osb-portal/src/utils.ts index deb419aa..495a2c99 100644 --- a/applications/osb-portal/src/utils.ts +++ b/applications/osb-portal/src/utils.ts @@ -14,9 +14,7 @@ export function getBaseDomain() { // Dev return window.APP_DOMAIN; } - return window.location.host.includes("app.") - ? window.location.host.split(".").slice(1).join(".") - : window.location.host; // remove the first part of the hostname + return window.location.host.replace("www.", ""); // remove the first part of the hostname } export function getApplicationDomain(app: OSBApplication) { From 90248c5461c263c3bfea1bf5ce394942ac4bb37a Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Fri, 28 Jul 2023 15:03:38 +0200 Subject: [PATCH 15/19] #777 fix workspace clone --- .../server/workspaces/service/crud_service.py | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/applications/workspaces/server/workspaces/service/crud_service.py b/applications/workspaces/server/workspaces/service/crud_service.py index fea247b8..84a16f96 100644 --- a/applications/workspaces/server/workspaces/service/crud_service.py +++ b/applications/workspaces/server/workspaces/service/crud_service.py @@ -210,24 +210,25 @@ def clone(self, workspace_id): user_id = keycloak_user_id() self.check_max_num_workspaces_per_user(user_id) from workspaces.service.workflow import clone_workspaces_content - workspace = self.get(workspace_id) - if workspace is None: - raise Exception( - f"Cannot clone workspace with id {workspace_id}: not found.") - workspace.user = None - workspace.id = None - workspace.name = f"Clone of {workspace.name}" - workspace.publicable = False - workspace.featured = False - workspace.timestamp_created = None - cloned = self.to_dao(workspace.to_dict()) - + with db.session.no_autoflush: + workspace = self.get(workspace_id) + if workspace is None: + raise Exception( + f"Cannot clone workspace with id {workspace_id}: not found.") + workspace.user = None + workspace.id = None + workspace.name = f"Clone of {workspace.name}" + workspace.publicable = False + workspace.featured = False + workspace.timestamp_created = None + cloned = self.to_dao(workspace.to_dict()) + - cloned = self.repository.post(cloned) + cloned = self.repository.post(cloned) - create_volume(name=self.get_pvc_name(cloned.id), - size=self.get_workspace_volume_size(workspace)) - clone_workspaces_content(workspace_id, cloned.id) + create_volume(name=self.get_pvc_name(cloned.id), + size=self.get_workspace_volume_size(workspace)) + clone_workspaces_content(workspace_id, cloned.id) return cloned def is_authorized(self, workspace): From b89d38db0a34c33be235b27ef7676b2e5d73b3e9 Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Fri, 28 Jul 2023 15:28:34 +0200 Subject: [PATCH 16/19] fix python requirement --- applications/workspaces/server/requirements.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/applications/workspaces/server/requirements.txt b/applications/workspaces/server/requirements.txt index 0c88b289..b2a88ba2 100644 --- a/applications/workspaces/server/requirements.txt +++ b/applications/workspaces/server/requirements.txt @@ -73,12 +73,9 @@ pytest-cov==3.0.0 pytest-randomly==1.2.3 python-dateutil==2.8.2 python-jose==3.3.0 -PyYAML==6.0 requests==2.27.1 requests-oauthlib==1.3.1 rsa==4.8 -ruamel.yaml==0.16.13 -ruamel.yaml.clib==0.2.6 sentry-sdk==0.14.4 six==1.16.0 SQLAlchemy==1.4.32 From 33f67c9903b5d5d90ef46c4aa8a4500037b16097 Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Fri, 28 Jul 2023 15:28:50 +0200 Subject: [PATCH 17/19] fix python requirement --- applications/workspaces/server/requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/applications/workspaces/server/requirements.txt b/applications/workspaces/server/requirements.txt index b2a88ba2..4cd709b2 100644 --- a/applications/workspaces/server/requirements.txt +++ b/applications/workspaces/server/requirements.txt @@ -56,7 +56,6 @@ platformdirs==2.5.1 pluggy==0.13.1 psycopg2-binary py==1.11.0 -pyaml==21.10.1 pyasn1==0.4.8 pyasn1-modules==0.2.8 pycodestyle==2.8.0 From 97178bb60cc6da48900aa284076d30cedcc54073 Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Fri, 28 Jul 2023 17:05:55 +0200 Subject: [PATCH 18/19] #777 fix workspace clone --- .../controllers/crud/base_model_controller.py | 5 +++-- .../controllers/crud/crud_controllers.py | 5 +++-- .../persistence/base_crud_persistence.py | 9 +++++++++ .../server/workspaces/service/crud_service.py | 20 ++++++++++++------- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/applications/workspaces/server/workspaces/controllers/crud/base_model_controller.py b/applications/workspaces/server/workspaces/controllers/crud/base_model_controller.py index a663b199..16d28034 100644 --- a/applications/workspaces/server/workspaces/controllers/crud/base_model_controller.py +++ b/applications/workspaces/server/workspaces/controllers/crud/base_model_controller.py @@ -1,8 +1,7 @@ from flask.views import MethodView from flask_sqlalchemy import Pagination -from workspaces.service.crud_service import BaseModelService, NotAuthorized -from workspaces.utils import dao_entity2dict +from workspaces.service.crud_service import BaseModelService, NotAuthorized, NotFoundException class BaseModelView(MethodView): @@ -51,6 +50,8 @@ def get(self, id_): obj = self.service.get(id_) except NotAuthorized: return "Access to the requested resources not authorized", 401 + except NotFoundException: + return f"{self.service.repository} with id {id_} not found.", 404 if obj is None: return f"{self.service.repository} with id {id_} not found.", 404 if isinstance(obj, dict): diff --git a/applications/workspaces/server/workspaces/controllers/crud/crud_controllers.py b/applications/workspaces/server/workspaces/controllers/crud/crud_controllers.py index 7c3750f2..e10baf98 100644 --- a/applications/workspaces/server/workspaces/controllers/crud/crud_controllers.py +++ b/applications/workspaces/server/workspaces/controllers/crud/crud_controllers.py @@ -8,11 +8,10 @@ WorkspaceService, WorkspaceresourceService, TagService, + NotFoundException ) -from workspaces.persistence.crud_persistence import OSBRepositoryRepository -from workspaces.utils import dao_entity2dict from workspaces.controllers.crud.base_model_controller import BaseModelView @@ -36,6 +35,8 @@ def get(self, id_, *args, **kwargs): osbrepository_ext = self.service.get(id_) except NotAuthorized: return "Access to the requested resources not authorized", 401 + except NotFoundException: + return f"{self.service.repository} with id {id_} not found.", 404 if osbrepository_ext is None: return f"{self.service.repository} with id {id_} not found.", 404 diff --git a/applications/workspaces/server/workspaces/persistence/base_crud_persistence.py b/applications/workspaces/server/workspaces/persistence/base_crud_persistence.py index cfd923e2..3ebc13f2 100644 --- a/applications/workspaces/server/workspaces/persistence/base_crud_persistence.py +++ b/applications/workspaces/server/workspaces/persistence/base_crud_persistence.py @@ -214,6 +214,15 @@ def set_timestamp_updated(self, obj): if hasattr(obj, "timestamp_updated"): setattr(obj, "timestamp_updated", func.now()) return obj + + def clone(self, id): + """Clone an object from the repository.""" + obj = self._get(id) + db.session.expunge(obj) + from sqlalchemy.orm.session import make_transient + make_transient(obj) + obj.id = None + return obj def save(self, obj): obj = self.set_timestamp_updated(obj) diff --git a/applications/workspaces/server/workspaces/service/crud_service.py b/applications/workspaces/server/workspaces/service/crud_service.py index 84a16f96..63d0eb48 100644 --- a/applications/workspaces/server/workspaces/service/crud_service.py +++ b/applications/workspaces/server/workspaces/service/crud_service.py @@ -44,6 +44,8 @@ def rm_null_values(dikt): class NotAuthorized(Exception): pass +class NotFoundException(Exception): + pass class NotAllowed(Exception): pass @@ -211,20 +213,22 @@ def clone(self, workspace_id): self.check_max_num_workspaces_per_user(user_id) from workspaces.service.workflow import clone_workspaces_content with db.session.no_autoflush: - workspace = self.get(workspace_id) + workspace = self.repository.clone(workspace_id) if workspace is None: - raise Exception( + raise NotFoundException( f"Cannot clone workspace with id {workspace_id}: not found.") + workspace.user = None - workspace.id = None workspace.name = f"Clone of {workspace.name}" workspace.publicable = False workspace.featured = False workspace.timestamp_created = None - cloned = self.to_dao(workspace.to_dict()) + workspace.resources = [] + + - cloned = self.repository.post(cloned) + cloned = self.repository.post(workspace) create_volume(name=self.get_pvc_name(cloned.id), size=self.get_workspace_volume_size(workspace)) @@ -435,8 +439,10 @@ def to_dao(cls, ws_dict: dict) -> TWorkspaceResourceEntity: if "origin" in ws_dict: wro_dao_dict = dict(ws_dict.get("origin")) ws_dict.update({"origin": json.dumps(wro_dao_dict)}) - - workspace_resource = super().to_dao(ws_dict) + if 'path' in ws_dict: + ws_dict['folder'] = ws_dict['path'] + del ws_dict['path'] + workspace_resource: TWorkspaceResourceEntity = super().to_dao(ws_dict) if not workspace_resource.resource_type or workspace_resource.resource_type == "u": origin = json.loads(workspace_resource.origin) workspace_resource.resource_type = guess_resource_type( From 53381fae804088faa926d2d139a5bfcea7306da1 Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Mon, 31 Jul 2023 10:04:09 +0200 Subject: [PATCH 19/19] #777 fix workspace clone user --- .../workspaces/server/workspaces/service/crud_service.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/workspaces/server/workspaces/service/crud_service.py b/applications/workspaces/server/workspaces/service/crud_service.py index 63d0eb48..a7bcba15 100644 --- a/applications/workspaces/server/workspaces/service/crud_service.py +++ b/applications/workspaces/server/workspaces/service/crud_service.py @@ -213,13 +213,13 @@ def clone(self, workspace_id): self.check_max_num_workspaces_per_user(user_id) from workspaces.service.workflow import clone_workspaces_content with db.session.no_autoflush: - workspace = self.repository.clone(workspace_id) + workspace: TWorkspaceEntity = self.repository.clone(workspace_id) if workspace is None: raise NotFoundException( f"Cannot clone workspace with id {workspace_id}: not found.") - workspace.user = None workspace.name = f"Clone of {workspace.name}" + workspace.user_id = user_id workspace.publicable = False workspace.featured = False workspace.timestamp_created = None