skypilot-nightly 1.0.0.dev20250321__py3-none-any.whl → 1.0.0.dev20250323__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.
- sky/__init__.py +2 -2
- sky/adaptors/cloudflare.py +0 -1
- sky/check.py +98 -29
- sky/clouds/cloud.py +2 -1
- sky/clouds/nebius.py +52 -8
- sky/core.py +3 -3
- sky/data/storage.py +4 -2
- sky/optimizer.py +4 -4
- sky/utils/kubernetes/gpu_labeler.py +4 -4
- sky/utils/kubernetes/kubernetes_deploy_utils.py +3 -3
- {skypilot_nightly-1.0.0.dev20250321.dist-info → skypilot_nightly-1.0.0.dev20250323.dist-info}/METADATA +6 -7
- {skypilot_nightly-1.0.0.dev20250321.dist-info → skypilot_nightly-1.0.0.dev20250323.dist-info}/RECORD +16 -16
- {skypilot_nightly-1.0.0.dev20250321.dist-info → skypilot_nightly-1.0.0.dev20250323.dist-info}/WHEEL +0 -0
- {skypilot_nightly-1.0.0.dev20250321.dist-info → skypilot_nightly-1.0.0.dev20250323.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20250321.dist-info → skypilot_nightly-1.0.0.dev20250323.dist-info}/licenses/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev20250321.dist-info → skypilot_nightly-1.0.0.dev20250323.dist-info}/top_level.txt +0 -0
sky/__init__.py
CHANGED
@@ -5,7 +5,7 @@ from typing import Optional
|
|
5
5
|
import urllib.request
|
6
6
|
|
7
7
|
# Replaced with the current commit when building the wheels.
|
8
|
-
_SKYPILOT_COMMIT_SHA = '
|
8
|
+
_SKYPILOT_COMMIT_SHA = '139a09e3445956740743049d352cd1cb6d202479'
|
9
9
|
|
10
10
|
|
11
11
|
def _get_git_commit():
|
@@ -35,7 +35,7 @@ def _get_git_commit():
|
|
35
35
|
|
36
36
|
|
37
37
|
__commit__ = _get_git_commit()
|
38
|
-
__version__ = '1.0.0.
|
38
|
+
__version__ = '1.0.0.dev20250323'
|
39
39
|
__root_dir__ = os.path.dirname(os.path.abspath(__file__))
|
40
40
|
|
41
41
|
|
sky/adaptors/cloudflare.py
CHANGED
sky/check.py
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
import os
|
3
3
|
import traceback
|
4
4
|
from types import ModuleType
|
5
|
-
from typing import Dict, Iterable, List, Optional, Set, Tuple,
|
5
|
+
from typing import (Any, Callable, Dict, Iterable, List, Optional, Set, Tuple,
|
6
|
+
Union)
|
6
7
|
|
7
8
|
import click
|
8
9
|
import colorama
|
@@ -42,6 +43,10 @@ def check_capabilities(
|
|
42
43
|
ModuleType]]) -> None:
|
43
44
|
cloud_repr, cloud = cloud_tuple
|
44
45
|
assert capabilities is not None
|
46
|
+
# cloud_capabilities is a list of (capability, ok, reason)
|
47
|
+
# where ok is True if the cloud credentials are valid for the capability
|
48
|
+
cloud_capabilities: List[Tuple[sky_cloud.CloudCapability, bool,
|
49
|
+
Optional[str]]] = []
|
45
50
|
for capability in capabilities:
|
46
51
|
with rich_utils.safe_status(f'Checking {cloud_repr}...'):
|
47
52
|
try:
|
@@ -52,28 +57,20 @@ def check_capabilities(
|
|
52
57
|
# Catch all exceptions to prevent a single cloud
|
53
58
|
# from blocking the check for other clouds.
|
54
59
|
ok, reason = False, traceback.format_exc()
|
55
|
-
|
56
|
-
|
57
|
-
echo(' ' + click.style(f'{cloud_repr}: {status_msg}', **styles) +
|
58
|
-
' ' * 30)
|
60
|
+
cloud_capabilities.append(
|
61
|
+
(capability, ok, reason.strip() if reason else None))
|
59
62
|
if ok:
|
60
63
|
enabled_clouds.setdefault(cloud_repr, []).append(capability)
|
61
|
-
if verbose and cloud is not cloudflare:
|
62
|
-
activated_account = cloud.get_active_user_identity_str()
|
63
|
-
if activated_account is not None:
|
64
|
-
echo(f' Activated account: {activated_account}')
|
65
|
-
if reason is not None:
|
66
|
-
echo(f' Hint: {reason}')
|
67
64
|
else:
|
68
65
|
disabled_clouds.setdefault(cloud_repr, []).append(capability)
|
69
|
-
|
66
|
+
_print_checked_cloud(echo, verbose, cloud_tuple, cloud_capabilities)
|
70
67
|
|
71
68
|
def get_cloud_tuple(
|
72
69
|
cloud_name: str) -> Tuple[str, Union[sky_clouds.Cloud, ModuleType]]:
|
73
70
|
# Validates cloud_name and returns a tuple of the cloud's name and
|
74
71
|
# the cloud object. Includes special handling for Cloudflare.
|
75
72
|
if cloud_name.lower().startswith('cloudflare'):
|
76
|
-
return cloudflare.
|
73
|
+
return cloudflare.NAME, cloudflare
|
77
74
|
else:
|
78
75
|
cloud_obj = registry.CLOUD_REGISTRY.from_str(cloud_name)
|
79
76
|
assert cloud_obj is not None, f'Cloud {cloud_name!r} not found'
|
@@ -81,7 +78,7 @@ def check_capabilities(
|
|
81
78
|
|
82
79
|
def get_all_clouds():
|
83
80
|
return tuple([repr(c) for c in registry.CLOUD_REGISTRY.values()] +
|
84
|
-
[cloudflare.
|
81
|
+
[cloudflare.NAME])
|
85
82
|
|
86
83
|
if clouds is not None:
|
87
84
|
cloud_list = clouds
|
@@ -158,8 +155,8 @@ def check_capabilities(
|
|
158
155
|
echo(click.style(disallowed_clouds_hint, dim=True))
|
159
156
|
raise SystemExit()
|
160
157
|
else:
|
161
|
-
clouds_arg = (' '
|
162
|
-
|
158
|
+
clouds_arg = (f' {" ".join(disabled_clouds).lower()}'
|
159
|
+
if clouds is not None else '')
|
163
160
|
echo(
|
164
161
|
click.style(
|
165
162
|
'\nTo enable a cloud, follow the hints above and rerun: ',
|
@@ -175,7 +172,8 @@ def check_capabilities(
|
|
175
172
|
# Pretty print for UX.
|
176
173
|
if not quiet:
|
177
174
|
enabled_clouds_str = '\n ' + '\n '.join([
|
178
|
-
_format_enabled_cloud(cloud
|
175
|
+
_format_enabled_cloud(cloud, capabilities)
|
176
|
+
for cloud, capabilities in enabled_clouds.items()
|
179
177
|
])
|
180
178
|
echo(f'\n{colorama.Fore.GREEN}{PARTY_POPPER_EMOJI} '
|
181
179
|
f'Enabled clouds {PARTY_POPPER_EMOJI}'
|
@@ -183,14 +181,11 @@ def check_capabilities(
|
|
183
181
|
return enabled_clouds
|
184
182
|
|
185
183
|
|
186
|
-
|
187
|
-
|
188
|
-
# This necessitates setting default capability to CloudCapability.COMPUTE.
|
189
|
-
def check(
|
184
|
+
def check_capability(
|
185
|
+
capability: sky_cloud.CloudCapability,
|
190
186
|
quiet: bool = False,
|
191
187
|
verbose: bool = False,
|
192
188
|
clouds: Optional[Iterable[str]] = None,
|
193
|
-
capability: sky_cloud.CloudCapability = sky_cloud.CloudCapability.COMPUTE,
|
194
189
|
) -> List[str]:
|
195
190
|
clouds_with_capability = []
|
196
191
|
enabled_clouds = check_capabilities(quiet, verbose, clouds, [capability])
|
@@ -200,6 +195,16 @@ def check(
|
|
200
195
|
return clouds_with_capability
|
201
196
|
|
202
197
|
|
198
|
+
def check(
|
199
|
+
quiet: bool = False,
|
200
|
+
verbose: bool = False,
|
201
|
+
clouds: Optional[Iterable[str]] = None,
|
202
|
+
) -> List[str]:
|
203
|
+
return list(
|
204
|
+
check_capabilities(quiet, verbose, clouds,
|
205
|
+
sky_cloud.ALL_CAPABILITIES).keys())
|
206
|
+
|
207
|
+
|
203
208
|
def get_cached_enabled_clouds_or_refresh(
|
204
209
|
capability: sky_cloud.CloudCapability,
|
205
210
|
raise_if_no_cloud_access: bool = False) -> List[sky_clouds.Cloud]:
|
@@ -219,7 +224,7 @@ def get_cached_enabled_clouds_or_refresh(
|
|
219
224
|
capability)
|
220
225
|
if not cached_enabled_clouds:
|
221
226
|
try:
|
222
|
-
|
227
|
+
check_capability(sky_cloud.CloudCapability.COMPUTE, quiet=True)
|
223
228
|
except SystemExit:
|
224
229
|
# If no cloud is enabled, check() will raise SystemExit.
|
225
230
|
# Here we catch it and raise the exception later only if
|
@@ -267,16 +272,80 @@ def get_cloud_credential_file_mounts(
|
|
267
272
|
return file_mounts
|
268
273
|
|
269
274
|
|
270
|
-
def
|
275
|
+
def _print_checked_cloud(
|
276
|
+
echo: Callable,
|
277
|
+
verbose: bool,
|
278
|
+
cloud_tuple: Tuple[str, Union[sky_clouds.Cloud, ModuleType]],
|
279
|
+
cloud_capabilities: List[Tuple[sky_cloud.CloudCapability, bool,
|
280
|
+
Optional[str]]],
|
281
|
+
) -> None:
|
282
|
+
"""Prints whether a cloud is enabled, and the capabilities that are enabled.
|
283
|
+
If any hints (for enabled capabilities) or
|
284
|
+
reasons (for disabled capabilities) are provided, they will be printed.
|
285
|
+
|
286
|
+
Args:
|
287
|
+
echo: The function to use to print the message.
|
288
|
+
verbose: Whether to print the verbose output.
|
289
|
+
cloud_tuple: The cloud to print the capabilities for.
|
290
|
+
cloud_capabilities: The capabilities for the cloud.
|
291
|
+
"""
|
292
|
+
cloud_repr, cloud = cloud_tuple
|
293
|
+
# Print the capabilities for the cloud.
|
294
|
+
# consider cloud enabled if any capability is enabled.
|
295
|
+
enabled_capabilities: List[sky_cloud.CloudCapability] = []
|
296
|
+
hints_to_capabilities: Dict[str, List[sky_cloud.CloudCapability]] = {}
|
297
|
+
reasons_to_capabilities: Dict[str, List[sky_cloud.CloudCapability]] = {}
|
298
|
+
for capability, ok, reason in cloud_capabilities:
|
299
|
+
if ok:
|
300
|
+
enabled_capabilities.append(capability)
|
301
|
+
if reason is not None:
|
302
|
+
hints_to_capabilities.setdefault(reason, []).append(capability)
|
303
|
+
elif reason is not None:
|
304
|
+
reasons_to_capabilities.setdefault(reason, []).append(capability)
|
305
|
+
status_msg: str = 'disabled'
|
306
|
+
styles: Dict[str, Any] = {'dim': True}
|
307
|
+
capability_string: str = ''
|
308
|
+
activated_account: Optional[str] = None
|
309
|
+
if enabled_capabilities:
|
310
|
+
status_msg = 'enabled'
|
311
|
+
styles = {'fg': 'green', 'bold': False}
|
312
|
+
capability_string = f'[{", ".join(enabled_capabilities)}]'
|
313
|
+
if verbose and cloud is not cloudflare:
|
314
|
+
activated_account = cloud.get_active_user_identity_str()
|
315
|
+
|
316
|
+
echo(
|
317
|
+
click.style(f' {cloud_repr}: {status_msg} {capability_string}',
|
318
|
+
**styles))
|
319
|
+
if activated_account is not None:
|
320
|
+
echo(f' Activated account: {activated_account}')
|
321
|
+
for reason, caps in hints_to_capabilities.items():
|
322
|
+
echo(f' Hint [{", ".join(caps)}]: {reason}')
|
323
|
+
for reason, caps in reasons_to_capabilities.items():
|
324
|
+
echo(f' Reason [{", ".join(caps)}]: {reason}')
|
325
|
+
|
326
|
+
|
327
|
+
def _format_enabled_cloud(cloud_name: str,
|
328
|
+
capabilities: List[sky_cloud.CloudCapability]) -> str:
|
329
|
+
"""Format the summary of enabled cloud and its enabled capabilities.
|
330
|
+
|
331
|
+
Args:
|
332
|
+
cloud_name: The name of the cloud.
|
333
|
+
capabilities: The capabilities of the cloud.
|
334
|
+
|
335
|
+
Returns:
|
336
|
+
A string of the formatted cloud and capabilities.
|
337
|
+
"""
|
338
|
+
cloud_and_capabilities = f'{cloud_name} [{", ".join(capabilities)}]'
|
271
339
|
|
272
|
-
def _green_color(
|
273
|
-
return
|
340
|
+
def _green_color(str_to_format: str) -> str:
|
341
|
+
return (
|
342
|
+
f'{colorama.Fore.GREEN}{str_to_format}{colorama.Style.RESET_ALL}')
|
274
343
|
|
275
344
|
if cloud_name == repr(sky_clouds.Kubernetes()):
|
276
345
|
# Get enabled contexts for Kubernetes
|
277
346
|
existing_contexts = sky_clouds.Kubernetes.existing_allowed_contexts()
|
278
347
|
if not existing_contexts:
|
279
|
-
return _green_color(
|
348
|
+
return _green_color(cloud_and_capabilities)
|
280
349
|
|
281
350
|
# Check if allowed_contexts is explicitly set in config
|
282
351
|
allowed_contexts = skypilot_config.get_nested(
|
@@ -294,7 +363,7 @@ def _format_enabled_cloud(cloud_name: str) -> str:
|
|
294
363
|
else:
|
295
364
|
context_info = f'Active context: {existing_contexts[0]}'
|
296
365
|
|
297
|
-
return (f'{_green_color(
|
366
|
+
return (f'{_green_color(cloud_and_capabilities)}\n'
|
298
367
|
f' {colorama.Style.DIM}{context_info}'
|
299
368
|
f'{colorama.Style.RESET_ALL}')
|
300
|
-
return _green_color(
|
369
|
+
return _green_color(cloud_and_capabilities)
|
sky/clouds/cloud.py
CHANGED
@@ -50,7 +50,8 @@ class CloudImplementationFeatures(enum.Enum):
|
|
50
50
|
AUTO_TERMINATE = 'auto_terminate' # Pod/VM can stop or down itself
|
51
51
|
|
52
52
|
|
53
|
-
|
53
|
+
# Use str, enum.Enum to allow CloudCapability to be used as a string.
|
54
|
+
class CloudCapability(str, enum.Enum):
|
54
55
|
# Compute capability.
|
55
56
|
COMPUTE = 'compute'
|
56
57
|
# Storage capability.
|
sky/clouds/nebius.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
""" Nebius Cloud. """
|
2
2
|
import logging
|
3
|
+
import os
|
3
4
|
import typing
|
4
5
|
from typing import Dict, Iterator, List, Optional, Tuple, Union
|
5
6
|
|
@@ -20,6 +21,22 @@ _CREDENTIAL_FILES = [
|
|
20
21
|
nebius.NEBIUS_CREDENTIALS_FILENAME
|
21
22
|
]
|
22
23
|
|
24
|
+
_INDENT_PREFIX = ' '
|
25
|
+
|
26
|
+
|
27
|
+
def nebius_profile_in_aws_cred() -> bool:
|
28
|
+
"""Checks if Nebius Object Storage profile is set in aws credentials."""
|
29
|
+
|
30
|
+
profile_path = os.path.expanduser('~/.aws/credentials')
|
31
|
+
nebius_profile_exists = False
|
32
|
+
if os.path.isfile(profile_path):
|
33
|
+
with open(profile_path, 'r', encoding='utf-8') as file:
|
34
|
+
for line in file:
|
35
|
+
if f'[{nebius.NEBIUS_PROFILE_NAME}]' in line:
|
36
|
+
nebius_profile_exists = True
|
37
|
+
|
38
|
+
return nebius_profile_exists
|
39
|
+
|
23
40
|
|
24
41
|
@registry.CLOUD_REGISTRY.register
|
25
42
|
class Nebius(clouds.Cloud):
|
@@ -254,14 +271,15 @@ class Nebius(clouds.Cloud):
|
|
254
271
|
"""Checks if the user has access credentials to
|
255
272
|
Nebius's compute service."""
|
256
273
|
logging.debug('Nebius cloud check credentials')
|
257
|
-
token_cred_msg = (
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
'
|
264
|
-
f'
|
274
|
+
token_cred_msg = (
|
275
|
+
f'{_INDENT_PREFIX}Credentials can be set up by running: \n'
|
276
|
+
f'{_INDENT_PREFIX} $ nebius iam get-access-token > {nebius.NEBIUS_IAM_TOKEN_PATH} \n' # pylint: disable=line-too-long
|
277
|
+
f'{_INDENT_PREFIX} or generate ~/.nebius/credentials.json')
|
278
|
+
|
279
|
+
tenant_msg = (f'{_INDENT_PREFIX}Copy your tenat ID from the web console and save it to file \n' # pylint: disable=line-too-long
|
280
|
+
f'{_INDENT_PREFIX} $ echo $NEBIUS_TENANT_ID_PATH > {nebius.NEBIUS_TENANT_ID_PATH} \n' # pylint: disable=line-too-long
|
281
|
+
f'{_INDENT_PREFIX} Or if you have 1 tenant you can run:\n' # pylint: disable=line-too-long
|
282
|
+
f'{_INDENT_PREFIX} $ nebius --format json iam whoami|jq -r \'.user_profile.tenants[0].tenant_id\' > {nebius.NEBIUS_TENANT_ID_PATH} \n') # pylint: disable=line-too-long
|
265
283
|
if not nebius.is_token_or_cred_file_exist():
|
266
284
|
return False, f'{token_cred_msg}'
|
267
285
|
sdk = nebius.sdk()
|
@@ -279,6 +297,32 @@ class Nebius(clouds.Cloud):
|
|
279
297
|
f'{tenant_msg}')
|
280
298
|
return True, None
|
281
299
|
|
300
|
+
@classmethod
|
301
|
+
def _check_storage_credentials(cls) -> Tuple[bool, Optional[str]]:
|
302
|
+
"""Checks if the user has access credentials to Nebius Object Storage.
|
303
|
+
|
304
|
+
Returns:
|
305
|
+
A tuple of a boolean value and a hint message where the bool
|
306
|
+
is True when credentials needed for Nebius Object Storage is set.
|
307
|
+
It is False when either of those are not set, which would hint
|
308
|
+
with a string on unset credential.
|
309
|
+
"""
|
310
|
+
hints = None
|
311
|
+
if not nebius_profile_in_aws_cred():
|
312
|
+
hints = (f'[{nebius.NEBIUS_PROFILE_NAME}] profile '
|
313
|
+
'is not set in ~/.aws/credentials.')
|
314
|
+
if hints:
|
315
|
+
hints += ' Run the following commands:'
|
316
|
+
if not nebius_profile_in_aws_cred():
|
317
|
+
hints += (
|
318
|
+
f'\n{_INDENT_PREFIX} $ pip install boto3'
|
319
|
+
f'\n{_INDENT_PREFIX} $ aws configure --profile nebius')
|
320
|
+
hints += (
|
321
|
+
f'\n{_INDENT_PREFIX}For more info: '
|
322
|
+
'https://docs.skypilot.co/en/latest/getting-started/installation.html#nebius' # pylint: disable=line-too-long
|
323
|
+
)
|
324
|
+
return (False, hints) if hints else (True, hints)
|
325
|
+
|
282
326
|
def get_credential_file_mounts(self) -> Dict[str, str]:
|
283
327
|
credential_file_mounts = {
|
284
328
|
f'~/.nebius/{filename}': f'~/.nebius/{filename}'
|
sky/core.py
CHANGED
@@ -1136,9 +1136,9 @@ def local_down() -> None:
|
|
1136
1136
|
# Run sky check
|
1137
1137
|
with rich_utils.safe_status(
|
1138
1138
|
ux_utils.spinner_message('Running sky check...')):
|
1139
|
-
sky_check.
|
1140
|
-
|
1141
|
-
|
1139
|
+
sky_check.check_capability(sky_cloud.CloudCapability.COMPUTE,
|
1140
|
+
clouds=['kubernetes'],
|
1141
|
+
quiet=True)
|
1142
1142
|
logger.info(
|
1143
1143
|
ux_utils.finishing_message('Local cluster removed.',
|
1144
1144
|
log_path=log_path,
|
sky/data/storage.py
CHANGED
@@ -107,8 +107,10 @@ def _is_storage_cloud_enabled(cloud_name: str,
|
|
107
107
|
return True
|
108
108
|
if try_fix_with_sky_check:
|
109
109
|
# TODO(zhwu): Only check the specified cloud to speed up.
|
110
|
-
sky_check.
|
111
|
-
|
110
|
+
sky_check.check_capability(
|
111
|
+
sky_cloud.CloudCapability.STORAGE,
|
112
|
+
quiet=True,
|
113
|
+
)
|
112
114
|
return _is_storage_cloud_enabled(cloud_name,
|
113
115
|
try_fix_with_sky_check=False)
|
114
116
|
return False
|
sky/optimizer.py
CHANGED
@@ -1226,10 +1226,10 @@ def _check_specified_clouds(dag: 'dag_lib.Dag') -> None:
|
|
1226
1226
|
all_clouds_specified.add(cloud_str)
|
1227
1227
|
|
1228
1228
|
# Explicitly check again to update the enabled cloud list.
|
1229
|
-
sky_check.
|
1230
|
-
|
1231
|
-
|
1232
|
-
|
1229
|
+
sky_check.check_capability(sky_cloud.CloudCapability.COMPUTE,
|
1230
|
+
quiet=True,
|
1231
|
+
clouds=list(clouds_need_recheck -
|
1232
|
+
global_disabled_clouds))
|
1233
1233
|
enabled_clouds = sky_check.get_cached_enabled_clouds_or_refresh(
|
1234
1234
|
capability=sky_cloud.CloudCapability.COMPUTE,
|
1235
1235
|
raise_if_no_cloud_access=True)
|
@@ -45,8 +45,8 @@ def cleanup() -> Tuple[bool, str]:
|
|
45
45
|
|
46
46
|
success = False
|
47
47
|
reason = ''
|
48
|
-
with rich_utils.
|
49
|
-
|
48
|
+
with rich_utils.client_status('Cleaning up existing GPU labeling '
|
49
|
+
'resources'):
|
50
50
|
try:
|
51
51
|
subprocess.run(del_command.split(), check=True, capture_output=True)
|
52
52
|
success = True
|
@@ -72,7 +72,7 @@ def label():
|
|
72
72
|
manifest_dir = os.path.join(sky_dir, 'utils/kubernetes')
|
73
73
|
|
74
74
|
# Apply the RBAC manifest using kubectl since it contains multiple resources
|
75
|
-
with rich_utils.
|
75
|
+
with rich_utils.client_status('Setting up GPU labeling'):
|
76
76
|
rbac_manifest_path = os.path.join(manifest_dir,
|
77
77
|
'k8s_gpu_labeler_setup.yaml')
|
78
78
|
try:
|
@@ -83,7 +83,7 @@ def label():
|
|
83
83
|
print('Error setting up GPU labeling: ' + output)
|
84
84
|
return
|
85
85
|
|
86
|
-
with rich_utils.
|
86
|
+
with rich_utils.client_status('Creating GPU labeler jobs'):
|
87
87
|
config.load_kube_config()
|
88
88
|
|
89
89
|
v1 = client.CoreV1Api()
|
@@ -168,9 +168,9 @@ def deploy_local_cluster(gpus: bool):
|
|
168
168
|
f'\nError: {stderr}')
|
169
169
|
# Run sky check
|
170
170
|
with rich_utils.safe_status('[bold cyan]Running sky check...'):
|
171
|
-
sky_check.
|
172
|
-
|
173
|
-
|
171
|
+
sky_check.check_capability(sky_cloud.CloudCapability.COMPUTE,
|
172
|
+
quiet=True,
|
173
|
+
clouds=['kubernetes'])
|
174
174
|
if cluster_created:
|
175
175
|
# Prepare completion message which shows CPU and GPU count
|
176
176
|
# Get number of CPUs
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: skypilot-nightly
|
3
|
-
Version: 1.0.0.
|
3
|
+
Version: 1.0.0.dev20250323
|
4
4
|
Summary: SkyPilot: An intercloud broker for the clouds
|
5
5
|
Author: SkyPilot Team
|
6
6
|
License: Apache 2.0
|
@@ -232,8 +232,8 @@ SkyPilot **unifies multiple clusters, clouds, and hardware**:
|
|
232
232
|
|
233
233
|
SkyPilot **cuts your cloud costs & maximizes GPU availability**:
|
234
234
|
* Autostop: automatic cleanup of idle resources
|
235
|
-
* [
|
236
|
-
*
|
235
|
+
* [Spot instance support](https://docs.skypilot.co/en/latest/examples/managed-jobs.html#running-on-spot-instances): 3-6x cost savings, with preemption auto-recovery
|
236
|
+
* Intelligent scheduling: automatically run on the cheapest & most available infra
|
237
237
|
|
238
238
|
SkyPilot supports your existing GPU, TPU, and CPU workloads, with no code changes.
|
239
239
|
|
@@ -248,6 +248,9 @@ To get the latest features and fixes, use the nightly build or [install from sou
|
|
248
248
|
pip install "skypilot-nightly[kubernetes,aws,gcp,azure,oci,lambda,runpod,fluidstack,paperspace,cudo,ibm,scp,nebius]"
|
249
249
|
```
|
250
250
|
|
251
|
+
<p align="center">
|
252
|
+
<img src="docs/source/_static/intro.gif" alt="SkyPilot">
|
253
|
+
</p>
|
251
254
|
|
252
255
|
Current supported infra: Kubernetes, AWS, GCP, Azure, OCI, Lambda Cloud, Fluidstack,
|
253
256
|
RunPod, Cudo, Digital Ocean, Paperspace, Cloudflare, Samsung, IBM, Vast.ai,
|
@@ -310,10 +313,6 @@ SkyPilot then performs the heavy-lifting for you, including:
|
|
310
313
|
4. Run the task's `setup` commands to prepare the VM for running the task
|
311
314
|
5. Run the task's `run` commands
|
312
315
|
|
313
|
-
<p align="center">
|
314
|
-
<img src="https://i.imgur.com/TgamzZ2.gif" alt="SkyPilot Demo"/>
|
315
|
-
</p>
|
316
|
-
|
317
316
|
|
318
317
|
See [Quickstart](https://docs.skypilot.co/en/latest/getting-started/quickstart.html) to get started with SkyPilot.
|
319
318
|
|
{skypilot_nightly-1.0.0.dev20250321.dist-info → skypilot_nightly-1.0.0.dev20250323.dist-info}/RECORD
RENAMED
@@ -1,16 +1,16 @@
|
|
1
|
-
sky/__init__.py,sha256=
|
1
|
+
sky/__init__.py,sha256=kS85lUqX3HwAZtxCHEfDM43o19-cPgoPlZ14r6PB70c,6428
|
2
2
|
sky/admin_policy.py,sha256=hPo02f_A32gCqhUueF0QYy1fMSSKqRwYEg_9FxScN_s,3248
|
3
3
|
sky/authentication.py,sha256=hCEqi77nprQEg3ktfRL51xiiw16zwZOmFEDB_Z7fWVU,22384
|
4
|
-
sky/check.py,sha256=
|
4
|
+
sky/check.py,sha256=iMGuM7yjUPRgDHc13Pf1_LSybBqIexq-6aXfnVcaI54,15898
|
5
5
|
sky/cli.py,sha256=o1IHTY4YSJzsfkynTynaN1dB4RBPZIRZGWQ4rTnVVnQ,221956
|
6
6
|
sky/cloud_stores.py,sha256=yo8xQGr8iabYGmn0E6o6jHsfJiomXCTCcR-WMLnNYTQ,26718
|
7
|
-
sky/core.py,sha256=
|
7
|
+
sky/core.py,sha256=BpZ5v-2aQEUkE3izBfMRSVFrmuTWY5_X_siHRf_ZRtI,47817
|
8
8
|
sky/dag.py,sha256=Yl7Ry26Vql5cv4YMz8g9kOUgtoCihJnw7c8NgZYakMY,3242
|
9
9
|
sky/exceptions.py,sha256=wSLZlhXRTg4EmB1a0GIusaq5izhAReCV1krN_q5pG2s,16727
|
10
10
|
sky/execution.py,sha256=9L8NFOXNphtabnsL7mHGPJeGdw4n6gIIUEOzjW7CEHw,28294
|
11
11
|
sky/global_user_state.py,sha256=uGmwtUL-HVKGqEwlEvIXFcQ_w2IxGE4msnffXUxCIGI,33574
|
12
12
|
sky/models.py,sha256=4xSW05BdDPEjW8Ubvj3VlVOVnzv0TbrolsFvR5R5v1U,638
|
13
|
-
sky/optimizer.py,sha256=
|
13
|
+
sky/optimizer.py,sha256=xVcj8_6ubr7EcAkvYv5_2X1c9uZINslYG3PuxGItUe0,60826
|
14
14
|
sky/resources.py,sha256=2qc5U09MFDaJjI1dHcThcRodpMGY7HyXzQn8eC4lvbE,72402
|
15
15
|
sky/sky_logging.py,sha256=pID2RINjH62n7SZpv70DuN8BSFYdCfTJ2ScGQpVmugg,5725
|
16
16
|
sky/skypilot_config.py,sha256=bt1vSis2aKKdQfPz80-KcjM9vNIg_qYKLNXur782Poo,8693
|
@@ -18,7 +18,7 @@ sky/task.py,sha256=tzy1XwQQyb1XbaVrCYDM6T6tF6AJlFU0g9KtJwBzkvQ,55583
|
|
18
18
|
sky/adaptors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
19
|
sky/adaptors/aws.py,sha256=iH55Cm6eXWwufAG0Dgk7LTQcADawNa3ELrBH1m6yuSY,7617
|
20
20
|
sky/adaptors/azure.py,sha256=r8xkjRgZZQfsSExNdguFa6c5fCLcUhZrFV8zs62VExo,21986
|
21
|
-
sky/adaptors/cloudflare.py,sha256
|
21
|
+
sky/adaptors/cloudflare.py,sha256=8XFjBKMusnR7EmteEGAsAAQUG4J0lDlqk7lkaum_5-4,8276
|
22
22
|
sky/adaptors/common.py,sha256=nJmuBYFokCH0vX2oFqdAJYS-84FnUSTmIPKjAi4gqzo,2877
|
23
23
|
sky/adaptors/cudo.py,sha256=WGvIQrlzJkGDe02Ve7pygA56tHwUc4kwS3XHW8kMFAA,239
|
24
24
|
sky/adaptors/do.py,sha256=dJ0BYbkQoUWVu6_9Pxq3fOu6PngjZyyCQzgjnODXLCA,777
|
@@ -49,7 +49,7 @@ sky/client/sdk.py,sha256=DL-3aV-kbK3T70_qXrEiMlaUmbiHaJk513gLp2by-6Y,68352
|
|
49
49
|
sky/clouds/__init__.py,sha256=OW6mJ-9hpJSBORCgt2LippLQEYZHNfnBW1mooRNNvxo,1416
|
50
50
|
sky/clouds/aws.py,sha256=-feXZ72UMUjuZz8dV4qMTjMMTC9pwfkQQT3KJDcIv5A,54633
|
51
51
|
sky/clouds/azure.py,sha256=Zpo6ftWz_B30mX7N-An7JVO-8v7aU3f9cw1iH9phvwE,32251
|
52
|
-
sky/clouds/cloud.py,sha256=
|
52
|
+
sky/clouds/cloud.py,sha256=OoSyFNYtby2Y0h2TpfMB_lEeolIZOQcfKgIn6AvRC68,36694
|
53
53
|
sky/clouds/cudo.py,sha256=_UkLEtwJsfDMKlmJfML5W3rA8VArba4x8YGIdnvgZoM,13226
|
54
54
|
sky/clouds/do.py,sha256=AHbdq5HqxqxKYp3sOCvywXme_eLckYtn1x-1yhlNH7U,11522
|
55
55
|
sky/clouds/fluidstack.py,sha256=6868c-3zGE0SOmgsjTSqyP_CpCyO4KKqt4vfoDads5c,12551
|
@@ -57,7 +57,7 @@ sky/clouds/gcp.py,sha256=sUJ9LXUnMxYm6OYZ5P-z1dJHxgVILuC3OW3eFSTNCv8,56919
|
|
57
57
|
sky/clouds/ibm.py,sha256=XtuPN8QgrwJdb1qb_b-7KwAE2tf_N9wh9eEfi2tcg-s,22013
|
58
58
|
sky/clouds/kubernetes.py,sha256=ivk6GlAbhj3oDaFfcIzwz2x7qRBrzShglV4FfzikqS0,36169
|
59
59
|
sky/clouds/lambda_cloud.py,sha256=yWJI4y3w20y1x6y519e3h0C3c9uTE3ku46zaFHicu1o,12801
|
60
|
-
sky/clouds/nebius.py,sha256=
|
60
|
+
sky/clouds/nebius.py,sha256=4D7C2NQYI-BNhXWNOyAXNAZj7-5nN33VQW1sxfSGt9w,14662
|
61
61
|
sky/clouds/oci.py,sha256=YO4kjSsHBmAVH4z1TuVP72zfmC0BXte4E0xIyZir9N4,27622
|
62
62
|
sky/clouds/paperspace.py,sha256=bS1RQzBPkS8uXWEUd6b1sXaINwjGFWbv56i-xnotrRY,10955
|
63
63
|
sky/clouds/runpod.py,sha256=P486CMN-Mt3R-7jMVd3XIGjLWYy0X5B74dK_IgAp2Cg,12149
|
@@ -104,7 +104,7 @@ sky/data/__init__.py,sha256=Nhaf1NURisXpZuwWANa2IuCyppIuc720FRwqSE2oEwY,184
|
|
104
104
|
sky/data/data_transfer.py,sha256=-JcnVa_LT0kQejcSCnBwYtxhuuaNDPf_Q5oz62p186c,11973
|
105
105
|
sky/data/data_utils.py,sha256=m1rrspfkgux7awWwTvQLFBjVix2KbKgRwgnhJDv3pcw,29895
|
106
106
|
sky/data/mounting_utils.py,sha256=gLplBNKRQvVUBdkIRZO-wW4wpfY_F8xmkMyMfSZasTQ,16832
|
107
|
-
sky/data/storage.py,sha256=
|
107
|
+
sky/data/storage.py,sha256=FSWTfNqtRHoz5TFHD8R6lRqxat0RVLA_Dqi1NtR7mU0,233449
|
108
108
|
sky/data/storage_utils.py,sha256=GEERbieI4RoQ4LvzVBieVuvUaDDvfP958edjp8tiWNc,12935
|
109
109
|
sky/jobs/__init__.py,sha256=qoI53-xXE0-SOkrLWigvhgFXjk7dWE0OTqGPYIk-kmM,1458
|
110
110
|
sky/jobs/constants.py,sha256=1XiIqdR5dEgGgepLKWkZCRT3MYSsMBR-dO7N4RTsjwg,3088
|
@@ -341,15 +341,15 @@ sky/utils/kubernetes/deploy_remote_cluster.sh,sha256=SGnqa5ks5Og-F96S_PIUbKzuKAt
|
|
341
341
|
sky/utils/kubernetes/exec_kubeconfig_converter.py,sha256=fE1SnteoxI05EaugnWeV82hXwZTVHmbXsh1aaZAgF3c,2548
|
342
342
|
sky/utils/kubernetes/generate_kind_config.py,sha256=_TNLnifA_r7-CRq083IP1xjelYqiLjzQX9ohuqYpDH8,3187
|
343
343
|
sky/utils/kubernetes/generate_kubeconfig.sh,sha256=MBvXJio0PeujZSCXiRKE_pa6HCTiU9qBzR1WrXccVSY,10477
|
344
|
-
sky/utils/kubernetes/gpu_labeler.py,sha256=
|
344
|
+
sky/utils/kubernetes/gpu_labeler.py,sha256=9VZkC4UuR4vtE6TAz5P0i279Rn8KEaHE35JA9OVHxqI,7006
|
345
345
|
sky/utils/kubernetes/k8s_gpu_labeler_job.yaml,sha256=k0TBoQ4zgf79-sVkixKSGYFHQ7ZWF5gdVIZPupCCo9A,1224
|
346
346
|
sky/utils/kubernetes/k8s_gpu_labeler_setup.yaml,sha256=VLKT2KKimZu1GDg_4AIlIt488oMQvhRZWwsj9vBbPUg,3812
|
347
|
-
sky/utils/kubernetes/kubernetes_deploy_utils.py,sha256=
|
347
|
+
sky/utils/kubernetes/kubernetes_deploy_utils.py,sha256=NtfbovAECN2A_R8x4FiNPaBVPWeuwaOVuuGsnVOSk2g,10231
|
348
348
|
sky/utils/kubernetes/rsync_helper.sh,sha256=h4YwrPFf9727CACnMJvF3EyK_0OeOYKKt4su_daKekw,1256
|
349
349
|
sky/utils/kubernetes/ssh_jump_lifecycle_manager.py,sha256=Kq1MDygF2IxFmu9FXpCxqucXLmeUrvs6OtRij6XTQbo,6554
|
350
|
-
skypilot_nightly-1.0.0.
|
351
|
-
skypilot_nightly-1.0.0.
|
352
|
-
skypilot_nightly-1.0.0.
|
353
|
-
skypilot_nightly-1.0.0.
|
354
|
-
skypilot_nightly-1.0.0.
|
355
|
-
skypilot_nightly-1.0.0.
|
350
|
+
skypilot_nightly-1.0.0.dev20250323.dist-info/licenses/LICENSE,sha256=emRJAvE7ngL6x0RhQvlns5wJzGI3NEQ_WMjNmd9TZc4,12170
|
351
|
+
skypilot_nightly-1.0.0.dev20250323.dist-info/METADATA,sha256=VG551sKN7L9CWS5ZPTjWM9uWlcm6OMI55E6miZKEDg0,18438
|
352
|
+
skypilot_nightly-1.0.0.dev20250323.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
|
353
|
+
skypilot_nightly-1.0.0.dev20250323.dist-info/entry_points.txt,sha256=StA6HYpuHj-Y61L2Ze-hK2IcLWgLZcML5gJu8cs6nU4,36
|
354
|
+
skypilot_nightly-1.0.0.dev20250323.dist-info/top_level.txt,sha256=qA8QuiNNb6Y1OF-pCUtPEr6sLEwy2xJX06Bd_CrtrHY,4
|
355
|
+
skypilot_nightly-1.0.0.dev20250323.dist-info/RECORD,,
|
{skypilot_nightly-1.0.0.dev20250321.dist-info → skypilot_nightly-1.0.0.dev20250323.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|