skypilot-nightly 1.0.0.dev20250905__py3-none-any.whl → 1.0.0.dev20251203__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 +10 -2
- sky/adaptors/aws.py +81 -16
- sky/adaptors/common.py +25 -2
- sky/adaptors/coreweave.py +278 -0
- sky/adaptors/do.py +8 -2
- sky/adaptors/gcp.py +11 -0
- sky/adaptors/ibm.py +5 -2
- sky/adaptors/kubernetes.py +64 -0
- sky/adaptors/nebius.py +3 -1
- sky/adaptors/primeintellect.py +1 -0
- sky/adaptors/seeweb.py +183 -0
- sky/adaptors/shadeform.py +89 -0
- sky/admin_policy.py +20 -0
- sky/authentication.py +157 -263
- sky/backends/__init__.py +3 -2
- sky/backends/backend.py +11 -3
- sky/backends/backend_utils.py +588 -184
- sky/backends/cloud_vm_ray_backend.py +1088 -904
- sky/backends/local_docker_backend.py +9 -5
- sky/backends/task_codegen.py +633 -0
- sky/backends/wheel_utils.py +18 -0
- sky/catalog/__init__.py +8 -0
- sky/catalog/aws_catalog.py +4 -0
- sky/catalog/common.py +19 -1
- sky/catalog/data_fetchers/fetch_aws.py +102 -80
- sky/catalog/data_fetchers/fetch_gcp.py +30 -3
- sky/catalog/data_fetchers/fetch_nebius.py +9 -6
- sky/catalog/data_fetchers/fetch_runpod.py +698 -0
- sky/catalog/data_fetchers/fetch_seeweb.py +329 -0
- sky/catalog/data_fetchers/fetch_shadeform.py +142 -0
- sky/catalog/kubernetes_catalog.py +24 -28
- sky/catalog/primeintellect_catalog.py +95 -0
- sky/catalog/runpod_catalog.py +5 -1
- sky/catalog/seeweb_catalog.py +184 -0
- sky/catalog/shadeform_catalog.py +165 -0
- sky/check.py +73 -43
- sky/client/cli/command.py +675 -412
- sky/client/cli/flags.py +4 -2
- sky/{volumes/utils.py → client/cli/table_utils.py} +111 -13
- sky/client/cli/utils.py +79 -0
- sky/client/common.py +12 -2
- sky/client/sdk.py +132 -63
- sky/client/sdk_async.py +34 -33
- sky/cloud_stores.py +82 -3
- sky/clouds/__init__.py +6 -0
- sky/clouds/aws.py +337 -129
- sky/clouds/azure.py +24 -18
- sky/clouds/cloud.py +40 -13
- sky/clouds/cudo.py +16 -13
- sky/clouds/do.py +9 -7
- sky/clouds/fluidstack.py +12 -5
- sky/clouds/gcp.py +14 -7
- sky/clouds/hyperbolic.py +12 -5
- sky/clouds/ibm.py +12 -5
- sky/clouds/kubernetes.py +80 -45
- sky/clouds/lambda_cloud.py +12 -5
- sky/clouds/nebius.py +23 -9
- sky/clouds/oci.py +19 -12
- sky/clouds/paperspace.py +4 -1
- sky/clouds/primeintellect.py +317 -0
- sky/clouds/runpod.py +85 -24
- sky/clouds/scp.py +12 -8
- sky/clouds/seeweb.py +477 -0
- sky/clouds/shadeform.py +400 -0
- sky/clouds/ssh.py +4 -2
- sky/clouds/utils/scp_utils.py +61 -50
- sky/clouds/vast.py +33 -27
- sky/clouds/vsphere.py +14 -16
- sky/core.py +174 -165
- sky/dashboard/out/404.html +1 -1
- sky/dashboard/out/_next/static/96_E2yl3QAiIJGOYCkSpB/_buildManifest.js +1 -0
- sky/dashboard/out/_next/static/chunks/1141-e6aa9ab418717c59.js +11 -0
- sky/dashboard/out/_next/static/chunks/1871-7e202677c42f43fe.js +6 -0
- sky/dashboard/out/_next/static/chunks/2260-7703229c33c5ebd5.js +1 -0
- sky/dashboard/out/_next/static/chunks/2369.fc20f0c2c8ed9fe7.js +15 -0
- sky/dashboard/out/_next/static/chunks/2755.edd818326d489a1d.js +26 -0
- sky/dashboard/out/_next/static/chunks/3294.20a8540fe697d5ee.js +1 -0
- sky/dashboard/out/_next/static/chunks/3785.7e245f318f9d1121.js +1 -0
- sky/dashboard/out/_next/static/chunks/{6601-06114c982db410b6.js → 3800-7b45f9fbb6308557.js} +1 -1
- sky/dashboard/out/_next/static/chunks/4725.172ede95d1b21022.js +1 -0
- sky/dashboard/out/_next/static/chunks/4937.a2baa2df5572a276.js +15 -0
- sky/dashboard/out/_next/static/chunks/6212-7bd06f60ba693125.js +13 -0
- sky/dashboard/out/_next/static/chunks/6856-8f27d1c10c98def8.js +1 -0
- sky/dashboard/out/_next/static/chunks/6990-9146207c4567fdfd.js +1 -0
- sky/dashboard/out/_next/static/chunks/7359-c8d04e06886000b3.js +30 -0
- sky/dashboard/out/_next/static/chunks/7615-019513abc55b3b47.js +1 -0
- sky/dashboard/out/_next/static/chunks/8640.5b9475a2d18c5416.js +16 -0
- sky/dashboard/out/_next/static/chunks/8969-452f9d5cbdd2dc73.js +1 -0
- sky/dashboard/out/_next/static/chunks/9025.fa408f3242e9028d.js +6 -0
- sky/dashboard/out/_next/static/chunks/9353-cff34f7e773b2e2b.js +1 -0
- sky/dashboard/out/_next/static/chunks/9360.a536cf6b1fa42355.js +31 -0
- sky/dashboard/out/_next/static/chunks/9847.3aaca6bb33455140.js +30 -0
- sky/dashboard/out/_next/static/chunks/pages/{_app-ce361c6959bc2001.js → _app-bde01e4a2beec258.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-792db96d918c98c9.js +16 -0
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-abfcac9c137aa543.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/clusters-ee39056f9851a3ff.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/infra/{[context]-6563820e094f68ca.js → [context]-c0b5935149902e6f.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/{infra-aabba60d57826e0f.js → infra-aed0ea19df7cf961.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-d66997e2bfc837cf.js +16 -0
- sky/dashboard/out/_next/static/chunks/pages/jobs/pools/[pool]-9faf940b253e3e06.js +21 -0
- sky/dashboard/out/_next/static/chunks/pages/jobs-2072b48b617989c9.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/users-f42674164aa73423.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/volumes-b84b948ff357c43e.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/workspaces/{[name]-af76bb06dbb3954f.js → [name]-84a40f8c7c627fe4.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/{workspaces-7598c33a746cdc91.js → workspaces-531b2f8c4bf89f82.js} +1 -1
- sky/dashboard/out/_next/static/chunks/webpack-64e05f17bf2cf8ce.js +1 -0
- sky/dashboard/out/_next/static/css/0748ce22df867032.css +3 -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/pools/[pool].html +1 -1
- sky/dashboard/out/jobs.html +1 -1
- sky/dashboard/out/users.html +1 -1
- sky/dashboard/out/volumes.html +1 -1
- sky/dashboard/out/workspace/new.html +1 -1
- sky/dashboard/out/workspaces/[name].html +1 -1
- sky/dashboard/out/workspaces.html +1 -1
- sky/data/data_utils.py +92 -1
- sky/data/mounting_utils.py +162 -29
- sky/data/storage.py +200 -19
- sky/data/storage_utils.py +10 -45
- sky/exceptions.py +18 -7
- sky/execution.py +74 -31
- sky/global_user_state.py +605 -191
- sky/jobs/__init__.py +2 -0
- sky/jobs/client/sdk.py +101 -4
- sky/jobs/client/sdk_async.py +31 -5
- sky/jobs/constants.py +15 -8
- sky/jobs/controller.py +726 -284
- sky/jobs/file_content_utils.py +128 -0
- sky/jobs/log_gc.py +193 -0
- sky/jobs/recovery_strategy.py +250 -100
- sky/jobs/scheduler.py +271 -173
- sky/jobs/server/core.py +367 -114
- sky/jobs/server/server.py +81 -35
- sky/jobs/server/utils.py +89 -35
- sky/jobs/state.py +1498 -620
- sky/jobs/utils.py +771 -306
- sky/logs/agent.py +40 -5
- sky/logs/aws.py +9 -19
- sky/metrics/utils.py +282 -39
- sky/optimizer.py +1 -1
- sky/provision/__init__.py +37 -1
- sky/provision/aws/config.py +34 -13
- sky/provision/aws/instance.py +5 -2
- sky/provision/azure/instance.py +5 -3
- sky/provision/common.py +2 -0
- sky/provision/cudo/instance.py +4 -3
- sky/provision/do/instance.py +4 -3
- sky/provision/docker_utils.py +97 -26
- sky/provision/fluidstack/instance.py +6 -5
- sky/provision/gcp/config.py +6 -1
- sky/provision/gcp/instance.py +4 -2
- sky/provision/hyperbolic/instance.py +4 -2
- sky/provision/instance_setup.py +66 -20
- sky/provision/kubernetes/__init__.py +2 -0
- sky/provision/kubernetes/config.py +7 -44
- sky/provision/kubernetes/constants.py +0 -1
- sky/provision/kubernetes/instance.py +609 -213
- sky/provision/kubernetes/manifests/fusermount-server-daemonset.yaml +1 -2
- sky/provision/kubernetes/network.py +12 -8
- sky/provision/kubernetes/network_utils.py +8 -25
- sky/provision/kubernetes/utils.py +382 -418
- sky/provision/kubernetes/volume.py +150 -18
- sky/provision/lambda_cloud/instance.py +16 -13
- sky/provision/nebius/instance.py +6 -2
- sky/provision/nebius/utils.py +103 -86
- sky/provision/oci/instance.py +4 -2
- sky/provision/paperspace/instance.py +4 -3
- sky/provision/primeintellect/__init__.py +10 -0
- sky/provision/primeintellect/config.py +11 -0
- sky/provision/primeintellect/instance.py +454 -0
- sky/provision/primeintellect/utils.py +398 -0
- sky/provision/provisioner.py +30 -9
- sky/provision/runpod/__init__.py +2 -0
- sky/provision/runpod/instance.py +4 -3
- sky/provision/runpod/volume.py +69 -13
- sky/provision/scp/instance.py +307 -130
- sky/provision/seeweb/__init__.py +11 -0
- sky/provision/seeweb/config.py +13 -0
- sky/provision/seeweb/instance.py +812 -0
- sky/provision/shadeform/__init__.py +11 -0
- sky/provision/shadeform/config.py +12 -0
- sky/provision/shadeform/instance.py +351 -0
- sky/provision/shadeform/shadeform_utils.py +83 -0
- sky/provision/vast/instance.py +5 -3
- sky/provision/volume.py +164 -0
- sky/provision/vsphere/common/ssl_helper.py +1 -1
- sky/provision/vsphere/common/vapiconnect.py +2 -1
- sky/provision/vsphere/common/vim_utils.py +3 -2
- sky/provision/vsphere/instance.py +8 -6
- sky/provision/vsphere/vsphere_utils.py +8 -1
- sky/resources.py +11 -3
- sky/schemas/api/responses.py +107 -6
- sky/schemas/db/global_user_state/008_skylet_ssh_tunnel_metadata.py +34 -0
- sky/schemas/db/global_user_state/009_last_activity_and_launched_at.py +89 -0
- sky/schemas/db/global_user_state/010_save_ssh_key.py +66 -0
- sky/schemas/db/global_user_state/011_is_ephemeral.py +34 -0
- sky/schemas/db/kv_cache/001_initial_schema.py +29 -0
- sky/schemas/db/serve_state/002_yaml_content.py +34 -0
- sky/schemas/db/skypilot_config/001_initial_schema.py +30 -0
- sky/schemas/db/spot_jobs/002_cluster_pool.py +3 -3
- sky/schemas/db/spot_jobs/004_job_file_contents.py +42 -0
- sky/schemas/db/spot_jobs/005_logs_gc.py +38 -0
- sky/schemas/db/spot_jobs/006_controller_pid_started_at.py +34 -0
- sky/schemas/db/spot_jobs/007_config_file_content.py +34 -0
- sky/schemas/generated/jobsv1_pb2.py +86 -0
- sky/schemas/generated/jobsv1_pb2.pyi +254 -0
- sky/schemas/generated/jobsv1_pb2_grpc.py +542 -0
- sky/schemas/generated/managed_jobsv1_pb2.py +76 -0
- sky/schemas/generated/managed_jobsv1_pb2.pyi +278 -0
- sky/schemas/generated/managed_jobsv1_pb2_grpc.py +278 -0
- sky/schemas/generated/servev1_pb2.py +58 -0
- sky/schemas/generated/servev1_pb2.pyi +115 -0
- sky/schemas/generated/servev1_pb2_grpc.py +322 -0
- sky/serve/autoscalers.py +2 -0
- sky/serve/client/impl.py +55 -21
- sky/serve/constants.py +4 -3
- sky/serve/controller.py +17 -11
- sky/serve/load_balancing_policies.py +1 -1
- sky/serve/replica_managers.py +219 -142
- sky/serve/serve_rpc_utils.py +179 -0
- sky/serve/serve_state.py +63 -54
- sky/serve/serve_utils.py +145 -109
- sky/serve/server/core.py +46 -25
- sky/serve/server/impl.py +311 -162
- sky/serve/server/server.py +21 -19
- sky/serve/service.py +84 -68
- sky/serve/service_spec.py +45 -7
- sky/server/auth/loopback.py +38 -0
- sky/server/auth/oauth2_proxy.py +12 -7
- sky/server/common.py +47 -24
- sky/server/config.py +62 -28
- sky/server/constants.py +9 -1
- sky/server/daemons.py +109 -38
- sky/server/metrics.py +76 -96
- sky/server/middleware_utils.py +166 -0
- sky/server/requests/executor.py +381 -145
- sky/server/requests/payloads.py +71 -18
- sky/server/requests/preconditions.py +15 -13
- sky/server/requests/request_names.py +121 -0
- sky/server/requests/requests.py +507 -157
- sky/server/requests/serializers/decoders.py +48 -17
- sky/server/requests/serializers/encoders.py +85 -20
- sky/server/requests/threads.py +117 -0
- sky/server/rest.py +116 -24
- sky/server/server.py +420 -172
- sky/server/stream_utils.py +219 -45
- sky/server/uvicorn.py +30 -19
- sky/setup_files/MANIFEST.in +6 -1
- sky/setup_files/alembic.ini +8 -0
- sky/setup_files/dependencies.py +62 -19
- sky/setup_files/setup.py +44 -44
- sky/sky_logging.py +13 -5
- sky/skylet/attempt_skylet.py +106 -24
- sky/skylet/configs.py +3 -1
- sky/skylet/constants.py +111 -26
- sky/skylet/events.py +64 -10
- sky/skylet/job_lib.py +141 -104
- sky/skylet/log_lib.py +233 -5
- sky/skylet/log_lib.pyi +40 -2
- sky/skylet/providers/ibm/node_provider.py +12 -8
- sky/skylet/providers/ibm/vpc_provider.py +13 -12
- sky/skylet/runtime_utils.py +21 -0
- sky/skylet/services.py +524 -0
- sky/skylet/skylet.py +22 -1
- sky/skylet/subprocess_daemon.py +104 -29
- sky/skypilot_config.py +99 -79
- sky/ssh_node_pools/server.py +9 -8
- sky/task.py +221 -104
- sky/templates/aws-ray.yml.j2 +1 -0
- sky/templates/azure-ray.yml.j2 +1 -0
- sky/templates/cudo-ray.yml.j2 +1 -0
- sky/templates/do-ray.yml.j2 +1 -0
- sky/templates/fluidstack-ray.yml.j2 +1 -0
- sky/templates/gcp-ray.yml.j2 +1 -0
- sky/templates/hyperbolic-ray.yml.j2 +1 -0
- sky/templates/ibm-ray.yml.j2 +2 -1
- sky/templates/jobs-controller.yaml.j2 +3 -0
- sky/templates/kubernetes-ray.yml.j2 +196 -55
- sky/templates/lambda-ray.yml.j2 +1 -0
- sky/templates/nebius-ray.yml.j2 +3 -0
- sky/templates/oci-ray.yml.j2 +1 -0
- sky/templates/paperspace-ray.yml.j2 +1 -0
- sky/templates/primeintellect-ray.yml.j2 +72 -0
- sky/templates/runpod-ray.yml.j2 +1 -0
- sky/templates/scp-ray.yml.j2 +1 -0
- sky/templates/seeweb-ray.yml.j2 +171 -0
- sky/templates/shadeform-ray.yml.j2 +73 -0
- sky/templates/vast-ray.yml.j2 +1 -0
- sky/templates/vsphere-ray.yml.j2 +1 -0
- sky/templates/websocket_proxy.py +188 -43
- sky/usage/usage_lib.py +16 -4
- sky/users/permission.py +60 -43
- sky/utils/accelerator_registry.py +6 -3
- sky/utils/admin_policy_utils.py +18 -5
- sky/utils/annotations.py +22 -0
- sky/utils/asyncio_utils.py +78 -0
- sky/utils/atomic.py +1 -1
- sky/utils/auth_utils.py +153 -0
- sky/utils/cli_utils/status_utils.py +12 -7
- sky/utils/cluster_utils.py +28 -6
- sky/utils/command_runner.py +88 -27
- sky/utils/command_runner.pyi +36 -3
- sky/utils/common.py +3 -1
- sky/utils/common_utils.py +37 -4
- sky/utils/config_utils.py +1 -14
- sky/utils/context.py +127 -40
- sky/utils/context_utils.py +73 -18
- sky/utils/controller_utils.py +229 -70
- sky/utils/db/db_utils.py +95 -18
- sky/utils/db/kv_cache.py +149 -0
- sky/utils/db/migration_utils.py +24 -7
- sky/utils/env_options.py +4 -0
- sky/utils/git.py +559 -1
- sky/utils/kubernetes/create_cluster.sh +15 -30
- sky/utils/kubernetes/delete_cluster.sh +10 -7
- sky/utils/kubernetes/{deploy_remote_cluster.py → deploy_ssh_node_pools.py} +258 -380
- sky/utils/kubernetes/generate_kind_config.py +6 -66
- sky/utils/kubernetes/gpu_labeler.py +13 -3
- sky/utils/kubernetes/k8s_gpu_labeler_job.yaml +2 -1
- sky/utils/kubernetes/k8s_gpu_labeler_setup.yaml +16 -16
- sky/utils/kubernetes/kubernetes_deploy_utils.py +213 -194
- sky/utils/kubernetes/rsync_helper.sh +11 -3
- sky/utils/kubernetes_enums.py +7 -15
- sky/utils/lock_events.py +4 -4
- sky/utils/locks.py +128 -31
- sky/utils/log_utils.py +0 -319
- sky/utils/resource_checker.py +13 -10
- sky/utils/resources_utils.py +53 -29
- sky/utils/rich_utils.py +8 -4
- sky/utils/schemas.py +107 -52
- sky/utils/subprocess_utils.py +17 -4
- sky/utils/thread_utils.py +91 -0
- sky/utils/timeline.py +2 -1
- sky/utils/ux_utils.py +35 -1
- sky/utils/volume.py +88 -4
- sky/utils/yaml_utils.py +9 -0
- sky/volumes/client/sdk.py +48 -10
- sky/volumes/server/core.py +59 -22
- sky/volumes/server/server.py +46 -17
- sky/volumes/volume.py +54 -42
- sky/workspaces/core.py +57 -21
- sky/workspaces/server.py +13 -12
- sky_templates/README.md +3 -0
- sky_templates/__init__.py +3 -0
- sky_templates/ray/__init__.py +0 -0
- sky_templates/ray/start_cluster +183 -0
- sky_templates/ray/stop_cluster +75 -0
- {skypilot_nightly-1.0.0.dev20250905.dist-info → skypilot_nightly-1.0.0.dev20251203.dist-info}/METADATA +331 -65
- skypilot_nightly-1.0.0.dev20251203.dist-info/RECORD +611 -0
- skypilot_nightly-1.0.0.dev20251203.dist-info/top_level.txt +2 -0
- sky/client/cli/git.py +0 -549
- sky/dashboard/out/_next/static/chunks/1121-408ed10b2f9fce17.js +0 -1
- sky/dashboard/out/_next/static/chunks/1141-943efc7aff0f0c06.js +0 -1
- sky/dashboard/out/_next/static/chunks/1836-37fede578e2da5f8.js +0 -40
- sky/dashboard/out/_next/static/chunks/3015-86cabed5d4669ad0.js +0 -1
- sky/dashboard/out/_next/static/chunks/3294.c80326aec9bfed40.js +0 -6
- sky/dashboard/out/_next/static/chunks/3785.4872a2f3aa489880.js +0 -1
- sky/dashboard/out/_next/static/chunks/4045.b30465273dc5e468.js +0 -21
- sky/dashboard/out/_next/static/chunks/4676-9da7fdbde90b5549.js +0 -10
- sky/dashboard/out/_next/static/chunks/4725.10f7a9a5d3ea8208.js +0 -1
- sky/dashboard/out/_next/static/chunks/5339.3fda4a4010ff4e06.js +0 -51
- sky/dashboard/out/_next/static/chunks/6135-4b4d5e824b7f9d3c.js +0 -1
- sky/dashboard/out/_next/static/chunks/649.b9d7f7d10c1b8c53.js +0 -45
- sky/dashboard/out/_next/static/chunks/6856-dca7962af4814e1b.js +0 -1
- sky/dashboard/out/_next/static/chunks/6990-08b2a1cae076a943.js +0 -1
- sky/dashboard/out/_next/static/chunks/7325.b4bc99ce0892dcd5.js +0 -6
- sky/dashboard/out/_next/static/chunks/754-d0da8ab45f9509e9.js +0 -18
- sky/dashboard/out/_next/static/chunks/7669.1f5d9a402bf5cc42.js +0 -36
- sky/dashboard/out/_next/static/chunks/8969-0be3036bf86f8256.js +0 -1
- sky/dashboard/out/_next/static/chunks/9025.c12318fb6a1a9093.js +0 -6
- sky/dashboard/out/_next/static/chunks/9037-fa1737818d0a0969.js +0 -6
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-1cbba24bd1bd35f8.js +0 -16
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-0b4b35dc1dfe046c.js +0 -16
- sky/dashboard/out/_next/static/chunks/pages/clusters-469814d711d63b1b.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-dd64309c3fe67ed2.js +0 -11
- sky/dashboard/out/_next/static/chunks/pages/jobs/pools/[pool]-07349868f7905d37.js +0 -16
- sky/dashboard/out/_next/static/chunks/pages/jobs-1f70d9faa564804f.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/users-018bf31cda52e11b.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/volumes-739726d6b823f532.js +0 -1
- sky/dashboard/out/_next/static/chunks/webpack-4fe903277b57b523.js +0 -1
- sky/dashboard/out/_next/static/css/4614e06482d7309e.css +0 -3
- sky/dashboard/out/_next/static/mS-4qZPSkRuA1u-g2wQhg/_buildManifest.js +0 -1
- sky/templates/kubernetes-ssh-jump.yml.j2 +0 -94
- sky/utils/kubernetes/ssh_jump_lifecycle_manager.py +0 -191
- skypilot_nightly-1.0.0.dev20250905.dist-info/RECORD +0 -547
- skypilot_nightly-1.0.0.dev20250905.dist-info/top_level.txt +0 -1
- /sky/dashboard/out/_next/static/{mS-4qZPSkRuA1u-g2wQhg → 96_E2yl3QAiIJGOYCkSpB}/_ssgManifest.js +0 -0
- {skypilot_nightly-1.0.0.dev20250905.dist-info → skypilot_nightly-1.0.0.dev20251203.dist-info}/WHEEL +0 -0
- {skypilot_nightly-1.0.0.dev20250905.dist-info → skypilot_nightly-1.0.0.dev20251203.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20250905.dist-info → skypilot_nightly-1.0.0.dev20251203.dist-info}/licenses/LICENSE +0 -0
sky/__init__.py
CHANGED
|
@@ -7,7 +7,7 @@ import urllib.request
|
|
|
7
7
|
from sky.utils import directory_utils
|
|
8
8
|
|
|
9
9
|
# Replaced with the current commit when building the wheels.
|
|
10
|
-
_SKYPILOT_COMMIT_SHA = '
|
|
10
|
+
_SKYPILOT_COMMIT_SHA = '3ff39aba6d4752d5c3b09e3fa7d778cefea39370'
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def _get_git_commit():
|
|
@@ -37,7 +37,7 @@ def _get_git_commit():
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
__commit__ = _get_git_commit()
|
|
40
|
-
__version__ = '1.0.0.
|
|
40
|
+
__version__ = '1.0.0.dev20251203'
|
|
41
41
|
__root_dir__ = directory_utils.get_sky_dir()
|
|
42
42
|
|
|
43
43
|
|
|
@@ -122,6 +122,7 @@ from sky.data import StoreType
|
|
|
122
122
|
from sky.jobs import ManagedJobStatus
|
|
123
123
|
from sky.optimizer import Optimizer
|
|
124
124
|
from sky.resources import Resources
|
|
125
|
+
from sky.server.requests.request_names import AdminPolicyRequestName
|
|
125
126
|
from sky.skylet.job_lib import JobStatus
|
|
126
127
|
from sky.task import Task
|
|
127
128
|
from sky.utils.common import OptimizeTarget
|
|
@@ -143,12 +144,15 @@ Kubernetes = clouds.Kubernetes
|
|
|
143
144
|
K8s = Kubernetes
|
|
144
145
|
OCI = clouds.OCI
|
|
145
146
|
Paperspace = clouds.Paperspace
|
|
147
|
+
PrimeIntellect = clouds.PrimeIntellect
|
|
146
148
|
RunPod = clouds.RunPod
|
|
147
149
|
Vast = clouds.Vast
|
|
148
150
|
Vsphere = clouds.Vsphere
|
|
149
151
|
Fluidstack = clouds.Fluidstack
|
|
150
152
|
Nebius = clouds.Nebius
|
|
151
153
|
Hyperbolic = clouds.Hyperbolic
|
|
154
|
+
Shadeform = clouds.Shadeform
|
|
155
|
+
Seeweb = clouds.Seeweb
|
|
152
156
|
|
|
153
157
|
__all__ = [
|
|
154
158
|
'__version__',
|
|
@@ -162,6 +166,7 @@ __all__ = [
|
|
|
162
166
|
'Lambda',
|
|
163
167
|
'OCI',
|
|
164
168
|
'Paperspace',
|
|
169
|
+
'PrimeIntellect',
|
|
165
170
|
'RunPod',
|
|
166
171
|
'Vast',
|
|
167
172
|
'SCP',
|
|
@@ -169,6 +174,8 @@ __all__ = [
|
|
|
169
174
|
'Fluidstack',
|
|
170
175
|
'Nebius',
|
|
171
176
|
'Hyperbolic',
|
|
177
|
+
'Shadeform',
|
|
178
|
+
'Seeweb',
|
|
172
179
|
'Optimizer',
|
|
173
180
|
'OptimizeTarget',
|
|
174
181
|
'backends',
|
|
@@ -222,6 +229,7 @@ __all__ = [
|
|
|
222
229
|
'MutatedUserRequest',
|
|
223
230
|
'AdminPolicy',
|
|
224
231
|
'Config',
|
|
232
|
+
'AdminPolicyRequestName',
|
|
225
233
|
# Registry
|
|
226
234
|
'CLOUD_REGISTRY',
|
|
227
235
|
'JOBS_RECOVERY_STRATEGY_REGISTRY',
|
sky/adaptors/aws.py
CHANGED
|
@@ -28,12 +28,14 @@ This is informed by the following boto3 docs:
|
|
|
28
28
|
|
|
29
29
|
# pylint: disable=import-outside-toplevel
|
|
30
30
|
|
|
31
|
+
import functools
|
|
31
32
|
import logging
|
|
32
33
|
import threading
|
|
33
34
|
import time
|
|
34
35
|
import typing
|
|
35
36
|
from typing import Callable, Literal, Optional, TypeVar
|
|
36
37
|
|
|
38
|
+
from sky import skypilot_config
|
|
37
39
|
from sky.adaptors import common
|
|
38
40
|
from sky.utils import annotations
|
|
39
41
|
from sky.utils import common_utils
|
|
@@ -67,17 +69,63 @@ version = 1
|
|
|
67
69
|
_MAX_ATTEMPT_FOR_CREATION = 5
|
|
68
70
|
|
|
69
71
|
|
|
70
|
-
class
|
|
72
|
+
class _ThreadLocalTTLCache(threading.local):
|
|
73
|
+
"""Thread-local storage for _thread_local_lru_cache decorator."""
|
|
71
74
|
|
|
72
|
-
def __init__(self, maxsize
|
|
75
|
+
def __init__(self, func, maxsize: int, ttl: int):
|
|
73
76
|
super().__init__()
|
|
74
|
-
self.
|
|
77
|
+
self.func = func
|
|
78
|
+
self.maxsize = maxsize
|
|
79
|
+
self.ttl = ttl
|
|
75
80
|
|
|
81
|
+
def get_cache(self):
|
|
82
|
+
if not hasattr(self, 'cache'):
|
|
83
|
+
self.cache = annotations.ttl_cache(scope='request',
|
|
84
|
+
maxsize=self.maxsize,
|
|
85
|
+
ttl=self.ttl,
|
|
86
|
+
timer=time.time)(self.func)
|
|
87
|
+
return self.cache
|
|
76
88
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
89
|
+
|
|
90
|
+
def _thread_local_ttl_cache(maxsize=32, ttl=60 * 55):
|
|
91
|
+
"""Thread-local TTL cache decorator.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
maxsize: Maximum size of the cache.
|
|
95
|
+
ttl: Time to live for the cache in seconds.
|
|
96
|
+
Default is 55 minutes, a bit less than 1 hour
|
|
97
|
+
default lifetime of an STS token.
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
def decorator(func):
|
|
101
|
+
# Create thread-local storage for the LRU cache
|
|
102
|
+
local_cache = _ThreadLocalTTLCache(func, maxsize, ttl)
|
|
103
|
+
|
|
104
|
+
# We can't apply the lru_cache here, because this runs at import time
|
|
105
|
+
# so we will always have the main thread's cache.
|
|
106
|
+
|
|
107
|
+
@functools.wraps(func)
|
|
108
|
+
def wrapper(*args, **kwargs):
|
|
109
|
+
# We are within the actual function call, which may be on a thread,
|
|
110
|
+
# so local_cache.cache will return the correct thread-local cache,
|
|
111
|
+
# which we can now apply and immediately call.
|
|
112
|
+
return local_cache.get_cache()(*args, **kwargs)
|
|
113
|
+
|
|
114
|
+
def cache_info():
|
|
115
|
+
# Note that this will only give the cache info for the current
|
|
116
|
+
# thread's cache.
|
|
117
|
+
return local_cache.get_cache().cache_info()
|
|
118
|
+
|
|
119
|
+
def cache_clear():
|
|
120
|
+
# Note that this will only clear the cache for the current thread.
|
|
121
|
+
local_cache.get_cache().cache_clear()
|
|
122
|
+
|
|
123
|
+
wrapper.cache_info = cache_info # type: ignore[attr-defined]
|
|
124
|
+
wrapper.cache_clear = cache_clear # type: ignore[attr-defined]
|
|
125
|
+
|
|
126
|
+
return wrapper
|
|
127
|
+
|
|
128
|
+
return decorator
|
|
81
129
|
|
|
82
130
|
|
|
83
131
|
def _assert_kwargs_builtin_type(kwargs):
|
|
@@ -119,12 +167,27 @@ def _create_aws_object(creation_fn_or_cls: Callable[[], T],
|
|
|
119
167
|
f'{common_utils.format_exception(e)}.')
|
|
120
168
|
|
|
121
169
|
|
|
122
|
-
|
|
170
|
+
def get_workspace_profile() -> Optional[str]:
|
|
171
|
+
"""Get AWS profile name from workspace config."""
|
|
172
|
+
return skypilot_config.get_workspace_cloud('aws').get('profile', None)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
# The TTL cache needs to be thread-local to avoid multiple threads sharing the
|
|
123
176
|
# same session object, which is not guaranteed to be thread-safe.
|
|
124
|
-
@
|
|
125
|
-
def session(check_credentials: bool = True):
|
|
126
|
-
"""Create an AWS session.
|
|
127
|
-
|
|
177
|
+
@_thread_local_ttl_cache()
|
|
178
|
+
def session(check_credentials: bool = True, profile: Optional[str] = None):
|
|
179
|
+
"""Create an AWS session.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
check_credentials: Whether to check if credentials are available.
|
|
183
|
+
profile: AWS profile name to use. If None, uses default credentials.
|
|
184
|
+
"""
|
|
185
|
+
if profile is not None:
|
|
186
|
+
logger.debug(f'Using AWS profile \'{profile}\'.')
|
|
187
|
+
s = _create_aws_object(
|
|
188
|
+
lambda: boto3.session.Session(profile_name=profile), 'session')
|
|
189
|
+
else:
|
|
190
|
+
s = _create_aws_object(boto3.session.Session, 'session')
|
|
128
191
|
if check_credentials and s.get_credentials() is None:
|
|
129
192
|
# s.get_credentials() can be None if there are actually no credentials,
|
|
130
193
|
# or if we fail to get credentials from IMDS (e.g. due to throttling).
|
|
@@ -180,13 +243,14 @@ def resource(service_name: str, **kwargs):
|
|
|
180
243
|
kwargs['config'] = config
|
|
181
244
|
|
|
182
245
|
check_credentials = kwargs.pop('check_credentials', True)
|
|
246
|
+
profile = get_workspace_profile()
|
|
183
247
|
|
|
184
248
|
# Need to use the client retrieved from the per-thread session to avoid
|
|
185
249
|
# thread-safety issues (Directly creating the client with boto3.resource()
|
|
186
250
|
# is not thread-safe). Reference: https://stackoverflow.com/a/59635814
|
|
187
251
|
return _create_aws_object(
|
|
188
|
-
lambda: session(check_credentials=check_credentials).
|
|
189
|
-
|
|
252
|
+
lambda: session(check_credentials=check_credentials, profile=profile).
|
|
253
|
+
resource(service_name, **kwargs), 'resource')
|
|
190
254
|
|
|
191
255
|
|
|
192
256
|
# New typing overloads can be added as needed.
|
|
@@ -221,14 +285,15 @@ def client(service_name: str, **kwargs):
|
|
|
221
285
|
_assert_kwargs_builtin_type(kwargs)
|
|
222
286
|
|
|
223
287
|
check_credentials = kwargs.pop('check_credentials', True)
|
|
288
|
+
profile = get_workspace_profile()
|
|
224
289
|
|
|
225
290
|
# Need to use the client retrieved from the per-thread session to avoid
|
|
226
291
|
# thread-safety issues (Directly creating the client with boto3.client() is
|
|
227
292
|
# not thread-safe). Reference: https://stackoverflow.com/a/59635814
|
|
228
293
|
|
|
229
294
|
return _create_aws_object(
|
|
230
|
-
lambda: session(check_credentials=check_credentials).
|
|
231
|
-
|
|
295
|
+
lambda: session(check_credentials=check_credentials, profile=profile).
|
|
296
|
+
client(service_name, **kwargs), 'client')
|
|
232
297
|
|
|
233
298
|
|
|
234
299
|
@common.load_lazy_modules(modules=_LAZY_MODULES)
|
sky/adaptors/common.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"""Lazy import for modules to avoid import error when not used."""
|
|
2
|
+
from importlib import util as importlib_util
|
|
2
3
|
import functools
|
|
3
4
|
import importlib
|
|
4
5
|
import threading
|
|
5
6
|
import types
|
|
6
|
-
from typing import Any, Callable, Optional, Tuple
|
|
7
|
+
from typing import Any, Callable, List, Optional, Tuple
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class LazyImport(types.ModuleType):
|
|
@@ -27,7 +28,7 @@ class LazyImport(types.ModuleType):
|
|
|
27
28
|
import_error_message: Optional[str] = None,
|
|
28
29
|
set_loggers: Optional[Callable] = None):
|
|
29
30
|
self._module_name = module_name
|
|
30
|
-
self._module = None
|
|
31
|
+
self._module: Optional[types.ModuleType] = None
|
|
31
32
|
self._import_error_message = import_error_message
|
|
32
33
|
self._set_loggers = set_loggers
|
|
33
34
|
self._lock = threading.RLock()
|
|
@@ -78,3 +79,25 @@ def load_lazy_modules(modules: Tuple[LazyImport, ...]):
|
|
|
78
79
|
return wrapper
|
|
79
80
|
|
|
80
81
|
return decorator
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def can_import_modules(module_names: List[str]) -> bool:
|
|
85
|
+
""" module availability without actually importing it to
|
|
86
|
+
save memory footprint.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
module_names: List[str], the names of the modules to check.
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
True if all modules are available, False otherwise.
|
|
93
|
+
If a module exists in sys.modules, but is set to None,
|
|
94
|
+
then it is considered as not available.
|
|
95
|
+
"""
|
|
96
|
+
try:
|
|
97
|
+
for module_name in module_names:
|
|
98
|
+
module_spec = importlib_util.find_spec(module_name)
|
|
99
|
+
if module_spec is None:
|
|
100
|
+
return False
|
|
101
|
+
return True
|
|
102
|
+
except ValueError:
|
|
103
|
+
return False
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"""CoreWeave cloud adaptor."""
|
|
2
|
+
|
|
3
|
+
import configparser
|
|
4
|
+
import contextlib
|
|
5
|
+
import os
|
|
6
|
+
import threading
|
|
7
|
+
from typing import Dict, Optional, Tuple
|
|
8
|
+
|
|
9
|
+
from sky import exceptions
|
|
10
|
+
from sky import sky_logging
|
|
11
|
+
from sky.adaptors import common
|
|
12
|
+
from sky.clouds import cloud
|
|
13
|
+
from sky.utils import annotations
|
|
14
|
+
from sky.utils import ux_utils
|
|
15
|
+
|
|
16
|
+
logger = sky_logging.init_logger(__name__)
|
|
17
|
+
|
|
18
|
+
COREWEAVE_PROFILE_NAME = 'cw'
|
|
19
|
+
COREWEAVE_CREDENTIALS_PATH = '~/.coreweave/cw.credentials'
|
|
20
|
+
COREWEAVE_CONFIG_PATH = '~/.coreweave/cw.config'
|
|
21
|
+
NAME = 'CoreWeave'
|
|
22
|
+
DEFAULT_REGION = 'US-EAST-01A'
|
|
23
|
+
_DEFAULT_ENDPOINT = 'https://cwobject.com'
|
|
24
|
+
_INDENT_PREFIX = ' '
|
|
25
|
+
|
|
26
|
+
_IMPORT_ERROR_MESSAGE = ('Failed to import dependencies for CoreWeave.'
|
|
27
|
+
'Try pip install "skypilot[coreweave]"')
|
|
28
|
+
|
|
29
|
+
boto3 = common.LazyImport('boto3', import_error_message=_IMPORT_ERROR_MESSAGE)
|
|
30
|
+
botocore = common.LazyImport('botocore',
|
|
31
|
+
import_error_message=_IMPORT_ERROR_MESSAGE)
|
|
32
|
+
|
|
33
|
+
_LAZY_MODULES = (boto3, botocore)
|
|
34
|
+
_session_creation_lock = threading.RLock()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@contextlib.contextmanager
|
|
38
|
+
def _load_cw_credentials_env():
|
|
39
|
+
"""Context manager to temporarily change the AWS credentials file path."""
|
|
40
|
+
prev_credentials_path = os.environ.get('AWS_SHARED_CREDENTIALS_FILE')
|
|
41
|
+
prev_config_path = os.environ.get('AWS_CONFIG_FILE')
|
|
42
|
+
os.environ['AWS_SHARED_CREDENTIALS_FILE'] = COREWEAVE_CREDENTIALS_PATH
|
|
43
|
+
os.environ['AWS_CONFIG_FILE'] = COREWEAVE_CONFIG_PATH
|
|
44
|
+
try:
|
|
45
|
+
yield
|
|
46
|
+
finally:
|
|
47
|
+
if prev_credentials_path is None:
|
|
48
|
+
del os.environ['AWS_SHARED_CREDENTIALS_FILE']
|
|
49
|
+
else:
|
|
50
|
+
os.environ['AWS_SHARED_CREDENTIALS_FILE'] = prev_credentials_path
|
|
51
|
+
if prev_config_path is None:
|
|
52
|
+
del os.environ['AWS_CONFIG_FILE']
|
|
53
|
+
else:
|
|
54
|
+
os.environ['AWS_CONFIG_FILE'] = prev_config_path
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def get_coreweave_credentials(boto3_session):
|
|
58
|
+
"""Gets the CoreWeave credentials from the boto3 session object.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
boto3_session: The boto3 session object.
|
|
62
|
+
Returns:
|
|
63
|
+
botocore.credentials.ReadOnlyCredentials object with the CoreWeave
|
|
64
|
+
credentials.
|
|
65
|
+
"""
|
|
66
|
+
with _load_cw_credentials_env():
|
|
67
|
+
coreweave_credentials = boto3_session.get_credentials()
|
|
68
|
+
if coreweave_credentials is None:
|
|
69
|
+
with ux_utils.print_exception_no_traceback():
|
|
70
|
+
raise ValueError('CoreWeave credentials not found. Run '
|
|
71
|
+
'`sky check` to verify credentials are '
|
|
72
|
+
'correctly set up.')
|
|
73
|
+
return coreweave_credentials.get_frozen_credentials()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@annotations.lru_cache(scope='global')
|
|
77
|
+
def session():
|
|
78
|
+
"""Create an AWS session for CoreWeave."""
|
|
79
|
+
# Creating the session object is not thread-safe for boto3,
|
|
80
|
+
# so we add a reentrant lock to synchronize the session creation.
|
|
81
|
+
# Reference: https://github.com/boto/boto3/issues/1592
|
|
82
|
+
# However, the session object itself is thread-safe, so we are
|
|
83
|
+
# able to use lru_cache() to cache the session object.
|
|
84
|
+
with _session_creation_lock:
|
|
85
|
+
with _load_cw_credentials_env():
|
|
86
|
+
session_ = boto3.session.Session(
|
|
87
|
+
profile_name=COREWEAVE_PROFILE_NAME)
|
|
88
|
+
return session_
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@annotations.lru_cache(scope='global')
|
|
92
|
+
def resource(resource_name: str, **kwargs):
|
|
93
|
+
"""Create a CoreWeave resource.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
resource_name: CoreWeave resource name (e.g., 's3').
|
|
97
|
+
kwargs: Other options.
|
|
98
|
+
"""
|
|
99
|
+
# Need to use the resource retrieved from the per-thread session
|
|
100
|
+
# to avoid thread-safety issues (Directly creating the client
|
|
101
|
+
# with boto3.resource() is not thread-safe).
|
|
102
|
+
# Reference: https://stackoverflow.com/a/59635814
|
|
103
|
+
|
|
104
|
+
session_ = session()
|
|
105
|
+
coreweave_credentials = get_coreweave_credentials(session_)
|
|
106
|
+
endpoint = get_endpoint()
|
|
107
|
+
|
|
108
|
+
return session_.resource(
|
|
109
|
+
resource_name,
|
|
110
|
+
endpoint_url=endpoint,
|
|
111
|
+
aws_access_key_id=coreweave_credentials.access_key,
|
|
112
|
+
aws_secret_access_key=coreweave_credentials.secret_key,
|
|
113
|
+
region_name='auto',
|
|
114
|
+
config=botocore.config.Config(s3={'addressing_style': 'virtual'}),
|
|
115
|
+
**kwargs)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
@annotations.lru_cache(scope='global')
|
|
119
|
+
def client(service_name: str):
|
|
120
|
+
"""Create CoreWeave client of a certain service.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
service_name: CoreWeave service name (e.g., 's3').
|
|
124
|
+
"""
|
|
125
|
+
# Need to use the client retrieved from the per-thread session
|
|
126
|
+
# to avoid thread-safety issues (Directly creating the client
|
|
127
|
+
# with boto3.client() is not thread-safe).
|
|
128
|
+
# Reference: https://stackoverflow.com/a/59635814
|
|
129
|
+
|
|
130
|
+
session_ = session()
|
|
131
|
+
coreweave_credentials = get_coreweave_credentials(session_)
|
|
132
|
+
endpoint = get_endpoint()
|
|
133
|
+
|
|
134
|
+
return session_.client(
|
|
135
|
+
service_name,
|
|
136
|
+
endpoint_url=endpoint,
|
|
137
|
+
aws_access_key_id=coreweave_credentials.access_key,
|
|
138
|
+
aws_secret_access_key=coreweave_credentials.secret_key,
|
|
139
|
+
region_name='auto',
|
|
140
|
+
config=botocore.config.Config(s3={'addressing_style': 'virtual'}),
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@common.load_lazy_modules(_LAZY_MODULES)
|
|
145
|
+
def botocore_exceptions():
|
|
146
|
+
"""AWS botocore exception."""
|
|
147
|
+
# pylint: disable=import-outside-toplevel
|
|
148
|
+
from botocore import exceptions as boto_exceptions
|
|
149
|
+
return boto_exceptions
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def get_endpoint():
|
|
153
|
+
"""Parse the COREWEAVE_CONFIG_PATH to get the endpoint_url.
|
|
154
|
+
|
|
155
|
+
The config file is an AWS-style config file with format:
|
|
156
|
+
[profile cw]
|
|
157
|
+
endpoint_url = https://cwobject.com
|
|
158
|
+
s3 =
|
|
159
|
+
addressing_style = virtual
|
|
160
|
+
|
|
161
|
+
Returns:
|
|
162
|
+
str: The endpoint URL from the config file, or the default endpoint
|
|
163
|
+
if the file doesn't exist or doesn't contain the endpoint_url.
|
|
164
|
+
"""
|
|
165
|
+
config_path = os.path.expanduser(COREWEAVE_CONFIG_PATH)
|
|
166
|
+
if not os.path.isfile(config_path):
|
|
167
|
+
return _DEFAULT_ENDPOINT
|
|
168
|
+
|
|
169
|
+
try:
|
|
170
|
+
config = configparser.ConfigParser()
|
|
171
|
+
config.read(config_path)
|
|
172
|
+
|
|
173
|
+
# Try to get endpoint_url from [profile cw] section
|
|
174
|
+
profile_section = f'profile {COREWEAVE_PROFILE_NAME}'
|
|
175
|
+
if config.has_section(profile_section):
|
|
176
|
+
if config.has_option(profile_section, 'endpoint_url'):
|
|
177
|
+
endpoint = config.get(profile_section, 'endpoint_url')
|
|
178
|
+
return endpoint.strip()
|
|
179
|
+
except (configparser.Error, OSError) as e:
|
|
180
|
+
logger.warning(f'Failed to parse CoreWeave config file: {e}. '
|
|
181
|
+
f'Using default endpoint: {_DEFAULT_ENDPOINT}')
|
|
182
|
+
|
|
183
|
+
return _DEFAULT_ENDPOINT
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def check_credentials(
|
|
187
|
+
cloud_capability: cloud.CloudCapability) -> Tuple[bool, Optional[str]]:
|
|
188
|
+
if cloud_capability == cloud.CloudCapability.STORAGE:
|
|
189
|
+
return check_storage_credentials()
|
|
190
|
+
else:
|
|
191
|
+
raise exceptions.NotSupportedError(
|
|
192
|
+
f'{NAME} does not support {cloud_capability}.')
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def check_storage_credentials() -> Tuple[bool, Optional[str]]:
|
|
196
|
+
"""Checks if the user has access credentials to CoreWeave Object Storage.
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
A tuple of a boolean value and a hint message where the bool
|
|
200
|
+
is True when both credentials needed for CoreWeave storage is set.
|
|
201
|
+
It is False when either of those are not set, which would hint with a
|
|
202
|
+
string on unset credential.
|
|
203
|
+
"""
|
|
204
|
+
hints = None
|
|
205
|
+
profile_in_cred = coreweave_profile_in_cred()
|
|
206
|
+
profile_in_config = coreweave_profile_in_config()
|
|
207
|
+
|
|
208
|
+
if not profile_in_cred:
|
|
209
|
+
hints = (f'[{COREWEAVE_PROFILE_NAME}] profile is not set in '
|
|
210
|
+
f'{COREWEAVE_CREDENTIALS_PATH}.')
|
|
211
|
+
if not profile_in_config:
|
|
212
|
+
if hints:
|
|
213
|
+
hints += ' Additionally, '
|
|
214
|
+
else:
|
|
215
|
+
hints = ''
|
|
216
|
+
hints += (f'[{COREWEAVE_PROFILE_NAME}] profile is not set in '
|
|
217
|
+
f'{COREWEAVE_CONFIG_PATH}.')
|
|
218
|
+
|
|
219
|
+
if hints:
|
|
220
|
+
hints += ' Run the following commands:'
|
|
221
|
+
if not profile_in_cred:
|
|
222
|
+
hints += f'\n{_INDENT_PREFIX} $ pip install boto3'
|
|
223
|
+
hints += (f'\n{_INDENT_PREFIX} $ AWS_SHARED_CREDENTIALS_FILE='
|
|
224
|
+
f'{COREWEAVE_CREDENTIALS_PATH} aws configure --profile '
|
|
225
|
+
f'{COREWEAVE_PROFILE_NAME}')
|
|
226
|
+
if not profile_in_config:
|
|
227
|
+
hints += (f'\n{_INDENT_PREFIX} $ AWS_CONFIG_FILE='
|
|
228
|
+
f'{COREWEAVE_CONFIG_PATH} aws configure set endpoint_url'
|
|
229
|
+
f' <ENDPOINT_URL> --profile '
|
|
230
|
+
f'{COREWEAVE_PROFILE_NAME}')
|
|
231
|
+
hints += (f'\n{_INDENT_PREFIX} $ AWS_CONFIG_FILE='
|
|
232
|
+
f'{COREWEAVE_CONFIG_PATH} aws configure set '
|
|
233
|
+
f's3.addressing_style virtual --profile '
|
|
234
|
+
f'{COREWEAVE_PROFILE_NAME}')
|
|
235
|
+
hints += f'\n{_INDENT_PREFIX}For more info: '
|
|
236
|
+
hints += 'https://docs.coreweave.com/docs/products/storage/object-storage/get-started-caios' # pylint: disable=line-too-long
|
|
237
|
+
|
|
238
|
+
return (False, hints) if hints else (True, hints)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def coreweave_profile_in_config() -> bool:
|
|
242
|
+
"""Checks if CoreWeave profile is set in config"""
|
|
243
|
+
conf_path = os.path.expanduser(COREWEAVE_CONFIG_PATH)
|
|
244
|
+
coreweave_profile_exists = False
|
|
245
|
+
if os.path.isfile(conf_path):
|
|
246
|
+
with open(conf_path, 'r', encoding='utf-8') as file:
|
|
247
|
+
for line in file:
|
|
248
|
+
if f'[profile {COREWEAVE_PROFILE_NAME}]' in line:
|
|
249
|
+
coreweave_profile_exists = True
|
|
250
|
+
break
|
|
251
|
+
return coreweave_profile_exists
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def coreweave_profile_in_cred() -> bool:
|
|
255
|
+
"""Checks if CoreWeave profile is set in credentials"""
|
|
256
|
+
cred_path = os.path.expanduser(COREWEAVE_CREDENTIALS_PATH)
|
|
257
|
+
coreweave_profile_exists = False
|
|
258
|
+
if os.path.isfile(cred_path):
|
|
259
|
+
with open(cred_path, 'r', encoding='utf-8') as file:
|
|
260
|
+
for line in file:
|
|
261
|
+
if f'[{COREWEAVE_PROFILE_NAME}]' in line:
|
|
262
|
+
coreweave_profile_exists = True
|
|
263
|
+
break
|
|
264
|
+
return coreweave_profile_exists
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def get_credential_file_mounts() -> Dict[str, str]:
|
|
268
|
+
"""Returns credential file mounts for CoreWeave.
|
|
269
|
+
|
|
270
|
+
Returns:
|
|
271
|
+
Dict[str, str]: A dictionary mapping source paths to destination paths
|
|
272
|
+
for credential files.
|
|
273
|
+
"""
|
|
274
|
+
coreweave_credential_mounts = {
|
|
275
|
+
COREWEAVE_CREDENTIALS_PATH: COREWEAVE_CREDENTIALS_PATH,
|
|
276
|
+
COREWEAVE_CONFIG_PATH: COREWEAVE_CONFIG_PATH
|
|
277
|
+
}
|
|
278
|
+
return coreweave_credential_mounts
|
sky/adaptors/do.py
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"""Digital Ocean cloud adaptors"""
|
|
2
2
|
|
|
3
|
-
# pylint: disable=import-outside-toplevel
|
|
4
|
-
|
|
5
3
|
from sky.adaptors import common
|
|
6
4
|
|
|
7
5
|
_IMPORT_ERROR_MESSAGE = ('Failed to import dependencies for DO. '
|
|
@@ -16,5 +14,13 @@ _LAZY_MODULES = (pydo, azure)
|
|
|
16
14
|
@common.load_lazy_modules(modules=_LAZY_MODULES)
|
|
17
15
|
def exceptions():
|
|
18
16
|
"""Azure exceptions."""
|
|
17
|
+
# pylint: disable=import-outside-toplevel
|
|
19
18
|
from azure.core import exceptions as azure_exceptions
|
|
20
19
|
return azure_exceptions
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def check_exceptions_dependencies_installed():
|
|
23
|
+
"""Check if the azure.core.exceptions module is installed."""
|
|
24
|
+
if not common.can_import_modules(['azure.core.exceptions']):
|
|
25
|
+
return False, _IMPORT_ERROR_MESSAGE
|
|
26
|
+
return True, None
|
sky/adaptors/gcp.py
CHANGED
|
@@ -2,9 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
# pylint: disable=import-outside-toplevel
|
|
4
4
|
import json
|
|
5
|
+
import warnings
|
|
5
6
|
|
|
6
7
|
from sky.adaptors import common
|
|
7
8
|
|
|
9
|
+
# Suppress FutureWarning from google.api_core about Python 3.10 support ending.
|
|
10
|
+
# This warning is informational and does not affect functionality.
|
|
11
|
+
# Reference: https://github.com/skypilot-org/skypilot/issues/7886
|
|
12
|
+
warnings.filterwarnings(
|
|
13
|
+
'ignore',
|
|
14
|
+
category=FutureWarning,
|
|
15
|
+
message=
|
|
16
|
+
r'.*You are using a Python version.*which Google will stop supporting.*',
|
|
17
|
+
)
|
|
18
|
+
|
|
8
19
|
_IMPORT_ERROR_MESSAGE = ('Failed to import dependencies for GCP. '
|
|
9
20
|
'Try pip install "skypilot[gcp]"')
|
|
10
21
|
googleapiclient = common.LazyImport('googleapiclient',
|
sky/adaptors/ibm.py
CHANGED
|
@@ -28,6 +28,9 @@ requests = common.LazyImport('requests',
|
|
|
28
28
|
import_error_message=_IMPORT_ERROR_MESSAGE)
|
|
29
29
|
yaml = common.LazyImport('yaml', import_error_message=_IMPORT_ERROR_MESSAGE)
|
|
30
30
|
|
|
31
|
+
# Global process lock for thread-safe boto3 operations
|
|
32
|
+
global_process_lock = None
|
|
33
|
+
|
|
31
34
|
|
|
32
35
|
def read_credential_file():
|
|
33
36
|
try:
|
|
@@ -152,9 +155,9 @@ def _get_global_process_lock():
|
|
|
152
155
|
already initialized.
|
|
153
156
|
Necessary when process are spawned without a shared lock.
|
|
154
157
|
"""
|
|
155
|
-
global global_process_lock
|
|
158
|
+
global global_process_lock
|
|
156
159
|
|
|
157
|
-
if
|
|
160
|
+
if global_process_lock is None:
|
|
158
161
|
global_process_lock = multiprocessing.Lock()
|
|
159
162
|
|
|
160
163
|
return global_process_lock
|