Skip to content

Commit 1d2e835

Browse files
committed
Prevent dstack Sky gateway deletion
1 parent 78527de commit 1d2e835

2 files changed

Lines changed: 10 additions & 3 deletions

File tree

src/dstack/_internal/server/background/pipeline_tasks/gateways.py

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

1010
from dstack._internal.core.backends.base.compute import ComputeWithGatewaySupport
1111
from dstack._internal.core.errors import BackendError, BackendNotAvailable
12+
from dstack._internal.core.models.backends.base import BackendType
1213
from dstack._internal.core.models.gateways import GatewayStatus
1314
from dstack._internal.server.background.pipeline_tasks.base import (
1415
Fetcher,
@@ -512,6 +513,7 @@ class _DeletedResult:
512513

513514

514515
async def _process_to_be_deleted_gateway(gateway_model: GatewayModel) -> _DeletedResult:
516+
assert gateway_model.backend.type != BackendType.DSTACK
515517
backend = await backends_services.get_project_backend_by_type_or_error(
516518
project=gateway_model.project, backend_type=gateway_model.backend.type
517519
)

src/dstack/_internal/server/services/gateways/__init__.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import httpx
1111
from sqlalchemy import func, select, update
1212
from sqlalchemy.ext.asyncio import AsyncSession
13-
from sqlalchemy.orm import selectinload
13+
from sqlalchemy.orm import joinedload, selectinload
1414

1515
import dstack._internal.utils.random_names as random_names
1616
from dstack._internal.core.backends.base.compute import (
@@ -42,6 +42,7 @@
4242
from dstack._internal.server import settings
4343
from dstack._internal.server.db import get_db, is_db_postgres, is_db_sqlite
4444
from dstack._internal.server.models import (
45+
BackendModel,
4546
GatewayComputeModel,
4647
GatewayModel,
4748
ProjectModel,
@@ -329,9 +330,10 @@ async def _delete_gateways_pipeline(
329330
GatewayModel.project_id == project.id,
330331
GatewayModel.lock_expires_at.is_(None),
331332
)
332-
.execution_options(populate_existing=True)
333+
.options(joinedload(GatewayModel.backend).load_only(BackendModel.type))
333334
.order_by(GatewayModel.id) # take locks in order
334-
.with_for_update(key_share=True, nowait=True)
335+
.with_for_update(key_share=True, nowait=True, of=GatewayModel)
336+
.execution_options(populate_existing=True)
335337
)
336338
gateway_models = res.scalars().all()
337339
if len(gateway_models) != len(gateways_ids):
@@ -340,6 +342,9 @@ async def _delete_gateways_pipeline(
340342
raise ServerClientError(
341343
"Failed to delete gateways: gateways are being processed currently. Try again later."
342344
)
345+
for gateway_model in gateway_models:
346+
if gateway_model.backend.type == BackendType.DSTACK:
347+
raise ServerClientError("Cannot delete dstack Sky gateway")
343348
for gateway_model in gateway_models:
344349
if not gateway_model.to_be_deleted:
345350
gateway_model.to_be_deleted = True

0 commit comments

Comments
 (0)