skypilot-nightly 1.0.0.dev20251002__py3-none-any.whl → 1.0.0.dev20251004__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.
- sky/__init__.py +2 -2
- sky/authentication.py +19 -109
- sky/backends/cloud_vm_ray_backend.py +42 -27
- sky/client/cli/command.py +1 -11
- sky/clouds/cudo.py +1 -1
- sky/clouds/kubernetes.py +7 -19
- sky/dashboard/out/404.html +1 -1
- sky/dashboard/out/_next/static/{16g0-hgEgk6Db72hpE8MY → KL03GEega4QqDqTOMtA_w}/_buildManifest.js +1 -1
- sky/dashboard/out/_next/static/chunks/3015-8d748834fcc60b46.js +1 -0
- sky/dashboard/out/_next/static/chunks/8969-66237729cdf9749e.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/{[job]-ad77b12fc736dca3.js → [job]-72794fc3fcdd517a.js} +1 -1
- sky/dashboard/out/_next/static/chunks/{webpack-7340bc0f0dd8ae74.js → webpack-3286453d56f3c0a0.js} +1 -1
- sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
- sky/dashboard/out/clusters/[cluster].html +1 -1
- sky/dashboard/out/clusters.html +1 -1
- sky/dashboard/out/config.html +1 -1
- sky/dashboard/out/index.html +1 -1
- sky/dashboard/out/infra/[context].html +1 -1
- sky/dashboard/out/infra.html +1 -1
- sky/dashboard/out/jobs/[job].html +1 -1
- sky/dashboard/out/jobs/pools/[pool].html +1 -1
- sky/dashboard/out/jobs.html +1 -1
- sky/dashboard/out/users.html +1 -1
- sky/dashboard/out/volumes.html +1 -1
- sky/dashboard/out/workspace/new.html +1 -1
- sky/dashboard/out/workspaces/[name].html +1 -1
- sky/dashboard/out/workspaces.html +1 -1
- sky/data/storage_utils.py +9 -0
- sky/execution.py +24 -2
- sky/global_user_state.py +16 -0
- sky/jobs/recovery_strategy.py +45 -0
- sky/jobs/server/core.py +60 -53
- sky/jobs/state.py +21 -1
- sky/jobs/utils.py +29 -11
- sky/provision/kubernetes/config.py +0 -42
- sky/provision/kubernetes/instance.py +1 -33
- sky/provision/kubernetes/manifests/fusermount-server-daemonset.yaml +1 -2
- sky/provision/kubernetes/network_utils.py +0 -21
- sky/provision/kubernetes/utils.py +136 -300
- sky/server/auth/loopback.py +38 -0
- sky/server/auth/oauth2_proxy.py +6 -0
- sky/server/server.py +6 -0
- sky/setup_files/dependencies.py +1 -0
- sky/templates/kubernetes-ray.yml.j2 +4 -13
- sky/utils/context.py +12 -7
- sky/utils/env_options.py +4 -0
- sky/utils/kubernetes_enums.py +2 -15
- sky/utils/schemas.py +17 -6
- {skypilot_nightly-1.0.0.dev20251002.dist-info → skypilot_nightly-1.0.0.dev20251004.dist-info}/METADATA +38 -37
- {skypilot_nightly-1.0.0.dev20251002.dist-info → skypilot_nightly-1.0.0.dev20251004.dist-info}/RECORD +55 -56
- sky/dashboard/out/_next/static/chunks/3015-88c7c8d69b0b6dba.js +0 -1
- sky/dashboard/out/_next/static/chunks/8969-d8bc3a2b9cf839a9.js +0 -1
- sky/templates/kubernetes-ssh-jump.yml.j2 +0 -94
- sky/utils/kubernetes/ssh_jump_lifecycle_manager.py +0 -191
- /sky/dashboard/out/_next/static/{16g0-hgEgk6Db72hpE8MY → KL03GEega4QqDqTOMtA_w}/_ssgManifest.js +0 -0
- {skypilot_nightly-1.0.0.dev20251002.dist-info → skypilot_nightly-1.0.0.dev20251004.dist-info}/WHEEL +0 -0
- {skypilot_nightly-1.0.0.dev20251002.dist-info → skypilot_nightly-1.0.0.dev20251004.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20251002.dist-info → skypilot_nightly-1.0.0.dev20251004.dist-info}/licenses/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev20251002.dist-info → skypilot_nightly-1.0.0.dev20251004.dist-info}/top_level.txt +0 -0
sky/__init__.py
CHANGED
|
@@ -7,7 +7,7 @@ import urllib.request
|
|
|
7
7
|
from sky.utils import directory_utils
|
|
8
8
|
|
|
9
9
|
# Replaced with the current commit when building the wheels.
|
|
10
|
-
_SKYPILOT_COMMIT_SHA = '
|
|
10
|
+
_SKYPILOT_COMMIT_SHA = '727ea9a60a919fd2ea477dea03a4096136355d20'
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def _get_git_commit():
|
|
@@ -37,7 +37,7 @@ def _get_git_commit():
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
__commit__ = _get_git_commit()
|
|
40
|
-
__version__ = '1.0.0.
|
|
40
|
+
__version__ = '1.0.0.dev20251004'
|
|
41
41
|
__root_dir__ = directory_utils.get_sky_dir()
|
|
42
42
|
|
|
43
43
|
|
sky/authentication.py
CHANGED
|
@@ -35,10 +35,8 @@ from sky import clouds
|
|
|
35
35
|
from sky import exceptions
|
|
36
36
|
from sky import global_user_state
|
|
37
37
|
from sky import sky_logging
|
|
38
|
-
from sky import skypilot_config
|
|
39
38
|
from sky.adaptors import gcp
|
|
40
39
|
from sky.adaptors import ibm
|
|
41
|
-
from sky.adaptors import kubernetes
|
|
42
40
|
from sky.adaptors import runpod
|
|
43
41
|
from sky.adaptors import seeweb as seeweb_adaptor
|
|
44
42
|
from sky.adaptors import vast
|
|
@@ -47,8 +45,6 @@ from sky.provision.kubernetes import utils as kubernetes_utils
|
|
|
47
45
|
from sky.provision.lambda_cloud import lambda_utils
|
|
48
46
|
from sky.provision.primeintellect import utils as primeintellect_utils
|
|
49
47
|
from sky.utils import common_utils
|
|
50
|
-
from sky.utils import config_utils
|
|
51
|
-
from sky.utils import kubernetes_enums
|
|
52
48
|
from sky.utils import subprocess_utils
|
|
53
49
|
from sky.utils import ux_utils
|
|
54
50
|
from sky.utils import yaml_utils
|
|
@@ -431,116 +427,30 @@ def setup_ibm_authentication(config: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
431
427
|
|
|
432
428
|
def setup_kubernetes_authentication(config: Dict[str, Any]) -> Dict[str, Any]:
|
|
433
429
|
context = kubernetes_utils.get_context_from_config(config['provider'])
|
|
434
|
-
|
|
435
|
-
# Default ssh session is established with kubectl port-forwarding with
|
|
436
|
-
# ClusterIP service.
|
|
437
|
-
nodeport_mode = kubernetes_enums.KubernetesNetworkingMode.NODEPORT
|
|
438
|
-
port_forward_mode = kubernetes_enums.KubernetesNetworkingMode.PORTFORWARD
|
|
439
|
-
network_mode_str = skypilot_config.get_effective_region_config(
|
|
440
|
-
cloud='kubernetes',
|
|
441
|
-
region=context,
|
|
442
|
-
keys=('networking',),
|
|
443
|
-
default_value=port_forward_mode.value)
|
|
444
|
-
try:
|
|
445
|
-
network_mode = kubernetes_enums.KubernetesNetworkingMode.from_str(
|
|
446
|
-
network_mode_str)
|
|
447
|
-
except ValueError as e:
|
|
448
|
-
# Add message saying "Please check: ~/.sky/config.yaml" to the error
|
|
449
|
-
# message.
|
|
450
|
-
with ux_utils.print_exception_no_traceback():
|
|
451
|
-
raise ValueError(str(e) +
|
|
452
|
-
' Please check: ~/.sky/config.yaml.') from None
|
|
453
|
-
_, public_key_path = get_or_generate_keys()
|
|
454
|
-
|
|
455
|
-
# Add the user's public key to the SkyPilot cluster.
|
|
456
|
-
secret_name = clouds.Kubernetes.SKY_SSH_KEY_SECRET_NAME
|
|
457
|
-
secret_field_name = clouds.Kubernetes().ssh_key_secret_field_name
|
|
458
430
|
namespace = kubernetes_utils.get_namespace_from_config(config['provider'])
|
|
459
|
-
k8s = kubernetes.kubernetes
|
|
460
|
-
with open(public_key_path, 'r', encoding='utf-8') as f:
|
|
461
|
-
public_key = f.read()
|
|
462
|
-
if not public_key.endswith('\n'):
|
|
463
|
-
public_key += '\n'
|
|
464
|
-
|
|
465
|
-
# Generate metadata
|
|
466
|
-
secret_metadata = {
|
|
467
|
-
'name': secret_name,
|
|
468
|
-
'labels': {
|
|
469
|
-
'parent': 'skypilot'
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
custom_metadata = skypilot_config.get_effective_region_config(
|
|
473
|
-
cloud='kubernetes',
|
|
474
|
-
region=context,
|
|
475
|
-
keys=('custom_metadata',),
|
|
476
|
-
default_value={})
|
|
477
|
-
config_utils.merge_k8s_configs(secret_metadata, custom_metadata)
|
|
478
|
-
|
|
479
|
-
secret = k8s.client.V1Secret(
|
|
480
|
-
metadata=k8s.client.V1ObjectMeta(**secret_metadata),
|
|
481
|
-
string_data={secret_field_name: public_key})
|
|
482
|
-
try:
|
|
483
|
-
if kubernetes_utils.check_secret_exists(secret_name, namespace,
|
|
484
|
-
context):
|
|
485
|
-
logger.debug(f'Key {secret_name} exists in the cluster, '
|
|
486
|
-
'patching it...')
|
|
487
|
-
kubernetes.core_api(context).patch_namespaced_secret(
|
|
488
|
-
secret_name, namespace, secret)
|
|
489
|
-
else:
|
|
490
|
-
logger.debug(f'Key {secret_name} does not exist in the cluster, '
|
|
491
|
-
'creating it...')
|
|
492
|
-
kubernetes.core_api(context).create_namespaced_secret(
|
|
493
|
-
namespace, secret)
|
|
494
|
-
except kubernetes.api_exception() as e:
|
|
495
|
-
if e.status == 409 and e.reason == 'AlreadyExists':
|
|
496
|
-
logger.debug(f'Key {secret_name} was created concurrently, '
|
|
497
|
-
'patching it...')
|
|
498
|
-
kubernetes.core_api(context).patch_namespaced_secret(
|
|
499
|
-
secret_name, namespace, secret)
|
|
500
|
-
else:
|
|
501
|
-
raise e
|
|
502
|
-
|
|
503
431
|
private_key_path, _ = get_or_generate_keys()
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
kubernetes_utils.check_port_forward_mode_dependencies()
|
|
522
|
-
# TODO(romilb): This can be further optimized. Instead of using the
|
|
523
|
-
# head node as a jump pod for worker nodes, we can also directly
|
|
524
|
-
# set the ssh_target to the worker node. However, that requires
|
|
525
|
-
# changes in the downstream code to return a mapping of node IPs to
|
|
526
|
-
# pod names (to be used as ssh_target) and updating the upstream
|
|
527
|
-
# SSHConfigHelper to use a different ProxyCommand for each pod.
|
|
528
|
-
# This optimization can reduce SSH time from ~0.35s to ~0.25s, tested
|
|
529
|
-
# on GKE.
|
|
530
|
-
ssh_target = config['cluster_name'] + '-head'
|
|
531
|
-
ssh_proxy_cmd = kubernetes_utils.get_ssh_proxy_command(
|
|
532
|
-
ssh_target,
|
|
533
|
-
port_forward_mode,
|
|
534
|
-
private_key_path=private_key_path,
|
|
535
|
-
context=context,
|
|
536
|
-
namespace=namespace)
|
|
537
|
-
else:
|
|
538
|
-
# This should never happen because we check for this in from_str above.
|
|
539
|
-
raise ValueError(f'Unsupported networking mode: {network_mode_str}')
|
|
432
|
+
# Using `kubectl port-forward` creates a direct tunnel to the pod and
|
|
433
|
+
# does not require a ssh jump pod.
|
|
434
|
+
kubernetes_utils.check_port_forward_mode_dependencies()
|
|
435
|
+
# TODO(romilb): This can be further optimized. Instead of using the
|
|
436
|
+
# head node as a jump pod for worker nodes, we can also directly
|
|
437
|
+
# set the ssh_target to the worker node. However, that requires
|
|
438
|
+
# changes in the downstream code to return a mapping of node IPs to
|
|
439
|
+
# pod names (to be used as ssh_target) and updating the upstream
|
|
440
|
+
# SSHConfigHelper to use a different ProxyCommand for each pod.
|
|
441
|
+
# This optimization can reduce SSH time from ~0.35s to ~0.25s, tested
|
|
442
|
+
# on GKE.
|
|
443
|
+
pod_name = config['cluster_name'] + '-head'
|
|
444
|
+
ssh_proxy_cmd = kubernetes_utils.get_ssh_proxy_command(
|
|
445
|
+
pod_name,
|
|
446
|
+
private_key_path=private_key_path,
|
|
447
|
+
context=context,
|
|
448
|
+
namespace=namespace)
|
|
540
449
|
config['auth']['ssh_proxy_command'] = ssh_proxy_cmd
|
|
541
450
|
config['auth']['ssh_private_key'] = private_key_path
|
|
542
451
|
|
|
543
|
-
|
|
452
|
+
# Add the user's public key to the SkyPilot cluster.
|
|
453
|
+
return configure_ssh_info(config)
|
|
544
454
|
|
|
545
455
|
|
|
546
456
|
# ---------------------------------- RunPod ---------------------------------- #
|
|
@@ -3277,6 +3277,10 @@ class CloudVmRayBackend(backends.Backend['CloudVmRayResourceHandle']):
|
|
|
3277
3277
|
self._requested_features = set()
|
|
3278
3278
|
self._dump_final_script = False
|
|
3279
3279
|
self._is_managed = False
|
|
3280
|
+
# Optional planner (via register_info): used under the per-cluster lock
|
|
3281
|
+
# to produce a fresh concrete plan when neither a reusable snapshot nor
|
|
3282
|
+
# a caller plan is available.
|
|
3283
|
+
self._planner = None
|
|
3280
3284
|
|
|
3281
3285
|
# Command for running the setup script. It is only set when the
|
|
3282
3286
|
# setup needs to be run outside the self._setup() and as part of
|
|
@@ -3294,6 +3298,9 @@ class CloudVmRayBackend(backends.Backend['CloudVmRayResourceHandle']):
|
|
|
3294
3298
|
self._requested_features)
|
|
3295
3299
|
self._dump_final_script = kwargs.pop('dump_final_script', False)
|
|
3296
3300
|
self._is_managed = kwargs.pop('is_managed', False)
|
|
3301
|
+
# Optional planner callback for a fresh plan under lock when no
|
|
3302
|
+
# reusable snapshot/caller plan exists. Keeps optimizer in upper layer.
|
|
3303
|
+
self._planner = kwargs.pop('planner', self._planner)
|
|
3297
3304
|
assert not kwargs, f'Unexpected kwargs: {kwargs}'
|
|
3298
3305
|
|
|
3299
3306
|
def check_resources_fit_cluster(
|
|
@@ -5843,33 +5850,41 @@ class CloudVmRayBackend(backends.Backend['CloudVmRayResourceHandle']):
|
|
|
5843
5850
|
common_utils.check_cluster_name_is_valid(cluster_name)
|
|
5844
5851
|
|
|
5845
5852
|
if to_provision is None:
|
|
5846
|
-
#
|
|
5847
|
-
#
|
|
5848
|
-
#
|
|
5849
|
-
#
|
|
5850
|
-
#
|
|
5851
|
-
#
|
|
5852
|
-
#
|
|
5853
|
-
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
handle_before_refresh,
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5853
|
+
# Recently terminated after refresh. OPTIMIZE usually ran outside
|
|
5854
|
+
# the lock, so that decision may be stale by now. Under the lock,
|
|
5855
|
+
# ensure we always have a concrete plan via the following order:
|
|
5856
|
+
# 1) Reuse last placement snapshot (if available);
|
|
5857
|
+
# 2) Else, call injected planner for a fresh plan.
|
|
5858
|
+
# If we still have a pre-refresh handle snapshot with a concrete
|
|
5859
|
+
# placement, prefer reusing it.
|
|
5860
|
+
if (isinstance(handle_before_refresh, CloudVmRayResourceHandle) and
|
|
5861
|
+
handle_before_refresh.launched_resources is not None):
|
|
5862
|
+
to_provision = handle_before_refresh.launched_resources
|
|
5863
|
+
# Ensure the requested task fits the previous placement.
|
|
5864
|
+
self.check_resources_fit_cluster(handle_before_refresh, task)
|
|
5865
|
+
# Mirror the original message for reuse path.
|
|
5866
|
+
status_before_refresh_str = None
|
|
5867
|
+
if status_before_refresh is not None:
|
|
5868
|
+
status_before_refresh_str = status_before_refresh.value
|
|
5869
|
+
logger.info(
|
|
5870
|
+
f'The cluster {cluster_name!r} (status: '
|
|
5871
|
+
f'{status_before_refresh_str}) was not found on the cloud: '
|
|
5872
|
+
'it may be autodowned, manually terminated, or its launch '
|
|
5873
|
+
'never succeeded. Provisioning a new cluster by using the '
|
|
5874
|
+
'same resources as its original launch.')
|
|
5875
|
+
elif self._planner is not None:
|
|
5876
|
+
to_provision = self._planner(task)
|
|
5877
|
+
logger.info(
|
|
5878
|
+
'Previous placement snapshot missing; computing a fresh '
|
|
5879
|
+
'plan for provisioning.')
|
|
5880
|
+
else:
|
|
5881
|
+
# Without a snapshot or planner, we cannot proceed safely.
|
|
5882
|
+
# Surface a user-friendly error without a long traceback.
|
|
5883
|
+
with ux_utils.print_exception_no_traceback():
|
|
5884
|
+
raise RuntimeError(
|
|
5885
|
+
'No concrete launch plan available after recent cloud '
|
|
5886
|
+
f'termination of cluster {cluster_name!r}. Ensure the '
|
|
5887
|
+
'OPTIMIZE stage runs or provide concrete resources.')
|
|
5873
5888
|
|
|
5874
5889
|
return RetryingVmProvisioner.ToProvisionConfig(
|
|
5875
5890
|
cluster_name,
|
sky/client/cli/command.py
CHANGED
|
@@ -1803,17 +1803,7 @@ def status(verbose: bool, refresh: bool, ip: bool, endpoints: bool,
|
|
|
1803
1803
|
return None
|
|
1804
1804
|
|
|
1805
1805
|
def submit_workspace() -> Optional[server_common.RequestId[Dict[str, Any]]]:
|
|
1806
|
-
|
|
1807
|
-
return sdk.workspaces()
|
|
1808
|
-
except RuntimeError:
|
|
1809
|
-
# Backward compatibility for API server before #5660.
|
|
1810
|
-
# TODO(zhwu): remove this after 0.10.0.
|
|
1811
|
-
logger.warning(f'{colorama.Style.DIM}SkyPilot API server is '
|
|
1812
|
-
'in an old version, and may miss feature: '
|
|
1813
|
-
'workspaces. Update with: sky api stop; '
|
|
1814
|
-
'sky api start'
|
|
1815
|
-
f'{colorama.Style.RESET_ALL}')
|
|
1816
|
-
return None
|
|
1806
|
+
return sdk.workspaces()
|
|
1817
1807
|
|
|
1818
1808
|
active_workspace = skypilot_config.get_active_workspace()
|
|
1819
1809
|
|
sky/clouds/cudo.py
CHANGED
|
@@ -288,7 +288,7 @@ class Cudo(clouds.Cloud):
|
|
|
288
288
|
cls) -> Tuple[bool, Optional[Union[str, Dict[str, str]]]]:
|
|
289
289
|
"""Checks if the user has access credentials to
|
|
290
290
|
Cudo's compute service."""
|
|
291
|
-
if not common.can_import_modules(['
|
|
291
|
+
if not common.can_import_modules(['cudo_compute']):
|
|
292
292
|
return False, (f'{cls._DEPENDENCY_HINT}\n'
|
|
293
293
|
f'{cls._INDENT_PREFIX}')
|
|
294
294
|
|
sky/clouds/kubernetes.py
CHANGED
|
@@ -25,6 +25,7 @@ from sky.provision.kubernetes.utils import normalize_tpu_accelerator_name
|
|
|
25
25
|
from sky.skylet import constants
|
|
26
26
|
from sky.utils import annotations
|
|
27
27
|
from sky.utils import common_utils
|
|
28
|
+
from sky.utils import env_options
|
|
28
29
|
from sky.utils import kubernetes_enums
|
|
29
30
|
from sky.utils import registry
|
|
30
31
|
from sky.utils import resources_utils
|
|
@@ -47,9 +48,6 @@ _FUSERMOUNT_SHARED_DIR = '/var/run/fusermount'
|
|
|
47
48
|
class Kubernetes(clouds.Cloud):
|
|
48
49
|
"""Kubernetes."""
|
|
49
50
|
|
|
50
|
-
SKY_SSH_KEY_SECRET_NAME = 'sky-ssh-keys'
|
|
51
|
-
SKY_SSH_JUMP_NAME = 'sky-ssh-jump-pod'
|
|
52
|
-
|
|
53
51
|
# Limit the length of the cluster name to avoid exceeding the limit of 63
|
|
54
52
|
# characters for Kubernetes resources. We limit to 42 characters (63-21) to
|
|
55
53
|
# allow additional characters for creating ingress services to expose ports.
|
|
@@ -98,14 +96,6 @@ class Kubernetes(clouds.Cloud):
|
|
|
98
96
|
# Set of contexts that has logged as temporarily unreachable
|
|
99
97
|
logged_unreachable_contexts: Set[str] = set()
|
|
100
98
|
|
|
101
|
-
@property
|
|
102
|
-
def ssh_key_secret_field_name(self):
|
|
103
|
-
# Use a fresh user hash to avoid conflicts in the secret object naming.
|
|
104
|
-
# This can happen when the controller is reusing the same user hash
|
|
105
|
-
# through USER_ID_ENV_VAR but has a different SSH key.
|
|
106
|
-
fresh_user_hash = common_utils.generate_user_hash()
|
|
107
|
-
return f'ssh-publickey-{fresh_user_hash}'
|
|
108
|
-
|
|
109
99
|
@classmethod
|
|
110
100
|
def _unsupported_features_for_resources(
|
|
111
101
|
cls, resources: 'resources_lib.Resources'
|
|
@@ -188,6 +178,12 @@ class Kubernetes(clouds.Cloud):
|
|
|
188
178
|
ctx for ctx in all_contexts if not ctx.startswith('ssh-')
|
|
189
179
|
]
|
|
190
180
|
|
|
181
|
+
allow_all_contexts = allowed_contexts == 'all' or (
|
|
182
|
+
allowed_contexts is None and
|
|
183
|
+
env_options.Options.ALLOW_ALL_KUBERNETES_CONTEXTS.get())
|
|
184
|
+
if allow_all_contexts:
|
|
185
|
+
allowed_contexts = all_contexts
|
|
186
|
+
|
|
191
187
|
if allowed_contexts is None:
|
|
192
188
|
# Try kubeconfig if present
|
|
193
189
|
current_context = (
|
|
@@ -517,9 +513,6 @@ class Kubernetes(clouds.Cloud):
|
|
|
517
513
|
return image_id
|
|
518
514
|
|
|
519
515
|
image_id = _get_image_id(resources)
|
|
520
|
-
# TODO(romilb): Create a lightweight image for SSH jump host
|
|
521
|
-
ssh_jump_image = catalog.get_image_id_from_tag(self.IMAGE_CPU,
|
|
522
|
-
clouds='kubernetes')
|
|
523
516
|
|
|
524
517
|
# Set environment variables for the pod. Note that SkyPilot env vars
|
|
525
518
|
# are set separately when the task is run. These env vars are
|
|
@@ -693,13 +686,8 @@ class Kubernetes(clouds.Cloud):
|
|
|
693
686
|
'accelerator_count': str(acc_count),
|
|
694
687
|
'timeout': str(timeout),
|
|
695
688
|
'k8s_port_mode': port_mode.value,
|
|
696
|
-
'k8s_networking_mode': network_utils.get_networking_mode(
|
|
697
|
-
None, context=context).value,
|
|
698
|
-
'k8s_ssh_key_secret_name': self.SKY_SSH_KEY_SECRET_NAME,
|
|
699
689
|
'k8s_acc_label_key': k8s_acc_label_key,
|
|
700
690
|
'k8s_acc_label_values': k8s_acc_label_values,
|
|
701
|
-
'k8s_ssh_jump_name': self.SKY_SSH_JUMP_NAME,
|
|
702
|
-
'k8s_ssh_jump_image': ssh_jump_image,
|
|
703
691
|
'k8s_service_account_name': k8s_service_account_name,
|
|
704
692
|
'k8s_automount_sa_token': 'true',
|
|
705
693
|
'k8s_fuse_device_required': fuse_device_required,
|
sky/dashboard/out/404.html
CHANGED
|
@@ -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-
|
|
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-3286453d56f3c0a0.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/KL03GEega4QqDqTOMtA_w/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/KL03GEega4QqDqTOMtA_w/_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":"KL03GEega4QqDqTOMtA_w","assetPrefix":"/dashboard","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
|
sky/dashboard/out/_next/static/{16g0-hgEgk6Db72hpE8MY → KL03GEega4QqDqTOMtA_w}/_buildManifest.js
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
self.__BUILD_MANIFEST=function(s,c,a,t,
|
|
1
|
+
self.__BUILD_MANIFEST=function(s,c,a,e,t,f,u,n,b,o,j,i,r,k){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/":["static/chunks/pages/index-444f1804401f04ea.js"],"/_error":["static/chunks/pages/_error-c66a4e8afc46f17b.js"],"/clusters":["static/chunks/pages/clusters-469814d711d63b1b.js"],"/clusters/[cluster]":[s,c,a,f,u,"static/chunks/4676-9da7fdbde90b5549.js",o,e,t,n,j,b,i,"static/chunks/6856-5fdc9b851a18acdb.js",r,k,"static/chunks/9037-d0c00018a5ba198c.js","static/chunks/pages/clusters/[cluster]-e052384df65ef200.js"],"/clusters/[cluster]/[job]":[s,c,a,f,e,t,b,"static/chunks/pages/clusters/[cluster]/[job]-72794fc3fcdd517a.js"],"/config":["static/chunks/pages/config-dfb9bf07b13045f4.js"],"/infra":["static/chunks/pages/infra-aabba60d57826e0f.js"],"/infra/[context]":["static/chunks/pages/infra/[context]-6563820e094f68ca.js"],"/jobs":["static/chunks/pages/jobs-1f70d9faa564804f.js"],"/jobs/pools/[pool]":[s,c,a,u,o,e,t,n,"static/chunks/pages/jobs/pools/[pool]-509b2977a6373bf6.js"],"/jobs/[job]":[s,c,a,f,u,o,e,t,n,b,"static/chunks/pages/jobs/[job]-dd64309c3fe67ed2.js"],"/users":["static/chunks/pages/users-018bf31cda52e11b.js"],"/volumes":["static/chunks/pages/volumes-739726d6b823f532.js"],"/workspace/new":["static/chunks/pages/workspace/new-3f88a1c7e86a3f86.js"],"/workspaces":["static/chunks/pages/workspaces-7528cc0ef8c522c5.js"],"/workspaces/[name]":[s,c,a,f,u,"static/chunks/1836-37fede578e2da5f8.js",e,t,n,j,b,i,r,k,"static/chunks/1141-159df2d4c441a9d1.js","static/chunks/pages/workspaces/[name]-af76bb06dbb3954f.js"],sortedPages:["/","/_app","/_error","/clusters","/clusters/[cluster]","/clusters/[cluster]/[job]","/config","/infra","/infra/[context]","/jobs","/jobs/pools/[pool]","/jobs/[job]","/users","/volumes","/workspace/new","/workspaces","/workspaces/[name]"]}}("static/chunks/616-3d59f75e2ccf9321.js","static/chunks/6130-2be46d70a38f1e82.js","static/chunks/5739-d67458fcb1386c92.js","static/chunks/6989-01359c57e018caa4.js","static/chunks/3850-ff4a9a69d978632b.js","static/chunks/7411-b15471acd2cba716.js","static/chunks/1272-1ef0bf0237faccdb.js","static/chunks/8969-66237729cdf9749e.js","static/chunks/6135-4b4d5e824b7f9d3c.js","static/chunks/754-d0da8ab45f9509e9.js","static/chunks/6990-f6818c84ed8f1c86.js","static/chunks/1121-d0782b9251f0fcd3.js","static/chunks/6601-06114c982db410b6.js","static/chunks/3015-8d748834fcc60b46.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3015],{23015:function(e,s,t){t.r(s),t.d(s,{ClusterJobs:function(){return H},ManagedJobs:function(){return Z},ManagedJobsTable:function(){return B},Status2Actions:function(){return q},filterJobsByName:function(){return J},filterJobsByPool:function(){return O},filterJobsByUser:function(){return W},filterJobsByWorkspace:function(){return U},statusGroups:function(){return z}});var r=t(85893),a=t(67294),l=t(11163),n=t(41664),i=t.n(n),c=t(55739),o=t(30803),d=t(37673),u=t(68764),h=t(36989),x=t(51214),m=t(68969),p=t(6378);class j{_generateFilterKey(e){let{allUsers:s=!0,nameMatch:t,userMatch:r,workspaceMatch:a,poolMatch:l,statuses:n}=e;return["allUsers:".concat(s),t?"name:".concat(t):"",r?"user:".concat(r):"",a?"workspace:".concat(a):"",l?"pool:".concat(l):"",n&&n.length>0?"statuses:".concat(n.sort().join(",")):""].filter(Boolean).join("|")||"default"}_getCacheStatus(e){let s=this.fullDataCache.get(e),t=Date.now();if(!s)return{isCached:!1,isFresh:!1,age:0,maxAge:12e4,hasData:!1};let r=t-s.timestamp;return{isCached:!0,isFresh:r<12e4,age:r,maxAge:12e4,hasData:s.jobs&&Array.isArray(s.jobs),data:s}}async getPaginatedJobs(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{page:s=1,limit:t=10,...r}=e,a=this._generateFilterKey(r);try{let e=this._getCacheStatus(a);if(e.isCached&&e.hasData){let l=e.data;if(!l.jobs||Array.isArray(l.jobs)&&0===l.jobs.length){if(!this.prefetching.has(a)){let e=this._loadFullDataset(r,a).catch(()=>{}).finally(()=>this.prefetching.delete(a));this.prefetching.set(a,e)}}else{let n=(s-1)*t,i=l.jobs.slice(n,n+t);if(!this.prefetching.has(a)&&(!e.isFresh||e.age>e.maxAge/2)){let e=this._loadFullDataset(r,a).catch(()=>{}).finally(()=>this.prefetching.delete(a));this.prefetching.set(a,e)}return{jobs:i,total:l.total,totalNoFilter:l.totalNoFilter||l.total,controllerStopped:l.controllerStopped,statusCounts:l.statusCounts||{},fromCache:!0,cacheStatus:e.isFresh?"local_cache_hit":"local_cache_stale_hit"}}}let l=await p.default.get(m.getManagedJobs,[{...r,page:s,limit:t}]),n=(null==l?void 0:l.jobs)||[],i="number"==typeof(null==l?void 0:l.total)?l.total:n.length,c=!!(null==l?void 0:l.controllerStopped);if(!this.prefetching.has(a)){let e=this._loadFullDataset(r,a).catch(e=>{console.warn("Background prefetch of full jobs failed:",e)}).finally(()=>{this.prefetching.delete(a)});this.prefetching.set(a,e)}return{jobs:n,total:i,totalNoFilter:(null==l?void 0:l.totalNoFilter)||i,controllerStopped:c,statusCounts:(null==l?void 0:l.statusCounts)||{},fromCache:!1,cacheStatus:"server_page_fetch"}}catch(e){return console.error("Error in getPaginatedJobs:",e),{jobs:[],total:0,totalNoFilter:0,controllerStopped:!1,statusCounts:{},fromCache:!1,cacheStatus:"error"}}}async _loadFullDataset(e,s){let t=await p.default.get(m.getManagedJobs,[e]);if(t.controllerStopped||!t.jobs)return t;let r={jobs:t.jobs,total:t.jobs.length,totalNoFilter:t.totalNoFilter||t.jobs.length,controllerStopped:!1,statusCounts:t.statusCounts||{},timestamp:Date.now()};return this.fullDataCache.set(s,r),r}isDataLoading(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},s=this._generateFilterKey(e);return this.isLoading.has(s)||this.prefetching.has(s)}isDataCached(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},s=this._generateFilterKey(e),t=this._getCacheStatus(s);return t.isCached&&t.isFresh&&t.hasData}getCacheStatus(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},s=this._generateFilterKey(e);return this._getCacheStatus(s)}invalidateCache(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;if(e){let s=this._generateFilterKey(e);this.fullDataCache.delete(s),this.isLoading.delete(s),this.prefetching.delete(s)}else this.fullDataCache.clear(),this.isLoading.clear(),this.prefetching.clear();p.default.invalidateFunction(m.getManagedJobs)}getCacheStats(){let e={cachedFilters:Array.from(this.fullDataCache.keys()),loadingFilters:Array.from(this.isLoading.keys()),prefetchingFilters:Array.from(this.prefetching.keys()),cacheSize:this.fullDataCache.size,loadingCount:this.isLoading.size,prefetchingCount:this.prefetching.size};for(let[s,t]of(e.detailedStatus={},this.fullDataCache.entries())){let r=this._getCacheStatus(s);e.detailedStatus[s]={age:r.age,isFresh:r.isFresh,hasData:r.hasData,jobCount:t.jobs?t.jobs.length:0}}return e}constructor(){this.fullDataCache=new Map,this.isLoading=new Map,this.prefetching=new Map}}let f=new j;var g=t(23266),b=t(17324),v=t(53081),w=t(13626),y=t(23293),N=t(6521),k=t(16826),C=t(92128),S=t(94545),_=t(99307),L=t(20546),E=t(23001),R=t(88950);let D=(e,s)=>{let t={...e.query},r=[],a=[],l=[];s.map((e,s)=>{var t;r.push(null!==(t=e.property.toLowerCase())&&void 0!==t?t:""),a.push(e.operator),l.push(e.value)}),t.property=r,t.operator=a,t.value=l,e.replace({pathname:e.pathname,query:t},void 0,{shallow:!0})},F=(e,s)=>{let t={...e.query},r=t.property,a=t.operator,l=t.value;if(void 0===r)return[];let n=[],i=Array.isArray(r)?r.length:1;if(1===i)n.push({property:s.get(r),operator:a,value:l});else for(let e=0;e<i;e++)n.push({property:s.get(r[e]),operator:a[e],value:l[e]});return n},M=e=>{var s,t;let{propertyList:l=[],valueList:n,setFilters:i,updateURLParams:c,placeholder:o="Filter items"}=e,d=(0,a.useRef)(null),u=(0,a.useRef)(null),[h,x]=(0,a.useState)(!1),[m,p]=(0,a.useState)(""),[j,f]=(0,a.useState)((null===(s=l[0])||void 0===s?void 0:s.value)||"status"),[g,b]=(0,a.useState)([]);(0,a.useEffect)(()=>{let e=e=>{u.current&&!u.current.contains(e.target)&&d.current&&!d.current.contains(e.target)&&x(!1)};return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[]),(0,a.useEffect)(()=>{let e=[];n&&"object"==typeof n&&(e=n[j]||[]),""!==m.trim()&&(e=e.filter(e=>e&&e.toString().toLowerCase().includes(m.toLowerCase()))),b(e)},[j,n,m]);let v=e=>{let s=l.find(s=>s.value===e);return s?s.label:e},w=e=>{i(s=>{let t=[...s,{property:v(j),operator:":",value:e}];return c(t),t}),x(!1),p(""),d.current.focus()};return(0,r.jsxs)("div",{className:"flex flex-row border border-gray-300 rounded-md overflow-visible",children:[(0,r.jsx)("div",{className:"border-r border-gray-300 flex-shrink-0",children:(0,r.jsxs)(R.Ph,{onValueChange:f,value:j,children:[(0,r.jsx)(R.i4,{"aria-label":"Filter Property",className:"focus:ring-0 focus:ring-offset-0 border-none rounded-l-md rounded-r-none w-20 sm:w-24 md:w-32 h-8 text-xs sm:text-sm",children:(0,r.jsx)(R.ki,{placeholder:(null===(t=l[0])||void 0===t?void 0:t.label)||"Status"})}),(0,r.jsx)(R.Bw,{children:l.map((e,s)=>(0,r.jsx)(R.Ql,{value:e.value,children:e.label},"property-item-".concat(s)))})]})}),(0,r.jsxs)("div",{className:"relative flex-1",children:[(0,r.jsx)("input",{type:"text",ref:d,placeholder:o,value:m,onChange:e=>{p(e.target.value),h||x(!0)},onFocus:()=>{x(!0)},onKeyDown:e=>{"Enter"===e.key&&""!==m.trim()?(i(e=>{let s=[...e,{property:v(j),operator:":",value:m}];return c(s),s}),p(""),x(!1)):"Escape"===e.key&&(x(!1),d.current.blur())},className:"h-8 w-full sm:w-96 px-3 pr-8 text-sm border-none rounded-l-none rounded-r-md focus:ring-0 focus:outline-none",autoComplete:"off"}),m&&(0,r.jsx)("button",{onClick:()=>{p(""),x(!1)},className:"absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-400 hover:text-gray-600",title:"Clear filter",tabIndex:-1,children:(0,r.jsx)("svg",{className:"h-4 w-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,r.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})}),h&&g.length>0&&(0,r.jsx)("div",{ref:u,className:"absolute z-50 mt-1 w-full bg-white border border-gray-200 rounded-md shadow-lg max-h-60 overflow-y-auto",style:{zIndex:9999},children:g.map((e,s)=>(0,r.jsx)("div",{className:"px-3 py-2 cursor-pointer hover:bg-gray-50 text-sm ".concat(s!==g.length-1?"border-b border-gray-100":""),onClick:()=>w(e),children:(0,r.jsx)("span",{className:"text-sm text-gray-700",children:e})},"".concat(e,"-").concat(s)))})]})]})},I=e=>{let{filters:s=[],setFilters:t,updateURLParams:a}=e,l=e=>{t(s=>{let t=s.filter((s,t)=>t!==e);return a(t),t})};return(0,r.jsx)(r.Fragment,{children:(0,r.jsx)("div",{className:"flex items-center gap-4 py-2 px-2",children:(0,r.jsxs)("div",{className:"flex flex-wrap items-content gap-2",children:[s.map((e,s)=>(0,r.jsx)(A,{filter:e,onRemove:()=>l(s)},"filteritem-".concat(s))),s.length>0&&(0,r.jsx)(r.Fragment,{children:(0,r.jsx)("button",{onClick:()=>{a([]),t([])},className:"rounded-full px-4 py-1 text-sm text-gray-700 bg-gray-200 hover:bg-gray-300",children:"Clear filters"})})]})})})},A=e=>{let{filter:s,onRemove:t}=e;return(0,r.jsx)(r.Fragment,{children:(0,r.jsxs)("div",{className:"flex items-center text-blue-600 bg-blue-100 px-1 py-1 rounded-full text-sm",children:[(0,r.jsxs)("div",{className:"flex items-center gap-1 px-2",children:[(0,r.jsx)("span",{children:"".concat(s.property," ")}),(0,r.jsx)("span",{children:"".concat(s.operator," ")}),(0,r.jsx)("span",{children:" ".concat(s.value)})]}),(0,r.jsx)("button",{onClick:()=>t(),className:"p-0.5 ml-1 transform text-gray-400 hover:text-gray-600 bg-blue-500 hover:bg-blue-600 rounded-full flex flex-col items-center",title:"Clear filter",children:(0,r.jsx)("svg",{className:"h-3 w-3",fill:"none",stroke:"white",viewBox:"0 0 24 24",children:(0,r.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:5,d:"M6 18L18 6M6 6l12 12"})})})]})})},z={active:["PENDING","RUNNING","RECOVERING","SUBMITTED","STARTING","CANCELLING"],finished:["SUCCEEDED","FAILED","CANCELLED","FAILED_SETUP","FAILED_PRECHECKS","FAILED_NO_RESOURCE","FAILED_CONTROLLER"]},P=[{label:"Name",value:"name"},{label:"User",value:"user"},{label:"Workspace",value:"workspace"},{label:"Pool",value:"pool"}];function J(e,s){if(!s||""===s.trim())return e;let t=s.toLowerCase().trim();return e.filter(e=>(e.name||"").toLowerCase().includes(t))}function U(e,s){return s&&"ALL_WORKSPACES"!==s?e.filter(e=>(e.workspace||"default").toLowerCase()===s.toLowerCase()):e}function W(e,s){return s&&"ALL_USERS"!==s?e.filter(e=>(e.user_hash||e.user)===s):e}function O(e,s){if(!s||""===s.trim())return e;let t=s.toLowerCase().trim();return e.filter(e=>(e.pool||"").toLowerCase().includes(t))}let T=e=>{if(!e)return"-";let s=e instanceof Date?e:new Date(1e3*e);return(0,r.jsx)(h.Zg,{date:s})};function Z(){let e=(0,l.useRouter)(),[s,t]=(0,a.useState)(!1),[n,c]=(0,a.useState)(!0),[o,d]=(0,a.useState)(!0),u=a.useRef(null),x=a.useRef(null),[j,g]=(0,a.useState)([]),[w,y]=(0,a.useState)([]),N=async function(){let e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];t(!0),!e&&o&&c(!0);try{let[e]=await Promise.all([p.default.get(m.vs,[{}])]);g(e.pools||[])}catch(e){console.error("Error fetching data:",e)}finally{t(!1),!e&&o&&(c(!1),d(!1))}};(0,a.useEffect)(()=>{N()},[]);let k=s=>{D(e,s)},C=a.useCallback(()=>{let s=new Map;s.set("",""),s.set("status","Status"),s.set("name","Name"),s.set("user","User"),s.set("workspace","Workspace"),s.set("pool","Pool"),y(F(e,s))},[e,y]);return(0,a.useEffect)(()=>{e.isReady&&C()},[e.isReady,e.query.tab,C]),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"flex flex-wrap items-center gap-2 mb-1",children:[(0,r.jsx)("div",{className:"text-base",children:(0,r.jsx)(i(),{href:"/jobs",className:"text-sky-blue hover:underline leading-none",children:"Managed Jobs"})}),(0,r.jsx)("div",{className:"w-full sm:w-auto",children:(0,r.jsx)(M,{propertyList:P,valueList:{},setFilters:y,updateURLParams:k,placeholder:"Filter jobs"})})]}),(0,r.jsx)(I,{filters:w,setFilters:y,updateURLParams:k}),(0,r.jsx)(B,{refreshInterval:h.yc,setLoading:t,refreshDataRef:u,filters:w,onRefresh:()=>{f.invalidateCache(),p.default.invalidate(m.vs,[{}]),p.default.invalidate(b.getWorkspaces),p.default.invalidate(v.R),u.current&&u.current(),x.current&&x.current()},poolsData:j,poolsLoading:n}),(0,r.jsx)("div",{className:"mb-4",children:(0,r.jsx)(V,{refreshInterval:h.yc,setLoading:t,refreshDataRef:x})})]})}function B(e){let{refreshInterval:s,setLoading:t,refreshDataRef:l,filters:n,onRefresh:j,poolsData:b,poolsLoading:v}=e,[N,k]=(0,a.useState)([]),[R,D]=(0,a.useState)(0),[F,M]=(0,a.useState)(0),[I,A]=(0,a.useState)({key:null,direction:"ascending"}),[P,J]=(0,a.useState)(!1),[U,W]=(0,a.useState)(!0),[O,Z]=(0,a.useState)(1),[B,H]=(0,a.useState)(10),[V,Y]=(0,a.useState)(null),Q=(0,a.useRef)(null),[X,$]=(0,a.useState)([]),[ee,es]=(0,a.useState)({}),[et,er]=(0,a.useState)({}),[ea,el]=(0,a.useState)(!1),[en,ei]=(0,a.useState)(!1),[ec,eo]=(0,a.useState)(!1),[ed,eu]=(0,a.useState)("all"),[eh,ex]=(0,a.useState)(!0),[em,ep]=(0,a.useState)({isOpen:!1,title:"",message:"",onConfirm:null}),ej=(0,E.X)(),ef=(0,a.useRef)(0),eg=async()=>{ep({isOpen:!0,title:"Restart Controller",message:"Are you sure you want to restart the controller?",onConfirm:async()=>{try{eo(!0),J(!0),await (0,m.Ce)("restartcontroller"),await eb()}catch(e){console.error("Error restarting controller:",e)}finally{eo(!1),J(!1)}}})},eb=a.useCallback(async function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},s=!1!==e.includeStatus,r=ef.current+1;ef.current=r,J(!0),t(!0);try{let e,t;let a=e=>{let s=(n||[]).find(s=>(s.property||"").toLowerCase()===e);return s&&s.value?String(s.value):void 0};X.length>0?t=X:eh?"active"===ed?t=z.active:"finished"===ed&&(t=z.finished):t=[];let l={allUsers:!0,nameMatch:a("name"),userMatch:a("user"),workspaceMatch:a("workspace"),poolMatch:a("pool"),statuses:t,page:O,limit:B},i=null;if(f.isDataCached(l),f.isDataLoading(l),s){let[s,t]=await Promise.all([f.getPaginatedJobs(l),p.default.get(g.getClusters)]);e=s,i=t}else e=await f.getPaginatedJobs(l);let{jobs:c=[],total:o=0,totalNoFilter:d=0,controllerStopped:u=!1,cacheStatus:h="unknown",statusCounts:x={}}=e||{},m=!1,j=!1;if(s&&i){let e=null==i?void 0:i.find(e=>(0,S.Ym)(e.cluster)),s=e?e.status:"NOT_FOUND";"STOPPED"==s&&u&&(m=!0),"LAUNCHING"==s&&(j=!0)}r===ef.current&&(k(c),D(o||0),M(d||0),el(!!m),ei(!!j),er(x),W(!1))}catch(e){console.error("Error fetching data:",e),r===ef.current&&(k([]),el(!1),W(!1))}finally{r===ef.current&&(J(!1),t(!1))}},[t,n,O,B,X,eh,ed]);a.useEffect(()=>{l&&(l.current=eb)},[l,eb]);let ev=a.useRef(eb);a.useEffect(()=>{ev.current=eb},[eb]);let ew=a.useRef(!0);a.useEffect(()=>{eb({includeStatus:!0}),ew.current=!1},[]),a.useEffect(()=>{ew.current||eb({includeStatus:!1})},[O]),a.useEffect(()=>{ew.current||eb({includeStatus:!0})},[n,B]),a.useEffect(()=>{ew.current||eb({includeStatus:!0})},[ed,X,eh]),(0,a.useEffect)(()=>{let e=setInterval(()=>{ev.current&&ev.current({includeStatus:!0})},s);return()=>{clearInterval(e)}},[s]),(0,a.useEffect)(()=>{Z(1)},[ed]),(0,a.useEffect)(()=>{Z(1)},[n,B]),(0,a.useEffect)(()=>{$([]),ex(!0)},[ed]);let ey=e=>{let s="ascending";I.key===e&&"ascending"===I.direction&&(s="descending"),A({key:e,direction:s})},eN=e=>I.key===e?"ascending"===I.direction?" ↑":" ↓":"";a.useMemo(()=>{let e=N||[];return{active:e.filter(e=>z.active.includes(e.status)).length,finished:e.filter(e=>z.finished.includes(e.status)).length}},[N]);let ek=e=>X.length>0?X.includes(e):"all"===ed||z[ed].includes(e),eC=a.useMemo(()=>N,[N]),eS=a.useMemo(()=>I.key?[...eC].sort((e,s)=>e[I.key]<s[I.key]?"ascending"===I.direction?-1:1:e[I.key]>s[I.key]?"ascending"===I.direction?1:-1:0):eC,[eC,I]),e_=(O-1)*B,eL=R>0?Math.ceil(R/B):0,eE=R>0?Math.min(e_+eS.length,R):0,eR=e=>{if(X.includes(e)){let s=X.filter(s=>s!==e);0===s.length?(ex(!0),$([])):($(s),ex(!1))}else $([...X,e]),ex(!1);Z(1)};return(0,a.useEffect)(()=>{es(et)},[et]),(0,r.jsxs)("div",{className:"relative",children:[(0,r.jsx)("div",{className:"flex flex-col space-y-1 mb-1",children:(0,r.jsxs)("div",{className:"flex flex-wrap items-center justify-between text-sm mb-1",children:[(0,r.jsxs)("div",{className:"flex flex-wrap items-center",children:[(0,r.jsx)("span",{className:"mr-2 text-sm font-medium",children:"Statuses:"}),(0,r.jsxs)("div",{className:"flex flex-wrap gap-2 items-center",children:[!P&&0===F&&!U&&(0,r.jsx)("span",{className:"text-gray-500 mr-2",children:"No jobs found"}),Object.entries(ee).map(e=>{let[s,t]=e;return(0,r.jsxs)("button",{onClick:()=>eR(s),className:"px-3 py-0.5 rounded-full flex items-center space-x-2 ".concat(ek(s)||X.includes(s)?(0,_.Cl)(s):"bg-gray-50 text-gray-600 hover:bg-gray-100"),children:[(0,r.jsx)("span",{children:s}),(0,r.jsx)("span",{className:"text-xs ".concat(ek(s)||X.includes(s)?"bg-white/50":"bg-gray-200"," px-1.5 py-0.5 rounded"),children:t})]},s)}),F>0&&(0,r.jsxs)("div",{className:"flex items-center ml-2 gap-2",children:[(0,r.jsx)("span",{className:"text-gray-500",children:"("}),(0,r.jsx)("button",{onClick:()=>{a.startTransition(()=>{eu("all"),$([]),ex(!0),Z(1)})},className:"text-sm font-medium ".concat("all"===ed&&eh?"text-purple-700 underline":"text-gray-600 hover:text-purple-700 hover:underline"),children:"show all jobs"}),(0,r.jsx)("span",{className:"text-gray-500 mx-1",children:"|"}),(0,r.jsx)("button",{onClick:()=>{a.startTransition(()=>{eu("active"),$([]),ex(!0),Z(1)})},className:"text-sm font-medium ".concat("active"===ed&&eh?"text-green-700 underline":"text-gray-600 hover:text-green-700 hover:underline"),children:"show all active jobs"}),(0,r.jsx)("span",{className:"text-gray-500 mx-1",children:"|"}),(0,r.jsx)("button",{onClick:()=>{a.startTransition(()=>{eu("finished"),$([]),ex(!0),Z(1)})},className:"text-sm font-medium ".concat("finished"===ed&&eh?"text-blue-700 underline":"text-gray-600 hover:text-blue-700 hover:underline"),children:"show all finished jobs"}),(0,r.jsx)("span",{className:"text-gray-500",children:")"})]})]})]}),(0,r.jsxs)("div",{className:"flex items-center gap-2",children:[P&&(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(c.Z,{size:15,className:"mt-0"}),(0,r.jsx)("span",{className:"ml-2 text-gray-500 text-sm",children:"Loading..."})]}),(0,r.jsxs)("button",{onClick:()=>{j&&j()},disabled:P,className:"text-sky-blue hover:text-sky-blue-bright flex items-center text-sm",children:[(0,r.jsx)(w.Z,{className:"h-4 w-4 mr-1.5"}),(0,r.jsx)("span",{children:"Refresh"})]})]})]})}),ej&&ea&&0===eS.length&&!P&&!U&&(0,r.jsx)("div",{className:"mb-4 p-4 bg-gray-50 rounded-lg border",children:(0,r.jsxs)("div",{className:"flex flex-col items-center space-y-3",children:[(0,r.jsxs)("p",{className:"text-gray-700 text-center text-sm",children:["Job controller stopped.",(0,r.jsx)("br",{}),"Restart to check status."]}),(0,r.jsx)(o.z,{variant:"outline",size:"sm",onClick:eg,className:"text-sky-blue hover:text-sky-blue-bright",disabled:P||ec,children:ec?(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(c.Z,{size:12,className:"mr-2"}),"Restarting..."]}):(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(y.Z,{className:"h-4 w-4 mr-2"}),"Restart"]})})]})}),(0,r.jsx)(d.Zb,{children:(0,r.jsx)("div",{className:"overflow-x-auto rounded-lg",children:(0,r.jsxs)(u.iA,{className:"min-w-full",children:[(0,r.jsx)(u.xD,{children:(0,r.jsxs)(u.SC,{children:[(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>ey("id"),children:["ID",eN("id")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>ey("name"),children:["Name",eN("name")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>ey("user"),children:["User",eN("user")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>ey("workspace"),children:["Workspace",eN("workspace")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>ey("submitted_at"),children:["Submitted",eN("submitted_at")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>ey("job_duration"),children:["Duration",eN("job_duration")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>ey("status"),children:["Status",eN("status")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>ey("resources_str"),children:["Requested",eN("resources_str")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>ey("infra"),children:["Infra",eN("infra")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>ey("cluster"),children:["Resources",eN("cluster")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>ey("recoveries"),children:["Recoveries",eN("recoveries")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>ey("pool"),children:["Worker Pool",eN("pool")]}),(0,r.jsx)(u.ss,{children:"Details"}),(0,r.jsx)(u.ss,{children:"Logs"})]})}),(0,r.jsx)(u.RM,{children:P&&U?(0,r.jsx)(u.SC,{children:(0,r.jsx)(u.pj,{colSpan:12,className:"text-center py-6 text-gray-500",children:(0,r.jsxs)("div",{className:"flex justify-center items-center",children:[(0,r.jsx)(c.Z,{size:20,className:"mr-2"}),(0,r.jsx)("span",{children:"Loading..."})]})})}):eS.length>0?(0,r.jsx)(r.Fragment,{children:eS.map(e=>(0,r.jsxs)(a.Fragment,{children:[(0,r.jsxs)(u.SC,{children:[(0,r.jsx)(u.pj,{children:(0,r.jsx)(i(),{href:"/jobs/".concat(e.id),className:"text-blue-600",children:e.id})}),(0,r.jsx)(u.pj,{children:(0,r.jsx)(i(),{href:"/jobs/".concat(e.id),className:"text-blue-600",children:e.name})}),(0,r.jsx)(u.pj,{children:(0,r.jsx)(L.H,{username:e.user,userHash:e.user_hash})}),(0,r.jsx)(u.pj,{children:(0,r.jsx)(i(),{href:"/workspaces",className:"text-gray-700 hover:text-blue-600 hover:underline",children:e.workspace||"default"})}),(0,r.jsx)(u.pj,{children:T(e.submitted_at)}),(0,r.jsx)(u.pj,{children:(0,h.LU)(e.job_duration)}),(0,r.jsx)(u.pj,{children:(0,r.jsx)(_.OE,{status:e.status})}),(0,r.jsx)(u.pj,{children:e.requested_resources}),(0,r.jsx)(u.pj,{children:e.infra&&"-"!==e.infra?(0,r.jsx)(h.Md,{content:e.full_infra||e.infra,className:"text-sm text-muted-foreground",children:(0,r.jsxs)("span",{children:[(0,r.jsx)(i(),{href:"/infra",className:"text-blue-600 hover:underline",children:e.cloud||e.infra.split("(")[0].trim()}),e.infra.includes("(")&&(0,r.jsx)("span",{children:" "+(()=>{let s=x.MO.NAME_TRUNCATE_LENGTH,t=e.infra.substring(e.infra.indexOf("(")),r=t.substring(1,t.length-1);if(r.length<=s)return t;let a="".concat(r.substring(0,Math.floor((s-3)/2)),"...").concat(r.substring(r.length-Math.ceil((s-3)/2)));return"(".concat(a,")")})()})]})}):(0,r.jsx)("span",{children:e.infra||"-"})}),(0,r.jsx)(u.pj,{children:(0,r.jsx)(h.Md,{content:e.resources_str_full||e.resources_str,className:"text-sm text-muted-foreground",children:(0,r.jsx)("span",{children:e.resources_str})})}),(0,r.jsx)(u.pj,{children:e.recoveries}),(0,r.jsx)(u.pj,{children:(0,r.jsx)("div",{className:v?"blur-sm transition-all duration-300":"",children:v?"-":(0,h.os)(e.pool,e.pool_hash,b)})}),(0,r.jsx)(u.pj,{children:e.details?(0,r.jsx)(G,{text:e.details,rowId:e.id,expandedRowId:V,setExpandedRowId:Y}):"-"}),(0,r.jsx)(u.pj,{children:(0,r.jsx)(q,{jobParent:"/jobs",jobId:e.id,managed:!0,workspace:e.workspace})})]}),V===e.id&&(0,r.jsx)(K,{text:e.details,colSpan:13,innerRef:Q})]},e.task_job_id))}):(0,r.jsx)(u.SC,{children:(0,r.jsx)(u.pj,{colSpan:13,className:"text-center py-6",children:(0,r.jsxs)("div",{className:"flex flex-col items-center space-y-4",children:[en&&(0,r.jsxs)("div",{className:"flex flex-col items-center space-y-2",children:[(0,r.jsx)("p",{className:"text-gray-700",children:"The managed job controller is launching. It will be ready shortly."}),(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(c.Z,{size:12,className:"mr-2"}),(0,r.jsx)("span",{className:"text-gray-500",children:"Launching..."})]})]}),!ea&&!en&&(0,r.jsx)("p",{className:"text-gray-500",children:"No active jobs"}),!ej&&ea&&(0,r.jsxs)("div",{className:"flex flex-col items-center space-y-3 px-4",children:[(0,r.jsx)("p",{className:"text-gray-700 text-center text-sm sm:text-base max-w-md",children:"The managed job controller has been stopped. Restart to check the latest job status."}),(0,r.jsx)(o.z,{variant:"outline",size:"sm",onClick:eg,className:"text-sky-blue hover:text-sky-blue-bright",disabled:P||ec,children:ec?(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(c.Z,{size:12,className:"mr-2"}),"Restarting..."]}):(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(y.Z,{className:"h-4 w-4 mr-2"}),"Restart Controller"]})})]})]})})})})]})})}),(0,r.jsx)("div",{className:"flex justify-end items-center py-2 px-4 text-sm text-gray-700",children:(0,r.jsxs)("div",{className:"flex items-center space-x-4",children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)("span",{className:"mr-2",children:"Rows per page:"}),(0,r.jsxs)("div",{className:"relative inline-block",children:[(0,r.jsxs)("select",{value:B,onChange:e=>{H(parseInt(e.target.value,10)),Z(1)},className:"py-1 pl-2 pr-6 appearance-none outline-none cursor-pointer border-none bg-transparent",style:{minWidth:"40px"},children:[(0,r.jsx)("option",{value:10,children:"10"}),(0,r.jsx)("option",{value:30,children:"30"}),(0,r.jsx)("option",{value:50,children:"50"}),(0,r.jsx)("option",{value:100,children:"100"}),(0,r.jsx)("option",{value:200,children:"200"})]}),(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4 text-gray-500 absolute right-0 top-1/2 transform -translate-y-1/2 pointer-events-none",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:(0,r.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]})]}),(0,r.jsx)("div",{children:R>0?"".concat(e_+1," – ").concat(eE," of ").concat(R):"0 – 0 of 0"}),(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,r.jsx)(o.z,{variant:"ghost",size:"icon",onClick:()=>{Z(e=>Math.max(e-1,1))},disabled:1===O||!eS||0===eS.length,className:"text-gray-500 h-8 w-8 p-0",children:(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"chevron-left",children:(0,r.jsx)("path",{d:"M15 18l-6-6 6-6"})})}),(0,r.jsx)(o.z,{variant:"ghost",size:"icon",onClick:()=>{eL>0&&O<eL&&Z(e=>e+1)},disabled:0===eL||O>=eL||!eS||0===eS.length,className:"text-gray-500 h-8 w-8 p-0",children:(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"chevron-right",children:(0,r.jsx)("path",{d:"M9 18l6-6-6-6"})})})]})]})}),(0,r.jsx)(C.cV,{isOpen:em.isOpen,onClose:()=>ep({...em,isOpen:!1}),onConfirm:em.onConfirm,title:em.title,message:em.message,confirmClassName:"bg-blue-600 hover:bg-blue-700 text-white"})]})}function q(e){let{withLabel:s=!1,jobParent:t,jobId:a,managed:n,workspace:i="default"}=e,c=(0,l.useRouter)(),o=(e,s)=>{e.preventDefault(),e.stopPropagation(),c.push({pathname:"".concat(t,"/").concat(a),query:{tab:s}})},d=function(e){let s=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(e.preventDefault(),e.stopPropagation(),n)(0,m.jh)({jobId:parseInt(a),controller:s});else{let e=t.match(/\/clusters\/(.+)/);if(e){let s=e[1];(0,g.GH)({clusterName:s,jobIds:[a],workspace:i})}}};return(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,r.jsx)(h.WH,{content:"View Job Logs",className:"capitalize text-sm text-muted-foreground",children:(0,r.jsxs)("button",{onClick:e=>o(e,"logs"),className:"text-sky-blue hover:text-sky-blue-bright font-medium inline-flex items-center h-8",children:[(0,r.jsx)(N.Z,{className:"w-4 h-4"}),s&&(0,r.jsx)("span",{className:"ml-1.5",children:"Logs"})]})},"logs"),(0,r.jsx)(h.WH,{content:"Download Job Logs",className:"capitalize text-sm text-muted-foreground",children:(0,r.jsxs)("button",{onClick:e=>d(e,!1),className:"text-sky-blue hover:text-sky-blue-bright font-medium inline-flex items-center h-8",children:[(0,r.jsx)(k.Z,{className:"w-4 h-4"}),s&&(0,r.jsx)("span",{className:"ml-1.5",children:"Download"})]})},"downloadlogs")]})}function H(e){let{clusterName:s,clusterJobData:t,loading:l,refreshClusterJobsOnly:n,userFilter:x=null,nameFilter:m=null,workspace:p="default"}=e,[j,f]=(0,a.useState)(null),[g,b]=(0,a.useState)({key:null,direction:"ascending"}),[v,y]=(0,a.useState)(1),[N,k]=(0,a.useState)(10),C=(0,a.useRef)(null),[S,E]=(0,a.useState)(null);(0,a.useEffect)(()=>{let e=e=>{j&&C.current&&!C.current.contains(e.target)&&f(null)};return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[j]);let R=a.useMemo(()=>{let e=t||[];return x&&"ALL_USERS"!==x&&(e=W(e,x)),m&&(e=J(e,m)),e},[t,x,m]);(0,a.useEffect)(()=>{JSON.stringify(t)!==JSON.stringify(S)&&E(t)},[t,S]);let D=a.useMemo(()=>g.key?[...R].sort((e,s)=>e[g.key]<s[g.key]?"ascending"===g.direction?-1:1:e[g.key]>s[g.key]?"ascending"===g.direction?1:-1:0):R,[R,g]),F=e=>{let s="ascending";g.key===e&&"ascending"===g.direction&&(s="descending"),b({key:e,direction:s})},M=e=>g.key===e?"ascending"===g.direction?" ↑":" ↓":"",I=Math.ceil(D.length/N),A=(v-1)*N,z=A+N,P=D.slice(A,z);return(0,r.jsxs)("div",{className:"relative",children:[(0,r.jsxs)(d.Zb,{children:[(0,r.jsxs)("div",{className:"flex items-center justify-between p-4",children:[(0,r.jsx)("h3",{className:"text-lg font-semibold",children:"Cluster Jobs"}),(0,r.jsx)("div",{className:"flex items-center",children:n&&(0,r.jsxs)("button",{onClick:n,disabled:l,className:"text-sky-blue hover:text-sky-blue-bright font-medium inline-flex items-center text-sm ml-2",children:[(0,r.jsx)(w.Z,{className:"w-4 h-4 mr-1"}),"Refresh Jobs"]})})]}),(0,r.jsxs)(u.iA,{children:[(0,r.jsx)(u.xD,{children:(0,r.jsxs)(u.SC,{children:[(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>F("id"),children:["ID",M("id")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>F("job"),children:["Name",M("job")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>F("user"),children:["User",M("user")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>F("workspace"),children:["Workspace",M("workspace")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>F("submitted_at"),children:["Submitted",M("submitted_at")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>F("job_duration"),children:["Duration",M("job_duration")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>F("status"),children:["Status",M("status")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap",onClick:()=>F("resources"),children:["Resources",M("resources")]}),(0,r.jsx)(u.ss,{className:"whitespace-nowrap",children:"Logs"})]})}),(0,r.jsx)(u.RM,{children:l?(0,r.jsx)(u.SC,{children:(0,r.jsx)(u.pj,{colSpan:9,className:"text-center py-12 text-gray-500",children:(0,r.jsxs)("div",{className:"flex justify-center items-center",children:[(0,r.jsx)(c.Z,{size:24,className:"mr-2"}),(0,r.jsx)("span",{children:"Loading cluster jobs..."})]})})}):P.length>0?P.map(e=>(0,r.jsxs)(a.Fragment,{children:[(0,r.jsxs)(u.SC,{className:j===e.id?"selected-row":"",children:[(0,r.jsx)(u.pj,{children:(0,r.jsx)(i(),{href:"/clusters/".concat(s,"/").concat(e.id),className:"text-blue-600",children:e.id})}),(0,r.jsx)(u.pj,{children:(0,r.jsx)(i(),{href:"/clusters/".concat(s,"/").concat(e.id),className:"text-blue-600",children:(0,r.jsx)(G,{text:e.job||"Unnamed job",rowId:e.id,expandedRowId:j,setExpandedRowId:f})})}),(0,r.jsx)(u.pj,{children:(0,r.jsx)(L.H,{username:e.user,userHash:e.user_hash})}),(0,r.jsx)(u.pj,{children:(0,r.jsx)(i(),{href:"/workspaces",className:"text-gray-700 hover:text-blue-600 hover:underline",children:e.workspace||"default"})}),(0,r.jsx)(u.pj,{children:T(e.submitted_at)}),(0,r.jsx)(u.pj,{children:(0,h.LU)(e.job_duration)}),(0,r.jsx)(u.pj,{children:(0,r.jsx)(_.OE,{status:e.status})}),(0,r.jsx)(u.pj,{children:e.resources}),(0,r.jsx)(u.pj,{className:"flex content-center items-center",children:(0,r.jsx)(q,{jobParent:"/clusters/".concat(s),jobId:e.id,managed:!1,workspace:p})})]}),j===e.id&&(0,r.jsx)(K,{text:e.job||"Unnamed job",colSpan:9,innerRef:C})]},e.id)):(0,r.jsx)(u.SC,{children:(0,r.jsx)(u.pj,{colSpan:8,className:"text-center py-6 text-gray-500",children:"No jobs found"})})})]})]}),D&&D.length>0&&(0,r.jsx)("div",{className:"flex justify-end items-center py-2 px-4 text-sm text-gray-700",children:(0,r.jsxs)("div",{className:"flex items-center space-x-4",children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)("span",{className:"mr-2",children:"Rows per page:"}),(0,r.jsxs)("div",{className:"relative inline-block",children:[(0,r.jsxs)("select",{value:N,onChange:e=>{k(parseInt(e.target.value,10)),y(1)},className:"py-1 pl-2 pr-6 appearance-none outline-none cursor-pointer border-none bg-transparent",style:{minWidth:"40px"},children:[(0,r.jsx)("option",{value:5,children:"5"}),(0,r.jsx)("option",{value:10,children:"10"}),(0,r.jsx)("option",{value:20,children:"20"}),(0,r.jsx)("option",{value:50,children:"50"})]}),(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4 text-gray-500 absolute right-0 top-1/2 transform -translate-y-1/2 pointer-events-none",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:(0,r.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]})]}),(0,r.jsxs)("div",{children:[A+1," – ",Math.min(z,D.length)," of"," ",D.length]}),(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,r.jsx)(o.z,{variant:"ghost",size:"icon",onClick:()=>{y(e=>Math.max(e-1,1))},disabled:1===v,className:"text-gray-500 h-8 w-8 p-0",children:(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"chevron-left",children:(0,r.jsx)("path",{d:"M15 18l-6-6 6-6"})})}),(0,r.jsx)(o.z,{variant:"ghost",size:"icon",onClick:()=>{y(e=>Math.min(e+1,I))},disabled:v===I||0===I,className:"text-gray-500 h-8 w-8 p-0",children:(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"chevron-right",children:(0,r.jsx)("path",{d:"M9 18l6-6-6-6"})})})]})]})})]})}function K(e){let{text:s,colSpan:t,innerRef:a}=e;return(0,r.jsx)(u.SC,{className:"expanded-details",children:(0,r.jsx)(u.pj,{colSpan:t,children:(0,r.jsx)("div",{className:"p-4 bg-gray-50 rounded-md border border-gray-200",ref:a,children:(0,r.jsx)("div",{className:"flex justify-between items-start",children:(0,r.jsxs)("div",{className:"flex-1",children:[(0,r.jsx)("p",{className:"text-sm font-medium text-gray-900",children:"Full Details"}),(0,r.jsx)("p",{className:"mt-1 text-sm text-gray-700",style:{whiteSpace:"pre-wrap"},children:s})]})})})})})}function G(e){let{text:s,rowId:t,expandedRowId:l,setExpandedRowId:n}=e,i=s||"",c=i.length>50,o=l===t,d=c?"".concat(i.substring(0,50)):i,u=(0,a.useRef)(null);return(0,r.jsxs)("div",{className:"truncated-details relative max-w-full flex items-center",children:[(0,r.jsx)("span",{className:"truncate",children:d}),c&&(0,r.jsx)("button",{ref:u,type:"button",onClick:e=>{e.preventDefault(),e.stopPropagation(),n(o?null:t)},className:"text-blue-600 hover:text-blue-800 font-medium ml-1 flex-shrink-0","data-button-type":"show-more-less",children:o?"... show less":"... show more"})]})}function V(e){let{refreshInterval:s,setLoading:t,refreshDataRef:l}=e,[n,o]=(0,a.useState)([]),[x,j]=(0,a.useState)({key:null,direction:"ascending"}),[f,g]=(0,a.useState)(!1),[b,v]=(0,a.useState)(!0),[w,y]=(0,a.useState)(1),[N,k]=(0,a.useState)(10),C=a.useCallback(async()=>{g(!0),t(!0);try{let{pools:e=[]}=await p.default.get(m.vs,[{}])||{};o(e),v(!1)}catch(e){console.error("Error fetching pools data:",e),o([]),v(!1)}finally{g(!1),t(!1)}},[t]);a.useEffect(()=>{l&&(l.current=C)},[l,C]),(0,a.useEffect)(()=>{o([]);let e=!0;C();let t=setInterval(()=>{e&&C()},s);return()=>{e=!1,clearInterval(t)}},[s,C]);let S=e=>{let s="ascending";x.key===e&&"ascending"===x.direction&&(s="descending"),j({key:e,direction:s})},L=e=>x.key===e?"ascending"===x.direction?" ↑":" ↓":"",E=a.useMemo(()=>x.key?[...n].sort((e,s)=>e[x.key]<s[x.key]?"ascending"===x.direction?-1:1:e[x.key]>s[x.key]?"ascending"===x.direction?1:-1:0):n,[n,x]),R=Math.ceil(E.length/N),D=(w-1)*N,F=D+N,M=E.slice(D,F),I=e=>{if(!e||!e.replica_info||0===e.replica_info.length)return"0 (target: 0)";let s=e.replica_info.filter(e=>"READY"===e.status).length,t=e.target_num_replicas||0;return"".concat(s," (target: ").concat(t,")")},A=e=>{let{jobCounts:s}=e;return(0,r.jsx)(h.x9,{jobCounts:s,getStatusStyle:_.Cl})},z=e=>{let{replicaInfo:s}=e;return(0,r.jsx)(h.Kl,{replicaInfo:s})};return(0,r.jsxs)(d.Zb,{children:[(0,r.jsx)("div",{className:"overflow-x-auto rounded-lg",children:(0,r.jsxs)(u.iA,{className:"min-w-full table-fixed",children:[(0,r.jsx)(u.xD,{children:(0,r.jsxs)(u.SC,{children:[(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap w-32",onClick:()=>S("name"),children:["Pool",L("name")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap w-40",onClick:()=>S("job_counts"),children:["Jobs",L("job_counts")]}),(0,r.jsx)(u.ss,{className:"whitespace-nowrap w-20",children:"Workers"}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap w-36",onClick:()=>S("requested_resources_str"),children:["Worker Details",L("requested_resources_str")]}),(0,r.jsxs)(u.ss,{className:"sortable whitespace-nowrap w-40",onClick:()=>S("requested_resources_str"),children:["Worker Resources",L("requested_resources_str")]})]})}),(0,r.jsx)(u.RM,{children:f&&b?(0,r.jsx)(u.SC,{children:(0,r.jsx)(u.pj,{colSpan:5,className:"text-center py-6 text-gray-500",children:(0,r.jsxs)("div",{className:"flex justify-center items-center",children:[(0,r.jsx)(c.Z,{size:20,className:"mr-2"}),(0,r.jsx)("span",{children:"Loading..."})]})})}):M.length>0?M.map(e=>(0,r.jsxs)(u.SC,{children:[(0,r.jsx)(u.pj,{children:(0,r.jsx)(i(),{href:"/jobs/pools/".concat(e.name),className:"text-blue-600 hover:text-blue-800",children:e.name})}),(0,r.jsx)(u.pj,{children:(0,r.jsx)(A,{jobCounts:e.jobCounts})}),(0,r.jsx)(u.pj,{children:I(e)}),(0,r.jsx)(u.pj,{children:(0,r.jsx)(z,{replicaInfo:e.replica_info})}),(0,r.jsx)(u.pj,{children:e.requested_resources_str||"-"})]},e.name)):(0,r.jsx)(u.SC,{children:(0,r.jsx)(u.pj,{colSpan:5,className:"text-center py-6 text-gray-500",children:"No pools found"})})})]})}),M.length>0&&R>1&&(0,r.jsxs)("div",{className:"flex items-center justify-between px-4 py-3 border-t border-gray-200",children:[(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,r.jsx)("span",{className:"text-sm text-gray-700",children:"Rows per page:"}),(0,r.jsxs)("select",{value:N,onChange:e=>{k(parseInt(e.target.value,10)),y(1)},className:"border border-gray-300 rounded px-2 py-1 text-sm",children:[(0,r.jsx)("option",{value:5,children:"5"}),(0,r.jsx)("option",{value:10,children:"10"}),(0,r.jsx)("option",{value:25,children:"25"}),(0,r.jsx)("option",{value:50,children:"50"})]})]}),(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,r.jsxs)("span",{className:"text-sm text-gray-700",children:[D+1,"-",Math.min(F,E.length)," of"," ",E.length]}),(0,r.jsx)("button",{onClick:()=>{y(e=>Math.max(e-1,1))},disabled:1===w,className:"px-2 py-1 text-sm border border-gray-300 rounded disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-50",children:"Previous"}),(0,r.jsx)("button",{onClick:()=>{y(e=>Math.min(e+1,R))},disabled:w===R,className:"px-2 py-1 text-sm border border-gray-300 rounded disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-50",children:"Next"})]})]})]})}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[8969],{68969:function(e,t,o){o.d(t,{Ce:function(){return p},NJ:function(){return h},UA:function(){return u},aT:function(){return l},getManagedJobs:function(){return i},jh:function(){return g},vs:function(){return d}});var r=o(67294),a=o(15821),n=o(93225),s=o(6378),c=o(47145);async function i(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};try{var t;let{allUsers:o=!0,skipFinished:r=!1,nameMatch:a,userMatch:s,workspaceMatch:i,poolMatch:l,page:d,limit:u,statuses:h}=e,p={all_users:o,verbose:!0,skip_finished:r};void 0!==a&&(p.name_match=a),void 0!==s&&(p.user_match=s),void 0!==i&&(p.workspace_match=i),void 0!==l&&(p.pool_match=l),void 0!==d&&(p.page=d),void 0!==u&&(p.limit=u),void 0!==h&&h.length>0&&(p.statuses=h);let g=(await c.x.post("/jobs/queue/v2",p)).headers.get("X-Skypilot-Request-ID"),b=await c.x.get("/api/get?request_id=".concat(g));if(500===b.status){try{let e=await b.json();if(e.detail&&e.detail.error)try{let t=JSON.parse(e.detail.error);if(t.type&&t.type===n.iW)return{jobs:[],total:0,controllerStopped:!0}}catch(e){console.error("Error parsing JSON:",e)}}catch(e){console.error("Error parsing JSON:",e)}return{jobs:[],total:0,controllerStopped:!1}}let f=await b.json(),m=f.return_value?JSON.parse(f.return_value):[],_=Array.isArray(m)?m:(null==m?void 0:m.jobs)||[],y=Array.isArray(m)?_.length:null!==(t=null==m?void 0:m.total)&&void 0!==t?t:_.length,w=(null==m?void 0:m.total_no_filter)||y,j=(null==m?void 0:m.status_counts)||{};return{jobs:_.map(e=>{var t;let o=0;e.end_at&&e.submitted_at?o=e.end_at-e.submitted_at:e.submitted_at&&(o=Date.now()/1e3-e.submitted_at);let r=[];e.submitted_at&&r.push({type:"PENDING",timestamp:e.submitted_at}),e.start_at&&r.push({type:"RUNNING",timestamp:e.start_at}),e.end_at&&r.push({type:e.status,timestamp:e.end_at});let a="",n="",s="",c="",i="";try{if(a=e.cloud||"",s=e.cluster_resources,n=e.region||"",a&&(c=a,n&&(c+="/".concat(n))),i=c,e.accelerators){let t=Object.entries(e.accelerators).map(e=>{let[t,o]=e;return"".concat(o,"x").concat(t)}).join(", ");t&&(i+=" (".concat(t,")"))}}catch(t){s=e.cluster_resources}return{id:e.job_id,task_job_id:e._job_id,task:e.task_name,name:e.job_name,job_duration:e.job_duration,total_duration:o,workspace:e.workspace,status:e.status,requested_resources:e.resources,resources_str:s,resources_str_full:e.cluster_resources_full||s,cloud:a,region:e.region,infra:c,full_infra:i,recoveries:e.recovery_count,details:e.details||e.failure_reason,user:e.user_name,user_hash:e.user_hash,submitted_at:e.submitted_at?new Date(1e3*e.submitted_at):null,events:r,dag_yaml:e.user_yaml,entrypoint:e.entrypoint,git_commit:(null===(t=e.metadata)||void 0===t?void 0:t.git_commit)||"-",pool:e.pool,pool_hash:e.pool_hash,current_cluster_name:e.current_cluster_name,job_id_on_pool_cluster:e.job_id_on_pool_cluster}}),total:y,totalNoFilter:w,controllerStopped:!1,statusCounts:j}}catch(e){return console.error("Error fetching managed job data:",e),{jobs:[],total:0,totalNoFilter:0,controllerStopped:!1,statusCounts:{}}}}async function l(e){let{allUsers:t=!0,nameMatch:o,userMatch:r,workspaceMatch:a,poolMatch:n,page:s=1,limit:c=10,useClientPagination:l=!0}=e||{};try{if(!l)return await i(e);let d=await i({allUsers:t,nameMatch:o,userMatch:r,workspaceMatch:a,poolMatch:n});if(d.controllerStopped||!d.jobs)return d;let u=d.jobs,h=u.length,p=(s-1)*c;return{jobs:u.slice(p,p+c),total:h,controllerStopped:!1}}catch(e){return console.error("Error fetching managed job data with client pagination:",e),{jobs:[],total:0,controllerStopped:!1}}}async function d(){try{let e=(await c.x.post("/jobs/pool_status",{pool_names:null})).headers.get("X-Skypilot-Request-ID"),t=await c.x.get("/api/get?request_id=".concat(e));if(500===t.status){try{let e=await t.json();if(e.detail&&e.detail.error)try{let t=JSON.parse(e.detail.error);if(t.type&&t.type===n.iW)return{pools:[],controllerStopped:!0}}catch(e){console.error("Failed to parse error JSON:",e)}}catch(e){console.error("Failed to parse response JSON:",e)}throw Error("Server error")}let o=await t.json(),r=o.return_value?JSON.parse(o.return_value):[],a={jobs:[]};try{let e=await i({allUsers:!0,skipFinished:!0});e.controllerStopped||(a=e)}catch(e){console.warn("Failed to fetch jobs for pool job counts:",e)}let s={},l=["SUCCEEDED","FAILED","FAILED_SETUP","FAILED_PRECHECKS","FAILED_NO_RESOURCE","FAILED_CONTROLLER","CANCELLED"];return a.jobs&&Array.isArray(a.jobs)&&a.jobs.forEach(e=>{let t=e.pool,o=e.status;t&&!l.includes(o)&&(s[t]||(s[t]={}),s[t][o]=(s[t][o]||0)+1)}),{pools:r.map(e=>({...e,jobCounts:s[e.name]||{}})),controllerStopped:!1}}catch(e){throw console.error("Error fetching pools:",e),e}}function u(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,[o,a]=(0,r.useState)(null),[n,c]=(0,r.useState)(!0);return(0,r.useEffect)(()=>{(async function(){if(e)try{var t;c(!0);let o=await s.default.get(i,[{allUsers:!0}]),r=null==o?void 0:null===(t=o.jobs)||void 0===t?void 0:t.find(t=>String(t.id)===String(e));r?a({jobs:[r],controllerStopped:o.controllerStopped||!1}):a({jobs:[],controllerStopped:o.controllerStopped||!1})}catch(e){console.error("Error fetching single managed job data:",e),a({jobs:[],controllerStopped:!1})}finally{c(!1)}})()},[e,t]),{jobData:o,loading:n}}async function h(e){let t,{jobId:o,controller:r=!1,signal:s,onNewLog:c}=e,i=Date.now(),l=new Promise(e=>{let o=()=>{let r=Date.now()-i;r>=3e4?e({timeout:!0}):t=setTimeout(o,3e4-r)};t=setTimeout(o,3e4)}),d=window.location.origin,u="".concat(d).concat(n.f4),h=(async()=>{try{let e=(await fetch("".concat(u,"/jobs/logs"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({controller:r,follow:!1,job_id:o,tail:1e4}),...s?{signal:s}:{}})).body.getReader();try{for(;;){let{done:t,value:o}=await e.read();if(t)break;i=Date.now();let r=new TextDecoder().decode(o);c(r)}}finally{if(!s||!s.aborted)try{e.cancel()}catch(e){"AbortError"!==e.name&&console.warn("Error canceling reader:",e)}t&&clearTimeout(t)}return{timeout:!1}}catch(e){if(t&&clearTimeout(t),"AbortError"===e.name)return{timeout:!1};throw e}})(),p=await Promise.race([h,l]);if(t&&clearTimeout(t),p.timeout){(0,a.C)("Log request for job ".concat(o," timed out after ").concat(30,"s of inactivity"),"warning");return}}async function p(e,t,o){let r="",s="",c="",i={};if("restartcontroller"===e)r="Restarting",s="restarted",c="jobs/queue/v2",i={all_users:!0,refresh:!0},t="controller";else throw Error("Invalid action: ".concat(e));(0,a.C)("".concat(r," job ").concat(t,"..."),"info");let l=window.location.origin,d="".concat(l).concat(n.f4);try{try{let e=(await fetch("".concat(d,"/").concat(c),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)})).headers.get("X-Skypilot-Request-ID"),l=await fetch("".concat(d,"/api/get?request_id=").concat(e));if(200===l.status)(0,a.C)("Job ".concat(t," ").concat(s," successfully."),"success");else if(500===l.status)try{let e=await l.json();if(e.detail&&e.detail.error)try{let s=JSON.parse(e.detail.error);s.type&&s.type===n.Bo?(0,a.C)("".concat(r," job ").concat(t," is not supported!"),"error",1e4):s.type&&s.type===n.mF?(0,a.C)("Cluster ".concat(o," does not exist."),"error"):s.type&&s.type===n.iW?(0,a.C)("Cluster ".concat(o," is not up."),"error"):(0,a.C)("".concat(r," job ").concat(t," failed: ").concat(s.type),"error")}catch(o){(0,a.C)("".concat(r," job ").concat(t," failed: ").concat(e.detail.error),"error")}else(0,a.C)("".concat(r," job ").concat(t," failed with no details."),"error")}catch(e){(0,a.C)("".concat(r," job ").concat(t," failed with parse error."),"error")}else(0,a.C)("".concat(r," job ").concat(t," failed with status ").concat(l.status,"."),"error")}catch(e){console.error("Fetch error:",e),(0,a.C)("Network error ".concat(r," job ").concat(t,": ").concat(e.message),"error")}}catch(e){console.error("Error in handleStop:",e),(0,a.C)("Critical error ".concat(r," job ").concat(t,": ").concat(e.message),"error")}}async function g(e){let{jobId:t=null,name:o=null,controller:r=!1}=e;try{let e=await c.x.fetch("/jobs/download_logs",{job_id:t,name:o,controller:r,refresh:!1}),s=Object.values(e||{});if(!s.length){(0,a.C)("No logs found to download.","warning");return}let i=window.location.origin,l="".concat(i).concat(n.f4,"/download"),d=await fetch("".concat(l,"?relative=items"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({folder_paths:s})});if(!d.ok){let e=await d.text();throw Error("Download failed: ".concat(d.status," ").concat(e))}let u=await d.blob(),h=window.URL.createObjectURL(u),p=document.createElement("a"),g=new Date().toISOString().replace(/[:.]/g,"-"),b=t?"job-".concat(t):o?"job-".concat(o):"job";p.href=h,p.download="managed-".concat(b,"-").concat(r?"controller-logs":"logs","-").concat(g,".zip"),document.body.appendChild(p),p.click(),p.remove(),window.URL.revokeObjectURL(h)}catch(e){console.error("Error downloading managed job logs:",e),(0,a.C)("Error downloading managed job logs: ".concat(e.message),"error")}}},15821:function(e,t,o){o.d(t,{C:function(){return r}});function r(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"info",o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:5e3,r=document.getElementById("toast-container");r||((r=document.createElement("div")).id="toast-container",r.className="fixed top-0 right-0 p-4 z-[9999] flex flex-col items-end space-y-2",document.body.appendChild(r));let a=document.createElement("div");switch(a.className="rounded-md border-l-4 p-4 shadow-md flex items-center justify-between max-w-md w-full mb-2 pointer-events-auto",t){case"success":a.className+=" bg-green-100 border-green-500 text-green-800";break;case"error":a.className+=" bg-red-100 border-red-500 text-red-800";break;case"warning":a.className+=" bg-yellow-100 border-yellow-500 text-yellow-800";break;default:a.className+=" bg-blue-100 border-blue-500 text-blue-800"}return a.innerHTML='\n <div class="flex-1 mr-2">\n <p class="text-sm font-medium">'.concat(e,'</p>\n </div>\n <button class="text-gray-500 hover:text-gray-700 focus:outline-none" aria-label="Close toast">\n <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">\n <line x1="18" y1="6" x2="6" y2="18"></line>\n <line x1="6" y1="6" x2="18" y2="18"></line>\n </svg>\n </button>\n '),r.appendChild(a),a.querySelector("button").addEventListener("click",()=>{r.removeChild(a)}),setTimeout(()=>{r.contains(a)&&r.removeChild(a)},o),a}},6378:function(e,t,o){o.r(t),o.d(t,{DashboardCache:function(){return n},dashboardCache:function(){return s}});let r=o(51214).ej.DEFAULT_TTL;function a(e){let t=5381;for(let o=0;o<e.length;o++)t=(t<<5)+t+e.charCodeAt(o);return t>>>0}class n{setPreloader(e){this.preloader=e}async get(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},a=o.ttl||r,n=!1!==o.refreshOnAccess,s=this._generateKey(e,t),c=e.name||"anonymous",i=this.cache.get(s),l=Date.now();if(i&&l-i.lastUpdated<a){let o=Math.round((l-i.lastUpdated)/1e3);if(this._debug("Cache HIT for ".concat(c," (age: ").concat(o,"s, TTL: ").concat(Math.round(a/1e3),"s)")),n&&(this.cache.set(s,{data:i.data,lastUpdated:l}),this._debug("Cache TTL refreshed for ".concat(c))),!this.backgroundJobs.has(s)){var d;(null===(d=this.preloader)||void 0===d?void 0:d.wasRecentlyPreloaded(e,t))?this._debug("Skipping background refresh for ".concat(c," - recently preloaded")):this._refreshInBackground(e,t,s)}return i.data}if(this.pendingRequests.has(s))return this._debug("Request deduplication: Waiting for pending request for ".concat(c)),this.pendingRequests.get(s);let u=(async()=>{try{let o=await e(...t);return this.cache.set(s,{data:o,lastUpdated:Date.now()}),o}catch(e){if(i)return console.warn("Failed to fetch fresh data for ".concat(s,", returning stale data:"),e),i.data;throw e}finally{this.pendingRequests.delete(s)}})();return this.pendingRequests.set(s,u),u}invalidate(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],o=this._generateKey(e,t);this.cache.delete(o),this.backgroundJobs.delete(o),this.pendingRequests.delete(o)}invalidateFunction(e){let t=a(e.toString()),o=[];for(let e of this.cache.keys())e.startsWith("".concat(t,"_"))&&o.push(e);o.forEach(e=>{this.cache.delete(e),this.backgroundJobs.delete(e),this.pendingRequests.delete(e)})}clear(){this.cache.clear(),this.backgroundJobs.clear(),this.pendingRequests.clear()}getStats(){return{cacheSize:this.cache.size,backgroundJobs:this.backgroundJobs.size,pendingRequests:this.pendingRequests.size,keys:Array.from(this.cache.keys())}}getDetailedStats(){let e=Date.now(),t=[];for(let[o,r]of this.cache.entries()){let a=e-r.lastUpdated;t.push({key:o,age:Math.round(a/1e3),lastUpdated:new Date(r.lastUpdated).toISOString(),hasBackgroundJob:this.backgroundJobs.has(o),hasPendingRequest:this.pendingRequests.has(o)})}return{cacheSize:this.cache.size,backgroundJobs:this.backgroundJobs.size,pendingRequests:this.pendingRequests.size,entries:t.sort((e,t)=>e.age-t.age)}}setDebugMode(e){this.debugMode=e}_debug(e){for(var t=arguments.length,o=Array(t>1?t-1:0),r=1;r<t;r++)o[r-1]=arguments[r];this.debugMode&&console.log("[DashboardCache] ".concat(e),...o)}_refreshInBackground(e,t,o){this.backgroundJobs.set(o,!0),e(...t).then(e=>{this.cache.set(o,{data:e,lastUpdated:Date.now()})}).catch(e=>{console.warn("Background refresh failed for ".concat(o,":"),e)}).finally(()=>{this.backgroundJobs.delete(o)})}_generateKey(e,t){let o=a(e.toString()),r=t.length>0?JSON.stringify(t):"";return"".concat(o,"_").concat(r)}constructor(){this.cache=new Map,this.backgroundJobs=new Map,this.pendingRequests=new Map,this.debugMode=!1,this.preloader=null}}let s=new n;t.default=s}}]);
|