Skip to content

Commit

Permalink
fix: Delete vfolder invitation and permission rows when deleting vfol…
Browse files Browse the repository at this point in the history
…ders (#2780)

Backported-from: main (24.09)
Backported-to: 24.03
Backport-of: 2780
  • Loading branch information
fregataa committed Sep 25, 2024
1 parent ba32a22 commit 80a351f
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 4 deletions.
1 change: 1 addition & 0 deletions changes/2780.fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Delete vfolder invitation and permission rows when deleting vfolders.
11 changes: 9 additions & 2 deletions src/ai/backend/manager/api/vfolder.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,11 @@
vfolder_status_map,
vfolders,
)
from ..models.utils import execute_with_retry
from ..models.utils import execute_with_retry, execute_with_txn_retry
from ..models.vfolder import (
VFolderPermissionRow,
delete_vfolder_relation_rows,
)
from .auth import admin_required, auth_required, superadmin_required
from .exceptions import (
BackendAgentError,
Expand Down Expand Up @@ -2254,9 +2258,12 @@ async def _delete(
permission=VFolderHostPermission.DELETE,
)

vfolder_row_ids = (entry["id"],)
async with root_ctx.db.connect() as db_conn:
await delete_vfolder_relation_rows(db_conn, root_ctx.db.begin_session, vfolder_row_ids)
await update_vfolder_status(
root_ctx.db,
(entry["id"],),
vfolder_row_ids,
VFolderOperationStatus.DELETE_PENDING,
)

Expand Down
57 changes: 55 additions & 2 deletions src/ai/backend/manager/models/vfolder.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,23 @@
import logging
import os.path
import uuid
from collections.abc import Container, Iterable, Mapping
from contextlib import AbstractAsyncContextManager as AbstractAsyncCtxMgr
from dataclasses import dataclass
from datetime import datetime
from pathlib import PurePosixPath
from typing import TYPE_CHECKING, Any, Final, List, Mapping, NamedTuple, Optional, Sequence
from typing import (
TYPE_CHECKING,
Any,
Callable,
Final,
List,
NamedTuple,
Optional,
Sequence,
TypeAlias,
cast,
)

import aiohttp
import aiotools
Expand Down Expand Up @@ -74,7 +88,7 @@
from .minilang.ordering import OrderSpecItem, QueryOrderParser
from .minilang.queryfilter import FieldSpecItem, QueryFilterParser, enum_field_getter
from .user import UserRole, UserRow
from .utils import ExtendedAsyncSAEngine, execute_with_retry, sql_json_merge
from .utils import ExtendedAsyncSAEngine, execute_with_retry, execute_with_txn_retry, sql_json_merge

if TYPE_CHECKING:
from ..api.context import BackgroundTaskManager
Expand Down Expand Up @@ -398,6 +412,12 @@ class VFolderCloneInfo(NamedTuple):
)


class VFolderInvitationRow(Base):
__table__ = vfolder_invitations

vfolder_row = relationship("VFolderRow", back_populates="invitation_rows")


vfolder_permissions = sa.Table(
"vfolder_permissions",
metadata,
Expand Down Expand Up @@ -426,6 +446,8 @@ class VFolderRow(Base):
back_populates="vfolder_rows",
primaryjoin="GroupRow.id == foreign(VFolderRow.group)",
)
permission_rows = relationship(VFolderPermissionRow, back_populates="vfolder_row")
invitation_rows = relationship(VFolderInvitationRow, back_populates="vfolder_row")

@classmethod
async def get(
Expand Down Expand Up @@ -1144,6 +1166,34 @@ async def _update_source_vfolder() -> None:
return task_id, target_folder_id.folder_id


async def _delete_vfolder_permission_rows(
db_session: SASession,
vfolder_row_ids: Iterable[uuid.UUID],
) -> None:
stmt = sa.delete(VFolderInvitationRow).where(VFolderInvitationRow.vfolder.in_(vfolder_row_ids))
await db_session.execute(stmt)


async def _delete_vfolder_invitation_rows(
db_session: SASession,
vfolder_row_ids: Iterable[uuid.UUID],
) -> None:
stmt = sa.delete(VFolderPermissionRow).where(VFolderPermissionRow.vfolder.in_(vfolder_row_ids))
await db_session.execute(stmt)


async def delete_vfolder_relation_rows(
db_conn: SAConnection,
begin_session: Callable[..., AbstractAsyncCtxMgr[SASession]],
vfolder_row_ids: Iterable[uuid.UUID],
) -> None:
async def _delete(db_session: SASession) -> None:
await _delete_vfolder_invitation_rows(db_session, vfolder_row_ids)
await _delete_vfolder_permission_rows(db_session, vfolder_row_ids)

await execute_with_txn_retry(_delete, begin_session, db_conn)


async def initiate_vfolder_deletion(
db_engine: ExtendedAsyncSAEngine,
requested_vfolders: Sequence[VFolderDeletionInfo],
Expand All @@ -1158,6 +1208,9 @@ async def initiate_vfolder_deletion(
return 0
elif vfolder_info_len == 1:
vfolders.c.id == vfolder_ids[0]

async with db_engine.connect() as db_conn:
await delete_vfolder_relation_rows(db_conn, db_engine.begin_session, vfolder_ids)
await update_vfolder_status(
db_engine, vfolder_ids, VFolderOperationStatus.DELETE_ONGOING, do_log=False
)
Expand Down

0 comments on commit 80a351f

Please sign in to comment.