skypilot-nightly 1.0.0.dev20250602__py3-none-any.whl → 1.0.0.dev20250604__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 +3 -3
- sky/adaptors/kubernetes.py +8 -0
- sky/backends/backend_utils.py +1 -0
- sky/backends/cloud_vm_ray_backend.py +8 -4
- sky/{clouds/service_catalog → catalog}/__init__.py +6 -17
- sky/{clouds/service_catalog → catalog}/aws_catalog.py +3 -3
- sky/{clouds/service_catalog → catalog}/azure_catalog.py +2 -2
- sky/{clouds/service_catalog → catalog}/common.py +10 -8
- sky/{clouds/service_catalog → catalog}/cudo_catalog.py +1 -1
- sky/{clouds/service_catalog → catalog}/data_fetchers/analyze.py +1 -1
- sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_aws.py +1 -1
- sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_vsphere.py +1 -1
- sky/{clouds/service_catalog → catalog}/do_catalog.py +1 -1
- sky/{clouds/service_catalog → catalog}/fluidstack_catalog.py +1 -1
- sky/{clouds/service_catalog → catalog}/gcp_catalog.py +2 -2
- sky/{clouds/service_catalog → catalog}/ibm_catalog.py +1 -1
- sky/{clouds/service_catalog → catalog}/kubernetes_catalog.py +2 -2
- sky/{clouds/service_catalog → catalog}/lambda_catalog.py +1 -1
- sky/{clouds/service_catalog → catalog}/nebius_catalog.py +1 -1
- sky/{clouds/service_catalog → catalog}/oci_catalog.py +1 -1
- sky/{clouds/service_catalog → catalog}/paperspace_catalog.py +1 -1
- sky/{clouds/service_catalog → catalog}/runpod_catalog.py +1 -1
- sky/{clouds/service_catalog → catalog}/scp_catalog.py +1 -1
- sky/{clouds/service_catalog → catalog}/ssh_catalog.py +3 -3
- sky/{clouds/service_catalog → catalog}/vast_catalog.py +1 -1
- sky/{clouds/service_catalog → catalog}/vsphere_catalog.py +1 -1
- sky/cli.py +7 -6
- sky/client/cli.py +7 -6
- sky/client/sdk.py +3 -4
- sky/clouds/aws.py +41 -40
- sky/clouds/azure.py +31 -34
- sky/clouds/cloud.py +8 -8
- sky/clouds/cudo.py +26 -26
- sky/clouds/do.py +24 -24
- sky/clouds/fluidstack.py +27 -29
- sky/clouds/gcp.py +45 -48
- sky/clouds/ibm.py +26 -26
- sky/clouds/kubernetes.py +24 -12
- sky/clouds/lambda_cloud.py +28 -30
- sky/clouds/nebius.py +26 -28
- sky/clouds/oci.py +32 -32
- sky/clouds/paperspace.py +24 -26
- sky/clouds/runpod.py +26 -28
- sky/clouds/scp.py +37 -36
- sky/clouds/utils/gcp_utils.py +3 -2
- sky/clouds/vast.py +27 -27
- sky/clouds/vsphere.py +12 -15
- sky/core.py +2 -2
- sky/dashboard/out/404.html +1 -1
- sky/dashboard/out/_next/static/chunks/236-fef38aa6e5639300.js +6 -0
- sky/dashboard/out/_next/static/chunks/37-947904ccc5687bac.js +6 -0
- sky/dashboard/out/_next/static/chunks/682-2be9b0f169727f2f.js +6 -0
- sky/dashboard/out/_next/static/chunks/856-f1b1f7f47edde2e8.js +1 -0
- sky/dashboard/out/_next/static/chunks/969-d7b6fb7f602bfcb3.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-158b70da336d8607.js +6 -0
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-62c9982dc3675725.js +6 -0
- sky/dashboard/out/_next/static/chunks/pages/{clusters-f37ff20f0af29aae.js → clusters-5549a350f97d7ef3.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/config-35383adcb0edb5e2.js +6 -0
- sky/dashboard/out/_next/static/chunks/pages/infra/{[context]-342bc15bb78ab2e5.js → [context]-b68ddeed712d45b5.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/{infra-7b4b8e7fa9fa0827.js → infra-13b117a831702196.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-a62a3c65dc9bc57c.js +11 -0
- sky/dashboard/out/_next/static/chunks/pages/{jobs-78a6c5ba3e24c0cf.js → jobs-a76b2700eca236f7.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/{users-89f9212b81d8897e.js → users-07b523ccb19317ad.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/workspace/{new-198b6e00d7d724c5.js → new-c7516f2b4c3727c0.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/workspaces/{[name]-2ce792183b03c341.js → [name]-7799de9e691e35d8.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/workspaces-f54921ec9eb20965.js +1 -0
- sky/dashboard/out/_next/static/css/63d3995d8b528eb1.css +3 -0
- sky/dashboard/out/_next/static/vWwfD3jOky5J5jULHp8JT/_buildManifest.js +1 -0
- 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.html +1 -1
- sky/dashboard/out/users.html +1 -1
- sky/dashboard/out/workspace/new.html +1 -1
- sky/dashboard/out/workspaces/[name].html +1 -1
- sky/dashboard/out/workspaces.html +1 -1
- sky/data/storage_utils.py +5 -2
- sky/execution.py +1 -2
- sky/global_user_state.py +2 -4
- sky/jobs/server/core.py +1 -1
- sky/jobs/utils.py +31 -1
- sky/optimizer.py +1 -1
- sky/provision/cudo/cudo_machine_type.py +1 -1
- sky/provision/gcp/constants.py +4 -0
- sky/provision/kubernetes/utils.py +35 -22
- sky/provision/vast/utils.py +1 -1
- sky/provision/vsphere/common/vim_utils.py +1 -2
- sky/provision/vsphere/instance.py +1 -1
- sky/provision/vsphere/vsphere_utils.py +7 -11
- sky/resources.py +33 -2
- sky/serve/server/core.py +1 -1
- sky/server/common.py +86 -53
- sky/server/constants.py +1 -1
- sky/server/requests/executor.py +4 -1
- sky/server/requests/payloads.py +16 -0
- sky/server/requests/serializers/decoders.py +1 -1
- sky/server/server.py +3 -3
- sky/skypilot_config.py +88 -37
- sky/usage/usage_lib.py +4 -3
- sky/utils/accelerator_registry.py +3 -3
- sky/utils/controller_utils.py +4 -14
- sky/utils/kubernetes/deploy_remote_cluster.py +2 -1
- sky/utils/schemas.py +6 -9
- {skypilot_nightly-1.0.0.dev20250602.dist-info → skypilot_nightly-1.0.0.dev20250604.dist-info}/METADATA +1 -1
- {skypilot_nightly-1.0.0.dev20250602.dist-info → skypilot_nightly-1.0.0.dev20250604.dist-info}/RECORD +127 -126
- sky/dashboard/out/_next/static/chunks/236-7458fda7b295f305.js +0 -6
- sky/dashboard/out/_next/static/chunks/37-b638675d511d58b4.js +0 -6
- sky/dashboard/out/_next/static/chunks/682-5c12535476a21ce3.js +0 -6
- sky/dashboard/out/_next/static/chunks/856-ab9627e7e8ac35e8.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-8f270e2c9c59fa1a.js +0 -6
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-25edb867a41b6b20.js +0 -6
- sky/dashboard/out/_next/static/chunks/pages/config-3c6a2dabf56e8cd6.js +0 -6
- sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-c0c1dff3cd463d9e.js +0 -11
- sky/dashboard/out/_next/static/chunks/pages/workspaces-17d41826537196e7.js +0 -1
- sky/dashboard/out/_next/static/css/2b3ee34e586949a3.css +0 -3
- sky/dashboard/out/_next/static/dev-ndwjPgd_uQ4dcXXiv/_buildManifest.js +0 -1
- /sky/{clouds/service_catalog → catalog}/config.py +0 -0
- /sky/{clouds/service_catalog → catalog}/constants.py +0 -0
- /sky/{clouds/service_catalog → catalog}/data_fetchers/__init__.py +0 -0
- /sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_azure.py +0 -0
- /sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_cudo.py +0 -0
- /sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_fluidstack.py +0 -0
- /sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_gcp.py +0 -0
- /sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_ibm.py +0 -0
- /sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_lambda_cloud.py +0 -0
- /sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_vast.py +0 -0
- /sky/dashboard/out/_next/static/chunks/{843-786c36624d5ff61f.js → 843-a097338acb89b7d7.js} +0 -0
- /sky/dashboard/out/_next/static/chunks/pages/{_app-ad1edd7fe17ea796.js → _app-67925f5e6382e22f.js} +0 -0
- /sky/dashboard/out/_next/static/{dev-ndwjPgd_uQ4dcXXiv → vWwfD3jOky5J5jULHp8JT}/_ssgManifest.js +0 -0
- {skypilot_nightly-1.0.0.dev20250602.dist-info → skypilot_nightly-1.0.0.dev20250604.dist-info}/WHEEL +0 -0
- {skypilot_nightly-1.0.0.dev20250602.dist-info → skypilot_nightly-1.0.0.dev20250604.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20250602.dist-info → skypilot_nightly-1.0.0.dev20250604.dist-info}/licenses/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev20250602.dist-info → skypilot_nightly-1.0.0.dev20250604.dist-info}/top_level.txt +0 -0
sky/server/requests/executor.py
CHANGED
@@ -239,8 +239,11 @@ def override_request_env_and_config(
|
|
239
239
|
client_command=request_body.entrypoint_command,
|
240
240
|
using_remote_api_server=request_body.using_remote_api_server)
|
241
241
|
try:
|
242
|
+
logger.debug(
|
243
|
+
f'override path: {request_body.override_skypilot_config_path}')
|
242
244
|
with skypilot_config.override_skypilot_config(
|
243
|
-
request_body.override_skypilot_config
|
245
|
+
request_body.override_skypilot_config,
|
246
|
+
request_body.override_skypilot_config_path):
|
244
247
|
yield
|
245
248
|
finally:
|
246
249
|
# We need to call the save_timeline() since atexit will not be
|
sky/server/requests/payloads.py
CHANGED
@@ -82,6 +82,17 @@ def get_override_skypilot_config_from_client() -> Dict[str, Any]:
|
|
82
82
|
return config
|
83
83
|
|
84
84
|
|
85
|
+
def get_override_skypilot_config_path_from_client() -> Optional[str]:
|
86
|
+
"""Returns the override config path from the client."""
|
87
|
+
if annotations.is_on_api_server:
|
88
|
+
return None
|
89
|
+
# Currently, we don't need to check if the client-side config
|
90
|
+
# has been overridden because we only deal with cases where
|
91
|
+
# client has a project-level config/changed config and the
|
92
|
+
# api server has a different config.
|
93
|
+
return skypilot_config.loaded_config_path_serialized()
|
94
|
+
|
95
|
+
|
85
96
|
class RequestBody(pydantic.BaseModel):
|
86
97
|
"""The request body for the SkyPilot API."""
|
87
98
|
env_vars: Dict[str, str] = {}
|
@@ -89,6 +100,7 @@ class RequestBody(pydantic.BaseModel):
|
|
89
100
|
entrypoint_command: str = ''
|
90
101
|
using_remote_api_server: bool = False
|
91
102
|
override_skypilot_config: Optional[Dict[str, Any]] = {}
|
103
|
+
override_skypilot_config_path: Optional[str] = None
|
92
104
|
|
93
105
|
# Allow extra fields in the request body, which is useful for backward
|
94
106
|
# compatibility, i.e., we can add new fields to the request body without
|
@@ -108,6 +120,9 @@ class RequestBody(pydantic.BaseModel):
|
|
108
120
|
data['override_skypilot_config'] = data.get(
|
109
121
|
'override_skypilot_config',
|
110
122
|
get_override_skypilot_config_from_client())
|
123
|
+
data['override_skypilot_config_path'] = data.get(
|
124
|
+
'override_skypilot_config_path',
|
125
|
+
get_override_skypilot_config_path_from_client())
|
111
126
|
super().__init__(**data)
|
112
127
|
|
113
128
|
def to_kwargs(self) -> Dict[str, Any]:
|
@@ -122,6 +137,7 @@ class RequestBody(pydantic.BaseModel):
|
|
122
137
|
kwargs.pop('entrypoint_command')
|
123
138
|
kwargs.pop('using_remote_api_server')
|
124
139
|
kwargs.pop('override_skypilot_config')
|
140
|
+
kwargs.pop('override_skypilot_config_path')
|
125
141
|
return kwargs
|
126
142
|
|
127
143
|
@property
|
@@ -6,7 +6,7 @@ from typing import Any, Dict, List, Optional, Tuple
|
|
6
6
|
|
7
7
|
from sky import jobs as managed_jobs
|
8
8
|
from sky import models
|
9
|
-
from sky.
|
9
|
+
from sky.catalog import common
|
10
10
|
from sky.data import storage
|
11
11
|
from sky.provision.kubernetes import utils as kubernetes_utils
|
12
12
|
from sky.serve import serve_state
|
sky/server/server.py
CHANGED
@@ -26,6 +26,7 @@ from fastapi.middleware import cors
|
|
26
26
|
import starlette.middleware.base
|
27
27
|
|
28
28
|
import sky
|
29
|
+
from sky import catalog
|
29
30
|
from sky import check as sky_check
|
30
31
|
from sky import clouds
|
31
32
|
from sky import core
|
@@ -34,7 +35,6 @@ from sky import execution
|
|
34
35
|
from sky import global_user_state
|
35
36
|
from sky import models
|
36
37
|
from sky import sky_logging
|
37
|
-
from sky.clouds import service_catalog
|
38
38
|
from sky.data import storage_utils
|
39
39
|
from sky.jobs.server import server as jobs_rest
|
40
40
|
from sky.provision.kubernetes import utils as kubernetes_utils
|
@@ -389,7 +389,7 @@ async def list_accelerators(
|
|
389
389
|
request_id=request.state.request_id,
|
390
390
|
request_name='list_accelerators',
|
391
391
|
request_body=list_accelerator_counts_body,
|
392
|
-
func=
|
392
|
+
func=catalog.list_accelerators,
|
393
393
|
schedule_type=requests_lib.ScheduleType.SHORT,
|
394
394
|
)
|
395
395
|
|
@@ -404,7 +404,7 @@ async def list_accelerator_counts(
|
|
404
404
|
request_id=request.state.request_id,
|
405
405
|
request_name='list_accelerator_counts',
|
406
406
|
request_body=list_accelerator_counts_body,
|
407
|
-
func=
|
407
|
+
func=catalog.list_accelerator_counts,
|
408
408
|
schedule_type=requests_lib.ScheduleType.SHORT,
|
409
409
|
)
|
410
410
|
|
sky/skypilot_config.py
CHANGED
@@ -55,7 +55,7 @@ import os
|
|
55
55
|
import tempfile
|
56
56
|
import threading
|
57
57
|
import typing
|
58
|
-
from typing import Any, Dict, Iterator, List, Optional, Tuple
|
58
|
+
from typing import Any, Dict, Iterator, List, Optional, Tuple, Union
|
59
59
|
|
60
60
|
import filelock
|
61
61
|
|
@@ -163,11 +163,23 @@ def _set_loaded_config(config: config_utils.Config) -> None:
|
|
163
163
|
_get_config_context().config = config
|
164
164
|
|
165
165
|
|
166
|
-
def _get_loaded_config_path() -> Optional[str]:
|
167
|
-
|
166
|
+
def _get_loaded_config_path() -> List[Optional[str]]:
|
167
|
+
serialized = _get_config_context().config_path
|
168
|
+
if not serialized:
|
169
|
+
return []
|
170
|
+
return json.loads(serialized)
|
171
|
+
|
172
|
+
|
173
|
+
def _set_loaded_config_path(
|
174
|
+
path: Optional[Union[str, List[Optional[str]]]]) -> None:
|
175
|
+
if not path:
|
176
|
+
_get_config_context().config_path = None
|
177
|
+
if isinstance(path, str):
|
178
|
+
path = [path]
|
179
|
+
_get_config_context().config_path = json.dumps(path)
|
168
180
|
|
169
181
|
|
170
|
-
def
|
182
|
+
def _set_loaded_config_path_serialized(path: Optional[str]) -> None:
|
171
183
|
_get_config_context().config_path = path
|
172
184
|
|
173
185
|
|
@@ -184,9 +196,14 @@ def get_user_config_path() -> str:
|
|
184
196
|
return _GLOBAL_CONFIG_PATH
|
185
197
|
|
186
198
|
|
187
|
-
def
|
188
|
-
|
189
|
-
|
199
|
+
def _get_config_from_path(path: Optional[str]) -> config_utils.Config:
|
200
|
+
if path is None:
|
201
|
+
return config_utils.Config()
|
202
|
+
return parse_and_validate_config_file(path)
|
203
|
+
|
204
|
+
|
205
|
+
def _resolve_user_config_path() -> Optional[str]:
|
206
|
+
# find the user config file path, None if not resolved.
|
190
207
|
user_config_path = _get_config_file_path(ENV_VAR_GLOBAL_CONFIG)
|
191
208
|
if user_config_path:
|
192
209
|
logger.debug('using user config file specified by '
|
@@ -203,16 +220,17 @@ def get_user_config() -> config_utils.Config:
|
|
203
220
|
user_config_path = get_user_config_path()
|
204
221
|
logger.debug(f'using default user config file: {user_config_path}')
|
205
222
|
user_config_path = os.path.expanduser(user_config_path)
|
206
|
-
|
207
|
-
# load the user config file
|
208
223
|
if os.path.exists(user_config_path):
|
209
|
-
|
210
|
-
|
211
|
-
user_config = config_utils.Config()
|
212
|
-
return user_config
|
224
|
+
return user_config_path
|
225
|
+
return None
|
213
226
|
|
214
227
|
|
215
|
-
def
|
228
|
+
def get_user_config() -> config_utils.Config:
|
229
|
+
"""Returns the user config."""
|
230
|
+
return _get_config_from_path(_resolve_user_config_path())
|
231
|
+
|
232
|
+
|
233
|
+
def _resolve_project_config_path() -> Optional[str]:
|
216
234
|
# find the project config file
|
217
235
|
project_config_path = _get_config_file_path(ENV_VAR_PROJECT_CONFIG)
|
218
236
|
if project_config_path:
|
@@ -231,17 +249,17 @@ def _get_project_config() -> config_utils.Config:
|
|
231
249
|
f'using default project config file: {_PROJECT_CONFIG_PATH}')
|
232
250
|
project_config_path = _PROJECT_CONFIG_PATH
|
233
251
|
project_config_path = os.path.expanduser(project_config_path)
|
234
|
-
|
235
|
-
# load the project config file
|
236
252
|
if os.path.exists(project_config_path):
|
237
|
-
|
238
|
-
|
239
|
-
project_config = config_utils.Config()
|
240
|
-
return project_config
|
253
|
+
return project_config_path
|
254
|
+
return None
|
241
255
|
|
242
256
|
|
243
|
-
def
|
244
|
-
"""Returns the
|
257
|
+
def _get_project_config() -> config_utils.Config:
|
258
|
+
"""Returns the project config."""
|
259
|
+
return _get_config_from_path(_resolve_project_config_path())
|
260
|
+
|
261
|
+
|
262
|
+
def _resolve_server_config_path() -> Optional[str]:
|
245
263
|
# find the server config file
|
246
264
|
server_config_path = _get_config_file_path(ENV_VAR_GLOBAL_CONFIG)
|
247
265
|
if server_config_path:
|
@@ -259,13 +277,14 @@ def get_server_config() -> config_utils.Config:
|
|
259
277
|
server_config_path = _GLOBAL_CONFIG_PATH
|
260
278
|
logger.debug(f'using default server config file: {server_config_path}')
|
261
279
|
server_config_path = os.path.expanduser(server_config_path)
|
262
|
-
|
263
|
-
# load the server config file
|
264
280
|
if os.path.exists(server_config_path):
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
281
|
+
return server_config_path
|
282
|
+
return None
|
283
|
+
|
284
|
+
|
285
|
+
def get_server_config() -> config_utils.Config:
|
286
|
+
"""Returns the server config."""
|
287
|
+
return _get_config_from_path(_resolve_server_config_path())
|
269
288
|
|
270
289
|
|
271
290
|
def get_nested(keys: Tuple[str, ...],
|
@@ -487,9 +506,11 @@ def _reload_config_from_internal_file(internal_config_path: str) -> None:
|
|
487
506
|
def _reload_config_as_server() -> None:
|
488
507
|
# Reset the global variables, to avoid using stale values.
|
489
508
|
_set_loaded_config(config_utils.Config())
|
509
|
+
_set_loaded_config_path(None)
|
490
510
|
|
491
511
|
overrides: List[config_utils.Config] = []
|
492
|
-
|
512
|
+
server_config_path = _resolve_server_config_path()
|
513
|
+
server_config = _get_config_from_path(server_config_path)
|
493
514
|
if server_config:
|
494
515
|
overrides.append(server_config)
|
495
516
|
|
@@ -503,17 +524,21 @@ def _reload_config_as_server() -> None:
|
|
503
524
|
f'server config: \n'
|
504
525
|
f'{common_utils.dump_yaml_str(dict(overlaid_server_config))}')
|
505
526
|
_set_loaded_config(overlaid_server_config)
|
527
|
+
_set_loaded_config_path(server_config_path)
|
506
528
|
|
507
529
|
|
508
530
|
def _reload_config_as_client() -> None:
|
509
531
|
# Reset the global variables, to avoid using stale values.
|
510
532
|
_set_loaded_config(config_utils.Config())
|
533
|
+
_set_loaded_config_path(None)
|
511
534
|
|
512
535
|
overrides: List[config_utils.Config] = []
|
513
|
-
|
536
|
+
user_config_path = _resolve_user_config_path()
|
537
|
+
user_config = _get_config_from_path(user_config_path)
|
514
538
|
if user_config:
|
515
539
|
overrides.append(user_config)
|
516
|
-
|
540
|
+
project_config_path = _resolve_project_config_path()
|
541
|
+
project_config = _get_config_from_path(project_config_path)
|
517
542
|
if project_config:
|
518
543
|
overrides.append(project_config)
|
519
544
|
|
@@ -527,14 +552,26 @@ def _reload_config_as_client() -> None:
|
|
527
552
|
f'client config (before task and CLI overrides): \n'
|
528
553
|
f'{common_utils.dump_yaml_str(dict(overlaid_client_config))}')
|
529
554
|
_set_loaded_config(overlaid_client_config)
|
555
|
+
_set_loaded_config_path([user_config_path, project_config_path])
|
530
556
|
|
531
557
|
|
532
558
|
def loaded_config_path() -> Optional[str]:
|
533
|
-
"""Returns the path to the loaded config file, or
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
559
|
+
"""Returns the path to the loaded config file, or '<overridden>' if the
|
560
|
+
config is overridden."""
|
561
|
+
path = [p for p in set(_get_loaded_config_path()) if p is not None]
|
562
|
+
if len(path) == 0:
|
563
|
+
return '<overridden>' if _is_config_overridden() else None
|
564
|
+
if len(path) == 1:
|
565
|
+
return path[0]
|
566
|
+
|
567
|
+
header = 'overridden' if _is_config_overridden() else 'merged'
|
568
|
+
path_str = ', '.join(p for p in path if p is not None)
|
569
|
+
return f'<{header} ({path_str})>'
|
570
|
+
|
571
|
+
|
572
|
+
def loaded_config_path_serialized() -> Optional[str]:
|
573
|
+
"""Returns the json serialized config path list"""
|
574
|
+
return _get_config_context().config_path
|
538
575
|
|
539
576
|
|
540
577
|
# Load on import, synchronization is guaranteed by python interpreter.
|
@@ -548,7 +585,9 @@ def loaded() -> bool:
|
|
548
585
|
|
549
586
|
@contextlib.contextmanager
|
550
587
|
def override_skypilot_config(
|
551
|
-
override_configs: Optional[Dict[str, Any]]
|
588
|
+
override_configs: Optional[Dict[str, Any]],
|
589
|
+
override_config_path_serialized: Optional[str] = None
|
590
|
+
) -> Iterator[None]:
|
552
591
|
"""Overrides the user configurations."""
|
553
592
|
# TODO(SKY-1215): allow admin user to extend the disallowed keys or specify
|
554
593
|
# allowed keys.
|
@@ -557,7 +596,13 @@ def override_skypilot_config(
|
|
557
596
|
yield
|
558
597
|
return
|
559
598
|
original_config = _get_loaded_config()
|
599
|
+
original_config_path = loaded_config_path_serialized()
|
560
600
|
override_configs = config_utils.Config(override_configs)
|
601
|
+
if override_config_path_serialized is None:
|
602
|
+
override_config_path = []
|
603
|
+
else:
|
604
|
+
override_config_path = json.loads(override_config_path_serialized)
|
605
|
+
|
561
606
|
disallowed_diff_keys = []
|
562
607
|
for key in constants.SKIPPED_CLIENT_OVERRIDE_KEYS:
|
563
608
|
value = override_configs.pop_nested(key, default_value=None)
|
@@ -602,6 +647,8 @@ def override_skypilot_config(
|
|
602
647
|
skip_none=False)
|
603
648
|
_set_config_overridden(True)
|
604
649
|
_set_loaded_config(config)
|
650
|
+
_set_loaded_config_path(_get_loaded_config_path() +
|
651
|
+
override_config_path)
|
605
652
|
yield
|
606
653
|
except exceptions.InvalidSkyPilotConfigError as e:
|
607
654
|
with ux_utils.print_exception_no_traceback():
|
@@ -616,6 +663,7 @@ def override_skypilot_config(
|
|
616
663
|
finally:
|
617
664
|
_set_loaded_config(original_config)
|
618
665
|
_set_config_overridden(False)
|
666
|
+
_set_loaded_config_path_serialized(original_config_path)
|
619
667
|
|
620
668
|
|
621
669
|
@contextlib.contextmanager
|
@@ -628,6 +676,7 @@ def replace_skypilot_config(new_configs: config_utils.Config) -> Iterator[None]:
|
|
628
676
|
sky_utils.context for more details.
|
629
677
|
"""
|
630
678
|
original_config = _get_loaded_config()
|
679
|
+
original_config_path = loaded_config_path_serialized()
|
631
680
|
original_env_var = os.environ.get(ENV_VAR_SKYPILOT_CONFIG)
|
632
681
|
if new_configs != original_config:
|
633
682
|
# Modify the global config of current process or context
|
@@ -642,9 +691,11 @@ def replace_skypilot_config(new_configs: config_utils.Config) -> Iterator[None]:
|
|
642
691
|
# Note that this code modifies os.environ directly because it
|
643
692
|
# will be hijacked to be context-aware if a context is active.
|
644
693
|
os.environ[ENV_VAR_SKYPILOT_CONFIG] = temp_file.name
|
694
|
+
_set_loaded_config_path(temp_file.name)
|
645
695
|
yield
|
646
696
|
# Restore the original config and env var.
|
647
697
|
_set_loaded_config(original_config)
|
698
|
+
_set_loaded_config_path_serialized(original_config_path)
|
648
699
|
if original_env_var:
|
649
700
|
os.environ[ENV_VAR_SKYPILOT_CONFIG] = original_env_var
|
650
701
|
else:
|
sky/usage/usage_lib.py
CHANGED
@@ -205,8 +205,8 @@ class UsageMessageToReport(MessageToReport):
|
|
205
205
|
logger.debug('Multiple accelerators are not supported: '
|
206
206
|
f'{resources.accelerators}.')
|
207
207
|
self.task_accelerators = list(resources.accelerators.keys())[0]
|
208
|
-
self.task_num_accelerators =
|
209
|
-
self.task_accelerators]
|
208
|
+
self.task_num_accelerators = int(
|
209
|
+
resources.accelerators[self.task_accelerators])
|
210
210
|
else:
|
211
211
|
self.task_accelerators = None
|
212
212
|
self.task_num_accelerators = None
|
@@ -245,7 +245,8 @@ class UsageMessageToReport(MessageToReport):
|
|
245
245
|
logger.debug('Multiple accelerators are not supported: '
|
246
246
|
f'{resources.accelerators}.')
|
247
247
|
self.accelerators = list(resources.accelerators.keys())[0]
|
248
|
-
self.num_accelerators =
|
248
|
+
self.num_accelerators = int(
|
249
|
+
resources.accelerators[self.accelerators])
|
249
250
|
else:
|
250
251
|
self.accelerators = None
|
251
252
|
self.num_accelerators = None
|
@@ -2,7 +2,7 @@
|
|
2
2
|
import typing
|
3
3
|
from typing import Optional
|
4
4
|
|
5
|
-
from sky
|
5
|
+
from sky import catalog
|
6
6
|
from sky.utils import rich_utils
|
7
7
|
from sky.utils import ux_utils
|
8
8
|
|
@@ -34,7 +34,7 @@ if typing.TYPE_CHECKING:
|
|
34
34
|
|
35
35
|
# Use a cached version of accelerators to cloud mapping, so that we don't have
|
36
36
|
# to download and read the catalog file for every cloud locally.
|
37
|
-
_accelerator_df =
|
37
|
+
_accelerator_df = catalog.common.read_catalog('common/accelerators.csv')
|
38
38
|
|
39
39
|
# List of non-GPU accelerators that are supported by our backend for job queue
|
40
40
|
# scheduling.
|
@@ -80,7 +80,7 @@ def canonicalize_accelerator_name(accelerator: str,
|
|
80
80
|
if not names and cloud_str in ['Kubernetes', None]:
|
81
81
|
with rich_utils.safe_status(
|
82
82
|
ux_utils.spinner_message('Listing accelerators on Kubernetes')):
|
83
|
-
searched =
|
83
|
+
searched = catalog.list_accelerators(
|
84
84
|
name_filter=accelerator,
|
85
85
|
case_sensitive=False,
|
86
86
|
clouds=cloud_str,
|
sky/utils/controller_utils.py
CHANGED
@@ -206,8 +206,7 @@ class Controllers(enum.Enum):
|
|
206
206
|
return None
|
207
207
|
|
208
208
|
|
209
|
-
def high_availability_specified(cluster_name: Optional[str]
|
210
|
-
skip_warning: bool = True) -> bool:
|
209
|
+
def high_availability_specified(cluster_name: Optional[str]) -> bool:
|
211
210
|
"""Check if the controller high availability is specified in user config.
|
212
211
|
"""
|
213
212
|
controller = Controllers.from_name(cluster_name)
|
@@ -215,18 +214,9 @@ def high_availability_specified(cluster_name: Optional[str],
|
|
215
214
|
return False
|
216
215
|
|
217
216
|
if skypilot_config.loaded():
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
if high_availability:
|
222
|
-
if controller.value.controller_type != 'serve':
|
223
|
-
if not skip_warning:
|
224
|
-
print(f'{colorama.Fore.RED}High availability controller is'
|
225
|
-
'only supported for SkyServe controller. It cannot'
|
226
|
-
f'be enabled for {controller.value.name}.'
|
227
|
-
f'Skipping this flag.{colorama.Style.RESET_ALL}')
|
228
|
-
else:
|
229
|
-
return True
|
217
|
+
return skypilot_config.get_nested((controller.value.controller_type,
|
218
|
+
'controller', 'high_availability'),
|
219
|
+
False)
|
230
220
|
return False
|
231
221
|
|
232
222
|
|
@@ -7,6 +7,7 @@ import os
|
|
7
7
|
import random
|
8
8
|
import re
|
9
9
|
import shlex
|
10
|
+
import shutil
|
10
11
|
import subprocess
|
11
12
|
import sys
|
12
13
|
import tempfile
|
@@ -1356,7 +1357,7 @@ def deploy_cluster(head_node,
|
|
1356
1357
|
merged_file.write(result)
|
1357
1358
|
|
1358
1359
|
# Replace the kubeconfig with the merged config
|
1359
|
-
|
1360
|
+
shutil.move(merged_config, kubeconfig_path)
|
1360
1361
|
|
1361
1362
|
# Set the new context as the current context
|
1362
1363
|
run_command(['kubectl', 'config', 'use-context', context_name],
|
sky/utils/schemas.py
CHANGED
@@ -6,6 +6,7 @@ https://json-schema.org/
|
|
6
6
|
import enum
|
7
7
|
from typing import Any, Dict, List, Tuple
|
8
8
|
|
9
|
+
from sky.catalog import constants as service_catalog_constants
|
9
10
|
from sky.skylet import constants
|
10
11
|
|
11
12
|
|
@@ -66,14 +67,10 @@ _AUTOSTOP_SCHEMA = {
|
|
66
67
|
|
67
68
|
def _get_single_resources_schema():
|
68
69
|
"""Schema for a single resource in a resources list."""
|
69
|
-
# To avoid circular imports, only import when needed.
|
70
|
-
# pylint: disable=import-outside-toplevel
|
71
|
-
from sky.clouds import service_catalog
|
72
|
-
|
73
70
|
# Building the regex pattern for the infra field
|
74
71
|
# Format: cloud[/region[/zone]] or wildcards or kubernetes context
|
75
72
|
# Match any cloud name (case insensitive)
|
76
|
-
all_clouds = list(
|
73
|
+
all_clouds = list(service_catalog_constants.ALL_CLOUDS)
|
77
74
|
all_clouds.remove('kubernetes')
|
78
75
|
cloud_pattern = f'(?i:({"|".join(all_clouds)}))'
|
79
76
|
|
@@ -110,7 +107,8 @@ def _get_single_resources_schema():
|
|
110
107
|
'properties': {
|
111
108
|
'cloud': {
|
112
109
|
'type': 'string',
|
113
|
-
'case_insensitive_enum': list(
|
110
|
+
'case_insensitive_enum': list(
|
111
|
+
service_catalog_constants.ALL_CLOUDS)
|
114
112
|
},
|
115
113
|
'region': {
|
116
114
|
'type': 'string',
|
@@ -856,7 +854,6 @@ _REMOTE_IDENTITY_SCHEMA_KUBERNETES = {
|
|
856
854
|
|
857
855
|
def get_config_schema():
|
858
856
|
# pylint: disable=import-outside-toplevel
|
859
|
-
from sky.clouds import service_catalog
|
860
857
|
from sky.utils import kubernetes_enums
|
861
858
|
|
862
859
|
resources_schema = {
|
@@ -1165,7 +1162,7 @@ def get_config_schema():
|
|
1165
1162
|
'items': {
|
1166
1163
|
'type': 'string',
|
1167
1164
|
'case_insensitive_enum':
|
1168
|
-
(list(
|
1165
|
+
(list(service_catalog_constants.ALL_CLOUDS) + ['cloudflare'])
|
1169
1166
|
}
|
1170
1167
|
}
|
1171
1168
|
|
@@ -1213,7 +1210,7 @@ def get_config_schema():
|
|
1213
1210
|
workspace_schema = {'type': 'string'}
|
1214
1211
|
|
1215
1212
|
allowed_workspace_cloud_names = list(
|
1216
|
-
|
1213
|
+
service_catalog_constants.ALL_CLOUDS) + ['cloudflare']
|
1217
1214
|
# Create pattern for not supported clouds, i.e.
|
1218
1215
|
# all clouds except gcp, kubernetes, ssh
|
1219
1216
|
not_supported_clouds = [
|