skypilot-nightly 1.0.0.dev20250612__py3-none-any.whl → 1.0.0.dev20250614__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 +4 -2
- sky/adaptors/hyperbolic.py +8 -0
- sky/adaptors/kubernetes.py +3 -2
- sky/authentication.py +20 -2
- sky/backends/backend_utils.py +11 -3
- sky/backends/cloud_vm_ray_backend.py +2 -1
- sky/benchmark/benchmark_state.py +2 -1
- sky/catalog/data_fetchers/fetch_aws.py +1 -1
- sky/catalog/data_fetchers/fetch_hyperbolic.py +136 -0
- sky/catalog/data_fetchers/fetch_vast.py +1 -1
- sky/catalog/hyperbolic_catalog.py +133 -0
- sky/check.py +2 -1
- sky/cli.py +1 -1
- sky/client/cli.py +1 -1
- sky/clouds/__init__.py +2 -0
- sky/clouds/cloud.py +1 -1
- sky/clouds/gcp.py +1 -1
- sky/clouds/hyperbolic.py +276 -0
- sky/clouds/kubernetes.py +8 -2
- sky/clouds/ssh.py +7 -3
- sky/dashboard/out/404.html +1 -1
- sky/dashboard/out/_next/static/chunks/37-7754056a4b503e1d.js +6 -0
- sky/dashboard/out/_next/static/chunks/600.bd2ed8c076b720ec.js +16 -0
- sky/dashboard/out/_next/static/chunks/{856-0776dc6ed6000c39.js → 856-c2c39c0912285e54.js} +1 -1
- sky/dashboard/out/_next/static/chunks/938-245c9ac4c9e8bf15.js +1 -0
- sky/dashboard/out/_next/static/chunks/{webpack-208a9812ab4f61c9.js → webpack-27de3d9d450d81c6.js} +1 -1
- sky/dashboard/out/_next/static/css/{5d71bfc09f184bab.css → 6f84444b8f3c656c.css} +1 -1
- sky/dashboard/out/_next/static/{G3DXdMFu2Jzd-Dody9iq1 → nm5jrKpUZh2W0SxzyDKhz}/_buildManifest.js +1 -1
- sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
- sky/dashboard/out/clusters/[cluster].html +1 -1
- sky/dashboard/out/clusters.html +1 -1
- sky/dashboard/out/config.html +1 -1
- sky/dashboard/out/index.html +1 -1
- sky/dashboard/out/infra/[context].html +1 -1
- sky/dashboard/out/infra.html +1 -1
- sky/dashboard/out/jobs/[job].html +1 -1
- sky/dashboard/out/jobs.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.py +2 -2
- sky/jobs/state.py +43 -44
- sky/provision/__init__.py +1 -0
- sky/provision/common.py +1 -1
- sky/provision/gcp/config.py +1 -1
- sky/provision/hyperbolic/__init__.py +11 -0
- sky/provision/hyperbolic/config.py +10 -0
- sky/provision/hyperbolic/instance.py +423 -0
- sky/provision/hyperbolic/utils.py +373 -0
- sky/provision/kubernetes/instance.py +2 -1
- sky/provision/kubernetes/utils.py +60 -13
- sky/resources.py +2 -2
- sky/serve/serve_state.py +81 -15
- sky/server/requests/preconditions.py +1 -1
- sky/server/requests/requests.py +11 -6
- sky/setup_files/dependencies.py +2 -1
- sky/skylet/configs.py +26 -19
- sky/skylet/constants.py +1 -1
- sky/skylet/job_lib.py +3 -5
- sky/task.py +1 -1
- sky/templates/hyperbolic-ray.yml.j2 +67 -0
- sky/templates/kubernetes-ray.yml.j2 +1 -1
- sky/users/permission.py +2 -0
- sky/utils/common_utils.py +6 -0
- sky/utils/context.py +1 -1
- sky/utils/infra_utils.py +1 -1
- sky/utils/kubernetes/generate_kubeconfig.sh +1 -1
- {skypilot_nightly-1.0.0.dev20250612.dist-info → skypilot_nightly-1.0.0.dev20250614.dist-info}/METADATA +2 -1
- {skypilot_nightly-1.0.0.dev20250612.dist-info → skypilot_nightly-1.0.0.dev20250614.dist-info}/RECORD +79 -70
- sky/dashboard/out/_next/static/chunks/37-d8aebf1683522a0b.js +0 -6
- sky/dashboard/out/_next/static/chunks/600.15a0009177e86b86.js +0 -16
- sky/dashboard/out/_next/static/chunks/938-ab185187a63f9cdb.js +0 -1
- /sky/dashboard/out/_next/static/chunks/{843-6fcc4bf91ac45b39.js → 843-5011affc9540757f.js} +0 -0
- /sky/dashboard/out/_next/static/chunks/pages/{_app-7bbd9d39d6f9a98a.js → _app-664031f6ae737f80.js} +0 -0
- /sky/dashboard/out/_next/static/chunks/pages/clusters/{[cluster]-451a14e7e755ebbc.js → [cluster]-20210f8cd809063d.js} +0 -0
- /sky/dashboard/out/_next/static/chunks/pages/{jobs-fe233baf3d073491.js → jobs-ae7a5e9fa5a5b5f0.js} +0 -0
- /sky/dashboard/out/_next/static/{G3DXdMFu2Jzd-Dody9iq1 → nm5jrKpUZh2W0SxzyDKhz}/_ssgManifest.js +0 -0
- {skypilot_nightly-1.0.0.dev20250612.dist-info → skypilot_nightly-1.0.0.dev20250614.dist-info}/WHEEL +0 -0
- {skypilot_nightly-1.0.0.dev20250612.dist-info → skypilot_nightly-1.0.0.dev20250614.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20250612.dist-info → skypilot_nightly-1.0.0.dev20250614.dist-info}/licenses/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev20250612.dist-info → skypilot_nightly-1.0.0.dev20250614.dist-info}/top_level.txt +0 -0
sky/jobs/state.py
CHANGED
@@ -161,8 +161,8 @@ def create_table(cursor, conn):
|
|
161
161
|
conn.commit()
|
162
162
|
|
163
163
|
|
164
|
-
# Module-level connection/cursor; thread-safe as the
|
165
|
-
#
|
164
|
+
# Module-level connection/cursor; thread-safe as the db is initialized once
|
165
|
+
# across all threads.
|
166
166
|
def _get_db_path() -> str:
|
167
167
|
"""Workaround to collapse multi-step Path ops for type checker.
|
168
168
|
Ensures _DB_PATH is str, avoiding Union[Path, str] inference.
|
@@ -173,8 +173,7 @@ def _get_db_path() -> str:
|
|
173
173
|
return str(path)
|
174
174
|
|
175
175
|
|
176
|
-
_DB_PATH =
|
177
|
-
_db_initialized = False
|
176
|
+
_DB_PATH = None
|
178
177
|
_db_init_lock = threading.Lock()
|
179
178
|
|
180
179
|
|
@@ -183,13 +182,13 @@ def _init_db(func):
|
|
183
182
|
|
184
183
|
@functools.wraps(func)
|
185
184
|
def wrapper(*args, **kwargs):
|
186
|
-
global
|
187
|
-
if
|
185
|
+
global _DB_PATH
|
186
|
+
if _DB_PATH is not None:
|
188
187
|
return func(*args, **kwargs)
|
189
188
|
with _db_init_lock:
|
190
|
-
if
|
189
|
+
if _DB_PATH is None:
|
190
|
+
_DB_PATH = _get_db_path()
|
191
191
|
db_utils.SQLiteConn(_DB_PATH, create_table)
|
192
|
-
_db_initialized = True
|
193
192
|
return func(*args, **kwargs)
|
194
193
|
|
195
194
|
return wrapper
|
@@ -442,7 +441,7 @@ class ManagedJobScheduleState(enum.Enum):
|
|
442
441
|
# === Status transition functions ===
|
443
442
|
@_init_db
|
444
443
|
def set_job_info(job_id: int, name: str, workspace: str, entrypoint: str):
|
445
|
-
assert
|
444
|
+
assert _DB_PATH is not None
|
446
445
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
447
446
|
cursor.execute(
|
448
447
|
"""\
|
@@ -456,7 +455,7 @@ def set_job_info(job_id: int, name: str, workspace: str, entrypoint: str):
|
|
456
455
|
@_init_db
|
457
456
|
def set_pending(job_id: int, task_id: int, task_name: str, resources_str: str):
|
458
457
|
"""Set the task to pending state."""
|
459
|
-
assert
|
458
|
+
assert _DB_PATH is not None
|
460
459
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
461
460
|
cursor.execute(
|
462
461
|
"""\
|
@@ -484,7 +483,7 @@ def set_starting(job_id: int, task_id: int, run_timestamp: str,
|
|
484
483
|
specs: The specs of the managed task.
|
485
484
|
callback_func: The callback function.
|
486
485
|
"""
|
487
|
-
assert
|
486
|
+
assert _DB_PATH is not None
|
488
487
|
# Use the timestamp in the `run_timestamp` ('sky-2022-10...'), to make
|
489
488
|
# the log directory and submission time align with each other, so as to
|
490
489
|
# make it easier to find them based on one of the values.
|
@@ -524,7 +523,7 @@ def set_backoff_pending(job_id: int, task_id: int):
|
|
524
523
|
This should only be used to transition from STARTING or RECOVERING back to
|
525
524
|
PENDING.
|
526
525
|
"""
|
527
|
-
assert
|
526
|
+
assert _DB_PATH is not None
|
528
527
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
529
528
|
cursor.execute(
|
530
529
|
"""\
|
@@ -552,7 +551,7 @@ def set_restarting(job_id: int, task_id: int, recovering: bool):
|
|
552
551
|
after using set_backoff_pending to transition back to PENDING during
|
553
552
|
launch retry backoff.
|
554
553
|
"""
|
555
|
-
assert
|
554
|
+
assert _DB_PATH is not None
|
556
555
|
target_status = ManagedJobStatus.STARTING.value
|
557
556
|
if recovering:
|
558
557
|
target_status = ManagedJobStatus.RECOVERING.value
|
@@ -578,7 +577,7 @@ def set_restarting(job_id: int, task_id: int, recovering: bool):
|
|
578
577
|
def set_started(job_id: int, task_id: int, start_time: float,
|
579
578
|
callback_func: CallbackType):
|
580
579
|
"""Set the task to started state."""
|
581
|
-
assert
|
580
|
+
assert _DB_PATH is not None
|
582
581
|
logger.info('Job started.')
|
583
582
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
584
583
|
cursor.execute(
|
@@ -610,7 +609,7 @@ def set_started(job_id: int, task_id: int, start_time: float,
|
|
610
609
|
@_init_db
|
611
610
|
def set_recovering(job_id: int, task_id: int, callback_func: CallbackType):
|
612
611
|
"""Set the task to recovering state, and update the job duration."""
|
613
|
-
assert
|
612
|
+
assert _DB_PATH is not None
|
614
613
|
logger.info('=== Recovering... ===')
|
615
614
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
616
615
|
cursor.execute(
|
@@ -634,7 +633,7 @@ def set_recovering(job_id: int, task_id: int, callback_func: CallbackType):
|
|
634
633
|
def set_recovered(job_id: int, task_id: int, recovered_time: float,
|
635
634
|
callback_func: CallbackType):
|
636
635
|
"""Set the task to recovered."""
|
637
|
-
assert
|
636
|
+
assert _DB_PATH is not None
|
638
637
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
639
638
|
cursor.execute(
|
640
639
|
"""\
|
@@ -658,7 +657,7 @@ def set_recovered(job_id: int, task_id: int, recovered_time: float,
|
|
658
657
|
def set_succeeded(job_id: int, task_id: int, end_time: float,
|
659
658
|
callback_func: CallbackType):
|
660
659
|
"""Set the task to succeeded, if it is in a non-terminal state."""
|
661
|
-
assert
|
660
|
+
assert _DB_PATH is not None
|
662
661
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
663
662
|
cursor.execute(
|
664
663
|
"""\
|
@@ -703,7 +702,7 @@ def set_failed(
|
|
703
702
|
override_terminal: If True, override the current status even if end_at
|
704
703
|
is already set.
|
705
704
|
"""
|
706
|
-
assert
|
705
|
+
assert _DB_PATH is not None
|
707
706
|
assert failure_type.is_failed(), failure_type
|
708
707
|
end_time = time.time() if end_time is None else end_time
|
709
708
|
|
@@ -761,7 +760,7 @@ def set_cancelling(job_id: int, callback_func: CallbackType):
|
|
761
760
|
task_id is not needed, because we expect the job should be cancelled
|
762
761
|
as a whole, and we should not cancel a single task.
|
763
762
|
"""
|
764
|
-
assert
|
763
|
+
assert _DB_PATH is not None
|
765
764
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
766
765
|
rows = cursor.execute(
|
767
766
|
"""\
|
@@ -783,7 +782,7 @@ def set_cancelled(job_id: int, callback_func: CallbackType):
|
|
783
782
|
|
784
783
|
The set_cancelling should be called before this function.
|
785
784
|
"""
|
786
|
-
assert
|
785
|
+
assert _DB_PATH is not None
|
787
786
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
788
787
|
rows = cursor.execute(
|
789
788
|
"""\
|
@@ -804,7 +803,7 @@ def set_cancelled(job_id: int, callback_func: CallbackType):
|
|
804
803
|
def set_local_log_file(job_id: int, task_id: Optional[int],
|
805
804
|
local_log_file: str):
|
806
805
|
"""Set the local log file for a job."""
|
807
|
-
assert
|
806
|
+
assert _DB_PATH is not None
|
808
807
|
filter_str = 'spot_job_id=(?)'
|
809
808
|
filter_args = [local_log_file, job_id]
|
810
809
|
|
@@ -822,7 +821,7 @@ def set_local_log_file(job_id: int, task_id: Optional[int],
|
|
822
821
|
def get_nonterminal_job_ids_by_name(name: Optional[str],
|
823
822
|
all_users: bool = False) -> List[int]:
|
824
823
|
"""Get non-terminal job ids by name."""
|
825
|
-
assert
|
824
|
+
assert _DB_PATH is not None
|
826
825
|
statuses = ', '.join(['?'] * len(ManagedJobStatus.terminal_statuses()))
|
827
826
|
field_values = [
|
828
827
|
status.value for status in ManagedJobStatus.terminal_statuses()
|
@@ -866,7 +865,7 @@ def get_schedule_live_jobs(job_id: Optional[int]) -> List[Dict[str, Any]]:
|
|
866
865
|
exception: the job may have just transitioned from WAITING to LAUNCHING, but
|
867
866
|
the controller process has not yet started.
|
868
867
|
"""
|
869
|
-
assert
|
868
|
+
assert _DB_PATH is not None
|
870
869
|
job_filter = '' if job_id is None else 'AND spot_job_id=(?)'
|
871
870
|
job_value = (job_id,) if job_id is not None else ()
|
872
871
|
|
@@ -909,7 +908,7 @@ def get_jobs_to_check_status(job_id: Optional[int] = None) -> List[int]:
|
|
909
908
|
- Jobs have schedule_state DONE but are in a non-terminal status
|
910
909
|
- Legacy jobs (that is, no schedule state) that are in non-terminal status
|
911
910
|
"""
|
912
|
-
assert
|
911
|
+
assert _DB_PATH is not None
|
913
912
|
job_filter = '' if job_id is None else 'AND spot.spot_job_id=(?)'
|
914
913
|
job_value = () if job_id is None else (job_id,)
|
915
914
|
|
@@ -958,7 +957,7 @@ def get_jobs_to_check_status(job_id: Optional[int] = None) -> List[int]:
|
|
958
957
|
@_init_db
|
959
958
|
def get_all_job_ids_by_name(name: Optional[str]) -> List[int]:
|
960
959
|
"""Get all job ids by name."""
|
961
|
-
assert
|
960
|
+
assert _DB_PATH is not None
|
962
961
|
name_filter = ''
|
963
962
|
field_values = []
|
964
963
|
if name is not None:
|
@@ -987,7 +986,7 @@ def get_all_job_ids_by_name(name: Optional[str]) -> List[int]:
|
|
987
986
|
@_init_db
|
988
987
|
def _get_all_task_ids_statuses(
|
989
988
|
job_id: int) -> List[Tuple[int, ManagedJobStatus]]:
|
990
|
-
assert
|
989
|
+
assert _DB_PATH is not None
|
991
990
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
992
991
|
id_statuses = cursor.execute(
|
993
992
|
"""\
|
@@ -1035,7 +1034,7 @@ def get_failure_reason(job_id: int) -> Optional[str]:
|
|
1035
1034
|
|
1036
1035
|
If the job has multiple tasks, we return the first failure reason.
|
1037
1036
|
"""
|
1038
|
-
assert
|
1037
|
+
assert _DB_PATH is not None
|
1039
1038
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
1040
1039
|
reason = cursor.execute(
|
1041
1040
|
"""\
|
@@ -1051,7 +1050,7 @@ def get_failure_reason(job_id: int) -> Optional[str]:
|
|
1051
1050
|
@_init_db
|
1052
1051
|
def get_managed_jobs(job_id: Optional[int] = None) -> List[Dict[str, Any]]:
|
1053
1052
|
"""Get managed jobs from the database."""
|
1054
|
-
assert
|
1053
|
+
assert _DB_PATH is not None
|
1055
1054
|
job_filter = '' if job_id is None else f'WHERE spot.spot_job_id={job_id}'
|
1056
1055
|
|
1057
1056
|
# Join spot and job_info tables to get the job name for each task.
|
@@ -1097,7 +1096,7 @@ def get_managed_jobs(job_id: Optional[int] = None) -> List[Dict[str, Any]]:
|
|
1097
1096
|
@_init_db
|
1098
1097
|
def get_task_name(job_id: int, task_id: int) -> str:
|
1099
1098
|
"""Get the task name of a job."""
|
1100
|
-
assert
|
1099
|
+
assert _DB_PATH is not None
|
1101
1100
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
1102
1101
|
task_name = cursor.execute(
|
1103
1102
|
"""\
|
@@ -1110,7 +1109,7 @@ def get_task_name(job_id: int, task_id: int) -> str:
|
|
1110
1109
|
@_init_db
|
1111
1110
|
def get_latest_job_id() -> Optional[int]:
|
1112
1111
|
"""Get the latest job id."""
|
1113
|
-
assert
|
1112
|
+
assert _DB_PATH is not None
|
1114
1113
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
1115
1114
|
rows = cursor.execute("""\
|
1116
1115
|
SELECT spot_job_id FROM spot
|
@@ -1123,7 +1122,7 @@ def get_latest_job_id() -> Optional[int]:
|
|
1123
1122
|
|
1124
1123
|
@_init_db
|
1125
1124
|
def get_task_specs(job_id: int, task_id: int) -> Dict[str, Any]:
|
1126
|
-
assert
|
1125
|
+
assert _DB_PATH is not None
|
1127
1126
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
1128
1127
|
task_specs = cursor.execute(
|
1129
1128
|
"""\
|
@@ -1136,7 +1135,7 @@ def get_task_specs(job_id: int, task_id: int) -> Dict[str, Any]:
|
|
1136
1135
|
@_init_db
|
1137
1136
|
def get_local_log_file(job_id: int, task_id: Optional[int]) -> Optional[str]:
|
1138
1137
|
"""Get the local log directory for a job."""
|
1139
|
-
assert
|
1138
|
+
assert _DB_PATH is not None
|
1140
1139
|
filter_str = 'spot_job_id=(?)'
|
1141
1140
|
filter_args = [job_id]
|
1142
1141
|
if task_id is not None:
|
@@ -1159,7 +1158,7 @@ def scheduler_set_waiting(job_id: int, dag_yaml_path: str,
|
|
1159
1158
|
original_user_yaml_path: str, env_file_path: str,
|
1160
1159
|
user_hash: str, priority: int) -> None:
|
1161
1160
|
"""Do not call without holding the scheduler lock."""
|
1162
|
-
assert
|
1161
|
+
assert _DB_PATH is not None
|
1163
1162
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
1164
1163
|
updated_count = cursor.execute(
|
1165
1164
|
'UPDATE job_info SET '
|
@@ -1177,7 +1176,7 @@ def scheduler_set_waiting(job_id: int, dag_yaml_path: str,
|
|
1177
1176
|
def scheduler_set_launching(job_id: int,
|
1178
1177
|
current_state: ManagedJobScheduleState) -> None:
|
1179
1178
|
"""Do not call without holding the scheduler lock."""
|
1180
|
-
assert
|
1179
|
+
assert _DB_PATH is not None
|
1181
1180
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
1182
1181
|
updated_count = cursor.execute(
|
1183
1182
|
'UPDATE job_info SET '
|
@@ -1191,7 +1190,7 @@ def scheduler_set_launching(job_id: int,
|
|
1191
1190
|
@_init_db
|
1192
1191
|
def scheduler_set_alive(job_id: int) -> None:
|
1193
1192
|
"""Do not call without holding the scheduler lock."""
|
1194
|
-
assert
|
1193
|
+
assert _DB_PATH is not None
|
1195
1194
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
1196
1195
|
updated_count = cursor.execute(
|
1197
1196
|
'UPDATE job_info SET '
|
@@ -1205,7 +1204,7 @@ def scheduler_set_alive(job_id: int) -> None:
|
|
1205
1204
|
@_init_db
|
1206
1205
|
def scheduler_set_alive_backoff(job_id: int) -> None:
|
1207
1206
|
"""Do not call without holding the scheduler lock."""
|
1208
|
-
assert
|
1207
|
+
assert _DB_PATH is not None
|
1209
1208
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
1210
1209
|
updated_count = cursor.execute(
|
1211
1210
|
'UPDATE job_info SET '
|
@@ -1219,7 +1218,7 @@ def scheduler_set_alive_backoff(job_id: int) -> None:
|
|
1219
1218
|
@_init_db
|
1220
1219
|
def scheduler_set_alive_waiting(job_id: int) -> None:
|
1221
1220
|
"""Do not call without holding the scheduler lock."""
|
1222
|
-
assert
|
1221
|
+
assert _DB_PATH is not None
|
1223
1222
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
1224
1223
|
updated_count = cursor.execute(
|
1225
1224
|
'UPDATE job_info SET '
|
@@ -1234,7 +1233,7 @@ def scheduler_set_alive_waiting(job_id: int) -> None:
|
|
1234
1233
|
@_init_db
|
1235
1234
|
def scheduler_set_done(job_id: int, idempotent: bool = False) -> None:
|
1236
1235
|
"""Do not call without holding the scheduler lock."""
|
1237
|
-
assert
|
1236
|
+
assert _DB_PATH is not None
|
1238
1237
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
1239
1238
|
updated_count = cursor.execute(
|
1240
1239
|
'UPDATE job_info SET '
|
@@ -1248,7 +1247,7 @@ def scheduler_set_done(job_id: int, idempotent: bool = False) -> None:
|
|
1248
1247
|
|
1249
1248
|
@_init_db
|
1250
1249
|
def set_job_controller_pid(job_id: int, pid: int):
|
1251
|
-
assert
|
1250
|
+
assert _DB_PATH is not None
|
1252
1251
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
1253
1252
|
updated_count = cursor.execute(
|
1254
1253
|
'UPDATE job_info SET '
|
@@ -1259,7 +1258,7 @@ def set_job_controller_pid(job_id: int, pid: int):
|
|
1259
1258
|
|
1260
1259
|
@_init_db
|
1261
1260
|
def get_job_schedule_state(job_id: int) -> ManagedJobScheduleState:
|
1262
|
-
assert
|
1261
|
+
assert _DB_PATH is not None
|
1263
1262
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
1264
1263
|
state = cursor.execute(
|
1265
1264
|
'SELECT schedule_state FROM job_info WHERE spot_job_id = (?)',
|
@@ -1269,7 +1268,7 @@ def get_job_schedule_state(job_id: int) -> ManagedJobScheduleState:
|
|
1269
1268
|
|
1270
1269
|
@_init_db
|
1271
1270
|
def get_num_launching_jobs() -> int:
|
1272
|
-
assert
|
1271
|
+
assert _DB_PATH is not None
|
1273
1272
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
1274
1273
|
return cursor.execute(
|
1275
1274
|
'SELECT COUNT(*) '
|
@@ -1280,7 +1279,7 @@ def get_num_launching_jobs() -> int:
|
|
1280
1279
|
|
1281
1280
|
@_init_db
|
1282
1281
|
def get_num_alive_jobs() -> int:
|
1283
|
-
assert
|
1282
|
+
assert _DB_PATH is not None
|
1284
1283
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
1285
1284
|
return cursor.execute(
|
1286
1285
|
'SELECT COUNT(*) '
|
@@ -1303,7 +1302,7 @@ def get_waiting_job() -> Optional[Dict[str, Any]]:
|
|
1303
1302
|
Backwards compatibility note: jobs submitted before #4485 will have no
|
1304
1303
|
schedule_state and will be ignored by this SQL query.
|
1305
1304
|
"""
|
1306
|
-
assert
|
1305
|
+
assert _DB_PATH is not None
|
1307
1306
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
1308
1307
|
# Get the highest-priority WAITING or ALIVE_WAITING job whose priority
|
1309
1308
|
# is greater than or equal to the highest priority LAUNCHING or
|
@@ -1338,7 +1337,7 @@ def get_waiting_job() -> Optional[Dict[str, Any]]:
|
|
1338
1337
|
@_init_db
|
1339
1338
|
def get_workspace(job_id: int) -> str:
|
1340
1339
|
"""Get the workspace of a job."""
|
1341
|
-
assert
|
1340
|
+
assert _DB_PATH is not None
|
1342
1341
|
with db_utils.safe_cursor(_DB_PATH) as cursor:
|
1343
1342
|
workspace = cursor.execute(
|
1344
1343
|
'SELECT workspace FROM job_info WHERE spot_job_id = (?)',
|
sky/provision/__init__.py
CHANGED
@@ -18,6 +18,7 @@ from sky.provision import common
|
|
18
18
|
from sky.provision import cudo
|
19
19
|
from sky.provision import fluidstack
|
20
20
|
from sky.provision import gcp
|
21
|
+
from sky.provision import hyperbolic
|
21
22
|
from sky.provision import kubernetes
|
22
23
|
from sky.provision import lambda_cloud
|
23
24
|
from sky.provision import nebius
|
sky/provision/common.py
CHANGED
sky/provision/gcp/config.py
CHANGED
@@ -274,7 +274,7 @@ def _is_permission_satisfied(service_account, crm, iam, required_permissions,
|
|
274
274
|
# For example, `roles/iam.serviceAccountUser` can be granted at the
|
275
275
|
# skypilot-v1 service account level, which can be checked with
|
276
276
|
# service_account_policy = iam.projects().serviceAccounts().getIamPolicy(
|
277
|
-
# resource=f'projects/{project_id}/
|
277
|
+
# resource=f'projects/{project_id}/serviceAccounts/{email}').execute()
|
278
278
|
# We now skip the check for `iam.serviceAccounts.actAs` permission for
|
279
279
|
# simplicity as it can be granted at the service account level.
|
280
280
|
def check_permissions(policy, required_permissions):
|
@@ -0,0 +1,11 @@
|
|
1
|
+
"""Hyperbolic provisioner for SkyPilot."""
|
2
|
+
|
3
|
+
from sky.provision.hyperbolic.config import bootstrap_instances
|
4
|
+
from sky.provision.hyperbolic.instance import cleanup_ports
|
5
|
+
from sky.provision.hyperbolic.instance import get_cluster_info
|
6
|
+
from sky.provision.hyperbolic.instance import open_ports
|
7
|
+
from sky.provision.hyperbolic.instance import query_instances
|
8
|
+
from sky.provision.hyperbolic.instance import run_instances
|
9
|
+
from sky.provision.hyperbolic.instance import stop_instances
|
10
|
+
from sky.provision.hyperbolic.instance import terminate_instances
|
11
|
+
from sky.provision.hyperbolic.instance import wait_instances
|
@@ -0,0 +1,10 @@
|
|
1
|
+
"""Hyperbolic Cloud configuration bootstrapping"""
|
2
|
+
|
3
|
+
from sky.provision import common
|
4
|
+
|
5
|
+
|
6
|
+
def bootstrap_instances(
|
7
|
+
region: str, cluster_name: str,
|
8
|
+
config: common.ProvisionConfig) -> common.ProvisionConfig:
|
9
|
+
del region, cluster_name # unused
|
10
|
+
return config
|