skypilot-nightly 1.0.0.dev20250607__py3-none-any.whl → 1.0.0.dev20250610__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.
Files changed (132) hide show
  1. sky/__init__.py +2 -2
  2. sky/admin_policy.py +3 -0
  3. sky/authentication.py +1 -7
  4. sky/backends/backend_utils.py +18 -2
  5. sky/backends/cloud_vm_ray_backend.py +9 -20
  6. sky/check.py +4 -3
  7. sky/cli.py +6 -9
  8. sky/client/cli.py +6 -9
  9. sky/client/sdk.py +49 -4
  10. sky/clouds/kubernetes.py +15 -24
  11. sky/core.py +3 -2
  12. sky/dashboard/out/404.html +1 -1
  13. sky/dashboard/out/_next/static/4lwUJxN6KwBqUxqO1VccB/_buildManifest.js +1 -0
  14. sky/dashboard/out/_next/static/chunks/211.692afc57e812ae1a.js +1 -0
  15. sky/dashboard/out/_next/static/chunks/350.9e123a4551f68b0d.js +1 -0
  16. sky/dashboard/out/_next/static/chunks/37-d8aebf1683522a0b.js +6 -0
  17. sky/dashboard/out/_next/static/chunks/42.d39e24467181b06b.js +6 -0
  18. sky/dashboard/out/_next/static/chunks/443.b2242d0efcdf5f47.js +1 -0
  19. sky/dashboard/out/_next/static/chunks/470-4d1a5dbe58a8a2b9.js +1 -0
  20. sky/dashboard/out/_next/static/chunks/{121-865d2bf8a3b84c6a.js → 491.b3d264269613fe09.js} +3 -3
  21. sky/dashboard/out/_next/static/chunks/513.211357a2914a34b2.js +1 -0
  22. sky/dashboard/out/_next/static/chunks/600.9cc76ec442b22e10.js +16 -0
  23. sky/dashboard/out/_next/static/chunks/616-d6128fa9e7cae6e6.js +39 -0
  24. sky/dashboard/out/_next/static/chunks/664-047bc03493fda379.js +1 -0
  25. sky/dashboard/out/_next/static/chunks/682.4dd5dc116f740b5f.js +6 -0
  26. sky/dashboard/out/_next/static/chunks/760-a89d354797ce7af5.js +1 -0
  27. sky/dashboard/out/_next/static/chunks/799-3625946b2ec2eb30.js +8 -0
  28. sky/dashboard/out/_next/static/chunks/804-4c9fc53aa74bc191.js +21 -0
  29. sky/dashboard/out/_next/static/chunks/843-6fcc4bf91ac45b39.js +11 -0
  30. sky/dashboard/out/_next/static/chunks/856-0776dc6ed6000c39.js +1 -0
  31. sky/dashboard/out/_next/static/chunks/901-b424d293275e1fd7.js +1 -0
  32. sky/dashboard/out/_next/static/chunks/938-a75b7712639298b7.js +1 -0
  33. sky/dashboard/out/_next/static/chunks/947-6620842ef80ae879.js +35 -0
  34. sky/dashboard/out/_next/static/chunks/969-20d54a9d998dc102.js +1 -0
  35. sky/dashboard/out/_next/static/chunks/973-c807fc34f09c7df3.js +1 -0
  36. sky/dashboard/out/_next/static/chunks/pages/_app-4768de0aede04dc9.js +20 -0
  37. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-89216c616dbaa9c5.js +6 -0
  38. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-451a14e7e755ebbc.js +6 -0
  39. sky/dashboard/out/_next/static/chunks/pages/clusters-e56b17fd85d0ba58.js +1 -0
  40. sky/dashboard/out/_next/static/chunks/pages/config-497a35a7ed49734a.js +1 -0
  41. sky/dashboard/out/_next/static/chunks/pages/infra/[context]-d2910be98e9227cb.js +1 -0
  42. sky/dashboard/out/_next/static/chunks/pages/infra-780860bcc1103945.js +1 -0
  43. sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-b3dbf38b51cb29be.js +16 -0
  44. sky/dashboard/out/_next/static/chunks/pages/jobs-fe233baf3d073491.js +1 -0
  45. sky/dashboard/out/_next/static/chunks/pages/users-c69ffcab9d6e5269.js +1 -0
  46. sky/dashboard/out/_next/static/chunks/pages/workspace/new-31aa8bdcb7592635.js +1 -0
  47. sky/dashboard/out/_next/static/chunks/pages/workspaces/[name]-c8c2191328532b7d.js +1 -0
  48. sky/dashboard/out/_next/static/chunks/pages/workspaces-82e6601baa5dd280.js +1 -0
  49. sky/dashboard/out/_next/static/chunks/webpack-0574a5a4ba3cf0ac.js +1 -0
  50. sky/dashboard/out/_next/static/css/8b1c8321d4c02372.css +3 -0
  51. sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
  52. sky/dashboard/out/clusters/[cluster].html +1 -1
  53. sky/dashboard/out/clusters.html +1 -1
  54. sky/dashboard/out/config.html +1 -1
  55. sky/dashboard/out/index.html +1 -1
  56. sky/dashboard/out/infra/[context].html +1 -1
  57. sky/dashboard/out/infra.html +1 -1
  58. sky/dashboard/out/jobs/[job].html +1 -1
  59. sky/dashboard/out/jobs.html +1 -1
  60. sky/dashboard/out/users.html +1 -1
  61. sky/dashboard/out/workspace/new.html +1 -1
  62. sky/dashboard/out/workspaces/[name].html +1 -1
  63. sky/dashboard/out/workspaces.html +1 -1
  64. sky/exceptions.py +23 -0
  65. sky/global_user_state.py +192 -80
  66. sky/jobs/client/sdk.py +29 -21
  67. sky/jobs/server/core.py +9 -1
  68. sky/jobs/server/server.py +0 -95
  69. sky/jobs/utils.py +2 -1
  70. sky/models.py +18 -0
  71. sky/provision/kubernetes/constants.py +9 -0
  72. sky/provision/kubernetes/utils.py +106 -7
  73. sky/serve/client/sdk.py +56 -45
  74. sky/serve/server/core.py +1 -1
  75. sky/server/common.py +5 -7
  76. sky/server/constants.py +0 -2
  77. sky/server/requests/executor.py +60 -22
  78. sky/server/requests/payloads.py +3 -0
  79. sky/server/requests/process.py +69 -29
  80. sky/server/requests/requests.py +4 -3
  81. sky/server/server.py +23 -5
  82. sky/server/stream_utils.py +111 -55
  83. sky/skylet/constants.py +4 -2
  84. sky/skylet/job_lib.py +2 -1
  85. sky/skypilot_config.py +108 -25
  86. sky/users/model.conf +1 -1
  87. sky/users/permission.py +149 -32
  88. sky/users/rbac.py +26 -0
  89. sky/users/server.py +14 -13
  90. sky/utils/admin_policy_utils.py +9 -3
  91. sky/utils/common.py +6 -1
  92. sky/utils/common_utils.py +21 -3
  93. sky/utils/context.py +21 -1
  94. sky/utils/controller_utils.py +16 -1
  95. sky/utils/kubernetes/exec_kubeconfig_converter.py +19 -47
  96. sky/utils/schemas.py +9 -0
  97. sky/workspaces/core.py +100 -8
  98. sky/workspaces/server.py +15 -2
  99. sky/workspaces/utils.py +56 -0
  100. {skypilot_nightly-1.0.0.dev20250607.dist-info → skypilot_nightly-1.0.0.dev20250610.dist-info}/METADATA +1 -1
  101. {skypilot_nightly-1.0.0.dev20250607.dist-info → skypilot_nightly-1.0.0.dev20250610.dist-info}/RECORD +106 -94
  102. sky/dashboard/out/_next/static/1qG0HTmVilJPxQdBk0fX5/_buildManifest.js +0 -1
  103. sky/dashboard/out/_next/static/chunks/236-619ed0248fb6fdd9.js +0 -6
  104. sky/dashboard/out/_next/static/chunks/293-351268365226d251.js +0 -1
  105. sky/dashboard/out/_next/static/chunks/37-600191c5804dcae2.js +0 -6
  106. sky/dashboard/out/_next/static/chunks/470-ad1e0db3afcbd9c9.js +0 -1
  107. sky/dashboard/out/_next/static/chunks/614-635a84e87800f99e.js +0 -66
  108. sky/dashboard/out/_next/static/chunks/682-b60cfdacc15202e8.js +0 -6
  109. sky/dashboard/out/_next/static/chunks/843-c296541442d4af88.js +0 -11
  110. sky/dashboard/out/_next/static/chunks/856-3a32da4b84176f6d.js +0 -1
  111. sky/dashboard/out/_next/static/chunks/969-2c584e28e6b4b106.js +0 -1
  112. sky/dashboard/out/_next/static/chunks/973-6d78a0814682d771.js +0 -1
  113. sky/dashboard/out/_next/static/chunks/pages/_app-cb81dc4d27f4d009.js +0 -1
  114. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-18aed9b56247d074.js +0 -6
  115. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-b919a73aecdfa78f.js +0 -6
  116. sky/dashboard/out/_next/static/chunks/pages/clusters-4f6b9dd9abcb33ad.js +0 -1
  117. sky/dashboard/out/_next/static/chunks/pages/config-fe375a56342cf609.js +0 -6
  118. sky/dashboard/out/_next/static/chunks/pages/infra/[context]-3a18d0eeb5119fe4.js +0 -1
  119. sky/dashboard/out/_next/static/chunks/pages/infra-a1a6abeeb58c1051.js +0 -1
  120. sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-1354e28c81eeb686.js +0 -16
  121. sky/dashboard/out/_next/static/chunks/pages/jobs-23bfc8bf373423db.js +0 -1
  122. sky/dashboard/out/_next/static/chunks/pages/users-5800045bd04e69c2.js +0 -16
  123. sky/dashboard/out/_next/static/chunks/pages/workspace/new-e1f9c0c3ff7ac4bd.js +0 -1
  124. sky/dashboard/out/_next/static/chunks/pages/workspaces/[name]-686590e0ee4b2412.js +0 -1
  125. sky/dashboard/out/_next/static/chunks/pages/workspaces-76b07aa5da91b0df.js +0 -1
  126. sky/dashboard/out/_next/static/chunks/webpack-65d465f948974c0d.js +0 -1
  127. sky/dashboard/out/_next/static/css/667d941a2888ce6e.css +0 -3
  128. /sky/dashboard/out/_next/static/{1qG0HTmVilJPxQdBk0fX5 → 4lwUJxN6KwBqUxqO1VccB}/_ssgManifest.js +0 -0
  129. {skypilot_nightly-1.0.0.dev20250607.dist-info → skypilot_nightly-1.0.0.dev20250610.dist-info}/WHEEL +0 -0
  130. {skypilot_nightly-1.0.0.dev20250607.dist-info → skypilot_nightly-1.0.0.dev20250610.dist-info}/entry_points.txt +0 -0
  131. {skypilot_nightly-1.0.0.dev20250607.dist-info → skypilot_nightly-1.0.0.dev20250610.dist-info}/licenses/LICENSE +0 -0
  132. {skypilot_nightly-1.0.0.dev20250607.dist-info → skypilot_nightly-1.0.0.dev20250610.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 = 'c0494f5f0d6e41f225bf39434e163810be000fe3'
8
+ _SKYPILOT_COMMIT_SHA = 'd738e2a04a6185c2c01cb41ad2456cbc964411f0'
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.dev20250607'
38
+ __version__ = '1.0.0.dev20250610'
39
39
  __root_dir__ = os.path.dirname(os.path.abspath(__file__))
40
40
 
41
41
 
sky/admin_policy.py CHANGED
@@ -29,6 +29,7 @@ class RequestOptions:
29
29
  idle_minutes_to_autostop: Optional[int]
30
30
  down: bool
31
31
  dryrun: bool
32
+ is_client_side: bool = False
32
33
 
33
34
 
34
35
  @dataclasses.dataclass
@@ -50,10 +51,12 @@ class UserRequest:
50
51
  task: User specified task.
51
52
  skypilot_config: Global skypilot config to be used in this request.
52
53
  request_options: Request options. It is None for jobs and services.
54
+ at_client_side: Is the request intercepted by the policy at client-side?
53
55
  """
54
56
  task: 'sky.Task'
55
57
  skypilot_config: 'sky.Config'
56
58
  request_options: Optional['RequestOptions'] = None
59
+ at_client_side: bool = False
57
60
 
58
61
 
59
62
  @dataclasses.dataclass
sky/authentication.py CHANGED
@@ -439,13 +439,7 @@ def setup_kubernetes_authentication(config: Dict[str, Any]) -> Dict[str, Any]:
439
439
  # Add the user's public key to the SkyPilot cluster.
440
440
  secret_name = clouds.Kubernetes.SKY_SSH_KEY_SECRET_NAME
441
441
  secret_field_name = clouds.Kubernetes().ssh_key_secret_field_name
442
- context = config['provider'].get(
443
- 'context', kubernetes_utils.get_current_kube_config_context_name())
444
- if context == kubernetes.in_cluster_context_name():
445
- # If the context is an in-cluster context name, we are running in a pod
446
- # with in-cluster configuration. We need to set the context to None
447
- # to use the mounted service account.
448
- context = None
442
+ context = kubernetes_utils.get_context_from_config(config['provider'])
449
443
  namespace = kubernetes_utils.get_namespace_from_config(config['provider'])
450
444
  k8s = kubernetes.kubernetes
451
445
  with open(public_key_path, 'r', encoding='utf-8') as f:
@@ -51,6 +51,7 @@ from sky.utils import status_lib
51
51
  from sky.utils import subprocess_utils
52
52
  from sky.utils import timeline
53
53
  from sky.utils import ux_utils
54
+ from sky.workspaces import core as workspaces_core
54
55
 
55
56
  if typing.TYPE_CHECKING:
56
57
  import requests
@@ -2570,19 +2571,34 @@ def get_clusters(
2570
2571
  public clouds only, and 'local' for only local clouds.
2571
2572
  cluster_names: If provided, only return records for the given cluster
2572
2573
  names.
2574
+ all_users: If True, return clusters from all users. If False, only
2575
+ return clusters from the current user.
2573
2576
 
2574
2577
  Returns:
2575
2578
  A list of cluster records. If the cluster does not exist or has been
2576
2579
  terminated, the record will be omitted from the returned list.
2577
2580
  """
2578
2581
  records = global_user_state.get_clusters()
2582
+ current_user = common_utils.get_current_user()
2583
+
2584
+ # Filter by user if requested
2579
2585
  if not all_users:
2580
- current_user_hash = common_utils.get_user_hash()
2581
2586
  records = [
2582
2587
  record for record in records
2583
- if record['user_hash'] == current_user_hash
2588
+ if record['user_hash'] == current_user.id
2584
2589
  ]
2585
2590
 
2591
+ accessible_workspaces = workspaces_core.get_workspaces()
2592
+
2593
+ workspace_filtered_records = []
2594
+ for record in records:
2595
+ cluster_workspace = record.get('workspace',
2596
+ constants.SKYPILOT_DEFAULT_WORKSPACE)
2597
+ if cluster_workspace in accessible_workspaces:
2598
+ workspace_filtered_records.append(record)
2599
+
2600
+ records = workspace_filtered_records
2601
+
2586
2602
  yellow = colorama.Fore.YELLOW
2587
2603
  bright = colorama.Style.BRIGHT
2588
2604
  reset = colorama.Style.RESET_ALL
@@ -2904,14 +2904,6 @@ class CloudVmRayBackend(backends.Backend['CloudVmRayResourceHandle']):
2904
2904
  # TODO(suquark): once we have sky on PyPI, we should directly
2905
2905
  # install sky from PyPI.
2906
2906
  local_wheel_path, wheel_hash = wheel_utils.build_sky_wheel()
2907
- # The most frequent reason for the failure of a provision
2908
- # request is resource unavailability instead of rate
2909
- # limiting; to make users wait shorter, we do not make
2910
- # backoffs exponential.
2911
- backoff = common_utils.Backoff(
2912
- initial_backoff=_RETRY_UNTIL_UP_INIT_GAP_SECONDS,
2913
- max_backoff_factor=1)
2914
- attempt_cnt = 1
2915
2907
  while True:
2916
2908
  # For on-demand instances, RetryingVmProvisioner will retry
2917
2909
  # within the given region first, then optionally retry on all
@@ -2955,19 +2947,16 @@ class CloudVmRayBackend(backends.Backend['CloudVmRayResourceHandle']):
2955
2947
  error_message = str(e)
2956
2948
 
2957
2949
  if retry_until_up:
2958
- logger.error(error_message)
2959
- # Sleep and retry.
2960
- gap_seconds = backoff.current_backoff()
2961
- plural = 's' if attempt_cnt > 1 else ''
2950
+ gap_seconds = _RETRY_UNTIL_UP_INIT_GAP_SECONDS
2962
2951
  retry_message = ux_utils.retry_message(
2963
- f'Retry after {gap_seconds:.0f}s '
2964
- f'({attempt_cnt} attempt{plural}). ')
2965
- logger.info(f'\n{retry_message} '
2966
- f'{ux_utils.log_path_hint(log_path)}'
2967
- f'{colorama.Style.RESET_ALL}')
2968
- attempt_cnt += 1
2969
- time.sleep(gap_seconds)
2970
- continue
2952
+ f'Retry after {gap_seconds:.0f}s ')
2953
+ hint_message = (f'\n{retry_message} '
2954
+ f'{ux_utils.log_path_hint(log_path)}'
2955
+ f'{colorama.Style.RESET_ALL}')
2956
+ raise exceptions.ExecutionRetryableError(
2957
+ error_message,
2958
+ hint=hint_message,
2959
+ retry_wait_seconds=gap_seconds)
2971
2960
  # Clean up the cluster's entry in `sky status`.
2972
2961
  # Do not remove the stopped cluster from the global state
2973
2962
  # if failed to start.
sky/check.py CHANGED
@@ -340,18 +340,19 @@ def get_cached_enabled_clouds_or_refresh(
340
340
  exceptions.NoCloudAccessError: if no public cloud is enabled and
341
341
  raise_if_no_cloud_access is set to True.
342
342
  """
343
+ active_workspace = skypilot_config.get_active_workspace()
343
344
  cached_enabled_clouds = global_user_state.get_cached_enabled_clouds(
344
- capability, skypilot_config.get_active_workspace())
345
+ capability, active_workspace)
345
346
  if not cached_enabled_clouds:
346
347
  try:
347
- check_capability(capability, quiet=True)
348
+ check_capability(capability, quiet=True, workspace=active_workspace)
348
349
  except SystemExit:
349
350
  # If no cloud is enabled, check() will raise SystemExit.
350
351
  # Here we catch it and raise the exception later only if
351
352
  # raise_if_no_cloud_access is set to True.
352
353
  pass
353
354
  cached_enabled_clouds = global_user_state.get_cached_enabled_clouds(
354
- capability, skypilot_config.get_active_workspace())
355
+ capability, active_workspace)
355
356
  if raise_if_no_cloud_access and not cached_enabled_clouds:
356
357
  with ux_utils.print_exception_no_traceback():
357
358
  raise exceptions.NoCloudAccessError(
sky/cli.py CHANGED
@@ -28,7 +28,6 @@ import copy
28
28
  import datetime
29
29
  import fnmatch
30
30
  import functools
31
- import getpass
32
31
  import os
33
32
  import pathlib
34
33
  import shlex
@@ -6243,19 +6242,17 @@ def api_info():
6243
6242
  """Shows the SkyPilot API server URL."""
6244
6243
  url = server_common.get_server_url()
6245
6244
  api_server_info = sdk.api_info()
6246
- user_name = os.getenv(constants.USER_ENV_VAR, getpass.getuser())
6247
- user_hash = common_utils.get_user_hash()
6248
6245
  api_server_user = api_server_info.get('user')
6249
6246
  if api_server_user is not None:
6250
- user_name = api_server_user['name']
6251
- user_hash = api_server_user['id']
6252
- dashboard_url = server_common.get_dashboard_url(url)
6253
- click.echo(f'Using SkyPilot API server: {url}\n'
6247
+ user = models.User(id=api_server_user['id'],
6248
+ name=api_server_user['name'])
6249
+ else:
6250
+ user = models.User.get_current_user()
6251
+ click.echo(f'Using SkyPilot API server and dashboard: {url}\n'
6254
6252
  f'{ux_utils.INDENT_SYMBOL}Status: {api_server_info["status"]}, '
6255
6253
  f'commit: {api_server_info["commit"]}, '
6256
6254
  f'version: {api_server_info["version"]}\n'
6257
- f'{ux_utils.INDENT_SYMBOL}User: {user_name} ({user_hash})\n'
6258
- f'{ux_utils.INDENT_LAST_SYMBOL}Dashboard: {dashboard_url}')
6255
+ f'{ux_utils.INDENT_LAST_SYMBOL}User: {user.name} ({user.id})')
6259
6256
 
6260
6257
 
6261
6258
  @cli.group(cls=_NaturalOrderGroup)
sky/client/cli.py CHANGED
@@ -28,7 +28,6 @@ import copy
28
28
  import datetime
29
29
  import fnmatch
30
30
  import functools
31
- import getpass
32
31
  import os
33
32
  import pathlib
34
33
  import shlex
@@ -6243,19 +6242,17 @@ def api_info():
6243
6242
  """Shows the SkyPilot API server URL."""
6244
6243
  url = server_common.get_server_url()
6245
6244
  api_server_info = sdk.api_info()
6246
- user_name = os.getenv(constants.USER_ENV_VAR, getpass.getuser())
6247
- user_hash = common_utils.get_user_hash()
6248
6245
  api_server_user = api_server_info.get('user')
6249
6246
  if api_server_user is not None:
6250
- user_name = api_server_user['name']
6251
- user_hash = api_server_user['id']
6252
- dashboard_url = server_common.get_dashboard_url(url)
6253
- click.echo(f'Using SkyPilot API server: {url}\n'
6247
+ user = models.User(id=api_server_user['id'],
6248
+ name=api_server_user['name'])
6249
+ else:
6250
+ user = models.User.get_current_user()
6251
+ click.echo(f'Using SkyPilot API server and dashboard: {url}\n'
6254
6252
  f'{ux_utils.INDENT_SYMBOL}Status: {api_server_info["status"]}, '
6255
6253
  f'commit: {api_server_info["commit"]}, '
6256
6254
  f'version: {api_server_info["version"]}\n'
6257
- f'{ux_utils.INDENT_SYMBOL}User: {user_name} ({user_hash})\n'
6258
- f'{ux_utils.INDENT_LAST_SYMBOL}Dashboard: {dashboard_url}')
6255
+ f'{ux_utils.INDENT_LAST_SYMBOL}User: {user.name} ({user.id})')
6259
6256
 
6260
6257
 
6261
6258
  @cli.group(cls=_NaturalOrderGroup)
sky/client/sdk.py CHANGED
@@ -42,10 +42,12 @@ from sky.server.requests import payloads
42
42
  from sky.server.requests import requests as requests_lib
43
43
  from sky.skylet import constants
44
44
  from sky.usage import usage_lib
45
+ from sky.utils import admin_policy_utils
45
46
  from sky.utils import annotations
46
47
  from sky.utils import cluster_utils
47
48
  from sky.utils import common
48
49
  from sky.utils import common_utils
50
+ from sky.utils import context as sky_context
49
51
  from sky.utils import dag_utils
50
52
  from sky.utils import env_options
51
53
  from sky.utils import infra_utils
@@ -355,6 +357,7 @@ def dashboard(starting_page: Optional[str] = None) -> None:
355
357
  @usage_lib.entrypoint
356
358
  @server_common.check_server_healthy_or_start
357
359
  @annotations.client_api
360
+ @sky_context.contextual
358
361
  def launch(
359
362
  task: Union['sky.Task', 'sky.Dag'],
360
363
  cluster_name: Optional[str] = None,
@@ -490,6 +493,50 @@ def launch(
490
493
  idle_minutes_to_autostop=idle_minutes_to_autostop,
491
494
  down=down,
492
495
  dryrun=dryrun)
496
+ with admin_policy_utils.apply_and_use_config_in_current_request(
497
+ dag, request_options=request_options, at_client_side=True) as dag:
498
+ return _launch(
499
+ dag,
500
+ cluster_name,
501
+ request_options,
502
+ retry_until_up,
503
+ idle_minutes_to_autostop,
504
+ dryrun,
505
+ down,
506
+ backend,
507
+ optimize_target,
508
+ no_setup,
509
+ clone_disk_from,
510
+ fast,
511
+ _need_confirmation,
512
+ _is_launched_by_jobs_controller,
513
+ _is_launched_by_sky_serve_controller,
514
+ _disable_controller_check,
515
+ )
516
+
517
+
518
+ def _launch(
519
+ dag: 'sky.Dag',
520
+ cluster_name: str,
521
+ request_options: admin_policy.RequestOptions,
522
+ retry_until_up: bool = False,
523
+ idle_minutes_to_autostop: Optional[int] = None,
524
+ dryrun: bool = False,
525
+ down: bool = False, # pylint: disable=redefined-outer-name
526
+ backend: Optional[backends.Backend] = None,
527
+ optimize_target: common.OptimizeTarget = common.OptimizeTarget.COST,
528
+ no_setup: bool = False,
529
+ clone_disk_from: Optional[str] = None,
530
+ fast: bool = False,
531
+ # Internal only:
532
+ # pylint: disable=invalid-name
533
+ _need_confirmation: bool = False,
534
+ _is_launched_by_jobs_controller: bool = False,
535
+ _is_launched_by_sky_serve_controller: bool = False,
536
+ _disable_controller_check: bool = False,
537
+ ) -> server_common.RequestId:
538
+ """Auxiliary function for launch(), refer to launch() for details."""
539
+
493
540
  validate(dag, admin_policy_request_options=request_options)
494
541
  # The flags have been applied to the task YAML and the backward
495
542
  # compatibility of admin policy has been handled. We should no longer use
@@ -1845,10 +1892,8 @@ def api_start(
1845
1892
  # Explain why current process exited
1846
1893
  logger.info('API server is already running:')
1847
1894
  api_server_url = server_common.get_server_url(host)
1848
- dashboard_url = server_common.get_dashboard_url(api_server_url)
1849
- dashboard_msg = f'Dashboard: {dashboard_url}'
1850
- logger.info(f'{ux_utils.INDENT_SYMBOL}SkyPilot API server: '
1851
- f'{api_server_url} {dashboard_msg}\n'
1895
+ logger.info(f'{ux_utils.INDENT_SYMBOL}SkyPilot API server and dashboard: '
1896
+ f'{api_server_url}\n'
1852
1897
  f'{ux_utils.INDENT_LAST_SYMBOL}'
1853
1898
  f'View API server logs at: {constants.API_SERVER_LOGS}')
1854
1899
 
sky/clouds/kubernetes.py CHANGED
@@ -1,4 +1,5 @@
1
1
  """Kubernetes."""
2
+ import os
2
3
  import re
3
4
  import subprocess
4
5
  import tempfile
@@ -106,17 +107,6 @@ class Kubernetes(clouds.Cloud):
106
107
  context = resources.region
107
108
  if context is None:
108
109
  context = kubernetes_utils.get_current_kube_config_context_name()
109
- # Features to be disabled for exec auth
110
- is_exec_auth, message = kubernetes_utils.is_kubeconfig_exec_auth(
111
- context)
112
- if is_exec_auth:
113
- assert isinstance(message, str), message
114
- # Controllers cannot spin up new pods with exec auth.
115
- unsupported_features[
116
- clouds.CloudImplementationFeatures.HOST_CONTROLLERS] = message
117
- # Pod does not have permissions to down itself with exec auth.
118
- unsupported_features[
119
- clouds.CloudImplementationFeatures.AUTODOWN] = message
120
110
  unsupported_features[clouds.CloudImplementationFeatures.STOP] = (
121
111
  'Stopping clusters is not supported on Kubernetes.')
122
112
  unsupported_features[clouds.CloudImplementationFeatures.AUTOSTOP] = (
@@ -537,20 +527,17 @@ class Kubernetes(clouds.Cloud):
537
527
  # If remote_identity is not a dict, use
538
528
  k8s_service_account_name = remote_identity
539
529
 
540
- if (k8s_service_account_name ==
541
- schemas.RemoteIdentityOptions.LOCAL_CREDENTIALS.value):
542
- # SA name doesn't matter since automounting credentials is disabled
543
- k8s_service_account_name = 'default'
544
- k8s_automount_sa_token = 'false'
545
- elif (k8s_service_account_name ==
546
- schemas.RemoteIdentityOptions.SERVICE_ACCOUNT.value):
547
- # Use the default service account
530
+ lc = schemas.RemoteIdentityOptions.LOCAL_CREDENTIALS.value
531
+ sa = schemas.RemoteIdentityOptions.SERVICE_ACCOUNT.value
532
+
533
+ if k8s_service_account_name == lc or k8s_service_account_name == sa:
534
+ # Use the default service account if remote identity is not set.
535
+ # For LOCAL_CREDENTIALS, this is for in-cluster authentication
536
+ # which needs a serviceaccount (specifically for SSH node pools
537
+ # which uses in-cluster authentication internally, and we would
538
+ # like to support exec-auth when the user is also using SSH infra)
548
539
  k8s_service_account_name = (
549
540
  kubernetes_utils.DEFAULT_SERVICE_ACCOUNT_NAME)
550
- k8s_automount_sa_token = 'true'
551
- else:
552
- # User specified a custom service account
553
- k8s_automount_sa_token = 'true'
554
541
 
555
542
  fuse_device_required = bool(resources.requires_fuse)
556
543
 
@@ -624,7 +611,7 @@ class Kubernetes(clouds.Cloud):
624
611
  'k8s_ssh_jump_name': self.SKY_SSH_JUMP_NAME,
625
612
  'k8s_ssh_jump_image': ssh_jump_image,
626
613
  'k8s_service_account_name': k8s_service_account_name,
627
- 'k8s_automount_sa_token': k8s_automount_sa_token,
614
+ 'k8s_automount_sa_token': 'true',
628
615
  'k8s_fuse_device_required': fuse_device_required,
629
616
  # Namespace to run the fusermount-server daemonset in
630
617
  'k8s_skypilot_system_namespace': _SKYPILOT_SYSTEM_NAMESPACE,
@@ -863,6 +850,10 @@ class Kubernetes(clouds.Cloud):
863
850
  f'> {kubeconfig_file}',
864
851
  shell=True,
865
852
  check=True)
853
+ if os.path.exists(kubeconfig_file):
854
+ # convert auth plugin paths (e.g.: gke-gcloud-auth-plugin)
855
+ kubeconfig_file = kubernetes_utils.format_kubeconfig_exec_auth_with_cache(kubeconfig_file) # pylint: disable=line-too-long
856
+
866
857
  # Upload kubeconfig to the default path to avoid having to set
867
858
  # KUBECONFIG in the environment.
868
859
  return {kubernetes.DEFAULT_KUBECONFIG_PATH: kubeconfig_file}
sky/core.py CHANGED
@@ -711,9 +711,10 @@ def queue(cluster_name: str,
711
711
  exceptions.CommandError: if failed to get the job queue with ssh.
712
712
  """
713
713
  all_jobs = not skip_finished
714
- user_hash: Optional[str] = common_utils.get_user_hash()
715
714
  if all_users:
716
715
  user_hash = None
716
+ else:
717
+ user_hash = common_utils.get_current_user().id
717
718
  code = job_lib.JobLibCodeGen.get_job_queue(user_hash, all_jobs)
718
719
 
719
720
  handle = backend_utils.check_cluster_available(
@@ -829,7 +830,7 @@ def cancel(
829
830
  backend.cancel_jobs(handle,
830
831
  job_ids,
831
832
  cancel_all=all or all_users,
832
- user_hash=common_utils.get_user_hash())
833
+ user_hash=common_utils.get_current_user().id)
833
834
 
834
835
 
835
836
  @usage_lib.entrypoint
@@ -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/667d941a2888ce6e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/667d941a2888ce6e.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-65d465f948974c0d.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-cb81dc4d27f4d009.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_error-1be831200e60c5c0.js" defer=""></script><script src="/dashboard/_next/static/1qG0HTmVilJPxQdBk0fX5/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/1qG0HTmVilJPxQdBk0fX5/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;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":"1qG0HTmVilJPxQdBk0fX5","assetPrefix":"/dashboard","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/8b1c8321d4c02372.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/8b1c8321d4c02372.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-0574a5a4ba3cf0ac.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-4768de0aede04dc9.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_error-1be831200e60c5c0.js" defer=""></script><script src="/dashboard/_next/static/4lwUJxN6KwBqUxqO1VccB/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/4lwUJxN6KwBqUxqO1VccB/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"4lwUJxN6KwBqUxqO1VccB","assetPrefix":"/dashboard","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
@@ -0,0 +1 @@
1
+ self.__BUILD_MANIFEST=function(s,c,a,e,t,n,b,r,u,i,j,k,f){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/":["static/chunks/pages/index-6b0d9e5031b70c58.js"],"/_error":["static/chunks/pages/_error-1be831200e60c5c0.js"],"/clusters":["static/chunks/pages/clusters-e56b17fd85d0ba58.js"],"/clusters/[cluster]":[s,c,a,e,t,b,u,n,i,r,j,k,f,"static/chunks/37-d8aebf1683522a0b.js","static/chunks/pages/clusters/[cluster]-451a14e7e755ebbc.js"],"/clusters/[cluster]/[job]":[s,c,a,e,t,n,"static/chunks/pages/clusters/[cluster]/[job]-89216c616dbaa9c5.js"],"/config":["static/chunks/pages/config-497a35a7ed49734a.js"],"/infra":["static/chunks/pages/infra-780860bcc1103945.js"],"/infra/[context]":["static/chunks/pages/infra/[context]-d2910be98e9227cb.js"],"/jobs":["static/chunks/pages/jobs-fe233baf3d073491.js"],"/jobs/[job]":[s,c,a,e,t,b,n,r,"static/chunks/pages/jobs/[job]-b3dbf38b51cb29be.js"],"/users":["static/chunks/pages/users-c69ffcab9d6e5269.js"],"/workspace/new":["static/chunks/pages/workspace/new-31aa8bdcb7592635.js"],"/workspaces":["static/chunks/pages/workspaces-82e6601baa5dd280.js"],"/workspaces/[name]":[s,c,a,e,t,b,u,n,i,r,j,k,f,"static/chunks/843-6fcc4bf91ac45b39.js","static/chunks/pages/workspaces/[name]-c8c2191328532b7d.js"],sortedPages:["/","/_app","/_error","/clusters","/clusters/[cluster]","/clusters/[cluster]/[job]","/config","/infra","/infra/[context]","/jobs","/jobs/[job]","/users","/workspace/new","/workspaces","/workspaces/[name]"]}}("static/chunks/616-d6128fa9e7cae6e6.js","static/chunks/760-a89d354797ce7af5.js","static/chunks/799-3625946b2ec2eb30.js","static/chunks/804-4c9fc53aa74bc191.js","static/chunks/664-047bc03493fda379.js","static/chunks/470-4d1a5dbe58a8a2b9.js","static/chunks/798-c0525dc3f21e488d.js","static/chunks/969-20d54a9d998dc102.js","static/chunks/947-6620842ef80ae879.js","static/chunks/901-b424d293275e1fd7.js","static/chunks/856-0776dc6ed6000c39.js","static/chunks/973-c807fc34f09c7df3.js","static/chunks/938-a75b7712639298b7.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[211],{803:function(e,r,n){n.d(r,{z:function(){return d}});var t=n(5893),l=n(7294),a=n(8426),s=n(2003),i=n(2350);let o=(0,s.j)("inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",{variants:{variant:{default:"bg-primary text-primary-foreground hover:bg-primary/90",destructive:"bg-destructive text-destructive-foreground hover:bg-destructive/90",outline:"border border-input bg-background hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-10 px-4 py-2",sm:"h-9 rounded-md px-3",lg:"h-11 rounded-md px-8",icon:"h-10 w-10"}},defaultVariants:{variant:"default",size:"default"}}),d=l.forwardRef((e,r)=>{let{className:n,variant:l,size:s,asChild:d=!1,...c}=e,u=d?a.g7:"button";return(0,t.jsx)(u,{className:(0,i.cn)(o({variant:l,size:s,className:n})),ref:r,...c})});d.displayName="Button"},7673:function(e,r,n){n.d(r,{Ol:function(){return d},Zb:function(){return o},aY:function(){return f},eW:function(){return p},ll:function(){return c}});var t=n(5893),l=n(7294),a=n(5697),s=n.n(a),i=n(2350);let o=l.forwardRef((e,r)=>{let{className:n,children:l,...a}=e;return(0,t.jsx)("div",{ref:r,className:(0,i.cn)("rounded-lg border bg-card text-card-foreground shadow-sm",n),...a,children:l})});o.displayName="Card",o.propTypes={className:s().string,children:s().node};let d=l.forwardRef((e,r)=>{let{className:n,children:l,...a}=e;return(0,t.jsx)("div",{ref:r,className:(0,i.cn)("flex flex-col space-y-1.5 p-6",n),...a,children:l})});d.displayName="CardHeader",d.propTypes={className:s().string,children:s().node};let c=l.forwardRef((e,r)=>{let{className:n,children:l,...a}=e;return(0,t.jsx)("h3",{ref:r,className:(0,i.cn)("text-2xl font-semibold leading-none tracking-tight",n),...a,children:l})});c.displayName="CardTitle",c.propTypes={className:s().string,children:s().node};let u=l.forwardRef((e,r)=>{let{className:n,children:l,...a}=e;return(0,t.jsx)("p",{ref:r,className:(0,i.cn)("text-sm text-muted-foreground",n),...a,children:l})});u.displayName="CardDescription",u.propTypes={className:s().string,children:s().node};let f=l.forwardRef((e,r)=>{let{className:n,children:l,...a}=e;return(0,t.jsx)("div",{ref:r,className:(0,i.cn)("p-6 pt-0",n),...a,children:l})});f.displayName="CardContent",f.propTypes={className:s().string,children:s().node};let p=l.forwardRef((e,r)=>{let{className:n,children:l,...a}=e;return(0,t.jsx)("div",{ref:r,className:(0,i.cn)("flex items-center p-6 pt-0",n),...a,children:l})});p.displayName="CardFooter",p.propTypes={className:s().string,children:s().node}},2003:function(e,r,n){n.d(r,{j:function(){return s}});var t=n(512);let l=e=>"boolean"==typeof e?`${e}`:0===e?"0":e,a=t.W,s=(e,r)=>n=>{var t;if((null==r?void 0:r.variants)==null)return a(e,null==n?void 0:n.class,null==n?void 0:n.className);let{variants:s,defaultVariants:i}=r,o=Object.keys(s).map(e=>{let r=null==n?void 0:n[e],t=null==i?void 0:i[e];if(null===r)return null;let a=l(r)||l(t);return s[e][a]}),d=n&&Object.entries(n).reduce((e,r)=>{let[n,t]=r;return void 0===t||(e[n]=t),e},{});return a(e,o,null==r?void 0:null===(t=r.compoundVariants)||void 0===t?void 0:t.reduce((e,r)=>{let{class:n,className:t,...l}=r;return Object.entries(l).every(e=>{let[r,n]=e;return Array.isArray(n)?n.includes({...i,...d}[r]):({...i,...d})[r]===n})?[...e,n,t]:e},[]),null==n?void 0:n.class,null==n?void 0:n.className)}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[350],{2350:function(n,r,u){u.d(r,{cn:function(){return c}});var e=u(512),t=u(8388);function c(){for(var n=arguments.length,r=Array(n),u=0;u<n;u++)r[u]=arguments[u];return(0,t.m6)((0,e.W)(r))}}}]);
@@ -0,0 +1,6 @@
1
+ "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[37,211],{9037:function(e,s,t){t.r(s),t.d(s,{ClusterTable:function(){return O},Clusters:function(){return _},Status2Actions:function(){return W},enabledActions:function(){return L},handleVSCodeConnection:function(){return M}});var r=t(5893),n=t(7294),l=t(1163),a=t(8799),c=t(6989),i=t(1664),o=t.n(i),d=t(803),u=t(7673),h=t(8764),x=t(3266),p=t(7324),f=t(4545),m=t(3626),j=t(998);/**
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 g=(0,j.Z)("Terminal",[["polyline",{points:"4 17 10 11 4 5",key:"akl6gq"}],["line",{x1:"12",x2:"20",y1:"19",y2:"19",key:"q2wloq"}]]),v=(0,j.Z)("SquareCode",[["path",{d:"M10 9.5 8 12l2 2.5",key:"3mjy60"}],["path",{d:"m14 9.5 2 2.5-2 2.5",key:"1bir2l"}],["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}]]);t(9470);var w=t(9284),y=t(9307),N=t(3001),b=t(8950),k=t(6378),C=t(6856);t(1272);let S="__ALL_WORKSPACES__",R=(e,s)=>{let t="",r="";return e>=0&&(t=e+"m",r=" "),s&&(t+="".concat(r,"(down)")),""===t&&(t="-"),t};function _(){let e=(0,l.useRouter)(),[s,t]=(0,n.useState)(!1),i=n.useRef(null),[d,u]=(0,n.useState)(!1),[h,f]=(0,n.useState)(!1),[j,g]=(0,n.useState)(null),[v,y]=(0,n.useState)(S),[R,_]=(0,n.useState)([]),M=(0,N.X)();return(0,n.useEffect)(()=>{e.isReady&&e.query.workspace&&y(Array.isArray(e.query.workspace)?e.query.workspace[0]:e.query.workspace)},[e.isReady,e.query.workspace]),(0,n.useEffect)(()=>{(async()=>{try{await C.ZP.preloadForPage("clusters");let e=await k.default.get(p.fX),s=Object.keys(e),t=await k.default.get(x.getClusters),r=[...new Set(t.map(e=>e.workspace||"default").filter(e=>e))],n=new Set(s);r.includes("default")&&n.has("default"),r.forEach(e=>n.add(e)),_(Array.from(n).sort())}catch(e){console.error("Error fetching data for workspace filter:",e),_(["default"])}})()},[]),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"flex items-center justify-between mb-4 h-5",children:[(0,r.jsxs)("div",{className:"text-base flex items-center",children:[(0,r.jsx)(o(),{href:"/clusters",className:"text-sky-blue hover:underline leading-none",children:"Sky Clusters"}),(0,r.jsxs)(b.Ph,{value:v,onValueChange:y,children:[(0,r.jsx)(b.i4,{className:"h-8 w-48 ml-4 mr-2 text-sm border-none focus:ring-0 focus:outline-none",children:(0,r.jsx)(b.ki,{placeholder:"Filter by workspace...",children:v===S?"All Workspaces":v})}),(0,r.jsxs)(b.Bw,{children:[(0,r.jsx)(b.Ql,{value:S,children:"All Workspaces"}),R.map(e=>(0,r.jsx)(b.Ql,{value:e,children:e},e))]})]})]}),(0,r.jsxs)("div",{className:"flex items-center",children:[s&&(0,r.jsxs)("div",{className:"flex items-center mr-2",children:[(0,r.jsx)(a.Z,{size:15,className:"mt-0"}),(0,r.jsx)("span",{className:"ml-2 text-gray-500",children:"Loading..."})]}),(0,r.jsxs)("button",{onClick:()=>{k.default.invalidate(x.getClusters),k.default.invalidate(p.fX),i.current&&i.current()},disabled:s,className:"text-sky-blue hover:text-sky-blue-bright flex items-center",children:[(0,r.jsx)(m.Z,{className:"h-4 w-4 mr-1.5"}),!M&&(0,r.jsx)("span",{children:"Refresh"})]})]})]}),(0,r.jsx)(O,{refreshInterval:c.yc,setLoading:t,refreshDataRef:i,workspaceFilter:v,onOpenSSHModal:e=>{g(e),u(!0)},onOpenVSCodeModal:e=>{g(e),f(!0)}}),(0,r.jsx)(w.Oh,{isOpen:d,onClose:()=>u(!1),cluster:j}),(0,r.jsx)(w._R,{isOpen:h,onClose:()=>f(!1),cluster:j})]})}function O(e){let{refreshInterval:s,setLoading:t,refreshDataRef:l,workspaceFilter:i,onOpenSSHModal:p,onOpenVSCodeModal:m}=e,[j,g]=(0,n.useState)([]),[v,w]=(0,n.useState)({key:null,direction:"ascending"}),[N,b]=(0,n.useState)(!1),[C,_]=(0,n.useState)(!0),[O,M]=(0,n.useState)(1),[A,L]=(0,n.useState)(10),V=n.useCallback(async()=>{t(!0),b(!0),g(await k.default.get(x.getClusters)),t(!1),b(!1),_(!1)},[t]),z=n.useMemo(()=>{let e=j;return i&&i!==S&&(e=j.filter(e=>(e.workspace||"default").toLowerCase()===i.toLowerCase())),(0,f.R0)(e,v.key,v.direction)},[j,v,i]);n.useEffect(()=>{l&&(l.current=V)},[l,V]),(0,n.useEffect)(()=>{g([]);let e=!0;V();let t=setInterval(()=>{e&&V()},s);return()=>{e=!1,clearInterval(t)}},[s,V]),(0,n.useEffect)(()=>{M(1)},[j.length]);let E=e=>{let s="ascending";v.key===e&&"ascending"===v.direction&&(s="descending"),w({key:e,direction:s})},q=e=>v.key===e?"ascending"===v.direction?" ↑":" ↓":"",T=Math.ceil(z.length/A),Z=(O-1)*A,F=Z+A,H=z.slice(Z,F);return(0,r.jsxs)("div",{children:[(0,r.jsx)(u.Zb,{children:(0,r.jsxs)(h.iA,{children:[(0,r.jsx)(h.xD,{children:(0,r.jsxs)(h.SC,{children:[(0,r.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>E("status"),children:["Status",q("status")]}),(0,r.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>E("cluster"),children:["Cluster",q("cluster")]}),(0,r.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>E("user"),children:["User",q("user")]}),(0,r.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>E("workspace"),children:["Workspace",q("workspace")]}),(0,r.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>E("infra"),children:["Infra",q("infra")]}),(0,r.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>E("resources_str"),children:["Resources",q("resources_str")]}),(0,r.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>E("time"),children:["Started",q("time")]}),(0,r.jsxs)(h.ss,{className:"sortable whitespace-nowrap",onClick:()=>E("autostop"),children:["Autostop",q("autostop")]}),(0,r.jsx)(h.ss,{children:"Actions"})]})}),(0,r.jsx)(h.RM,{children:N&&C?(0,r.jsx)(h.SC,{children:(0,r.jsx)(h.pj,{colSpan:9,className:"text-center py-6 text-gray-500",children:(0,r.jsxs)("div",{className:"flex justify-center items-center",children:[(0,r.jsx)(a.Z,{size:20,className:"mr-2"}),(0,r.jsx)("span",{children:"Loading..."})]})})}):H.length>0?H.map((e,s)=>(0,r.jsxs)(h.SC,{children:[(0,r.jsx)(h.pj,{children:(0,r.jsx)(y.OE,{status:e.status})}),(0,r.jsx)(h.pj,{children:(0,r.jsx)(o(),{href:"/clusters/".concat(e.cluster),className:"text-blue-600",children:e.cluster})}),(0,r.jsx)(h.pj,{children:e.user}),(0,r.jsx)(h.pj,{children:(0,r.jsx)(o(),{href:"/workspaces",className:"text-blue-600 hover:underline",children:e.workspace||"default"})}),(0,r.jsx)(h.pj,{children:(0,r.jsx)(c.Md,{content:e.full_infra||e.infra,className:"text-sm text-muted-foreground",children:(0,r.jsxs)("span",{children:[(0,r.jsx)(o(),{href:"/infra",className:"text-blue-600 hover:underline",children:e.cloud}),e.infra.includes("(")&&(0,r.jsx)("span",{children:" "+e.infra.substring(e.infra.indexOf("("))})]})})}),(0,r.jsx)(h.pj,{children:(0,r.jsx)(c.Md,{content:e.resources_str_full||e.resources_str,className:"text-sm text-muted-foreground",children:(0,r.jsx)("span",{children:e.resources_str})})}),(0,r.jsx)(h.pj,{children:(0,c.GV)(e.time)}),(0,r.jsx)(h.pj,{children:R(e.autostop,e.to_down)}),(0,r.jsx)(h.pj,{className:"text-left",children:(0,r.jsx)(W,{cluster:e.cluster,status:e.status,onOpenSSHModal:p,onOpenVSCodeModal:m})})]},s)):(0,r.jsx)(h.SC,{children:(0,r.jsx)(h.pj,{colSpan:9,className:"text-center py-6 text-gray-500",children:"No active clusters"})})})]})}),j.length>0&&(0,r.jsx)("div",{className:"flex justify-end items-center py-2 px-4 text-sm text-gray-700",children:(0,r.jsxs)("div",{className:"flex items-center space-x-4",children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)("span",{className:"mr-2",children:"Rows per page:"}),(0,r.jsxs)("div",{className:"relative inline-block",children:[(0,r.jsxs)("select",{value:A,onChange:e=>{L(parseInt(e.target.value,10)),M(1)},className:"py-1 pl-2 pr-6 appearance-none outline-none cursor-pointer border-none bg-transparent",style:{minWidth:"40px"},children:[(0,r.jsx)("option",{value:10,children:"10"}),(0,r.jsx)("option",{value:30,children:"30"}),(0,r.jsx)("option",{value:50,children:"50"}),(0,r.jsx)("option",{value:100,children:"100"}),(0,r.jsx)("option",{value:200,children:"200"})]}),(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4 text-gray-500 absolute right-0 top-1/2 transform -translate-y-1/2 pointer-events-none",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:(0,r.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]})]}),(0,r.jsxs)("div",{children:[Z+1," – ",Math.min(F,j.length)," of"," ",j.length]}),(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,r.jsx)(d.z,{variant:"ghost",size:"icon",onClick:()=>{M(e=>Math.max(e-1,1))},disabled:1===O,className:"text-gray-500 h-8 w-8 p-0",children:(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"chevron-left",children:(0,r.jsx)("path",{d:"M15 18l-6-6 6-6"})})}),(0,r.jsx)(d.z,{variant:"ghost",size:"icon",onClick:()=>{M(e=>Math.min(e+1,T))},disabled:O===T||0===T,className:"text-gray-500 h-8 w-8 p-0",children:(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"chevron-right",children:(0,r.jsx)("path",{d:"M9 18l6-6-6-6"})})})]})]})})]})}let M=(e,s)=>{s&&s(e)},A=(e,s)=>{s?s(e):window.open("ssh://".concat(e))},L=e=>"RUNNING"===e?["connect","VSCode"]:[],V={connect:(0,r.jsx)(g,{className:"w-4 h-4 text-gray-500 inline-block"}),VSCode:(0,r.jsx)(v,{className:"w-4 h-4 text-gray-500 inline-block"})};function W(e){let{withLabel:s=!1,cluster:t,status:n,onOpenSSHModal:l,onOpenVSCodeModal:a}=e,i=L(n),o=(0,N.X)(),d=e=>{switch(e){case"connect":A(t,l);break;case"VSCode":M(t,a);break;default:return}};return(0,r.jsx)(r.Fragment,{children:(0,r.jsx)("div",{className:"flex items-center space-x-4",children:Object.entries(V).map(e=>{let t,n,[l,a]=e;switch(l){case"connect":t="Connect",n="Connect with SSH";break;case"VSCode":t="VSCode",n="Open in VS Code"}return(s||(t=""),i.includes(l))?(0,r.jsx)(c.WH,{content:n,className:"capitalize text-sm text-muted-foreground",children:(0,r.jsxs)("button",{onClick:()=>d(l),className:"text-sky-blue hover:text-sky-blue-bright font-medium inline-flex items-center",children:[a,!o&&(0,r.jsx)("span",{className:"ml-1.5",children:t})]})},l):(0,r.jsx)(c.WH,{content:n,className:"capitalize text-sm text-muted-foreground",children:(0,r.jsxs)("span",{className:"opacity-30 flex items-center cursor-not-allowed text-sm",title:l,children:[a,!o&&(0,r.jsx)("span",{className:"ml-1.5",children:t})]})},l)})})})}},803:function(e,s,t){t.d(s,{z:function(){return o}});var r=t(5893),n=t(7294),l=t(8426),a=t(2003),c=t(2350);let i=(0,a.j)("inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",{variants:{variant:{default:"bg-primary text-primary-foreground hover:bg-primary/90",destructive:"bg-destructive text-destructive-foreground hover:bg-destructive/90",outline:"border border-input bg-background hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-10 px-4 py-2",sm:"h-9 rounded-md px-3",lg:"h-11 rounded-md px-8",icon:"h-10 w-10"}},defaultVariants:{variant:"default",size:"default"}}),o=n.forwardRef((e,s)=>{let{className:t,variant:n,size:a,asChild:o=!1,...d}=e,u=o?l.g7:"button";return(0,r.jsx)(u,{className:(0,c.cn)(i({variant:n,size:a,className:t})),ref:s,...d})});o.displayName="Button"},7673:function(e,s,t){t.d(s,{Ol:function(){return o},Zb:function(){return i},aY:function(){return h},eW:function(){return x},ll:function(){return d}});var r=t(5893),n=t(7294),l=t(5697),a=t.n(l),c=t(2350);let i=n.forwardRef((e,s)=>{let{className:t,children:n,...l}=e;return(0,r.jsx)("div",{ref:s,className:(0,c.cn)("rounded-lg border bg-card text-card-foreground shadow-sm",t),...l,children:n})});i.displayName="Card",i.propTypes={className:a().string,children:a().node};let o=n.forwardRef((e,s)=>{let{className:t,children:n,...l}=e;return(0,r.jsx)("div",{ref:s,className:(0,c.cn)("flex flex-col space-y-1.5 p-6",t),...l,children:n})});o.displayName="CardHeader",o.propTypes={className:a().string,children:a().node};let d=n.forwardRef((e,s)=>{let{className:t,children:n,...l}=e;return(0,r.jsx)("h3",{ref:s,className:(0,c.cn)("text-2xl font-semibold leading-none tracking-tight",t),...l,children:n})});d.displayName="CardTitle",d.propTypes={className:a().string,children:a().node};let u=n.forwardRef((e,s)=>{let{className:t,children:n,...l}=e;return(0,r.jsx)("p",{ref:s,className:(0,c.cn)("text-sm text-muted-foreground",t),...l,children:n})});u.displayName="CardDescription",u.propTypes={className:a().string,children:a().node};let h=n.forwardRef((e,s)=>{let{className:t,children:n,...l}=e;return(0,r.jsx)("div",{ref:s,className:(0,c.cn)("p-6 pt-0",t),...l,children:n})});h.displayName="CardContent",h.propTypes={className:a().string,children:a().node};let x=n.forwardRef((e,s)=>{let{className:t,children:n,...l}=e;return(0,r.jsx)("div",{ref:s,className:(0,c.cn)("flex items-center p-6 pt-0",t),...l,children:n})});x.displayName="CardFooter",x.propTypes={className:a().string,children:a().node}},2003:function(e,s,t){t.d(s,{j:function(){return a}});var r=t(512);let n=e=>"boolean"==typeof e?`${e}`:0===e?"0":e,l=r.W,a=(e,s)=>t=>{var r;if((null==s?void 0:s.variants)==null)return l(e,null==t?void 0:t.class,null==t?void 0:t.className);let{variants:a,defaultVariants:c}=s,i=Object.keys(a).map(e=>{let s=null==t?void 0:t[e],r=null==c?void 0:c[e];if(null===s)return null;let l=n(s)||n(r);return a[e][l]}),o=t&&Object.entries(t).reduce((e,s)=>{let[t,r]=s;return void 0===r||(e[t]=r),e},{});return l(e,i,null==s?void 0:null===(r=s.compoundVariants)||void 0===r?void 0:r.reduce((e,s)=>{let{class:t,className:r,...n}=s;return Object.entries(n).every(e=>{let[s,t]=e;return Array.isArray(t)?t.includes({...c,...o}[s]):({...c,...o})[s]===t})?[...e,t,r]:e},[]),null==t?void 0:t.class,null==t?void 0:t.className)}}}]);
@@ -0,0 +1,6 @@
1
+ "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[42,211],{9333:function(e,n,t){t.d(n,{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,t(998).Z)("Save",[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]])},4042:function(e,n,t){t.r(n),t.d(n,{Config:function(){return x}});var r=t(5893),a=t(7294),l=t(1163),s=t(803),i=t(7673),o=t(7324),c=t(1812),d=t(8799),u=t(9333),f=t(1272),m=t(6989),h=t(7145);function p(){let[e,n]=(0,a.useState)(null),[t,l]=(0,a.useState)(null),s=async()=>{let e=await h.x.get("/api/health"),t=await e.json();t.version&&n(t.version),t.commit&&l(t.commit)};return((0,a.useEffect)(()=>{s()},[]),e)?(0,r.jsx)(m.Md,{content:t?"Commit: ".concat(t):"Commit information not available",className:"text-sm text-muted-foreground",children:(0,r.jsxs)("div",{className:"text-sm text-gray-500 cursor-help border-b border-dotted border-gray-400 inline-block",children:["Version: ",e]})}):null}function x(){let e=(0,l.useRouter)(),[n,t]=(0,a.useState)(""),[m,x]=(0,a.useState)(!0),[g,y]=(0,a.useState)(!1),[v,b]=(0,a.useState)(null),[j,N]=(0,a.useState)(!1),w=(0,a.useRef)(null);(0,a.useEffect)(()=>{k()},[]),(0,a.useEffect)(()=>()=>{w.current&&clearTimeout(w.current)},[]);let k=async()=>{x(!0),b(null);try{let e=await (0,o.iE)();0===Object.keys(e).length?t(""):t(f.ZP.dump(e,{indent:2}))}catch(e){console.error("Error loading config:",e),b(e)}finally{x(!1)}},R=async()=>{y(!0),b(null),w.current&&(clearTimeout(w.current),w.current=null);try{let e=await h.x.get("/users/role");if(!e.ok){let n=await e.json();throw Error(n.detail||"Failed to get user role")}let t=await e.json(),r=t.role;if("admin"!=r){b(Error("".concat(t.name," is logged in as non-admin and cannot edit config"))),y(!1);return}let a=f.ZP.load(n);if(null==a&&(a={}),"object"!=typeof a||Array.isArray(a)){let e="Invalid config structure: Configuration must be a mapping (key-value pairs) in YAML format.";Array.isArray(a),e="Invalid config structure: Configuration must be a mapping (key-value pairs) in YAML format.",b(Error(e)),y(!1);return}await (0,o.rF)(a),N(!0),w.current=setTimeout(()=>{N(!1),w.current=null},5e3)}catch(e){console.error("Error saving config:",e),b(e)}finally{y(!1)}};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"flex items-center justify-between mb-4 h-5",children:[(0,r.jsx)("div",{className:"text-base flex items-center",children:(0,r.jsx)("span",{className:"text-sky-blue",children:"SkyPilot Configuration"})}),(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)("div",{className:"text-sm flex items-center",children:(m||g)&&(0,r.jsxs)("div",{className:"flex items-center mr-4",children:[(0,r.jsx)(d.Z,{size:15,className:"mt-0"}),(0,r.jsx)("span",{className:"ml-2 text-gray-500",children:g?"Applying...":"Loading..."})]})}),(0,r.jsx)(p,{})]})]}),(0,r.jsxs)(i.Zb,{className:"w-full",children:[(0,r.jsx)(i.Ol,{children:(0,r.jsx)(i.ll,{className:"text-base font-normal flex items-center justify-between",children:(0,r.jsx)("span",{children:"Edit SkyPilot API Server Configuration"})})}),(0,r.jsxs)(i.aY,{className:"space-y-4",children:[(0,r.jsxs)("p",{className:"text-sm text-gray-600 mb-3",children:["Refer to the"," ",(0,r.jsx)("a",{href:"https://docs.skypilot.co/en/latest/reference/config.html",target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:underline",children:"SkyPilot Docs"})," ","for details. The configuration should be in YAML format."]}),j&&(0,r.jsx)("div",{className:"bg-green-50 border border-green-200 rounded p-4 mb-6",children:(0,r.jsxs)("div",{className:"flex items-center justify-between",children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)("div",{className:"flex-shrink-0",children:(0,r.jsx)("svg",{className:"h-5 w-5 text-green-400",viewBox:"0 0 20 20",fill:"currentColor",children:(0,r.jsx)("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z",clipRule:"evenodd"})})}),(0,r.jsx)("div",{className:"ml-3",children:(0,r.jsx)("p",{className:"text-sm font-medium text-green-800",children:"Configuration saved successfully!"})})]}),(0,r.jsx)("div",{className:"ml-auto pl-3",children:(0,r.jsx)("div",{className:"-mx-1.5 -my-1.5",children:(0,r.jsxs)("button",{type:"button",onClick:()=>{N(!1),w.current&&(clearTimeout(w.current),w.current=null)},className:"inline-flex rounded-md bg-green-50 p-1.5 text-green-500 hover:bg-green-100 focus:outline-none focus:ring-2 focus:ring-green-600 focus:ring-offset-2 focus:ring-offset-green-50",children:[(0,r.jsx)("span",{className:"sr-only",children:"Dismiss"}),(0,r.jsx)("svg",{className:"h-5 w-5",viewBox:"0 0 20 20",fill:"currentColor",children:(0,r.jsx)("path",{fillRule:"evenodd",d:"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z",clipRule:"evenodd"})})]})})})]})}),v&&(0,r.jsx)("div",{className:"mb-6",children:(0,r.jsx)(c.X,{error:v,title:"Failed to apply new configuration",onDismiss:()=>b(null)})}),(0,r.jsx)("div",{className:"w-full",children:(0,r.jsx)("textarea",{value:n,onChange:e=>t(e.target.value),className:"w-full h-96 p-3 border border-gray-300 rounded font-mono text-sm resize-vertical focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:m?"Loading configuration...":"# Enter SkyPilot configuration in YAML format\n# Example:\n# kubernetes:\n# allowed_contexts: [default, my-context]",disabled:m||g})}),(0,r.jsxs)("div",{className:"flex justify-end space-x-3 pt-3",children:[(0,r.jsx)(s.z,{variant:"outline",onClick:()=>{e.push("/workspaces")},disabled:g,children:"Cancel"}),(0,r.jsx)(s.z,{onClick:R,disabled:m||g,className:"inline-flex items-center bg-blue-600 hover:bg-blue-700 text-white",children:g?(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(d.Z,{size:16,className:"mr-2"}),"Applying..."]}):(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(u.Z,{className:"w-4 h-4 mr-1.5"}),"Apply"]})})]})]})]})]})}},1812:function(e,n,t){t.d(n,{X:function(){return s}});var r=t(5893),a=t(7294);let l=e=>{if(!(null==e?void 0:e.message))return"An unexpected error occurred.";let n=e.message;return n.includes("failed:")&&(n=n.split("failed:")[1].trim()),n},s=e=>{let{error:n,title:t="Error",onDismiss:s}=e,[i,o]=(0,a.useState)(!1);if((0,a.useEffect)(()=>{n&&o(!1)},[n]),!n||i)return null;let c="string"==typeof n?n:l(n);return(0,r.jsx)("div",{className:"bg-red-50 border border-red-200 rounded-md p-3 mb-4",children:(0,r.jsxs)("div",{className:"flex items-center justify-between",children:[(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)("div",{className:"flex-shrink-0",children:(0,r.jsx)("svg",{className:"h-5 w-5 text-red-400",viewBox:"0 0 20 20",fill:"currentColor",children:(0,r.jsx)("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z",clipRule:"evenodd"})})}),(0,r.jsx)("div",{className:"ml-3",children:(0,r.jsxs)("div",{className:"text-sm text-red-800",children:[(0,r.jsxs)("strong",{children:[t,":"]})," ",c]})})]}),(0,r.jsx)("button",{onClick:()=>{o(!0),s&&s()},className:"flex-shrink-0 ml-4 text-red-400 hover:text-red-600 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 focus:ring-offset-red-50 rounded","aria-label":"Dismiss error",children:(0,r.jsx)("svg",{className:"h-4 w-4",viewBox:"0 0 20 20",fill:"currentColor",children:(0,r.jsx)("path",{fillRule:"evenodd",d:"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z",clipRule:"evenodd"})})})]})})}},803:function(e,n,t){t.d(n,{z:function(){return c}});var r=t(5893),a=t(7294),l=t(8426),s=t(2003),i=t(2350);let o=(0,s.j)("inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",{variants:{variant:{default:"bg-primary text-primary-foreground hover:bg-primary/90",destructive:"bg-destructive text-destructive-foreground hover:bg-destructive/90",outline:"border border-input bg-background hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-10 px-4 py-2",sm:"h-9 rounded-md px-3",lg:"h-11 rounded-md px-8",icon:"h-10 w-10"}},defaultVariants:{variant:"default",size:"default"}}),c=a.forwardRef((e,n)=>{let{className:t,variant:a,size:s,asChild:c=!1,...d}=e,u=c?l.g7:"button";return(0,r.jsx)(u,{className:(0,i.cn)(o({variant:a,size:s,className:t})),ref:n,...d})});c.displayName="Button"},7673:function(e,n,t){t.d(n,{Ol:function(){return c},Zb:function(){return o},aY:function(){return f},eW:function(){return m},ll:function(){return d}});var r=t(5893),a=t(7294),l=t(5697),s=t.n(l),i=t(2350);let o=a.forwardRef((e,n)=>{let{className:t,children:a,...l}=e;return(0,r.jsx)("div",{ref:n,className:(0,i.cn)("rounded-lg border bg-card text-card-foreground shadow-sm",t),...l,children:a})});o.displayName="Card",o.propTypes={className:s().string,children:s().node};let c=a.forwardRef((e,n)=>{let{className:t,children:a,...l}=e;return(0,r.jsx)("div",{ref:n,className:(0,i.cn)("flex flex-col space-y-1.5 p-6",t),...l,children:a})});c.displayName="CardHeader",c.propTypes={className:s().string,children:s().node};let d=a.forwardRef((e,n)=>{let{className:t,children:a,...l}=e;return(0,r.jsx)("h3",{ref:n,className:(0,i.cn)("text-2xl font-semibold leading-none tracking-tight",t),...l,children:a})});d.displayName="CardTitle",d.propTypes={className:s().string,children:s().node};let u=a.forwardRef((e,n)=>{let{className:t,children:a,...l}=e;return(0,r.jsx)("p",{ref:n,className:(0,i.cn)("text-sm text-muted-foreground",t),...l,children:a})});u.displayName="CardDescription",u.propTypes={className:s().string,children:s().node};let f=a.forwardRef((e,n)=>{let{className:t,children:a,...l}=e;return(0,r.jsx)("div",{ref:n,className:(0,i.cn)("p-6 pt-0",t),...l,children:a})});f.displayName="CardContent",f.propTypes={className:s().string,children:s().node};let m=a.forwardRef((e,n)=>{let{className:t,children:a,...l}=e;return(0,r.jsx)("div",{ref:n,className:(0,i.cn)("flex items-center p-6 pt-0",t),...l,children:a})});m.displayName="CardFooter",m.propTypes={className:s().string,children:s().node}},8950:function(e,n,t){t.d(n,{Bw:function(){return p},Ph:function(){return d},Ql:function(){return x},i4:function(){return f},ki:function(){return u}});var r=t(5893),a=t(7294),l=t(2067),s=t(5895),i=t(7242),o=t(282),c=t(2350);let d=l.fC;l.ZA;let u=l.B4,f=a.forwardRef((e,n)=>{let{className:t,children:a,...i}=e;return(0,r.jsxs)(l.xz,{ref:n,className:(0,c.cn)("flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",t),...i,children:[a,(0,r.jsx)(l.JO,{asChild:!0,children:(0,r.jsx)(s.Z,{className:"h-4 w-4 opacity-50"})})]})});f.displayName=l.xz.displayName;let m=a.forwardRef((e,n)=>{let{className:t,...a}=e;return(0,r.jsx)(l.u_,{ref:n,className:(0,c.cn)("flex cursor-default items-center justify-center py-1",t),...a,children:(0,r.jsx)(i.Z,{className:"h-4 w-4"})})});m.displayName=l.u_.displayName;let h=a.forwardRef((e,n)=>{let{className:t,...a}=e;return(0,r.jsx)(l.$G,{ref:n,className:(0,c.cn)("flex cursor-default items-center justify-center py-1",t),...a,children:(0,r.jsx)(s.Z,{className:"h-4 w-4"})})});h.displayName=l.$G.displayName;let p=a.forwardRef((e,n)=>{let{className:t,children:a,position:s="popper",...i}=e;return(0,r.jsx)(l.h_,{children:(0,r.jsxs)(l.VY,{ref:n,className:(0,c.cn)("relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2","popper"===s&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",t),position:s,...i,children:[(0,r.jsx)(m,{}),(0,r.jsx)(l.l_,{className:(0,c.cn)("p-1","popper"===s&&"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"),children:a}),(0,r.jsx)(h,{})]})})});p.displayName=l.VY.displayName,a.forwardRef((e,n)=>{let{className:t,...a}=e;return(0,r.jsx)(l.__,{ref:n,className:(0,c.cn)("py-1.5 pl-8 pr-2 text-sm font-semibold",t),...a})}).displayName=l.__.displayName;let x=a.forwardRef((e,n)=>{let{className:t,children:a,...s}=e;return(0,r.jsxs)(l.ck,{ref:n,className:(0,c.cn)("relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",t),...s,children:[(0,r.jsx)("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:(0,r.jsx)(l.wU,{children:(0,r.jsx)(o.Z,{className:"h-4 w-4"})})}),(0,r.jsx)(l.eT,{children:a})]})});x.displayName=l.ck.displayName,a.forwardRef((e,n)=>{let{className:t,...a}=e;return(0,r.jsx)(l.Z0,{ref:n,className:(0,c.cn)("-mx-1 my-1 h-px bg-muted",t),...a})}).displayName=l.Z0.displayName},6989:function(e,n,t){t.d(n,{$B:function(){return g},GV:function(){return d},LU:function(){return p},Md:function(){return h},WH:function(){return m},o0:function(){return u},q8:function(){return x},yc:function(){return o}});var r=t(5893),a=t(7294),l=t(3302),s=t(1886),i=t(8950);let o=t(1214).nb.REFRESH_INTERVAL;function c(e){return e.charAt(0).toUpperCase()+e.slice(1)}function d(e){if(!e)return"N/A";let n=new Date;if(!(7>Math.abs((n-e)/864e5)))return(0,r.jsx)(m,{content:c(u(e)),className:"text-sm text-muted-foreground",children:c(e.toLocaleString("en-CA",{year:"numeric",month:"2-digit",day:"2-digit"}).replace(",",""))});{let t=function(e){if(!e||"string"!=typeof e)return e;if("just now"===e)return"now";let n=e.match(/^about\s+(\d+)\s+(\w+)\s+ago$/i);if(n){let e=n[1],t=n[2],r={second:"s",seconds:"s",minute:"m",minutes:"m",hour:"h",hours:"h",day:"d",days:"d",month:"mo",months:"mo",year:"yr",years:"yr"};if(r[t])return"".concat(e).concat(r[t]," ago")}let t=e.match(/^a[n]?\s+(\w+)\s+ago$/i);if(t){let e=t[1],n={second:"s",minute:"m",hour:"h",day:"d",month:"mo",year:"yr"};if(n[e])return"1".concat(n[e]," ago")}let r=e.match(/^(\d+)\s+(\w+)\s+ago$/i);if(r){let e=r[1],n=r[2],t={second:"s",seconds:"s",minute:"m",minutes:"m",hour:"h",hours:"h",day:"d",days:"d",month:"mo",months:"mo",year:"yr",years:"yr"};if(t[n])return"".concat(e).concat(t[n]," ago")}return e}((0,s.B)(e,n,{addSuffix:!0}));return(0,r.jsx)(m,{content:u(e),className:"capitalize text-sm text-muted-foreground",children:t})}}function u(e){return e.toLocaleString("en-CA",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1,timeZoneName:"short"}).replace(",","")}let f={placement:"bottom",color:"default"},m=e=>{let{children:n,...t}=e,a=t.content;return t.content=void 0,(0,r.jsx)(l.e,{...f,...t,content:(0,r.jsx)("span",{className:"left-full w-max px-2 py-1 text-sm text-gray-100 bg-gray-500 text-sm capitalize rounded",children:a}),children:n})},h=e=>{let{children:n,...t}=e,a=t.content;return t.content=void 0,(0,r.jsx)(l.e,{...f,...t,content:(0,r.jsx)("span",{className:"left-full w-max px-2 py-1 text-sm text-gray-100 bg-gray-500 text-sm rounded",children:a}),children:n})};function p(e){if(!e&&0!==e)return"-";let n=e=Math.floor(e),t="",r=0;for(let e of[{value:86400,label:"d"},{value:3600,label:"h"},{value:60,label:"m"},{value:1,label:"s"}])if(n>=e.value&&r<2){let a=Math.floor(n/e.value);t+="".concat(a).concat(e.label," "),n%=e.value,r++}return t.trim()||"0s"}function x(e){return e?(e=e.split("\n").filter(e=>!e.match(/<rich_.*?\[bold cyan\]/)&&!e.match(/<rich_.*>.*<\/rich_.*>/)&&!e.match(/├──/)&&!e.match(/└──/)).join("\n").replace(/\x1b\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGKH]/g,"")).split("\n").map(e=>{let n=e.match(/^([IWED])\s+(\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})\s+([^:]+:\d+\])(.*)/);if(n){let[e,t,r,a,l]=n,s={I:"INFO",W:"WARNING",E:"ERROR",D:"DEBUG"}[t]||"";return'<span class="log-line '.concat(s,'"><span class="level">').concat(t,'</span><span class="timestamp">').concat(r,'</span><span class="location">').concat(a,'</span><span class="message">').concat(l,"</span></span>")}let t=e.match(/^(\([^)]+\))(.*)$/);if(t){let[e,n,r]=t;return'<span class="log-line"><span class="log-prefix">'.concat(n,'</span><span class="log-rest">').concat(r,"</span></span>")}return'<span class="log-line"><span class="message">'.concat(e,"</span></span>")}).join("\n"):""}function g(e){let{logs:n,controller:t=!1}=e,[l,s]=(0,a.useState)("all"),[o,c]=(0,a.useState)(n),[d,u]=(0,a.useState)([]);return(0,a.useEffect)(()=>{u(function(e){let n;let t=/\((head|worker\d+),/g,r=new Set;for(;null!==(n=t.exec(e));)r.add(n[1]);return Array.from(r).sort((e,n)=>"head"===e?-1:"head"===n?1:e.localeCompare(n,void 0,{numeric:!0,sensitivity:"base"}))}(n))},[n]),(0,a.useEffect)(()=>{"all"===l?c(n):c(n.split("\n").filter(e=>e.includes("(".concat(l,","))).join("\n"))},[l,n]),(0,r.jsxs)("div",{children:[(0,r.jsx)("style",{children:'\n .logs-container {\n background-color: #f7f7f7;\n padding: 16px;\n max-height: calc(100vh - 300px);\n overflow-y: auto;\n overflow-x: hidden;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;\n line-height: 1.5;\n border-radius: 6px;\n min-height: fit-content;\n }\n\n .log-line {\n display: block;\n white-space: pre-wrap;\n margin: 2px 0;\n }\n\n .log-line .level {\n display: inline;\n width: 1ch;\n margin-right: 1ch;\n font-weight: bold;\n }\n\n .log-line.INFO .level {\n color: #2563eb;\n }\n\n .log-line.WARNING .level {\n color: #d97706;\n }\n\n .log-line.ERROR .level {\n color: #dc2626;\n }\n\n .log-line.DEBUG .level {\n color: #6b7280;\n }\n\n .log-line .timestamp {\n color: #059669;\n margin-right: 1ch;\n white-space: nowrap;\n }\n\n .log-line .location {\n color: #6366f1;\n margin-right: 1ch;\n white-space: nowrap;\n }\n\n .log-line .message {\n color: #111827;\n word-break: break-word;\n white-space: pre-wrap;\n }\n\n .log-line .log-prefix {\n color: #6366f1;\n font-weight: 500;\n }\n\n .log-line .log-rest {\n color: #111827;\n word-break: break-word;\n white-space: pre-wrap;\n }\n'}),!t&&(0,r.jsx)("div",{style:{marginBottom:"1rem"},children:(0,r.jsxs)(i.Ph,{onValueChange:e=>s(e),value:l,children:[(0,r.jsx)(i.i4,{"aria-label":"Node",className:"focus:ring-0 focus:ring-offset-0",children:(0,r.jsx)(i.ki,{placeholder:"Select Node"})}),(0,r.jsxs)(i.Bw,{children:[(0,r.jsx)(i.Ql,{value:"all",children:"All Nodes"}),d.map(e=>(0,r.jsx)(i.Ql,{value:e,children:e},e))]})]})}),(0,r.jsx)("div",{className:"logs-container",dangerouslySetInnerHTML:{__html:o}})]})}},1214:function(e,n,t){t.d(n,{MO:function(){return l},ej:function(){return r},nb:function(){return a}});let r={DEFAULT_TTL:12e4},a={REFRESH_INTERVAL:3e4,GPU_REFRESH_INTERVAL:3e4},l={NAME_TRUNCATE_LENGTH:20}},2003:function(e,n,t){t.d(n,{j:function(){return s}});var r=t(512);let a=e=>"boolean"==typeof e?`${e}`:0===e?"0":e,l=r.W,s=(e,n)=>t=>{var r;if((null==n?void 0:n.variants)==null)return l(e,null==t?void 0:t.class,null==t?void 0:t.className);let{variants:s,defaultVariants:i}=n,o=Object.keys(s).map(e=>{let n=null==t?void 0:t[e],r=null==i?void 0:i[e];if(null===n)return null;let l=a(n)||a(r);return s[e][l]}),c=t&&Object.entries(t).reduce((e,n)=>{let[t,r]=n;return void 0===r||(e[t]=r),e},{});return l(e,o,null==n?void 0:null===(r=n.compoundVariants)||void 0===r?void 0:r.reduce((e,n)=>{let{class:t,className:r,...a}=n;return Object.entries(a).every(e=>{let[n,t]=e;return Array.isArray(t)?t.includes({...i,...c}[n]):({...i,...c})[n]===t})?[...e,t,r]:e},[]),null==t?void 0:t.class,null==t?void 0:t.className)}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[443,211],{1812:function(e,s,r){r.d(s,{X:function(){return a}});var t=r(5893),n=r(7294);let l=e=>{if(!(null==e?void 0:e.message))return"An unexpected error occurred.";let s=e.message;return s.includes("failed:")&&(s=s.split("failed:")[1].trim()),s},a=e=>{let{error:s,title:r="Error",onDismiss:a}=e,[i,c]=(0,n.useState)(!1);if((0,n.useEffect)(()=>{s&&c(!1)},[s]),!s||i)return null;let o="string"==typeof s?s:l(s);return(0,t.jsx)("div",{className:"bg-red-50 border border-red-200 rounded-md p-3 mb-4",children:(0,t.jsxs)("div",{className:"flex items-center justify-between",children:[(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("div",{className:"flex-shrink-0",children:(0,t.jsx)("svg",{className:"h-5 w-5 text-red-400",viewBox:"0 0 20 20",fill:"currentColor",children:(0,t.jsx)("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z",clipRule:"evenodd"})})}),(0,t.jsx)("div",{className:"ml-3",children:(0,t.jsxs)("div",{className:"text-sm text-red-800",children:[(0,t.jsxs)("strong",{children:[r,":"]})," ",o]})})]}),(0,t.jsx)("button",{onClick:()=>{c(!0),a&&a()},className:"flex-shrink-0 ml-4 text-red-400 hover:text-red-600 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 focus:ring-offset-red-50 rounded","aria-label":"Dismiss error",children:(0,t.jsx)("svg",{className:"h-4 w-4",viewBox:"0 0 20 20",fill:"currentColor",children:(0,t.jsx)("path",{fillRule:"evenodd",d:"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z",clipRule:"evenodd"})})})]})})}},803:function(e,s,r){r.d(s,{z:function(){return o}});var t=r(5893),n=r(7294),l=r(8426),a=r(2003),i=r(2350);let c=(0,a.j)("inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",{variants:{variant:{default:"bg-primary text-primary-foreground hover:bg-primary/90",destructive:"bg-destructive text-destructive-foreground hover:bg-destructive/90",outline:"border border-input bg-background hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-10 px-4 py-2",sm:"h-9 rounded-md px-3",lg:"h-11 rounded-md px-8",icon:"h-10 w-10"}},defaultVariants:{variant:"default",size:"default"}}),o=n.forwardRef((e,s)=>{let{className:r,variant:n,size:a,asChild:o=!1,...d}=e,u=o?l.g7:"button";return(0,t.jsx)(u,{className:(0,i.cn)(c({variant:n,size:a,className:r})),ref:s,...d})});o.displayName="Button"},7673:function(e,s,r){r.d(s,{Ol:function(){return o},Zb:function(){return c},aY:function(){return m},eW:function(){return x},ll:function(){return d}});var t=r(5893),n=r(7294),l=r(5697),a=r.n(l),i=r(2350);let c=n.forwardRef((e,s)=>{let{className:r,children:n,...l}=e;return(0,t.jsx)("div",{ref:s,className:(0,i.cn)("rounded-lg border bg-card text-card-foreground shadow-sm",r),...l,children:n})});c.displayName="Card",c.propTypes={className:a().string,children:a().node};let o=n.forwardRef((e,s)=>{let{className:r,children:n,...l}=e;return(0,t.jsx)("div",{ref:s,className:(0,i.cn)("flex flex-col space-y-1.5 p-6",r),...l,children:n})});o.displayName="CardHeader",o.propTypes={className:a().string,children:a().node};let d=n.forwardRef((e,s)=>{let{className:r,children:n,...l}=e;return(0,t.jsx)("h3",{ref:s,className:(0,i.cn)("text-2xl font-semibold leading-none tracking-tight",r),...l,children:n})});d.displayName="CardTitle",d.propTypes={className:a().string,children:a().node};let u=n.forwardRef((e,s)=>{let{className:r,children:n,...l}=e;return(0,t.jsx)("p",{ref:s,className:(0,i.cn)("text-sm text-muted-foreground",r),...l,children:n})});u.displayName="CardDescription",u.propTypes={className:a().string,children:a().node};let m=n.forwardRef((e,s)=>{let{className:r,children:n,...l}=e;return(0,t.jsx)("div",{ref:s,className:(0,i.cn)("p-6 pt-0",r),...l,children:n})});m.displayName="CardContent",m.propTypes={className:a().string,children:a().node};let x=n.forwardRef((e,s)=>{let{className:r,children:n,...l}=e;return(0,t.jsx)("div",{ref:s,className:(0,i.cn)("flex items-center p-6 pt-0",r),...l,children:n})});x.displayName="CardFooter",x.propTypes={className:a().string,children:a().node}},5443:function(e,s,r){r.r(s),r.d(s,{Workspaces:function(){return D}});var t=r(5893),n=r(7294),l=r(1163),a=r(3266),i=r(8969),c=r(7324),o=r(7673),d=r(803),u=r(8799),m=r(1272),x=r(326),h=r(3850),f=r(1812),p=r(3626),g=r(3001),j=r(938),v=r(6378),N=r(1214),b=r(6856),y=r(7145);let w=e=>{let{isPrivate:s}=e;return s?(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-amber-100 text-amber-800 border border-amber-300",children:"Private"}):(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800 border border-green-300",children:"Public"})},k=e=>{let{workspace:s,onDelete:r,onEdit:n,router:l,rawWorkspacesData:a,checkPermissionAndAct:i,roleLoading:c}=e,m=!0===((null==a?void 0:a[s.name])||{}).private;return(0,t.jsxs)(o.Zb,{children:[(0,t.jsx)(o.Ol,{children:(0,t.jsx)(o.ll,{className:"text-base font-normal",children:(0,t.jsxs)("div",{className:"flex items-center justify-between",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"font-semibold",children:"Workspace:"})," ",s.name]}),(0,t.jsx)(w,{isPrivate:m})]})})}),(0,t.jsxs)(o.aY,{className:"text-sm pb-2",children:[(0,t.jsxs)("div",{className:"py-2 flex items-center justify-between",children:[(0,t.jsxs)("div",{className:"flex items-center text-gray-600",children:[(0,t.jsx)(h.QT,{className:"w-4 h-4 mr-2 text-gray-500"}),(0,t.jsx)("span",{children:"Clusters (Running / Total)"})]}),(0,t.jsxs)("button",{onClick:()=>{l.push({pathname:"/clusters",query:{workspace:s.name}})},className:"font-normal text-blue-600 hover:text-blue-800 hover:underline cursor-pointer",children:[s.runningClusterCount," / ",s.totalClusterCount]})]}),(0,t.jsxs)("div",{className:"py-2 flex items-center justify-between border-t border-gray-100",children:[(0,t.jsxs)("div",{className:"flex items-center text-gray-600",children:[(0,t.jsx)(h.Vp,{className:"w-4 h-4 mr-2 text-gray-500"}),(0,t.jsx)("span",{children:"Managed Jobs"})]}),(0,t.jsx)("button",{onClick:()=>{l.push({pathname:"/jobs",query:{workspace:s.name}})},className:"font-normal text-blue-600 hover:text-blue-800 hover:underline cursor-pointer",children:s.managedJobsCount})]})]}),(0,t.jsxs)("div",{className:"px-6 pb-3 text-sm pt-3",children:[(0,t.jsx)("h4",{className:"mb-2 text-xs text-gray-500 tracking-wider",children:"Enabled Infra"}),(0,t.jsx)("div",{className:"flex flex-wrap gap-x-4 gap-y-1",children:s.clouds.map(e=>(0,t.jsxs)("div",{className:"flex items-center text-gray-700",children:[(0,t.jsx)(h.Ye,{className:"w-3.5 h-3.5 mr-1.5 text-green-500"}),(0,t.jsx)("span",{children:e})]},e))})]}),(0,t.jsxs)(o.eW,{className:"flex justify-end pt-3 gap-2",children:[(0,t.jsx)(d.z,{variant:"outline",size:"sm",onClick:()=>r(s.name),disabled:"default"===s.name||c,title:"default"===s.name?"Cannot delete default workspace":"Delete workspace",className:"text-red-600 hover:text-red-700 hover:bg-red-50",children:c?(0,t.jsxs)("div",{className:"flex items-center",children:[(0,t.jsx)(u.Z,{size:12,className:"mr-1"}),(0,t.jsx)("span",{children:"Delete"})]}):"Delete"}),(0,t.jsx)(d.z,{variant:"outline",size:"sm",onClick:()=>{i("cannot edit workspace",()=>{n(s.name)})},disabled:c,children:c?(0,t.jsxs)("div",{className:"flex items-center",children:[(0,t.jsx)(u.Z,{size:12,className:"mr-1"}),(0,t.jsx)("span",{children:"Edit"})]}):"Edit"})]})]},s.name)},C=e=>{let{onClick:s,checkPermissionAndAct:r,roleLoading:n}=e;return(0,t.jsx)(o.Zb,{className:"border-2 border-dashed border-sky-300 hover:border-sky-400 cursor-pointer transition-colors flex flex-col",onClick:()=>{r("cannot create workspace",s)},children:(0,t.jsx)("div",{className:"flex-1 flex items-center justify-center p-6",children:(0,t.jsxs)("div",{className:"text-center",children:[(0,t.jsx)("div",{className:"w-16 h-16 rounded-full bg-sky-100 flex items-center justify-center mb-4 mx-auto",children:(0,t.jsx)("span",{className:"text-3xl text-sky-600",children:"+"})}),(0,t.jsx)("h3",{className:"text-lg font-medium text-sky-700 mb-2",children:"Create New Workspace"}),(0,t.jsx)("p",{className:"text-sm text-gray-500",children:"Set up a new workspace with custom infrastructure configurations"})]})})},"create-new")},E=e=>{let{workspaceCount:s,runningClusters:r,totalClusters:n,managedJobs:l,router:a}=e;return(0,t.jsx)("div",{className:"bg-sky-50 p-4 rounded-lg shadow mb-6",children:(0,t.jsxs)("div",{className:"flex flex-col sm:flex-row justify-around items-center",children:[(0,t.jsx)("div",{className:"p-2",children:(0,t.jsxs)("div",{className:"flex items-center",children:[(0,t.jsx)(h.E9,{className:"w-5 h-5 mr-2 text-sky-600"}),(0,t.jsx)("span",{className:"text-sm text-gray-600",children:"Workspaces:"}),(0,t.jsx)("span",{className:"ml-1 text-xl font-semibold text-sky-700",children:s})]})}),(0,t.jsx)("div",{className:"p-2",children:(0,t.jsxs)("div",{className:"flex items-center",children:[(0,t.jsx)(h.QT,{className:"w-5 h-5 mr-2 text-sky-600"}),(0,t.jsx)("span",{className:"text-sm text-gray-600",children:"Clusters (Running / Total):"}),(0,t.jsxs)("button",{onClick:()=>a.push("/clusters"),className:"ml-1 text-xl font-semibold text-blue-600 hover:text-blue-800 hover:underline cursor-pointer",children:[r," / ",n]})]})}),(0,t.jsx)("div",{className:"p-2",children:(0,t.jsxs)("div",{className:"flex items-center",children:[(0,t.jsx)(h.Vp,{className:"w-5 h-5 mr-2 text-sky-600"}),(0,t.jsx)("span",{className:"text-sm text-gray-600",children:"Managed Jobs:"}),(0,t.jsx)("button",{onClick:()=>a.push("/jobs"),className:"ml-1 text-xl font-semibold text-blue-600 hover:text-blue-800 hover:underline cursor-pointer",children:l})]})})]})})},z=N.nb.REFRESH_INTERVAL;function D(){let[e,s]=(0,n.useState)([]),[r,o]=(0,n.useState)({runningClusters:0,totalClusters:0,managedJobs:0}),[h,N]=(0,n.useState)(!0),[w,D]=(0,n.useState)(null),[R,T]=(0,n.useState)(!1),[O,S]=(0,n.useState)({confirmOpen:!1,workspaceToDelete:null,deleting:!1,error:null}),[A,Z]=(0,n.useState)({open:!1,message:"",userName:""}),[L,J]=(0,n.useState)(null),[P,W]=(0,n.useState)(!1),F=(0,l.useRouter)(),V=(0,g.X)(),M=async()=>{if(L&&Date.now()-L.timestamp<3e5)return L;W(!0);try{let e=await y.x.get("/users/role");if(!e.ok){let s=await e.json();throw Error(s.detail||"Failed to get user role")}let s=await e.json(),r={role:s.role,name:s.name,timestamp:Date.now()};return J(r),W(!1),r}catch(e){throw W(!1),e}},X=async(e,s)=>{try{let r=await M();if("admin"!==r.role)return Z({open:!0,message:e,userName:r.name.toLowerCase()}),!1;return s(),!0}catch(e){return console.error("Failed to check user role:",e),Z({open:!0,message:"Error: ".concat(e.message),userName:""}),!1}},_=async function(){let e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];e&&N(!0);try{let[e,r,t]=await Promise.all([v.default.get(c.fX),v.default.get(a.getClusters),v.default.get(i.getManagedJobs,[{allUsers:!0}])]);D(e);let n=Object.keys(e),l=await Promise.all(n.map(e=>v.default.get(c.yz,[e]))),d=Object.fromEntries(n.map((e,s)=>[e,l[s]])),u=Object.fromEntries(r.map(e=>[e.cluster,e.workspace||"default"])),m={};n.forEach(e=>{m[e]={name:e,totalClusterCount:0,runningClusterCount:0,managedJobsCount:0,clouds:new Set}});let x=0;r.forEach(e=>{let s=e.workspace||"default";m[s]||(m[s]={name:s,totalClusterCount:0,runningClusterCount:0,managedJobsCount:0,clouds:new Set}),m[s].totalClusterCount++,("RUNNING"===e.status||"LAUNCHING"===e.status)&&(m[s].runningClusterCount++,x++),e.cloud&&m[s].clouds.add(e.cloud)});let h=t.jobs||[],f=new Set(j.statusGroups.active),p=0;h.forEach(e=>{let s=e.cluster_name||e.resources&&e.resources.cluster_name;if(s){let r=u[s];r&&m[r]&&f.has(e.status)&&m[r].managedJobsCount++}f.has(e.status)&&p++});let g=Object.values(m).filter(e=>n.includes(e.name)).map(e=>({...e,clouds:Array.isArray(d[e.name])?d[e.name]:[]})).sort((e,s)=>e.name.localeCompare(s.name));s(g),o({runningClusters:x,totalClusters:r.length,managedJobs:p})}catch(e){console.error("Error fetching workspace data:",e),s([]),o({runningClusters:0,totalClusters:0,managedJobs:0})}e&&N(!1)};(0,n.useEffect)(()=>{(async()=>{await b.ZP.preloadForPage("workspaces"),_(!0)})();let e=setInterval(()=>{_(!1)},z);return()=>clearInterval(e)},[]);let B=e=>{X("cannot delete workspace",()=>{S({confirmOpen:!0,workspaceToDelete:e,deleting:!1,error:null})})},I=async()=>{if(O.workspaceToDelete){S(e=>({...e,deleting:!0,error:null}));try{await (0,c.zl)(O.workspaceToDelete),S({confirmOpen:!1,workspaceToDelete:null,deleting:!1,error:null}),v.default.invalidate(c.fX),await _(!0)}catch(e){console.error("Error deleting workspace:",e),S(s=>({...s,deleting:!1,error:e}))}}},q=()=>{S({confirmOpen:!1,workspaceToDelete:null,deleting:!1,error:null})};return h&&0===e.length?(0,t.jsxs)("div",{className:"flex justify-center items-center h-64",children:[(0,t.jsx)(u.Z,{}),(0,t.jsx)("span",{className:"ml-2 text-gray-500",children:"Loading workspaces..."})]}):(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-4 h-5",children:[(0,t.jsxs)("div",{className:"text-base flex items-center",children:[(0,t.jsx)("span",{className:"text-sky-blue leading-none",children:"Workspaces"}),(0,t.jsx)(d.z,{variant:"outline",size:"sm",onClick:()=>{X("cannot edit config",()=>{F.push("/config")})},className:"ml-4 px-2 py-1 text-xs",disabled:h||P||!w||0===Object.keys(w).length,children:P?(0,t.jsxs)("div",{className:"flex items-center",children:[(0,t.jsx)(u.Z,{size:12,className:"mr-1"}),(0,t.jsx)("span",{children:"Edit All Configs"})]}):"Edit All Configs"})]}),(0,t.jsxs)("div",{className:"flex items-center",children:[h&&(0,t.jsxs)("div",{className:"flex items-center mr-2",children:[(0,t.jsx)(u.Z,{size:15,className:"mt-0"}),(0,t.jsx)("span",{className:"ml-2 text-gray-500 text-xs",children:"Refreshing..."})]}),(0,t.jsxs)("button",{onClick:()=>{v.default.invalidate(c.fX),v.default.invalidate(a.getClusters),v.default.invalidate(i.getManagedJobs,[{allUsers:!0}]),v.default.invalidateFunction(c.yz),_(!0)},disabled:h,className:"text-sky-blue hover:text-sky-blue-bright flex items-center",children:[(0,t.jsx)(p.Z,{className:"h-4 w-4 mr-1.5"}),!V&&(0,t.jsx)("span",{children:"Refresh"})]})]})]}),(0,t.jsx)(E,{workspaceCount:e.length,runningClusters:r.runningClusters,totalClusters:r.totalClusters,managedJobs:r.managedJobs,router:F}),0!==e.length||h?(0,t.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6",children:[e.map(e=>(0,t.jsx)(k,{workspace:e,onDelete:B,onEdit:e=>F.push("/workspaces/".concat(e)),router:F,rawWorkspacesData:w,checkPermissionAndAct:X,roleLoading:P},e.name)),(0,t.jsx)(C,{onClick:()=>F.push("/workspace/new"),checkPermissionAndAct:X,roleLoading:P})]}):(0,t.jsxs)("div",{className:"text-center py-10",children:[(0,t.jsx)("p",{className:"text-lg text-gray-600",children:"No workspaces found."}),(0,t.jsx)("p",{className:"text-sm text-gray-500 mt-2",children:"Create a cluster to see its workspace here."})]}),w&&(0,t.jsx)(x.Vq,{open:R,onOpenChange:T,children:(0,t.jsxs)(x.cZ,{className:"sm:max-w-md md:max-w-lg lg:max-w-xl xl:max-w-2xl w-full max-h-[90vh] flex flex-col",children:[(0,t.jsx)(x.fK,{children:(0,t.jsx)(x.$N,{className:"pr-10",children:"All Workspaces Configuration"})}),(0,t.jsx)("div",{className:"flex-grow overflow-y-auto py-4",children:(0,t.jsx)("pre",{style:{backgroundColor:"#f5f5f5",padding:"16px",borderRadius:"8px",overflowX:"auto",whiteSpace:"pre",wordBreak:"normal"},children:m.ZP.dump(w,{indent:2})})})]})}),(0,t.jsx)(x.Vq,{open:A.open,onOpenChange:e=>Z(s=>({...s,open:e})),children:(0,t.jsxs)(x.cZ,{className:"sm:max-w-md transition-all duration-200 ease-in-out",children:[(0,t.jsxs)(x.fK,{children:[(0,t.jsx)(x.$N,{children:"Permission Denied"}),(0,t.jsx)(x.Be,{children:P?(0,t.jsxs)("div",{className:"flex items-center py-2",children:[(0,t.jsx)(u.Z,{size:16,className:"mr-2"}),(0,t.jsx)("span",{children:"Checking permissions..."})]}):(0,t.jsx)(t.Fragment,{children:A.userName?(0,t.jsxs)(t.Fragment,{children:[A.userName," is logged in as non-admin and ",A.message,"."]}):A.message})})]}),(0,t.jsx)(x.cN,{children:(0,t.jsx)(d.z,{variant:"outline",onClick:()=>Z(e=>({...e,open:!1})),disabled:P,children:"OK"})})]})}),(0,t.jsx)(x.Vq,{open:O.confirmOpen,onOpenChange:q,children:(0,t.jsxs)(x.cZ,{className:"sm:max-w-md",children:[(0,t.jsxs)(x.fK,{children:[(0,t.jsx)(x.$N,{children:"Delete Workspace"}),(0,t.jsxs)(x.Be,{children:['Are you sure you want to delete workspace "',O.workspaceToDelete,'"? This action cannot be undone.']})]}),(0,t.jsx)(f.X,{error:O.error,title:"Deletion Failed",onDismiss:()=>S(e=>({...e,error:null}))}),(0,t.jsxs)(x.cN,{children:[(0,t.jsx)(d.z,{variant:"outline",onClick:q,disabled:O.deleting,children:"Cancel"}),(0,t.jsx)(d.z,{variant:"destructive",onClick:I,disabled:O.deleting,children:O.deleting?"Deleting...":"Delete"})]})]})})]})}},2003:function(e,s,r){r.d(s,{j:function(){return a}});var t=r(512);let n=e=>"boolean"==typeof e?`${e}`:0===e?"0":e,l=t.W,a=(e,s)=>r=>{var t;if((null==s?void 0:s.variants)==null)return l(e,null==r?void 0:r.class,null==r?void 0:r.className);let{variants:a,defaultVariants:i}=s,c=Object.keys(a).map(e=>{let s=null==r?void 0:r[e],t=null==i?void 0:i[e];if(null===s)return null;let l=n(s)||n(t);return a[e][l]}),o=r&&Object.entries(r).reduce((e,s)=>{let[r,t]=s;return void 0===t||(e[r]=t),e},{});return l(e,c,null==s?void 0:null===(t=s.compoundVariants)||void 0===t?void 0:t.reduce((e,s)=>{let{class:r,className:t,...n}=s;return Object.entries(n).every(e=>{let[s,r]=e;return Array.isArray(r)?r.includes({...i,...o}[s]):({...i,...o})[s]===r})?[...e,r,t]:e},[]),null==r?void 0:r.class,null==r?void 0:r.className)}}}]);