skypilot-nightly 1.0.0.dev20250526__py3-none-any.whl → 1.0.0.dev20250528__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.
- sky/__init__.py +2 -2
- sky/adaptors/kubernetes.py +13 -1
- sky/backends/cloud_vm_ray_backend.py +2 -2
- sky/check.py +32 -6
- sky/cli.py +5 -22
- sky/client/cli.py +5 -22
- sky/client/sdk.py +5 -2
- sky/clouds/cloud.py +2 -2
- sky/clouds/kubernetes.py +12 -7
- sky/clouds/service_catalog/kubernetes_catalog.py +4 -0
- sky/clouds/ssh.py +24 -8
- sky/core.py +20 -2
- sky/dashboard/out/404.html +1 -1
- sky/dashboard/out/_next/static/Mx1iAbDQn1jMHh3UHmK3R/_buildManifest.js +1 -0
- sky/dashboard/out/_next/static/chunks/121-8f55ee3fa6301784.js +20 -0
- sky/dashboard/out/_next/static/chunks/{573-f17bd89d9f9118b3.js → 173-7db8607cefc20f70.js} +5 -5
- sky/dashboard/out/_next/static/chunks/236-d6900c828331f664.js +6 -0
- sky/dashboard/out/_next/static/chunks/293-351268365226d251.js +1 -0
- sky/dashboard/out/_next/static/chunks/{498-d7722313e5e5b4e6.js → 320-afea3ddcc5bd1c6c.js} +1 -16
- sky/dashboard/out/_next/static/chunks/470-4d003c441839094d.js +1 -0
- sky/dashboard/out/_next/static/chunks/578-9146658cead92981.js +6 -0
- sky/dashboard/out/_next/static/chunks/843-256ec920f6d5f41f.js +11 -0
- sky/dashboard/out/_next/static/chunks/856-62b87c68917b08ed.js +1 -0
- sky/dashboard/out/_next/static/chunks/973-1a09cac61cfcc1e1.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-159bffb2fa34ed54.js +6 -0
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-9506c00257d10dbd.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/{clusters-9e6d1ec6e1ac5b29.js → clusters-943992b84fd6f4ee.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/config-41738d1896fc02fe.js +6 -0
- sky/dashboard/out/_next/static/chunks/pages/infra-881fcd902fbbd0e5.js +6 -0
- sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-2c29e97a6aa50dd4.js +6 -0
- sky/dashboard/out/_next/static/chunks/pages/jobs-a4efc09e61988f8d.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/users-b2634885d67c49a6.js +6 -0
- sky/dashboard/out/_next/static/chunks/pages/workspace/{new-bbf436f41381e169.js → new-579b3203c7c19d84.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/workspaces/{[name]-7733c960685b4385.js → [name]-9388e38fac73ee8f.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/workspaces-610c49ae3619ee85.js +1 -0
- sky/dashboard/out/_next/static/css/ffd1cd601648c303.css +3 -0
- sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
- sky/dashboard/out/clusters/[cluster].html +1 -1
- sky/dashboard/out/clusters.html +1 -1
- sky/dashboard/out/config.html +1 -0
- sky/dashboard/out/index.html +1 -1
- sky/dashboard/out/infra.html +1 -1
- sky/dashboard/out/jobs/[job].html +1 -1
- sky/dashboard/out/jobs.html +1 -1
- sky/dashboard/out/users.html +1 -1
- sky/dashboard/out/workspace/new.html +1 -1
- sky/dashboard/out/workspaces/[name].html +1 -1
- sky/dashboard/out/workspaces.html +1 -1
- sky/global_user_state.py +181 -134
- sky/provision/kubernetes/utils.py +4 -4
- sky/server/constants.py +1 -1
- sky/server/requests/payloads.py +18 -5
- sky/server/requests/serializers/decoders.py +0 -11
- sky/server/server.py +25 -14
- sky/setup_files/dependencies.py +1 -0
- sky/skylet/constants.py +4 -0
- sky/skypilot_config.py +4 -0
- sky/utils/db_utils.py +34 -46
- sky/utils/kubernetes/exec_kubeconfig_converter.py +19 -0
- sky/utils/schemas.py +57 -5
- sky/utils/subprocess_utils.py +2 -3
- sky/workspaces/core.py +186 -50
- sky/workspaces/server.py +25 -0
- {skypilot_nightly-1.0.0.dev20250526.dist-info → skypilot_nightly-1.0.0.dev20250528.dist-info}/METADATA +2 -1
- {skypilot_nightly-1.0.0.dev20250526.dist-info → skypilot_nightly-1.0.0.dev20250528.dist-info}/RECORD +71 -67
- {skypilot_nightly-1.0.0.dev20250526.dist-info → skypilot_nightly-1.0.0.dev20250528.dist-info}/WHEEL +1 -1
- sky/dashboard/out/_next/static/7GEgRyZKRaSnYZCV1Jwol/_buildManifest.js +0 -1
- sky/dashboard/out/_next/static/chunks/25-062253ea41fb8eec.js +0 -6
- sky/dashboard/out/_next/static/chunks/480-5a0de8b6570ea105.js +0 -1
- sky/dashboard/out/_next/static/chunks/488-50d843fdb5396d32.js +0 -15
- sky/dashboard/out/_next/static/chunks/578-d351125af46c293f.js +0 -6
- sky/dashboard/out/_next/static/chunks/734-a6e01d7f98904741.js +0 -1
- sky/dashboard/out/_next/static/chunks/938-59956af3950b02ed.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-3b5aad09a25f64b7.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-9529d9e882a0e75c.js +0 -16
- sky/dashboard/out/_next/static/chunks/pages/infra-abb7d744ecf15109.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-48dc8d67d4b60be1.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/jobs-73d5e0c369d00346.js +0 -16
- sky/dashboard/out/_next/static/chunks/pages/users-b8acf6e6735323a2.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/workspaces-5ed48b3201b998c8.js +0 -1
- sky/dashboard/out/_next/static/css/28558d57108b05ae.css +0 -3
- /sky/dashboard/out/_next/static/{7GEgRyZKRaSnYZCV1Jwol → Mx1iAbDQn1jMHh3UHmK3R}/_ssgManifest.js +0 -0
- /sky/dashboard/out/_next/static/chunks/pages/{_app-96a715a6fb01e228.js → _app-a631df412d8172de.js} +0 -0
- {skypilot_nightly-1.0.0.dev20250526.dist-info → skypilot_nightly-1.0.0.dev20250528.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20250526.dist-info → skypilot_nightly-1.0.0.dev20250528.dist-info}/licenses/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev20250526.dist-info → skypilot_nightly-1.0.0.dev20250528.dist-info}/top_level.txt +0 -0
sky/__init__.py
CHANGED
@@ -5,7 +5,7 @@ from typing import Optional
|
|
5
5
|
import urllib.request
|
6
6
|
|
7
7
|
# Replaced with the current commit when building the wheels.
|
8
|
-
_SKYPILOT_COMMIT_SHA = '
|
8
|
+
_SKYPILOT_COMMIT_SHA = '19ec9254037c83057b1e3f51f5dc17045ec42b53'
|
9
9
|
|
10
10
|
|
11
11
|
def _get_git_commit():
|
@@ -35,7 +35,7 @@ def _get_git_commit():
|
|
35
35
|
|
36
36
|
|
37
37
|
__commit__ = _get_git_commit()
|
38
|
-
__version__ = '1.0.0.
|
38
|
+
__version__ = '1.0.0.dev20250528'
|
39
39
|
__root_dir__ = os.path.dirname(os.path.abspath(__file__))
|
40
40
|
|
41
41
|
|
sky/adaptors/kubernetes.py
CHANGED
@@ -66,12 +66,20 @@ def _api_logging_decorator(logger_src: str, level: int):
|
|
66
66
|
return decorated_api
|
67
67
|
|
68
68
|
|
69
|
+
def _get_config_file() -> str:
|
70
|
+
# Kubernetes load the kubeconfig from the KUBECONFIG env var on
|
71
|
+
# package initialization. So we have to reload the KUBECOFNIG env var
|
72
|
+
# everytime in case the KUBECONFIG env var is changed.
|
73
|
+
return os.environ.get('KUBECONFIG', '~/.kube/config')
|
74
|
+
|
75
|
+
|
69
76
|
def _load_config(context: Optional[str] = None):
|
70
77
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
71
78
|
|
72
79
|
def _load_config_from_kubeconfig(context: Optional[str] = None):
|
73
80
|
try:
|
74
|
-
kubernetes.config.load_kube_config(
|
81
|
+
kubernetes.config.load_kube_config(config_file=_get_config_file(),
|
82
|
+
context=context)
|
75
83
|
except kubernetes.config.config_exception.ConfigException as e:
|
76
84
|
suffix = common_utils.format_exception(e, use_bracket=True)
|
77
85
|
context_name = '(current-context)' if context is None else context
|
@@ -139,6 +147,10 @@ def _load_config(context: Optional[str] = None):
|
|
139
147
|
_load_config_from_kubeconfig(context)
|
140
148
|
|
141
149
|
|
150
|
+
def list_kube_config_contexts():
|
151
|
+
return kubernetes.config.list_kube_config_contexts(_get_config_file())
|
152
|
+
|
153
|
+
|
142
154
|
@_api_logging_decorator('urllib3', logging.ERROR)
|
143
155
|
@annotations.lru_cache(scope='request')
|
144
156
|
def core_api(context: Optional[str] = None):
|
@@ -1727,12 +1727,12 @@ class RetryingVmProvisioner(object):
|
|
1727
1727
|
f'{requested_resources}. ')
|
1728
1728
|
elif to_provision.region is not None:
|
1729
1729
|
# For public clouds, provision.region is always set.
|
1730
|
-
if
|
1730
|
+
if clouds.SSH().is_same_cloud(to_provision.cloud):
|
1731
1731
|
message = ('Failed to acquire resources in SSH Node Pool '
|
1732
1732
|
f'({to_provision.region.lstrip("ssh-")}) for '
|
1733
1733
|
f'{requested_resources}. The SSH Node Pool may not '
|
1734
1734
|
'have enough resources.')
|
1735
|
-
elif
|
1735
|
+
elif clouds.Kubernetes().is_same_cloud(to_provision.cloud):
|
1736
1736
|
message = ('Failed to acquire resources in context '
|
1737
1737
|
f'{to_provision.region} for {requested_resources}. ')
|
1738
1738
|
else:
|
sky/check.py
CHANGED
@@ -143,12 +143,15 @@ def check_capabilities(
|
|
143
143
|
combinations = list(itertools.product(clouds_to_check, capabilities))
|
144
144
|
|
145
145
|
cloud2ctx2text: Dict[str, Dict[str, str]] = {}
|
146
|
+
if not config_allowed_cloud_names:
|
147
|
+
for capability in capabilities:
|
148
|
+
global_user_state.set_enabled_clouds([], capability,
|
149
|
+
current_workspace_name)
|
146
150
|
if not combinations:
|
147
151
|
echo(
|
148
152
|
_summary_message(enabled_clouds, cloud2ctx2text,
|
149
153
|
current_workspace_name, hide_workspace_str,
|
150
154
|
disallowed_cloud_names))
|
151
|
-
|
152
155
|
return {}
|
153
156
|
|
154
157
|
workspace_str = f' for workspace: {current_workspace_name!r}'
|
@@ -504,6 +507,18 @@ def _format_context_details(cloud: Union[str, sky_clouds.Cloud],
|
|
504
507
|
f'{str_to_format}'
|
505
508
|
f'{colorama.Style.RESET_ALL}')
|
506
509
|
|
510
|
+
# For SSH, determine which contexts are disabled due to allowed_node_pools
|
511
|
+
disabled_due_to_allowed_node_pools = set()
|
512
|
+
if isinstance(cloud_type, sky_clouds.SSH):
|
513
|
+
# Get all node pool contexts from file
|
514
|
+
all_node_pool_contexts = sky_clouds.SSH.get_ssh_node_pool_contexts()
|
515
|
+
# Get allowed contexts (after filtering)
|
516
|
+
allowed_contexts = sky_clouds.SSH.existing_allowed_contexts()
|
517
|
+
# Contexts that exist in file but not in allowed list are disabled
|
518
|
+
# due to allowed_node_pools configuration
|
519
|
+
disabled_due_to_allowed_node_pools = (set(all_node_pool_contexts) -
|
520
|
+
set(allowed_contexts))
|
521
|
+
|
507
522
|
# Format the context info with consistent styling
|
508
523
|
contexts_formatted = []
|
509
524
|
for i, context in enumerate(filtered_contexts):
|
@@ -519,11 +534,22 @@ def _format_context_details(cloud: Union[str, sky_clouds.Cloud],
|
|
519
534
|
text_suffix = ''
|
520
535
|
if show_details:
|
521
536
|
if ctx2text is not None:
|
522
|
-
|
523
|
-
f': {ctx2text[context]}'
|
524
|
-
|
525
|
-
|
526
|
-
|
537
|
+
if context in ctx2text:
|
538
|
+
text_suffix = f': {ctx2text[context]}'
|
539
|
+
elif (isinstance(cloud_type, sky_clouds.SSH) and
|
540
|
+
context in disabled_due_to_allowed_node_pools):
|
541
|
+
# Context is disabled due to allowed_node_pools config
|
542
|
+
text_suffix = (': ' + _red_color('disabled. ') +
|
543
|
+
_dim_color('Reason: Not included in '
|
544
|
+
'allowed_node_pools '
|
545
|
+
'configuration.'))
|
546
|
+
else:
|
547
|
+
# Default case - not set up
|
548
|
+
text_suffix = (': ' + _red_color('disabled. ') +
|
549
|
+
_dim_color('Reason: Not set up. Use '
|
550
|
+
'`sky ssh up --infra '
|
551
|
+
f'{context.lstrip("ssh-")}` '
|
552
|
+
'to set up.'))
|
527
553
|
contexts_formatted.append(
|
528
554
|
f'\n {symbol}{cleaned_context}{text_suffix}')
|
529
555
|
identity_str = ('SSH Node Pools' if isinstance(cloud_type, sky_clouds.SSH)
|
sky/cli.py
CHANGED
@@ -1789,20 +1789,8 @@ def _show_enabled_infra(active_workspace: str, show_workspace: bool):
|
|
1789
1789
|
title = (f'{colorama.Fore.CYAN}{colorama.Style.BRIGHT}Enabled Infra'
|
1790
1790
|
f'{workspace_str}:'
|
1791
1791
|
f'{colorama.Style.RESET_ALL} ')
|
1792
|
-
|
1793
|
-
|
1794
|
-
enabled_k8s_infras = []
|
1795
|
-
enabled_cloud_infras = []
|
1796
|
-
for cloud in enabled_clouds:
|
1797
|
-
cloud_infra = cloud.get_infras()
|
1798
|
-
if isinstance(cloud, clouds.SSH):
|
1799
|
-
enabled_ssh_infras.extend(cloud_infra)
|
1800
|
-
elif isinstance(cloud, clouds.Kubernetes):
|
1801
|
-
enabled_k8s_infras.extend(cloud_infra)
|
1802
|
-
else:
|
1803
|
-
enabled_cloud_infras.extend(cloud_infra)
|
1804
|
-
all_infras = sorted(enabled_ssh_infras) + sorted(
|
1805
|
-
enabled_k8s_infras) + sorted(enabled_cloud_infras)
|
1792
|
+
all_infras = sdk.get(
|
1793
|
+
sdk.enabled_clouds(workspace=active_workspace, expand=True))
|
1806
1794
|
click.echo(f'{title}{", ".join(all_infras)}\n')
|
1807
1795
|
|
1808
1796
|
|
@@ -1997,7 +1985,7 @@ def status(verbose: bool, refresh: bool, ip: bool, endpoints: bool,
|
|
1997
1985
|
workspace_request_id = sdk.workspaces()
|
1998
1986
|
except RuntimeError:
|
1999
1987
|
# Backward compatibility for API server before #5660.
|
2000
|
-
# TODO(zhwu): remove this after 0.
|
1988
|
+
# TODO(zhwu): remove this after 0.10.0.
|
2001
1989
|
logger.warning(f'{colorama.Style.DIM}SkyPilot API server is '
|
2002
1990
|
'in an old version, and may miss feature: '
|
2003
1991
|
'workspaces. Update with: sky api stop; '
|
@@ -3524,13 +3512,8 @@ def show_gpus(
|
|
3524
3512
|
cloud_is_ssh = isinstance(cloud_obj, clouds.SSH)
|
3525
3513
|
# TODO(romilb): We should move this to the backend.
|
3526
3514
|
kubernetes_autoscaling = kubernetes_utils.get_autoscaler_type() is not None
|
3527
|
-
kubernetes_is_enabled =
|
3528
|
-
ssh_is_enabled =
|
3529
|
-
for cloud in enabled_clouds:
|
3530
|
-
if isinstance(cloud, clouds.SSH):
|
3531
|
-
ssh_is_enabled = True
|
3532
|
-
elif isinstance(cloud, clouds.Kubernetes):
|
3533
|
-
kubernetes_is_enabled = True
|
3515
|
+
kubernetes_is_enabled = clouds.Kubernetes.canonical_name() in enabled_clouds
|
3516
|
+
ssh_is_enabled = clouds.SSH.canonical_name() in enabled_clouds
|
3534
3517
|
query_k8s_realtime_gpu = (kubernetes_is_enabled and
|
3535
3518
|
(cloud_name is None or cloud_is_kubernetes))
|
3536
3519
|
query_ssh_realtime_gpu = (ssh_is_enabled and
|
sky/client/cli.py
CHANGED
@@ -1789,20 +1789,8 @@ def _show_enabled_infra(active_workspace: str, show_workspace: bool):
|
|
1789
1789
|
title = (f'{colorama.Fore.CYAN}{colorama.Style.BRIGHT}Enabled Infra'
|
1790
1790
|
f'{workspace_str}:'
|
1791
1791
|
f'{colorama.Style.RESET_ALL} ')
|
1792
|
-
|
1793
|
-
|
1794
|
-
enabled_k8s_infras = []
|
1795
|
-
enabled_cloud_infras = []
|
1796
|
-
for cloud in enabled_clouds:
|
1797
|
-
cloud_infra = cloud.get_infras()
|
1798
|
-
if isinstance(cloud, clouds.SSH):
|
1799
|
-
enabled_ssh_infras.extend(cloud_infra)
|
1800
|
-
elif isinstance(cloud, clouds.Kubernetes):
|
1801
|
-
enabled_k8s_infras.extend(cloud_infra)
|
1802
|
-
else:
|
1803
|
-
enabled_cloud_infras.extend(cloud_infra)
|
1804
|
-
all_infras = sorted(enabled_ssh_infras) + sorted(
|
1805
|
-
enabled_k8s_infras) + sorted(enabled_cloud_infras)
|
1792
|
+
all_infras = sdk.get(
|
1793
|
+
sdk.enabled_clouds(workspace=active_workspace, expand=True))
|
1806
1794
|
click.echo(f'{title}{", ".join(all_infras)}\n')
|
1807
1795
|
|
1808
1796
|
|
@@ -1997,7 +1985,7 @@ def status(verbose: bool, refresh: bool, ip: bool, endpoints: bool,
|
|
1997
1985
|
workspace_request_id = sdk.workspaces()
|
1998
1986
|
except RuntimeError:
|
1999
1987
|
# Backward compatibility for API server before #5660.
|
2000
|
-
# TODO(zhwu): remove this after 0.
|
1988
|
+
# TODO(zhwu): remove this after 0.10.0.
|
2001
1989
|
logger.warning(f'{colorama.Style.DIM}SkyPilot API server is '
|
2002
1990
|
'in an old version, and may miss feature: '
|
2003
1991
|
'workspaces. Update with: sky api stop; '
|
@@ -3524,13 +3512,8 @@ def show_gpus(
|
|
3524
3512
|
cloud_is_ssh = isinstance(cloud_obj, clouds.SSH)
|
3525
3513
|
# TODO(romilb): We should move this to the backend.
|
3526
3514
|
kubernetes_autoscaling = kubernetes_utils.get_autoscaler_type() is not None
|
3527
|
-
kubernetes_is_enabled =
|
3528
|
-
ssh_is_enabled =
|
3529
|
-
for cloud in enabled_clouds:
|
3530
|
-
if isinstance(cloud, clouds.SSH):
|
3531
|
-
ssh_is_enabled = True
|
3532
|
-
elif isinstance(cloud, clouds.Kubernetes):
|
3533
|
-
kubernetes_is_enabled = True
|
3515
|
+
kubernetes_is_enabled = clouds.Kubernetes.canonical_name() in enabled_clouds
|
3516
|
+
ssh_is_enabled = clouds.SSH.canonical_name() in enabled_clouds
|
3534
3517
|
query_k8s_realtime_gpu = (kubernetes_is_enabled and
|
3535
3518
|
(cloud_name is None or cloud_is_kubernetes))
|
3536
3519
|
query_ssh_realtime_gpu = (ssh_is_enabled and
|
sky/client/sdk.py
CHANGED
@@ -138,12 +138,14 @@ def check(infra_list: Optional[Tuple[str, ...]],
|
|
138
138
|
@usage_lib.entrypoint
|
139
139
|
@server_common.check_server_healthy_or_start
|
140
140
|
@annotations.client_api
|
141
|
-
def enabled_clouds(workspace: Optional[str] = None
|
141
|
+
def enabled_clouds(workspace: Optional[str] = None,
|
142
|
+
expand: bool = False) -> server_common.RequestId:
|
142
143
|
"""Gets the enabled clouds.
|
143
144
|
|
144
145
|
Args:
|
145
146
|
workspace: The workspace to get the enabled clouds for. If None, the
|
146
147
|
active workspace will be used.
|
148
|
+
expand: Whether to expand Kubernetes and SSH to list of resource pools.
|
147
149
|
|
148
150
|
Returns:
|
149
151
|
The request ID of the enabled clouds request.
|
@@ -154,7 +156,7 @@ def enabled_clouds(workspace: Optional[str] = None) -> server_common.RequestId:
|
|
154
156
|
if workspace is None:
|
155
157
|
workspace = skypilot_config.get_active_workspace()
|
156
158
|
response = requests.get((f'{server_common.get_server_url()}/enabled_clouds?'
|
157
|
-
f'workspace={workspace}'),
|
159
|
+
f'workspace={workspace}&expand={expand}'),
|
158
160
|
cookies=server_common.get_api_cookie_jar())
|
159
161
|
return server_common.get_request_id(response)
|
160
162
|
|
@@ -1919,6 +1921,7 @@ def api_login(endpoint: Optional[str] = None, get_token: bool = False) -> None:
|
|
1919
1921
|
if (endpoint is not None and not endpoint.startswith('http://') and
|
1920
1922
|
not endpoint.startswith('https://')):
|
1921
1923
|
raise click.BadParameter('Endpoint must be a valid URL.')
|
1924
|
+
endpoint = endpoint.rstrip('/')
|
1922
1925
|
|
1923
1926
|
server_status = server_common.check_server_healthy(endpoint)
|
1924
1927
|
if server_status == server_common.ApiServerStatus.NEEDS_AUTH or get_token:
|
sky/clouds/cloud.py
CHANGED
@@ -492,13 +492,13 @@ class Cloud:
|
|
492
492
|
f'{cls._REPR} does not support {CloudCapability.STORAGE.value}.')
|
493
493
|
|
494
494
|
@classmethod
|
495
|
-
def
|
495
|
+
def expand_infras(cls) -> List[str]:
|
496
496
|
"""Returns a list of enabled infrastructures for this cloud.
|
497
497
|
|
498
498
|
For Kubernetes and SSH, return a list of resource pools.
|
499
499
|
For all other clouds, return self.
|
500
500
|
"""
|
501
|
-
return [cls.
|
501
|
+
return [cls.canonical_name()]
|
502
502
|
|
503
503
|
# TODO(zhwu): Make the return type immutable.
|
504
504
|
@classmethod
|
sky/clouds/kubernetes.py
CHANGED
@@ -164,15 +164,20 @@ class Kubernetes(clouds.Cloud):
|
|
164
164
|
|
165
165
|
all_contexts = set(all_contexts)
|
166
166
|
|
167
|
+
# Allowed_contexts specified for workspace should take precedence over
|
168
|
+
# the global allowed_contexts.
|
169
|
+
allowed_contexts = skypilot_config.get_workspace_cloud(
|
170
|
+
'kubernetes').get('allowed_contexts', None)
|
171
|
+
if allowed_contexts is None:
|
172
|
+
allowed_contexts = skypilot_config.get_nested(
|
173
|
+
('kubernetes', 'allowed_contexts'), None)
|
174
|
+
|
167
175
|
# Exclude contexts starting with `ssh-`
|
168
176
|
# TODO(romilb): Remove when SSH Node Pools use a separate kubeconfig.
|
169
177
|
all_contexts = [
|
170
178
|
ctx for ctx in all_contexts if not ctx.startswith('ssh-')
|
171
179
|
]
|
172
180
|
|
173
|
-
allowed_contexts = skypilot_config.get_nested(
|
174
|
-
('kubernetes', 'allowed_contexts'), None)
|
175
|
-
|
176
181
|
if allowed_contexts is None:
|
177
182
|
# Try kubeconfig if present
|
178
183
|
current_context = (
|
@@ -848,11 +853,11 @@ class Kubernetes(clouds.Cloud):
|
|
848
853
|
|
849
854
|
@classmethod
|
850
855
|
def get_user_identities(cls) -> Optional[List[List[str]]]:
|
851
|
-
k8s = kubernetes.kubernetes
|
852
856
|
identities = []
|
857
|
+
k8s = kubernetes.kubernetes
|
853
858
|
try:
|
854
859
|
all_contexts, current_context = (
|
855
|
-
|
860
|
+
kubernetes.list_kube_config_contexts())
|
856
861
|
except k8s.config.config_exception.ConfigException:
|
857
862
|
return None
|
858
863
|
# Add current context at the head of the list
|
@@ -894,8 +899,8 @@ class Kubernetes(clouds.Cloud):
|
|
894
899
|
return True, None
|
895
900
|
|
896
901
|
@classmethod
|
897
|
-
def
|
902
|
+
def expand_infras(cls) -> List[str]:
|
898
903
|
return [
|
899
|
-
f'{cls.
|
904
|
+
f'{cls.canonical_name()}/{c}'
|
900
905
|
for c in cls.existing_allowed_contexts(silent=True)
|
901
906
|
]
|
@@ -260,6 +260,10 @@ def _list_accelerators(
|
|
260
260
|
container.resources.requests))
|
261
261
|
|
262
262
|
accelerators_available = accelerator_count - allocated_qty
|
263
|
+
# Initialize the total_accelerators_available to make sure the
|
264
|
+
# key exists in the dictionary.
|
265
|
+
total_accelerators_available[accelerator_name] = (
|
266
|
+
total_accelerators_available.get(accelerator_name, 0))
|
263
267
|
|
264
268
|
if accelerators_available >= min_quantity_filter:
|
265
269
|
quantized_availability = min_quantity_filter * (
|
sky/clouds/ssh.py
CHANGED
@@ -7,6 +7,7 @@ from typing import Dict, List, Optional, Set, Tuple, Union
|
|
7
7
|
import yaml
|
8
8
|
|
9
9
|
from sky import sky_logging
|
10
|
+
from sky import skypilot_config
|
10
11
|
from sky.adaptors import kubernetes as kubernetes_adaptor
|
11
12
|
from sky.clouds import kubernetes
|
12
13
|
from sky.provision.kubernetes import utils as kubernetes_utils
|
@@ -134,29 +135,44 @@ class SSH(kubernetes.Kubernetes):
|
|
134
135
|
|
135
136
|
all_contexts = set(all_contexts)
|
136
137
|
|
138
|
+
# Workspace-level allowed_node_pools should take precedence over
|
139
|
+
# the global allowed_node_pools.
|
140
|
+
allowed_node_pools = skypilot_config.get_workspace_cloud('ssh').get(
|
141
|
+
'allowed_node_pools', None)
|
142
|
+
if allowed_node_pools is None:
|
143
|
+
allowed_node_pools = skypilot_config.get_nested(
|
144
|
+
('ssh', 'allowed_node_pools'), None)
|
145
|
+
|
137
146
|
# Filter for SSH contexts (those starting with 'ssh-')
|
138
147
|
ssh_contexts = [
|
139
148
|
context for context in all_contexts if context.startswith('ssh-')
|
140
149
|
]
|
141
150
|
|
142
151
|
# Get contexts from SSH node pools file
|
143
|
-
|
152
|
+
all_node_pool_contexts = cls.get_ssh_node_pool_contexts()
|
153
|
+
|
154
|
+
def filter_by_allowed_node_pools(ctxs):
|
155
|
+
if allowed_node_pools is None:
|
156
|
+
return ctxs
|
157
|
+
return [
|
158
|
+
ctx for ctx in ctxs if ctx.lstrip('ssh-') in allowed_node_pools
|
159
|
+
]
|
144
160
|
|
145
|
-
if
|
161
|
+
if all_node_pool_contexts:
|
146
162
|
# Only include allowed contexts that exist
|
147
163
|
existing_contexts = []
|
148
164
|
skipped_contexts = []
|
149
|
-
for context in
|
165
|
+
for context in all_node_pool_contexts:
|
150
166
|
if context in ssh_contexts:
|
151
167
|
existing_contexts.append(context)
|
152
168
|
else:
|
153
169
|
skipped_contexts.append(context)
|
154
170
|
if not silent:
|
155
171
|
cls._ssh_log_skipped_contexts_once(tuple(skipped_contexts))
|
156
|
-
return existing_contexts
|
172
|
+
return filter_by_allowed_node_pools(existing_contexts)
|
157
173
|
|
158
|
-
# If no
|
159
|
-
return ssh_contexts
|
174
|
+
# If no all_node_pool_contexts found, return all SSH contexts
|
175
|
+
return filter_by_allowed_node_pools(ssh_contexts)
|
160
176
|
|
161
177
|
@classmethod
|
162
178
|
def _check_compute_credentials(
|
@@ -192,9 +208,9 @@ class SSH(kubernetes.Kubernetes):
|
|
192
208
|
return success, ctx2text
|
193
209
|
|
194
210
|
@classmethod
|
195
|
-
def
|
211
|
+
def expand_infras(cls) -> List[str]:
|
196
212
|
return [
|
197
|
-
f'{cls.
|
213
|
+
f'{cls.canonical_name()}/{c.lstrip("ssh-")}'
|
198
214
|
for c in cls.existing_allowed_contexts(silent=True)
|
199
215
|
]
|
200
216
|
|
sky/core.py
CHANGED
@@ -1010,11 +1010,29 @@ def storage_delete(name: str) -> None:
|
|
1010
1010
|
# = Catalog Observe =
|
1011
1011
|
# ===================
|
1012
1012
|
@usage_lib.entrypoint
|
1013
|
-
def enabled_clouds(workspace: Optional[str] = None
|
1013
|
+
def enabled_clouds(workspace: Optional[str] = None,
|
1014
|
+
expand: bool = False) -> List[str]:
|
1014
1015
|
if workspace is None:
|
1015
1016
|
workspace = skypilot_config.get_active_workspace()
|
1016
|
-
|
1017
|
+
cached_clouds = global_user_state.get_cached_enabled_clouds(
|
1017
1018
|
sky_cloud.CloudCapability.COMPUTE, workspace=workspace)
|
1019
|
+
with skypilot_config.local_active_workspace_ctx(workspace):
|
1020
|
+
if not expand:
|
1021
|
+
return [cloud.canonical_name() for cloud in cached_clouds]
|
1022
|
+
enabled_ssh_infras = []
|
1023
|
+
enabled_k8s_infras = []
|
1024
|
+
enabled_cloud_infras = []
|
1025
|
+
for cloud in cached_clouds:
|
1026
|
+
cloud_infra = cloud.expand_infras()
|
1027
|
+
if isinstance(cloud, clouds.SSH):
|
1028
|
+
enabled_ssh_infras.extend(cloud_infra)
|
1029
|
+
elif isinstance(cloud, clouds.Kubernetes):
|
1030
|
+
enabled_k8s_infras.extend(cloud_infra)
|
1031
|
+
else:
|
1032
|
+
enabled_cloud_infras.extend(cloud_infra)
|
1033
|
+
all_infras = sorted(enabled_ssh_infras) + sorted(
|
1034
|
+
enabled_k8s_infras) + sorted(enabled_cloud_infras)
|
1035
|
+
return all_infras
|
1018
1036
|
|
1019
1037
|
|
1020
1038
|
@usage_lib.entrypoint
|
sky/dashboard/out/404.html
CHANGED
@@ -1 +1 @@
|
|
1
|
-
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>404: This page could not be found</title><meta name="next-head-count" content="3"/><link rel="preload" href="/dashboard/_next/static/css/
|
1
|
+
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>404: This page could not be found</title><meta name="next-head-count" content="3"/><link rel="preload" href="/dashboard/_next/static/css/ffd1cd601648c303.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/ffd1cd601648c303.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-deda68c926e8d0bc.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-a631df412d8172de.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_error-1be831200e60c5c0.js" defer=""></script><script src="/dashboard/_next/static/Mx1iAbDQn1jMHh3UHmK3R/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/Mx1iAbDQn1jMHh3UHmK3R/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"Mx1iAbDQn1jMHh3UHmK3R","assetPrefix":"/dashboard","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
|
@@ -0,0 +1 @@
|
|
1
|
+
self.__BUILD_MANIFEST=function(s,c,e,a,t,r,u,n,f,j,i){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/":["static/chunks/pages/index-6b0d9e5031b70c58.js"],"/_error":["static/chunks/pages/_error-1be831200e60c5c0.js"],"/clusters":[s,t,c,e,a,r,j,"static/chunks/pages/clusters-943992b84fd6f4ee.js"],"/clusters/[cluster]":[s,t,c,e,a,r,u,j,"static/chunks/pages/clusters/[cluster]-9506c00257d10dbd.js"],"/clusters/[cluster]/[job]":[s,c,"static/chunks/pages/clusters/[cluster]/[job]-159bffb2fa34ed54.js"],"/config":[n,s,f,c,e,"static/chunks/pages/config-41738d1896fc02fe.js"],"/infra":[s,c,e,a,"static/chunks/pages/infra-881fcd902fbbd0e5.js"],"/jobs":[s,t,c,e,a,r,u,"static/chunks/pages/jobs-a4efc09e61988f8d.js"],"/jobs/[job]":[s,c,"static/chunks/pages/jobs/[job]-2c29e97a6aa50dd4.js"],"/users":[s,c,e,a,"static/chunks/pages/users-b2634885d67c49a6.js"],"/workspace/new":[n,s,t,f,c,e,a,r,u,i,"static/chunks/pages/workspace/new-579b3203c7c19d84.js"],"/workspaces":[n,s,t,f,c,e,a,r,u,"static/chunks/pages/workspaces-610c49ae3619ee85.js"],"/workspaces/[name]":[n,s,t,f,c,e,a,r,u,i,"static/chunks/pages/workspaces/[name]-9388e38fac73ee8f.js"],sortedPages:["/","/_app","/_error","/clusters","/clusters/[cluster]","/clusters/[cluster]/[job]","/config","/infra","/jobs","/jobs/[job]","/users","/workspace/new","/workspaces","/workspaces/[name]"]}}("static/chunks/173-7db8607cefc20f70.js","static/chunks/470-4d003c441839094d.js","static/chunks/293-351268365226d251.js","static/chunks/856-62b87c68917b08ed.js","static/chunks/121-8f55ee3fa6301784.js","static/chunks/973-1a09cac61cfcc1e1.js","static/chunks/236-d6900c828331f664.js","static/chunks/9f96d65d-5a3e4af68c26849e.js","static/chunks/320-afea3ddcc5bd1c6c.js","static/chunks/578-9146658cead92981.js","static/chunks/843-256ec920f6d5f41f.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
@@ -0,0 +1,20 @@
|
|
1
|
+
"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[121],{8671:function(e,t,n){n.d(t,{Z:function(){return r}});/**
|
2
|
+
* @license lucide-react v0.407.0 - ISC
|
3
|
+
*
|
4
|
+
* This source code is licensed under the ISC license.
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
6
|
+
*/let r=(0,n(998).Z)("Copy",[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]])},3626:function(e,t,n){n.d(t,{Z:function(){return r}});/**
|
7
|
+
* @license lucide-react v0.407.0 - ISC
|
8
|
+
*
|
9
|
+
* This source code is licensed under the ISC license.
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
11
|
+
*/let r=(0,n(998).Z)("RotateCw",[["path",{d:"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8",key:"1p45f6"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}]])},3767:function(e,t,n){n.d(t,{Z:function(){return r}});/**
|
12
|
+
* @license lucide-react v0.407.0 - ISC
|
13
|
+
*
|
14
|
+
* This source code is licensed under the ISC license.
|
15
|
+
* See the LICENSE file in the root directory of this source tree.
|
16
|
+
*/let r=(0,n(998).Z)("X",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]])},6327:function(e,t,n){n.d(t,{x8:function(){return el},VY:function(){return eo},dk:function(){return ea},aV:function(){return er},h_:function(){return en},fC:function(){return ee},Dx:function(){return ei},xz:function(){return et}});var r=n(7294),o=n(6206),i=n(8771),a=n(5360),l=n(1276),u=n(7342),s=n(6063),d=n(5420),c=n(2651),f=n(9981),p=e=>{let t,n;let{present:o,children:a}=e,l=function(e){var t,n;let[o,i]=r.useState(),a=r.useRef(null),l=r.useRef(e),u=r.useRef("none"),[s,d]=(t=e?"mounted":"unmounted",n={mounted:{UNMOUNT:"unmounted",ANIMATION_OUT:"unmountSuspended"},unmountSuspended:{MOUNT:"mounted",ANIMATION_END:"unmounted"},unmounted:{MOUNT:"mounted"}},r.useReducer((e,t)=>n[e][t]??e,t));return r.useEffect(()=>{let e=m(a.current);u.current="mounted"===s?e:"none"},[s]),(0,f.b)(()=>{let t=a.current,n=l.current;if(n!==e){let r=u.current,o=m(t);e?d("MOUNT"):"none"===o||t?.display==="none"?d("UNMOUNT"):n&&r!==o?d("ANIMATION_OUT"):d("UNMOUNT"),l.current=e}},[e,d]),(0,f.b)(()=>{if(o){let e;let t=o.ownerDocument.defaultView??window,n=n=>{let r=m(a.current).includes(n.animationName);if(n.target===o&&r&&(d("ANIMATION_END"),!l.current)){let n=o.style.animationFillMode;o.style.animationFillMode="forwards",e=t.setTimeout(()=>{"forwards"===o.style.animationFillMode&&(o.style.animationFillMode=n)})}},r=e=>{e.target===o&&(u.current=m(a.current))};return o.addEventListener("animationstart",r),o.addEventListener("animationcancel",n),o.addEventListener("animationend",n),()=>{t.clearTimeout(e),o.removeEventListener("animationstart",r),o.removeEventListener("animationcancel",n),o.removeEventListener("animationend",n)}}d("ANIMATION_END")},[o,d]),{isPresent:["mounted","unmountSuspended"].includes(s),ref:r.useCallback(e=>{a.current=e?getComputedStyle(e):null,i(e)},[])}}(o),u="function"==typeof a?a({present:l.isPresent}):r.Children.only(a),s=(0,i.e)(l.ref,(t=Object.getOwnPropertyDescriptor(u.props,"ref")?.get)&&"isReactWarning"in t&&t.isReactWarning?u.ref:(t=Object.getOwnPropertyDescriptor(u,"ref")?.get)&&"isReactWarning"in t&&t.isReactWarning?u.props.ref:u.props.ref||u.ref);return"function"==typeof a||l.isPresent?r.cloneElement(u,{ref:s}):null};function m(e){return e?.animationName||"none"}p.displayName="Presence";var g=n(5320),v=n(7552),y=n(6223),N=n(3541),h=n(8426),D=n(5893),O="Dialog",[b,M]=(0,a.b)(O),[R,x]=b(O),j=e=>{let{__scopeDialog:t,children:n,open:o,defaultOpen:i,onOpenChange:a,modal:s=!0}=e,d=r.useRef(null),c=r.useRef(null),[f,p]=(0,u.T)({prop:o,defaultProp:i??!1,onChange:a,caller:O});return(0,D.jsx)(R,{scope:t,triggerRef:d,contentRef:c,contentId:(0,l.M)(),titleId:(0,l.M)(),descriptionId:(0,l.M)(),open:f,onOpenChange:p,onOpenToggle:r.useCallback(()=>p(e=>!e),[p]),modal:s,children:n})};j.displayName=O;var w="DialogTrigger",I=r.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,a=x(w,n),l=(0,i.e)(t,a.triggerRef);return(0,D.jsx)(g.WV.button,{type:"button","aria-haspopup":"dialog","aria-expanded":a.open,"aria-controls":a.contentId,"data-state":H(a.open),...r,ref:l,onClick:(0,o.M)(e.onClick,a.onOpenToggle)})});I.displayName=w;var C="DialogPortal",[E,_]=b(C,{forceMount:void 0}),T=e=>{let{__scopeDialog:t,forceMount:n,children:o,container:i}=e,a=x(C,t);return(0,D.jsx)(E,{scope:t,forceMount:n,children:r.Children.map(o,e=>(0,D.jsx)(p,{present:n||a.open,children:(0,D.jsx)(c.h,{asChild:!0,container:i,children:e})}))})};T.displayName=C;var k="DialogOverlay",A=r.forwardRef((e,t)=>{let n=_(k,e.__scopeDialog),{forceMount:r=n.forceMount,...o}=e,i=x(k,e.__scopeDialog);return i.modal?(0,D.jsx)(p,{present:r||i.open,children:(0,D.jsx)(P,{...o,ref:t})}):null});A.displayName=k;var F=(0,h.Z8)("DialogOverlay.RemoveScroll"),P=r.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,o=x(k,n);return(0,D.jsx)(y.Z,{as:F,allowPinchZoom:!0,shards:[o.contentRef],children:(0,D.jsx)(g.WV.div,{"data-state":H(o.open),...r,ref:t,style:{pointerEvents:"auto",...r.style}})})}),W="DialogContent",U=r.forwardRef((e,t)=>{let n=_(W,e.__scopeDialog),{forceMount:r=n.forceMount,...o}=e,i=x(W,e.__scopeDialog);return(0,D.jsx)(p,{present:r||i.open,children:i.modal?(0,D.jsx)(V,{...o,ref:t}):(0,D.jsx)(Z,{...o,ref:t})})});U.displayName=W;var V=r.forwardRef((e,t)=>{let n=x(W,e.__scopeDialog),a=r.useRef(null),l=(0,i.e)(t,n.contentRef,a);return r.useEffect(()=>{let e=a.current;if(e)return(0,N.Ry)(e)},[]),(0,D.jsx)(S,{...e,ref:l,trapFocus:n.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:(0,o.M)(e.onCloseAutoFocus,e=>{e.preventDefault(),n.triggerRef.current?.focus()}),onPointerDownOutside:(0,o.M)(e.onPointerDownOutside,e=>{let t=e.detail.originalEvent,n=0===t.button&&!0===t.ctrlKey;(2===t.button||n)&&e.preventDefault()}),onFocusOutside:(0,o.M)(e.onFocusOutside,e=>e.preventDefault())})}),Z=r.forwardRef((e,t)=>{let n=x(W,e.__scopeDialog),o=r.useRef(!1),i=r.useRef(!1);return(0,D.jsx)(S,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:t=>{e.onCloseAutoFocus?.(t),t.defaultPrevented||(o.current||n.triggerRef.current?.focus(),t.preventDefault()),o.current=!1,i.current=!1},onInteractOutside:t=>{e.onInteractOutside?.(t),t.defaultPrevented||(o.current=!0,"pointerdown"!==t.detail.originalEvent.type||(i.current=!0));let r=t.target;n.triggerRef.current?.contains(r)&&t.preventDefault(),"focusin"===t.detail.originalEvent.type&&i.current&&t.preventDefault()}})}),S=r.forwardRef((e,t)=>{let{__scopeDialog:n,trapFocus:o,onOpenAutoFocus:a,onCloseAutoFocus:l,...u}=e,c=x(W,n),f=r.useRef(null),p=(0,i.e)(t,f);return(0,v.EW)(),(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(d.M,{asChild:!0,loop:!0,trapped:o,onMountAutoFocus:a,onUnmountAutoFocus:l,children:(0,D.jsx)(s.XB,{role:"dialog",id:c.contentId,"aria-describedby":c.descriptionId,"aria-labelledby":c.titleId,"data-state":H(c.open),...u,ref:p,onDismiss:()=>c.onOpenChange(!1)})}),(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(J,{titleId:c.titleId}),(0,D.jsx)(Q,{contentRef:f,descriptionId:c.descriptionId})]})]})}),L="DialogTitle",$=r.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,o=x(L,n);return(0,D.jsx)(g.WV.h2,{id:o.titleId,...r,ref:t})});$.displayName=L;var B="DialogDescription",q=r.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,o=x(B,n);return(0,D.jsx)(g.WV.p,{id:o.descriptionId,...r,ref:t})});q.displayName=B;var z="DialogClose",X=r.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,i=x(z,n);return(0,D.jsx)(g.WV.button,{type:"button",...r,ref:t,onClick:(0,o.M)(e.onClick,()=>i.onOpenChange(!1))})});function H(e){return e?"open":"closed"}X.displayName=z;var K="DialogTitleWarning",[Y,G]=(0,a.k)(K,{contentName:W,titleName:L,docsSlug:"dialog"}),J=({titleId:e})=>{let t=G(K),n=`\`${t.contentName}\` requires a \`${t.titleName}\` for the component to be accessible for screen reader users.
|
17
|
+
|
18
|
+
If you want to hide the \`${t.titleName}\`, you can wrap it with our VisuallyHidden component.
|
19
|
+
|
20
|
+
For more information, see https://radix-ui.com/primitives/docs/components/${t.docsSlug}`;return r.useEffect(()=>{e&&!document.getElementById(e)&&console.error(n)},[n,e]),null},Q=({contentRef:e,descriptionId:t})=>{let n=G("DialogDescriptionWarning"),o=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${n.contentName}}.`;return r.useEffect(()=>{let n=e.current?.getAttribute("aria-describedby");t&&n&&!document.getElementById(t)&&console.warn(o)},[o,e,t]),null},ee=j,et=I,en=T,er=A,eo=U,ei=$,ea=q,el=X},2003:function(e,t,n){n.d(t,{j:function(){return a}});var r=n(512);let o=e=>"boolean"==typeof e?`${e}`:0===e?"0":e,i=r.W,a=(e,t)=>n=>{var r;if((null==t?void 0:t.variants)==null)return i(e,null==n?void 0:n.class,null==n?void 0:n.className);let{variants:a,defaultVariants:l}=t,u=Object.keys(a).map(e=>{let t=null==n?void 0:n[e],r=null==l?void 0:l[e];if(null===t)return null;let i=o(t)||o(r);return a[e][i]}),s=n&&Object.entries(n).reduce((e,t)=>{let[n,r]=t;return void 0===r||(e[n]=r),e},{});return i(e,u,null==t?void 0:null===(r=t.compoundVariants)||void 0===r?void 0:r.reduce((e,t)=>{let{class:n,className:r,...o}=t;return Object.entries(o).every(e=>{let[t,n]=e;return Array.isArray(n)?n.includes({...l,...s}[t]):({...l,...s})[t]===n})?[...e,n,r]:e},[]),null==n?void 0:n.class,null==n?void 0:n.className)}}}]);
|