skypilot-nightly 1.0.0.dev2024053101__py3-none-any.whl → 1.0.0.dev2025022801__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 +64 -32
- sky/adaptors/aws.py +23 -6
- sky/adaptors/azure.py +432 -15
- sky/adaptors/cloudflare.py +5 -5
- sky/adaptors/common.py +19 -9
- sky/adaptors/do.py +20 -0
- sky/adaptors/gcp.py +3 -2
- sky/adaptors/kubernetes.py +122 -88
- sky/adaptors/nebius.py +100 -0
- sky/adaptors/oci.py +39 -1
- sky/adaptors/vast.py +29 -0
- sky/admin_policy.py +101 -0
- sky/authentication.py +117 -98
- sky/backends/backend.py +52 -20
- sky/backends/backend_utils.py +669 -557
- sky/backends/cloud_vm_ray_backend.py +1099 -808
- sky/backends/local_docker_backend.py +14 -8
- sky/backends/wheel_utils.py +38 -20
- sky/benchmark/benchmark_utils.py +22 -23
- sky/check.py +76 -27
- sky/cli.py +1586 -1139
- sky/client/__init__.py +1 -0
- sky/client/cli.py +5683 -0
- sky/client/common.py +345 -0
- sky/client/sdk.py +1765 -0
- sky/cloud_stores.py +283 -19
- sky/clouds/__init__.py +7 -2
- sky/clouds/aws.py +303 -112
- sky/clouds/azure.py +185 -179
- sky/clouds/cloud.py +115 -37
- sky/clouds/cudo.py +29 -22
- sky/clouds/do.py +313 -0
- sky/clouds/fluidstack.py +44 -54
- sky/clouds/gcp.py +206 -65
- sky/clouds/ibm.py +26 -21
- sky/clouds/kubernetes.py +345 -91
- sky/clouds/lambda_cloud.py +40 -29
- sky/clouds/nebius.py +297 -0
- sky/clouds/oci.py +129 -90
- sky/clouds/paperspace.py +22 -18
- sky/clouds/runpod.py +53 -34
- sky/clouds/scp.py +28 -24
- sky/clouds/service_catalog/__init__.py +19 -13
- sky/clouds/service_catalog/aws_catalog.py +29 -12
- sky/clouds/service_catalog/azure_catalog.py +33 -6
- sky/clouds/service_catalog/common.py +95 -75
- sky/clouds/service_catalog/constants.py +3 -3
- sky/clouds/service_catalog/cudo_catalog.py +13 -3
- sky/clouds/service_catalog/data_fetchers/fetch_aws.py +36 -21
- sky/clouds/service_catalog/data_fetchers/fetch_azure.py +31 -4
- sky/clouds/service_catalog/data_fetchers/fetch_cudo.py +8 -117
- sky/clouds/service_catalog/data_fetchers/fetch_fluidstack.py +197 -44
- sky/clouds/service_catalog/data_fetchers/fetch_gcp.py +224 -36
- sky/clouds/service_catalog/data_fetchers/fetch_lambda_cloud.py +44 -24
- sky/clouds/service_catalog/data_fetchers/fetch_vast.py +147 -0
- sky/clouds/service_catalog/data_fetchers/fetch_vsphere.py +1 -1
- sky/clouds/service_catalog/do_catalog.py +111 -0
- sky/clouds/service_catalog/fluidstack_catalog.py +2 -2
- sky/clouds/service_catalog/gcp_catalog.py +16 -2
- sky/clouds/service_catalog/ibm_catalog.py +2 -2
- sky/clouds/service_catalog/kubernetes_catalog.py +192 -70
- sky/clouds/service_catalog/lambda_catalog.py +8 -3
- sky/clouds/service_catalog/nebius_catalog.py +116 -0
- sky/clouds/service_catalog/oci_catalog.py +31 -4
- sky/clouds/service_catalog/paperspace_catalog.py +2 -2
- sky/clouds/service_catalog/runpod_catalog.py +2 -2
- sky/clouds/service_catalog/scp_catalog.py +2 -2
- sky/clouds/service_catalog/vast_catalog.py +104 -0
- sky/clouds/service_catalog/vsphere_catalog.py +2 -2
- sky/clouds/utils/aws_utils.py +65 -0
- sky/clouds/utils/azure_utils.py +91 -0
- sky/clouds/utils/gcp_utils.py +5 -9
- sky/clouds/utils/oci_utils.py +47 -5
- sky/clouds/utils/scp_utils.py +4 -3
- sky/clouds/vast.py +280 -0
- sky/clouds/vsphere.py +22 -18
- sky/core.py +361 -107
- sky/dag.py +41 -28
- sky/data/data_transfer.py +37 -0
- sky/data/data_utils.py +211 -32
- sky/data/mounting_utils.py +182 -30
- sky/data/storage.py +2118 -270
- sky/data/storage_utils.py +126 -5
- sky/exceptions.py +179 -8
- sky/execution.py +158 -85
- sky/global_user_state.py +150 -34
- sky/jobs/__init__.py +12 -10
- sky/jobs/client/__init__.py +0 -0
- sky/jobs/client/sdk.py +302 -0
- sky/jobs/constants.py +49 -11
- sky/jobs/controller.py +161 -99
- sky/jobs/dashboard/dashboard.py +171 -25
- sky/jobs/dashboard/templates/index.html +572 -60
- sky/jobs/recovery_strategy.py +157 -156
- sky/jobs/scheduler.py +307 -0
- sky/jobs/server/__init__.py +1 -0
- sky/jobs/server/core.py +598 -0
- sky/jobs/server/dashboard_utils.py +69 -0
- sky/jobs/server/server.py +190 -0
- sky/jobs/state.py +627 -122
- sky/jobs/utils.py +615 -206
- sky/models.py +27 -0
- sky/optimizer.py +142 -83
- sky/provision/__init__.py +20 -5
- sky/provision/aws/config.py +124 -42
- sky/provision/aws/instance.py +130 -53
- sky/provision/azure/__init__.py +7 -0
- sky/{skylet/providers → provision}/azure/azure-config-template.json +19 -7
- sky/provision/azure/config.py +220 -0
- sky/provision/azure/instance.py +1012 -37
- sky/provision/common.py +31 -3
- sky/provision/constants.py +25 -0
- sky/provision/cudo/__init__.py +2 -1
- sky/provision/cudo/cudo_utils.py +112 -0
- sky/provision/cudo/cudo_wrapper.py +37 -16
- sky/provision/cudo/instance.py +28 -12
- sky/provision/do/__init__.py +11 -0
- sky/provision/do/config.py +14 -0
- sky/provision/do/constants.py +10 -0
- sky/provision/do/instance.py +287 -0
- sky/provision/do/utils.py +301 -0
- sky/provision/docker_utils.py +82 -46
- sky/provision/fluidstack/fluidstack_utils.py +57 -125
- sky/provision/fluidstack/instance.py +15 -43
- sky/provision/gcp/config.py +19 -9
- sky/provision/gcp/constants.py +7 -1
- sky/provision/gcp/instance.py +55 -34
- sky/provision/gcp/instance_utils.py +339 -80
- sky/provision/gcp/mig_utils.py +210 -0
- sky/provision/instance_setup.py +172 -133
- sky/provision/kubernetes/__init__.py +1 -0
- sky/provision/kubernetes/config.py +104 -90
- sky/provision/kubernetes/constants.py +8 -0
- sky/provision/kubernetes/instance.py +680 -325
- sky/provision/kubernetes/manifests/smarter-device-manager-daemonset.yaml +3 -0
- sky/provision/kubernetes/network.py +54 -20
- sky/provision/kubernetes/network_utils.py +70 -21
- sky/provision/kubernetes/utils.py +1370 -251
- sky/provision/lambda_cloud/__init__.py +11 -0
- sky/provision/lambda_cloud/config.py +10 -0
- sky/provision/lambda_cloud/instance.py +265 -0
- sky/{clouds/utils → provision/lambda_cloud}/lambda_utils.py +24 -23
- sky/provision/logging.py +1 -1
- sky/provision/nebius/__init__.py +11 -0
- sky/provision/nebius/config.py +11 -0
- sky/provision/nebius/instance.py +285 -0
- sky/provision/nebius/utils.py +318 -0
- sky/provision/oci/__init__.py +15 -0
- sky/provision/oci/config.py +51 -0
- sky/provision/oci/instance.py +436 -0
- sky/provision/oci/query_utils.py +681 -0
- sky/provision/paperspace/constants.py +6 -0
- sky/provision/paperspace/instance.py +4 -3
- sky/provision/paperspace/utils.py +2 -0
- sky/provision/provisioner.py +207 -130
- sky/provision/runpod/__init__.py +1 -0
- sky/provision/runpod/api/__init__.py +3 -0
- sky/provision/runpod/api/commands.py +119 -0
- sky/provision/runpod/api/pods.py +142 -0
- sky/provision/runpod/instance.py +64 -8
- sky/provision/runpod/utils.py +239 -23
- sky/provision/vast/__init__.py +10 -0
- sky/provision/vast/config.py +11 -0
- sky/provision/vast/instance.py +247 -0
- sky/provision/vast/utils.py +162 -0
- sky/provision/vsphere/common/vim_utils.py +1 -1
- sky/provision/vsphere/instance.py +8 -18
- sky/provision/vsphere/vsphere_utils.py +1 -1
- sky/resources.py +247 -102
- sky/serve/__init__.py +9 -9
- sky/serve/autoscalers.py +361 -299
- sky/serve/client/__init__.py +0 -0
- sky/serve/client/sdk.py +366 -0
- sky/serve/constants.py +12 -3
- sky/serve/controller.py +106 -36
- sky/serve/load_balancer.py +63 -12
- sky/serve/load_balancing_policies.py +84 -2
- sky/serve/replica_managers.py +42 -34
- sky/serve/serve_state.py +62 -32
- sky/serve/serve_utils.py +271 -160
- sky/serve/server/__init__.py +0 -0
- sky/serve/{core.py → server/core.py} +271 -90
- sky/serve/server/server.py +112 -0
- sky/serve/service.py +52 -16
- sky/serve/service_spec.py +95 -32
- sky/server/__init__.py +1 -0
- sky/server/common.py +430 -0
- sky/server/constants.py +21 -0
- sky/server/html/log.html +174 -0
- sky/server/requests/__init__.py +0 -0
- sky/server/requests/executor.py +472 -0
- sky/server/requests/payloads.py +487 -0
- sky/server/requests/queues/__init__.py +0 -0
- sky/server/requests/queues/mp_queue.py +76 -0
- sky/server/requests/requests.py +567 -0
- sky/server/requests/serializers/__init__.py +0 -0
- sky/server/requests/serializers/decoders.py +192 -0
- sky/server/requests/serializers/encoders.py +166 -0
- sky/server/server.py +1106 -0
- sky/server/stream_utils.py +141 -0
- sky/setup_files/MANIFEST.in +2 -5
- sky/setup_files/dependencies.py +159 -0
- sky/setup_files/setup.py +14 -125
- sky/sky_logging.py +59 -14
- sky/skylet/autostop_lib.py +2 -2
- sky/skylet/constants.py +183 -50
- sky/skylet/events.py +22 -10
- sky/skylet/job_lib.py +403 -258
- sky/skylet/log_lib.py +111 -71
- sky/skylet/log_lib.pyi +6 -0
- sky/skylet/providers/command_runner.py +6 -8
- sky/skylet/providers/ibm/node_provider.py +2 -2
- sky/skylet/providers/scp/config.py +11 -3
- sky/skylet/providers/scp/node_provider.py +8 -8
- sky/skylet/skylet.py +3 -1
- sky/skylet/subprocess_daemon.py +69 -17
- sky/skypilot_config.py +119 -57
- sky/task.py +205 -64
- sky/templates/aws-ray.yml.j2 +37 -7
- sky/templates/azure-ray.yml.j2 +27 -82
- sky/templates/cudo-ray.yml.j2 +7 -3
- sky/templates/do-ray.yml.j2 +98 -0
- sky/templates/fluidstack-ray.yml.j2 +7 -4
- sky/templates/gcp-ray.yml.j2 +26 -6
- sky/templates/ibm-ray.yml.j2 +3 -2
- sky/templates/jobs-controller.yaml.j2 +46 -11
- sky/templates/kubernetes-ingress.yml.j2 +7 -0
- sky/templates/kubernetes-loadbalancer.yml.j2 +7 -0
- sky/templates/{kubernetes-port-forward-proxy-command.sh.j2 → kubernetes-port-forward-proxy-command.sh} +51 -7
- sky/templates/kubernetes-ray.yml.j2 +292 -25
- sky/templates/lambda-ray.yml.j2 +30 -40
- sky/templates/nebius-ray.yml.j2 +79 -0
- sky/templates/oci-ray.yml.j2 +18 -57
- sky/templates/paperspace-ray.yml.j2 +10 -6
- sky/templates/runpod-ray.yml.j2 +26 -4
- sky/templates/scp-ray.yml.j2 +3 -2
- sky/templates/sky-serve-controller.yaml.j2 +12 -1
- sky/templates/skypilot-server-kubernetes-proxy.sh +36 -0
- sky/templates/vast-ray.yml.j2 +70 -0
- sky/templates/vsphere-ray.yml.j2 +8 -3
- sky/templates/websocket_proxy.py +64 -0
- sky/usage/constants.py +10 -1
- sky/usage/usage_lib.py +130 -37
- sky/utils/accelerator_registry.py +35 -51
- sky/utils/admin_policy_utils.py +147 -0
- sky/utils/annotations.py +51 -0
- sky/utils/cli_utils/status_utils.py +81 -23
- sky/utils/cluster_utils.py +356 -0
- sky/utils/command_runner.py +452 -89
- sky/utils/command_runner.pyi +77 -3
- sky/utils/common.py +54 -0
- sky/utils/common_utils.py +319 -108
- sky/utils/config_utils.py +204 -0
- sky/utils/control_master_utils.py +48 -0
- sky/utils/controller_utils.py +548 -266
- sky/utils/dag_utils.py +93 -32
- sky/utils/db_utils.py +18 -4
- sky/utils/env_options.py +29 -7
- sky/utils/kubernetes/create_cluster.sh +8 -60
- sky/utils/kubernetes/deploy_remote_cluster.sh +243 -0
- sky/utils/kubernetes/exec_kubeconfig_converter.py +73 -0
- sky/utils/kubernetes/generate_kubeconfig.sh +336 -0
- sky/utils/kubernetes/gpu_labeler.py +4 -4
- sky/utils/kubernetes/k8s_gpu_labeler_job.yaml +4 -3
- sky/utils/kubernetes/kubernetes_deploy_utils.py +228 -0
- sky/utils/kubernetes/rsync_helper.sh +24 -0
- sky/utils/kubernetes/ssh_jump_lifecycle_manager.py +1 -1
- sky/utils/log_utils.py +240 -33
- sky/utils/message_utils.py +81 -0
- sky/utils/registry.py +127 -0
- sky/utils/resources_utils.py +94 -22
- sky/utils/rich_utils.py +247 -18
- sky/utils/schemas.py +284 -64
- sky/{status_lib.py → utils/status_lib.py} +12 -7
- sky/utils/subprocess_utils.py +212 -46
- sky/utils/timeline.py +12 -7
- sky/utils/ux_utils.py +168 -15
- skypilot_nightly-1.0.0.dev2025022801.dist-info/METADATA +363 -0
- skypilot_nightly-1.0.0.dev2025022801.dist-info/RECORD +352 -0
- {skypilot_nightly-1.0.0.dev2024053101.dist-info → skypilot_nightly-1.0.0.dev2025022801.dist-info}/WHEEL +1 -1
- sky/clouds/cloud_registry.py +0 -31
- sky/jobs/core.py +0 -330
- sky/skylet/providers/azure/__init__.py +0 -2
- sky/skylet/providers/azure/azure-vm-template.json +0 -301
- sky/skylet/providers/azure/config.py +0 -170
- sky/skylet/providers/azure/node_provider.py +0 -466
- sky/skylet/providers/lambda_cloud/__init__.py +0 -2
- sky/skylet/providers/lambda_cloud/node_provider.py +0 -320
- sky/skylet/providers/oci/__init__.py +0 -2
- sky/skylet/providers/oci/node_provider.py +0 -488
- sky/skylet/providers/oci/query_helper.py +0 -383
- sky/skylet/providers/oci/utils.py +0 -21
- sky/utils/cluster_yaml_utils.py +0 -24
- sky/utils/kubernetes/generate_static_kubeconfig.sh +0 -137
- skypilot_nightly-1.0.0.dev2024053101.dist-info/METADATA +0 -315
- skypilot_nightly-1.0.0.dev2024053101.dist-info/RECORD +0 -275
- {skypilot_nightly-1.0.0.dev2024053101.dist-info → skypilot_nightly-1.0.0.dev2025022801.dist-info}/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev2024053101.dist-info → skypilot_nightly-1.0.0.dev2025022801.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev2024053101.dist-info → skypilot_nightly-1.0.0.dev2025022801.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,204 @@
|
|
1
|
+
"""Utilities for nested config."""
|
2
|
+
import copy
|
3
|
+
from typing import Any, Dict, List, Optional, Tuple
|
4
|
+
|
5
|
+
from sky import sky_logging
|
6
|
+
|
7
|
+
logger = sky_logging.init_logger(__name__)
|
8
|
+
|
9
|
+
|
10
|
+
class Config(Dict[str, Any]):
|
11
|
+
"""SkyPilot config that supports setting/getting values with nested keys."""
|
12
|
+
|
13
|
+
def get_nested(
|
14
|
+
self,
|
15
|
+
keys: Tuple[str, ...],
|
16
|
+
default_value: Any,
|
17
|
+
override_configs: Optional[Dict[str, Any]] = None,
|
18
|
+
allowed_override_keys: Optional[List[Tuple[str, ...]]] = None,
|
19
|
+
disallowed_override_keys: Optional[List[Tuple[str,
|
20
|
+
...]]] = None) -> Any:
|
21
|
+
"""Gets a nested key.
|
22
|
+
|
23
|
+
If any key is not found, or any intermediate key does not point to a
|
24
|
+
dict value, returns 'default_value'.
|
25
|
+
|
26
|
+
Args:
|
27
|
+
keys: A tuple of strings representing the nested keys.
|
28
|
+
default_value: The default value to return if the key is not found.
|
29
|
+
override_configs: A dict of override configs with the same schema as
|
30
|
+
the config file, but only containing the keys to override.
|
31
|
+
allowed_override_keys: A list of keys that are allowed to be
|
32
|
+
overridden.
|
33
|
+
disallowed_override_keys: A list of keys that are disallowed to be
|
34
|
+
overridden.
|
35
|
+
|
36
|
+
Returns:
|
37
|
+
The value of the nested key, or 'default_value' if not found.
|
38
|
+
"""
|
39
|
+
config = copy.deepcopy(self)
|
40
|
+
if override_configs is not None:
|
41
|
+
config = _recursive_update(config, override_configs,
|
42
|
+
allowed_override_keys,
|
43
|
+
disallowed_override_keys)
|
44
|
+
return _get_nested(config, keys, default_value, pop=False)
|
45
|
+
|
46
|
+
def set_nested(self, keys: Tuple[str, ...], value: Any) -> None:
|
47
|
+
"""In-place sets a nested key to value.
|
48
|
+
|
49
|
+
Like get_nested(), if any key is not found, this will not raise an
|
50
|
+
error.
|
51
|
+
"""
|
52
|
+
override = {}
|
53
|
+
for i, key in enumerate(reversed(keys)):
|
54
|
+
if i == 0:
|
55
|
+
override = {key: value}
|
56
|
+
else:
|
57
|
+
override = {key: override}
|
58
|
+
_recursive_update(self, override)
|
59
|
+
|
60
|
+
def pop_nested(self, keys: Tuple[str, ...], default_value: Any) -> Any:
|
61
|
+
"""Pops a nested key."""
|
62
|
+
return _get_nested(self, keys, default_value, pop=True)
|
63
|
+
|
64
|
+
@classmethod
|
65
|
+
def from_dict(cls, config: Optional[Dict[str, Any]]) -> 'Config':
|
66
|
+
if config is None:
|
67
|
+
return cls()
|
68
|
+
return cls(**config)
|
69
|
+
|
70
|
+
|
71
|
+
def _check_allowed_and_disallowed_override_keys(
|
72
|
+
key: str,
|
73
|
+
allowed_override_keys: Optional[List[Tuple[str, ...]]] = None,
|
74
|
+
disallowed_override_keys: Optional[List[Tuple[str, ...]]] = None
|
75
|
+
) -> Tuple[Optional[List[Tuple[str, ...]]], Optional[List[Tuple[str, ...]]]]:
|
76
|
+
allowed_keys_with_matched_prefix: Optional[List[Tuple[str, ...]]] = []
|
77
|
+
disallowed_keys_with_matched_prefix: Optional[List[Tuple[str, ...]]] = []
|
78
|
+
if allowed_override_keys is not None:
|
79
|
+
for nested_key in allowed_override_keys:
|
80
|
+
if key == nested_key[0]:
|
81
|
+
if len(nested_key) == 1:
|
82
|
+
# Allowed key is fully matched, no need to check further.
|
83
|
+
allowed_keys_with_matched_prefix = None
|
84
|
+
break
|
85
|
+
assert allowed_keys_with_matched_prefix is not None
|
86
|
+
allowed_keys_with_matched_prefix.append(nested_key[1:])
|
87
|
+
if (allowed_keys_with_matched_prefix is not None and
|
88
|
+
not allowed_keys_with_matched_prefix):
|
89
|
+
raise ValueError(f'Key {key} is not in allowed override keys: '
|
90
|
+
f'{allowed_override_keys}')
|
91
|
+
else:
|
92
|
+
allowed_keys_with_matched_prefix = None
|
93
|
+
|
94
|
+
if disallowed_override_keys is not None:
|
95
|
+
for nested_key in disallowed_override_keys:
|
96
|
+
if key == nested_key[0]:
|
97
|
+
if len(nested_key) == 1:
|
98
|
+
raise ValueError(
|
99
|
+
f'Key {key} is in disallowed override keys: '
|
100
|
+
f'{disallowed_override_keys}')
|
101
|
+
assert disallowed_keys_with_matched_prefix is not None
|
102
|
+
disallowed_keys_with_matched_prefix.append(nested_key[1:])
|
103
|
+
else:
|
104
|
+
disallowed_keys_with_matched_prefix = None
|
105
|
+
return allowed_keys_with_matched_prefix, disallowed_keys_with_matched_prefix
|
106
|
+
|
107
|
+
|
108
|
+
def _recursive_update(
|
109
|
+
base_config: Config,
|
110
|
+
override_config: Dict[str, Any],
|
111
|
+
allowed_override_keys: Optional[List[Tuple[str, ...]]] = None,
|
112
|
+
disallowed_override_keys: Optional[List[Tuple[str,
|
113
|
+
...]]] = None) -> Config:
|
114
|
+
"""Recursively updates base configuration with override configuration"""
|
115
|
+
for key, value in override_config.items():
|
116
|
+
(next_allowed_override_keys, next_disallowed_override_keys
|
117
|
+
) = _check_allowed_and_disallowed_override_keys(
|
118
|
+
key, allowed_override_keys, disallowed_override_keys)
|
119
|
+
if key == 'kubernetes' and key in base_config:
|
120
|
+
merge_k8s_configs(base_config[key], value,
|
121
|
+
next_allowed_override_keys,
|
122
|
+
next_disallowed_override_keys)
|
123
|
+
elif (isinstance(value, dict) and key in base_config and
|
124
|
+
isinstance(base_config[key], dict)):
|
125
|
+
_recursive_update(base_config[key], value,
|
126
|
+
next_allowed_override_keys,
|
127
|
+
next_disallowed_override_keys)
|
128
|
+
else:
|
129
|
+
base_config[key] = value
|
130
|
+
return base_config
|
131
|
+
|
132
|
+
|
133
|
+
def _get_nested(configs: Optional[Dict[str, Any]],
|
134
|
+
keys: Tuple[str, ...],
|
135
|
+
default_value: Any,
|
136
|
+
pop: bool = False) -> Any:
|
137
|
+
if configs is None:
|
138
|
+
return default_value
|
139
|
+
curr = configs
|
140
|
+
for i, key in enumerate(keys):
|
141
|
+
if isinstance(curr, dict) and key in curr:
|
142
|
+
value = curr[key]
|
143
|
+
if i == len(keys) - 1:
|
144
|
+
if pop:
|
145
|
+
curr.pop(key, default_value)
|
146
|
+
curr = value
|
147
|
+
else:
|
148
|
+
return default_value
|
149
|
+
logger.debug(f'User config: {".".join(keys)} -> {curr}')
|
150
|
+
return curr
|
151
|
+
|
152
|
+
|
153
|
+
def merge_k8s_configs(
|
154
|
+
base_config: Dict[Any, Any],
|
155
|
+
override_config: Dict[Any, Any],
|
156
|
+
allowed_override_keys: Optional[List[Tuple[str, ...]]] = None,
|
157
|
+
disallowed_override_keys: Optional[List[Tuple[str,
|
158
|
+
...]]] = None) -> None:
|
159
|
+
"""Merge two configs into the base_config.
|
160
|
+
|
161
|
+
Updates nested dictionaries instead of replacing them.
|
162
|
+
If a list is encountered, it will be appended to the base_config list.
|
163
|
+
|
164
|
+
An exception is when the key is 'containers', in which case the
|
165
|
+
first container in the list will be fetched and merge_dict will be
|
166
|
+
called on it with the first container in the base_config list.
|
167
|
+
"""
|
168
|
+
for key, value in override_config.items():
|
169
|
+
(next_allowed_override_keys, next_disallowed_override_keys
|
170
|
+
) = _check_allowed_and_disallowed_override_keys(
|
171
|
+
key, allowed_override_keys, disallowed_override_keys)
|
172
|
+
if isinstance(value, dict) and key in base_config:
|
173
|
+
merge_k8s_configs(base_config[key], value,
|
174
|
+
next_allowed_override_keys,
|
175
|
+
next_disallowed_override_keys)
|
176
|
+
elif isinstance(value, list) and key in base_config:
|
177
|
+
assert isinstance(base_config[key], list), \
|
178
|
+
f'Expected {key} to be a list, found {base_config[key]}'
|
179
|
+
if key in ['containers', 'imagePullSecrets']:
|
180
|
+
# If the key is 'containers' or 'imagePullSecrets, we take the
|
181
|
+
# first and only container/secret in the list and merge it, as
|
182
|
+
# we only support one container per pod.
|
183
|
+
assert len(value) == 1, \
|
184
|
+
f'Expected only one container, found {value}'
|
185
|
+
merge_k8s_configs(base_config[key][0], value[0],
|
186
|
+
next_allowed_override_keys,
|
187
|
+
next_disallowed_override_keys)
|
188
|
+
elif key in ['volumes', 'volumeMounts']:
|
189
|
+
# If the key is 'volumes' or 'volumeMounts', we search for
|
190
|
+
# item with the same name and merge it.
|
191
|
+
for new_volume in value:
|
192
|
+
new_volume_name = new_volume.get('name')
|
193
|
+
if new_volume_name is not None:
|
194
|
+
destination_volume = next(
|
195
|
+
(v for v in base_config[key]
|
196
|
+
if v.get('name') == new_volume_name), None)
|
197
|
+
if destination_volume is not None:
|
198
|
+
merge_k8s_configs(destination_volume, new_volume)
|
199
|
+
else:
|
200
|
+
base_config[key].append(new_volume)
|
201
|
+
else:
|
202
|
+
base_config[key].extend(value)
|
203
|
+
else:
|
204
|
+
base_config[key] = value
|
@@ -0,0 +1,48 @@
|
|
1
|
+
"""Utils to check if the ssh control master should be disabled."""
|
2
|
+
|
3
|
+
from sky import sky_logging
|
4
|
+
from sky.utils import annotations
|
5
|
+
from sky.utils import subprocess_utils
|
6
|
+
|
7
|
+
logger = sky_logging.init_logger(__name__)
|
8
|
+
|
9
|
+
|
10
|
+
def is_tmp_9p_filesystem() -> bool:
|
11
|
+
"""Check if the /tmp filesystem is 9p.
|
12
|
+
|
13
|
+
Returns:
|
14
|
+
bool: True if the /tmp filesystem is 9p, False otherwise.
|
15
|
+
"""
|
16
|
+
|
17
|
+
result = subprocess_utils.run(['df', '-T', '/tmp'],
|
18
|
+
capture_output=True,
|
19
|
+
text=True,
|
20
|
+
shell=None,
|
21
|
+
check=False,
|
22
|
+
executable=None)
|
23
|
+
|
24
|
+
if result.returncode != 0:
|
25
|
+
return False
|
26
|
+
|
27
|
+
filesystem_infos = result.stdout.strip().split('\n')
|
28
|
+
if len(filesystem_infos) < 2:
|
29
|
+
return False
|
30
|
+
filesystem_types = filesystem_infos[1].split()
|
31
|
+
if len(filesystem_types) < 2:
|
32
|
+
return False
|
33
|
+
return filesystem_types[1].lower() == '9p'
|
34
|
+
|
35
|
+
|
36
|
+
@annotations.lru_cache(scope='global')
|
37
|
+
def should_disable_control_master() -> bool:
|
38
|
+
"""Whether disable ssh control master based on file system.
|
39
|
+
|
40
|
+
Returns:
|
41
|
+
bool: True if the ssh control master should be disabled,
|
42
|
+
False otherwise.
|
43
|
+
"""
|
44
|
+
if is_tmp_9p_filesystem():
|
45
|
+
return True
|
46
|
+
# there may be additional criteria to disable ssh control master
|
47
|
+
# in the future. They should be checked here
|
48
|
+
return False
|