dstack 0.19.10__py3-none-any.whl → 0.19.11__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.

Potentially problematic release.


This version of dstack might be problematic. Click here for more details.

Files changed (39) hide show
  1. dstack/_internal/cli/commands/metrics.py +25 -10
  2. dstack/_internal/cli/commands/offer.py +2 -0
  3. dstack/_internal/cli/services/configurators/run.py +1 -1
  4. dstack/_internal/cli/utils/updates.py +13 -1
  5. dstack/_internal/core/backends/aws/compute.py +21 -9
  6. dstack/_internal/core/backends/azure/compute.py +7 -5
  7. dstack/_internal/core/backends/base/compute.py +9 -4
  8. dstack/_internal/core/backends/gcp/compute.py +43 -20
  9. dstack/_internal/core/backends/gcp/resources.py +18 -2
  10. dstack/_internal/core/backends/local/compute.py +4 -2
  11. dstack/_internal/core/models/configurations.py +2 -1
  12. dstack/_internal/core/models/runs.py +2 -1
  13. dstack/_internal/proxy/gateway/resources/nginx/00-log-format.conf +11 -1
  14. dstack/_internal/proxy/gateway/resources/nginx/service.jinja2 +12 -6
  15. dstack/_internal/proxy/gateway/services/stats.py +17 -3
  16. dstack/_internal/server/background/tasks/process_submitted_jobs.py +3 -3
  17. dstack/_internal/server/routers/repos.py +9 -4
  18. dstack/_internal/server/services/fleets.py +2 -2
  19. dstack/_internal/server/services/gateways/__init__.py +1 -1
  20. dstack/_internal/server/services/jobs/__init__.py +4 -4
  21. dstack/_internal/server/services/jobs/configurators/base.py +15 -1
  22. dstack/_internal/server/services/jobs/configurators/extensions/cursor.py +3 -1
  23. dstack/_internal/server/services/jobs/configurators/extensions/vscode.py +3 -1
  24. dstack/_internal/server/services/plugins.py +64 -32
  25. dstack/_internal/server/services/runs.py +2 -2
  26. dstack/_internal/server/services/volumes.py +1 -1
  27. dstack/_internal/server/statics/index.html +1 -1
  28. dstack/_internal/server/statics/{main-b4803049eac16aea9a49.js → main-5b9786c955b42bf93581.js} +5 -5
  29. dstack/_internal/server/statics/{main-b4803049eac16aea9a49.js.map → main-5b9786c955b42bf93581.js.map} +1 -1
  30. dstack/plugins/builtin/__init__.py +0 -0
  31. dstack/plugins/builtin/rest_plugin/__init__.py +18 -0
  32. dstack/plugins/builtin/rest_plugin/_models.py +48 -0
  33. dstack/plugins/builtin/rest_plugin/_plugin.py +127 -0
  34. dstack/version.py +2 -2
  35. {dstack-0.19.10.dist-info → dstack-0.19.11.dist-info}/METADATA +1 -2
  36. {dstack-0.19.10.dist-info → dstack-0.19.11.dist-info}/RECORD +39 -35
  37. {dstack-0.19.10.dist-info → dstack-0.19.11.dist-info}/WHEEL +0 -0
  38. {dstack-0.19.10.dist-info → dstack-0.19.11.dist-info}/entry_points.txt +0 -0
  39. {dstack-0.19.10.dist-info → dstack-0.19.11.dist-info}/licenses/LICENSE.md +0 -0
@@ -1,7 +1,6 @@
1
1
  from typing import List, Tuple
2
2
 
3
3
  from fastapi import APIRouter, Depends, Request, UploadFile
4
- from humanize import naturalsize
5
4
  from sqlalchemy.ext.asyncio import AsyncSession
6
5
 
7
6
  from dstack._internal.core.errors import ResourceNotExistsError, ServerClientError
@@ -20,6 +19,7 @@ from dstack._internal.server.utils.routers import (
20
19
  get_base_api_additional_responses,
21
20
  get_request_size,
22
21
  )
22
+ from dstack._internal.utils.common import sizeof_fmt
23
23
 
24
24
  router = APIRouter(
25
25
  prefix="/api/project/{project_name}/repos",
@@ -98,10 +98,15 @@ async def upload_code(
98
98
  ):
99
99
  request_size = get_request_size(request)
100
100
  if SERVER_CODE_UPLOAD_LIMIT > 0 and request_size > SERVER_CODE_UPLOAD_LIMIT:
101
+ diff_size_fmt = sizeof_fmt(request_size)
102
+ limit_fmt = sizeof_fmt(SERVER_CODE_UPLOAD_LIMIT)
103
+ if diff_size_fmt == limit_fmt:
104
+ diff_size_fmt = f"{request_size}B"
105
+ limit_fmt = f"{SERVER_CODE_UPLOAD_LIMIT}B"
101
106
  raise ServerClientError(
102
- f"Repo diff size is {naturalsize(request_size)}, which exceeds the limit of "
103
- f"{naturalsize(SERVER_CODE_UPLOAD_LIMIT)}. Use .gitignore to exclude large files from the repo. This "
104
- f"limit can be modified by setting the DSTACK_SERVER_CODE_UPLOAD_LIMIT_BYTES environment variable"
107
+ f"Repo diff size is {diff_size_fmt}, which exceeds the limit of {limit_fmt}."
108
+ " Use .gitignore to exclude large files from the repo."
109
+ " This limit can be modified by setting the DSTACK_SERVER_CODE_UPLOAD_LIMIT environment variable."
105
110
  )
106
111
  _, project = user_project
107
112
  await repos.upload_code(
@@ -237,7 +237,7 @@ async def get_plan(
237
237
  ) -> FleetPlan:
238
238
  # Spec must be copied by parsing to calculate merged_profile
239
239
  effective_spec = FleetSpec.parse_obj(spec.dict())
240
- effective_spec = apply_plugin_policies(
240
+ effective_spec = await apply_plugin_policies(
241
241
  user=user.name,
242
242
  project=project.name,
243
243
  spec=effective_spec,
@@ -342,7 +342,7 @@ async def create_fleet(
342
342
  spec: FleetSpec,
343
343
  ) -> Fleet:
344
344
  # Spec must be copied by parsing to calculate merged_profile
345
- spec = apply_plugin_policies(
345
+ spec = await apply_plugin_policies(
346
346
  user=user.name,
347
347
  project=project.name,
348
348
  spec=spec,
@@ -140,7 +140,7 @@ async def create_gateway(
140
140
  project: ProjectModel,
141
141
  configuration: GatewayConfiguration,
142
142
  ) -> Gateway:
143
- spec = apply_plugin_policies(
143
+ spec = await apply_plugin_policies(
144
144
  user=user.name,
145
145
  project=project.name,
146
146
  # Create pseudo spec until the gateway API is updated to accept spec
@@ -470,20 +470,20 @@ async def _detach_volume_from_job_instance(
470
470
  await run_async(
471
471
  compute.detach_volume,
472
472
  volume=volume,
473
- instance_id=jpd.instance_id,
473
+ provisioning_data=jpd,
474
474
  force=False,
475
475
  )
476
476
  # For some backends, the volume may be detached immediately
477
477
  detached = await run_async(
478
478
  compute.is_volume_detached,
479
479
  volume=volume,
480
- instance_id=jpd.instance_id,
480
+ provisioning_data=jpd,
481
481
  )
482
482
  else:
483
483
  detached = await run_async(
484
484
  compute.is_volume_detached,
485
485
  volume=volume,
486
- instance_id=jpd.instance_id,
486
+ provisioning_data=jpd,
487
487
  )
488
488
  if not detached and _should_force_detach_volume(job_model, job_spec.stop_duration):
489
489
  logger.info(
@@ -494,7 +494,7 @@ async def _detach_volume_from_job_instance(
494
494
  await run_async(
495
495
  compute.detach_volume,
496
496
  volume=volume,
497
- instance_id=jpd.instance_id,
497
+ provisioning_data=jpd,
498
498
  force=True,
499
499
  )
500
500
  # Let the next iteration check if force detach worked
@@ -10,6 +10,7 @@ from dstack._internal import settings
10
10
  from dstack._internal.core.errors import DockerRegistryError, ServerClientError
11
11
  from dstack._internal.core.models.common import RegistryAuth
12
12
  from dstack._internal.core.models.configurations import (
13
+ DEFAULT_REPO_DIR,
13
14
  PortMapping,
14
15
  PythonVersion,
15
16
  RunConfigurationType,
@@ -149,7 +150,8 @@ class JobConfigurator(ABC):
149
150
  commands = self.run_spec.configuration.commands
150
151
  elif shell_commands := self._shell_commands():
151
152
  entrypoint = [self._shell(), "-i", "-c"]
152
- commands = [_join_shell_commands(shell_commands)]
153
+ dstack_image_commands = self._dstack_image_commands()
154
+ commands = [_join_shell_commands(dstack_image_commands + shell_commands)]
153
155
  else: # custom docker image without commands
154
156
  image_config = await self._get_image_config()
155
157
  entrypoint = image_config.entrypoint or []
@@ -164,6 +166,18 @@ class JobConfigurator(ABC):
164
166
 
165
167
  return result
166
168
 
169
+ def _dstack_image_commands(self) -> List[str]:
170
+ if (
171
+ self.run_spec.configuration.image is not None
172
+ or self.run_spec.configuration.entrypoint is not None
173
+ ):
174
+ return []
175
+ return [
176
+ f"uv venv --prompt workflow --seed {DEFAULT_REPO_DIR}/.venv > /dev/null 2>&1",
177
+ f"echo 'source {DEFAULT_REPO_DIR}/.venv/bin/activate' >> ~/.bashrc",
178
+ f"source {DEFAULT_REPO_DIR}/.venv/bin/activate",
179
+ ]
180
+
167
181
  def _app_specs(self) -> List[AppSpec]:
168
182
  specs = []
169
183
  for i, pm in enumerate(filter_reserved_ports(self._ports())):
@@ -1,5 +1,7 @@
1
1
  from typing import List
2
2
 
3
+ from dstack._internal.core.models.configurations import DEFAULT_REPO_DIR
4
+
3
5
 
4
6
  class CursorDesktop:
5
7
  def __init__(
@@ -37,6 +39,6 @@ class CursorDesktop:
37
39
  return [
38
40
  "echo To open in Cursor, use link below:",
39
41
  "echo ''",
40
- f"echo ' cursor://vscode-remote/ssh-remote+{self.run_name}/workflow'", # TODO use $REPO_DIR
42
+ f"echo ' cursor://vscode-remote/ssh-remote+{self.run_name}{DEFAULT_REPO_DIR}'", # TODO use $REPO_DIR
41
43
  "echo ''",
42
44
  ]
@@ -1,5 +1,7 @@
1
1
  from typing import List
2
2
 
3
+ from dstack._internal.core.models.configurations import DEFAULT_REPO_DIR
4
+
3
5
 
4
6
  class VSCodeDesktop:
5
7
  def __init__(
@@ -37,6 +39,6 @@ class VSCodeDesktop:
37
39
  return [
38
40
  "echo To open in VS Code Desktop, use link below:",
39
41
  "echo ''",
40
- f"echo ' vscode://vscode-remote/ssh-remote+{self.run_name}/workflow'", # TODO use $REPO_DIR
42
+ f"echo ' vscode://vscode-remote/ssh-remote+{self.run_name}{DEFAULT_REPO_DIR}'", # TODO use $REPO_DIR
41
43
  "echo ''",
42
44
  ]
@@ -1,9 +1,11 @@
1
1
  import itertools
2
2
  from importlib import import_module
3
+ from typing import Dict
3
4
 
4
5
  from backports.entry_points_selectable import entry_points # backport for Python 3.9
5
6
 
6
7
  from dstack._internal.core.errors import ServerClientError
8
+ from dstack._internal.utils.common import run_async
7
9
  from dstack._internal.utils.logging import get_logger
8
10
  from dstack.plugins import ApplyPolicy, ApplySpec, Plugin
9
11
 
@@ -12,59 +14,89 @@ logger = get_logger(__name__)
12
14
 
13
15
  _PLUGINS: list[Plugin] = []
14
16
 
17
+ _BUILTIN_PLUGINS: Dict[str, str] = {"rest_plugin": "dstack.plugins.builtin.rest_plugin:RESTPlugin"}
15
18
 
16
- def load_plugins(enabled_plugins: list[str]):
17
- _PLUGINS.clear()
18
- plugins_entrypoints = entry_points(group="dstack.plugins")
19
- plugins_to_load = enabled_plugins.copy()
20
- for entrypoint in plugins_entrypoints:
21
- if entrypoint.name not in enabled_plugins:
22
- logger.info(
23
- ("Found not enabled plugin %s. Plugin will not be loaded."),
24
- entrypoint.name,
25
- )
26
- continue
19
+
20
+ class PluginEntrypoint:
21
+ def __init__(self, name: str, import_path: str, is_builtin: bool = False):
22
+ self.name = name
23
+ self.import_path = import_path
24
+ self.is_builtin = is_builtin
25
+
26
+ def load(self):
27
+ module_path, _, class_name = self.import_path.partition(":")
27
28
  try:
28
- module_path, _, class_name = entrypoint.value.partition(":")
29
29
  module = import_module(module_path)
30
+ plugin_class = getattr(module, class_name, None)
31
+ if plugin_class is None:
32
+ logger.warning(
33
+ ("Failed to load plugin %s: plugin class %s not found in module %s."),
34
+ self.name,
35
+ class_name,
36
+ module_path,
37
+ )
38
+ return None
39
+ if not issubclass(plugin_class, Plugin):
40
+ logger.warning(
41
+ ("Failed to load plugin %s: plugin class %s is not a subclass of Plugin."),
42
+ self.name,
43
+ class_name,
44
+ )
45
+ return None
46
+ return plugin_class()
30
47
  except ImportError:
31
48
  logger.warning(
32
49
  (
33
50
  "Failed to load plugin %s when importing %s."
34
51
  " Ensure the module is on the import path."
35
52
  ),
36
- entrypoint.name,
37
- entrypoint.value,
53
+ self.name,
54
+ self.import_path,
38
55
  )
39
- continue
40
- plugin_class = getattr(module, class_name, None)
41
- if plugin_class is None:
42
- logger.warning(
43
- ("Failed to load plugin %s: plugin class %s not found in module %s."),
56
+ return None
57
+
58
+
59
+ def load_plugins(enabled_plugins: list[str]):
60
+ _PLUGINS.clear()
61
+ entrypoints: dict[str, PluginEntrypoint] = {}
62
+ plugins_to_load = enabled_plugins.copy()
63
+ for entrypoint in entry_points(group="dstack.plugins"):
64
+ if entrypoint.name not in enabled_plugins:
65
+ logger.info(
66
+ ("Found not enabled plugin %s. Plugin will not be loaded."),
44
67
  entrypoint.name,
45
- class_name,
46
- module_path,
47
68
  )
48
69
  continue
49
- if not issubclass(plugin_class, Plugin):
50
- logger.warning(
51
- ("Failed to load plugin %s: plugin class %s is not a subclass of Plugin."),
52
- entrypoint.name,
53
- class_name,
70
+ else:
71
+ entrypoints[entrypoint.name] = PluginEntrypoint(
72
+ entrypoint.name, entrypoint.value, is_builtin=False
54
73
  )
55
- continue
56
- plugins_to_load.remove(entrypoint.name)
57
- _PLUGINS.append(plugin_class())
58
- logger.info("Loaded plugin %s", entrypoint.name)
74
+
75
+ for name, import_path in _BUILTIN_PLUGINS.items():
76
+ if name not in enabled_plugins:
77
+ logger.info(
78
+ ("Found not enabled builtin plugin %s. Plugin will not be loaded."),
79
+ name,
80
+ )
81
+ else:
82
+ entrypoints[name] = PluginEntrypoint(name, import_path, is_builtin=True)
83
+
84
+ for plugin_name, plugin_entrypoint in entrypoints.items():
85
+ plugin_instance = plugin_entrypoint.load()
86
+ if plugin_instance is not None:
87
+ _PLUGINS.append(plugin_instance)
88
+ plugins_to_load.remove(plugin_name)
89
+ logger.info("Loaded plugin %s", plugin_name)
90
+
59
91
  if plugins_to_load:
60
92
  logger.warning("Enabled plugins not found: %s", plugins_to_load)
61
93
 
62
94
 
63
- def apply_plugin_policies(user: str, project: str, spec: ApplySpec) -> ApplySpec:
95
+ async def apply_plugin_policies(user: str, project: str, spec: ApplySpec) -> ApplySpec:
64
96
  policies = _get_apply_policies()
65
97
  for policy in policies:
66
98
  try:
67
- spec = policy.on_apply(user=user, project=project, spec=spec)
99
+ spec = await run_async(policy.on_apply, user=user, project=project, spec=spec)
68
100
  except ValueError as e:
69
101
  msg = None
70
102
  if len(e.args) > 0:
@@ -283,7 +283,7 @@ async def get_plan(
283
283
  ) -> RunPlan:
284
284
  # Spec must be copied by parsing to calculate merged_profile
285
285
  effective_run_spec = RunSpec.parse_obj(run_spec.dict())
286
- effective_run_spec = apply_plugin_policies(
286
+ effective_run_spec = await apply_plugin_policies(
287
287
  user=user.name,
288
288
  project=project.name,
289
289
  spec=effective_run_spec,
@@ -382,7 +382,7 @@ async def apply_plan(
382
382
  force: bool,
383
383
  ) -> Run:
384
384
  run_spec = plan.run_spec
385
- run_spec = apply_plugin_policies(
385
+ run_spec = await apply_plugin_policies(
386
386
  user=user.name,
387
387
  project=project.name,
388
388
  spec=run_spec,
@@ -205,7 +205,7 @@ async def create_volume(
205
205
  user: UserModel,
206
206
  configuration: VolumeConfiguration,
207
207
  ) -> Volume:
208
- spec = apply_plugin_policies(
208
+ spec = await apply_plugin_policies(
209
209
  user=user.name,
210
210
  project=project.name,
211
211
  # Create pseudo spec until the volume API is updated to accept spec
@@ -1,3 +1,3 @@
1
1
  <!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><title>dstack</title><meta name="description" content="Get GPUs at the best prices and availability from a wide range of providers. No cloud account of your own is required.
2
2
  "/><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet"><meta name="og:title" content="dstack"><meta name="og:type" content="article"><meta name="og:image" content="/splash_thumbnail.png"><meta name="og:description" content="Get GPUs at the best prices and availability from a wide range of providers. No cloud account of your own is required.
3
- "><link rel="icon" type="image/x-icon" href="/assets/favicon.ico"><link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png"><link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png"><link rel="icon" type="image/png" sizes="48x48" href="/assets/favicon-48x48.png"><link rel="manifest" href="/assets/manifest.webmanifest"><meta name="mobile-web-app-capable" content="yes"><meta name="theme-color" content="#fff"><meta name="application-name" content="dstackai"><link rel="apple-touch-icon" sizes="57x57" href="/assets/apple-touch-icon-57x57.png"><link rel="apple-touch-icon" sizes="60x60" href="/assets/apple-touch-icon-60x60.png"><link rel="apple-touch-icon" sizes="72x72" href="/assets/apple-touch-icon-72x72.png"><link rel="apple-touch-icon" sizes="76x76" href="/assets/apple-touch-icon-76x76.png"><link rel="apple-touch-icon" sizes="114x114" href="/assets/apple-touch-icon-114x114.png"><link rel="apple-touch-icon" sizes="120x120" href="/assets/apple-touch-icon-120x120.png"><link rel="apple-touch-icon" sizes="144x144" href="/assets/apple-touch-icon-144x144.png"><link rel="apple-touch-icon" sizes="152x152" href="/assets/apple-touch-icon-152x152.png"><link rel="apple-touch-icon" sizes="167x167" href="/assets/apple-touch-icon-167x167.png"><link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon-180x180.png"><link rel="apple-touch-icon" sizes="1024x1024" href="/assets/apple-touch-icon-1024x1024.png"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"><meta name="apple-mobile-web-app-title" content="dstackai"><link rel="apple-touch-startup-image" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-640x1136.png"><link rel="apple-touch-startup-image" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-1136x640.png"><link rel="apple-touch-startup-image" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-750x1334.png"><link rel="apple-touch-startup-image" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-1334x750.png"><link rel="apple-touch-startup-image" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1125x2436.png"><link rel="apple-touch-startup-image" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2436x1125.png"><link rel="apple-touch-startup-image" media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1170x2532.png"><link rel="apple-touch-startup-image" media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2532x1170.png"><link rel="apple-touch-startup-image" media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1179x2556.png"><link rel="apple-touch-startup-image" media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2556x1179.png"><link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-828x1792.png"><link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-1792x828.png"><link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1242x2688.png"><link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2688x1242.png"><link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1242x2208.png"><link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2208x1242.png"><link rel="apple-touch-startup-image" media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1284x2778.png"><link rel="apple-touch-startup-image" media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2778x1284.png"><link rel="apple-touch-startup-image" media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1290x2796.png"><link rel="apple-touch-startup-image" media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2796x1290.png"><link rel="apple-touch-startup-image" media="(device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1488x2266.png"><link rel="apple-touch-startup-image" media="(device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2266x1488.png"><link rel="apple-touch-startup-image" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1536x2048.png"><link rel="apple-touch-startup-image" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2048x1536.png"><link rel="apple-touch-startup-image" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1620x2160.png"><link rel="apple-touch-startup-image" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2160x1620.png"><link rel="apple-touch-startup-image" media="(device-width: 820px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1640x2160.png"><link rel="apple-touch-startup-image" media="(device-width: 820px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2160x1640.png"><link rel="apple-touch-startup-image" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1668x2388.png"><link rel="apple-touch-startup-image" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2388x1668.png"><link rel="apple-touch-startup-image" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1668x2224.png"><link rel="apple-touch-startup-image" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2224x1668.png"><link rel="apple-touch-startup-image" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-2048x2732.png"><link rel="apple-touch-startup-image" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2732x2048.png"><meta name="msapplication-TileColor" content="#fff"><meta name="msapplication-TileImage" content="/assets/mstile-144x144.png"><meta name="msapplication-config" content="/assets/browserconfig.xml"><link rel="yandex-tableau-widget" href="/assets/yandex-browser-manifest.json"><script defer="defer" src="/main-b4803049eac16aea9a49.js"></script><link href="/main-8f9c66f404e9c7e7e020.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div class="b-page-header" id="header"></div><div id="root"></div></body></html>
3
+ "><link rel="icon" type="image/x-icon" href="/assets/favicon.ico"><link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png"><link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png"><link rel="icon" type="image/png" sizes="48x48" href="/assets/favicon-48x48.png"><link rel="manifest" href="/assets/manifest.webmanifest"><meta name="mobile-web-app-capable" content="yes"><meta name="theme-color" content="#fff"><meta name="application-name" content="dstackai"><link rel="apple-touch-icon" sizes="57x57" href="/assets/apple-touch-icon-57x57.png"><link rel="apple-touch-icon" sizes="60x60" href="/assets/apple-touch-icon-60x60.png"><link rel="apple-touch-icon" sizes="72x72" href="/assets/apple-touch-icon-72x72.png"><link rel="apple-touch-icon" sizes="76x76" href="/assets/apple-touch-icon-76x76.png"><link rel="apple-touch-icon" sizes="114x114" href="/assets/apple-touch-icon-114x114.png"><link rel="apple-touch-icon" sizes="120x120" href="/assets/apple-touch-icon-120x120.png"><link rel="apple-touch-icon" sizes="144x144" href="/assets/apple-touch-icon-144x144.png"><link rel="apple-touch-icon" sizes="152x152" href="/assets/apple-touch-icon-152x152.png"><link rel="apple-touch-icon" sizes="167x167" href="/assets/apple-touch-icon-167x167.png"><link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon-180x180.png"><link rel="apple-touch-icon" sizes="1024x1024" href="/assets/apple-touch-icon-1024x1024.png"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"><meta name="apple-mobile-web-app-title" content="dstackai"><link rel="apple-touch-startup-image" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-640x1136.png"><link rel="apple-touch-startup-image" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-1136x640.png"><link rel="apple-touch-startup-image" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-750x1334.png"><link rel="apple-touch-startup-image" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-1334x750.png"><link rel="apple-touch-startup-image" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1125x2436.png"><link rel="apple-touch-startup-image" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2436x1125.png"><link rel="apple-touch-startup-image" media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1170x2532.png"><link rel="apple-touch-startup-image" media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2532x1170.png"><link rel="apple-touch-startup-image" media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1179x2556.png"><link rel="apple-touch-startup-image" media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2556x1179.png"><link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-828x1792.png"><link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-1792x828.png"><link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1242x2688.png"><link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2688x1242.png"><link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1242x2208.png"><link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2208x1242.png"><link rel="apple-touch-startup-image" media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1284x2778.png"><link rel="apple-touch-startup-image" media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2778x1284.png"><link rel="apple-touch-startup-image" media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1290x2796.png"><link rel="apple-touch-startup-image" media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2796x1290.png"><link rel="apple-touch-startup-image" media="(device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1488x2266.png"><link rel="apple-touch-startup-image" media="(device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2266x1488.png"><link rel="apple-touch-startup-image" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1536x2048.png"><link rel="apple-touch-startup-image" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2048x1536.png"><link rel="apple-touch-startup-image" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1620x2160.png"><link rel="apple-touch-startup-image" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2160x1620.png"><link rel="apple-touch-startup-image" media="(device-width: 820px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1640x2160.png"><link rel="apple-touch-startup-image" media="(device-width: 820px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2160x1640.png"><link rel="apple-touch-startup-image" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1668x2388.png"><link rel="apple-touch-startup-image" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2388x1668.png"><link rel="apple-touch-startup-image" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-1668x2224.png"><link rel="apple-touch-startup-image" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2224x1668.png"><link rel="apple-touch-startup-image" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/assets/apple-touch-startup-image-2048x2732.png"><link rel="apple-touch-startup-image" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/assets/apple-touch-startup-image-2732x2048.png"><meta name="msapplication-TileColor" content="#fff"><meta name="msapplication-TileImage" content="/assets/mstile-144x144.png"><meta name="msapplication-config" content="/assets/browserconfig.xml"><link rel="yandex-tableau-widget" href="/assets/yandex-browser-manifest.json"><script defer="defer" src="/main-5b9786c955b42bf93581.js"></script><link href="/main-8f9c66f404e9c7e7e020.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div class="b-page-header" id="header"></div><div id="root"></div></body></html>
@@ -133990,7 +133990,7 @@ var src_useBackendsTable=function(projectName,backends){var _useTranslation=src_
133990
133990
  ;// ./src/pages/Project/Backends/hooks/index.ts
133991
133991
 
133992
133992
  ;// ./src/pages/Project/Backends/Table/constants.tsx
133993
- var src_BACKENDS_HELP_SKY={header:/*#__PURE__*/src_react.createElement("h2",null,"SKy Backends"),body:/*#__PURE__*/src_react.createElement(src_react.Fragment,null,/*#__PURE__*/src_react.createElement("p",null,"Some text"))};var src_BACKENDS_HELP_ENTERPRISE={header:/*#__PURE__*/src_react.createElement("h2",null,"Enterprise Backends"),body:/*#__PURE__*/src_react.createElement(src_react.Fragment,null,/*#__PURE__*/src_react.createElement("p",null,"Some text"))};
133993
+ var src_BACKENDS_HELP_SKY={header:/*#__PURE__*/src_react.createElement("h2",null,"Backends"),body:/*#__PURE__*/src_react.createElement(src_react.Fragment,null,/*#__PURE__*/src_react.createElement("p",null,"To use ",/*#__PURE__*/src_react.createElement("code",null,"dstack")," with cloud providers, you have to configure backends."),/*#__PURE__*/src_react.createElement("h4",null,"Marketplace"),/*#__PURE__*/src_react.createElement("p",null,"By default, ",/*#__PURE__*/src_react.createElement("code",null,"dstack Sky")," includes a preset of backends that let you access compute from the "," ",/*#__PURE__*/src_react.createElement("code",null,"dstack")," marketplace and pay through your ",/*#__PURE__*/src_react.createElement("code",null,"dstack Sky")," user billing."),/*#__PURE__*/src_react.createElement("h4",null,"Your own cloud accounts"),/*#__PURE__*/src_react.createElement("p",null,"You can also configure custom backends to use your own cloud providers, either instead of or in addition to the default ones."),/*#__PURE__*/src_react.createElement("p",null,"See the ",/*#__PURE__*/src_react.createElement("a",{href:"https://dstack.ai/docs/concepts/backends",target:"_blank"},"documentation")," for the list of supported backends."))};var src_BACKENDS_HELP_ENTERPRISE={header:/*#__PURE__*/src_react.createElement("h2",null,"Backends"),body:/*#__PURE__*/src_react.createElement(src_react.Fragment,null,/*#__PURE__*/src_react.createElement("p",null,"To use ",/*#__PURE__*/src_react.createElement("code",null,"dstack")," with cloud providers, you have to configure backends."),/*#__PURE__*/src_react.createElement("p",null,"See the ",/*#__PURE__*/src_react.createElement("a",{href:"https://dstack.ai/docs/concepts/backends",target:"_blank"},"documentation")," for the list of supported backends."))};
133994
133994
  ;// ./src/pages/Project/Backends/Table/styles.module.scss
133995
133995
  // extracted by mini-css-extract-plugin
133996
133996
  /* harmony default export */ const src_Table_styles_module = ({"cell":"biUJI","contextMenu":"A3asV","ellipsisCell":"kUgHm"});
@@ -134001,7 +134001,7 @@ var src_hooks_useColumnsDefinitions_useColumnsDefinitions=function(_ref){var loa
134001
134001
  ;// ./src/pages/Project/Backends/Table/index.tsx
134002
134002
  function src_Table_ownKeys(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter(function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable})),t.push.apply(t,o)}return t}function src_Table_objectSpread(e){for(var t,r=1;r<arguments.length;r++)t=null==arguments[r]?{}:arguments[r],r%2?src_Table_ownKeys(Object(t),!0).forEach(function(r){src_defineProperty_defineProperty(e,r,t[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):src_Table_ownKeys(Object(t)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))});return e}var src_INFO= true?src_BACKENDS_HELP_ENTERPRISE:0;var src_BackendsTable=function(_ref){var backends=_ref.backends,editBackend=_ref.editBackend,deleteBackends=_ref.deleteBackends,onClickAddBackend=_ref.onClickAddBackend,isDisabledDelete=_ref.isDisabledDelete,_useTranslation=src_useTranslation_useTranslation(),t=_useTranslation.t,_useHelpPanel=src_useHelpPanel_useHelpPanel(),_useHelpPanel2=src_slicedToArray_slicedToArray(_useHelpPanel,1),openHelpPanel=_useHelpPanel2[0],renderEmptyMessage=function(){return/*#__PURE__*/src_react.createElement(src_ListEmptyMessage_ListEmptyMessage,{title:t("backend.empty_message_title"),message:t("backend.empty_message_text")},onClickAddBackend&&/*#__PURE__*/src_react.createElement(src_Button_Button,{onClick:onClickAddBackend},t("common.add")))},_useCollection=src_use_collection_useCollection(null!==backends&&void 0!==backends?backends:[],{filtering:{empty:renderEmptyMessage(),noMatch:renderEmptyMessage()},selection:{}}),items=_useCollection.items,collectionProps=_useCollection.collectionProps,selectedItems=collectionProps.selectedItems,isDisabledDeleteSelected=!(null!==selectedItems&&void 0!==selectedItems&&selectedItems.length)||isDisabledDelete,_useColumnsDefinition=src_hooks_useColumnsDefinitions_useColumnsDefinitions(src_Table_objectSpread({},editBackend?{onEditClick:function(backend){return editBackend(backend)}}:{})),columns=_useColumnsDefinition.columns;return/*#__PURE__*/src_react.createElement(src_table,src_extends_extends({},collectionProps,{columnDefinitions:columns,items:items,loadingText:t("common.loading"),selectionType:deleteBackends||editBackend?"multi":void 0,stickyHeader:!0,header:/*#__PURE__*/src_react.createElement(src_components_header_Header,{counter:function(){return null!==backends&&void 0!==backends&&backends.length?"(".concat(backends.length,")"):""}(),info:/*#__PURE__*/src_react.createElement(src_InfoLink_InfoLink,{onFollow:function(){return openHelpPanel(src_INFO)}}),actions:/*#__PURE__*/src_react.createElement(src_space_between_SpaceBetween,{size:"xs",direction:"horizontal"},deleteBackends&&/*#__PURE__*/src_react.createElement(src_ButtonWithConfirmation,{disabled:isDisabledDeleteSelected,formAction:"none",onClick:function(){null!==selectedItems&&void 0!==selectedItems&&selectedItems.length&&deleteBackends&&deleteBackends(selectedItems)},confirmTitle:t("backend.edit.delete_backends_confirm_title"),confirmContent:t("backend.edit.delete_backends_confirm_message")},t("common.delete")),onClickAddBackend&&/*#__PURE__*/src_react.createElement(src_Button_Button,{onClick:onClickAddBackend/*disabled={isDisabledAddBackendButton}*/},t("common.add")))},t("backend.page_title_other"))}))};
134003
134003
  ;// ./src/pages/Project/Gateways/Table/constants.tsx
134004
- var src_GATEWAYS_INFO={header:/*#__PURE__*/src_react.createElement("h2",null,"Gateways"),body:/*#__PURE__*/src_react.createElement(src_react.Fragment,null,/*#__PURE__*/src_react.createElement("p",null,"Some text"))};
134004
+ var src_GATEWAYS_INFO={header:/*#__PURE__*/src_react.createElement("h2",null,"Gateways"),body:/*#__PURE__*/src_react.createElement(src_react.Fragment,null,/*#__PURE__*/src_react.createElement("p",null,"Gateways manage the ingress traffic for running services."),/*#__PURE__*/src_react.createElement("p",null,"To learn more about gateways, see the ",/*#__PURE__*/src_react.createElement("a",{href:"https://dstack.ai/docs/concepts/gateways",target:"_blank"},"documentation"),"."))};
134005
134005
  ;// ./src/pages/Project/Gateways/Table/styles.module.scss
134006
134006
  // extracted by mini-css-extract-plugin
134007
134007
  /* harmony default export */ const src_Gateways_Table_styles_module = ({"cell":"naCdG","contextMenu":"_TtVL","ellipsisCell":"FLA_c"});
@@ -134032,7 +134032,7 @@ var src_useGatewaysTable=function(projectName){var navigate=src_dist_useNavigate
134032
134032
  ;// ./src/pages/Project/Gateways/hooks/index.ts
134033
134033
 
134034
134034
  ;// ./src/pages/Project/Details/Settings/constants.tsx
134035
- var src_CLI_INFO={header:/*#__PURE__*/src_react.createElement("h2",null,"CLI"),body:/*#__PURE__*/src_react.createElement(src_react.Fragment,null,/*#__PURE__*/src_react.createElement("p",null,"Some text"))};
134035
+ var src_CLI_INFO={header:/*#__PURE__*/src_react.createElement("h2",null,"CLI"),body:/*#__PURE__*/src_react.createElement(src_react.Fragment,null,/*#__PURE__*/src_react.createElement("p",null,"To use this project with your CLI, add it using the",/*#__PURE__*/src_react.createElement("a",{href:"https://dstack.ai/docs/reference/cli/dstack/project/",target:"_blank"},/*#__PURE__*/src_react.createElement("code",null,"dstack project add"))," command."),/*#__PURE__*/src_react.createElement("p",null,"To learn how to install the CLI, refer to the"," ",/*#__PURE__*/src_react.createElement("a",{href:"https://dstack.ai/docs/cli/installation",target:"_blank"},"installation")," guide."))};
134036
134036
  ;// ./src/pages/Project/Details/Settings/styles.module.scss
134037
134037
  // extracted by mini-css-extract-plugin
134038
134038
  /* harmony default export */ const src_Settings_styles_module = ({"dangerSectionGrid":"U24Qs","dangerSectionField":"AKyqV","codeWrapper":"LmVNG","code":"Vntdh","copy":"Wtjre"});
@@ -134045,7 +134045,7 @@ var src_ProjectAdd=function(){var _useTranslation=src_useTranslation_useTranslat
134045
134045
  ;// ./src/pages/Project/index.tsx
134046
134046
  var src_Project=function(){return null};
134047
134047
  ;// ./src/pages/Project/Backends/YAMLForm/constants.tsx
134048
- var src_CONFIG_YAML_HELP_SKY={header:/*#__PURE__*/src_react.createElement("h2",null,"Backend config"),body:/*#__PURE__*/src_react.createElement(src_react.Fragment,null,/*#__PURE__*/src_react.createElement("p",null,"The backend config is defined in the YAML format. It specifies the backend's ",/*#__PURE__*/src_react.createElement("code",null,"type")," and settings,"," ","such as ",/*#__PURE__*/src_react.createElement("code",null,"creds"),", ",/*#__PURE__*/src_react.createElement("code",null,"regions"),", and so on."),/*#__PURE__*/src_react.createElement("h4",null,"Marketplace"),/*#__PURE__*/src_react.createElement("p",null,"If you set ",/*#__PURE__*/src_react.createElement("code",null,"creds"),"'s ",/*#__PURE__*/src_react.createElement("code",null,"type")," to ",/*#__PURE__*/src_react.createElement("code",null,"dstack"),", you'll get compute from"," ",/*#__PURE__*/src_react.createElement("code",null,"dstack"),"'s marketplace and will pay for it via your ",/*#__PURE__*/src_react.createElement("code",null,"dstack Sky")," user billing. Example:"),/*#__PURE__*/src_react.createElement("p",null,/*#__PURE__*/src_react.createElement("pre",null,"type: aws","\n","creds:","\n"," ","type: dstack","\n")),/*#__PURE__*/src_react.createElement("p",null,"You can see all supported backend types at the"," ",/*#__PURE__*/src_react.createElement("a",{href:"https://dstack.ai/docs/reference/server/config.yml/#examples",target:"_blank"},"documentation"),"."),/*#__PURE__*/src_react.createElement("h4",null,"Your own cloud account"),/*#__PURE__*/src_react.createElement("p",null,"If you want to use your own cloud account, configure ",/*#__PURE__*/src_react.createElement("code",null,"creds")," and other settings according to the"," ",/*#__PURE__*/src_react.createElement("a",{href:"https://dstack.ai/docs/reference/server/config.yml/#examples",target:"_blank"},"documentation"),". Example:"),/*#__PURE__*/src_react.createElement("p",null,/*#__PURE__*/src_react.createElement("pre",null,"type: aws","\n","creds:","\n"," ","type: access_key","\n"," ","access_key: AIZKISCVKUK","\n"," ","secret_key: QSbmpqJIUBn1")))};var src_CONFIG_YAML_HELP_ENTERPRISE={header:/*#__PURE__*/src_react.createElement("h2",null,"Backend config"),body:/*#__PURE__*/src_react.createElement(src_react.Fragment,null,/*#__PURE__*/src_react.createElement("p",null,"The backend config is defined in the YAML format. It specifies the backend's ",/*#__PURE__*/src_react.createElement("code",null,"type")," and settings, such as ",/*#__PURE__*/src_react.createElement("code",null,"creds"),", ",/*#__PURE__*/src_react.createElement("code",null,"regions"),", and so on."),/*#__PURE__*/src_react.createElement("p",null,"Example:"),/*#__PURE__*/src_react.createElement("p",null,/*#__PURE__*/src_react.createElement("pre",null,"type: aws","\n","creds:","\n"," ","type: access_key","\n"," ","access_key: AIZKISCVKUK","\n"," ","secret_key: QSbmpqJIUBn1")),/*#__PURE__*/src_react.createElement("p",null,"Each backend type may support different properties. See the"," ",/*#__PURE__*/src_react.createElement("a",{href:"https://dstack.ai/docs/reference/server/config.yml/#examples"},"reference page")," for more examples."))};
134048
+ var src_CONFIG_YAML_HELP_SKY={header:/*#__PURE__*/src_react.createElement("h2",null,"Backend config"),body:/*#__PURE__*/src_react.createElement(src_react.Fragment,null,/*#__PURE__*/src_react.createElement("p",null,"The backend config is defined in the YAML format. It specifies the backend's ",/*#__PURE__*/src_react.createElement("code",null,"type")," and settings,"," ","such as ",/*#__PURE__*/src_react.createElement("code",null,"creds"),", ",/*#__PURE__*/src_react.createElement("code",null,"regions"),", and so on."),/*#__PURE__*/src_react.createElement("h4",null,"Marketplace"),/*#__PURE__*/src_react.createElement("p",null,"If you set ",/*#__PURE__*/src_react.createElement("code",null,"creds"),"'s ",/*#__PURE__*/src_react.createElement("code",null,"type")," to ",/*#__PURE__*/src_react.createElement("code",null,"dstack"),", you'll get compute from"," ",/*#__PURE__*/src_react.createElement("code",null,"dstack"),"'s marketplace and will pay for it via your ",/*#__PURE__*/src_react.createElement("code",null,"dstack Sky")," user billing. Example:"),/*#__PURE__*/src_react.createElement("p",null,/*#__PURE__*/src_react.createElement("pre",null,"type: aws","\n","creds:","\n"," ","type: dstack","\n")),/*#__PURE__*/src_react.createElement("p",null,"You can see all supported backend types at the"," ",/*#__PURE__*/src_react.createElement("a",{href:"https://dstack.ai/docs/concepts/backends",target:"_blank"},"documentation"),"."),/*#__PURE__*/src_react.createElement("h4",null,"Your own cloud account"),/*#__PURE__*/src_react.createElement("p",null,"If you want to use your own cloud account, configure ",/*#__PURE__*/src_react.createElement("code",null,"creds")," and other settings according to the"," ",/*#__PURE__*/src_react.createElement("a",{href:"https://dstack.ai/docs/concepts/backends",target:"_blank"},"documentation"),". Example:"),/*#__PURE__*/src_react.createElement("p",null,/*#__PURE__*/src_react.createElement("pre",null,"type: aws","\n","creds:","\n"," ","type: access_key","\n"," ","access_key: AIZKISCVKUK","\n"," ","secret_key: QSbmpqJIUBn1")))};var src_CONFIG_YAML_HELP_ENTERPRISE={header:/*#__PURE__*/src_react.createElement("h2",null,"Backend config"),body:/*#__PURE__*/src_react.createElement(src_react.Fragment,null,/*#__PURE__*/src_react.createElement("p",null,"The backend config is defined in the YAML format. It specifies the backend's ",/*#__PURE__*/src_react.createElement("code",null,"type")," and settings, such as ",/*#__PURE__*/src_react.createElement("code",null,"creds"),", ",/*#__PURE__*/src_react.createElement("code",null,"regions"),", and so on."),/*#__PURE__*/src_react.createElement("p",null,"Example:"),/*#__PURE__*/src_react.createElement("p",null,/*#__PURE__*/src_react.createElement("pre",null,"type: aws","\n","creds:","\n"," ","type: access_key","\n"," ","access_key: AIZKISCVKUK","\n"," ","secret_key: QSbmpqJIUBn1")),/*#__PURE__*/src_react.createElement("p",null,"Each backend type may support different properties. See the"," ",/*#__PURE__*/src_react.createElement("a",{href:"https://dstack.ai/docs/concepts/backends",target:"_blank"},"documentaiton")," for more examples."))};
134049
134049
  ;// ./src/pages/Project/Backends/YAMLForm/index.tsx
134050
134050
  var src_YAMLForm_INFO= true?src_CONFIG_YAML_HELP_ENTERPRISE:0;var src_YAMLForm=function(_ref){var initialValues=_ref.initialValues,onCancel=_ref.onCancel,loading=_ref.loading,onSubmitProp=_ref.onSubmit,onApplyProp=_ref.onApply,_useTranslation=src_useTranslation_useTranslation(),t=_useTranslation.t,_useHelpPanel=src_useHelpPanel_useHelpPanel(),_useHelpPanel2=src_slicedToArray_slicedToArray(_useHelpPanel,1),openHelpPanel=_useHelpPanel2[0],_useNotifications=src_useNotifications_useNotifications(),_useNotifications2=src_slicedToArray_slicedToArray(_useNotifications,1),pushNotification=_useNotifications2[0],_useState=(0,src_react.useState)(!1),_useState2=src_slicedToArray_slicedToArray(_useState,2),isApplying=_useState2[0],setIsApplying=_useState2[1],_useForm=src_index_esm_useForm({defaultValues:initialValues}),handleSubmit=_useForm.handleSubmit,control=_useForm.control,setError=_useForm.setError,clearErrors=_useForm.clearErrors;return/*#__PURE__*/src_react.createElement("form",{onSubmit:handleSubmit(function(data){clearErrors();var submitCallback=isApplying&&onApplyProp?onApplyProp:onSubmitProp;submitCallback(data).finally(function(){return setIsApplying(!1)}).catch(function(errorResponse){var errorRequestData=null===errorResponse||void 0===errorResponse?void 0:errorResponse.data;if(src_isResponseServerError(errorRequestData))errorRequestData.detail.forEach(function(error){src_isResponseServerFormFieldError(error)?setError(error.loc.join("."),{type:"custom",message:error.msg}):pushNotification({type:"error",content:t("common.server_error",{error:error.msg})})});else{var _errorResponse$error;pushNotification({type:"error",content:t("common.server_error",{error:null!==(_errorResponse$error=null===errorResponse||void 0===errorResponse?void 0:errorResponse.error)&&void 0!==_errorResponse$error?_errorResponse$error:errorResponse})})}})})},/*#__PURE__*/src_react.createElement(src_form_Form,{actions:/*#__PURE__*/src_react.createElement(src_space_between_SpaceBetween,{direction:"horizontal",size:"xs"},/*#__PURE__*/src_react.createElement(src_Button_Button,{formAction:"none",disabled:loading,variant:"link",onClick:onCancel},t("common.cancel")),onApplyProp&&/*#__PURE__*/src_react.createElement(src_Button_Button,{loading:loading,disabled:loading,onClick:function(){return setIsApplying(!0)}},t("common.apply")),/*#__PURE__*/src_react.createElement(src_Button_Button,{loading:loading,disabled:loading,variant:"primary"},t("common.save")))},/*#__PURE__*/src_react.createElement(src_FormCodeEditor,{info:/*#__PURE__*/src_react.createElement(src_InfoLink_InfoLink,{onFollow:function(){return openHelpPanel(src_YAMLForm_INFO)}}),control:control,label:t("projects.edit.backend_config"),description:t("projects.edit.backend_config_description"),name:"config_yaml",language:"yaml",loading:loading,editorContentHeight:600})))};
134051
134051
  ;// ./src/pages/Project/Backends/Add/index.tsx
@@ -136477,4 +136477,4 @@ var src_container=document.getElementById("root"),src_src_theme={tokens:{fontFam
136477
136477
 
136478
136478
  /******/ })()
136479
136479
  ;
136480
- //# sourceMappingURL=main-b4803049eac16aea9a49.js.map
136480
+ //# sourceMappingURL=main-5b9786c955b42bf93581.js.map