skypilot-nightly 1.0.0.dev20250909__py3-none-any.whl → 1.0.0.dev20250912__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of skypilot-nightly might be problematic. Click here for more details.

Files changed (97) hide show
  1. sky/__init__.py +2 -2
  2. sky/authentication.py +19 -4
  3. sky/backends/backend_utils.py +160 -23
  4. sky/backends/cloud_vm_ray_backend.py +226 -74
  5. sky/catalog/__init__.py +7 -0
  6. sky/catalog/aws_catalog.py +4 -0
  7. sky/catalog/common.py +18 -0
  8. sky/catalog/data_fetchers/fetch_aws.py +13 -1
  9. sky/client/cli/command.py +2 -71
  10. sky/client/sdk.py +20 -0
  11. sky/client/sdk_async.py +23 -18
  12. sky/clouds/aws.py +26 -6
  13. sky/clouds/cloud.py +8 -0
  14. sky/dashboard/out/404.html +1 -1
  15. sky/dashboard/out/_next/static/chunks/3294.ba6586f9755b0edb.js +6 -0
  16. sky/dashboard/out/_next/static/chunks/{webpack-d4fabc08788e14af.js → webpack-e8a0c4c3c6f408fb.js} +1 -1
  17. sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
  18. sky/dashboard/out/clusters/[cluster].html +1 -1
  19. sky/dashboard/out/clusters.html +1 -1
  20. sky/dashboard/out/config.html +1 -1
  21. sky/dashboard/out/index.html +1 -1
  22. sky/dashboard/out/infra/[context].html +1 -1
  23. sky/dashboard/out/infra.html +1 -1
  24. sky/dashboard/out/jobs/[job].html +1 -1
  25. sky/dashboard/out/jobs/pools/[pool].html +1 -1
  26. sky/dashboard/out/jobs.html +1 -1
  27. sky/dashboard/out/users.html +1 -1
  28. sky/dashboard/out/volumes.html +1 -1
  29. sky/dashboard/out/workspace/new.html +1 -1
  30. sky/dashboard/out/workspaces/[name].html +1 -1
  31. sky/dashboard/out/workspaces.html +1 -1
  32. sky/data/storage.py +5 -1
  33. sky/execution.py +21 -14
  34. sky/global_user_state.py +34 -0
  35. sky/jobs/client/sdk_async.py +4 -2
  36. sky/jobs/constants.py +3 -0
  37. sky/jobs/controller.py +734 -310
  38. sky/jobs/recovery_strategy.py +251 -129
  39. sky/jobs/scheduler.py +247 -174
  40. sky/jobs/server/core.py +20 -4
  41. sky/jobs/server/utils.py +2 -2
  42. sky/jobs/state.py +709 -508
  43. sky/jobs/utils.py +90 -40
  44. sky/logs/agent.py +10 -2
  45. sky/provision/aws/config.py +4 -1
  46. sky/provision/gcp/config.py +6 -1
  47. sky/provision/kubernetes/config.py +7 -2
  48. sky/provision/kubernetes/instance.py +84 -41
  49. sky/provision/kubernetes/utils.py +17 -8
  50. sky/provision/provisioner.py +1 -0
  51. sky/provision/vast/instance.py +1 -1
  52. sky/schemas/db/global_user_state/008_skylet_ssh_tunnel_metadata.py +34 -0
  53. sky/serve/replica_managers.py +0 -7
  54. sky/serve/serve_utils.py +5 -0
  55. sky/serve/server/impl.py +1 -2
  56. sky/serve/service.py +0 -2
  57. sky/server/common.py +8 -3
  58. sky/server/config.py +55 -27
  59. sky/server/constants.py +1 -0
  60. sky/server/daemons.py +7 -11
  61. sky/server/metrics.py +41 -8
  62. sky/server/requests/executor.py +41 -4
  63. sky/server/requests/serializers/encoders.py +1 -1
  64. sky/server/server.py +9 -1
  65. sky/server/uvicorn.py +11 -5
  66. sky/setup_files/dependencies.py +4 -2
  67. sky/skylet/attempt_skylet.py +1 -0
  68. sky/skylet/constants.py +14 -7
  69. sky/skylet/events.py +2 -10
  70. sky/skylet/log_lib.py +11 -0
  71. sky/skylet/log_lib.pyi +9 -0
  72. sky/task.py +62 -0
  73. sky/templates/kubernetes-ray.yml.j2 +120 -3
  74. sky/utils/accelerator_registry.py +3 -1
  75. sky/utils/command_runner.py +35 -11
  76. sky/utils/command_runner.pyi +25 -3
  77. sky/utils/common_utils.py +11 -1
  78. sky/utils/context_utils.py +15 -2
  79. sky/utils/controller_utils.py +5 -0
  80. sky/utils/db/db_utils.py +31 -2
  81. sky/utils/db/migration_utils.py +1 -1
  82. sky/utils/git.py +559 -1
  83. sky/utils/resource_checker.py +8 -7
  84. sky/utils/rich_utils.py +3 -1
  85. sky/utils/subprocess_utils.py +9 -0
  86. sky/volumes/volume.py +2 -0
  87. sky/workspaces/core.py +57 -21
  88. {skypilot_nightly-1.0.0.dev20250909.dist-info → skypilot_nightly-1.0.0.dev20250912.dist-info}/METADATA +38 -36
  89. {skypilot_nightly-1.0.0.dev20250909.dist-info → skypilot_nightly-1.0.0.dev20250912.dist-info}/RECORD +95 -95
  90. sky/client/cli/git.py +0 -549
  91. sky/dashboard/out/_next/static/chunks/3294.c80326aec9bfed40.js +0 -6
  92. /sky/dashboard/out/_next/static/{eWytLgin5zvayQw3Xk46m → DAiq7V2xJnO1LSfmunZl6}/_buildManifest.js +0 -0
  93. /sky/dashboard/out/_next/static/{eWytLgin5zvayQw3Xk46m → DAiq7V2xJnO1LSfmunZl6}/_ssgManifest.js +0 -0
  94. {skypilot_nightly-1.0.0.dev20250909.dist-info → skypilot_nightly-1.0.0.dev20250912.dist-info}/WHEEL +0 -0
  95. {skypilot_nightly-1.0.0.dev20250909.dist-info → skypilot_nightly-1.0.0.dev20250912.dist-info}/entry_points.txt +0 -0
  96. {skypilot_nightly-1.0.0.dev20250909.dist-info → skypilot_nightly-1.0.0.dev20250912.dist-info}/licenses/LICENSE +0 -0
  97. {skypilot_nightly-1.0.0.dev20250909.dist-info → skypilot_nightly-1.0.0.dev20250912.dist-info}/top_level.txt +0 -0
sky/client/cli/command.py CHANGED
@@ -59,7 +59,6 @@ from sky import task as task_lib
59
59
  from sky.adaptors import common as adaptors_common
60
60
  from sky.client import sdk
61
61
  from sky.client.cli import flags
62
- from sky.client.cli import git
63
62
  from sky.data import storage_utils
64
63
  from sky.provision.kubernetes import constants as kubernetes_constants
65
64
  from sky.provision.kubernetes import utils as kubernetes_utils
@@ -79,7 +78,6 @@ from sky.utils import controller_utils
79
78
  from sky.utils import dag_utils
80
79
  from sky.utils import directory_utils
81
80
  from sky.utils import env_options
82
- from sky.utils import git as git_utils
83
81
  from sky.utils import infra_utils
84
82
  from sky.utils import log_utils
85
83
  from sky.utils import registry
@@ -783,8 +781,8 @@ def _make_task_or_dag_from_entrypoint_with_overrides(
783
781
 
784
782
  # Update the workdir config from the command line parameters.
785
783
  # And update the envs and secrets from the workdir.
786
- _update_task_workdir(task, workdir, git_url, git_ref)
787
- _update_task_workdir_and_secrets_from_workdir(task)
784
+ task.update_workdir(workdir, git_url, git_ref)
785
+ task.update_envs_and_secrets_from_workdir()
788
786
 
789
787
  # job launch specific.
790
788
  if job_recovery is not None:
@@ -799,73 +797,6 @@ def _make_task_or_dag_from_entrypoint_with_overrides(
799
797
  return task
800
798
 
801
799
 
802
- def _update_task_workdir(task: task_lib.Task, workdir: Optional[str],
803
- git_url: Optional[str], git_ref: Optional[str]):
804
- """Updates the task workdir.
805
-
806
- Args:
807
- task: The task to update.
808
- workdir: The workdir to update.
809
- git_url: The git url to update.
810
- git_ref: The git ref to update.
811
- """
812
- if task.workdir is None or isinstance(task.workdir, str):
813
- if workdir is not None:
814
- task.workdir = workdir
815
- return
816
- if git_url is not None:
817
- task.workdir = {}
818
- task.workdir['url'] = git_url
819
- if git_ref is not None:
820
- task.workdir['ref'] = git_ref
821
- return
822
- return
823
- if git_url is not None:
824
- task.workdir['url'] = git_url
825
- if git_ref is not None:
826
- task.workdir['ref'] = git_ref
827
- return
828
-
829
-
830
- def _update_task_workdir_and_secrets_from_workdir(task: task_lib.Task):
831
- """Updates the task secrets from the workdir.
832
-
833
- Args:
834
- task: The task to update.
835
- """
836
- if task.workdir is None:
837
- return
838
- if not isinstance(task.workdir, dict):
839
- return
840
- url = task.workdir['url']
841
- ref = task.workdir.get('ref', '')
842
- token = os.environ.get(git_utils.GIT_TOKEN_ENV_VAR)
843
- ssh_key_path = os.environ.get(git_utils.GIT_SSH_KEY_PATH_ENV_VAR)
844
- try:
845
- git_repo = git.GitRepo(url, ref, token, ssh_key_path)
846
- clone_info = git_repo.get_repo_clone_info()
847
- if clone_info is None:
848
- return
849
- task.envs[git_utils.GIT_URL_ENV_VAR] = clone_info.url
850
- if ref:
851
- ref_type = git_repo.get_ref_type()
852
- if ref_type == git.GitRefType.COMMIT:
853
- task.envs[git_utils.GIT_COMMIT_HASH_ENV_VAR] = ref
854
- elif ref_type == git.GitRefType.BRANCH:
855
- task.envs[git_utils.GIT_BRANCH_ENV_VAR] = ref
856
- elif ref_type == git.GitRefType.TAG:
857
- task.envs[git_utils.GIT_TAG_ENV_VAR] = ref
858
- if clone_info.token is None and clone_info.ssh_key is None:
859
- return
860
- if clone_info.token is not None:
861
- task.secrets[git_utils.GIT_TOKEN_ENV_VAR] = clone_info.token
862
- if clone_info.ssh_key is not None:
863
- task.secrets[git_utils.GIT_SSH_KEY_ENV_VAR] = clone_info.ssh_key
864
- except exceptions.GitError as e:
865
- with ux_utils.print_exception_no_traceback():
866
- raise ValueError(f'{str(e)}') from None
867
-
868
-
869
800
  class _NaturalOrderGroup(click.Group):
870
801
  """Lists commands in the order defined in this script.
871
802
 
sky/client/sdk.py CHANGED
@@ -31,6 +31,7 @@ from sky import skypilot_config
31
31
  from sky.adaptors import common as adaptors_common
32
32
  from sky.client import common as client_common
33
33
  from sky.client import oauth as oauth_lib
34
+ from sky.jobs import scheduler
34
35
  from sky.schemas.api import responses
35
36
  from sky.server import common as server_common
36
37
  from sky.server import rest
@@ -2287,6 +2288,25 @@ def api_stop() -> None:
2287
2288
  f'Cannot kill the API server at {server_url} because it is not '
2288
2289
  f'the default SkyPilot API server started locally.')
2289
2290
 
2291
+ try:
2292
+ with open(os.path.expanduser(scheduler.JOB_CONTROLLER_PID_PATH),
2293
+ 'r',
2294
+ encoding='utf-8') as f:
2295
+ pids = f.read().split('\n')[:-1]
2296
+ for pid in pids:
2297
+ if subprocess_utils.is_process_alive(int(pid.strip())):
2298
+ subprocess_utils.kill_children_processes(
2299
+ parent_pids=[int(pid.strip())], force=True)
2300
+ os.remove(os.path.expanduser(scheduler.JOB_CONTROLLER_PID_PATH))
2301
+ except FileNotFoundError:
2302
+ # its fine we will create it
2303
+ pass
2304
+ except Exception as e: # pylint: disable=broad-except
2305
+ # in case we get perm issues or something is messed up, just ignore it
2306
+ # and assume the process is dead
2307
+ logger.error(f'Error looking at job controller pid file: {e}')
2308
+ pass
2309
+
2290
2310
  found = _local_api_server_running(kill=True)
2291
2311
 
2292
2312
  # Remove the database for requests.
sky/client/sdk_async.py CHANGED
@@ -19,20 +19,16 @@ import aiohttp
19
19
  import colorama
20
20
 
21
21
  from sky import admin_policy
22
- from sky import backends
23
22
  from sky import catalog
24
23
  from sky import exceptions
25
- from sky import models
26
24
  from sky import sky_logging
27
25
  from sky.client import common as client_common
28
26
  from sky.client import sdk
29
- from sky.provision.kubernetes import utils as kubernetes_utils
30
27
  from sky.schemas.api import responses
31
28
  from sky.server import common as server_common
32
29
  from sky.server import rest
33
30
  from sky.server.requests import payloads
34
31
  from sky.server.requests import requests as requests_lib
35
- from sky.skylet import job_lib
36
32
  from sky.usage import usage_lib
37
33
  from sky.utils import annotations
38
34
  from sky.utils import common
@@ -45,6 +41,11 @@ if typing.TYPE_CHECKING:
45
41
  import io
46
42
 
47
43
  import sky
44
+ from sky import backends
45
+ from sky import models
46
+ from sky.provision.kubernetes import utils as kubernetes_utils
47
+ from sky.skylet import autostop_lib
48
+ from sky.skylet import job_lib
48
49
 
49
50
  logger = sky_logging.init_logger(__name__)
50
51
  logging.getLogger('httpx').setLevel(logging.CRITICAL)
@@ -381,9 +382,10 @@ async def launch(
381
382
  cluster_name: Optional[str] = None,
382
383
  retry_until_up: bool = False,
383
384
  idle_minutes_to_autostop: Optional[int] = None,
385
+ wait_for: Optional['autostop_lib.AutostopWaitFor'] = None,
384
386
  dryrun: bool = False,
385
387
  down: bool = False, # pylint: disable=redefined-outer-name
386
- backend: Optional[backends.Backend] = None,
388
+ backend: Optional['backends.Backend'] = None,
387
389
  optimize_target: common.OptimizeTarget = common.OptimizeTarget.COST,
388
390
  no_setup: bool = False,
389
391
  clone_disk_from: Optional[str] = None,
@@ -395,12 +397,12 @@ async def launch(
395
397
  _is_launched_by_sky_serve_controller: bool = False,
396
398
  _disable_controller_check: bool = False,
397
399
  stream_logs: Optional[StreamConfig] = DEFAULT_STREAM_CONFIG,
398
- ) -> Tuple[Optional[int], Optional[backends.ResourceHandle]]:
400
+ ) -> Tuple[Optional[int], Optional['backends.ResourceHandle']]:
399
401
  """Async version of launch() that launches a cluster or task."""
400
402
  request_id = await context_utils.to_thread(
401
403
  sdk.launch, task, cluster_name, retry_until_up,
402
- idle_minutes_to_autostop, dryrun, down, backend, optimize_target,
403
- no_setup, clone_disk_from, fast, _need_confirmation,
404
+ idle_minutes_to_autostop, wait_for, dryrun, down, backend,
405
+ optimize_target, no_setup, clone_disk_from, fast, _need_confirmation,
404
406
  _is_launched_by_jobs_controller, _is_launched_by_sky_serve_controller,
405
407
  _disable_controller_check)
406
408
  if stream_logs is not None:
@@ -416,9 +418,9 @@ async def exec( # pylint: disable=redefined-builtin
416
418
  cluster_name: Optional[str] = None,
417
419
  dryrun: bool = False,
418
420
  down: bool = False, # pylint: disable=redefined-outer-name
419
- backend: Optional[backends.Backend] = None,
421
+ backend: Optional['backends.Backend'] = None,
420
422
  stream_logs: Optional[StreamConfig] = DEFAULT_STREAM_CONFIG,
421
- ) -> Tuple[Optional[int], Optional[backends.ResourceHandle]]:
423
+ ) -> Tuple[Optional[int], Optional['backends.ResourceHandle']]:
422
424
  """Async version of exec() that executes a task on an existing cluster."""
423
425
  request_id = await context_utils.to_thread(sdk.exec, task, cluster_name,
424
426
  dryrun, down, backend)
@@ -454,15 +456,17 @@ async def download_logs(cluster_name: str,
454
456
  async def start(
455
457
  cluster_name: str,
456
458
  idle_minutes_to_autostop: Optional[int] = None,
459
+ wait_for: Optional['autostop_lib.AutostopWaitFor'] = None,
457
460
  retry_until_up: bool = False,
458
461
  down: bool = False, # pylint: disable=redefined-outer-name
459
462
  force: bool = False,
460
463
  stream_logs: Optional[StreamConfig] = DEFAULT_STREAM_CONFIG,
461
- ) -> backends.CloudVmRayResourceHandle:
464
+ ) -> 'backends.CloudVmRayResourceHandle':
462
465
  """Async version of start() that restarts a cluster."""
463
466
  request_id = await context_utils.to_thread(sdk.start, cluster_name,
464
467
  idle_minutes_to_autostop,
465
- retry_until_up, down, force)
468
+ wait_for, retry_until_up, down,
469
+ force)
466
470
  if stream_logs is not None:
467
471
  return await _stream_and_get(request_id, stream_logs)
468
472
  else:
@@ -502,13 +506,14 @@ async def stop(
502
506
  async def autostop(
503
507
  cluster_name: str,
504
508
  idle_minutes: int,
509
+ wait_for: Optional['autostop_lib.AutostopWaitFor'] = None,
505
510
  down: bool = False, # pylint: disable=redefined-outer-name
506
511
  stream_logs: Optional[StreamConfig] = DEFAULT_STREAM_CONFIG
507
512
  ) -> None:
508
513
  """Async version of autostop() that schedules an autostop/autodown for a
509
514
  cluster."""
510
515
  request_id = await context_utils.to_thread(sdk.autostop, cluster_name,
511
- idle_minutes, down)
516
+ idle_minutes, wait_for, down)
512
517
  if stream_logs is not None:
513
518
  return await _stream_and_get(request_id, stream_logs)
514
519
  else:
@@ -538,7 +543,7 @@ async def job_status(
538
543
  cluster_name: str,
539
544
  job_ids: Optional[List[int]] = None,
540
545
  stream_logs: Optional[StreamConfig] = DEFAULT_STREAM_CONFIG
541
- ) -> Dict[Optional[int], Optional[job_lib.JobStatus]]:
546
+ ) -> Dict[Optional[int], Optional['job_lib.JobStatus']]:
542
547
  """Async version of job_status() that gets the status of jobs on a
543
548
  cluster."""
544
549
  request_id = await context_utils.to_thread(sdk.job_status, cluster_name,
@@ -718,7 +723,7 @@ async def realtime_kubernetes_gpu_availability(
718
723
  quantity_filter: Optional[int] = None,
719
724
  is_ssh: Optional[bool] = None,
720
725
  stream_logs: Optional[StreamConfig] = DEFAULT_STREAM_CONFIG
721
- ) -> List[Tuple[str, List[models.RealtimeGpuAvailability]]]:
726
+ ) -> List[Tuple[str, List['models.RealtimeGpuAvailability']]]:
722
727
  """Async version of realtime_kubernetes_gpu_availability() that gets the
723
728
  real-time Kubernetes GPU availability."""
724
729
  request_id = await context_utils.to_thread(
@@ -735,7 +740,7 @@ async def realtime_kubernetes_gpu_availability(
735
740
  async def kubernetes_node_info(
736
741
  context: Optional[str] = None,
737
742
  stream_logs: Optional[StreamConfig] = DEFAULT_STREAM_CONFIG
738
- ) -> models.KubernetesNodesInfo:
743
+ ) -> 'models.KubernetesNodesInfo':
739
744
  """Async version of kubernetes_node_info() that gets the resource
740
745
  information for all the nodes in the cluster."""
741
746
  request_id = await context_utils.to_thread(sdk.kubernetes_node_info,
@@ -750,8 +755,8 @@ async def kubernetes_node_info(
750
755
  @annotations.client_api
751
756
  async def status_kubernetes(
752
757
  stream_logs: Optional[StreamConfig] = DEFAULT_STREAM_CONFIG
753
- ) -> Tuple[List[kubernetes_utils.KubernetesSkyPilotClusterInfoPayload],
754
- List[kubernetes_utils.KubernetesSkyPilotClusterInfoPayload],
758
+ ) -> Tuple[List['kubernetes_utils.KubernetesSkyPilotClusterInfoPayload'],
759
+ List['kubernetes_utils.KubernetesSkyPilotClusterInfoPayload'],
755
760
  List[Dict[str, Any]], Optional[str]]:
756
761
  """Async version of status_kubernetes() that gets all SkyPilot clusters
757
762
  and jobs in the Kubernetes cluster."""
sky/clouds/aws.py CHANGED
@@ -39,9 +39,11 @@ logger = sky_logging.init_logger(__name__)
39
39
 
40
40
  # Image ID tags
41
41
  _DEFAULT_CPU_IMAGE_ID = 'skypilot:custom-cpu-ubuntu'
42
+ _DEFAULT_CPU_ARM64_IMAGE_ID = 'skypilot:custom-cpu-ubuntu-arm64'
42
43
  # For GPU-related package version,
43
44
  # see sky/catalog/images/provisioners/cuda.sh
44
45
  _DEFAULT_GPU_IMAGE_ID = 'skypilot:custom-gpu-ubuntu'
46
+ _DEFAULT_GPU_ARM64_IMAGE_ID = 'skypilot:custom-gpu-ubuntu-arm64'
45
47
  _DEFAULT_GPU_K80_IMAGE_ID = 'skypilot:k80-ubuntu-2004'
46
48
  _DEFAULT_NEURON_IMAGE_ID = 'skypilot:neuron-ubuntu-2204'
47
49
 
@@ -156,7 +158,9 @@ def _get_max_efa_interfaces(instance_type: str, region_name: str) -> int:
156
158
  try:
157
159
  client = aws.client('ec2', region_name=region_name)
158
160
  response = client.describe_instance_types(
159
- InstanceTypes=[instance_type],
161
+ # TODO(cooperc): fix the types for mypy 1.16
162
+ # Boto3 type stubs expect Literal instance types; using str list here.
163
+ InstanceTypes=[instance_type], # type: ignore
160
164
  Filters=[{
161
165
  'Name': 'network-info.efa-supported',
162
166
  'Values': ['true']
@@ -362,13 +366,22 @@ class AWS(clouds.Cloud):
362
366
  @classmethod
363
367
  def _get_default_ami(cls, region_name: str, instance_type: str) -> str:
364
368
  acc = cls.get_accelerators_from_instance_type(instance_type)
365
- image_id = catalog.get_image_id_from_tag(_DEFAULT_CPU_IMAGE_ID,
366
- region_name,
367
- clouds='aws')
368
- if acc is not None:
369
- image_id = catalog.get_image_id_from_tag(_DEFAULT_GPU_IMAGE_ID,
369
+ arch = cls.get_arch_from_instance_type(instance_type)
370
+ if arch == constants.ARM64_ARCH:
371
+ image_id = catalog.get_image_id_from_tag(
372
+ _DEFAULT_CPU_ARM64_IMAGE_ID, region_name, clouds='aws')
373
+ else:
374
+ image_id = catalog.get_image_id_from_tag(_DEFAULT_CPU_IMAGE_ID,
370
375
  region_name,
371
376
  clouds='aws')
377
+ if acc is not None:
378
+ if arch == constants.ARM64_ARCH:
379
+ image_id = catalog.get_image_id_from_tag(
380
+ _DEFAULT_GPU_ARM64_IMAGE_ID, region_name, clouds='aws')
381
+ else:
382
+ image_id = catalog.get_image_id_from_tag(_DEFAULT_GPU_IMAGE_ID,
383
+ region_name,
384
+ clouds='aws')
372
385
  assert len(acc) == 1, acc
373
386
  acc_name = list(acc.keys())[0]
374
387
  if acc_name == 'K80':
@@ -571,6 +584,13 @@ class AWS(clouds.Cloud):
571
584
  return catalog.get_accelerators_from_instance_type(instance_type,
572
585
  clouds='aws')
573
586
 
587
+ @classmethod
588
+ def get_arch_from_instance_type(
589
+ cls,
590
+ instance_type: str,
591
+ ) -> Optional[str]:
592
+ return catalog.get_arch_from_instance_type(instance_type, clouds='aws')
593
+
574
594
  @classmethod
575
595
  def get_vcpus_mem_from_instance_type(
576
596
  cls,
sky/clouds/cloud.py CHANGED
@@ -340,6 +340,14 @@ class Cloud:
340
340
  """Returns {acc: acc_count} held by 'instance_type', if any."""
341
341
  raise NotImplementedError
342
342
 
343
+ @classmethod
344
+ def get_arch_from_instance_type(
345
+ cls,
346
+ instance_type: str,
347
+ ) -> Optional[str]:
348
+ """Returns the arch of the instance type, if any."""
349
+ raise NotImplementedError
350
+
343
351
  @classmethod
344
352
  def get_default_instance_type(cls,
345
353
  cpus: Optional[str] = None,
@@ -1 +1 @@
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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-d4fabc08788e14af.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_error-c66a4e8afc46f17b.js" defer=""></script><script src="/dashboard/_next/static/eWytLgin5zvayQw3Xk46m/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/eWytLgin5zvayQw3Xk46m/_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":"eWytLgin5zvayQw3Xk46m","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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-e8a0c4c3c6f408fb.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_error-c66a4e8afc46f17b.js" defer=""></script><script src="/dashboard/_next/static/DAiq7V2xJnO1LSfmunZl6/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/DAiq7V2xJnO1LSfmunZl6/_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":"DAiq7V2xJnO1LSfmunZl6","assetPrefix":"/dashboard","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
@@ -0,0 +1,6 @@
1
+ "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3294],{98418:function(e,s,t){t.d(s,{Z:function(){return a}});/**
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 a=(0,t(60998).Z)("Trash",[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",key:"4alrt4"}],["path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",key:"v07s0e"}]])},53294:function(e,s,t){t.r(s),t.d(s,{ContextDetails:function(){return I},GPUs:function(){return E},InfrastructureSection:function(){return D}});var a=t(85893),l=t(67294),r=t(55739);t(6135);var n=t(26409),o=t(98418),i=t(13626),d=t(23001),c=t(17853),m=t(32045),u=t(23266),x=t(68969),h=t(29326),g=t(50326),p=t(30803),f=t(42557),y=t(29749),j=t(69123);function b(e){let{isOpen:s,onClose:t,onSave:n,poolData:o=null,isLoading:i=!1}=e,[d,c]=(0,l.useState)(""),[m,u]=(0,l.useState)(""),[x,b]=(0,l.useState)("ubuntu"),[N,v]=(0,l.useState)(null),[w,S]=(0,l.useState)(""),[_,C]=(0,l.useState)({}),k=null!==o;(0,l.useEffect)(()=>{if(k&&o){var e,s,t;c(o.name||""),u(((null===(e=o.config)||void 0===e?void 0:e.hosts)||[]).join("\n")),b((null===(s=o.config)||void 0===s?void 0:s.user)||"ubuntu"),S((null===(t=o.config)||void 0===t?void 0:t.password)||"")}else c(""),u(""),b("ubuntu"),v(null),S("");C({})},[k,o]);let P=()=>{let e={};return d.trim()||(e.poolName="Pool name is required"),m.trim()||(e.hosts="At least one host is required"),x.trim()||(e.sshUser="SSH user is required"),N||w||(e.auth="Either SSH key file or password is required"),C(e),0===Object.keys(e).length},U=async()=>{if(!P())return;let e={hosts:m.split("\n").map(e=>e.trim()).filter(e=>e.length>0),user:x};try{if(N){let s=N.name;await (0,h.hY)(s,N),e.identity_file="~/.sky/ssh_keys/".concat(s)}w&&(e.password=w),n(d,e)}catch(e){console.error("Failed to upload SSH key:",e),C({..._,keyUpload:"Failed to upload SSH key"})}},D=()=>{i||t()};return(0,a.jsx)(g.Vq,{open:s,onOpenChange:D,children:(0,a.jsxs)(g.cZ,{className:"max-w-2xl max-h-[80vh] overflow-y-auto",children:[(0,a.jsx)(g.fK,{children:(0,a.jsx)(g.$N,{children:k?"Edit SSH Node Pool: ".concat(null==o?void 0:o.name):"Add SSH Node Pool"})}),(0,a.jsxs)("div",{className:"space-y-6",children:[(0,a.jsxs)("div",{className:"space-y-2",children:[(0,a.jsx)(y._,{htmlFor:"poolName",children:"Pool Name"}),(0,a.jsx)(f.I,{id:"poolName",placeholder:"my-ssh-cluster",value:d,onChange:e=>c(e.target.value),disabled:k,className:"placeholder:text-gray-500 ".concat(_.poolName?"border-red-500":"")}),_.poolName&&(0,a.jsx)("p",{className:"text-sm text-red-500",children:_.poolName})]}),(0,a.jsxs)("div",{className:"space-y-2",children:[(0,a.jsx)(y._,{htmlFor:"hosts",children:"Hosts (one per line)"}),(0,a.jsx)(j.g,{id:"hosts",placeholder:"192.168.1.10\n192.168.1.11\nhostname.example.com",value:m,onChange:e=>u(e.target.value),rows:6,className:"placeholder:text-gray-500 ".concat(_.hosts?"border-red-500":"")}),_.hosts&&(0,a.jsx)("p",{className:"text-sm text-red-500",children:_.hosts})]}),(0,a.jsxs)("div",{className:"space-y-2",children:[(0,a.jsx)(y._,{htmlFor:"sshUser",children:"SSH User"}),(0,a.jsx)(f.I,{id:"sshUser",placeholder:"ubuntu",value:x,onChange:e=>b(e.target.value),className:"placeholder:text-gray-500 ".concat(_.sshUser?"border-red-500":"")}),_.sshUser&&(0,a.jsx)("p",{className:"text-sm text-red-500",children:_.sshUser})]}),(0,a.jsxs)("div",{className:"space-y-2",children:[(0,a.jsx)(y._,{htmlFor:"keyFile",children:"SSH Private Key File"}),(0,a.jsx)(f.I,{id:"keyFile",type:"file",accept:".pem,.key,id_rsa,id_ed25519",onChange:e=>{var s;return v((null===(s=e.target.files)||void 0===s?void 0:s[0])||null)},className:"border-0 bg-transparent p-0 shadow-none focus:ring-0 file:mr-2 file:text-sm file:py-1 file:px-3 file:border file:border-gray-300 file:rounded file:bg-gray-50 hover:file:bg-gray-100 file:cursor-pointer"}),_.keyUpload&&(0,a.jsx)("p",{className:"text-sm text-red-500",children:_.keyUpload})]}),(0,a.jsxs)("div",{className:"space-y-2",children:[(0,a.jsx)(y._,{htmlFor:"password",children:"Password (optional, if sudo requires a password)"}),(0,a.jsx)(f.I,{id:"password",type:"password",placeholder:"Leave empty if using passwordless sudo",value:w,onChange:e=>S(e.target.value),className:"placeholder:text-gray-500"})]}),_.auth&&(0,a.jsx)("p",{className:"text-sm text-red-500",children:_.auth})]}),(0,a.jsxs)(g.cN,{children:[(0,a.jsx)(p.z,{variant:"outline",onClick:D,disabled:i,children:"Cancel"}),(0,a.jsx)(p.z,{onClick:U,disabled:i,className:"bg-blue-600 hover:bg-blue-700 text-white disabled:bg-gray-300 disabled:text-gray-500",children:i?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(r.Z,{size:16,className:"mr-2"}),"Saving..."]}):k?"Update Pool":"Create Pool"})]})]})})}var N=t(6378),v=t(36856),w=t(51214),S=t(11163),_=t(41664),C=t.n(_),k=t(36989);t(37673);let P=w.nb.REFRESH_INTERVAL,U=w.MO.NAME_TRUNCATE_LENGTH;function D(e){let{title:s,isLoading:t,isDataLoaded:l,contexts:n,gpus:o,groupedPerContextGPUs:i,groupedPerNodeGPUs:d,handleContextClick:c,contextStats:m={},jobsData:u={},isJobsDataLoading:x=!0,isSSH:h=!1,actionButton:g=null}=e,p=n||[];return t&&0===p.length?(0,a.jsx)("div",{className:"rounded-lg border bg-card text-card-foreground shadow-sm mb-6",children:(0,a.jsxs)("div",{className:"p-5",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold mb-4",children:s}),(0,a.jsxs)("div",{className:"flex items-center justify-center py-6",children:[(0,a.jsx)(r.Z,{size:24,className:"mr-3"}),(0,a.jsxs)("span",{className:"text-gray-500",children:["Loading ",s,"..."]})]})]})}):l&&0===p.length?(0,a.jsx)("div",{className:"rounded-lg border bg-card text-card-foreground shadow-sm mb-6",children:(0,a.jsxs)("div",{className:"p-5",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold",children:s}),g]}),(0,a.jsxs)("p",{className:"text-sm text-gray-500",children:["No ",s," found or ",s," is not configured."]})]})}):p.length>0?(0,a.jsx)("div",{className:"rounded-lg border bg-card text-card-foreground shadow-sm mb-6",children:(0,a.jsxs)("div",{className:"p-5",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold",children:s}),(0,a.jsxs)("span",{className:"ml-2 px-2 py-0.5 bg-blue-100 text-blue-800 rounded-full text-xs font-medium",children:[p.length," ",1===p.length?h?"pool":"context":h?"pools":"contexts"]})]}),g]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[(0,a.jsx)("div",{children:(0,a.jsx)("div",{className:"overflow-x-auto rounded-md border border-gray-200 shadow-sm bg-white",children:(0,a.jsxs)("table",{className:"min-w-full text-sm",children:[(0,a.jsx)("thead",{className:"bg-gray-50",children:(0,a.jsxs)("tr",{children:[(0,a.jsx)("th",{className:"p-3 text-left font-medium text-gray-600 w-1/4",children:h?"Node Pool":"Context"}),(0,a.jsx)("th",{className:"p-3 text-left font-medium text-gray-600 w-1/8",children:"Clusters"}),(0,a.jsx)("th",{className:"p-3 text-left font-medium text-gray-600 w-1/8",children:"Jobs"}),(0,a.jsx)("th",{className:"p-3 text-left font-medium text-gray-600 w-1/8",children:"Nodes"}),(0,a.jsx)("th",{className:"p-3 text-left font-medium text-gray-600 w-1/4",children:"GPU Types"}),(0,a.jsx)("th",{className:"p-3 text-left font-medium text-gray-600 w-1/8",children:"#GPUs"})]})}),(0,a.jsx)("tbody",{className:"bg-white divide-y divide-gray-200 ".concat(p.length>5?"max-h-[250px] overflow-y-auto block":""),children:p.map(e=>{var s,t;let n=i[e]||[],o=d[e]||[],g=n.reduce((e,s)=>e+(s.gpu_total||0),0),p=h?"ssh/".concat(e.replace(/^ssh-/,"")):"kubernetes/".concat(e),f=m[p]||{clusters:0,jobs:0},y=Object.keys(m).length>0&&m[p]||l,j=i&&Object.keys(i).length>0||l,b=d&&Object.keys(d).length>0||l,N=j?Object.keys(n.reduce((e,s)=>(e[s.gpu_name]=(e[s.gpu_name]||0)+(s.gpu_total||0),e),{})).join(", "):null,v=h?e.replace(/^ssh-/,""):e;return(0,a.jsxs)("tr",{className:"hover:bg-gray-50",children:[(0,a.jsx)("td",{className:"p-3",children:(0,a.jsx)(k.Md,{content:v,className:"text-sm text-muted-foreground",children:(0,a.jsx)("span",{className:"text-blue-600 hover:underline cursor-pointer",onClick:()=>c(e),children:v.length>U?"".concat(v.substring(0,Math.floor((U-3)/2)),"...").concat(v.substring(v.length-Math.ceil((U-3)/2))):v})})}),(0,a.jsx)("td",{className:"p-3",children:y?f.clusters>0?(0,a.jsx)("span",{className:"px-2 py-0.5 bg-blue-100 text-blue-800 rounded text-xs font-medium",children:f.clusters}):(0,a.jsx)("span",{className:"px-2 py-0.5 bg-gray-100 text-gray-500 rounded text-xs font-medium",children:"0"}):(0,a.jsx)("div",{className:"flex items-center justify-center",children:(0,a.jsx)(r.Z,{size:12})})}),(0,a.jsx)("td",{className:"p-3",children:x?(0,a.jsx)("span",{className:"px-2 py-0.5 bg-gray-100 text-gray-500 rounded text-xs font-medium",children:(0,a.jsx)(r.Z,{size:12})}):(null===(s=u[p])||void 0===s?void 0:s.jobs)?(0,a.jsx)("span",{className:"px-2 py-0.5 bg-green-100 text-green-800 rounded text-xs font-medium",children:null===(t=u[p])||void 0===t?void 0:t.jobs}):(0,a.jsx)("span",{className:"px-2 py-0.5 bg-gray-100 text-gray-500 rounded text-xs font-medium",children:"0"})}),(0,a.jsx)("td",{className:"p-3",children:b?o.length:(0,a.jsx)("div",{className:"flex items-center justify-center",children:(0,a.jsx)(r.Z,{size:16})})}),(0,a.jsx)("td",{className:"p-3",children:j?N||"-":(0,a.jsx)("div",{className:"flex items-center justify-center",children:(0,a.jsx)(r.Z,{size:16})})}),(0,a.jsx)("td",{className:"p-3",children:j?g:(0,a.jsx)("div",{className:"flex items-center justify-center",children:(0,a.jsx)(r.Z,{size:16})})})]},e)})})]})})}),o&&o.length>0&&(0,a.jsx)("div",{children:(0,a.jsx)("div",{className:"overflow-x-auto rounded-md border border-gray-200 shadow-sm bg-white",children:(0,a.jsxs)("table",{className:"min-w-full text-sm",children:[(0,a.jsx)("thead",{className:"bg-gray-50",children:(0,a.jsxs)("tr",{children:[(0,a.jsxs)("th",{className:"p-3 text-left font-medium text-gray-600 w-1/4 whitespace-nowrap",children:["GPU",(0,a.jsxs)("span",{className:"ml-2 px-2 py-0.5 bg-green-100 text-green-800 rounded-full text-xs font-medium whitespace-nowrap",children:[o.reduce((e,s)=>e+s.gpu_free,0)," ","of"," ",o.reduce((e,s)=>e+s.gpu_total,0)," ","free"]})]}),(0,a.jsx)("th",{className:"p-3 text-left font-medium text-gray-600 w-1/4",children:"Requestable"}),(0,a.jsx)("th",{className:"p-3 text-left font-medium text-gray-600 w-1/2",children:(0,a.jsx)("div",{className:"flex items-center",children:(0,a.jsx)("span",{children:"Utilization"})})})]})}),(0,a.jsx)("tbody",{className:"bg-white divide-y divide-gray-200 ".concat(o.length>5?"max-h-[250px] overflow-y-auto block":""),children:o.map(e=>{let s=e.gpu_total-e.gpu_free,t=e.gpu_total>0?e.gpu_free/e.gpu_total*100:0,l=e.gpu_total>0?s/e.gpu_total*100:0,r=i?Object.values(i).flat().filter(s=>s.gpu_name===e.gpu_name&&(h?s.context.startsWith("ssh-"):!s.context.startsWith("ssh-"))).map(e=>e.gpu_requestable_qty_per_node).filter((e,s,t)=>t.indexOf(e)===s).join(", "):"-";return(0,a.jsxs)("tr",{children:[(0,a.jsx)("td",{className:"p-3 font-medium w-24 whitespace-nowrap",children:e.gpu_name}),(0,a.jsxs)("td",{className:"p-3 text-xs text-gray-600",children:[r||"-"," / node"]}),(0,a.jsx)("td",{className:"p-3 w-2/3",children:(0,a.jsx)("div",{className:"flex items-center gap-3",children:(0,a.jsxs)("div",{className:"flex-1 bg-gray-100 rounded-md h-5 flex overflow-hidden shadow-sm min-w-[100px] w-full",children:[l>0&&(0,a.jsx)("div",{style:{width:"".concat(l,"%")},className:"bg-yellow-500 h-full flex items-center justify-center text-white text-xs font-medium",children:l>15&&"".concat(s," used")}),t>0&&(0,a.jsx)("div",{style:{width:"".concat(t,"%")},className:"bg-green-700 h-full flex items-center justify-center text-white text-xs font-medium",children:t>15&&"".concat(e.gpu_free," free")})]})})})]},e.gpu_name)})})]})})})]})]})}):null}function I(e){let{contextName:s,gpusInContext:t,nodesInContext:n}=e,o=s.startsWith("ssh-"),[i,d]=(0,l.useState)([]),[m,u]=(0,l.useState)("$__all"),[x,h]=(0,l.useState)({from:"now-1h",to:"now"}),[g,p]=(0,l.useState)(!1),[f,y]=(0,l.useState)(!1);(0,l.useEffect)(()=>{(async()=>{y(await (0,c.TO)())})()},[]);let j=(0,l.useCallback)(async()=>{if(f){p(!0);try{let e=(0,c.ki)(),t="in-cluster"===s?"^$":s,a="query="+encodeURIComponent('group by (node) (DCGM_FI_DEV_GPU_TEMP{cluster=~"'.concat(t,'"} or label_replace(amd_gpu_gfx_activity{cluster=~"').concat(t,'"}, "node", "$1", "hostname", "(.*)"))')),l="/api/datasources/proxy/1/api/v1/query?".concat(a);try{let s=await fetch("".concat(e).concat(l),{method:"GET",credentials:"include",headers:{Accept:"application/json"}});if(s.ok){let e=await s.json();if(e.data&&e.data.result&&e.data.result.length>0){let s=e.data.result.map(e=>e.metric.node).filter(Boolean).sort();d(s),console.log("Successfully fetched hosts for cluster ".concat(t||"in-cluster",":"),s)}else console.log("No nodes found for this cluster"),d([])}else console.log("HTTP ".concat(s.status," from ").concat(l,": ").concat(s.statusText)),d([])}catch(e){console.log("Failed to fetch from ".concat(l,":"),e),d([])}}catch(e){console.error("Error fetching available hosts:",e),d([])}finally{p(!1)}}},[f,s]);(0,l.useEffect)(()=>{f&&n&&n.length>0&&j()},[n,f,j]);let b=e=>{let t=(0,c.ki)(),a="in-cluster"===s?"^$":s;return"".concat(t,"/d-solo/skypilot-dcgm-cluster-dashboard/skypilot-dcgm-kubernetes-cluster-dashboard?orgId=1&timezone=browser&var-datasource=prometheus&var-host=").concat(encodeURIComponent(m),"&var-gpu=$__all&var-cluster=").concat(encodeURIComponent(a),"&refresh=5s&theme=light&from=").concat(encodeURIComponent(x.from),"&to=").concat(encodeURIComponent(x.to),"&panelId=").concat(e,"&__feature.dashboardSceneSolo")},N=e=>{h({"15m":{from:"now-15m",to:"now"},"1h":{from:"now-1h",to:"now"},"6h":{from:"now-6h",to:"now"},"24h":{from:"now-24h",to:"now"},"7d":{from:"now-7d",to:"now"}}[e])};return(0,a.jsx)("div",{className:"mb-4",children:(0,a.jsx)("div",{className:"rounded-lg border bg-card text-card-foreground shadow-sm h-full",children:(0,a.jsxs)("div",{className:"p-5",children:[(0,a.jsx)("div",{className:"flex items-center justify-between mb-4",children:(0,a.jsx)("h4",{className:"text-lg font-semibold",children:"Available GPUs"})}),(0,a.jsx)("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mb-6",children:t.map(e=>{let s=e.gpu_total-e.gpu_free,t=e.gpu_total>0?e.gpu_free/e.gpu_total*100:0,l=e.gpu_total>0?s/e.gpu_total*100:0;return(0,a.jsxs)("div",{className:"p-3 bg-gray-50 rounded-md border border-gray-200 shadow-sm",children:[(0,a.jsxs)("div",{className:"flex justify-between items-center mb-1.5 flex-wrap",children:[(0,a.jsxs)("div",{className:"font-medium text-gray-800 text-sm",children:[e.gpu_name,(0,a.jsxs)("span",{className:"text-xs text-gray-500 ml-2",children:["(Requestable: ",e.gpu_requestable_qty_per_node," / node)"]})]}),(0,a.jsxs)("span",{className:"text-xs font-medium",children:[e.gpu_free," free / ",e.gpu_total," total"]})]}),(0,a.jsxs)("div",{className:"w-full bg-gray-100 rounded-md h-4 flex overflow-hidden shadow-sm",children:[l>0&&(0,a.jsx)("div",{style:{width:"".concat(l,"%")},className:"bg-yellow-500 h-full flex items-center justify-center text-white text-xs",children:l>15&&"".concat(s," used")}),t>0&&(0,a.jsx)("div",{style:{width:"".concat(t,"%")},className:"bg-green-700 h-full flex items-center justify-center text-white text-xs",children:t>15&&"".concat(e.gpu_free," free")})]})]},e.gpu_name)})}),n&&n.length>0&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("h4",{className:"text-lg font-semibold mb-4",children:"Nodes"}),(0,a.jsx)("div",{className:"overflow-x-auto rounded-md border border-gray-200 shadow-sm",children:(0,a.jsxs)("table",{className:"min-w-full text-sm",children:[(0,a.jsx)("thead",{className:"bg-gray-100",children:(0,a.jsxs)("tr",{children:[(0,a.jsx)("th",{className:"p-3 text-left font-medium text-gray-600",children:"Node"}),(0,a.jsx)("th",{className:"p-3 text-left font-medium text-gray-600",children:"IP Address"}),(0,a.jsx)("th",{className:"p-3 text-left font-medium text-gray-600",children:"GPU"}),(0,a.jsx)("th",{className:"p-3 text-right font-medium text-gray-600",children:"Availability"})]})}),(0,a.jsx)("tbody",{className:"bg-white divide-y divide-gray-200",children:n.map((e,s)=>(0,a.jsxs)("tr",{className:"hover:bg-gray-50",children:[(0,a.jsx)("td",{className:"p-3 whitespace-nowrap text-gray-700",children:e.node_name}),(0,a.jsx)("td",{className:"p-3 whitespace-nowrap text-gray-700",children:e.ip_address||"-"}),(0,a.jsx)("td",{className:"p-3 whitespace-nowrap text-gray-700",children:e.gpu_name}),(0,a.jsx)("td",{className:"p-3 whitespace-nowrap text-right text-gray-700",children:"".concat(e.gpu_free," of ").concat(e.gpu_total," free")})]},"".concat(e.node_name,"-").concat(s)))})]})})]}),f&&t&&t.length>0&&!o&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("h4",{className:"text-lg font-semibold mb-4 mt-6",children:"GPU Metrics"}),(0,a.jsxs)("div",{className:"mb-4 p-4 bg-gray-50 rounded-md border border-gray-200",children:[(0,a.jsxs)("div",{className:"flex flex-col sm:flex-row gap-4 items-start sm:items-center",children:[n&&n.length>0&&(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)("label",{htmlFor:"host-select",className:"text-sm font-medium text-gray-700 whitespace-nowrap",children:"Node:"}),(0,a.jsxs)("select",{id:"host-select",value:m,onChange:e=>{u(e.target.value)},disabled:g,className:"px-3 py-1 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-sky-blue focus:border-transparent",children:[(0,a.jsx)("option",{value:"$__all",children:"All Nodes"}),i.map(e=>(0,a.jsx)("option",{value:e,children:e},e))]}),g&&(0,a.jsx)("div",{className:"ml-2",children:(0,a.jsx)(r.Z,{size:16})})]}),(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)("label",{className:"text-sm font-medium text-gray-700 whitespace-nowrap",children:"Time Range:"}),(0,a.jsx)("div",{className:"flex gap-1",children:[{label:"15m",value:"15m"},{label:"1h",value:"1h"},{label:"6h",value:"6h"},{label:"24h",value:"24h"},{label:"7d",value:"7d"}].map(e=>(0,a.jsx)("button",{onClick:()=>N(e.value),className:"px-2 py-1 text-xs font-medium rounded border transition-colors ".concat(x.from==="now-".concat(e.value)&&"now"===x.to?"bg-sky-blue text-white border-sky-blue":"bg-white text-gray-600 border-gray-300 hover:bg-gray-50"),children:e.label},e.value))})]})]}),(0,a.jsx)("div",{className:"mt-2 text-xs text-gray-500",children:n&&n.length>0?(0,a.jsxs)(a.Fragment,{children:["Showing:"," ","$__all"===m?"All nodes":m," ","• Time: ",x.from," to ",x.to,i.length>0&&(0,a.jsxs)("span",{children:[" ","• ",i.length," nodes available"]})]}):(0,a.jsxs)(a.Fragment,{children:["Cluster:"," ",o?s.replace(/^ssh-/,""):s," ","• Time: ",x.from," to ",x.to," • Showing metrics for all nodes in cluster"]})})]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 lg:grid-cols-3 gap-4",children:[(0,a.jsx)("div",{className:"bg-white rounded-md border border-gray-200 shadow-sm",children:(0,a.jsx)("div",{className:"p-2",children:(0,a.jsx)("iframe",{src:b("6"),width:"100%",height:"400",frameBorder:"0",title:"GPU Utilization",className:"rounded"},"gpu-util-".concat(m,"-").concat(x.from,"-").concat(x.to))})}),(0,a.jsx)("div",{className:"bg-white rounded-md border border-gray-200 shadow-sm",children:(0,a.jsx)("div",{className:"p-2",children:(0,a.jsx)("iframe",{src:b("18"),width:"100%",height:"400",frameBorder:"0",title:"GPU Memory",className:"rounded"},"gpu-memory-".concat(m,"-").concat(x.from,"-").concat(x.to))})}),(0,a.jsx)("div",{className:"bg-white rounded-md border border-gray-200 shadow-sm",children:(0,a.jsx)("div",{className:"p-2",children:(0,a.jsx)("iframe",{src:b("10"),width:"100%",height:"400",frameBorder:"0",title:"GPU Power Consumption",className:"rounded"},"gpu-power-".concat(m,"-").concat(x.from,"-").concat(x.to))})}),(0,a.jsx)("div",{className:"bg-white rounded-md border border-gray-200 shadow-sm",children:(0,a.jsx)("div",{className:"p-2",children:(0,a.jsx)("iframe",{src:b("12"),width:"100%",height:"400",frameBorder:"0",title:"GPU Temperature",className:"rounded"},"gpu-temp-".concat(m,"-").concat(x.from,"-").concat(x.to))})}),(0,a.jsx)("div",{className:"bg-white rounded-md border border-gray-200 shadow-sm",children:(0,a.jsx)("div",{className:"p-2",children:(0,a.jsx)("iframe",{src:b("22"),width:"100%",height:"400",frameBorder:"0",title:"CPU Utilization",className:"rounded"},"cpu-util-".concat(m,"-").concat(x.from,"-").concat(x.to))})}),(0,a.jsx)("div",{className:"bg-white rounded-md border border-gray-200 shadow-sm",children:(0,a.jsx)("div",{className:"p-2",children:(0,a.jsx)("iframe",{src:b("21"),width:"100%",height:"400",frameBorder:"0",title:"Memory Utilization",className:"rounded"},"memory-util-".concat(m,"-").concat(x.from,"-").concat(x.to))})})]})]})]})})})}function H(e){var s;let{poolName:t,gpusInContext:i,nodesInContext:d,handleDeploySSHPool:c,handleEditSSHPool:m,handleDeleteSSHPool:u,poolConfig:x}=e,[f,y]=(0,l.useState)(null),[j,b]=(0,l.useState)(!0),[N,v]=(0,l.useState)({isOpen:!1,action:null,loading:!1}),[w,S]=(0,l.useState)({isOpen:!1,logs:"",isStreaming:!1,deploymentComplete:!1,deploymentSuccess:!1,requestId:null});(0,l.useEffect)(()=>{(async()=>{try{b(!0);let e=await (0,h.IS)(t);y(e)}catch(e){console.error("Failed to fetch SSH Node Pool status:",e),y({pool_name:t,status:"Error",reason:"Failed to fetch status"})}finally{b(!1)}})()},[t]);let{deployDisabled:_}=(()=>{if(!f)return{deployDisabled:!0};let e=f.status;return"Ready"===e?{deployDisabled:!0}:"Error"===e?{deployDisabled:!0}:{deployDisabled:!1}})(),C=async()=>{v({...N,loading:!0});try{if("deploy"===N.action){v({isOpen:!1,action:null,loading:!1}),S({isOpen:!0,logs:"",isStreaming:!0,deploymentComplete:!1,deploymentSuccess:!1,requestId:null});try{let e=(await c(t)).request_id;S(s=>({...s,requestId:e}));let s=new AbortController;await (0,h.wJ)({requestId:e,signal:s.signal,onNewLog:e=>{S(s=>({...s,logs:s.logs+e}))}}),S(e=>({...e,isStreaming:!1,deploymentComplete:!0,deploymentSuccess:!0})),setTimeout(async()=>{(async()=>{try{let e=await (0,h.IS)(t);y(e)}catch(e){console.error("Failed to fetch SSH Node Pool status after deployment:",e)}})()},1e3)}catch(e){console.error("Deployment failed:",e),S(s=>({...s,isStreaming:!1,deploymentComplete:!0,deploymentSuccess:!1,logs:s.logs+"\nDeployment failed: ".concat(e.message)}))}}else if("delete"===N.action){v({isOpen:!1,action:null,loading:!1}),S({isOpen:!0,logs:"",isStreaming:!0,deploymentComplete:!1,deploymentSuccess:!1,requestId:null});try{let e=(await (0,h.ez)(t)).request_id;S(s=>({...s,requestId:e})),e&&await (0,h.mF)({requestId:e,signal:null,onNewLog:e=>{S(s=>({...s,logs:s.logs+e}))},operationType:"down"}),await u(t),S(e=>({...e,isStreaming:!1,deploymentComplete:!0,deploymentSuccess:!0,logs:e.logs+"\nSSH Node Pool teardown completed successfully."}))}catch(e){console.error("Down operation failed:",e),S(s=>({...s,isStreaming:!1,deploymentComplete:!0,deploymentSuccess:!1,logs:s.logs+"\nTeardown failed: ".concat(e.message)}))}}}catch(e){console.error("Action failed:",e),v({...N,loading:!1})}},k=()=>{v({isOpen:!1,action:null,loading:!1})},P=()=>{S({isOpen:!1,logs:"",isStreaming:!1,deploymentComplete:!1,deploymentSuccess:!1,requestId:null}),w.deploymentComplete&&setTimeout(()=>{(async()=>{try{let e=await (0,h.IS)(t);y(e)}catch(e){console.error("Failed to refresh status:",e)}})()},1e3)},U="deploy"===N.action?{title:"Deploy SSH Node Pool",description:'Are you sure you want to deploy SSH Node Pool "'.concat(t,'"?'),details:["• Set up SkyPilot runtime on the configured SSH hosts","• Install required components and dependencies","• Make the node pool available for workloads","","This process may take a few minutes to complete."]}:{title:"Delete SSH Node Pool",description:'Are you sure you want to delete SSH Node Pool "'.concat(t,'"?'),details:["• Clean up any deployed resources","• Remove the SSH Node Pool configuration"]};return(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"mb-6",children:(0,a.jsxs)("div",{className:"rounded-lg border bg-card text-card-foreground shadow-sm",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between px-4 pt-4",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold",children:"SSH Node Pool Details"}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsxs)("button",{className:"px-3 py-1 text-sm border rounded flex items-center ".concat(_?"border-gray-300 bg-gray-100 text-gray-400 cursor-not-allowed":"border-green-300 bg-green-50 text-green-700 hover:bg-green-100"),onClick:_?void 0:()=>{v({isOpen:!0,action:"deploy",loading:!1})},disabled:_,children:[(0,a.jsx)(n.Z,{className:"w-4 h-4 mr-2"}),"Deploy"]}),(0,a.jsxs)("button",{className:"px-3 py-1 text-sm border border-gray-300 rounded hover:bg-gray-50 flex items-center text-red-600 hover:text-red-700",onClick:()=>{v({isOpen:!0,action:"delete",loading:!1})},children:[(0,a.jsx)(o.Z,{className:"w-4 h-4 mr-2"}),"Delete"]})]})]}),(0,a.jsx)("div",{className:"p-4",children:(0,a.jsxs)("div",{className:"grid grid-cols-2 gap-6",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"text-gray-600 font-medium text-base",children:"Pool Name"}),(0,a.jsx)("div",{className:"text-base mt-1",children:t})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"text-gray-600 font-medium text-base",children:"Nodes"}),(0,a.jsx)("div",{className:"text-base mt-1",children:d?d.length:0})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"text-gray-600 font-medium text-base",children:"Status"}),(0,a.jsx)("div",{className:"text-base mt-1",children:j?(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(r.Z,{size:16,className:"mr-2"}),(0,a.jsx)("span",{className:"text-gray-500",children:"Loading..."})]}):f?(0,a.jsx)(e=>{let{status:s,reason:t}=e,l="Ready"===s,r="Not Ready"===s?"Click Deploy to set up this node pool":t;return(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)("span",{className:"px-2 py-0.5 rounded text-xs font-medium ".concat(l?"bg-green-100":"bg-red-100"," ").concat(l?"text-green-800":"text-red-800"),children:s}),!l&&r&&(0,a.jsxs)("span",{className:"text-sm text-gray-600",children:["(",r,")"]})]})},{status:f.status,reason:f.reason}):(0,a.jsx)("span",{className:"text-gray-500",children:"Unknown"})})]})]})})]})}),(0,a.jsx)(I,{contextName:"ssh-".concat(t),gpusInContext:i,nodesInContext:d}),(0,a.jsx)(g.Vq,{open:N.isOpen,onOpenChange:k,children:(0,a.jsxs)(g.cZ,{className:"sm:max-w-md",children:[(0,a.jsxs)(g.fK,{className:"",children:[(0,a.jsx)(g.$N,{className:"",children:U.title}),(0,a.jsx)(g.Be,{className:"",children:U.description})]}),(0,a.jsx)("div",{className:"py-4",children:(0,a.jsxs)("div",{className:"text-sm text-gray-600 space-y-1",children:[(0,a.jsx)("p",{className:"font-medium mb-2",children:"This will:"}),U.details.map((e,s)=>(0,a.jsx)("p",{className:""===e?"pt-2":"",children:e},s))]})}),(0,a.jsxs)(g.cN,{className:"",children:[(0,a.jsx)(p.z,{variant:"outline",onClick:k,disabled:N.loading,className:"",children:"Cancel"}),(0,a.jsx)(p.z,{onClick:C,disabled:N.loading,className:"deploy"===N.action?"bg-green-600 hover:bg-green-700 text-white":"bg-red-600 hover:bg-red-700 text-white",children:N.loading?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(r.Z,{size:16,className:"mr-2"}),"deploy"===N.action?"Deploying...":"Deleting..."]}):"deploy"===N.action?"Deploy":"Delete"})]})]})}),(0,a.jsx)(g.Vq,{open:w.isOpen,onOpenChange:w.isStreaming?void 0:P,children:(0,a.jsxs)(g.cZ,{className:"sm:max-w-4xl max-h-[80vh]",children:[(0,a.jsxs)(g.fK,{className:"",children:[(0,a.jsxs)(g.$N,{className:"",children:["Deploying SSH Node Pool: ",t]}),(0,a.jsx)(g.Be,{className:"",children:w.isStreaming?"Deployment in progress. Do not close this dialog.":w.deploymentSuccess?"Deployment completed successfully!":"Deployment completed with errors."})]}),(0,a.jsx)("div",{className:"py-4",children:(0,a.jsxs)("div",{className:"bg-black text-green-400 p-4 rounded-md font-mono text-sm max-h-96 overflow-y-auto",children:[(0,a.jsx)("pre",{className:"whitespace-pre-wrap",children:(s=w.logs)?s.split("\n").map(e=>(e=e.replace(/\x1b\[[0-9;]*m/g,"")).match(/^D \d{2}-\d{2} \d{2}:\d{2}:\d{2}/)?null:e=(e=e.replace(/├──/g,"├─")).replace(/└──/g,"└─")).filter(e=>null!==e&&""!==e.trim()).join("\n"):""}),w.isStreaming&&(0,a.jsxs)("div",{className:"flex items-center mt-2",children:[(0,a.jsx)(r.Z,{size:16,className:"mr-2 text-green-400"}),(0,a.jsx)("span",{className:"text-green-400",children:"Streaming logs..."})]})]})}),(0,a.jsx)(g.cN,{className:"",children:(0,a.jsx)(p.z,{onClick:P,disabled:w.isStreaming,className:w.deploymentSuccess?"bg-green-600 hover:bg-green-700 text-white":w.deploymentComplete&&!w.deploymentSuccess?"bg-red-600 hover:bg-red-700 text-white":"bg-gray-600 hover:bg-gray-700 text-white",children:w.isStreaming?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(r.Z,{size:16,className:"mr-2"}),"Deploying..."]}):"Close"})})]})})]})}function E(){let[e,s]=(0,l.useState)(!0),[t,n]=(0,l.useState)(!0),[o,c]=(0,l.useState)(!0),g=l.useRef(null),p=(0,d.X)(),[f,y]=(0,l.useState)(!1),[j,w]=(0,l.useState)(!1),_=(0,S.useRouter)(),[k,U]=(0,l.useState)([]),[E,F]=(0,l.useState)([]),[R,z]=(0,l.useState)([]),[A,q]=(0,l.useState)([]),[M,Z]=(0,l.useState)([]),[O,L]=(0,l.useState)(0),[T,G]=(0,l.useState)(0),[W,B]=(0,l.useState)({}),[K,$]=(0,l.useState)({}),[J,V]=(0,l.useState)(!1),[X,Y]=(0,l.useState)(null),[Q,ee]=(0,l.useState)(!1),[es,et]=(0,l.useState)(!0),[ea,el]=(0,l.useState)({}),[er,en]=(0,l.useState)(null),eo=l.useCallback(async function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{showLoadingIndicators:!0},{showLoadingIndicators:t=!0,forceRefresh:a=!1}=e;t&&(s(!0),n(!0),ee(!0),et(!0));try{async function l(e){await ei(e),await em(e)}await Promise.all([l(a),ec(a),ed(a)])}catch(e){console.error("Error in fetchData:",e),U([]),F([]),z([]),q([]),B({}),y(!0),s(!1),Z([]),L(0),G(0),w(!0),$({}),ee(!1),el({}),et(!1)}finally{t&&(s(!1),n(!1),ee(!1),et(!1)),o&&t&&c(!1)}},[o]),ei=async e=>{try{let t=e?await (0,m.Cu)():await N.default.get(m.Cu);if(t){let{allContextNames:e,allGPUs:a,perContextGPUs:l,perNodeGPUs:r,contextStats:n}=t;U(e||[]),F(a||[]),z(l||[]),q(r||[]),B(n||{}),y(!0),s(!1)}else null===t&&(U([]),F([]),z([]),q([]),B({}),y(!0),s(!1))}catch(e){console.error("Error in fetchKubernetesData:",e),U([]),F([]),z([]),q([]),B({}),y(!0),s(!1)}},ed=async e=>{try{let s=e?await (0,x.getManagedJobs)({allUsers:!0}):await N.default.get(x.getManagedJobs,[{allUsers:!0}]),t=(null==s?void 0:s.jobs)||[];el(await (0,m.R8)(t)),et(!1)}catch(e){console.error("Error in fetchManagedJobsData:",e),el({}),et(!1)}},ec=async e=>{try{let s=e?await (0,m.ef)():await N.default.get(m.ef,[e]);s?(Z(s.clouds||[]),L(s.totalClouds||0),G(s.enabledClouds||0),w(!0)):null===s&&(Z([]),L(0),G(0),w(!0))}catch(e){console.error("Error in fetchCloudData:",e),Z([]),L(0),G(0),w(!0)}},em=async e=>{try{let s=e?await (0,h.It)():await N.default.get(h.It);$(s),ee(!1)}catch(e){console.error("Failed to fetch SSH Node Pools:",e),$({}),ee(!1)}},eu=(e,s)=>{Y({name:e,config:s}),V(!0)},ex=async e=>{try{await (0,h.MV)(e),await em(),en(null),_.push("/infra")}catch(e){throw console.error("Failed to delete SSH Node Pool:",e),e}},eh=async e=>{try{await (0,h._x)(e)}catch(e){throw console.error("Failed to deploy SSH Node Pool:",e),e}},eg=async(e,s)=>{ee(!0);try{let t={...K};t[e]=s,await (0,h.Ri)(t),await em(),V(!1)}catch(e){console.error("Failed to save SSH Node Pool:",e),alert("Failed to save SSH Node Pool. Please try again.")}finally{ee(!1)}};(0,l.useEffect)(()=>{g.current=eo},[eo]),(0,l.useEffect)(()=>{(async()=>{await v.ZP.preloadForPage("infra"),eo({showLoadingIndicators:!0})})()},[eo]),(0,l.useEffect)(()=>{let e=!0,s=setInterval(()=>{e&&g.current&&g.current({showLoadingIndicators:!1})},P);return()=>{e=!1,clearInterval(s)}},[]),(0,l.useEffect)(()=>()=>{y(!1),w(!1),ee(!1),c(!0),et(!1)},[]);let ep=()=>{N.default.invalidate(u.getClusters),N.default.invalidate(x.getManagedJobs,[{allUsers:!0}]),N.default.invalidate(m.Cu),N.default.invalidate(m.ef,[!1]),N.default.invalidate(h.It),g.current&&g.current({showLoadingIndicators:!0,forceRefresh:!0})};(0,l.useEffect)(()=>{let e=e=>{(e.metaKey||e.ctrlKey)&&"r"===e.key&&(e.preventDefault(),ep())};return window.addEventListener("keydown",e),()=>{window.removeEventListener("keydown",e)}},[]),(E||[]).length,(E||[]).reduce((e,s)=>e+s.gpu_total,0),(E||[]).reduce((e,s)=>e+s.gpu_free,0);let ef=l.useMemo(()=>R?R.reduce((e,s)=>{let{context:t}=s;return e[t]||(e[t]=[]),e[t].push(s),e},{}):{},[R]),ey=l.useMemo(()=>k&&Array.isArray(k)?k.filter(e=>e.startsWith("ssh-")):[],[k]),ej=l.useMemo(()=>k&&Array.isArray(k)?k.filter(e=>!e.startsWith("ssh-")):[],[k]),eb=l.useMemo(()=>{if(!R||!E)return[];let e=new Set;return R.forEach(s=>{s.context.startsWith("ssh-")&&e.add(s.gpu_name)}),E.filter(s=>e.has(s.gpu_name))},[E,R]),eN=l.useMemo(()=>{if(!R||!E)return[];let e=new Set;return R.forEach(s=>{s.context.startsWith("ssh-")||e.add(s.gpu_name)}),E.filter(s=>e.has(s.gpu_name))},[E,R]),ev=l.useMemo(()=>A?A.reduce((e,s)=>{let{context:t}=s;return e[t]||(e[t]=[]),e[t].push(s),e},{}):{},[A]);(0,l.useEffect)(()=>{_.isReady&&_.query.context&&en(decodeURIComponent(Array.isArray(_.query.context)?_.query.context[0]:_.query.context))},[_.isReady,_.query.context]);let ew=e=>{en(e),_.push("/infra/".concat(encodeURIComponent(e)))},eS=s=>{let t=ef[s]||[],l=ev[s]||[];if(e&&!f)return(0,a.jsxs)("div",{className:"flex flex-col items-center justify-center h-64",children:[(0,a.jsx)(r.Z,{size:32,className:"mb-4"}),(0,a.jsx)("span",{className:"text-gray-500 text-lg",children:"Loading Context..."})]});if(s.startsWith("ssh-")){let e=s.replace(/^ssh-/,"");return(0,a.jsx)(H,{poolName:e,gpusInContext:t,nodesInContext:l,handleDeploySSHPool:eh,handleEditSSHPool:eu,handleDeleteSSHPool:ex,poolConfig:K[e]})}return(0,a.jsx)(I,{contextName:s,gpusInContext:t,nodesInContext:l})},e_=()=>t&&(!M||0===M.length)?(0,a.jsx)("div",{className:"rounded-lg border bg-card text-card-foreground shadow-sm mb-6",children:(0,a.jsxs)("div",{className:"p-5",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold mb-4",children:"Cloud"}),(0,a.jsxs)("div",{className:"flex items-center justify-center py-6",children:[(0,a.jsx)(r.Z,{size:24,className:"mr-3"}),(0,a.jsx)("span",{className:"text-gray-500",children:"Loading Cloud..."})]})]})}):(0,a.jsx)("div",{className:"rounded-lg border bg-card text-card-foreground shadow-sm mb-6",children:(0,a.jsxs)("div",{className:"p-5",children:[(0,a.jsxs)("div",{className:"flex items-center mb-4",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold",children:"Cloud"}),(0,a.jsxs)("span",{className:"ml-2 px-2 py-0.5 bg-blue-100 text-blue-800 rounded-full text-xs font-medium",children:[T," of ",O," enabled"]})]}),M&&0!==M.length?(0,a.jsx)("div",{className:"overflow-x-auto rounded-md border border-gray-200 shadow-sm bg-white",children:(0,a.jsxs)("table",{className:"min-w-full text-sm",children:[(0,a.jsx)("thead",{className:"bg-gray-50",children:(0,a.jsxs)("tr",{children:[(0,a.jsx)("th",{className:"p-3 text-left font-medium text-gray-600 w-32",children:"Cloud"}),(0,a.jsx)("th",{className:"p-3 text-left font-medium text-gray-600 w-24",children:"Clusters"}),(0,a.jsx)("th",{className:"p-3 text-left font-medium text-gray-600 w-24",children:"Jobs"})]})}),(0,a.jsx)("tbody",{className:"bg-white divide-y divide-gray-200",children:M.map(e=>{let s=j&&void 0!==e.clusters&&void 0!==e.jobs;return(0,a.jsxs)("tr",{className:"hover:bg-gray-50",children:[(0,a.jsx)("td",{className:"p-3 font-medium text-gray-700",children:e.name}),(0,a.jsx)("td",{className:"p-3",children:s?e.clusters>0?(0,a.jsx)("span",{className:"px-2 py-0.5 bg-blue-100 text-blue-800 rounded text-xs font-medium",children:e.clusters}):(0,a.jsx)("span",{className:"px-2 py-0.5 bg-gray-100 text-gray-500 rounded text-xs font-medium",children:"0"}):(0,a.jsx)("div",{className:"flex items-center justify-center",children:(0,a.jsx)(r.Z,{size:16})})}),(0,a.jsx)("td",{className:"p-3",children:s?e.jobs>0?(0,a.jsx)("span",{className:"px-2 py-0.5 bg-green-100 text-green-800 rounded text-xs font-medium",children:e.jobs}):(0,a.jsx)("span",{className:"px-2 py-0.5 bg-gray-100 text-gray-500 rounded text-xs font-medium",children:"0"}):(0,a.jsx)("div",{className:"flex items-center justify-center",children:(0,a.jsx)(r.Z,{size:16})})})]},e.name)})})]})}):(0,a.jsx)("p",{className:"text-sm text-gray-500",children:"No enabled clouds available."})]})}),eC=()=>(0,a.jsx)(D,{title:"SSH Node Pool",isLoading:e,isDataLoaded:f,contexts:ey,gpus:eb,groupedPerContextGPUs:ef,groupedPerNodeGPUs:ev,handleContextClick:ew,contextStats:W,jobsData:ea,isJobsDataLoading:es,isSSH:!0,actionButton:null}),ek=()=>(0,a.jsx)(D,{title:"Kubernetes",isLoading:e,isDataLoaded:f,contexts:ej,gpus:eN,groupedPerContextGPUs:ef,groupedPerNodeGPUs:ev,handleContextClick:ew,contextStats:W,jobsData:ea,isJobsDataLoading:es,isSSH:!1}),eP=e||t;return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"flex items-center justify-between mb-4 h-5",children:[(0,a.jsxs)("div",{className:"text-base flex items-center",children:[(0,a.jsx)(C(),{href:"/infra",className:"text-sky-blue hover:underline ".concat(er?"":"cursor-default"),children:"Infrastructure"}),er&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{className:"mx-2 text-gray-500",children:"›"}),er.startsWith("ssh-")?(0,a.jsx)(C(),{href:"/infra",className:"text-sky-blue hover:underline cursor-pointer",children:"SSH Node Pool"}):(0,a.jsx)(C(),{href:"/infra",className:"text-sky-blue hover:underline cursor-pointer",children:"Kubernetes"}),(0,a.jsx)("span",{className:"mx-2 text-gray-500",children:"›"}),(0,a.jsx)("span",{className:"text-sky-blue",children:er.startsWith("ssh-")?er.replace(/^ssh-/,""):er})]})]}),(0,a.jsxs)("div",{className:"flex items-center",children:[eP&&(0,a.jsxs)("div",{className:"flex items-center mr-2",children:[(0,a.jsx)(r.Z,{size:15,className:"mt-0"}),(0,a.jsx)("span",{className:"ml-2 text-gray-500",children:"Loading..."})]}),(0,a.jsxs)("button",{onClick:ep,disabled:eP,className:"text-sky-blue hover:text-sky-blue-bright flex items-center",children:[(0,a.jsx)(i.Z,{className:"h-4 w-4 mr-1.5"}),!p&&"Refresh"]})]})]}),(()=>{if(er)return e&&!f?(0,a.jsxs)("div",{className:"flex flex-col items-center justify-center h-64",children:[(0,a.jsx)(r.Z,{size:32,className:"mb-4"}),(0,a.jsx)("span",{className:"text-gray-500 text-lg",children:"Loading Context..."})]}):eS(er);let s=[];s.push({name:"Kubernetes",render:ek,hasActivity:ej.length>0,priority:1}),s.push({name:"Cloud",render:e_,hasActivity:T>0,priority:2}),s.push({name:"SSH Node Pool",render:eC,hasActivity:ey.length>0&&function(e){let s=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return e.some(e=>{let t=W[s?"ssh/".concat(e.replace(/^ssh-/,"")):"kubernetes/".concat(e)]||{clusters:0,jobs:0};return t.clusters>0||t.jobs>0})}(ey,!0),priority:3});let t=s.sort((e,s)=>e.hasActivity!==s.hasActivity?e.hasActivity?-1:1:e.priority-s.priority);return(0,a.jsx)(a.Fragment,{children:t.map((e,s)=>(0,a.jsx)(l.Fragment,{children:e.render()},s))})})(),(0,a.jsx)(b,{isOpen:J,onClose:()=>V(!1),onSave:eg,poolData:X,isLoading:Q})]})}},42557:function(e,s,t){t.d(s,{I:function(){return n}});var a=t(85893),l=t(67294),r=t(32350);let n=l.forwardRef((e,s)=>{let{className:t,type:l,...n}=e;return(0,a.jsx)("input",{type:l,className:(0,r.cn)("flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",t),ref:s,...n})});n.displayName="Input"},29749:function(e,s,t){t.d(s,{_:function(){return c}});var a=t(85893),l=t(67294),r=t(75320),n=l.forwardRef((e,s)=>(0,a.jsx)(r.WV.label,{...e,ref:s,onMouseDown:s=>{s.target.closest("button, input, select, textarea")||(e.onMouseDown?.(s),!s.defaultPrevented&&s.detail>1&&s.preventDefault())}}));n.displayName="Label";var o=t(12003),i=t(32350);let d=(0,o.j)("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"),c=l.forwardRef((e,s)=>{let{className:t,...l}=e;return(0,a.jsx)(n,{ref:s,className:(0,i.cn)(d(),t),...l})});c.displayName=n.displayName},69123:function(e,s,t){t.d(s,{g:function(){return n}});var a=t(85893),l=t(67294),r=t(32350);let n=l.forwardRef((e,s)=>{let{className:t,...l}=e;return(0,a.jsx)("textarea",{className:(0,r.cn)("flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",t),ref:s,...l})});n.displayName="Textarea"},17853:function(e,s,t){t.d(s,{TO:function(){return r},ki:function(){return n}});let a=null,l=null,r=async()=>null!==a?a:l||(l=(async()=>{try{let e="".concat(window.location.origin,"/grafana"),s=await fetch("".concat(e,"/api/health"),{method:"GET",credentials:"include",headers:{Accept:"application/json"},signal:AbortSignal.timeout(5e3)});return 200==s.status}catch(e){return console.debug("Grafana availability check failed:",e),a=!1,!1}finally{l=null}})()),n=()=>"".concat(window.location.origin,"/grafana")}}]);
@@ -1 +1 @@
1
- !function(){"use strict";var e,t,n,r,c,o,u,a,f,i={},d={};function s(e){var t=d[e];if(void 0!==t)return t.exports;var n=d[e]={exports:{}},r=!0;try{i[e](n,n.exports,s),r=!1}finally{r&&delete d[e]}return n.exports}s.m=i,e=[],s.O=function(t,n,r,c){if(n){c=c||0;for(var o=e.length;o>0&&e[o-1][2]>c;o--)e[o]=e[o-1];e[o]=[n,r,c];return}for(var u=1/0,o=0;o<e.length;o++){for(var n=e[o][0],r=e[o][1],c=e[o][2],a=!0,f=0;f<n.length;f++)u>=c&&Object.keys(s.O).every(function(e){return s.O[e](n[f])})?n.splice(f--,1):(a=!1,c<u&&(u=c));if(a){e.splice(o--,1);var i=r();void 0!==i&&(t=i)}}return t},s.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return s.d(t,{a:t}),t},n=Object.getPrototypeOf?function(e){return Object.getPrototypeOf(e)}:function(e){return e.__proto__},s.t=function(e,r){if(1&r&&(e=this(e)),8&r||"object"==typeof e&&e&&(4&r&&e.__esModule||16&r&&"function"==typeof e.then))return e;var c=Object.create(null);s.r(c);var o={};t=t||[null,n({}),n([]),n(n)];for(var u=2&r&&e;"object"==typeof u&&!~t.indexOf(u);u=n(u))Object.getOwnPropertyNames(u).forEach(function(t){o[t]=function(){return e[t]}});return o.default=function(){return e},s.d(c,o),c},s.d=function(e,t){for(var n in t)s.o(t,n)&&!s.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},s.f={},s.e=function(e){return Promise.all(Object.keys(s.f).reduce(function(t,n){return s.f[n](e,t),t},[]))},s.u=function(e){return 2350===e?"static/chunks/2350.fab69e61bac57b23.js":7325===e?"static/chunks/7325.b4bc99ce0892dcd5.js":3937===e?"static/chunks/3937.210053269f121201.js":9025===e?"static/chunks/9025.c12318fb6a1a9093.js":3294===e?"static/chunks/3294.c80326aec9bfed40.js":649===e?"static/chunks/649.b9d7f7d10c1b8c53.js":7669===e?"static/chunks/7669.1f5d9a402bf5cc42.js":4045===e?"static/chunks/4045.b30465273dc5e468.js":4725===e?"static/chunks/4725.10f7a9a5d3ea8208.js":3785===e?"static/chunks/3785.4872a2f3aa489880.js":5339===e?"static/chunks/5339.3fda4a4010ff4e06.js":"static/chunks/"+e+"-"+({616:"3d59f75e2ccf9321",1121:"408ed10b2f9fce17",1141:"943efc7aff0f0c06",1272:"1ef0bf0237faccdb",1836:"37fede578e2da5f8",3015:"86cabed5d4669ad0",3850:"ff4a9a69d978632b",4676:"9da7fdbde90b5549",5739:"d67458fcb1386c92",6130:"2be46d70a38f1e82",6135:"4b4d5e824b7f9d3c",6601:"06114c982db410b6",6856:"6e2bc8a6fd0867af",6989:"01359c57e018caa4",6990:"08b2a1cae076a943",7411:"b15471acd2cba716",8969:"0487dfbf149d9e53",9037:"fa1737818d0a0969"})[e]+".js"},s.miniCssF=function(e){},s.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),s.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r={},c="_N_E:",s.l=function(e,t,n,o){if(r[e]){r[e].push(t);return}if(void 0!==n)for(var u,a,f=document.getElementsByTagName("script"),i=0;i<f.length;i++){var d=f[i];if(d.getAttribute("src")==e||d.getAttribute("data-webpack")==c+n){u=d;break}}u||(a=!0,(u=document.createElement("script")).charset="utf-8",u.timeout=120,s.nc&&u.setAttribute("nonce",s.nc),u.setAttribute("data-webpack",c+n),u.src=s.tu(e)),r[e]=[t];var b=function(t,n){u.onerror=u.onload=null,clearTimeout(l);var c=r[e];if(delete r[e],u.parentNode&&u.parentNode.removeChild(u),c&&c.forEach(function(e){return e(n)}),t)return t(n)},l=setTimeout(b.bind(null,void 0,{type:"timeout",target:u}),12e4);u.onerror=b.bind(null,u.onerror),u.onload=b.bind(null,u.onload),a&&document.head.appendChild(u)},s.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},s.tt=function(){return void 0===o&&(o={createScriptURL:function(e){return e}},"undefined"!=typeof trustedTypes&&trustedTypes.createPolicy&&(o=trustedTypes.createPolicy("nextjs#bundler",o))),o},s.tu=function(e){return s.tt().createScriptURL(e)},s.p="/dashboard/_next/",u={2272:0},s.f.j=function(e,t){var n=s.o(u,e)?u[e]:void 0;if(0!==n){if(n)t.push(n[2]);else if(2272!=e){var r=new Promise(function(t,r){n=u[e]=[t,r]});t.push(n[2]=r);var c=s.p+s.u(e),o=Error();s.l(c,function(t){if(s.o(u,e)&&(0!==(n=u[e])&&(u[e]=void 0),n)){var r=t&&("load"===t.type?"missing":t.type),c=t&&t.target&&t.target.src;o.message="Loading chunk "+e+" failed.\n("+r+": "+c+")",o.name="ChunkLoadError",o.type=r,o.request=c,n[1](o)}},"chunk-"+e,e)}else u[e]=0}},s.O.j=function(e){return 0===u[e]},a=function(e,t){var n,r,c=t[0],o=t[1],a=t[2],f=0;if(c.some(function(e){return 0!==u[e]})){for(n in o)s.o(o,n)&&(s.m[n]=o[n]);if(a)var i=a(s)}for(e&&e(t);f<c.length;f++)r=c[f],s.o(u,r)&&u[r]&&u[r][0](),u[r]=0;return s.O(i)},(f=self.webpackChunk_N_E=self.webpackChunk_N_E||[]).forEach(a.bind(null,0)),f.push=a.bind(null,f.push.bind(f)),s.nc=void 0}();
1
+ !function(){"use strict";var e,t,n,r,c,o,u,a,f,i={},d={};function s(e){var t=d[e];if(void 0!==t)return t.exports;var n=d[e]={exports:{}},r=!0;try{i[e](n,n.exports,s),r=!1}finally{r&&delete d[e]}return n.exports}s.m=i,e=[],s.O=function(t,n,r,c){if(n){c=c||0;for(var o=e.length;o>0&&e[o-1][2]>c;o--)e[o]=e[o-1];e[o]=[n,r,c];return}for(var u=1/0,o=0;o<e.length;o++){for(var n=e[o][0],r=e[o][1],c=e[o][2],a=!0,f=0;f<n.length;f++)u>=c&&Object.keys(s.O).every(function(e){return s.O[e](n[f])})?n.splice(f--,1):(a=!1,c<u&&(u=c));if(a){e.splice(o--,1);var i=r();void 0!==i&&(t=i)}}return t},s.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return s.d(t,{a:t}),t},n=Object.getPrototypeOf?function(e){return Object.getPrototypeOf(e)}:function(e){return e.__proto__},s.t=function(e,r){if(1&r&&(e=this(e)),8&r||"object"==typeof e&&e&&(4&r&&e.__esModule||16&r&&"function"==typeof e.then))return e;var c=Object.create(null);s.r(c);var o={};t=t||[null,n({}),n([]),n(n)];for(var u=2&r&&e;"object"==typeof u&&!~t.indexOf(u);u=n(u))Object.getOwnPropertyNames(u).forEach(function(t){o[t]=function(){return e[t]}});return o.default=function(){return e},s.d(c,o),c},s.d=function(e,t){for(var n in t)s.o(t,n)&&!s.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},s.f={},s.e=function(e){return Promise.all(Object.keys(s.f).reduce(function(t,n){return s.f[n](e,t),t},[]))},s.u=function(e){return 2350===e?"static/chunks/2350.fab69e61bac57b23.js":7325===e?"static/chunks/7325.b4bc99ce0892dcd5.js":3937===e?"static/chunks/3937.210053269f121201.js":9025===e?"static/chunks/9025.c12318fb6a1a9093.js":3294===e?"static/chunks/3294.ba6586f9755b0edb.js":649===e?"static/chunks/649.b9d7f7d10c1b8c53.js":7669===e?"static/chunks/7669.1f5d9a402bf5cc42.js":4045===e?"static/chunks/4045.b30465273dc5e468.js":4725===e?"static/chunks/4725.10f7a9a5d3ea8208.js":3785===e?"static/chunks/3785.4872a2f3aa489880.js":5339===e?"static/chunks/5339.3fda4a4010ff4e06.js":"static/chunks/"+e+"-"+({616:"3d59f75e2ccf9321",1121:"408ed10b2f9fce17",1141:"943efc7aff0f0c06",1272:"1ef0bf0237faccdb",1836:"37fede578e2da5f8",3015:"86cabed5d4669ad0",3850:"ff4a9a69d978632b",4676:"9da7fdbde90b5549",5739:"d67458fcb1386c92",6130:"2be46d70a38f1e82",6135:"4b4d5e824b7f9d3c",6601:"06114c982db410b6",6856:"6e2bc8a6fd0867af",6989:"01359c57e018caa4",6990:"08b2a1cae076a943",7411:"b15471acd2cba716",8969:"0487dfbf149d9e53",9037:"fa1737818d0a0969"})[e]+".js"},s.miniCssF=function(e){},s.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),s.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r={},c="_N_E:",s.l=function(e,t,n,o){if(r[e]){r[e].push(t);return}if(void 0!==n)for(var u,a,f=document.getElementsByTagName("script"),i=0;i<f.length;i++){var d=f[i];if(d.getAttribute("src")==e||d.getAttribute("data-webpack")==c+n){u=d;break}}u||(a=!0,(u=document.createElement("script")).charset="utf-8",u.timeout=120,s.nc&&u.setAttribute("nonce",s.nc),u.setAttribute("data-webpack",c+n),u.src=s.tu(e)),r[e]=[t];var b=function(t,n){u.onerror=u.onload=null,clearTimeout(l);var c=r[e];if(delete r[e],u.parentNode&&u.parentNode.removeChild(u),c&&c.forEach(function(e){return e(n)}),t)return t(n)},l=setTimeout(b.bind(null,void 0,{type:"timeout",target:u}),12e4);u.onerror=b.bind(null,u.onerror),u.onload=b.bind(null,u.onload),a&&document.head.appendChild(u)},s.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},s.tt=function(){return void 0===o&&(o={createScriptURL:function(e){return e}},"undefined"!=typeof trustedTypes&&trustedTypes.createPolicy&&(o=trustedTypes.createPolicy("nextjs#bundler",o))),o},s.tu=function(e){return s.tt().createScriptURL(e)},s.p="/dashboard/_next/",u={2272:0},s.f.j=function(e,t){var n=s.o(u,e)?u[e]:void 0;if(0!==n){if(n)t.push(n[2]);else if(2272!=e){var r=new Promise(function(t,r){n=u[e]=[t,r]});t.push(n[2]=r);var c=s.p+s.u(e),o=Error();s.l(c,function(t){if(s.o(u,e)&&(0!==(n=u[e])&&(u[e]=void 0),n)){var r=t&&("load"===t.type?"missing":t.type),c=t&&t.target&&t.target.src;o.message="Loading chunk "+e+" failed.\n("+r+": "+c+")",o.name="ChunkLoadError",o.type=r,o.request=c,n[1](o)}},"chunk-"+e,e)}else u[e]=0}},s.O.j=function(e){return 0===u[e]},a=function(e,t){var n,r,c=t[0],o=t[1],a=t[2],f=0;if(c.some(function(e){return 0!==u[e]})){for(n in o)s.o(o,n)&&(s.m[n]=o[n]);if(a)var i=a(s)}for(e&&e(t);f<c.length;f++)r=c[f],s.o(u,r)&&u[r]&&u[r][0](),u[r]=0;return s.O(i)},(f=self.webpackChunk_N_E=self.webpackChunk_N_E||[]).forEach(a.bind(null,0)),f.push=a.bind(null,f.push.bind(f)),s.nc=void 0}();
@@ -1 +1 @@
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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-d4fabc08788e14af.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-4b4d5e824b7f9d3c.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters/%5Bcluster%5D/%5Bjob%5D-1cbba24bd1bd35f8.js" defer=""></script><script src="/dashboard/_next/static/eWytLgin5zvayQw3Xk46m/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/eWytLgin5zvayQw3Xk46m/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters/[cluster]/[job]","query":{},"buildId":"eWytLgin5zvayQw3Xk46m","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-e8a0c4c3c6f408fb.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-4b4d5e824b7f9d3c.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters/%5Bcluster%5D/%5Bjob%5D-1cbba24bd1bd35f8.js" defer=""></script><script src="/dashboard/_next/static/DAiq7V2xJnO1LSfmunZl6/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/DAiq7V2xJnO1LSfmunZl6/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters/[cluster]/[job]","query":{},"buildId":"DAiq7V2xJnO1LSfmunZl6","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-d4fabc08788e14af.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/4676-9da7fdbde90b5549.js" defer=""></script><script src="/dashboard/_next/static/chunks/754-d0da8ab45f9509e9.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-0487dfbf149d9e53.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-08b2a1cae076a943.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-4b4d5e824b7f9d3c.js" defer=""></script><script src="/dashboard/_next/static/chunks/1121-408ed10b2f9fce17.js" defer=""></script><script src="/dashboard/_next/static/chunks/6856-6e2bc8a6fd0867af.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-06114c982db410b6.js" defer=""></script><script src="/dashboard/_next/static/chunks/3015-86cabed5d4669ad0.js" defer=""></script><script src="/dashboard/_next/static/chunks/9037-fa1737818d0a0969.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters/%5Bcluster%5D-0b4b35dc1dfe046c.js" defer=""></script><script src="/dashboard/_next/static/eWytLgin5zvayQw3Xk46m/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/eWytLgin5zvayQw3Xk46m/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters/[cluster]","query":{},"buildId":"eWytLgin5zvayQw3Xk46m","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-e8a0c4c3c6f408fb.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/4676-9da7fdbde90b5549.js" defer=""></script><script src="/dashboard/_next/static/chunks/754-d0da8ab45f9509e9.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-0487dfbf149d9e53.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-08b2a1cae076a943.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-4b4d5e824b7f9d3c.js" defer=""></script><script src="/dashboard/_next/static/chunks/1121-408ed10b2f9fce17.js" defer=""></script><script src="/dashboard/_next/static/chunks/6856-6e2bc8a6fd0867af.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-06114c982db410b6.js" defer=""></script><script src="/dashboard/_next/static/chunks/3015-86cabed5d4669ad0.js" defer=""></script><script src="/dashboard/_next/static/chunks/9037-fa1737818d0a0969.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters/%5Bcluster%5D-0b4b35dc1dfe046c.js" defer=""></script><script src="/dashboard/_next/static/DAiq7V2xJnO1LSfmunZl6/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/DAiq7V2xJnO1LSfmunZl6/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters/[cluster]","query":{},"buildId":"DAiq7V2xJnO1LSfmunZl6","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-d4fabc08788e14af.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters-469814d711d63b1b.js" defer=""></script><script src="/dashboard/_next/static/eWytLgin5zvayQw3Xk46m/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/eWytLgin5zvayQw3Xk46m/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters","query":{},"buildId":"eWytLgin5zvayQw3Xk46m","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-e8a0c4c3c6f408fb.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters-469814d711d63b1b.js" defer=""></script><script src="/dashboard/_next/static/DAiq7V2xJnO1LSfmunZl6/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/DAiq7V2xJnO1LSfmunZl6/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters","query":{},"buildId":"DAiq7V2xJnO1LSfmunZl6","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-d4fabc08788e14af.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/config-dfb9bf07b13045f4.js" defer=""></script><script src="/dashboard/_next/static/eWytLgin5zvayQw3Xk46m/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/eWytLgin5zvayQw3Xk46m/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/config","query":{},"buildId":"eWytLgin5zvayQw3Xk46m","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-e8a0c4c3c6f408fb.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/config-dfb9bf07b13045f4.js" defer=""></script><script src="/dashboard/_next/static/DAiq7V2xJnO1LSfmunZl6/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/DAiq7V2xJnO1LSfmunZl6/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/config","query":{},"buildId":"DAiq7V2xJnO1LSfmunZl6","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-d4fabc08788e14af.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/index-444f1804401f04ea.js" defer=""></script><script src="/dashboard/_next/static/eWytLgin5zvayQw3Xk46m/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/eWytLgin5zvayQw3Xk46m/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/","query":{},"buildId":"eWytLgin5zvayQw3Xk46m","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-e8a0c4c3c6f408fb.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/index-444f1804401f04ea.js" defer=""></script><script src="/dashboard/_next/static/DAiq7V2xJnO1LSfmunZl6/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/DAiq7V2xJnO1LSfmunZl6/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/","query":{},"buildId":"DAiq7V2xJnO1LSfmunZl6","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>