skypilot-nightly 1.0.0.dev20250812__py3-none-any.whl → 1.0.0.dev20250814__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 +4 -2
- sky/backends/backend_utils.py +69 -6
- sky/backends/cloud_vm_ray_backend.py +156 -25
- sky/catalog/cudo_catalog.py +1 -1
- sky/catalog/data_fetchers/fetch_cudo.py +1 -1
- sky/catalog/data_fetchers/fetch_nebius.py +6 -3
- sky/client/cli/command.py +40 -77
- sky/client/common.py +1 -1
- sky/client/sdk.py +19 -19
- sky/client/sdk_async.py +5 -4
- sky/clouds/aws.py +52 -1
- sky/clouds/kubernetes.py +14 -0
- sky/dag.py +1 -0
- sky/dashboard/out/404.html +1 -1
- sky/dashboard/out/_next/static/{Fuy7OzApYTUMz2QgoP7dP → Y0eNlwi85qGRecLTin11y}/_buildManifest.js +1 -1
- sky/dashboard/out/_next/static/chunks/{6989-6129c1cfbcf51063.js → 6989-37611fe6b86d274d.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/{_app-491a4d699d95e808.js → _app-c2ea34fda4f1f8c8.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/jobs/pools/{[pool]-f5ccf5d39d87aebe.js → [pool]-664c36eda967b1ba.js} +1 -1
- sky/dashboard/out/_next/static/chunks/{webpack-7fd0cf9dbecff10f.js → webpack-00c0a51d21157453.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.py +11 -1
- sky/exceptions.py +5 -0
- sky/global_user_state.py +63 -7
- sky/jobs/constants.py +1 -1
- sky/jobs/controller.py +0 -1
- sky/jobs/recovery_strategy.py +3 -3
- sky/jobs/scheduler.py +23 -68
- sky/jobs/server/core.py +18 -12
- sky/jobs/state.py +6 -2
- sky/jobs/utils.py +8 -0
- sky/provision/__init__.py +1 -0
- sky/provision/aws/config.py +9 -0
- sky/provision/aws/instance.py +36 -13
- sky/provision/azure/instance.py +2 -0
- sky/provision/cudo/cudo_wrapper.py +1 -1
- sky/provision/cudo/instance.py +2 -0
- sky/provision/do/instance.py +2 -0
- sky/provision/fluidstack/instance.py +2 -0
- sky/provision/gcp/instance.py +2 -0
- sky/provision/hyperbolic/instance.py +2 -1
- sky/provision/kubernetes/instance.py +133 -0
- sky/provision/lambda_cloud/instance.py +2 -0
- sky/provision/nebius/instance.py +2 -0
- sky/provision/oci/instance.py +2 -0
- sky/provision/paperspace/instance.py +2 -1
- sky/provision/paperspace/utils.py +1 -1
- sky/provision/runpod/instance.py +2 -0
- sky/provision/runpod/utils.py +1 -1
- sky/provision/scp/instance.py +2 -0
- sky/provision/vast/instance.py +2 -0
- sky/provision/vsphere/instance.py +2 -0
- sky/resources.py +1 -2
- sky/schemas/__init__.py +0 -0
- sky/schemas/api/__init__.py +0 -0
- sky/schemas/api/responses.py +70 -0
- sky/schemas/generated/__init__.py +0 -0
- sky/schemas/generated/autostopv1_pb2.py +36 -0
- sky/schemas/generated/autostopv1_pb2.pyi +43 -0
- sky/schemas/generated/autostopv1_pb2_grpc.py +146 -0
- sky/serve/constants.py +3 -7
- sky/serve/replica_managers.py +15 -16
- sky/serve/serve_state.py +10 -0
- sky/serve/serve_utils.py +21 -20
- sky/serve/server/impl.py +15 -19
- sky/serve/service.py +31 -16
- sky/server/server.py +20 -14
- sky/setup_files/dependencies.py +11 -10
- sky/skylet/autostop_lib.py +38 -5
- sky/skylet/constants.py +3 -1
- sky/skylet/services.py +44 -0
- sky/skylet/skylet.py +49 -4
- sky/task.py +19 -16
- sky/templates/aws-ray.yml.j2 +2 -2
- sky/templates/jobs-controller.yaml.j2 +6 -0
- sky/utils/command_runner.py +1 -1
- sky/utils/config_utils.py +29 -5
- sky/utils/controller_utils.py +73 -0
- sky/utils/db/db_utils.py +17 -0
- sky/utils/schemas.py +3 -0
- sky/volumes/server/core.py +2 -2
- sky/volumes/server/server.py +2 -2
- {skypilot_nightly-1.0.0.dev20250812.dist-info → skypilot_nightly-1.0.0.dev20250814.dist-info}/METADATA +5 -7
- {skypilot_nightly-1.0.0.dev20250812.dist-info → skypilot_nightly-1.0.0.dev20250814.dist-info}/RECORD +102 -94
- /sky/dashboard/out/_next/static/{Fuy7OzApYTUMz2QgoP7dP → Y0eNlwi85qGRecLTin11y}/_ssgManifest.js +0 -0
- {skypilot_nightly-1.0.0.dev20250812.dist-info → skypilot_nightly-1.0.0.dev20250814.dist-info}/WHEEL +0 -0
- {skypilot_nightly-1.0.0.dev20250812.dist-info → skypilot_nightly-1.0.0.dev20250814.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20250812.dist-info → skypilot_nightly-1.0.0.dev20250814.dist-info}/licenses/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev20250812.dist-info → skypilot_nightly-1.0.0.dev20250814.dist-info}/top_level.txt +0 -0
sky/client/cli/command.py
CHANGED
|
@@ -275,65 +275,6 @@ def _merge_env_vars(env_dict: Optional[Dict[str, str]],
|
|
|
275
275
|
return list(env_dict.items())
|
|
276
276
|
|
|
277
277
|
|
|
278
|
-
def _format_job_ids_str(job_ids: List[int], max_length: int = 30) -> str:
|
|
279
|
-
"""Format job IDs string with ellipsis if too long.
|
|
280
|
-
|
|
281
|
-
Args:
|
|
282
|
-
job_ids: List of job IDs to format.
|
|
283
|
-
max_length: Maximum length of the output string.
|
|
284
|
-
|
|
285
|
-
Returns:
|
|
286
|
-
Formatted string like "11,12,...,2017,2018" if truncated,
|
|
287
|
-
or the full string if it fits within max_length.
|
|
288
|
-
"""
|
|
289
|
-
if not job_ids:
|
|
290
|
-
return ''
|
|
291
|
-
|
|
292
|
-
# Convert all to strings
|
|
293
|
-
job_strs = [str(job_id) for job_id in job_ids]
|
|
294
|
-
full_str = ','.join(job_strs)
|
|
295
|
-
|
|
296
|
-
# If it fits, return as is
|
|
297
|
-
if len(full_str) <= max_length:
|
|
298
|
-
return full_str
|
|
299
|
-
|
|
300
|
-
if len(job_strs) <= 2:
|
|
301
|
-
return full_str # Can't truncate further
|
|
302
|
-
|
|
303
|
-
# Need to truncate with ellipsis
|
|
304
|
-
ellipsis = '...'
|
|
305
|
-
|
|
306
|
-
# Start with minimum: first and last
|
|
307
|
-
start_count = 1
|
|
308
|
-
end_count = 1
|
|
309
|
-
|
|
310
|
-
while start_count + end_count < len(job_strs):
|
|
311
|
-
# Try adding one more to start
|
|
312
|
-
if start_count + 1 + end_count < len(job_strs):
|
|
313
|
-
start_part = ','.join(job_strs[:start_count + 1])
|
|
314
|
-
end_part = ','.join(job_strs[-end_count:])
|
|
315
|
-
candidate = f'{start_part},{ellipsis},{end_part}'
|
|
316
|
-
if len(candidate) <= max_length:
|
|
317
|
-
start_count += 1
|
|
318
|
-
continue
|
|
319
|
-
|
|
320
|
-
# Try adding one more to end
|
|
321
|
-
if start_count + end_count + 1 < len(job_strs):
|
|
322
|
-
start_part = ','.join(job_strs[:start_count])
|
|
323
|
-
end_part = ','.join(job_strs[-(end_count + 1):])
|
|
324
|
-
candidate = f'{start_part},{ellipsis},{end_part}'
|
|
325
|
-
if len(candidate) <= max_length:
|
|
326
|
-
end_count += 1
|
|
327
|
-
continue
|
|
328
|
-
|
|
329
|
-
# Can't add more
|
|
330
|
-
break
|
|
331
|
-
|
|
332
|
-
start_part = ','.join(job_strs[:start_count])
|
|
333
|
-
end_part = ','.join(job_strs[-end_count:])
|
|
334
|
-
return f'{start_part},{ellipsis},{end_part}'
|
|
335
|
-
|
|
336
|
-
|
|
337
278
|
def _complete_cluster_name(ctx: click.Context, param: click.Parameter,
|
|
338
279
|
incomplete: str) -> List[str]:
|
|
339
280
|
"""Handle shell completion for cluster names."""
|
|
@@ -1187,11 +1128,15 @@ def launch(
|
|
|
1187
1128
|
raise ValueError(f'{backend_name} backend is not supported.')
|
|
1188
1129
|
|
|
1189
1130
|
if task.service is not None:
|
|
1131
|
+
noun = 'pool' if task.service.pool else 'service'
|
|
1132
|
+
capnoun = noun.capitalize()
|
|
1133
|
+
sysname = 'Jobs Worker Pool' if task.service.pool else 'SkyServe'
|
|
1134
|
+
cmd = 'sky jobs pool apply' if task.service.pool else 'sky serve up'
|
|
1190
1135
|
logger.info(
|
|
1191
|
-
f'{colorama.Fore.YELLOW}
|
|
1192
|
-
f'`sky launch`. {colorama.Style.RESET_ALL}\n
|
|
1193
|
-
'To spin up a
|
|
1194
|
-
f'{colorama.Style.RESET_ALL}{colorama.Style.BRIGHT}
|
|
1136
|
+
f'{colorama.Fore.YELLOW}{capnoun} section will be ignored when '
|
|
1137
|
+
f'using `sky launch`. {colorama.Style.RESET_ALL}\n'
|
|
1138
|
+
f'{colorama.Fore.YELLOW}To spin up a {noun}, use {sysname} CLI: '
|
|
1139
|
+
f'{colorama.Style.RESET_ALL}{colorama.Style.BRIGHT}{cmd}'
|
|
1195
1140
|
f'{colorama.Style.RESET_ALL}')
|
|
1196
1141
|
|
|
1197
1142
|
request_id = sdk.launch(
|
|
@@ -2981,15 +2926,15 @@ def _hint_or_raise_for_down_jobs_controller(controller_name: str,
|
|
|
2981
2926
|
controller = controller_utils.Controllers.from_name(controller_name)
|
|
2982
2927
|
assert controller is not None, controller_name
|
|
2983
2928
|
|
|
2984
|
-
# TODO(tian): We also need to check pools after we allow running pools on
|
|
2985
|
-
# jobs controller.
|
|
2986
2929
|
with rich_utils.client_status(
|
|
2987
|
-
'[bold cyan]Checking for in-progress managed jobs[/]'):
|
|
2930
|
+
'[bold cyan]Checking for in-progress managed jobs and pools[/]'):
|
|
2988
2931
|
try:
|
|
2989
2932
|
request_id = managed_jobs.queue(refresh=False,
|
|
2990
2933
|
skip_finished=True,
|
|
2991
2934
|
all_users=True)
|
|
2992
2935
|
managed_jobs_ = sdk.stream_and_get(request_id)
|
|
2936
|
+
request_id_pools = managed_jobs.pool_status(pool_names=None)
|
|
2937
|
+
pools_ = sdk.stream_and_get(request_id_pools)
|
|
2993
2938
|
except exceptions.ClusterNotUpError as e:
|
|
2994
2939
|
if controller.value.connection_error_hint in str(e):
|
|
2995
2940
|
with ux_utils.print_exception_no_traceback():
|
|
@@ -3004,6 +2949,7 @@ def _hint_or_raise_for_down_jobs_controller(controller_name: str,
|
|
|
3004
2949
|
# the controller being STOPPED or being firstly launched, i.e.,
|
|
3005
2950
|
# there is no in-prgress managed jobs.
|
|
3006
2951
|
managed_jobs_ = []
|
|
2952
|
+
pools_ = []
|
|
3007
2953
|
except exceptions.InconsistentConsolidationModeError:
|
|
3008
2954
|
# If this error is raised, it means the user switched to the
|
|
3009
2955
|
# consolidation mode but the previous controller cluster is still
|
|
@@ -3021,6 +2967,8 @@ def _hint_or_raise_for_down_jobs_controller(controller_name: str,
|
|
|
3021
2967
|
skip_finished=True,
|
|
3022
2968
|
all_users=True)
|
|
3023
2969
|
managed_jobs_ = sdk.stream_and_get(request_id)
|
|
2970
|
+
request_id_pools = managed_jobs.pool_status(pool_names=None)
|
|
2971
|
+
pools_ = sdk.stream_and_get(request_id_pools)
|
|
3024
2972
|
|
|
3025
2973
|
msg = (f'{colorama.Fore.YELLOW}WARNING: Tearing down the managed '
|
|
3026
2974
|
'jobs controller. Please be aware of the following:'
|
|
@@ -3042,9 +2990,23 @@ def _hint_or_raise_for_down_jobs_controller(controller_name: str,
|
|
|
3042
2990
|
else:
|
|
3043
2991
|
with ux_utils.print_exception_no_traceback():
|
|
3044
2992
|
raise exceptions.NotSupportedError(msg)
|
|
2993
|
+
elif pools_:
|
|
2994
|
+
pool_names = ', '.join([pool['name'] for pool in pools_])
|
|
2995
|
+
if purge:
|
|
2996
|
+
logger.warning('--purge is set, ignoring the in-progress pools. '
|
|
2997
|
+
'This could cause leaked clusters!')
|
|
2998
|
+
else:
|
|
2999
|
+
msg = (f'{colorama.Fore.YELLOW}WARNING: Tearing down the managed '
|
|
3000
|
+
'jobs controller is not supported, as it is currently '
|
|
3001
|
+
f'hosting the following pools: {pool_names}. Please '
|
|
3002
|
+
'terminate the pools first with '
|
|
3003
|
+
f'{colorama.Style.BRIGHT}sky jobs pool down -a'
|
|
3004
|
+
f'{colorama.Style.RESET_ALL}.')
|
|
3005
|
+
with ux_utils.print_exception_no_traceback():
|
|
3006
|
+
raise exceptions.NotSupportedError(msg)
|
|
3045
3007
|
else:
|
|
3046
|
-
click.echo(' * No in-progress managed jobs found. It
|
|
3047
|
-
'terminate (see caveats above).')
|
|
3008
|
+
click.echo(' * No in-progress managed jobs or running pools found. It '
|
|
3009
|
+
'should be safe to terminate (see caveats above).')
|
|
3048
3010
|
|
|
3049
3011
|
|
|
3050
3012
|
def _hint_or_raise_for_down_sky_serve_controller(controller_name: str,
|
|
@@ -4509,8 +4471,8 @@ def jobs_launch(
|
|
|
4509
4471
|
if print_setup_fm_warning:
|
|
4510
4472
|
click.secho(
|
|
4511
4473
|
f'{colorama.Fore.YELLOW}setup/file_mounts/storage_mounts'
|
|
4512
|
-
' will be ignored
|
|
4513
|
-
f'use `sky pool apply {pool} pool.yaml`. '
|
|
4474
|
+
' will be ignored when submit jobs to pool. To update a pool, '
|
|
4475
|
+
f'please use `sky jobs pool apply {pool} new-pool.yaml`. '
|
|
4514
4476
|
f'{colorama.Style.RESET_ALL}')
|
|
4515
4477
|
|
|
4516
4478
|
# Optimize info is only show if _need_confirmation.
|
|
@@ -4537,7 +4499,9 @@ def jobs_launch(
|
|
|
4537
4499
|
controller=False)
|
|
4538
4500
|
sys.exit(returncode)
|
|
4539
4501
|
else:
|
|
4540
|
-
|
|
4502
|
+
# TODO(tian): This can be very long. Considering have a "group id"
|
|
4503
|
+
# and query all job ids with the same group id.
|
|
4504
|
+
job_ids_str = ','.join(map(str, job_ids))
|
|
4541
4505
|
click.secho(
|
|
4542
4506
|
f'Jobs submitted with IDs: {colorama.Fore.CYAN}'
|
|
4543
4507
|
f'{job_ids_str}{colorama.Style.RESET_ALL}.'
|
|
@@ -6212,16 +6176,15 @@ def api_info():
|
|
|
6212
6176
|
"""Shows the SkyPilot API server URL."""
|
|
6213
6177
|
url = server_common.get_server_url()
|
|
6214
6178
|
api_server_info = sdk.api_info()
|
|
6215
|
-
api_server_user = api_server_info.
|
|
6179
|
+
api_server_user = api_server_info.user
|
|
6216
6180
|
if api_server_user is not None:
|
|
6217
|
-
user =
|
|
6218
|
-
name=api_server_user['name'])
|
|
6181
|
+
user = api_server_user
|
|
6219
6182
|
else:
|
|
6220
6183
|
user = models.User.get_current_user()
|
|
6221
6184
|
click.echo(f'Using SkyPilot API server and dashboard: {url}\n'
|
|
6222
|
-
f'{ux_utils.INDENT_SYMBOL}Status: {api_server_info
|
|
6223
|
-
f'commit: {api_server_info
|
|
6224
|
-
f'version: {api_server_info
|
|
6185
|
+
f'{ux_utils.INDENT_SYMBOL}Status: {api_server_info.status}, '
|
|
6186
|
+
f'commit: {api_server_info.commit}, '
|
|
6187
|
+
f'version: {api_server_info.version}\n'
|
|
6225
6188
|
f'{ux_utils.INDENT_LAST_SYMBOL}User: {user.name} ({user.id})')
|
|
6226
6189
|
|
|
6227
6190
|
|
sky/client/common.py
CHANGED
sky/client/sdk.py
CHANGED
|
@@ -30,6 +30,7 @@ from sky import skypilot_config
|
|
|
30
30
|
from sky.adaptors import common as adaptors_common
|
|
31
31
|
from sky.client import common as client_common
|
|
32
32
|
from sky.client import oauth as oauth_lib
|
|
33
|
+
from sky.schemas.api import responses
|
|
33
34
|
from sky.server import common as server_common
|
|
34
35
|
from sky.server import rest
|
|
35
36
|
from sky.server import versions
|
|
@@ -66,8 +67,8 @@ if typing.TYPE_CHECKING:
|
|
|
66
67
|
|
|
67
68
|
import sky
|
|
68
69
|
from sky import backends
|
|
70
|
+
from sky import catalog
|
|
69
71
|
from sky import models
|
|
70
|
-
import sky.catalog
|
|
71
72
|
from sky.provision.kubernetes import utils as kubernetes_utils
|
|
72
73
|
from sky.skylet import job_lib
|
|
73
74
|
else:
|
|
@@ -234,7 +235,7 @@ def list_accelerators(
|
|
|
234
235
|
require_price: bool = True,
|
|
235
236
|
case_sensitive: bool = True
|
|
236
237
|
) -> server_common.RequestId[Dict[str,
|
|
237
|
-
List['
|
|
238
|
+
List['catalog.common.InstanceTypeInfo']]]:
|
|
238
239
|
"""Lists the names of all accelerators offered by Sky.
|
|
239
240
|
|
|
240
241
|
This will include all accelerators offered by Sky, including those
|
|
@@ -479,11 +480,11 @@ def launch(
|
|
|
479
480
|
This option works in conjunction with ``idle_minutes_to_autostop``.
|
|
480
481
|
Choices:
|
|
481
482
|
|
|
482
|
-
1. "jobs_and_ssh" (default) - Wait for
|
|
483
|
-
|
|
484
|
-
2. "jobs" -
|
|
485
|
-
3. "none" -
|
|
486
|
-
|
|
483
|
+
1. "jobs_and_ssh" (default) - Wait for in-progress jobs and SSH
|
|
484
|
+
connections to finish.
|
|
485
|
+
2. "jobs" - Only wait for in-progress jobs.
|
|
486
|
+
3. "none" - Wait for nothing; autostop right after
|
|
487
|
+
``idle_minutes_to_autostop``.
|
|
487
488
|
dryrun: if True, do not actually launch the cluster.
|
|
488
489
|
down: Tear down the cluster after all jobs finish (successfully or
|
|
489
490
|
abnormally). If --idle-minutes-to-autostop is also set, the
|
|
@@ -935,11 +936,11 @@ def start(
|
|
|
935
936
|
This option works in conjunction with ``idle_minutes_to_autostop``.
|
|
936
937
|
Choices:
|
|
937
938
|
|
|
938
|
-
1. "jobs_and_ssh" (default) - Wait for
|
|
939
|
-
|
|
940
|
-
2. "jobs" -
|
|
941
|
-
3. "none" -
|
|
942
|
-
|
|
939
|
+
1. "jobs_and_ssh" (default) - Wait for in-progress jobs and SSH
|
|
940
|
+
connections to finish.
|
|
941
|
+
2. "jobs" - Only wait for in-progress jobs.
|
|
942
|
+
3. "none" - Wait for nothing; autostop right after
|
|
943
|
+
``idle_minutes_to_autostop``.
|
|
943
944
|
retry_until_up: whether to retry launching the cluster until it is
|
|
944
945
|
up.
|
|
945
946
|
down: Autodown the cluster: tear down the cluster after specified
|
|
@@ -1118,11 +1119,10 @@ def autostop(
|
|
|
1118
1119
|
This option works in conjunction with ``idle_minutes``.
|
|
1119
1120
|
Choices:
|
|
1120
1121
|
|
|
1121
|
-
1. "jobs_and_ssh" (default) - Wait for
|
|
1122
|
-
|
|
1123
|
-
2. "jobs" -
|
|
1124
|
-
3. "none" -
|
|
1125
|
-
regardless of running jobs or SSH connections.
|
|
1122
|
+
1. "jobs_and_ssh" (default) - Wait for in-progress jobs and SSH
|
|
1123
|
+
connections to finish.
|
|
1124
|
+
2. "jobs" - Only wait for in-progress jobs.
|
|
1125
|
+
3. "none" - Wait for nothing; autostop right after ``idle_minutes``.
|
|
1126
1126
|
down: if true, use autodown (tear down the cluster; non-restartable),
|
|
1127
1127
|
rather than autostop (restartable).
|
|
1128
1128
|
|
|
@@ -2059,7 +2059,7 @@ def api_status(
|
|
|
2059
2059
|
@usage_lib.entrypoint
|
|
2060
2060
|
@server_common.check_server_healthy_or_start
|
|
2061
2061
|
@annotations.client_api
|
|
2062
|
-
def api_info() ->
|
|
2062
|
+
def api_info() -> responses.APIHealthResponse:
|
|
2063
2063
|
"""Gets the server's status, commit and version.
|
|
2064
2064
|
|
|
2065
2065
|
Returns:
|
|
@@ -2084,7 +2084,7 @@ def api_info() -> Dict[str, Any]:
|
|
|
2084
2084
|
"""
|
|
2085
2085
|
response = server_common.make_authenticated_request('GET', '/api/health')
|
|
2086
2086
|
response.raise_for_status()
|
|
2087
|
-
return response.json()
|
|
2087
|
+
return responses.APIHealthResponse(**response.json())
|
|
2088
2088
|
|
|
2089
2089
|
|
|
2090
2090
|
@usage_lib.entrypoint
|
sky/client/sdk_async.py
CHANGED
|
@@ -20,13 +20,14 @@ import colorama
|
|
|
20
20
|
|
|
21
21
|
from sky import admin_policy
|
|
22
22
|
from sky import backends
|
|
23
|
+
from sky import catalog
|
|
23
24
|
from sky import exceptions
|
|
24
25
|
from sky import models
|
|
25
26
|
from sky import sky_logging
|
|
26
|
-
import sky.catalog
|
|
27
27
|
from sky.client import common as client_common
|
|
28
28
|
from sky.client import sdk
|
|
29
29
|
from sky.provision.kubernetes import utils as kubernetes_utils
|
|
30
|
+
from sky.schemas.api import responses
|
|
30
31
|
from sky.server import common as server_common
|
|
31
32
|
from sky.server import rest
|
|
32
33
|
from sky.server.requests import payloads
|
|
@@ -301,7 +302,7 @@ async def list_accelerators(
|
|
|
301
302
|
require_price: bool = True,
|
|
302
303
|
case_sensitive: bool = True,
|
|
303
304
|
stream_logs: Optional[StreamConfig] = DEFAULT_STREAM_CONFIG
|
|
304
|
-
) -> Dict[str, List[
|
|
305
|
+
) -> Dict[str, List[catalog.common.InstanceTypeInfo]]:
|
|
305
306
|
"""Async version of list_accelerators() that lists the names of all
|
|
306
307
|
accelerators offered by Sky."""
|
|
307
308
|
request_id = await context_utils.to_thread(sdk.list_accelerators, gpus_only,
|
|
@@ -345,7 +346,7 @@ async def optimize(
|
|
|
345
346
|
admin_policy_request_options: Optional[
|
|
346
347
|
admin_policy.RequestOptions] = None,
|
|
347
348
|
stream_logs: Optional[StreamConfig] = DEFAULT_STREAM_CONFIG
|
|
348
|
-
) -> sky.
|
|
349
|
+
) -> 'sky.Dag':
|
|
349
350
|
"""Async version of optimize() that finds the best execution plan for the
|
|
350
351
|
given DAG."""
|
|
351
352
|
request_id = await context_utils.to_thread(sdk.optimize, dag, minimize,
|
|
@@ -786,7 +787,7 @@ async def dashboard(starting_page: Optional[str] = None) -> None:
|
|
|
786
787
|
|
|
787
788
|
@usage_lib.entrypoint
|
|
788
789
|
@annotations.client_api
|
|
789
|
-
async def api_info() ->
|
|
790
|
+
async def api_info() -> responses.APIHealthResponse:
|
|
790
791
|
"""Async version of api_info() that gets the server's status, commit and
|
|
791
792
|
version."""
|
|
792
793
|
return await context_utils.to_thread(sdk.api_info)
|
sky/clouds/aws.py
CHANGED
|
@@ -65,6 +65,8 @@ _CREDENTIAL_FILES = [
|
|
|
65
65
|
]
|
|
66
66
|
|
|
67
67
|
DEFAULT_AMI_GB = 45
|
|
68
|
+
DEFAULT_SSH_USER = 'ubuntu'
|
|
69
|
+
DEFAULT_ROOT_DEVICE_NAME = '/dev/sda1'
|
|
68
70
|
|
|
69
71
|
# Temporary measure, as deleting per-cluster SGs is too slow.
|
|
70
72
|
# See https://github.com/skypilot-org/skypilot/pull/742.
|
|
@@ -343,6 +345,44 @@ class AWS(clouds.Cloud):
|
|
|
343
345
|
raise ValueError(image_not_found_message) from None
|
|
344
346
|
return image_size
|
|
345
347
|
|
|
348
|
+
@classmethod
|
|
349
|
+
@annotations.lru_cache(scope='request', maxsize=1)
|
|
350
|
+
def get_image_root_device_name(cls, image_id: str,
|
|
351
|
+
region: Optional[str]) -> str:
|
|
352
|
+
if image_id.startswith('skypilot:'):
|
|
353
|
+
return DEFAULT_ROOT_DEVICE_NAME
|
|
354
|
+
assert region is not None, (image_id, region)
|
|
355
|
+
image_not_found_message = (
|
|
356
|
+
f'Image {image_id!r} not found in AWS region {region}.\n'
|
|
357
|
+
f'To find AWS AMI IDs: https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-images.html#examples\n' # pylint: disable=line-too-long
|
|
358
|
+
'Example: ami-0729d913a335efca7')
|
|
359
|
+
try:
|
|
360
|
+
client = aws.client('ec2', region_name=region)
|
|
361
|
+
image_info = client.describe_images(ImageIds=[image_id]).get(
|
|
362
|
+
'Images', [])
|
|
363
|
+
if not image_info:
|
|
364
|
+
with ux_utils.print_exception_no_traceback():
|
|
365
|
+
raise ValueError(image_not_found_message)
|
|
366
|
+
image = image_info[0]
|
|
367
|
+
if 'RootDeviceName' not in image:
|
|
368
|
+
logger.warning(f'Image {image_id!r} does not have a root '
|
|
369
|
+
f'device name. '
|
|
370
|
+
f'Using {DEFAULT_ROOT_DEVICE_NAME}.')
|
|
371
|
+
return DEFAULT_ROOT_DEVICE_NAME
|
|
372
|
+
return image['RootDeviceName']
|
|
373
|
+
except (aws.botocore_exceptions().NoCredentialsError,
|
|
374
|
+
aws.botocore_exceptions().ProfileNotFound):
|
|
375
|
+
# Fallback to default root device name if no credentials are
|
|
376
|
+
# available.
|
|
377
|
+
# The credentials issue will be caught when actually provisioning
|
|
378
|
+
# the instance and appropriate errors will be raised there.
|
|
379
|
+
logger.warning(f'No credentials available for region {region}. '
|
|
380
|
+
f'Using {DEFAULT_ROOT_DEVICE_NAME}.')
|
|
381
|
+
return DEFAULT_ROOT_DEVICE_NAME
|
|
382
|
+
except aws.botocore_exceptions().ClientError:
|
|
383
|
+
with ux_utils.print_exception_no_traceback():
|
|
384
|
+
raise ValueError(image_not_found_message) from None
|
|
385
|
+
|
|
346
386
|
@classmethod
|
|
347
387
|
def get_zone_shell_cmd(cls) -> Optional[str]:
|
|
348
388
|
# The command for getting the current zone is from:
|
|
@@ -466,6 +506,15 @@ class AWS(clouds.Cloud):
|
|
|
466
506
|
image_id = self._get_image_id(image_id_to_use, region_name,
|
|
467
507
|
resources.instance_type)
|
|
468
508
|
|
|
509
|
+
root_device_name = self.get_image_root_device_name(
|
|
510
|
+
image_id, region_name)
|
|
511
|
+
|
|
512
|
+
ssh_user = skypilot_config.get_effective_region_config(
|
|
513
|
+
cloud='aws',
|
|
514
|
+
region=region_name,
|
|
515
|
+
keys=('ssh_user',),
|
|
516
|
+
default_value=DEFAULT_SSH_USER)
|
|
517
|
+
|
|
469
518
|
disk_encrypted = skypilot_config.get_effective_region_config(
|
|
470
519
|
cloud='aws',
|
|
471
520
|
region=region_name,
|
|
@@ -509,6 +558,8 @@ class AWS(clouds.Cloud):
|
|
|
509
558
|
'region': region_name,
|
|
510
559
|
'zones': ','.join(zone_names),
|
|
511
560
|
'image_id': image_id,
|
|
561
|
+
'root_device_name': root_device_name,
|
|
562
|
+
'ssh_user': ssh_user,
|
|
512
563
|
'security_group': security_group,
|
|
513
564
|
'security_group_managed_by_skypilot':
|
|
514
565
|
str(security_group != user_security_group).lower(),
|
|
@@ -1080,7 +1131,7 @@ class AWS(clouds.Cloud):
|
|
|
1080
1131
|
|
|
1081
1132
|
image_name = f'skypilot-{cluster_name.display_name}-{int(time.time())}'
|
|
1082
1133
|
|
|
1083
|
-
status = provision_lib.query_instances('AWS',
|
|
1134
|
+
status = provision_lib.query_instances('AWS', cluster_name.display_name,
|
|
1084
1135
|
cluster_name.name_on_cloud,
|
|
1085
1136
|
{'region': region})
|
|
1086
1137
|
instance_ids = list(status.keys())
|
sky/clouds/kubernetes.py
CHANGED
|
@@ -771,11 +771,25 @@ class Kubernetes(clouds.Cloud):
|
|
|
771
771
|
|
|
772
772
|
return deploy_vars
|
|
773
773
|
|
|
774
|
+
@staticmethod
|
|
775
|
+
def _warn_on_disk_size(resources: 'resources_lib.Resources'):
|
|
776
|
+
if resources.disk_size is not None:
|
|
777
|
+
logger.info(f'{colorama.Style.DIM}Disk size {resources.disk_size} '
|
|
778
|
+
'is not supported by Kubernetes. '
|
|
779
|
+
'To add additional disk, use volumes.'
|
|
780
|
+
f'{colorama.Style.RESET_ALL}')
|
|
781
|
+
if resources.disk_tier is not None:
|
|
782
|
+
logger.info(f'{colorama.Style.DIM}Disk tier {resources.disk_tier} '
|
|
783
|
+
'is not supported by Kubernetes. '
|
|
784
|
+
'To add additional disk, use volumes.'
|
|
785
|
+
f'{colorama.Style.RESET_ALL}')
|
|
786
|
+
|
|
774
787
|
def _get_feasible_launchable_resources(
|
|
775
788
|
self, resources: 'resources_lib.Resources'
|
|
776
789
|
) -> 'resources_utils.FeasibleResources':
|
|
777
790
|
# TODO(zhwu): This needs to be updated to return the correct region
|
|
778
791
|
# (context) that has enough resources.
|
|
792
|
+
self._warn_on_disk_size(resources)
|
|
779
793
|
fuzzy_candidate_list: List[str] = []
|
|
780
794
|
if resources.instance_type is not None:
|
|
781
795
|
assert resources.is_launchable(), resources
|
sky/dag.py
CHANGED
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-00c0a51d21157453.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-c2ea34fda4f1f8c8.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_error-c66a4e8afc46f17b.js" defer=""></script><script src="/dashboard/_next/static/Y0eNlwi85qGRecLTin11y/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/Y0eNlwi85qGRecLTin11y/_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":"Y0eNlwi85qGRecLTin11y","assetPrefix":"/dashboard","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
|
sky/dashboard/out/_next/static/{Fuy7OzApYTUMz2QgoP7dP → Y0eNlwi85qGRecLTin11y}/_buildManifest.js
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
self.__BUILD_MANIFEST=function(s,c,a,e,t,f,u,n,o,r,j,i,
|
|
1
|
+
self.__BUILD_MANIFEST=function(s,c,a,e,t,f,u,n,o,r,j,b,i,k,d){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/":["static/chunks/pages/index-444f1804401f04ea.js"],"/_error":["static/chunks/pages/_error-c66a4e8afc46f17b.js"],"/clusters":["static/chunks/pages/clusters-b30460f683e6ba96.js"],"/clusters/[cluster]":[s,c,a,f,u,j,r,e,t,n,b,i,o,k,d,"static/chunks/1871-980a395e92633a5c.js","static/chunks/pages/clusters/[cluster]-da9cc0901349c2e9.js"],"/clusters/[cluster]/[job]":[s,c,a,f,e,t,o,"static/chunks/pages/clusters/[cluster]/[job]-078751bad714c017.js"],"/config":["static/chunks/pages/config-dfb9bf07b13045f4.js"],"/infra":["static/chunks/pages/infra-fc9222e26c8e2f0d.js"],"/infra/[context]":["static/chunks/pages/infra/[context]-13d53fffc03ccb52.js"],"/jobs":["static/chunks/pages/jobs-cdc60fb5d371e16a.js"],"/jobs/pools/[pool]":[s,c,a,u,r,e,t,n,"static/chunks/pages/jobs/pools/[pool]-664c36eda967b1ba.js"],"/jobs/[job]":[s,c,a,f,u,r,e,t,n,o,"static/chunks/pages/jobs/[job]-154f55cf8af55be5.js"],"/users":["static/chunks/pages/users-7ed36e44e779d5c7.js"],"/volumes":["static/chunks/pages/volumes-c9695d657f78b5dc.js"],"/workspace/new":["static/chunks/pages/workspace/new-3f88a1c7e86a3f86.js"],"/workspaces":["static/chunks/pages/workspaces-8f67be60165724cc.js"],"/workspaces/[name]":[s,c,a,f,u,j,e,t,n,b,i,o,k,d,"static/chunks/1141-a8a8f1adba34c892.js","static/chunks/pages/workspaces/[name]-f72f73bcef9541dc.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-37611fe6b86d274d.js","static/chunks/3850-ff4a9a69d978632b.js","static/chunks/7411-b15471acd2cba716.js","static/chunks/1272-1ef0bf0237faccdb.js","static/chunks/8969-c9686994ddafcf01.js","static/chunks/6135-85426374db04811e.js","static/chunks/6212-7bd06f60ba693125.js","static/chunks/1559-6c00e20454194859.js","static/chunks/6990-0f886f16e0d55ff8.js","static/chunks/8056-5bdeda81199c0def.js","static/chunks/6601-06114c982db410b6.js","static/chunks/9159-11421c0f2909236f.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[6989],{88950:function(e,n,t){t.d(n,{Bw:function(){return p},Ph:function(){return d},Ql:function(){return x},i4:function(){return m},ki:function(){return u}});var r=t(85893),a=t(67294),s=t(2067),l=t(45895),o=t(7242),i=t(70282),c=t(32350);let d=s.fC;s.ZA;let u=s.B4,m=a.forwardRef((e,n)=>{let{className:t,children:a,...o}=e;return(0,r.jsxs)(s.xz,{ref:n,className:(0,c.cn)("flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",t),...o,children:[a,(0,r.jsx)(s.JO,{asChild:!0,children:(0,r.jsx)(l.Z,{className:"h-4 w-4 opacity-50"})})]})});m.displayName=s.xz.displayName;let f=a.forwardRef((e,n)=>{let{className:t,...a}=e;return(0,r.jsx)(s.u_,{ref:n,className:(0,c.cn)("flex cursor-default items-center justify-center py-1",t),...a,children:(0,r.jsx)(o.Z,{className:"h-4 w-4"})})});f.displayName=s.u_.displayName;let h=a.forwardRef((e,n)=>{let{className:t,...a}=e;return(0,r.jsx)(s.$G,{ref:n,className:(0,c.cn)("flex cursor-default items-center justify-center py-1",t),...a,children:(0,r.jsx)(l.Z,{className:"h-4 w-4"})})});h.displayName=s.$G.displayName;let p=a.forwardRef((e,n)=>{let{className:t,children:a,position:l="popper",...o}=e;return(0,r.jsx)(s.h_,{children:(0,r.jsxs)(s.VY,{ref:n,className:(0,c.cn)("relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2","popper"===l&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",t),position:l,...o,children:[(0,r.jsx)(f,{}),(0,r.jsx)(s.l_,{className:(0,c.cn)("p-1","popper"===l&&"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"),children:a}),(0,r.jsx)(h,{})]})})});p.displayName=s.VY.displayName,a.forwardRef((e,n)=>{let{className:t,...a}=e;return(0,r.jsx)(s.__,{ref:n,className:(0,c.cn)("py-1.5 pl-8 pr-2 text-sm font-semibold",t),...a})}).displayName=s.__.displayName;let x=a.forwardRef((e,n)=>{let{className:t,children:a,...l}=e;return(0,r.jsxs)(s.ck,{ref:n,className:(0,c.cn)("relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",t),...l,children:[(0,r.jsx)("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:(0,r.jsx)(s.wU,{children:(0,r.jsx)(i.Z,{className:"h-4 w-4"})})}),(0,r.jsx)(s.eT,{children:a})]})});x.displayName=s.ck.displayName,a.forwardRef((e,n)=>{let{className:t,...a}=e;return(0,r.jsx)(s.Z0,{ref:n,className:(0,c.cn)("-mx-1 my-1 h-px bg-muted",t),...a})}).displayName=s.Z0.displayName},36989:function(e,n,t){t.d(n,{$B:function(){return g},Kl:function(){return v},LU:function(){return p},Md:function(){return h},WH:function(){return f},Zg:function(){return b},Zn:function(){return x},os:function(){return _},sY:function(){return j},x9:function(){return N},xn:function(){return y},yc:function(){return u}});var r=t(85893),a=t(67294),s=t(53302),l=t(11886),o=t(88950),i=t(51214),c=t(41664),d=t.n(c);let u=i.nb.REFRESH_INTERVAL,m={placement:"bottom",color:"default"},f=e=>{let{children:n,...t}=e,a=t.content;return t.content=void 0,(0,r.jsx)(s.e,{...m,...t,content:(0,r.jsx)("span",{className:"left-full w-max px-2 py-1 text-sm text-gray-100 bg-gray-500 text-sm capitalize rounded",children:a}),children:n})},h=e=>{let{children:n,...t}=e,a=t.content;return t.content=void 0,(0,r.jsx)(s.e,{...m,...t,content:(0,r.jsx)("span",{className:"left-full w-max px-2 py-1 text-sm text-gray-100 bg-gray-500 text-sm rounded",children:a}),children:n})};function p(e){if(!e&&0!==e)return"-";let n=e=Math.floor(e),t="",r=0;for(let e of[{value:31536e3,label:"y"},{value:2592e3,label:"mo"},{value:86400,label:"d"},{value:3600,label:"h"},{value:60,label:"m"},{value:1,label:"s"}])if(n>=e.value&&r<2){let a=Math.floor(n/e.value);t+="".concat(a).concat(e.label," "),n%=e.value,r++}return t.trim()||"0s"}function x(e){return e.replace(/\x1b\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGKH]/g,"")}function g(e){let{logs:n,controller:t=!1}=e,[s,l]=(0,a.useState)("all"),[i,c]=(0,a.useState)(n),[d,u]=(0,a.useState)([]);return(0,a.useEffect)(()=>{u(function(e){let n;let t=/\((head|worker\d+),/g,r=new Set;for(;null!==(n=t.exec(e));)r.add(n[1]);return Array.from(r).sort((e,n)=>"head"===e?-1:"head"===n?1:e.localeCompare(n,void 0,{numeric:!0,sensitivity:"base"}))}(n))},[n]),(0,a.useEffect)(()=>{"all"===s?c(n):c(n.split("\n").filter(e=>e.includes("(".concat(s,","))).join("\n"))},[s,n]),(0,r.jsxs)("div",{children:[(0,r.jsx)("style",{children:'\n .logs-container {\n background-color: #f7f7f7;\n padding: 16px;\n max-height: calc(100vh - 300px);\n overflow-y: auto;\n overflow-x: hidden;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;\n line-height: 1.5;\n border-radius: 6px;\n min-height: fit-content;\n }\n\n .log-line {\n display: block;\n white-space: pre-wrap;\n margin: 2px 0;\n }\n\n .log-line .level {\n display: inline;\n width: 1ch;\n margin-right: 1ch;\n font-weight: bold;\n }\n\n .log-line.INFO .level {\n color: #2563eb;\n }\n\n .log-line.WARNING .level {\n color: #d97706;\n }\n\n .log-line.ERROR .level {\n color: #dc2626;\n }\n\n .log-line.DEBUG .level {\n color: #6b7280;\n }\n\n .log-line .timestamp {\n color: #059669;\n margin-right: 1ch;\n white-space: nowrap;\n }\n\n .log-line .location {\n color: #6366f1;\n margin-right: 1ch;\n white-space: nowrap;\n }\n\n .log-line .message {\n color: #111827;\n word-break: break-word;\n white-space: pre-wrap;\n }\n\n .log-line .log-prefix {\n color: #6366f1;\n font-weight: 500;\n }\n\n .log-line .log-rest {\n color: #111827;\n word-break: break-word;\n white-space: pre-wrap;\n }\n'}),!t&&(0,r.jsx)("div",{style:{marginBottom:"1rem"},children:(0,r.jsxs)(o.Ph,{onValueChange:e=>l(e),value:s,children:[(0,r.jsx)(o.i4,{"aria-label":"Node",className:"focus:ring-0 focus:ring-offset-0",children:(0,r.jsx)(o.ki,{placeholder:"Select Node"})}),(0,r.jsxs)(o.Bw,{children:[(0,r.jsx)(o.Ql,{value:"all",children:"All Nodes"}),d.map(e=>(0,r.jsx)(o.Ql,{value:e,children:e},e))]})]})}),(0,r.jsx)("div",{className:"logs-container",dangerouslySetInnerHTML:{__html:i?x(i).split("\n").filter(e=>""!==e.trim()&&!e.match(/<rich_.*?\[bold cyan\]/)&&!e.match(/<rich_.*>.*<\/rich_.*>/)&&!e.match(/├──/)&&!e.match(/└──/)).map(e=>'<span class="log-line"><span class="message">'.concat(e,"</span></span>")).join("\n"):""}})]})}function b(e){let n,{date:t}=e;if(!t)return"N/A";let a=new Date,s=t.getFullYear()+"-"+String(t.getMonth()+1).padStart(2,"0")+"-"+String(t.getDate()).padStart(2,"0"),o=t.toLocaleString("en-US",{hour:"numeric",minute:"2-digit",second:"2-digit",hour12:!0,timeZoneName:"short"});return n=function(e){if(!e||"string"!=typeof e)return e;if("just now"===e)return"now";if("less than a minute ago"===e.toLowerCase())return"Less than 1m ago";let n=e.match(/^about\s+(\d+)\s+(\w+)\s+ago$/i);if(n){let e=n[1],t=n[2],r={second:"s",seconds:"s",minute:"m",minutes:"m",hour:"h",hours:"h",day:"d",days:"d",month:"mo",months:"mo",year:"yr",years:"yr"};if(r[t])return"".concat(e).concat(r[t]," ago")}let t=e.match(/^a[n]?\s+(\w+)\s+ago$/i);if(t){let e=t[1],n={second:"s",minute:"m",hour:"h",day:"d",month:"mo",year:"yr"};if(n[e])return"1".concat(n[e]," ago")}let r=e.match(/^(\d+)\s+(\w+)\s+ago$/i);if(r){let e=r[1],n=r[2],t={second:"s",seconds:"s",minute:"m",minutes:"m",hour:"h",hours:"h",day:"d",days:"d",month:"mo",months:"mo",year:"yr",years:"yr"};if(t[n])return"".concat(e).concat(t[n]," ago")}return e}((0,l.B)(t,a,{addSuffix:!0})),(0,r.jsx)(f,{content:s+" "+o,className:"text-sm text-muted-foreground",children:(0,r.jsx)("span",{className:"border-b border-dotted border-gray-400 cursor-help",children:n})})}function y(e){return e?e.getFullYear()+"-"+String(e.getMonth()+1).padStart(2,"0")+"-"+String(e.getDate()).padStart(2,"0")+" "+e.toLocaleString("en-US",{hour:"numeric",minute:"2-digit",second:"2-digit",hour12:!0,timeZoneName:"short"}):"N/A"}let j=e=>e&&e.jobCounts?e.jobCounts:{},w=e=>{if(!e||0===e.length)return{};let n=e.filter(e=>"READY"===e.status),t={};n.forEach(e=>{try{let n=e.cloud,r=e.region;t[n]||(t[n]={count:0,regions:new Set}),t[n].count+=1,r&&t[n].regions.add(r)}catch(e){t.Unknown||(t.Unknown={count:0,regions:new Set}),t.Unknown.count+=1}});let r={};return Object.entries(t).forEach(e=>{let[n,t]=e,a=t.regions.size,s=n.toLowerCase().includes("kubernetes")||n.toLowerCase().includes("k8s")?"context":"region",l=1===a?"1 ".concat(s):"".concat(a," ").concat(s,"s");r[a>0?"".concat(n," (").concat(l,")"):n]=t.count}),r},N=e=>{let{jobCounts:n,getStatusStyle:t}=e;return n&&0!==Object.keys(n).length?(0,r.jsx)("div",{className:"flex flex-wrap gap-1",children:Object.entries(n).map(e=>{let[n,a]=e,s=t(n);return(0,r.jsxs)("span",{className:"px-2 py-1 rounded-full flex items-center space-x-2 text-xs font-medium ".concat(s),children:[(0,r.jsx)("span",{children:n}),(0,r.jsx)("span",{className:"text-xs bg-white/50 px-1.5 py-0.5 rounded",children:a})]},n)})}):(0,r.jsx)("span",{className:"text-gray-1000",children:"No active jobs"})},v=e=>{let{replicaInfo:n}=e,t=w(n);if(0===Object.keys(t).length)return(0,r.jsx)("span",{className:"text-gray-500 text-sm",children:"-"});let a=i.MO.NAME_TRUNCATE_LENGTH,s=e=>{let n=e.indexOf("(");if(-1===n)return e;let t=e.substring(0,n).trim(),r=e.substring(n+1,e.length-1);if(r.length<=a)return e;let s="".concat(r.substring(0,Math.floor((a-3)/2)),"...").concat(r.substring(r.length-Math.ceil((a-3)/2)));return"".concat(t," (").concat(s,")")};return(0,r.jsx)("div",{className:"flex flex-wrap gap-1",children:Object.entries(t).map(e=>{let[n,t]=e,a=s(n),l=a!==n;return(0,r.jsxs)("span",{className:"px-2 py-1 rounded-full flex items-center space-x-2 text-xs font-medium bg-blue-50 text-blue-700",children:[l?(0,r.jsx)(h,{content:n,className:"text-sm text-muted-foreground",children:(0,r.jsx)("span",{children:a})}):(0,r.jsx)("span",{children:n}),(0,r.jsx)("span",{className:"text-xs bg-white/50 px-1.5 py-0.5 rounded",children:t})]},n)})})},_=(e,n,t)=>{if(!e)return"-";if(t.find(t=>t.name===e&&t.hash===n)&&n)return(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,r.jsx)(h,{content:"This pool is running",placement:"top",children:(0,r.jsx)("div",{className:"w-2 h-2 bg-green-700 rounded-full"})}),(0,r.jsx)(d(),{href:"/jobs/pools/".concat(e),className:"text-gray-700 hover:text-blue-600 hover:underline",children:e})]});let a=n?n.substring(0,4):"";return(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,r.jsx)(h,{content:"This pool is terminated",placement:"top",children:(0,r.jsx)("div",{className:"w-2 h-2 bg-gray-800"})}),(0,r.jsxs)("span",{children:[e," (",a,")"]})]})}},51214:function(e,n,t){t.d(n,{MO:function(){return s},ej:function(){return r},nb:function(){return a}});let r={DEFAULT_TTL:12e4},a={REFRESH_INTERVAL:3e4,GPU_REFRESH_INTERVAL:3e4},s={NAME_TRUNCATE_LENGTH:20}}}]);
|
|
1
|
+
"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[6989],{88950:function(e,n,t){t.d(n,{Bw:function(){return p},Ph:function(){return d},Ql:function(){return x},i4:function(){return f},ki:function(){return u}});var r=t(85893),a=t(67294),s=t(2067),l=t(45895),o=t(7242),i=t(70282),c=t(32350);let d=s.fC;s.ZA;let u=s.B4,f=a.forwardRef((e,n)=>{let{className:t,children:a,...o}=e;return(0,r.jsxs)(s.xz,{ref:n,className:(0,c.cn)("flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",t),...o,children:[a,(0,r.jsx)(s.JO,{asChild:!0,children:(0,r.jsx)(l.Z,{className:"h-4 w-4 opacity-50"})})]})});f.displayName=s.xz.displayName;let m=a.forwardRef((e,n)=>{let{className:t,...a}=e;return(0,r.jsx)(s.u_,{ref:n,className:(0,c.cn)("flex cursor-default items-center justify-center py-1",t),...a,children:(0,r.jsx)(o.Z,{className:"h-4 w-4"})})});m.displayName=s.u_.displayName;let h=a.forwardRef((e,n)=>{let{className:t,...a}=e;return(0,r.jsx)(s.$G,{ref:n,className:(0,c.cn)("flex cursor-default items-center justify-center py-1",t),...a,children:(0,r.jsx)(l.Z,{className:"h-4 w-4"})})});h.displayName=s.$G.displayName;let p=a.forwardRef((e,n)=>{let{className:t,children:a,position:l="popper",...o}=e;return(0,r.jsx)(s.h_,{children:(0,r.jsxs)(s.VY,{ref:n,className:(0,c.cn)("relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2","popper"===l&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",t),position:l,...o,children:[(0,r.jsx)(m,{}),(0,r.jsx)(s.l_,{className:(0,c.cn)("p-1","popper"===l&&"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"),children:a}),(0,r.jsx)(h,{})]})})});p.displayName=s.VY.displayName,a.forwardRef((e,n)=>{let{className:t,...a}=e;return(0,r.jsx)(s.__,{ref:n,className:(0,c.cn)("py-1.5 pl-8 pr-2 text-sm font-semibold",t),...a})}).displayName=s.__.displayName;let x=a.forwardRef((e,n)=>{let{className:t,children:a,...l}=e;return(0,r.jsxs)(s.ck,{ref:n,className:(0,c.cn)("relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",t),...l,children:[(0,r.jsx)("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:(0,r.jsx)(s.wU,{children:(0,r.jsx)(i.Z,{className:"h-4 w-4"})})}),(0,r.jsx)(s.eT,{children:a})]})});x.displayName=s.ck.displayName,a.forwardRef((e,n)=>{let{className:t,...a}=e;return(0,r.jsx)(s.Z0,{ref:n,className:(0,c.cn)("-mx-1 my-1 h-px bg-muted",t),...a})}).displayName=s.Z0.displayName},36989:function(e,n,t){t.d(n,{$B:function(){return g},Kl:function(){return v},LU:function(){return p},Md:function(){return h},WH:function(){return m},Zg:function(){return b},Zn:function(){return x},os:function(){return _},sY:function(){return j},x9:function(){return N},xn:function(){return y},yc:function(){return u}});var r=t(85893),a=t(67294),s=t(53302),l=t(11886),o=t(88950),i=t(51214),c=t(41664),d=t.n(c);let u=i.nb.REFRESH_INTERVAL,f={placement:"bottom",color:"default"},m=e=>{let{children:n,...t}=e,a=t.content;return t.content=void 0,(0,r.jsx)(s.e,{...f,...t,content:(0,r.jsx)("span",{className:"left-full w-max px-2 py-1 text-sm text-gray-100 bg-gray-500 text-sm capitalize rounded",children:a}),children:n})},h=e=>{let{children:n,...t}=e,a=t.content;return t.content=void 0,(0,r.jsx)(s.e,{...f,...t,content:(0,r.jsx)("span",{className:"left-full w-max px-2 py-1 text-sm text-gray-100 bg-gray-500 text-sm rounded",children:a}),children:n})};function p(e){if(!e&&0!==e)return"-";let n=e=Math.floor(e),t="",r=0;for(let e of[{value:31536e3,label:"y"},{value:2592e3,label:"mo"},{value:86400,label:"d"},{value:3600,label:"h"},{value:60,label:"m"},{value:1,label:"s"}])if(n>=e.value&&r<2){let a=Math.floor(n/e.value);t+="".concat(a).concat(e.label," "),n%=e.value,r++}return t.trim()||"0s"}function x(e){return e.replace(/\x1b\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGKH]/g,"")}function g(e){let{logs:n,controller:t=!1}=e,[s,l]=(0,a.useState)("all"),[i,c]=(0,a.useState)(n),[d,u]=(0,a.useState)([]);return(0,a.useEffect)(()=>{u(function(e){let n;let t=/\((head|worker\d+),/g,r=new Set;for(;null!==(n=t.exec(e));)r.add(n[1]);return Array.from(r).sort((e,n)=>"head"===e?-1:"head"===n?1:e.localeCompare(n,void 0,{numeric:!0,sensitivity:"base"}))}(n))},[n]),(0,a.useEffect)(()=>{"all"===s?c(n):c(n.split("\n").filter(e=>e.includes("(".concat(s,","))).join("\n"))},[s,n]),(0,r.jsxs)("div",{children:[(0,r.jsx)("style",{children:'\n .logs-container {\n background-color: #f7f7f7;\n padding: 16px;\n max-height: calc(100vh - 300px);\n overflow-y: auto;\n overflow-x: hidden;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;\n line-height: 1.5;\n border-radius: 6px;\n min-height: fit-content;\n }\n\n .log-line {\n display: block;\n white-space: pre-wrap;\n margin: 2px 0;\n }\n\n .log-line .level {\n display: inline;\n width: 1ch;\n margin-right: 1ch;\n font-weight: bold;\n }\n\n .log-line.INFO .level {\n color: #2563eb;\n }\n\n .log-line.WARNING .level {\n color: #d97706;\n }\n\n .log-line.ERROR .level {\n color: #dc2626;\n }\n\n .log-line.DEBUG .level {\n color: #6b7280;\n }\n\n .log-line .timestamp {\n color: #059669;\n margin-right: 1ch;\n white-space: nowrap;\n }\n\n .log-line .location {\n color: #6366f1;\n margin-right: 1ch;\n white-space: nowrap;\n }\n\n .log-line .message {\n color: #111827;\n word-break: break-word;\n white-space: pre-wrap;\n }\n\n .log-line .log-prefix {\n color: #6366f1;\n font-weight: 500;\n }\n\n .log-line .log-rest {\n color: #111827;\n word-break: break-word;\n white-space: pre-wrap;\n }\n'}),!t&&(0,r.jsx)("div",{style:{marginBottom:"1rem"},children:(0,r.jsxs)(o.Ph,{onValueChange:e=>l(e),value:s,children:[(0,r.jsx)(o.i4,{"aria-label":"Node",className:"focus:ring-0 focus:ring-offset-0",children:(0,r.jsx)(o.ki,{placeholder:"Select Node"})}),(0,r.jsxs)(o.Bw,{children:[(0,r.jsx)(o.Ql,{value:"all",children:"All Nodes"}),d.map(e=>(0,r.jsx)(o.Ql,{value:e,children:e},e))]})]})}),(0,r.jsx)("div",{className:"logs-container",dangerouslySetInnerHTML:{__html:i?x(i).split("\n").filter(e=>""!==e.trim()&&!e.match(/<rich_.*?\[bold cyan\]/)&&!e.match(/<rich_.*>.*<\/rich_.*>/)&&!e.match(/├──/)&&!e.match(/└──/)).map(e=>'<span class="log-line"><span class="message">'.concat(e,"</span></span>")).join("\n"):""}})]})}function b(e){let n,{date:t}=e;if(!t)return"N/A";let a=new Date,s=t.getFullYear()+"-"+String(t.getMonth()+1).padStart(2,"0")+"-"+String(t.getDate()).padStart(2,"0"),o=t.toLocaleString("en-US",{hour:"numeric",minute:"2-digit",second:"2-digit",hour12:!0,timeZoneName:"short"});return n=function(e){if(!e||"string"!=typeof e)return e;if("just now"===e)return"now";if("less than a minute ago"===e.toLowerCase())return"Less than 1m ago";let n=e.match(/^about\s+(\d+)\s+(\w+)\s+ago$/i);if(n){let e=n[1],t=n[2],r={second:"s",seconds:"s",minute:"m",minutes:"m",hour:"h",hours:"h",day:"d",days:"d",month:"mo",months:"mo",year:"yr",years:"yr"};if(r[t])return"".concat(e).concat(r[t]," ago")}let t=e.match(/^a[n]?\s+(\w+)\s+ago$/i);if(t){let e=t[1],n={second:"s",minute:"m",hour:"h",day:"d",month:"mo",year:"yr"};if(n[e])return"1".concat(n[e]," ago")}let r=e.match(/^(\d+)\s+(\w+)\s+ago$/i);if(r){let e=r[1],n=r[2],t={second:"s",seconds:"s",minute:"m",minutes:"m",hour:"h",hours:"h",day:"d",days:"d",month:"mo",months:"mo",year:"yr",years:"yr"};if(t[n])return"".concat(e).concat(t[n]," ago")}return e}((0,l.B)(t,a,{addSuffix:!0})),(0,r.jsx)(m,{content:s+" "+o,className:"text-sm text-muted-foreground",children:(0,r.jsx)("span",{className:"border-b border-dotted border-gray-400 cursor-help",children:n})})}function y(e){return e?e.getFullYear()+"-"+String(e.getMonth()+1).padStart(2,"0")+"-"+String(e.getDate()).padStart(2,"0")+" "+e.toLocaleString("en-US",{hour:"numeric",minute:"2-digit",second:"2-digit",hour12:!0,timeZoneName:"short"}):"N/A"}let j=e=>e&&e.jobCounts?e.jobCounts:{},w=e=>{if(!e||0===e.length)return{};let n=e.filter(e=>"READY"===e.status),t={};n.forEach(e=>{try{let n=e.cloud&&""!==e.cloud.trim()&&"undefined"!==e.cloud,r=e.region&&"undefined"!==e.region&&null!==e.region&&""!==e.region.trim();if(!n&&!r)return;let a=n?e.cloud:"Unknown",s=r?e.region:null;t[a]||(t[a]={count:0,regions:new Set}),t[a].count+=1,s&&t[a].regions.add(s)}catch(e){t.Unknown||(t.Unknown={count:0,regions:new Set}),t.Unknown.count+=1}});let r={};return Object.entries(t).forEach(e=>{let[n,t]=e,a=t.regions.size,s=n.toLowerCase().includes("kubernetes")||n.toLowerCase().includes("k8s")?"context":"region",l=1===a?"1 ".concat(s):"".concat(a," ").concat(s,"s");r[a>0?"".concat(n," (").concat(l,")"):n]=t.count}),r},N=e=>{let{jobCounts:n,getStatusStyle:t}=e;return n&&0!==Object.keys(n).length?(0,r.jsx)("div",{className:"flex flex-wrap gap-1",children:Object.entries(n).map(e=>{let[n,a]=e,s=t(n);return(0,r.jsxs)("span",{className:"px-2 py-1 rounded-full flex items-center space-x-2 text-xs font-medium ".concat(s),children:[(0,r.jsx)("span",{children:n}),(0,r.jsx)("span",{className:"text-xs bg-white/50 px-1.5 py-0.5 rounded",children:a})]},n)})}):(0,r.jsx)("span",{className:"text-gray-1000",children:"No active jobs"})},v=e=>{let{replicaInfo:n}=e,t=w(n);if(0===Object.keys(t).length)return(0,r.jsx)("span",{className:"text-gray-500 text-sm",children:"-"});let a=i.MO.NAME_TRUNCATE_LENGTH,s=e=>{let n=e.indexOf("(");if(-1===n)return e;let t=e.substring(0,n).trim(),r=e.substring(n+1,e.length-1);if(r.length<=a)return e;let s="".concat(r.substring(0,Math.floor((a-3)/2)),"...").concat(r.substring(r.length-Math.ceil((a-3)/2)));return"".concat(t," (").concat(s,")")};return(0,r.jsx)("div",{className:"flex flex-wrap gap-1",children:Object.entries(t).map(e=>{let[n,t]=e,a=s(n),l=a!==n;return(0,r.jsxs)("span",{className:"px-2 py-1 rounded-full flex items-center space-x-2 text-xs font-medium bg-blue-50 text-blue-700",children:[l?(0,r.jsx)(h,{content:n,className:"text-sm text-muted-foreground",children:(0,r.jsx)("span",{children:a})}):(0,r.jsx)("span",{children:n}),(0,r.jsx)("span",{className:"text-xs bg-white/50 px-1.5 py-0.5 rounded",children:t})]},n)})})},_=(e,n,t)=>{if(!e)return"-";if(t.find(t=>t.name===e&&t.hash===n)&&n)return(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,r.jsx)(h,{content:"This pool is running",placement:"top",children:(0,r.jsx)("div",{className:"w-2 h-2 bg-green-700 rounded-full"})}),(0,r.jsx)(d(),{href:"/jobs/pools/".concat(e),className:"text-gray-700 hover:text-blue-600 hover:underline",children:e})]});let a=n?n.substring(0,4):"";return(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,r.jsx)(h,{content:"This pool is terminated",placement:"top",children:(0,r.jsx)("div",{className:"w-2 h-2 bg-gray-800"})}),(0,r.jsxs)("span",{children:[e," (",a,")"]})]})}},51214:function(e,n,t){t.d(n,{MO:function(){return s},ej:function(){return r},nb:function(){return a}});let r={DEFAULT_TTL:12e4},a={REFRESH_INTERVAL:3e4,GPU_REFRESH_INTERVAL:3e4},s={NAME_TRUNCATE_LENGTH:20}}}]);
|