skypilot-nightly 1.0.0.dev20250827__py3-none-any.whl → 1.0.0.dev20250829__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/admin_policy.py +11 -10
- sky/authentication.py +1 -1
- sky/backends/backend.py +3 -5
- sky/backends/backend_utils.py +140 -52
- sky/backends/cloud_vm_ray_backend.py +30 -25
- sky/backends/local_docker_backend.py +3 -8
- sky/backends/wheel_utils.py +35 -8
- sky/client/cli/command.py +41 -9
- sky/client/sdk.py +23 -8
- sky/client/sdk_async.py +6 -2
- sky/clouds/aws.py +118 -1
- sky/core.py +1 -4
- sky/dashboard/out/404.html +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/global_user_state.py +82 -22
- sky/jobs/client/sdk.py +5 -2
- sky/jobs/recovery_strategy.py +9 -4
- sky/jobs/server/server.py +2 -1
- sky/logs/agent.py +2 -2
- sky/logs/aws.py +6 -3
- sky/provision/aws/config.py +78 -3
- sky/provision/aws/instance.py +45 -6
- sky/provision/do/utils.py +2 -1
- sky/provision/kubernetes/instance.py +55 -11
- sky/provision/kubernetes/utils.py +11 -2
- sky/provision/nebius/utils.py +36 -2
- sky/schemas/db/global_user_state/007_cluster_event_request_id.py +34 -0
- sky/serve/client/impl.py +5 -4
- sky/serve/replica_managers.py +4 -3
- sky/serve/serve_utils.py +2 -2
- sky/serve/server/impl.py +3 -2
- sky/serve/server/server.py +2 -1
- sky/server/auth/oauth2_proxy.py +10 -4
- sky/server/common.py +4 -4
- sky/server/daemons.py +16 -5
- sky/server/requests/executor.py +5 -3
- sky/server/requests/payloads.py +3 -1
- sky/server/requests/preconditions.py +3 -2
- sky/server/requests/requests.py +121 -19
- sky/server/server.py +85 -60
- sky/server/stream_utils.py +7 -5
- sky/setup_files/dependencies.py +6 -1
- sky/sky_logging.py +28 -0
- sky/skylet/constants.py +6 -0
- sky/skylet/events.py +2 -3
- sky/skypilot_config.py +10 -10
- sky/task.py +1 -1
- sky/templates/aws-ray.yml.j2 +1 -0
- sky/templates/nebius-ray.yml.j2 +4 -8
- sky/usage/usage_lib.py +3 -2
- sky/utils/annotations.py +8 -2
- sky/utils/cluster_utils.py +3 -3
- sky/utils/common_utils.py +0 -72
- sky/utils/controller_utils.py +4 -3
- sky/utils/dag_utils.py +4 -4
- sky/utils/db/db_utils.py +11 -0
- sky/utils/db/migration_utils.py +1 -1
- sky/utils/kubernetes/config_map_utils.py +3 -3
- sky/utils/kubernetes_enums.py +1 -0
- sky/utils/lock_events.py +94 -0
- sky/utils/schemas.py +3 -0
- sky/utils/timeline.py +24 -93
- sky/utils/yaml_utils.py +77 -10
- {skypilot_nightly-1.0.0.dev20250827.dist-info → skypilot_nightly-1.0.0.dev20250829.dist-info}/METADATA +8 -2
- {skypilot_nightly-1.0.0.dev20250827.dist-info → skypilot_nightly-1.0.0.dev20250829.dist-info}/RECORD +86 -84
- /sky/dashboard/out/_next/static/{-eL7Ky3bxVivzeLHNB9U6 → hYJYFIxp_ZFONR4wTIJqZ}/_buildManifest.js +0 -0
- /sky/dashboard/out/_next/static/{-eL7Ky3bxVivzeLHNB9U6 → hYJYFIxp_ZFONR4wTIJqZ}/_ssgManifest.js +0 -0
- {skypilot_nightly-1.0.0.dev20250827.dist-info → skypilot_nightly-1.0.0.dev20250829.dist-info}/WHEEL +0 -0
- {skypilot_nightly-1.0.0.dev20250827.dist-info → skypilot_nightly-1.0.0.dev20250829.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20250827.dist-info → skypilot_nightly-1.0.0.dev20250829.dist-info}/licenses/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev20250827.dist-info → skypilot_nightly-1.0.0.dev20250829.dist-info}/top_level.txt +0 -0
sky/backends/wheel_utils.py
CHANGED
|
@@ -16,6 +16,7 @@ import pathlib
|
|
|
16
16
|
import re
|
|
17
17
|
import shutil
|
|
18
18
|
import subprocess
|
|
19
|
+
import sys
|
|
19
20
|
import tempfile
|
|
20
21
|
from typing import Optional, Tuple
|
|
21
22
|
|
|
@@ -133,19 +134,45 @@ def _build_sky_wheel() -> pathlib.Path:
|
|
|
133
134
|
# It is important to normalize the path, otherwise 'pip wheel' would
|
|
134
135
|
# treat the directory as a file and generate an empty wheel.
|
|
135
136
|
norm_path = str(tmp_dir) + os.sep
|
|
137
|
+
# TODO(#5046): Consider adding native UV support for building wheels.
|
|
138
|
+
# Use `python -m pip` instead of `pip3` for better compatibility across
|
|
139
|
+
# different environments (conda, venv, UV, system Python, etc.)
|
|
136
140
|
try:
|
|
137
|
-
# TODO(suquark): For python>=3.7, 'subprocess.run' supports capture
|
|
138
|
-
# of the output.
|
|
139
141
|
subprocess.run([
|
|
140
|
-
'
|
|
142
|
+
sys.executable, '-m', 'pip', 'wheel', '--no-deps', norm_path,
|
|
143
|
+
'--wheel-dir',
|
|
141
144
|
str(tmp_dir)
|
|
142
145
|
],
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
+
capture_output=True,
|
|
147
|
+
check=True,
|
|
148
|
+
text=True)
|
|
146
149
|
except subprocess.CalledProcessError as e:
|
|
147
|
-
|
|
148
|
-
|
|
150
|
+
error_msg = e.stderr
|
|
151
|
+
if 'No module named pip' in error_msg:
|
|
152
|
+
# pip module not found - provide helpful suggestions based on
|
|
153
|
+
# the available package managers
|
|
154
|
+
if shutil.which('uv'):
|
|
155
|
+
msg = ('pip module not found. Since you have UV installed, '
|
|
156
|
+
'you can install pip by running:\n'
|
|
157
|
+
' uv pip install pip')
|
|
158
|
+
elif shutil.which('conda'):
|
|
159
|
+
msg = (
|
|
160
|
+
'pip module not found. Since you have conda installed, '
|
|
161
|
+
'you can install pip by running:\n'
|
|
162
|
+
' conda install pip')
|
|
163
|
+
else:
|
|
164
|
+
msg = ('pip module not found. Please install pip for your '
|
|
165
|
+
f'Python environment ({sys.executable}).')
|
|
166
|
+
else:
|
|
167
|
+
# Other pip errors
|
|
168
|
+
msg = f'pip wheel command failed. Error: {error_msg}'
|
|
169
|
+
raise RuntimeError('Failed to build pip wheel for SkyPilot.\n' +
|
|
170
|
+
msg) from e
|
|
171
|
+
except FileNotFoundError as e:
|
|
172
|
+
# Python executable not found (extremely rare)
|
|
173
|
+
raise RuntimeError(
|
|
174
|
+
f'Failed to build pip wheel for SkyPilot. '
|
|
175
|
+
f'Python executable not found: {sys.executable}') from e
|
|
149
176
|
|
|
150
177
|
try:
|
|
151
178
|
wheel_path = next(tmp_dir.glob(_WHEEL_PATTERN))
|
sky/client/cli/command.py
CHANGED
|
@@ -287,9 +287,10 @@ def _complete_cluster_name(ctx: click.Context, param: click.Parameter,
|
|
|
287
287
|
del ctx, param # Unused.
|
|
288
288
|
# TODO(zhwu): we send requests to API server for completion, which can cause
|
|
289
289
|
# large latency. We should investigate caching mechanism if needed.
|
|
290
|
-
response =
|
|
291
|
-
|
|
290
|
+
response = server_common.make_authenticated_request(
|
|
291
|
+
'GET',
|
|
292
292
|
f'/api/completion/cluster_name?incomplete={incomplete}',
|
|
293
|
+
retry=False,
|
|
293
294
|
timeout=2.0,
|
|
294
295
|
)
|
|
295
296
|
response.raise_for_status()
|
|
@@ -300,9 +301,10 @@ def _complete_storage_name(ctx: click.Context, param: click.Parameter,
|
|
|
300
301
|
incomplete: str) -> List[str]:
|
|
301
302
|
"""Handle shell completion for storage names."""
|
|
302
303
|
del ctx, param # Unused.
|
|
303
|
-
response =
|
|
304
|
-
|
|
304
|
+
response = server_common.make_authenticated_request(
|
|
305
|
+
'GET',
|
|
305
306
|
f'/api/completion/storage_name?incomplete={incomplete}',
|
|
307
|
+
retry=False,
|
|
306
308
|
timeout=2.0,
|
|
307
309
|
)
|
|
308
310
|
response.raise_for_status()
|
|
@@ -313,15 +315,34 @@ def _complete_volume_name(ctx: click.Context, param: click.Parameter,
|
|
|
313
315
|
incomplete: str) -> List[str]:
|
|
314
316
|
"""Handle shell completion for volume names."""
|
|
315
317
|
del ctx, param # Unused.
|
|
316
|
-
response =
|
|
317
|
-
|
|
318
|
+
response = server_common.make_authenticated_request(
|
|
319
|
+
'GET',
|
|
318
320
|
f'/api/completion/volume_name?incomplete={incomplete}',
|
|
321
|
+
retry=False,
|
|
319
322
|
timeout=2.0,
|
|
320
323
|
)
|
|
321
324
|
response.raise_for_status()
|
|
322
325
|
return response.json()
|
|
323
326
|
|
|
324
327
|
|
|
328
|
+
def _complete_api_request(ctx: click.Context, param: click.Parameter,
|
|
329
|
+
incomplete: str) -> List[str]:
|
|
330
|
+
"""Handle shell completion for API requests."""
|
|
331
|
+
del ctx, param # Unused.
|
|
332
|
+
response = server_common.make_authenticated_request(
|
|
333
|
+
'GET',
|
|
334
|
+
f'/api/completion/api_request?incomplete={incomplete}',
|
|
335
|
+
retry=False,
|
|
336
|
+
timeout=2.0,
|
|
337
|
+
)
|
|
338
|
+
try:
|
|
339
|
+
response.raise_for_status()
|
|
340
|
+
except requests_lib.exceptions.HTTPError:
|
|
341
|
+
# Server may be outdated/missing this API. Silently skip.
|
|
342
|
+
return []
|
|
343
|
+
return response.json()
|
|
344
|
+
|
|
345
|
+
|
|
325
346
|
def _complete_file_name(ctx: click.Context, param: click.Parameter,
|
|
326
347
|
incomplete: str) -> List[str]:
|
|
327
348
|
"""Handle shell completion for file names.
|
|
@@ -6018,7 +6039,10 @@ def api_stop():
|
|
|
6018
6039
|
|
|
6019
6040
|
@api.command('logs', cls=_DocumentedCodeCommand)
|
|
6020
6041
|
@flags.config_option(expose_value=False)
|
|
6021
|
-
@click.argument('request_id',
|
|
6042
|
+
@click.argument('request_id',
|
|
6043
|
+
required=False,
|
|
6044
|
+
type=str,
|
|
6045
|
+
**_get_shell_complete_args(_complete_api_request))
|
|
6022
6046
|
@click.option('--server-logs',
|
|
6023
6047
|
is_flag=True,
|
|
6024
6048
|
default=False,
|
|
@@ -6062,7 +6086,11 @@ def api_logs(request_id: Optional[str], server_logs: bool,
|
|
|
6062
6086
|
|
|
6063
6087
|
@api.command('cancel', cls=_DocumentedCodeCommand)
|
|
6064
6088
|
@flags.config_option(expose_value=False)
|
|
6065
|
-
@click.argument('request_ids',
|
|
6089
|
+
@click.argument('request_ids',
|
|
6090
|
+
required=False,
|
|
6091
|
+
type=str,
|
|
6092
|
+
nargs=-1,
|
|
6093
|
+
**_get_shell_complete_args(_complete_api_request))
|
|
6066
6094
|
@flags.all_option('Cancel all your requests.')
|
|
6067
6095
|
@flags.all_users_option('Cancel all requests from all users.')
|
|
6068
6096
|
@usage_lib.entrypoint
|
|
@@ -6094,7 +6122,11 @@ def api_cancel(request_ids: Optional[List[str]], all: bool, all_users: bool):
|
|
|
6094
6122
|
|
|
6095
6123
|
@api.command('status', cls=_DocumentedCodeCommand)
|
|
6096
6124
|
@flags.config_option(expose_value=False)
|
|
6097
|
-
@click.argument('request_ids',
|
|
6125
|
+
@click.argument('request_ids',
|
|
6126
|
+
required=False,
|
|
6127
|
+
type=str,
|
|
6128
|
+
nargs=-1,
|
|
6129
|
+
**_get_shell_complete_args(_complete_api_request))
|
|
6098
6130
|
@click.option('--all-status',
|
|
6099
6131
|
'-a',
|
|
6100
6132
|
is_flag=True,
|
sky/client/sdk.py
CHANGED
|
@@ -53,6 +53,7 @@ from sky.utils import rich_utils
|
|
|
53
53
|
from sky.utils import status_lib
|
|
54
54
|
from sky.utils import subprocess_utils
|
|
55
55
|
from sky.utils import ux_utils
|
|
56
|
+
from sky.utils import yaml_utils
|
|
56
57
|
from sky.utils.kubernetes import ssh_utils
|
|
57
58
|
|
|
58
59
|
if typing.TYPE_CHECKING:
|
|
@@ -100,7 +101,8 @@ def reload_config() -> None:
|
|
|
100
101
|
def stream_response(request_id: None,
|
|
101
102
|
response: 'requests.Response',
|
|
102
103
|
output_stream: Optional['io.TextIOBase'] = None,
|
|
103
|
-
resumable: bool = False
|
|
104
|
+
resumable: bool = False,
|
|
105
|
+
get_result: bool = True) -> None:
|
|
104
106
|
...
|
|
105
107
|
|
|
106
108
|
|
|
@@ -108,14 +110,16 @@ def stream_response(request_id: None,
|
|
|
108
110
|
def stream_response(request_id: server_common.RequestId[T],
|
|
109
111
|
response: 'requests.Response',
|
|
110
112
|
output_stream: Optional['io.TextIOBase'] = None,
|
|
111
|
-
resumable: bool = False
|
|
113
|
+
resumable: bool = False,
|
|
114
|
+
get_result: bool = True) -> T:
|
|
112
115
|
...
|
|
113
116
|
|
|
114
117
|
|
|
115
118
|
def stream_response(request_id: Optional[server_common.RequestId[T]],
|
|
116
119
|
response: 'requests.Response',
|
|
117
120
|
output_stream: Optional['io.TextIOBase'] = None,
|
|
118
|
-
resumable: bool = False
|
|
121
|
+
resumable: bool = False,
|
|
122
|
+
get_result: bool = True) -> Optional[T]:
|
|
119
123
|
"""Streams the response to the console.
|
|
120
124
|
|
|
121
125
|
Args:
|
|
@@ -128,6 +132,9 @@ def stream_response(request_id: Optional[server_common.RequestId[T]],
|
|
|
128
132
|
console.
|
|
129
133
|
resumable: Whether the response is resumable on retry. If True, the
|
|
130
134
|
streaming will start from the previous failure point on retry.
|
|
135
|
+
get_result: Whether to get the result of the request. This will
|
|
136
|
+
typically be set to False for `--no-follow` flags as requests may
|
|
137
|
+
continue to run for long periods of time without further streaming.
|
|
131
138
|
"""
|
|
132
139
|
|
|
133
140
|
retry_context: Optional[rest.RetryContext] = None
|
|
@@ -143,7 +150,7 @@ def stream_response(request_id: Optional[server_common.RequestId[T]],
|
|
|
143
150
|
elif line_count > retry_context.line_processed:
|
|
144
151
|
print(line, flush=True, end='', file=output_stream)
|
|
145
152
|
retry_context.line_processed = line_count
|
|
146
|
-
if request_id is not None:
|
|
153
|
+
if request_id is not None and get_result:
|
|
147
154
|
return get(request_id)
|
|
148
155
|
else:
|
|
149
156
|
return None
|
|
@@ -942,10 +949,13 @@ def tail_provision_logs(cluster_name: str,
|
|
|
942
949
|
# to return cleanly after printing the tailed lines. If we provided a
|
|
943
950
|
# non-None request_id here, the get(request_id) in stream_response(
|
|
944
951
|
# would fail since /provision_logs does not create a request record.
|
|
952
|
+
# By virtue of this, we set get_result to False to block get() from
|
|
953
|
+
# running.
|
|
945
954
|
stream_response(request_id=None,
|
|
946
955
|
response=response,
|
|
947
956
|
output_stream=output_stream,
|
|
948
|
-
resumable=(tail == 0)
|
|
957
|
+
resumable=(tail == 0),
|
|
958
|
+
get_result=False)
|
|
949
959
|
return 0
|
|
950
960
|
|
|
951
961
|
|
|
@@ -2025,6 +2035,8 @@ def stream_and_get(
|
|
|
2025
2035
|
Returns:
|
|
2026
2036
|
The ``Request Returns`` of the specified request. See the documentation
|
|
2027
2037
|
of the specific requests above for more details.
|
|
2038
|
+
If follow is False, will always return None. See note on
|
|
2039
|
+
stream_response.
|
|
2028
2040
|
|
|
2029
2041
|
Raises:
|
|
2030
2042
|
Exception: It raises the same exceptions as the specific requests,
|
|
@@ -2056,7 +2068,10 @@ def stream_and_get(
|
|
|
2056
2068
|
if request_id is None:
|
|
2057
2069
|
return None
|
|
2058
2070
|
return get(request_id)
|
|
2059
|
-
return stream_response(request_id,
|
|
2071
|
+
return stream_response(request_id,
|
|
2072
|
+
response,
|
|
2073
|
+
output_stream,
|
|
2074
|
+
get_result=follow)
|
|
2060
2075
|
|
|
2061
2076
|
|
|
2062
2077
|
@usage_lib.entrypoint
|
|
@@ -2332,7 +2347,7 @@ def _save_config_updates(endpoint: Optional[str] = None,
|
|
|
2332
2347
|
config['api_server'][
|
|
2333
2348
|
'service_account_token'] = service_account_token
|
|
2334
2349
|
|
|
2335
|
-
|
|
2350
|
+
yaml_utils.dump_yaml(str(config_path), config)
|
|
2336
2351
|
skypilot_config.reload_config()
|
|
2337
2352
|
|
|
2338
2353
|
|
|
@@ -2348,7 +2363,7 @@ def _clear_api_server_config() -> None:
|
|
|
2348
2363
|
config = dict(config)
|
|
2349
2364
|
del config['api_server']
|
|
2350
2365
|
|
|
2351
|
-
|
|
2366
|
+
yaml_utils.dump_yaml(str(config_path), config, blank=True)
|
|
2352
2367
|
skypilot_config.reload_config()
|
|
2353
2368
|
|
|
2354
2369
|
|
sky/client/sdk_async.py
CHANGED
|
@@ -144,7 +144,8 @@ async def get(request_id: str) -> Any:
|
|
|
144
144
|
async def stream_response_async(request_id: Optional[str],
|
|
145
145
|
response: 'aiohttp.ClientResponse',
|
|
146
146
|
output_stream: Optional['io.TextIOBase'] = None,
|
|
147
|
-
resumable: bool = False
|
|
147
|
+
resumable: bool = False,
|
|
148
|
+
get_result: bool = True) -> Any:
|
|
148
149
|
"""Async version of stream_response that streams the response to the
|
|
149
150
|
console.
|
|
150
151
|
|
|
@@ -155,6 +156,9 @@ async def stream_response_async(request_id: Optional[str],
|
|
|
155
156
|
console.
|
|
156
157
|
resumable: Whether the response is resumable on retry. If True, the
|
|
157
158
|
streaming will start from the previous failure point on retry.
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
Result of request_id if given. Will only return if get_result is True.
|
|
158
162
|
"""
|
|
159
163
|
|
|
160
164
|
retry_context: Optional[rest.RetryContext] = None
|
|
@@ -170,7 +174,7 @@ async def stream_response_async(request_id: Optional[str],
|
|
|
170
174
|
elif line_count > retry_context.line_processed:
|
|
171
175
|
print(line, flush=True, end='', file=output_stream)
|
|
172
176
|
retry_context.line_processed = line_count
|
|
173
|
-
if request_id is not None:
|
|
177
|
+
if request_id is not None and get_result:
|
|
174
178
|
return await get(request_id)
|
|
175
179
|
except Exception: # pylint: disable=broad-except
|
|
176
180
|
logger.debug(f'To stream request logs: sky api logs {request_id}')
|
sky/clouds/aws.py
CHANGED
|
@@ -77,6 +77,103 @@ DEFAULT_SECURITY_GROUP_NAME = f'sky-sg-{common_utils.user_and_hostname_hash()}'
|
|
|
77
77
|
# Security group to use when user specified ports in their resources.
|
|
78
78
|
USER_PORTS_SECURITY_GROUP_NAME = 'sky-sg-{}'
|
|
79
79
|
|
|
80
|
+
# GPU instance types that support EFA
|
|
81
|
+
# TODO(hailong): Some CPU instance types also support EFA, may need to support
|
|
82
|
+
# all of them later.
|
|
83
|
+
# TODO(hailong): Add the EFA info in catalog.
|
|
84
|
+
_EFA_INSTANCE_TYPE_PREFIXES = [
|
|
85
|
+
'g4dn.',
|
|
86
|
+
'g5.',
|
|
87
|
+
'g6.',
|
|
88
|
+
'gr6.',
|
|
89
|
+
'g6e.',
|
|
90
|
+
'p4d.',
|
|
91
|
+
'p4de.',
|
|
92
|
+
'p5.',
|
|
93
|
+
'p5e.',
|
|
94
|
+
'p5en.',
|
|
95
|
+
'p6-b200.',
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
# Docker run options for EFA.
|
|
99
|
+
# Refer to https://github.com/ofiwg/libfabric/issues/6437 for updating
|
|
100
|
+
# memlock ulimit
|
|
101
|
+
_EFA_DOCKER_RUN_OPTIONS = [
|
|
102
|
+
'--cap-add=IPC_LOCK',
|
|
103
|
+
'--device=/dev/infiniband',
|
|
104
|
+
'--ulimit memlock=-1:-1',
|
|
105
|
+
]
|
|
106
|
+
|
|
107
|
+
# AWS EFA image name.
|
|
108
|
+
# Refer to https://docs.aws.amazon.com/dlami/latest/devguide/aws-deep-learning-base-gpu-ami-ubuntu-22-04.html for latest version. # pylint: disable=line-too-long
|
|
109
|
+
# TODO(hailong): may need to update the version later.
|
|
110
|
+
_EFA_IMAGE_NAME = 'Deep Learning Base OSS Nvidia Driver GPU AMI' \
|
|
111
|
+
' (Ubuntu 22.04) 20250808'
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def _is_efa_instance_type(instance_type: str) -> bool:
|
|
115
|
+
"""Check if the instance type is in EFA supported instance family."""
|
|
116
|
+
return any(
|
|
117
|
+
instance_type.startswith(prefix)
|
|
118
|
+
for prefix in _EFA_INSTANCE_TYPE_PREFIXES)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@annotations.lru_cache(scope='global', maxsize=128)
|
|
122
|
+
def _get_efa_image_id(region_name: str) -> Optional[str]:
|
|
123
|
+
"""Get the EFA image id for the given region."""
|
|
124
|
+
try:
|
|
125
|
+
client = aws.client('ec2', region_name=region_name)
|
|
126
|
+
response = client.describe_images(Filters=[{
|
|
127
|
+
'Name': 'name',
|
|
128
|
+
'Values': [_EFA_IMAGE_NAME]
|
|
129
|
+
}])
|
|
130
|
+
if 'Images' not in response:
|
|
131
|
+
return None
|
|
132
|
+
if len(response['Images']) == 0:
|
|
133
|
+
return None
|
|
134
|
+
available_images = [
|
|
135
|
+
img for img in response['Images'] if img['State'] == 'available'
|
|
136
|
+
]
|
|
137
|
+
if len(available_images) == 0:
|
|
138
|
+
return None
|
|
139
|
+
sorted_images = sorted(available_images,
|
|
140
|
+
key=lambda x: x['CreationDate'],
|
|
141
|
+
reverse=True)
|
|
142
|
+
return sorted_images[0]['ImageId']
|
|
143
|
+
except (aws.botocore_exceptions().NoCredentialsError,
|
|
144
|
+
aws.botocore_exceptions().ProfileNotFound,
|
|
145
|
+
aws.botocore_exceptions().ClientError) as e:
|
|
146
|
+
with ux_utils.print_exception_no_traceback():
|
|
147
|
+
raise ValueError(f'Failed to get EFA image id: {e}') from None
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@annotations.lru_cache(scope='global', maxsize=128)
|
|
151
|
+
def _get_max_efa_interfaces(instance_type: str, region_name: str) -> int:
|
|
152
|
+
"""Get the maximum number of EFA interfaces for the given instance type."""
|
|
153
|
+
if not _is_efa_instance_type(instance_type):
|
|
154
|
+
return 0
|
|
155
|
+
try:
|
|
156
|
+
client = aws.client('ec2', region_name=region_name)
|
|
157
|
+
response = client.describe_instance_types(
|
|
158
|
+
InstanceTypes=[instance_type],
|
|
159
|
+
Filters=[{
|
|
160
|
+
'Name': 'network-info.efa-supported',
|
|
161
|
+
'Values': ['true']
|
|
162
|
+
}])
|
|
163
|
+
if 'InstanceTypes' in response and len(response['InstanceTypes']) > 0:
|
|
164
|
+
network_info = response['InstanceTypes'][0]['NetworkInfo']
|
|
165
|
+
if ('EfaInfo' in network_info and
|
|
166
|
+
'MaximumEfaInterfaces' in network_info['EfaInfo']):
|
|
167
|
+
return network_info['EfaInfo']['MaximumEfaInterfaces']
|
|
168
|
+
return 0
|
|
169
|
+
except (aws.botocore_exceptions().NoCredentialsError,
|
|
170
|
+
aws.botocore_exceptions().ProfileNotFound,
|
|
171
|
+
aws.botocore_exceptions().ClientError) as e:
|
|
172
|
+
with ux_utils.print_exception_no_traceback():
|
|
173
|
+
raise ValueError(
|
|
174
|
+
f'Failed to get max EFA interfaces for {instance_type}: {e}'
|
|
175
|
+
) from None
|
|
176
|
+
|
|
80
177
|
|
|
81
178
|
class AWSIdentityType(enum.Enum):
|
|
82
179
|
"""AWS identity type.
|
|
@@ -295,8 +392,13 @@ class AWS(clouds.Cloud):
|
|
|
295
392
|
image_id: Optional[Dict[Optional[str], str]],
|
|
296
393
|
region_name: str,
|
|
297
394
|
instance_type: str,
|
|
395
|
+
enable_efa: bool,
|
|
298
396
|
) -> str:
|
|
299
397
|
if image_id is None:
|
|
398
|
+
if enable_efa:
|
|
399
|
+
efa_image_id = _get_efa_image_id(region_name)
|
|
400
|
+
if efa_image_id:
|
|
401
|
+
return efa_image_id
|
|
300
402
|
return cls._get_default_ami(region_name, instance_type)
|
|
301
403
|
if None in image_id:
|
|
302
404
|
image_id_str = image_id[None]
|
|
@@ -499,12 +601,25 @@ class AWS(clouds.Cloud):
|
|
|
499
601
|
custom_resources = resources_utils.make_ray_custom_resources_str(
|
|
500
602
|
acc_dict)
|
|
501
603
|
|
|
604
|
+
network_tier = (resources.network_tier if resources.network_tier
|
|
605
|
+
is not None else resources_utils.NetworkTier.STANDARD)
|
|
606
|
+
if network_tier == resources_utils.NetworkTier.BEST:
|
|
607
|
+
max_efa_interfaces = _get_max_efa_interfaces(
|
|
608
|
+
resources.instance_type, region_name)
|
|
609
|
+
enable_efa = max_efa_interfaces > 0
|
|
610
|
+
else:
|
|
611
|
+
max_efa_interfaces = 0
|
|
612
|
+
enable_efa = False
|
|
613
|
+
|
|
614
|
+
docker_run_options = []
|
|
502
615
|
if resources.extract_docker_image() is not None:
|
|
503
616
|
image_id_to_use = None
|
|
617
|
+
if enable_efa:
|
|
618
|
+
docker_run_options = _EFA_DOCKER_RUN_OPTIONS
|
|
504
619
|
else:
|
|
505
620
|
image_id_to_use = resources.image_id
|
|
506
621
|
image_id = self._get_image_id(image_id_to_use, region_name,
|
|
507
|
-
resources.instance_type)
|
|
622
|
+
resources.instance_type, enable_efa)
|
|
508
623
|
|
|
509
624
|
root_device_name = self.get_image_root_device_name(
|
|
510
625
|
image_id, region_name)
|
|
@@ -563,6 +678,8 @@ class AWS(clouds.Cloud):
|
|
|
563
678
|
'security_group': security_group,
|
|
564
679
|
'security_group_managed_by_skypilot':
|
|
565
680
|
str(security_group != user_security_group).lower(),
|
|
681
|
+
'max_efa_interfaces': max_efa_interfaces,
|
|
682
|
+
'docker_run_options': docker_run_options,
|
|
566
683
|
**AWS._get_disk_specs(resources.disk_tier)
|
|
567
684
|
}
|
|
568
685
|
|
sky/core.py
CHANGED
|
@@ -594,10 +594,7 @@ def down(cluster_name: str, purge: bool = False) -> None:
|
|
|
594
594
|
|
|
595
595
|
usage_lib.record_cluster_name_for_current_operation(cluster_name)
|
|
596
596
|
backend = backend_utils.get_backend_from_handle(handle)
|
|
597
|
-
backend.teardown(handle,
|
|
598
|
-
terminate=True,
|
|
599
|
-
purge=purge,
|
|
600
|
-
explicitly_requested=True)
|
|
597
|
+
backend.teardown(handle, terminate=True, purge=purge)
|
|
601
598
|
|
|
602
599
|
|
|
603
600
|
@usage_lib.entrypoint
|
sky/dashboard/out/404.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><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-6e76f636a048e145.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
|
|
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-6e76f636a048e145.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/hYJYFIxp_ZFONR4wTIJqZ/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_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":"hYJYFIxp_ZFONR4wTIJqZ","assetPrefix":"/dashboard","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-4b4d5e824b7f9d3c.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters/%5Bcluster%5D/%5Bjob%5D-06afb50d25f7c61f.js" defer=""></script><script src="/dashboard/_next/static
|
|
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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-4b4d5e824b7f9d3c.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters/%5Bcluster%5D/%5Bjob%5D-06afb50d25f7c61f.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters/[cluster]/[job]","query":{},"buildId":"hYJYFIxp_ZFONR4wTIJqZ","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/4676-9da7fdbde90b5549.js" defer=""></script><script src="/dashboard/_next/static/chunks/754-d0da8ab45f9509e9.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-4a6f1a928fb6d370.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-08b2a1cae076a943.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-4b4d5e824b7f9d3c.js" defer=""></script><script src="/dashboard/_next/static/chunks/1121-8afcf719ea87debc.js" defer=""></script><script src="/dashboard/_next/static/chunks/6856-049014c6d43d127b.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-06114c982db410b6.js" defer=""></script><script src="/dashboard/_next/static/chunks/3015-6c9c09593b1e67b6.js" defer=""></script><script src="/dashboard/_next/static/chunks/9037-89a84fd7fa31362d.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters/%5Bcluster%5D-a0527109c2fab467.js" defer=""></script><script src="/dashboard/_next/static
|
|
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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/4676-9da7fdbde90b5549.js" defer=""></script><script src="/dashboard/_next/static/chunks/754-d0da8ab45f9509e9.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-4a6f1a928fb6d370.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-08b2a1cae076a943.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-4b4d5e824b7f9d3c.js" defer=""></script><script src="/dashboard/_next/static/chunks/1121-8afcf719ea87debc.js" defer=""></script><script src="/dashboard/_next/static/chunks/6856-049014c6d43d127b.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-06114c982db410b6.js" defer=""></script><script src="/dashboard/_next/static/chunks/3015-6c9c09593b1e67b6.js" defer=""></script><script src="/dashboard/_next/static/chunks/9037-89a84fd7fa31362d.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters/%5Bcluster%5D-a0527109c2fab467.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters/[cluster]","query":{},"buildId":"hYJYFIxp_ZFONR4wTIJqZ","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/dashboard/out/clusters.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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters-469814d711d63b1b.js" defer=""></script><script src="/dashboard/_next/static
|
|
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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters-469814d711d63b1b.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters","query":{},"buildId":"hYJYFIxp_ZFONR4wTIJqZ","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/dashboard/out/config.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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/config-dfb9bf07b13045f4.js" defer=""></script><script src="/dashboard/_next/static
|
|
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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/config-dfb9bf07b13045f4.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/config","query":{},"buildId":"hYJYFIxp_ZFONR4wTIJqZ","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/dashboard/out/index.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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/index-444f1804401f04ea.js" defer=""></script><script src="/dashboard/_next/static
|
|
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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/index-444f1804401f04ea.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/","query":{},"buildId":"hYJYFIxp_ZFONR4wTIJqZ","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-6e76f636a048e145.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/infra/%5Bcontext%5D-81351f95f3bec08e.js" defer=""></script><script src="/dashboard/_next/static
|
|
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-6e76f636a048e145.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/infra/%5Bcontext%5D-81351f95f3bec08e.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/infra/[context]","query":{},"buildId":"hYJYFIxp_ZFONR4wTIJqZ","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/dashboard/out/infra.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-6e76f636a048e145.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/infra-c320641c2bcbbea6.js" defer=""></script><script src="/dashboard/_next/static
|
|
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-6e76f636a048e145.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/infra-c320641c2bcbbea6.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/infra","query":{},"buildId":"hYJYFIxp_ZFONR4wTIJqZ","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/754-d0da8ab45f9509e9.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-4a6f1a928fb6d370.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-4b4d5e824b7f9d3c.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/%5Bjob%5D-dd64309c3fe67ed2.js" defer=""></script><script src="/dashboard/_next/static
|
|
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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/754-d0da8ab45f9509e9.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-4a6f1a928fb6d370.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-4b4d5e824b7f9d3c.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/%5Bjob%5D-dd64309c3fe67ed2.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs/[job]","query":{},"buildId":"hYJYFIxp_ZFONR4wTIJqZ","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/754-d0da8ab45f9509e9.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-4a6f1a928fb6d370.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/pools/%5Bpool%5D-07349868f7905d37.js" defer=""></script><script src="/dashboard/_next/static
|
|
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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/754-d0da8ab45f9509e9.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-4a6f1a928fb6d370.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/pools/%5Bpool%5D-07349868f7905d37.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/hYJYFIxp_ZFONR4wTIJqZ/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs/pools/[pool]","query":{},"buildId":"hYJYFIxp_ZFONR4wTIJqZ","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|