diff --git a/contributing/PROXY.md b/contributing/PROXY.md index bc79c4fbb..6c738e999 100644 --- a/contributing/PROXY.md +++ b/contributing/PROXY.md @@ -127,7 +127,7 @@ There are also similar gateway-specific helper functions to obtain gateway-speci ## Gateway operations -Gateway instances are managed by the `dstack` server. A gateway is associated with a project and some backend in the project. In `dstack` Sky, there is also a global gateway associated with all projects. +Gateway instances are managed by the `dstack` server. A gateway is associated with a project and some backend in the project. Gateways can be shared between projects using Exports. ### Creation diff --git a/src/dstack/_internal/server/background/pipeline_tasks/gateways.py b/src/dstack/_internal/server/background/pipeline_tasks/gateways.py index 05393eb1a..5c834c852 100644 --- a/src/dstack/_internal/server/background/pipeline_tasks/gateways.py +++ b/src/dstack/_internal/server/background/pipeline_tasks/gateways.py @@ -9,7 +9,6 @@ from dstack._internal.core.backends.base.compute import ComputeWithGatewaySupport from dstack._internal.core.errors import BackendError, BackendNotAvailable -from dstack._internal.core.models.backends.base import BackendType from dstack._internal.core.models.gateways import GATEWAY_REPLICAS_DEFAULT, GatewayStatus from dstack._internal.server.background.pipeline_tasks.base import ( Fetcher, @@ -425,13 +424,11 @@ async def _process_provisioning_gateway(gateway_model: GatewayModel) -> _Provisi # Provisioning gateways must have compute. assert len(gateway_computes) > 0 - # FIXME: problems caused by blocking on connect_to_gateway_with_retry and configure_gateway: + # TODO: do only one connection/configuration attempt per pipeline tick. + # Blocking on connect_to_gateway_with_retry and configure_gateway now has these cons: # - cannot delete the gateway before it is provisioned because the DB model is locked # - connection retry counter is reset on server restart # - only one server replica is processing the gateway - # Easy to fix by doing only one connection/configuration attempt per processing iteration. The - # main challenge is applying the same provisioning model to the dstack Sky gateway to avoid - # maintaining a different model for Sky. errors = await asyncio.gather( *(_connect_and_configure_gateway_replica(gateway_model, gc) for gc in gateway_computes) @@ -580,7 +577,6 @@ class _ProcessToBeDeletedResult: async def _process_to_be_deleted_gateway(gateway_model: GatewayModel) -> _ProcessToBeDeletedResult: - assert gateway_model.backend.type != BackendType.DSTACK backend = await backends_services.get_project_backend_by_type_or_error( project=gateway_model.project, backend_type=gateway_model.backend.type ) diff --git a/src/dstack/_internal/server/services/exports.py b/src/dstack/_internal/server/services/exports.py index 4c9299886..276374646 100644 --- a/src/dstack/_internal/server/services/exports.py +++ b/src/dstack/_internal/server/services/exports.py @@ -12,7 +12,6 @@ ResourceNotExistsError, ServerClientError, ) -from dstack._internal.core.models.backends.base import BackendType from dstack._internal.core.models.exports import ( Export, ExportedFleet, @@ -401,8 +400,6 @@ async def add_exported_gateways( session=session, project=export.project, load_backend_type=True ) gateways = [g for g in gateways if g.name in names] - if any(g.backend.type == BackendType.DSTACK for g in gateways): - raise ServerClientError("Exporting the built-in dstack Sky gateway is not allowed") if missing := set(names) - {g.name for g in gateways}: raise ResourceNotExistsError( f"Gateways {missing} not found in project {export.project.name!r}" diff --git a/src/dstack/_internal/server/services/gateways/__init__.py b/src/dstack/_internal/server/services/gateways/__init__.py index bfd05cecf..e81dbf704 100644 --- a/src/dstack/_internal/server/services/gateways/__init__.py +++ b/src/dstack/_internal/server/services/gateways/__init__.py @@ -297,7 +297,6 @@ async def create_gateway( return gateway_model_to_gateway(gateway, default_gateway_id=default_gateway.id) -# NOTE: dstack Sky imports and uses this function async def connect_to_gateway_with_retry( gateway_compute: GatewayComputeModel, ) -> Optional[GatewayConnection]: @@ -370,9 +369,6 @@ async def delete_gateways( raise ServerClientError( "Failed to delete gateways: gateways are being processed currently. Try again later." ) - for gateway_model in gateway_models: - if gateway_model.backend.type == BackendType.DSTACK: - raise ServerClientError("Cannot delete dstack Sky gateway") for gateway_model in gateway_models: if not gateway_model.to_be_deleted: gateway_model.to_be_deleted = True @@ -397,8 +393,6 @@ async def set_gateway_wildcard_domain( ) as gateway: if gateway is None: raise ResourceNotExistsError() - if gateway.backend.type == BackendType.DSTACK: - raise ServerClientError("Custom domains for dstack Sky gateway are not supported") old_domain = gateway.wildcard_domain if old_domain != wildcard_domain: gateway.wildcard_domain = wildcard_domain @@ -758,7 +752,6 @@ def _get_gateway_compute_router_config( return compute_config.router -# NOTE: dstack Sky imports and uses this function async def configure_gateway( connection: GatewayConnection, attempts: int = GATEWAY_CONFIGURE_ATTEMPTS, @@ -839,9 +832,6 @@ def gateway_model_to_gateway( default_gateway_id: ID of the default gateway in the project where `gateway_model` is being viewed. Can be different from `gateway_model.project` if the gateway is imported. """ - backend_type = gateway_model.backend.type - if gateway_model.backend.type == BackendType.DSTACK: - backend_type = BackendType.AWS is_default = default_gateway_id == gateway_model.id configuration = get_gateway_configuration(gateway_model) configuration.default = is_default @@ -867,7 +857,7 @@ def gateway_model_to_gateway( name=gateway_model.name, project_name=gateway_model.project.name, hostname=gateway_hostname, - backend=backend_type, + backend=gateway_model.backend.type, region=gateway_model.region, wildcard_domain=gateway_model.wildcard_domain, default=is_default, diff --git a/src/tests/_internal/server/routers/test_exports.py b/src/tests/_internal/server/routers/test_exports.py index 9a21f2cb4..907dab95a 100644 --- a/src/tests/_internal/server/routers/test_exports.py +++ b/src/tests/_internal/server/routers/test_exports.py @@ -5,7 +5,6 @@ from sqlalchemy import func, select from sqlalchemy.ext.asyncio import AsyncSession -from dstack._internal.core.models.backends.base import BackendType from dstack._internal.core.models.users import GlobalRole, ProjectRole from dstack._internal.server.models import ExportModel, ImportModel from dstack._internal.server.services.projects import add_project_member @@ -254,14 +253,6 @@ async def test_creates_global_export(self, session: AsyncSession, client: AsyncC "Fleets ['cloud-fleet'] are cloud fleets. Can only export SSH fleets", id="cloud-fleet", ), - pytest.param( - { - "name": "test-export", - "exported_gateways": ["sky-gateway"], - }, - "Exporting the built-in dstack Sky gateway is not allowed", - id="sky-gateway", - ), pytest.param( { "name": "test-export", @@ -321,15 +312,6 @@ async def test_rejects_invalid_export( backend_id=backend.id, name="exported-gateway", ) - sky_backend = await create_backend( - session=session, project_id=project.id, backend_type=BackendType.DSTACK - ) - await create_gateway( - session=session, - project_id=project.id, - backend_id=sky_backend.id, - name="sky-gateway", - ) not_permitted_project = await create_project( session=session, name="NotPermittedProject", owner=user ) @@ -733,14 +715,6 @@ async def test_can_add_same_entities_as_existing_deleted_ones( "Fleets ['cloud-fleet'] are cloud fleets. Can only export SSH fleets", id="add-cloud-fleet", ), - pytest.param( - { - "name": "test-export", - "add_exported_gateways": ["sky-gateway"], - }, - "Exporting the built-in dstack Sky gateway is not allowed", - id="add-sky-gateway", - ), pytest.param( { "name": "test-export", @@ -936,15 +910,6 @@ async def test_rejects_invalid_update( name="not-exported-fleet", spec=get_fleet_spec(get_ssh_fleet_configuration()), ) - sky_backend = await create_backend( - session=session, project_id=project.id, backend_type=BackendType.DSTACK - ) - await create_gateway( - session=session, - project_id=project.id, - backend_id=sky_backend.id, - name="sky-gateway", - ) not_importer_project = await create_project( session=session, name="NotImporterProject", owner=user )