From d57f61dbb4d3d4720edda4319f5d304c9b580d66 Mon Sep 17 00:00:00 2001 From: Victor Skvortsov Date: Tue, 15 Aug 2023 15:43:29 +0500 Subject: [PATCH] Show error on dstack init if no backends configured --- .../_internal/cli/commands/init/__init__.py | 8 ++++++++ cli/dstack/api/hub/_api_client.py | 18 ++++++++++++++++++ cli/dstack/api/hub/_client.py | 11 +++++++---- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/cli/dstack/_internal/cli/commands/init/__init__.py b/cli/dstack/_internal/cli/commands/init/__init__.py index 6d7d56259..561344aaf 100644 --- a/cli/dstack/_internal/cli/commands/init/__init__.py +++ b/cli/dstack/_internal/cli/commands/init/__init__.py @@ -80,6 +80,14 @@ def _command(self, args: Namespace): ) ) hub_client = get_hub_client(project_name=args.project) + backends = hub_client.list_backends() + if len(backends) == 0: + add_backends_url = ( + f"{hub_client.client_config.url}/projects/{hub_client.project}/backends/add" + ) + raise CLIError( + f"No backends configured. To configure a backend, open {add_backends_url}" + ) if repo_credentials is not None: hub_client.save_repo_credentials(repo_credentials) console.print(f"[green]OK[/]") diff --git a/cli/dstack/api/hub/_api_client.py b/cli/dstack/api/hub/_api_client.py index 1d8133237..dcb171d37 100644 --- a/cli/dstack/api/hub/_api_client.py +++ b/cli/dstack/api/hub/_api_client.py @@ -25,6 +25,7 @@ from dstack._internal.hub.schemas import ( AddTagRun, ArtifactsList, + BackendInfo, JobHeadList, JobsGet, JobsList, @@ -75,6 +76,23 @@ def get_project_info(self) -> ProjectInfo: return ProjectInfo.parse_obj(resp.json()) resp.raise_for_status() + def list_backends(self) -> List[BackendInfo]: + url = _project_url( + url=self.url, + project=self.project, + additional_path=f"/backends/list", + ) + resp = _make_hub_request( + requests.post, + host=self.url, + url=url, + headers=self._headers(), + ) + if resp.ok: + body = resp.json() + return [BackendInfo.parse_obj(i) for i in body] + resp.raise_for_status() + def get_run_plan(self, jobs: List[Job], backends: Optional[List[str]]) -> RunPlan: url = _project_url( url=self.url, diff --git a/cli/dstack/api/hub/_client.py b/cli/dstack/api/hub/_client.py index 87856758a..cf7621160 100644 --- a/cli/dstack/api/hub/_client.py +++ b/cli/dstack/api/hub/_client.py @@ -20,7 +20,7 @@ from dstack._internal.core.run import RunHead from dstack._internal.core.secret import Secret from dstack._internal.core.tag import TagHead -from dstack._internal.hub.schemas import ProjectInfo, RunInfo +from dstack._internal.hub.schemas import BackendInfo, ProjectInfo, RunInfo from dstack.api.hub._api_client import HubAPIClient from dstack.api.hub._config import HubClientConfig from dstack.api.hub._storage import HUBStorage @@ -38,12 +38,12 @@ def __init__( ): self.project = project self.repo = repo + self.client_config = config self._repo_credentials = repo_credentials self._auto_init = auto_init - self._client_config = config self._api_client = HubAPIClient( - url=self._client_config.url, - token=self._client_config.token, + url=self.client_config.url, + token=self.client_config.token, project=self.project, repo=self.repo, ) @@ -55,6 +55,9 @@ def validate_config(config: HubClientConfig, project: str): url=config.url, token=config.token, project=project, repo=None ).get_project_info() + def list_backends(self) -> List[BackendInfo]: + return self._api_client.list_backends() + def create_run(self, run_name: Optional[str]) -> str: return self._api_client.create_run(run_name)