dstack 0.18.38__py3-none-any.whl → 0.18.40rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dstack/_internal/cli/services/configurators/fleet.py +1 -1
- dstack/_internal/cli/services/configurators/gateway.py +10 -1
- dstack/_internal/cli/utils/common.py +1 -2
- dstack/_internal/core/models/configurations.py +21 -0
- dstack/_internal/core/models/runs.py +1 -0
- dstack/_internal/core/models/volumes.py +9 -0
- dstack/_internal/core/services/logs.py +4 -1
- dstack/_internal/core/services/ssh/attach.py +6 -5
- dstack/_internal/proxy/lib/models.py +1 -0
- dstack/_internal/proxy/lib/testing/common.py +2 -0
- dstack/_internal/server/app.py +7 -3
- dstack/_internal/server/background/tasks/process_submitted_jobs.py +2 -2
- dstack/_internal/server/schemas/runner.py +1 -0
- dstack/_internal/server/services/fleets.py +1 -1
- dstack/_internal/server/services/jobs/configurators/base.py +10 -0
- dstack/_internal/server/services/jobs/configurators/dev.py +3 -0
- dstack/_internal/server/services/jobs/configurators/service.py +3 -0
- dstack/_internal/server/services/jobs/configurators/task.py +3 -0
- dstack/_internal/server/services/proxy/repo.py +1 -0
- dstack/_internal/server/services/proxy/services/service_proxy.py +4 -0
- dstack/_internal/server/services/runs.py +5 -4
- dstack/_internal/server/statics/index.html +1 -1
- dstack/_internal/server/statics/{main-623e02815ab7a6b56019.js → main-11ec5e4a00ea6ec833e3.js} +3 -3
- dstack/_internal/server/statics/{main-623e02815ab7a6b56019.js.map → main-11ec5e4a00ea6ec833e3.js.map} +1 -1
- dstack/api/_public/runs.py +8 -0
- dstack/api/server/__init__.py +19 -3
- dstack/api/server/_fleets.py +6 -1
- dstack/api/server/_runs.py +28 -8
- dstack/version.py +1 -1
- {dstack-0.18.38.dist-info → dstack-0.18.40rc1.dist-info}/METADATA +6 -7
- {dstack-0.18.38.dist-info → dstack-0.18.40rc1.dist-info}/RECORD +40 -40
- tests/_internal/core/services/test_logs.py +16 -6
- tests/_internal/server/background/tasks/test_process_submitted_jobs.py +74 -1
- tests/_internal/server/routers/test_runs.py +4 -0
- tests/_internal/server/services/proxy/routers/test_service_proxy.py +39 -0
- tests/_internal/server/services/runner/test_client.py +6 -2
- {dstack-0.18.38.dist-info → dstack-0.18.40rc1.dist-info}/LICENSE.md +0 -0
- {dstack-0.18.38.dist-info → dstack-0.18.40rc1.dist-info}/WHEEL +0 -0
- {dstack-0.18.38.dist-info → dstack-0.18.40rc1.dist-info}/entry_points.txt +0 -0
- {dstack-0.18.38.dist-info → dstack-0.18.40rc1.dist-info}/top_level.txt +0 -0
|
@@ -4,6 +4,7 @@ from unittest.mock import patch
|
|
|
4
4
|
import httpx
|
|
5
5
|
import pytest
|
|
6
6
|
from fastapi import FastAPI
|
|
7
|
+
from fastapi.responses import PlainTextResponse
|
|
7
8
|
|
|
8
9
|
from dstack._internal.proxy.gateway.repo.repo import GatewayProxyRepo
|
|
9
10
|
from dstack._internal.proxy.lib.auth import BaseProxyAuthProvider
|
|
@@ -25,6 +26,8 @@ ProxyTestRepo = GatewayProxyRepo
|
|
|
25
26
|
|
|
26
27
|
@pytest.fixture
|
|
27
28
|
def mock_replica_client_httpbin(httpbin) -> Generator[None, None, None]:
|
|
29
|
+
"""Mocks deployed services. Replaces them with httpbin"""
|
|
30
|
+
|
|
28
31
|
with patch(
|
|
29
32
|
"dstack._internal.proxy.lib.services.service_connection.ServiceConnectionPool.get_or_add"
|
|
30
33
|
) as add_connection_mock:
|
|
@@ -34,6 +37,20 @@ def mock_replica_client_httpbin(httpbin) -> Generator[None, None, None]:
|
|
|
34
37
|
yield
|
|
35
38
|
|
|
36
39
|
|
|
40
|
+
@pytest.fixture
|
|
41
|
+
def mock_replica_client_path_reporter() -> Generator[None, None, None]:
|
|
42
|
+
"""Mocks deployed services. Replaces them with an app that returns the requested path"""
|
|
43
|
+
|
|
44
|
+
app = FastAPI()
|
|
45
|
+
app.get("{path:path}")(lambda path: PlainTextResponse(path))
|
|
46
|
+
client = ServiceClient(base_url="http://test/", transport=httpx.ASGITransport(app))
|
|
47
|
+
with patch(
|
|
48
|
+
"dstack._internal.proxy.lib.services.service_connection.ServiceConnectionPool.get_or_add"
|
|
49
|
+
) as add_connection_mock:
|
|
50
|
+
add_connection_mock.return_value.client.return_value = client
|
|
51
|
+
yield
|
|
52
|
+
|
|
53
|
+
|
|
37
54
|
def make_app(
|
|
38
55
|
repo: BaseProxyRepo, auth: BaseProxyAuthProvider = ProxyTestAuthProvider()
|
|
39
56
|
) -> FastAPI:
|
|
@@ -200,3 +217,25 @@ async def test_auth(mock_replica_client_httpbin, token: Optional[str], status: i
|
|
|
200
217
|
url = "http://test-host/proxy/services/test-proj/httpbin/"
|
|
201
218
|
resp = await client.get(url, headers=headers)
|
|
202
219
|
assert resp.status_code == status
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
@pytest.mark.asyncio
|
|
223
|
+
@pytest.mark.parametrize(
|
|
224
|
+
("strip", "downstream_path", "upstream_path"),
|
|
225
|
+
[
|
|
226
|
+
(True, "/proxy/services/my-proj/my-run/", "/"),
|
|
227
|
+
(True, "/proxy/services/my-proj/my-run/a/b", "/a/b"),
|
|
228
|
+
(False, "/proxy/services/my-proj/my-run/", "/proxy/services/my-proj/my-run/"),
|
|
229
|
+
(False, "/proxy/services/my-proj/my-run/a/b", "/proxy/services/my-proj/my-run/a/b"),
|
|
230
|
+
],
|
|
231
|
+
)
|
|
232
|
+
async def test_strip_prefix(
|
|
233
|
+
mock_replica_client_path_reporter, strip: bool, downstream_path: str, upstream_path: str
|
|
234
|
+
) -> None:
|
|
235
|
+
repo = ProxyTestRepo()
|
|
236
|
+
await repo.set_project(make_project("my-proj"))
|
|
237
|
+
await repo.set_service(make_service("my-proj", "my-run", strip_prefix=strip))
|
|
238
|
+
_, client = make_app_client(repo)
|
|
239
|
+
resp = await client.get(f"http://test-host{downstream_path}")
|
|
240
|
+
assert resp.status_code == 200
|
|
241
|
+
assert resp.text == upstream_path
|
|
@@ -175,7 +175,9 @@ class TestShimClientV1(BaseShimClientTest):
|
|
|
175
175
|
"device_name": "/dev/sdv",
|
|
176
176
|
}
|
|
177
177
|
],
|
|
178
|
-
"instance_mounts": [
|
|
178
|
+
"instance_mounts": [
|
|
179
|
+
{"instance_path": "/mnt/nfs/home", "path": "/home", "optional": False}
|
|
180
|
+
],
|
|
179
181
|
}
|
|
180
182
|
self.assert_request(adapter, 0, "POST", "/api/submit", expected_request)
|
|
181
183
|
|
|
@@ -341,7 +343,9 @@ class TestShimClientV2(BaseShimClientTest):
|
|
|
341
343
|
}
|
|
342
344
|
],
|
|
343
345
|
"volume_mounts": [{"name": "vol", "path": "/vol"}],
|
|
344
|
-
"instance_mounts": [
|
|
346
|
+
"instance_mounts": [
|
|
347
|
+
{"instance_path": "/mnt/nfs/home", "path": "/home", "optional": False}
|
|
348
|
+
],
|
|
345
349
|
"host_ssh_user": "dstack",
|
|
346
350
|
"host_ssh_keys": ["host_key"],
|
|
347
351
|
"container_ssh_keys": ["project_key", "user_key"],
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|