skypilot-nightly 1.0.0.dev20250627__py3-none-any.whl → 1.0.0.dev20250630__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sky/__init__.py +2 -2
- sky/adaptors/kubernetes.py +14 -0
- sky/adaptors/nebius.py +2 -2
- sky/authentication.py +12 -5
- sky/backends/backend_utils.py +92 -26
- sky/check.py +5 -2
- sky/client/cli/command.py +39 -8
- sky/client/sdk.py +217 -167
- sky/client/service_account_auth.py +47 -0
- sky/clouds/aws.py +10 -4
- sky/clouds/azure.py +5 -2
- sky/clouds/cloud.py +5 -2
- sky/clouds/gcp.py +31 -18
- sky/clouds/kubernetes.py +54 -34
- sky/clouds/nebius.py +8 -2
- sky/clouds/ssh.py +5 -2
- sky/clouds/utils/aws_utils.py +10 -4
- sky/clouds/utils/gcp_utils.py +22 -7
- sky/clouds/utils/oci_utils.py +62 -14
- sky/dashboard/out/404.html +1 -1
- sky/dashboard/out/_next/static/NdypbqMxaYucRGfopkKXa/_buildManifest.js +1 -0
- sky/dashboard/out/_next/static/chunks/1043-1b39779691bb4030.js +1 -0
- sky/dashboard/out/_next/static/chunks/{141-fa5a20cbf401b351.js → 1141-726e5a3f00b67185.js} +2 -2
- sky/dashboard/out/_next/static/chunks/1272-1ef0bf0237faccdb.js +1 -0
- sky/dashboard/out/_next/static/chunks/1664-d65361e92b85e786.js +1 -0
- sky/dashboard/out/_next/static/chunks/1691.44e378727a41f3b5.js +21 -0
- sky/dashboard/out/_next/static/chunks/1871-80dea41717729fa5.js +6 -0
- sky/dashboard/out/_next/static/chunks/2544.27f70672535675ed.js +1 -0
- sky/dashboard/out/_next/static/chunks/{875.52c962183328b3f2.js → 2875.c24c6d57dc82e436.js} +1 -1
- sky/dashboard/out/_next/static/chunks/3256.7257acd01b481bed.js +11 -0
- sky/dashboard/out/_next/static/chunks/3698-52ad1ca228faa776.js +1 -0
- sky/dashboard/out/_next/static/chunks/3785.b3cc2bc1d49d2c3c.js +1 -0
- sky/dashboard/out/_next/static/chunks/3937.d7f1c55d1916c7f2.js +1 -0
- sky/dashboard/out/_next/static/chunks/{947-6620842ef80ae879.js → 3947-b059261d6fa88a1f.js} +1 -1
- sky/dashboard/out/_next/static/chunks/{697.6460bf72e760addd.js → 4697.f5421144224da9fc.js} +1 -1
- sky/dashboard/out/_next/static/chunks/4725.4c849b1e05c8e9ad.js +1 -0
- sky/dashboard/out/_next/static/chunks/5230-df791914b54d91d9.js +1 -0
- sky/dashboard/out/_next/static/chunks/{491.b3d264269613fe09.js → 5491.918ffed0ba7a5294.js} +1 -1
- sky/dashboard/out/_next/static/chunks/5739-5ea3ffa10fc884f2.js +8 -0
- sky/dashboard/out/_next/static/chunks/616-162f3033ffcd3d31.js +39 -0
- sky/dashboard/out/_next/static/chunks/6601-fcfad0ddf92ec7ab.js +1 -0
- sky/dashboard/out/_next/static/chunks/6989-6ff4e45dfb49d11d.js +1 -0
- sky/dashboard/out/_next/static/chunks/6990-d0dc765474fa0eca.js +1 -0
- sky/dashboard/out/_next/static/chunks/8969-909d53833da080cb.js +1 -0
- sky/dashboard/out/_next/static/chunks/8982.a2e214068f30a857.js +1 -0
- sky/dashboard/out/_next/static/chunks/{25.76c246239df93d50.js → 9025.a7c44babfe56ce09.js} +2 -2
- sky/dashboard/out/_next/static/chunks/938-044ad21de8b4626b.js +1 -0
- sky/dashboard/out/_next/static/chunks/9470-21d059a1dfa03f61.js +1 -0
- sky/dashboard/out/_next/static/chunks/9984.739ae958a066298d.js +1 -0
- sky/dashboard/out/_next/static/chunks/fd9d1056-61f2257a9cd8b32b.js +1 -0
- sky/dashboard/out/_next/static/chunks/{framework-87d061ee6ed71b28.js → framework-efc06c2733009cd3.js} +1 -1
- sky/dashboard/out/_next/static/chunks/main-app-68c028b1bc5e1b72.js +1 -0
- sky/dashboard/out/_next/static/chunks/{main-e0e2335212e72357.js → main-c0a4f1ea606d48d2.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/{_app-9a3ce3170d2edcec.js → _app-a37b06ddb64521fd.js} +2 -2
- sky/dashboard/out/_next/static/chunks/pages/_error-c72a1f77a3c0be1b.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-8135aba0712bda37.js +6 -0
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-b8e1114e6d38218c.js +6 -0
- sky/dashboard/out/_next/static/chunks/pages/clusters-9744c271a1642f76.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/config-a2673b256b6d416f.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/index-927ddeebe57a8ac3.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/infra/[context]-8b0809f59034d509.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/infra-ae9d2f705ce582c9.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-c4d5cfac7fbc0668.js +16 -0
- sky/dashboard/out/_next/static/chunks/pages/jobs-5bbdc71878f0a068.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/users-cd43fb3c122eedde.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/volumes-4ebf6484f7216387.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/workspace/new-5629d4e551dba1ee.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/workspaces/[name]-7c0187f43757a548.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/workspaces-06bde99155fa6292.js +1 -0
- sky/dashboard/out/_next/static/chunks/webpack-d427db53e54de9ce.js +1 -0
- sky/dashboard/out/_next/static/css/0da6afe66176678a.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.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/storage.py +8 -3
- sky/global_user_state.py +257 -9
- sky/jobs/client/sdk.py +20 -25
- sky/models.py +16 -0
- sky/optimizer.py +46 -0
- sky/provision/__init__.py +14 -6
- sky/provision/kubernetes/config.py +1 -1
- sky/provision/kubernetes/constants.py +9 -0
- sky/provision/kubernetes/instance.py +24 -18
- sky/provision/kubernetes/network.py +15 -9
- sky/provision/kubernetes/network_utils.py +42 -23
- sky/provision/kubernetes/utils.py +73 -35
- sky/provision/kubernetes/volume.py +77 -15
- sky/provision/nebius/utils.py +10 -4
- sky/resources.py +10 -4
- sky/serve/client/sdk.py +28 -34
- sky/server/common.py +51 -3
- sky/server/constants.py +3 -0
- sky/server/requests/executor.py +4 -0
- sky/server/requests/payloads.py +33 -0
- sky/server/requests/requests.py +19 -0
- sky/server/rest.py +6 -15
- sky/server/server.py +121 -6
- sky/skylet/constants.py +7 -0
- sky/skypilot_config.py +32 -4
- sky/task.py +12 -0
- sky/users/permission.py +29 -0
- sky/users/server.py +384 -5
- sky/users/token_service.py +196 -0
- sky/utils/common_utils.py +4 -5
- sky/utils/config_utils.py +41 -0
- sky/utils/controller_utils.py +5 -1
- sky/utils/log_utils.py +68 -0
- sky/utils/resource_checker.py +153 -0
- sky/utils/resources_utils.py +12 -4
- sky/utils/schemas.py +87 -60
- sky/utils/subprocess_utils.py +2 -6
- sky/volumes/server/core.py +103 -78
- sky/volumes/utils.py +22 -5
- sky/workspaces/core.py +9 -117
- {skypilot_nightly-1.0.0.dev20250627.dist-info → skypilot_nightly-1.0.0.dev20250630.dist-info}/METADATA +1 -1
- {skypilot_nightly-1.0.0.dev20250627.dist-info → skypilot_nightly-1.0.0.dev20250630.dist-info}/RECORD +133 -128
- sky/dashboard/out/_next/static/HudU4f4Xsy-cP51JvXSZ-/_buildManifest.js +0 -1
- sky/dashboard/out/_next/static/chunks/230-d6e363362017ff3a.js +0 -1
- sky/dashboard/out/_next/static/chunks/43-36177d00f6956ab2.js +0 -1
- sky/dashboard/out/_next/static/chunks/470-92dd1614396389be.js +0 -1
- sky/dashboard/out/_next/static/chunks/544.110e53813fb98e2e.js +0 -1
- sky/dashboard/out/_next/static/chunks/616-d6128fa9e7cae6e6.js +0 -39
- sky/dashboard/out/_next/static/chunks/645.961f08e39b8ce447.js +0 -1
- sky/dashboard/out/_next/static/chunks/664-047bc03493fda379.js +0 -1
- sky/dashboard/out/_next/static/chunks/690.55f9eed3be903f56.js +0 -16
- sky/dashboard/out/_next/static/chunks/785.dc2686c3c1235554.js +0 -1
- sky/dashboard/out/_next/static/chunks/798-c0525dc3f21e488d.js +0 -1
- sky/dashboard/out/_next/static/chunks/799-3625946b2ec2eb30.js +0 -8
- sky/dashboard/out/_next/static/chunks/871-3db673be3ee3750b.js +0 -6
- sky/dashboard/out/_next/static/chunks/937.3759f538f11a0953.js +0 -1
- sky/dashboard/out/_next/static/chunks/938-068520cc11738deb.js +0 -1
- sky/dashboard/out/_next/static/chunks/969-d3a0b53f728d280a.js +0 -1
- sky/dashboard/out/_next/static/chunks/973-81b2d057178adb76.js +0 -1
- sky/dashboard/out/_next/static/chunks/982.1b61658204416b0f.js +0 -1
- sky/dashboard/out/_next/static/chunks/984.e8bac186a24e5178.js +0 -1
- sky/dashboard/out/_next/static/chunks/989-db34c16ad7ea6155.js +0 -1
- sky/dashboard/out/_next/static/chunks/990-0ad5ea1699e03ee8.js +0 -1
- sky/dashboard/out/_next/static/chunks/fd9d1056-2821b0f0cabcd8bd.js +0 -1
- sky/dashboard/out/_next/static/chunks/main-app-241eb28595532291.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/_error-1be831200e60c5c0.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-aff040d7bc5d0086.js +0 -6
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-8040f2483897ed0c.js +0 -6
- sky/dashboard/out/_next/static/chunks/pages/clusters-f119a5630a1efd61.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/config-6b255eae088da6a3.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/index-6b0d9e5031b70c58.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/infra/[context]-b302aea4d65766bf.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/infra-ee8cc4d449945d19.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-e4b23128db0774cd.js +0 -16
- sky/dashboard/out/_next/static/chunks/pages/jobs-0a5695ff3075d94a.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/users-4978cbb093e141e7.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/volumes-476b670ef33d1ecd.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/workspace/new-5b59bce9eb208d84.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/workspaces/[name]-cb7e720b739de53a.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/workspaces-50e230828730cfb3.js +0 -1
- sky/dashboard/out/_next/static/chunks/webpack-08fdb9e6070127fc.js +0 -1
- sky/dashboard/out/_next/static/css/52082cf558ec9705.css +0 -3
- /sky/dashboard/out/_next/static/{HudU4f4Xsy-cP51JvXSZ- → NdypbqMxaYucRGfopkKXa}/_ssgManifest.js +0 -0
- /sky/dashboard/out/_next/static/chunks/{804-4c9fc53aa74bc191.js → 804-9f5e98ce84d46bdd.js} +0 -0
- {skypilot_nightly-1.0.0.dev20250627.dist-info → skypilot_nightly-1.0.0.dev20250630.dist-info}/WHEEL +0 -0
- {skypilot_nightly-1.0.0.dev20250627.dist-info → skypilot_nightly-1.0.0.dev20250630.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20250627.dist-info → skypilot_nightly-1.0.0.dev20250630.dist-info}/licenses/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev20250627.dist-info → skypilot_nightly-1.0.0.dev20250630.dist-info}/top_level.txt +0 -0
sky/provision/__init__.py
CHANGED
@@ -6,7 +6,7 @@ providers supported by SkyPilot need to follow.
|
|
6
6
|
import functools
|
7
7
|
import inspect
|
8
8
|
import typing
|
9
|
-
from typing import Any, Dict, List, Optional, Type
|
9
|
+
from typing import Any, Dict, List, Optional, Tuple, Type
|
10
10
|
|
11
11
|
from sky import models
|
12
12
|
from sky import sky_logging
|
@@ -106,7 +106,7 @@ def bootstrap_instances(
|
|
106
106
|
|
107
107
|
@_route_to_cloud_impl
|
108
108
|
def apply_volume(provider_name: str,
|
109
|
-
|
109
|
+
volume_config: models.VolumeConfig) -> models.VolumeConfig:
|
110
110
|
"""Create or register a volume.
|
111
111
|
|
112
112
|
This function creates or registers a volume with the provided configuration,
|
@@ -117,15 +117,23 @@ def apply_volume(provider_name: str,
|
|
117
117
|
|
118
118
|
@_route_to_cloud_impl
|
119
119
|
def delete_volume(provider_name: str,
|
120
|
-
|
120
|
+
volume_config: models.VolumeConfig) -> models.VolumeConfig:
|
121
121
|
"""Delete a volume."""
|
122
122
|
raise NotImplementedError
|
123
123
|
|
124
124
|
|
125
125
|
@_route_to_cloud_impl
|
126
|
-
def get_volume_usedby(
|
127
|
-
|
128
|
-
|
126
|
+
def get_volume_usedby(
|
127
|
+
provider_name: str,
|
128
|
+
volume_config: models.VolumeConfig,
|
129
|
+
) -> Tuple[List[str], List[str]]:
|
130
|
+
"""Get the usedby of a volume.
|
131
|
+
|
132
|
+
Returns:
|
133
|
+
usedby_pods: List of pods using the volume. These may include pods
|
134
|
+
not created by SkyPilot.
|
135
|
+
usedby_clusters: List of clusters using the volume.
|
136
|
+
"""
|
129
137
|
raise NotImplementedError
|
130
138
|
|
131
139
|
|
@@ -35,7 +35,7 @@ def bootstrap_instances(
|
|
35
35
|
_configure_services(namespace, context, config.provider_config)
|
36
36
|
|
37
37
|
networking_mode = network_utils.get_networking_mode(
|
38
|
-
config.provider_config.get('networking_mode'))
|
38
|
+
config.provider_config.get('networking_mode'), context)
|
39
39
|
if networking_mode == kubernetes_enums.KubernetesNetworkingMode.NODEPORT:
|
40
40
|
config = _configure_ssh_jump(namespace, context, config)
|
41
41
|
|
@@ -15,3 +15,12 @@ SKY_K8S_EXEC_AUTH_PATH = '$HOME/skypilot-runtime/bin:$HOME/google-cloud-sdk/bin:
|
|
15
15
|
|
16
16
|
# cache directory for kubeconfig with modified exec auth
|
17
17
|
SKY_K8S_EXEC_AUTH_KUBECONFIG_CACHE = '~/.sky/generated/kubeconfigs'
|
18
|
+
|
19
|
+
# Labels for the Pods created by SkyPilot
|
20
|
+
TAG_RAY_CLUSTER_NAME = 'ray-cluster-name'
|
21
|
+
TAG_SKYPILOT_CLUSTER_NAME = 'skypilot-cluster-name'
|
22
|
+
TAG_POD_INITIALIZED = 'skypilot-initialized'
|
23
|
+
TAG_SKYPILOT_DEPLOYMENT_NAME = 'skypilot-deployment-name'
|
24
|
+
|
25
|
+
# Pod phases that are not holding PVCs
|
26
|
+
PVC_NOT_HOLD_POD_PHASES = ['Succeeded', 'Failed']
|
@@ -12,6 +12,7 @@ from sky.provision import common
|
|
12
12
|
from sky.provision import constants
|
13
13
|
from sky.provision import docker_utils
|
14
14
|
from sky.provision.kubernetes import config as config_lib
|
15
|
+
from sky.provision.kubernetes import constants as k8s_constants
|
15
16
|
from sky.provision.kubernetes import network_utils
|
16
17
|
from sky.provision.kubernetes import utils as kubernetes_utils
|
17
18
|
from sky.provision.kubernetes import volume
|
@@ -30,14 +31,10 @@ _MAX_RETRIES = 3
|
|
30
31
|
_NUM_THREADS = subprocess_utils.get_parallel_threads('kubernetes')
|
31
32
|
|
32
33
|
logger = sky_logging.init_logger(__name__)
|
33
|
-
TAG_RAY_CLUSTER_NAME = 'ray-cluster-name'
|
34
|
-
TAG_SKYPILOT_CLUSTER_NAME = 'skypilot-cluster-name'
|
35
|
-
TAG_POD_INITIALIZED = 'skypilot-initialized'
|
36
|
-
TAG_SKYPILOT_DEPLOYMENT_NAME = 'skypilot-deployment-name'
|
37
34
|
|
38
35
|
|
39
36
|
def ray_tag_filter(cluster_name: str) -> Dict[str, str]:
|
40
|
-
return {TAG_RAY_CLUSTER_NAME: cluster_name}
|
37
|
+
return {k8s_constants.TAG_RAY_CLUSTER_NAME: cluster_name}
|
41
38
|
|
42
39
|
|
43
40
|
def _is_head(pod) -> bool:
|
@@ -75,7 +72,8 @@ def is_high_availability_cluster_by_kubectl(
|
|
75
72
|
deployment_list = kubernetes.apps_api(
|
76
73
|
context).list_namespaced_deployment(
|
77
74
|
namespace,
|
78
|
-
label_selector=
|
75
|
+
label_selector=
|
76
|
+
f'{k8s_constants.TAG_SKYPILOT_CLUSTER_NAME}={cluster_name}')
|
79
77
|
except kubernetes.api_exception():
|
80
78
|
return False
|
81
79
|
# It is a high availability cluster if there is at least one deployment
|
@@ -280,10 +278,12 @@ def _wait_for_pods_to_schedule(namespace, context, new_nodes, timeout: int):
|
|
280
278
|
while _evaluate_timeout():
|
281
279
|
# Get all pods in a single API call using the cluster name label
|
282
280
|
# which all pods in new_nodes should share
|
283
|
-
cluster_name = new_nodes[0].metadata.labels[
|
281
|
+
cluster_name = new_nodes[0].metadata.labels[
|
282
|
+
k8s_constants.TAG_SKYPILOT_CLUSTER_NAME]
|
284
283
|
pods = kubernetes.core_api(context).list_namespaced_pod(
|
285
284
|
namespace,
|
286
|
-
label_selector=
|
285
|
+
label_selector=
|
286
|
+
f'{k8s_constants.TAG_SKYPILOT_CLUSTER_NAME}={cluster_name}').items
|
287
287
|
|
288
288
|
# Get the set of found pod names and check if we have all expected pods
|
289
289
|
found_pod_names = {pod.metadata.name for pod in pods}
|
@@ -361,10 +361,12 @@ def _wait_for_pods_to_run(namespace, context, new_nodes):
|
|
361
361
|
|
362
362
|
while True:
|
363
363
|
# Get all pods in a single API call
|
364
|
-
cluster_name = new_nodes[0].metadata.labels[
|
364
|
+
cluster_name = new_nodes[0].metadata.labels[
|
365
|
+
k8s_constants.TAG_SKYPILOT_CLUSTER_NAME]
|
365
366
|
all_pods = kubernetes.core_api(context).list_namespaced_pod(
|
366
367
|
namespace,
|
367
|
-
label_selector=
|
368
|
+
label_selector=
|
369
|
+
f'{k8s_constants.TAG_SKYPILOT_CLUSTER_NAME}={cluster_name}').items
|
368
370
|
|
369
371
|
# Get the set of found pod names and check if we have all expected pods
|
370
372
|
found_pod_names = {pod.metadata.name for pod in all_pods}
|
@@ -732,7 +734,7 @@ def _create_pods(region: str, cluster_name_on_cloud: str,
|
|
732
734
|
else:
|
733
735
|
pod_spec['metadata']['labels'] = tags
|
734
736
|
pod_spec['metadata']['labels'].update(
|
735
|
-
{TAG_SKYPILOT_CLUSTER_NAME: cluster_name_on_cloud})
|
737
|
+
{k8s_constants.TAG_SKYPILOT_CLUSTER_NAME: cluster_name_on_cloud})
|
736
738
|
|
737
739
|
terminating_pods = kubernetes_utils.filter_pods(namespace, context, tags,
|
738
740
|
['Terminating'])
|
@@ -841,7 +843,7 @@ def _create_pods(region: str, cluster_name_on_cloud: str,
|
|
841
843
|
'podAffinityTerm': {
|
842
844
|
'labelSelector': {
|
843
845
|
'matchExpressions': [{
|
844
|
-
'key': TAG_SKYPILOT_CLUSTER_NAME,
|
846
|
+
'key': k8s_constants.TAG_SKYPILOT_CLUSTER_NAME,
|
845
847
|
'operator': 'In',
|
846
848
|
'values': [cluster_name_on_cloud]
|
847
849
|
}]
|
@@ -884,7 +886,7 @@ def _create_pods(region: str, cluster_name_on_cloud: str,
|
|
884
886
|
# Add the deployment name as a label to the pod spec
|
885
887
|
deployment_name = deployment_spec['metadata']['name']
|
886
888
|
pod_spec_copy['metadata']['labels'][
|
887
|
-
TAG_SKYPILOT_DEPLOYMENT_NAME] = deployment_name
|
889
|
+
k8s_constants.TAG_SKYPILOT_DEPLOYMENT_NAME] = deployment_name
|
888
890
|
template_pod_spec['metadata'] = pod_spec_copy['metadata']
|
889
891
|
template_pod_spec['spec'].update(pod_spec_copy['spec'])
|
890
892
|
# Propagate the labels to the deployment for identification.
|
@@ -941,7 +943,7 @@ def _create_pods(region: str, cluster_name_on_cloud: str,
|
|
941
943
|
head_pod_name = pod.metadata.name
|
942
944
|
|
943
945
|
networking_mode = network_utils.get_networking_mode(
|
944
|
-
config.provider_config.get('networking_mode'))
|
946
|
+
config.provider_config.get('networking_mode'), context)
|
945
947
|
if networking_mode == kubernetes_enums.KubernetesNetworkingMode.NODEPORT:
|
946
948
|
# Adding the jump pod to the new_nodes list as well so it can be
|
947
949
|
# checked if it's scheduled and running along with other pods.
|
@@ -1102,7 +1104,7 @@ def terminate_instances(
|
|
1102
1104
|
|
1103
1105
|
# Clean up the SSH jump pod if in use
|
1104
1106
|
networking_mode = network_utils.get_networking_mode(
|
1105
|
-
provider_config.get('networking_mode'))
|
1107
|
+
provider_config.get('networking_mode'), context)
|
1106
1108
|
if networking_mode == kubernetes_enums.KubernetesNetworkingMode.NODEPORT:
|
1107
1109
|
pod_name = list(pods.keys())[0]
|
1108
1110
|
try:
|
@@ -1147,8 +1149,11 @@ def get_cluster_info(
|
|
1147
1149
|
head_pod_name = None
|
1148
1150
|
|
1149
1151
|
port_forward_mode = kubernetes_enums.KubernetesNetworkingMode.PORTFORWARD
|
1150
|
-
network_mode_str = skypilot_config.
|
1151
|
-
|
1152
|
+
network_mode_str = skypilot_config.get_effective_region_config(
|
1153
|
+
cloud='kubernetes',
|
1154
|
+
region=context,
|
1155
|
+
keys=('networking_mode',),
|
1156
|
+
default_value=port_forward_mode.value)
|
1152
1157
|
network_mode = kubernetes_enums.KubernetesNetworkingMode.from_str(
|
1153
1158
|
network_mode_str)
|
1154
1159
|
external_ip = kubernetes_utils.get_external_ip(network_mode, context)
|
@@ -1286,7 +1291,8 @@ def get_command_runners(
|
|
1286
1291
|
|
1287
1292
|
# Try to get deployment name from label first
|
1288
1293
|
head_instance_info = instances[pod_name][0]
|
1289
|
-
deployment = head_instance_info.tags.get(
|
1294
|
+
deployment = head_instance_info.tags.get(
|
1295
|
+
k8s_constants.TAG_SKYPILOT_DEPLOYMENT_NAME)
|
1290
1296
|
|
1291
1297
|
node_list = [((namespace, context), pod_name)]
|
1292
1298
|
head_runner = command_runner.KubernetesCommandRunner(
|
@@ -22,8 +22,9 @@ def open_ports(
|
|
22
22
|
) -> None:
|
23
23
|
"""See sky/provision/__init__.py"""
|
24
24
|
assert provider_config is not None, 'provider_config is required'
|
25
|
+
context = kubernetes_utils.get_context_from_config(provider_config)
|
25
26
|
port_mode = network_utils.get_port_mode(
|
26
|
-
provider_config.get('port_mode', None))
|
27
|
+
provider_config.get('port_mode', None), context)
|
27
28
|
ports = list(port_ranges_to_set(ports))
|
28
29
|
if port_mode == kubernetes_enums.KubernetesPortMode.LOADBALANCER:
|
29
30
|
_open_ports_using_loadbalancer(
|
@@ -46,8 +47,10 @@ def _open_ports_using_loadbalancer(
|
|
46
47
|
) -> None:
|
47
48
|
service_name = _LOADBALANCER_SERVICE_NAME.format(
|
48
49
|
cluster_name_on_cloud=cluster_name_on_cloud)
|
50
|
+
context = kubernetes_utils.get_context_from_config(provider_config)
|
49
51
|
content = network_utils.fill_loadbalancer_template(
|
50
52
|
namespace=provider_config.get('namespace', 'default'),
|
53
|
+
context=context,
|
51
54
|
service_name=service_name,
|
52
55
|
ports=ports,
|
53
56
|
selector_key='skypilot-cluster',
|
@@ -59,7 +62,7 @@ def _open_ports_using_loadbalancer(
|
|
59
62
|
|
60
63
|
network_utils.create_or_replace_namespaced_service(
|
61
64
|
namespace=kubernetes_utils.get_namespace_from_config(provider_config),
|
62
|
-
context=
|
65
|
+
context=context,
|
63
66
|
service_name=service_name,
|
64
67
|
service_spec=content['service_spec'])
|
65
68
|
|
@@ -70,6 +73,7 @@ def _open_ports_using_ingress(
|
|
70
73
|
provider_config: Dict[str, Any],
|
71
74
|
) -> None:
|
72
75
|
context = kubernetes_utils.get_context_from_config(provider_config)
|
76
|
+
namespace = kubernetes_utils.get_namespace_from_config(provider_config)
|
73
77
|
# Check if an ingress controller exists
|
74
78
|
if not network_utils.ingress_controller_exists(context):
|
75
79
|
raise Exception(
|
@@ -100,6 +104,7 @@ def _open_ports_using_ingress(
|
|
100
104
|
# multiple rules.
|
101
105
|
content = network_utils.fill_ingress_template(
|
102
106
|
namespace=provider_config.get('namespace', 'default'),
|
107
|
+
context=context,
|
103
108
|
service_details=service_details,
|
104
109
|
ingress_name=f'{cluster_name_on_cloud}-skypilot-ingress',
|
105
110
|
selector_key='skypilot-cluster',
|
@@ -111,9 +116,8 @@ def _open_ports_using_ingress(
|
|
111
116
|
# Update metadata from config
|
112
117
|
kubernetes_utils.merge_custom_metadata(service_spec['metadata'])
|
113
118
|
network_utils.create_or_replace_namespaced_service(
|
114
|
-
namespace=
|
115
|
-
|
116
|
-
context=kubernetes_utils.get_context_from_config(provider_config),
|
119
|
+
namespace=namespace,
|
120
|
+
context=context,
|
117
121
|
service_name=service_name,
|
118
122
|
service_spec=service_spec,
|
119
123
|
)
|
@@ -121,8 +125,8 @@ def _open_ports_using_ingress(
|
|
121
125
|
kubernetes_utils.merge_custom_metadata(content['ingress_spec']['metadata'])
|
122
126
|
# Create or update the single ingress for all services
|
123
127
|
network_utils.create_or_replace_namespaced_ingress(
|
124
|
-
namespace=
|
125
|
-
context=
|
128
|
+
namespace=namespace,
|
129
|
+
context=context,
|
126
130
|
ingress_name=f'{cluster_name_on_cloud}-skypilot-ingress',
|
127
131
|
ingress_spec=content['ingress_spec'],
|
128
132
|
)
|
@@ -135,8 +139,9 @@ def cleanup_ports(
|
|
135
139
|
) -> None:
|
136
140
|
"""See sky/provision/__init__.py"""
|
137
141
|
assert provider_config is not None, 'provider_config is required'
|
142
|
+
context = kubernetes_utils.get_context_from_config(provider_config)
|
138
143
|
port_mode = network_utils.get_port_mode(
|
139
|
-
provider_config.get('port_mode', None))
|
144
|
+
provider_config.get('port_mode', None), context)
|
140
145
|
ports = list(port_ranges_to_set(ports))
|
141
146
|
if port_mode == kubernetes_enums.KubernetesPortMode.LOADBALANCER:
|
142
147
|
_cleanup_ports_for_loadbalancer(
|
@@ -202,8 +207,9 @@ def query_ports(
|
|
202
207
|
"""See sky/provision/__init__.py"""
|
203
208
|
del head_ip # unused
|
204
209
|
assert provider_config is not None, 'provider_config is required'
|
210
|
+
context = kubernetes_utils.get_context_from_config(provider_config)
|
205
211
|
port_mode = network_utils.get_port_mode(
|
206
|
-
provider_config.get('port_mode', None))
|
212
|
+
provider_config.get('port_mode', None), context)
|
207
213
|
ports = list(port_ranges_to_set(ports))
|
208
214
|
|
209
215
|
try:
|
@@ -28,7 +28,8 @@ _LOADBALANCER_TEMPLATE_NAME = 'kubernetes-loadbalancer.yml.j2'
|
|
28
28
|
|
29
29
|
|
30
30
|
def get_port_mode(
|
31
|
-
mode_str: Optional[str]
|
31
|
+
mode_str: Optional[str],
|
32
|
+
context: Optional[str]) -> kubernetes_enums.KubernetesPortMode:
|
32
33
|
"""Get the port mode from the provider config."""
|
33
34
|
|
34
35
|
curr_kube_config = kubernetes_utils.get_current_kube_config_context_name()
|
@@ -38,9 +39,11 @@ def get_port_mode(
|
|
38
39
|
# If running in kind (`sky local up`), use ingress mode
|
39
40
|
return kubernetes_enums.KubernetesPortMode.INGRESS
|
40
41
|
|
41
|
-
mode_str = mode_str or skypilot_config.
|
42
|
-
|
43
|
-
|
42
|
+
mode_str = mode_str or skypilot_config.get_effective_region_config(
|
43
|
+
cloud='kubernetes',
|
44
|
+
region=context,
|
45
|
+
keys=('ports',),
|
46
|
+
default_value=kubernetes_enums.KubernetesPortMode.LOADBALANCER.value)
|
44
47
|
try:
|
45
48
|
port_mode = kubernetes_enums.KubernetesPortMode(mode_str)
|
46
49
|
except ValueError as e:
|
@@ -54,12 +57,16 @@ def get_port_mode(
|
|
54
57
|
|
55
58
|
|
56
59
|
def get_networking_mode(
|
57
|
-
mode_str: Optional[str]
|
60
|
+
mode_str: Optional[str],
|
61
|
+
context: Optional[str],
|
58
62
|
) -> kubernetes_enums.KubernetesNetworkingMode:
|
59
63
|
"""Get the networking mode from the provider config."""
|
60
|
-
mode_str = mode_str or skypilot_config.
|
61
|
-
|
62
|
-
|
64
|
+
mode_str = mode_str or skypilot_config.get_effective_region_config(
|
65
|
+
cloud='kubernetes',
|
66
|
+
region=context,
|
67
|
+
keys=('networking_mode',),
|
68
|
+
default_value=kubernetes_enums.KubernetesNetworkingMode.PORTFORWARD.
|
69
|
+
value)
|
63
70
|
try:
|
64
71
|
networking_mode = kubernetes_enums.KubernetesNetworkingMode.from_str(
|
65
72
|
mode_str)
|
@@ -70,9 +77,9 @@ def get_networking_mode(
|
|
70
77
|
return networking_mode
|
71
78
|
|
72
79
|
|
73
|
-
def fill_loadbalancer_template(namespace: str,
|
74
|
-
ports: List[int],
|
75
|
-
selector_value: str) -> Dict:
|
80
|
+
def fill_loadbalancer_template(namespace: str, context: Optional[str],
|
81
|
+
service_name: str, ports: List[int],
|
82
|
+
selector_key: str, selector_value: str) -> Dict:
|
76
83
|
template_path = os.path.join(sky.__root_dir__, 'templates',
|
77
84
|
_LOADBALANCER_TEMPLATE_NAME)
|
78
85
|
if not os.path.exists(template_path):
|
@@ -81,10 +88,16 @@ def fill_loadbalancer_template(namespace: str, service_name: str,
|
|
81
88
|
|
82
89
|
with open(template_path, 'r', encoding='utf-8') as fin:
|
83
90
|
template = fin.read()
|
84
|
-
annotations = skypilot_config.
|
85
|
-
|
86
|
-
|
87
|
-
('
|
91
|
+
annotations = skypilot_config.get_effective_region_config(
|
92
|
+
cloud='kubernetes',
|
93
|
+
region=context,
|
94
|
+
keys=('custom_metadata', 'annotations'),
|
95
|
+
default_value={})
|
96
|
+
labels = skypilot_config.get_effective_region_config(
|
97
|
+
cloud='kubernetes',
|
98
|
+
region=context,
|
99
|
+
keys=('custom_metadata', 'labels'),
|
100
|
+
default_value={})
|
88
101
|
j2_template = jinja2.Template(template)
|
89
102
|
cont = j2_template.render(
|
90
103
|
namespace=namespace,
|
@@ -99,10 +112,10 @@ def fill_loadbalancer_template(namespace: str, service_name: str,
|
|
99
112
|
return content
|
100
113
|
|
101
114
|
|
102
|
-
def fill_ingress_template(namespace: str,
|
103
|
-
|
104
|
-
|
105
|
-
selector_value: str) -> Dict:
|
115
|
+
def fill_ingress_template(namespace: str, context: Optional[str],
|
116
|
+
service_details: List[Tuple[str, int,
|
117
|
+
str]], ingress_name: str,
|
118
|
+
selector_key: str, selector_value: str) -> Dict:
|
106
119
|
template_path = os.path.join(sky.__root_dir__, 'templates',
|
107
120
|
_INGRESS_TEMPLATE_NAME)
|
108
121
|
if not os.path.exists(template_path):
|
@@ -110,10 +123,16 @@ def fill_ingress_template(namespace: str, service_details: List[Tuple[str, int,
|
|
110
123
|
f'Template "{_INGRESS_TEMPLATE_NAME}" does not exist.')
|
111
124
|
with open(template_path, 'r', encoding='utf-8') as fin:
|
112
125
|
template = fin.read()
|
113
|
-
annotations = skypilot_config.
|
114
|
-
|
115
|
-
|
116
|
-
('
|
126
|
+
annotations = skypilot_config.get_effective_region_config(
|
127
|
+
cloud='kubernetes',
|
128
|
+
region=context,
|
129
|
+
keys=('custom_metadata', 'annotations'),
|
130
|
+
default_value={})
|
131
|
+
labels = skypilot_config.get_effective_region_config(
|
132
|
+
cloud='kubernetes',
|
133
|
+
region=context,
|
134
|
+
keys=('custom_metadata', 'labels'),
|
135
|
+
default_value={})
|
117
136
|
j2_template = jinja2.Template(template)
|
118
137
|
cont = j2_template.render(
|
119
138
|
namespace=namespace,
|
@@ -1190,7 +1190,11 @@ def get_accelerator_label_key_values(
|
|
1190
1190
|
context_display_name = common_utils.removeprefix(
|
1191
1191
|
context, 'ssh-') if (context and is_ssh_node_pool) else context
|
1192
1192
|
|
1193
|
-
autoscaler_type =
|
1193
|
+
autoscaler_type = skypilot_config.get_effective_region_config(
|
1194
|
+
cloud='kubernetes',
|
1195
|
+
region=context,
|
1196
|
+
keys=('autoscaler',),
|
1197
|
+
default_value=None)
|
1194
1198
|
if autoscaler_type is not None:
|
1195
1199
|
# If autoscaler is set in config.yaml, override the label key and value
|
1196
1200
|
# to the autoscaler's format and bypass the GPU checks.
|
@@ -1595,9 +1599,11 @@ def is_kubeconfig_exec_auth(
|
|
1595
1599
|
user_details = next(
|
1596
1600
|
user for user in user_details if user['name'] == target_username)
|
1597
1601
|
|
1598
|
-
remote_identity = skypilot_config.
|
1599
|
-
|
1600
|
-
|
1602
|
+
remote_identity = skypilot_config.get_effective_region_config(
|
1603
|
+
cloud='kubernetes',
|
1604
|
+
region=context,
|
1605
|
+
keys=('remote_identity',),
|
1606
|
+
default_value=schemas.get_default_remote_identity('kubernetes'))
|
1601
1607
|
if ('exec' in user_details.get('user', {}) and remote_identity
|
1602
1608
|
== schemas.RemoteIdentityOptions.LOCAL_CREDENTIALS.value):
|
1603
1609
|
ctx_name = context_obj['name']
|
@@ -2078,7 +2084,7 @@ def setup_ssh_jump_svc(ssh_jump_name: str, namespace: str,
|
|
2078
2084
|
content = fill_ssh_jump_template('', '', ssh_jump_name, service_type.value)
|
2079
2085
|
|
2080
2086
|
# Add custom metadata from config
|
2081
|
-
merge_custom_metadata(content['service_spec']['metadata'])
|
2087
|
+
merge_custom_metadata(content['service_spec']['metadata'], context)
|
2082
2088
|
|
2083
2089
|
# Create service
|
2084
2090
|
try:
|
@@ -2158,7 +2164,7 @@ def setup_ssh_jump_pod(ssh_jump_name: str, ssh_jump_image: str,
|
|
2158
2164
|
|
2159
2165
|
# Add custom metadata to all objects
|
2160
2166
|
for object_type in content.keys():
|
2161
|
-
merge_custom_metadata(content[object_type]['metadata'])
|
2167
|
+
merge_custom_metadata(content[object_type]['metadata'], context)
|
2162
2168
|
|
2163
2169
|
# ServiceAccount
|
2164
2170
|
try:
|
@@ -2370,7 +2376,7 @@ def check_port_forward_mode_dependencies(
|
|
2370
2376
|
return None
|
2371
2377
|
|
2372
2378
|
|
2373
|
-
def get_endpoint_debug_message() -> str:
|
2379
|
+
def get_endpoint_debug_message(context: Optional[str] = None) -> str:
|
2374
2380
|
""" Returns a string message for user to debug Kubernetes port opening
|
2375
2381
|
|
2376
2382
|
Polls the configured ports mode on Kubernetes to produce an
|
@@ -2378,7 +2384,7 @@ def get_endpoint_debug_message() -> str:
|
|
2378
2384
|
|
2379
2385
|
Also checks if the
|
2380
2386
|
"""
|
2381
|
-
port_mode = network_utils.get_port_mode()
|
2387
|
+
port_mode = network_utils.get_port_mode(None, context)
|
2382
2388
|
if port_mode == kubernetes_enums.KubernetesPortMode.INGRESS:
|
2383
2389
|
endpoint_type = 'Ingress'
|
2384
2390
|
debug_cmd = 'kubectl describe ingress && kubectl describe ingressclass'
|
@@ -2396,6 +2402,7 @@ def combine_pod_config_fields(
|
|
2396
2402
|
cluster_yaml_path: str,
|
2397
2403
|
cluster_config_overrides: Dict[str, Any],
|
2398
2404
|
cloud: Optional[clouds.Cloud] = None,
|
2405
|
+
context: Optional[str] = None,
|
2399
2406
|
) -> None:
|
2400
2407
|
"""Adds or updates fields in the YAML with fields from the
|
2401
2408
|
~/.sky/config.yaml's kubernetes.pod_spec dict.
|
@@ -2438,19 +2445,28 @@ def combine_pod_config_fields(
|
|
2438
2445
|
with open(cluster_yaml_path, 'r', encoding='utf-8') as f:
|
2439
2446
|
yaml_content = f.read()
|
2440
2447
|
yaml_obj = yaml.safe_load(yaml_content)
|
2441
|
-
# We don't use override_configs in `
|
2448
|
+
# We don't use override_configs in `get_effective_region_config`, as merging
|
2442
2449
|
# the pod config requires special handling.
|
2443
2450
|
if isinstance(cloud, clouds.SSH):
|
2444
|
-
kubernetes_config = skypilot_config.
|
2445
|
-
|
2446
|
-
|
2447
|
-
|
2448
|
-
'
|
2451
|
+
kubernetes_config = skypilot_config.get_effective_region_config(
|
2452
|
+
cloud='ssh', region=None, keys=('pod_config',), default_value={})
|
2453
|
+
override_pod_config = config_utils.get_cloud_config_value_from_dict(
|
2454
|
+
dict_config=cluster_config_overrides,
|
2455
|
+
cloud='ssh',
|
2456
|
+
keys=('pod_config',),
|
2457
|
+
default_value={})
|
2449
2458
|
else:
|
2450
|
-
kubernetes_config = skypilot_config.
|
2451
|
-
|
2452
|
-
|
2453
|
-
|
2459
|
+
kubernetes_config = skypilot_config.get_effective_region_config(
|
2460
|
+
cloud='kubernetes',
|
2461
|
+
region=context,
|
2462
|
+
keys=('pod_config',),
|
2463
|
+
default_value={})
|
2464
|
+
override_pod_config = config_utils.get_cloud_config_value_from_dict(
|
2465
|
+
dict_config=cluster_config_overrides,
|
2466
|
+
cloud='kubernetes',
|
2467
|
+
region=context,
|
2468
|
+
keys=('pod_config',),
|
2469
|
+
default_value={})
|
2454
2470
|
config_utils.merge_k8s_configs(kubernetes_config, override_pod_config)
|
2455
2471
|
|
2456
2472
|
# Merge the kubernetes config into the YAML for both head and worker nodes.
|
@@ -2462,7 +2478,8 @@ def combine_pod_config_fields(
|
|
2462
2478
|
common_utils.dump_yaml(cluster_yaml_path, yaml_obj)
|
2463
2479
|
|
2464
2480
|
|
2465
|
-
def combine_metadata_fields(cluster_yaml_path: str
|
2481
|
+
def combine_metadata_fields(cluster_yaml_path: str,
|
2482
|
+
context: Optional[str] = None) -> None:
|
2466
2483
|
"""Updates the metadata for all Kubernetes objects created by SkyPilot with
|
2467
2484
|
fields from the ~/.sky/config.yaml's kubernetes.custom_metadata dict.
|
2468
2485
|
|
@@ -2472,8 +2489,11 @@ def combine_metadata_fields(cluster_yaml_path: str) -> None:
|
|
2472
2489
|
with open(cluster_yaml_path, 'r', encoding='utf-8') as f:
|
2473
2490
|
yaml_content = f.read()
|
2474
2491
|
yaml_obj = yaml.safe_load(yaml_content)
|
2475
|
-
custom_metadata = skypilot_config.
|
2476
|
-
|
2492
|
+
custom_metadata = skypilot_config.get_effective_region_config(
|
2493
|
+
cloud='kubernetes',
|
2494
|
+
region=context,
|
2495
|
+
keys=('custom_metadata',),
|
2496
|
+
default_value={})
|
2477
2497
|
|
2478
2498
|
# List of objects in the cluster YAML to be updated
|
2479
2499
|
combination_destinations = [
|
@@ -2496,13 +2516,17 @@ def combine_metadata_fields(cluster_yaml_path: str) -> None:
|
|
2496
2516
|
common_utils.dump_yaml(cluster_yaml_path, yaml_obj)
|
2497
2517
|
|
2498
2518
|
|
2499
|
-
def merge_custom_metadata(original_metadata: Dict[str, Any]
|
2519
|
+
def merge_custom_metadata(original_metadata: Dict[str, Any],
|
2520
|
+
context: Optional[str] = None) -> None:
|
2500
2521
|
"""Merges original metadata with custom_metadata from config
|
2501
2522
|
|
2502
2523
|
Merge is done in-place, so return is not required
|
2503
2524
|
"""
|
2504
|
-
custom_metadata = skypilot_config.
|
2505
|
-
|
2525
|
+
custom_metadata = skypilot_config.get_effective_region_config(
|
2526
|
+
cloud='kubernetes',
|
2527
|
+
region=context,
|
2528
|
+
keys=('custom_metadata',),
|
2529
|
+
default_value={})
|
2506
2530
|
config_utils.merge_k8s_configs(original_metadata, custom_metadata)
|
2507
2531
|
|
2508
2532
|
|
@@ -2556,7 +2580,7 @@ def create_namespace(namespace: str, context: Optional[str]) -> None:
|
|
2556
2580
|
return
|
2557
2581
|
|
2558
2582
|
ns_metadata = dict(name=namespace, labels={'parent': 'skypilot'})
|
2559
|
-
merge_custom_metadata(ns_metadata)
|
2583
|
+
merge_custom_metadata(ns_metadata, context)
|
2560
2584
|
namespace_obj = kubernetes_client.V1Namespace(metadata=ns_metadata)
|
2561
2585
|
try:
|
2562
2586
|
kubernetes.core_api(context).create_namespace(namespace_obj)
|
@@ -2582,15 +2606,14 @@ def get_head_pod_name(cluster_name_on_cloud: str):
|
|
2582
2606
|
return f'{cluster_name_on_cloud}-head'
|
2583
2607
|
|
2584
2608
|
|
2585
|
-
def
|
2586
|
-
|
2587
|
-
|
2588
|
-
|
2589
|
-
|
2590
|
-
|
2591
|
-
|
2592
|
-
|
2593
|
-
return autoscaler_type
|
2609
|
+
def get_custom_config_k8s_contexts() -> List[str]:
|
2610
|
+
"""Returns the list of context names from the config"""
|
2611
|
+
contexts = skypilot_config.get_effective_region_config(
|
2612
|
+
cloud='kubernetes',
|
2613
|
+
region=None,
|
2614
|
+
keys=('context_configs',),
|
2615
|
+
default_value={})
|
2616
|
+
return [*contexts] or []
|
2594
2617
|
|
2595
2618
|
|
2596
2619
|
# Mapping of known spot label keys and values for different cluster types
|
@@ -2602,6 +2625,21 @@ SPOT_LABEL_MAP = {
|
|
2602
2625
|
}
|
2603
2626
|
|
2604
2627
|
|
2628
|
+
def get_autoscaler_type(
|
2629
|
+
context: Optional[str] = None
|
2630
|
+
) -> Optional[kubernetes_enums.KubernetesAutoscalerType]:
|
2631
|
+
"""Returns the autoscaler type by reading from config"""
|
2632
|
+
autoscaler_type = skypilot_config.get_effective_region_config(
|
2633
|
+
cloud='kubernetes',
|
2634
|
+
region=context,
|
2635
|
+
keys=('autoscaler',),
|
2636
|
+
default_value=None)
|
2637
|
+
if autoscaler_type is not None:
|
2638
|
+
autoscaler_type = kubernetes_enums.KubernetesAutoscalerType(
|
2639
|
+
autoscaler_type)
|
2640
|
+
return autoscaler_type
|
2641
|
+
|
2642
|
+
|
2605
2643
|
def get_spot_label(
|
2606
2644
|
context: Optional[str] = None) -> Tuple[Optional[str], Optional[str]]:
|
2607
2645
|
"""Get the spot label key and value for using spot instances, if supported.
|
@@ -2625,7 +2663,7 @@ def get_spot_label(
|
|
2625
2663
|
|
2626
2664
|
# Check if autoscaler is configured. Allow spot instances if autoscaler type
|
2627
2665
|
# is known to support spot instances.
|
2628
|
-
autoscaler_type = get_autoscaler_type()
|
2666
|
+
autoscaler_type = get_autoscaler_type(context=context)
|
2629
2667
|
if autoscaler_type == kubernetes_enums.KubernetesAutoscalerType.GKE:
|
2630
2668
|
return SPOT_LABEL_MAP[autoscaler_type.value]
|
2631
2669
|
|