Skip to content

Commit 1c2a7bd

Browse files
authored
Fix CLI incompatibility with older /get_my_user (#3198)
1 parent 220a1fa commit 1c2a7bd

File tree

2 files changed

+20
-4
lines changed

2 files changed

+20
-4
lines changed

src/dstack/api/_public/runs.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
get_service_port,
4949
)
5050
from dstack._internal.core.models.runs import Run as RunModel
51+
from dstack._internal.core.models.users import UserWithCreds
5152
from dstack._internal.core.services.configs import ConfigManager
5253
from dstack._internal.core.services.logs import URLReplacer
5354
from dstack._internal.core.services.ssh.attach import SSHAttach
@@ -283,7 +284,7 @@ def attach(
283284
user = self._api_client.users.get_my_user()
284285
run_ssh_key_pub = self._run.run_spec.ssh_key_pub
285286
config_manager = ConfigManager()
286-
if user.ssh_public_key == run_ssh_key_pub:
287+
if isinstance(user, UserWithCreds) and user.ssh_public_key == run_ssh_key_pub:
287288
token_hash = hashlib.sha1(user.creds.token.encode()).hexdigest()[:8]
288289
config_manager.dstack_ssh_dir.mkdir(parents=True, exist_ok=True)
289290
ssh_identity_file = config_manager.dstack_ssh_dir / token_hash

src/dstack/api/server/_users.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import List
22

3-
from pydantic import parse_obj_as
3+
from pydantic import ValidationError, parse_obj_as
44

55
from dstack._internal.core.models.users import GlobalRole, User, UserWithCreds
66
from dstack._internal.server.schemas.users import (
@@ -17,9 +17,24 @@ def list(self) -> List[User]:
1717
resp = self._request("/api/users/list")
1818
return parse_obj_as(List[User.__response__], resp.json())
1919

20-
def get_my_user(self) -> UserWithCreds:
20+
def get_my_user(self) -> User:
21+
"""
22+
Returns `User` with pre-0.19.33 servers, or `UserWithCreds` with newer servers.
23+
"""
24+
2125
resp = self._request("/api/users/get_my_user")
22-
return parse_obj_as(UserWithCreds.__response__, resp.json())
26+
try:
27+
return parse_obj_as(UserWithCreds.__response__, resp.json())
28+
except ValidationError as e:
29+
# Compatibility with pre-0.19.33 server
30+
if (
31+
len(e.errors()) == 1
32+
and e.errors()[0]["loc"] == ("__root__", "creds")
33+
and e.errors()[0]["type"] == "value_error.missing"
34+
):
35+
return parse_obj_as(User.__response__, resp.json())
36+
else:
37+
raise
2338

2439
def get_user(self, username: str) -> User:
2540
body = GetUserRequest(username=username)

0 commit comments

Comments
 (0)