skypilot-nightly 1.0.0.dev20250119__py3-none-any.whl → 1.0.0.dev20250120__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/serve/autoscalers.py +359 -301
- sky/serve/controller.py +10 -8
- sky/serve/core.py +54 -2
- sky/serve/load_balancer.py +27 -10
- sky/serve/serve_state.py +10 -5
- sky/serve/serve_utils.py +28 -1
- sky/serve/service.py +4 -3
- sky/serve/service_spec.py +31 -0
- sky/templates/sky-serve-controller.yaml.j2 +4 -0
- sky/utils/schemas.py +13 -0
- {skypilot_nightly-1.0.0.dev20250119.dist-info → skypilot_nightly-1.0.0.dev20250120.dist-info}/METADATA +1 -1
- {skypilot_nightly-1.0.0.dev20250119.dist-info → skypilot_nightly-1.0.0.dev20250120.dist-info}/RECORD +17 -17
- {skypilot_nightly-1.0.0.dev20250119.dist-info → skypilot_nightly-1.0.0.dev20250120.dist-info}/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev20250119.dist-info → skypilot_nightly-1.0.0.dev20250120.dist-info}/WHEEL +0 -0
- {skypilot_nightly-1.0.0.dev20250119.dist-info → skypilot_nightly-1.0.0.dev20250120.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20250119.dist-info → skypilot_nightly-1.0.0.dev20250120.dist-info}/top_level.txt +0 -0
sky/serve/controller.py
CHANGED
@@ -67,9 +67,16 @@ class SkyServeController:
|
|
67
67
|
try:
|
68
68
|
replica_infos = serve_state.get_replica_infos(
|
69
69
|
self._service_name)
|
70
|
+
# Use the active versions set by replica manager to make
|
71
|
+
# sure we only scale down the outdated replicas that are
|
72
|
+
# not used by the load balancer.
|
73
|
+
record = serve_state.get_service_from_name(self._service_name)
|
74
|
+
assert record is not None, ('No service record found for '
|
75
|
+
f'{self._service_name}')
|
76
|
+
active_versions = record['active_versions']
|
70
77
|
logger.info(f'All replica info: {replica_infos}')
|
71
|
-
scaling_options = self._autoscaler.
|
72
|
-
replica_infos)
|
78
|
+
scaling_options = self._autoscaler.generate_scaling_decisions(
|
79
|
+
replica_infos, active_versions)
|
73
80
|
for scaling_option in scaling_options:
|
74
81
|
logger.info(f'Scaling option received: {scaling_option}')
|
75
82
|
if (scaling_option.operator ==
|
@@ -77,15 +84,10 @@ class SkyServeController:
|
|
77
84
|
assert (scaling_option.target is None or isinstance(
|
78
85
|
scaling_option.target, dict)), scaling_option
|
79
86
|
self._replica_manager.scale_up(scaling_option.target)
|
80
|
-
|
81
|
-
autoscalers.AutoscalerDecisionOperator.SCALE_DOWN):
|
87
|
+
else:
|
82
88
|
assert isinstance(scaling_option.target,
|
83
89
|
int), scaling_option
|
84
90
|
self._replica_manager.scale_down(scaling_option.target)
|
85
|
-
else:
|
86
|
-
with ux_utils.enable_traceback():
|
87
|
-
logger.error('Error in scaling_option.operator: '
|
88
|
-
f'{scaling_option.operator}')
|
89
91
|
except Exception as e: # pylint: disable=broad-except
|
90
92
|
# No matter what error happens, we should keep the
|
91
93
|
# monitor running.
|
sky/serve/core.py
CHANGED
@@ -95,6 +95,38 @@ def _validate_service_task(task: 'sky.Task') -> None:
|
|
95
95
|
'Please specify the same port instead.')
|
96
96
|
|
97
97
|
|
98
|
+
def _rewrite_tls_credential_paths_and_get_tls_env_vars(
|
99
|
+
service_name: str, task: 'sky.Task') -> Dict[str, Any]:
|
100
|
+
"""Rewrite the paths of TLS credentials in the task.
|
101
|
+
|
102
|
+
Args:
|
103
|
+
service_name: Name of the service.
|
104
|
+
task: sky.Task to rewrite.
|
105
|
+
|
106
|
+
Returns:
|
107
|
+
The generated template variables for TLS.
|
108
|
+
"""
|
109
|
+
service_spec = task.service
|
110
|
+
# Already checked by _validate_service_task
|
111
|
+
assert service_spec is not None
|
112
|
+
if service_spec.tls_credential is None:
|
113
|
+
return {'use_tls': False}
|
114
|
+
remote_tls_keyfile = (
|
115
|
+
serve_utils.generate_remote_tls_keyfile_name(service_name))
|
116
|
+
remote_tls_certfile = (
|
117
|
+
serve_utils.generate_remote_tls_certfile_name(service_name))
|
118
|
+
tls_template_vars = {
|
119
|
+
'use_tls': True,
|
120
|
+
'remote_tls_keyfile': remote_tls_keyfile,
|
121
|
+
'remote_tls_certfile': remote_tls_certfile,
|
122
|
+
'local_tls_keyfile': service_spec.tls_credential.keyfile,
|
123
|
+
'local_tls_certfile': service_spec.tls_credential.certfile,
|
124
|
+
}
|
125
|
+
service_spec.tls_credential = serve_utils.TLSCredential(
|
126
|
+
remote_tls_keyfile, remote_tls_certfile)
|
127
|
+
return tls_template_vars
|
128
|
+
|
129
|
+
|
98
130
|
@usage_lib.entrypoint
|
99
131
|
def up(
|
100
132
|
task: 'sky.Task',
|
@@ -140,6 +172,9 @@ def up(
|
|
140
172
|
controller_utils.maybe_translate_local_file_mounts_and_sync_up(
|
141
173
|
task, path='serve')
|
142
174
|
|
175
|
+
tls_template_vars = _rewrite_tls_credential_paths_and_get_tls_env_vars(
|
176
|
+
service_name, task)
|
177
|
+
|
143
178
|
with tempfile.NamedTemporaryFile(
|
144
179
|
prefix=f'service-task-{service_name}-',
|
145
180
|
mode='w',
|
@@ -168,6 +203,7 @@ def up(
|
|
168
203
|
'remote_user_config_path': remote_config_yaml_path,
|
169
204
|
'modified_catalogs':
|
170
205
|
service_catalog_common.get_modified_catalog_file_mounts(),
|
206
|
+
**tls_template_vars,
|
171
207
|
**controller_utils.shared_controller_vars_to_fill(
|
172
208
|
controller=controller_utils.Controllers.SKY_SERVE_CONTROLLER,
|
173
209
|
remote_user_config_path=remote_config_yaml_path,
|
@@ -273,10 +309,16 @@ def up(
|
|
273
309
|
else:
|
274
310
|
lb_port = serve_utils.load_service_initialization_result(
|
275
311
|
lb_port_payload)
|
276
|
-
|
312
|
+
socket_endpoint = backend_utils.get_endpoints(
|
277
313
|
controller_handle.cluster_name, lb_port,
|
278
314
|
skip_status_check=True).get(lb_port)
|
279
|
-
assert
|
315
|
+
assert socket_endpoint is not None, (
|
316
|
+
'Did not get endpoint for controller.')
|
317
|
+
# Already checked by _validate_service_task
|
318
|
+
assert task.service is not None
|
319
|
+
protocol = ('http'
|
320
|
+
if task.service.tls_credential is None else 'https')
|
321
|
+
endpoint = f'{protocol}://{socket_endpoint}'
|
280
322
|
|
281
323
|
sky_logging.print(
|
282
324
|
f'{fore.CYAN}Service name: '
|
@@ -325,6 +367,7 @@ def update(
|
|
325
367
|
service_name: Name of the service.
|
326
368
|
"""
|
327
369
|
_validate_service_task(task)
|
370
|
+
|
328
371
|
# Always apply the policy again here, even though it might have been applied
|
329
372
|
# in the CLI. This is to ensure that we apply the policy to the final DAG
|
330
373
|
# and get the mutated config.
|
@@ -333,6 +376,14 @@ def update(
|
|
333
376
|
dag, _ = admin_policy_utils.apply(
|
334
377
|
task, use_mutated_config_in_current_request=False)
|
335
378
|
task = dag.tasks[0]
|
379
|
+
|
380
|
+
assert task.service is not None
|
381
|
+
if task.service.tls_credential is not None:
|
382
|
+
logger.warning('Updating TLS keyfile and certfile is not supported. '
|
383
|
+
'Any updates to the keyfile and certfile will not take '
|
384
|
+
'effect. To update TLS keyfile and certfile, please '
|
385
|
+
'tear down the service and spin up a new one.')
|
386
|
+
|
336
387
|
handle = backend_utils.is_controller_accessible(
|
337
388
|
controller=controller_utils.Controllers.SKY_SERVE_CONTROLLER,
|
338
389
|
stopped_message=
|
@@ -600,6 +651,7 @@ def status(
|
|
600
651
|
'requested_resources_str': (str) str representation of
|
601
652
|
requested resources,
|
602
653
|
'load_balancing_policy': (str) load balancing policy name,
|
654
|
+
'tls_encrypted': (bool) whether the service is TLS encrypted,
|
603
655
|
'replica_info': (List[Dict[str, Any]]) replica information,
|
604
656
|
}
|
605
657
|
|
sky/serve/load_balancer.py
CHANGED
@@ -27,10 +27,12 @@ class SkyServeLoadBalancer:
|
|
27
27
|
policy.
|
28
28
|
"""
|
29
29
|
|
30
|
-
def __init__(
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
def __init__(
|
31
|
+
self,
|
32
|
+
controller_url: str,
|
33
|
+
load_balancer_port: int,
|
34
|
+
load_balancing_policy_name: Optional[str] = None,
|
35
|
+
tls_credential: Optional[serve_utils.TLSCredential] = None) -> None:
|
34
36
|
"""Initialize the load balancer.
|
35
37
|
|
36
38
|
Args:
|
@@ -38,6 +40,8 @@ class SkyServeLoadBalancer:
|
|
38
40
|
load_balancer_port: The port where the load balancer listens to.
|
39
41
|
load_balancing_policy_name: The name of the load balancing policy
|
40
42
|
to use. Defaults to None.
|
43
|
+
tls_credentials: The TLS credentials for HTTPS endpoint. Defaults
|
44
|
+
to None.
|
41
45
|
"""
|
42
46
|
self._app = fastapi.FastAPI()
|
43
47
|
self._controller_url: str = controller_url
|
@@ -49,6 +53,8 @@ class SkyServeLoadBalancer:
|
|
49
53
|
f'{load_balancing_policy_name}.')
|
50
54
|
self._request_aggregator: serve_utils.RequestsAggregator = (
|
51
55
|
serve_utils.RequestTimestamp())
|
56
|
+
self._tls_credential: Optional[serve_utils.TLSCredential] = (
|
57
|
+
tls_credential)
|
52
58
|
# TODO(tian): httpx.Client has a resource limit of 100 max connections
|
53
59
|
# for each client. We should wait for feedback on the best max
|
54
60
|
# connections.
|
@@ -231,15 +237,25 @@ class SkyServeLoadBalancer:
|
|
231
237
|
# Register controller synchronization task
|
232
238
|
asyncio.create_task(self._sync_with_controller())
|
233
239
|
|
240
|
+
uvicorn_tls_kwargs = ({} if self._tls_credential is None else
|
241
|
+
self._tls_credential.dump_uvicorn_kwargs())
|
242
|
+
|
243
|
+
protocol = 'https' if self._tls_credential is not None else 'http'
|
244
|
+
|
234
245
|
logger.info('SkyServe Load Balancer started on '
|
235
|
-
f'
|
246
|
+
f'{protocol}://0.0.0.0:{self._load_balancer_port}')
|
236
247
|
|
237
|
-
uvicorn.run(self._app,
|
248
|
+
uvicorn.run(self._app,
|
249
|
+
host='0.0.0.0',
|
250
|
+
port=self._load_balancer_port,
|
251
|
+
**uvicorn_tls_kwargs)
|
238
252
|
|
239
253
|
|
240
|
-
def run_load_balancer(
|
241
|
-
|
242
|
-
|
254
|
+
def run_load_balancer(
|
255
|
+
controller_addr: str,
|
256
|
+
load_balancer_port: int,
|
257
|
+
load_balancing_policy_name: Optional[str] = None,
|
258
|
+
tls_credential: Optional[serve_utils.TLSCredential] = None) -> None:
|
243
259
|
""" Run the load balancer.
|
244
260
|
|
245
261
|
Args:
|
@@ -251,7 +267,8 @@ def run_load_balancer(controller_addr: str,
|
|
251
267
|
load_balancer = SkyServeLoadBalancer(
|
252
268
|
controller_url=controller_addr,
|
253
269
|
load_balancer_port=load_balancer_port,
|
254
|
-
load_balancing_policy_name=load_balancing_policy_name
|
270
|
+
load_balancing_policy_name=load_balancing_policy_name,
|
271
|
+
tls_credential=tls_credential)
|
255
272
|
load_balancer.run()
|
256
273
|
|
257
274
|
|
sky/serve/serve_state.py
CHANGED
@@ -79,6 +79,9 @@ db_utils.add_column_to_table(_DB.cursor, _DB.conn, 'services',
|
|
79
79
|
f'TEXT DEFAULT {json.dumps([])!r}')
|
80
80
|
db_utils.add_column_to_table(_DB.cursor, _DB.conn, 'services',
|
81
81
|
'load_balancing_policy', 'TEXT DEFAULT NULL')
|
82
|
+
# Whether the service's load balancer is encrypted with TLS.
|
83
|
+
db_utils.add_column_to_table(_DB.cursor, _DB.conn, 'services', 'tls_encrypted',
|
84
|
+
'INTEGER DEFAULT 0')
|
82
85
|
_UNIQUE_CONSTRAINT_FAILED_ERROR_MSG = 'UNIQUE constraint failed: services.name'
|
83
86
|
|
84
87
|
|
@@ -245,7 +248,7 @@ _SERVICE_STATUS_TO_COLOR = {
|
|
245
248
|
|
246
249
|
def add_service(name: str, controller_job_id: int, policy: str,
|
247
250
|
requested_resources_str: str, load_balancing_policy: str,
|
248
|
-
status: ServiceStatus) -> bool:
|
251
|
+
status: ServiceStatus, tls_encrypted: bool) -> bool:
|
249
252
|
"""Add a service in the database.
|
250
253
|
|
251
254
|
Returns:
|
@@ -258,10 +261,11 @@ def add_service(name: str, controller_job_id: int, policy: str,
|
|
258
261
|
"""\
|
259
262
|
INSERT INTO services
|
260
263
|
(name, controller_job_id, status, policy,
|
261
|
-
requested_resources_str, load_balancing_policy)
|
262
|
-
VALUES (?, ?, ?, ?, ?, ?)""",
|
264
|
+
requested_resources_str, load_balancing_policy, tls_encrypted)
|
265
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)""",
|
263
266
|
(name, controller_job_id, status.value, policy,
|
264
|
-
requested_resources_str, load_balancing_policy
|
267
|
+
requested_resources_str, load_balancing_policy,
|
268
|
+
int(tls_encrypted)))
|
265
269
|
|
266
270
|
except sqlite3.IntegrityError as e:
|
267
271
|
if str(e) != _UNIQUE_CONSTRAINT_FAILED_ERROR_MSG:
|
@@ -328,7 +332,7 @@ def set_service_load_balancer_port(service_name: str,
|
|
328
332
|
def _get_service_from_row(row) -> Dict[str, Any]:
|
329
333
|
(current_version, name, controller_job_id, controller_port,
|
330
334
|
load_balancer_port, status, uptime, policy, _, _, requested_resources_str,
|
331
|
-
_, active_versions, load_balancing_policy) = row[:
|
335
|
+
_, active_versions, load_balancing_policy, tls_encrypted) = row[:15]
|
332
336
|
if load_balancing_policy is None:
|
333
337
|
# This entry in database was added in #4439, and it will always be set
|
334
338
|
# to a str value. If it is None, it means it is an legacy entry and is
|
@@ -351,6 +355,7 @@ def _get_service_from_row(row) -> Dict[str, Any]:
|
|
351
355
|
'active_versions': json.loads(active_versions),
|
352
356
|
'requested_resources_str': requested_resources_str,
|
353
357
|
'load_balancing_policy': load_balancing_policy,
|
358
|
+
'tls_encrypted': bool(tls_encrypted),
|
354
359
|
}
|
355
360
|
|
356
361
|
|
sky/serve/serve_utils.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
"""User interface with the SkyServe."""
|
2
2
|
import base64
|
3
3
|
import collections
|
4
|
+
import dataclasses
|
4
5
|
import enum
|
5
6
|
import os
|
6
7
|
import pathlib
|
@@ -92,6 +93,19 @@ class UpdateMode(enum.Enum):
|
|
92
93
|
BLUE_GREEN = 'blue_green'
|
93
94
|
|
94
95
|
|
96
|
+
@dataclasses.dataclass
|
97
|
+
class TLSCredential:
|
98
|
+
"""TLS credential for the service."""
|
99
|
+
keyfile: str
|
100
|
+
certfile: str
|
101
|
+
|
102
|
+
def dump_uvicorn_kwargs(self) -> Dict[str, str]:
|
103
|
+
return {
|
104
|
+
'ssl_keyfile': os.path.expanduser(self.keyfile),
|
105
|
+
'ssl_certfile': os.path.expanduser(self.certfile),
|
106
|
+
}
|
107
|
+
|
108
|
+
|
95
109
|
DEFAULT_UPDATE_MODE = UpdateMode.ROLLING
|
96
110
|
|
97
111
|
_SIGNAL_TO_ERROR = {
|
@@ -243,6 +257,18 @@ def generate_replica_log_file_name(service_name: str, replica_id: int) -> str:
|
|
243
257
|
return os.path.join(dir_name, f'replica_{replica_id}.log')
|
244
258
|
|
245
259
|
|
260
|
+
def generate_remote_tls_keyfile_name(service_name: str) -> str:
|
261
|
+
dir_name = generate_remote_service_dir_name(service_name)
|
262
|
+
# Don't expand here since it is used for remote machine.
|
263
|
+
return os.path.join(dir_name, 'tls_keyfile')
|
264
|
+
|
265
|
+
|
266
|
+
def generate_remote_tls_certfile_name(service_name: str) -> str:
|
267
|
+
dir_name = generate_remote_service_dir_name(service_name)
|
268
|
+
# Don't expand here since it is used for remote machine.
|
269
|
+
return os.path.join(dir_name, 'tls_certfile')
|
270
|
+
|
271
|
+
|
246
272
|
def generate_replica_cluster_name(service_name: str, replica_id: int) -> str:
|
247
273
|
return f'{service_name}-{replica_id}'
|
248
274
|
|
@@ -799,7 +825,8 @@ def get_endpoint(service_record: Dict[str, Any]) -> str:
|
|
799
825
|
if endpoint is None:
|
800
826
|
return '-'
|
801
827
|
assert isinstance(endpoint, str), endpoint
|
802
|
-
|
828
|
+
protocol = 'https' if service_record['tls_encrypted'] else 'http'
|
829
|
+
return f'{protocol}://{endpoint}'
|
803
830
|
|
804
831
|
|
805
832
|
def format_service_table(service_records: List[Dict[str, Any]],
|
sky/serve/service.py
CHANGED
@@ -151,7 +151,8 @@ def _start(service_name: str, tmp_task_yaml: str, job_id: int):
|
|
151
151
|
policy=service_spec.autoscaling_policy_str(),
|
152
152
|
requested_resources_str=backend_utils.get_task_resources_str(task),
|
153
153
|
load_balancing_policy=service_spec.load_balancing_policy,
|
154
|
-
status=serve_state.ServiceStatus.CONTROLLER_INIT
|
154
|
+
status=serve_state.ServiceStatus.CONTROLLER_INIT,
|
155
|
+
tls_encrypted=service_spec.tls_credential is not None)
|
155
156
|
# Directly throw an error here. See sky/serve/api.py::up
|
156
157
|
# for more details.
|
157
158
|
if not success:
|
@@ -214,7 +215,6 @@ def _start(service_name: str, tmp_task_yaml: str, job_id: int):
|
|
214
215
|
serve_state.set_service_controller_port(service_name,
|
215
216
|
controller_port)
|
216
217
|
|
217
|
-
# TODO(tian): Support HTTPS.
|
218
218
|
controller_addr = f'http://{controller_host}:{controller_port}'
|
219
219
|
|
220
220
|
load_balancer_port = common_utils.find_free_port(
|
@@ -231,7 +231,8 @@ def _start(service_name: str, tmp_task_yaml: str, job_id: int):
|
|
231
231
|
target=ux_utils.RedirectOutputForProcess(
|
232
232
|
load_balancer.run_load_balancer,
|
233
233
|
load_balancer_log_file).run,
|
234
|
-
args=(controller_addr, load_balancer_port, policy_name
|
234
|
+
args=(controller_addr, load_balancer_port, policy_name,
|
235
|
+
service_spec.tls_credential))
|
235
236
|
load_balancer_process.start()
|
236
237
|
serve_state.set_service_load_balancer_port(service_name,
|
237
238
|
load_balancer_port)
|
sky/serve/service_spec.py
CHANGED
@@ -9,6 +9,7 @@ import yaml
|
|
9
9
|
from sky import serve
|
10
10
|
from sky.serve import constants
|
11
11
|
from sky.serve import load_balancing_policies as lb_policies
|
12
|
+
from sky.serve import serve_utils
|
12
13
|
from sky.utils import common_utils
|
13
14
|
from sky.utils import schemas
|
14
15
|
from sky.utils import ux_utils
|
@@ -26,6 +27,7 @@ class SkyServiceSpec:
|
|
26
27
|
max_replicas: Optional[int] = None,
|
27
28
|
target_qps_per_replica: Optional[float] = None,
|
28
29
|
post_data: Optional[Dict[str, Any]] = None,
|
30
|
+
tls_credential: Optional[serve_utils.TLSCredential] = None,
|
29
31
|
readiness_headers: Optional[Dict[str, str]] = None,
|
30
32
|
dynamic_ondemand_fallback: Optional[bool] = None,
|
31
33
|
base_ondemand_fallback_replicas: Optional[int] = None,
|
@@ -72,6 +74,8 @@ class SkyServiceSpec:
|
|
72
74
|
self._max_replicas: Optional[int] = max_replicas
|
73
75
|
self._target_qps_per_replica: Optional[float] = target_qps_per_replica
|
74
76
|
self._post_data: Optional[Dict[str, Any]] = post_data
|
77
|
+
self._tls_credential: Optional[serve_utils.TLSCredential] = (
|
78
|
+
tls_credential)
|
75
79
|
self._readiness_headers: Optional[Dict[str, str]] = readiness_headers
|
76
80
|
self._dynamic_ondemand_fallback: Optional[
|
77
81
|
bool] = dynamic_ondemand_fallback
|
@@ -163,6 +167,14 @@ class SkyServiceSpec:
|
|
163
167
|
|
164
168
|
service_config['load_balancing_policy'] = config.get(
|
165
169
|
'load_balancing_policy', None)
|
170
|
+
|
171
|
+
tls_section = config.get('tls', None)
|
172
|
+
if tls_section is not None:
|
173
|
+
service_config['tls_credential'] = serve_utils.TLSCredential(
|
174
|
+
keyfile=tls_section.get('keyfile', None),
|
175
|
+
certfile=tls_section.get('certfile', None),
|
176
|
+
)
|
177
|
+
|
166
178
|
return SkyServiceSpec(**service_config)
|
167
179
|
|
168
180
|
@staticmethod
|
@@ -223,6 +235,9 @@ class SkyServiceSpec:
|
|
223
235
|
self.downscale_delay_seconds)
|
224
236
|
add_if_not_none('load_balancing_policy', None,
|
225
237
|
self._load_balancing_policy)
|
238
|
+
if self.tls_credential is not None:
|
239
|
+
add_if_not_none('tls', 'keyfile', self.tls_credential.keyfile)
|
240
|
+
add_if_not_none('tls', 'certfile', self.tls_credential.certfile)
|
226
241
|
return config
|
227
242
|
|
228
243
|
def probe_str(self):
|
@@ -267,12 +282,19 @@ class SkyServiceSpec:
|
|
267
282
|
f'replica{max_plural} (target QPS per replica: '
|
268
283
|
f'{self.target_qps_per_replica})')
|
269
284
|
|
285
|
+
def tls_str(self):
|
286
|
+
if self.tls_credential is None:
|
287
|
+
return 'No TLS Enabled'
|
288
|
+
return (f'Keyfile: {self.tls_credential.keyfile}, '
|
289
|
+
f'Certfile: {self.tls_credential.certfile}')
|
290
|
+
|
270
291
|
def __repr__(self) -> str:
|
271
292
|
return textwrap.dedent(f"""\
|
272
293
|
Readiness probe method: {self.probe_str()}
|
273
294
|
Readiness initial delay seconds: {self.initial_delay_seconds}
|
274
295
|
Readiness probe timeout seconds: {self.readiness_timeout_seconds}
|
275
296
|
Replica autoscaling policy: {self.autoscaling_policy_str()}
|
297
|
+
TLS Certificates: {self.tls_str()}
|
276
298
|
Spot Policy: {self.spot_policy_str()}
|
277
299
|
Load Balancing Policy: {self.load_balancing_policy}
|
278
300
|
""")
|
@@ -306,6 +328,15 @@ class SkyServiceSpec:
|
|
306
328
|
def post_data(self) -> Optional[Dict[str, Any]]:
|
307
329
|
return self._post_data
|
308
330
|
|
331
|
+
@property
|
332
|
+
def tls_credential(self) -> Optional[serve_utils.TLSCredential]:
|
333
|
+
return self._tls_credential
|
334
|
+
|
335
|
+
@tls_credential.setter
|
336
|
+
def tls_credential(self,
|
337
|
+
value: Optional[serve_utils.TLSCredential]) -> None:
|
338
|
+
self._tls_credential = value
|
339
|
+
|
309
340
|
@property
|
310
341
|
def readiness_headers(self) -> Optional[Dict[str, str]]:
|
311
342
|
return self._readiness_headers
|
@@ -29,6 +29,10 @@ file_mounts:
|
|
29
29
|
{%- for remote_catalog_path, local_catalog_path in modified_catalogs.items() %}
|
30
30
|
{{remote_catalog_path}}: {{local_catalog_path}}
|
31
31
|
{%- endfor %}
|
32
|
+
{%- if use_tls %}
|
33
|
+
{{remote_tls_keyfile}}: {{local_tls_keyfile}}
|
34
|
+
{{remote_tls_certfile}}: {{local_tls_certfile}}
|
35
|
+
{%- endif %}
|
32
36
|
|
33
37
|
run: |
|
34
38
|
# Activate the Python environment, so that cloud SDKs can be found in the
|
sky/utils/schemas.py
CHANGED
@@ -396,6 +396,19 @@ def get_service_schema():
|
|
396
396
|
'case_insensitive_enum': list(
|
397
397
|
load_balancing_policies.LB_POLICIES.keys())
|
398
398
|
},
|
399
|
+
'tls': {
|
400
|
+
'type': 'object',
|
401
|
+
'required': ['keyfile', 'certfile'],
|
402
|
+
'additionalProperties': False,
|
403
|
+
'properties': {
|
404
|
+
'keyfile': {
|
405
|
+
'type': 'string',
|
406
|
+
},
|
407
|
+
'certfile': {
|
408
|
+
'type': 'string',
|
409
|
+
},
|
410
|
+
},
|
411
|
+
},
|
399
412
|
}
|
400
413
|
}
|
401
414
|
|
{skypilot_nightly-1.0.0.dev20250119.dist-info → skypilot_nightly-1.0.0.dev20250120.dist-info}/RECORD
RENAMED
@@ -1,4 +1,4 @@
|
|
1
|
-
sky/__init__.py,sha256=
|
1
|
+
sky/__init__.py,sha256=H1OJA_bZf59Rdg7CgHy8yMr7uxtMUwuxW7gGNX2jVlk,5944
|
2
2
|
sky/admin_policy.py,sha256=hPo02f_A32gCqhUueF0QYy1fMSSKqRwYEg_9FxScN_s,3248
|
3
3
|
sky/authentication.py,sha256=LXUDABKP1FJCS256xTTDJa40WXwHKF5x49S-4hZbD1M,21501
|
4
4
|
sky/check.py,sha256=s8deMVL-k9y8gd519K7NWZc3DqWsEySwiAr0uH3Vvcc,9459
|
@@ -188,17 +188,17 @@ sky/provision/vsphere/common/ssl_helper.py,sha256=TYzN9K0i_Mk_17PKGyGPgvOGfoizys
|
|
188
188
|
sky/provision/vsphere/common/vapiconnect.py,sha256=R2I1ZWBA19d11fZ_FrIzQT8E1aLl1HU4Rdcj8Z5r3NE,2932
|
189
189
|
sky/provision/vsphere/common/vim_utils.py,sha256=y_i_bh6jxAEfaoVKbgVB02vWE0HbxP9oM83rANT8kBE,17871
|
190
190
|
sky/serve/__init__.py,sha256=Bqw8nB9u1QF3ryjbV797SPZq0DWAcjT94E_5B8J24ag,1808
|
191
|
-
sky/serve/autoscalers.py,sha256=
|
191
|
+
sky/serve/autoscalers.py,sha256=OxaynplCqbmrMA3fIGhxkugaGm-50QoI8S1fIfHK0M0,31667
|
192
192
|
sky/serve/constants.py,sha256=7MflfgTHO9gDSux93U4BmNeEMWXxZB4q7I54KUwgp-s,4651
|
193
|
-
sky/serve/controller.py,sha256=
|
194
|
-
sky/serve/core.py,sha256=
|
195
|
-
sky/serve/load_balancer.py,sha256=
|
193
|
+
sky/serve/controller.py,sha256=jtzWHsLHnVPQ727ZpDZTUpGTtIOssbnQpXeWOyAuW_s,11886
|
194
|
+
sky/serve/core.py,sha256=RHPobivYdQj2PWs0uRLd_KvyAa7altqrT81si1IUlIs,35402
|
195
|
+
sky/serve/load_balancer.py,sha256=2nkMPRvy-h7hJL4Qq__tkT8nIAVC_nmjyXf8mMGYEFk,13658
|
196
196
|
sky/serve/load_balancing_policies.py,sha256=XVj76qBgqh7h6wfx53RKQFzBefDWTE4TCdCEtFLLtI4,5398
|
197
197
|
sky/serve/replica_managers.py,sha256=SFvK7ewilc3NVRcqXg63WtU1WmhJKPtJd27JfKR2aow,57716
|
198
|
-
sky/serve/serve_state.py,sha256=
|
199
|
-
sky/serve/serve_utils.py,sha256=
|
200
|
-
sky/serve/service.py,sha256=
|
201
|
-
sky/serve/service_spec.py,sha256=
|
198
|
+
sky/serve/serve_state.py,sha256=2V9WVD9OZ26vgyIJ-kZcrlouazwFTrpjlZAK9DRv3uA,20084
|
199
|
+
sky/serve/serve_utils.py,sha256=m1Zcjslnzcr5AAppzV48WDOwMWjRaXotTUd_iN-dHgc,40654
|
200
|
+
sky/serve/service.py,sha256=DPU1PJGuHa1WaNqxYqgpmqd4LA9jBbQM-KlLrA6C1M0,12156
|
201
|
+
sky/serve/service_spec.py,sha256=26MCrv0mRbwfPCtg7uKD0xJjFXHzdajKM0gKuIGOKMc,16259
|
202
202
|
sky/setup_files/MANIFEST.in,sha256=WF0T89NLichHxZDDSQzvSpiONtAEFyur2MPmGczgTIo,555
|
203
203
|
sky/setup_files/dependencies.py,sha256=ujGG0rFG8TWGgJv21N-xD0fetYRlaf_xV8ILdsCQDiU,6087
|
204
204
|
sky/setup_files/setup.py,sha256=HMqAIxHrhtQUOlm6_Iz5E_bL4dUvsYgXc9YVQIFayPs,7417
|
@@ -250,7 +250,7 @@ sky/templates/oci-ray.yml.j2,sha256=92dvXGaUd2Kwep9fgTjOsAPJiBLr8GQTjy7pFvuPAyE,
|
|
250
250
|
sky/templates/paperspace-ray.yml.j2,sha256=HQjZNamrB_a4fOMCxQXSVdV5JIHtbGtAE0JzEO8uuVQ,4021
|
251
251
|
sky/templates/runpod-ray.yml.j2,sha256=bUiF4Y_EkCA_GKLtTzPXbajdL-NOUiJ38Pe4dZd2dys,4284
|
252
252
|
sky/templates/scp-ray.yml.j2,sha256=I9u8Ax-lit-d6UrCC9BVU8avst8w1cwK6TrzZBcz_JM,5608
|
253
|
-
sky/templates/sky-serve-controller.yaml.j2,sha256=
|
253
|
+
sky/templates/sky-serve-controller.yaml.j2,sha256=1K-ObUxhpz1q_LfuZsHpJRyhcPfW3km7-RxbxyCo994,1757
|
254
254
|
sky/templates/vsphere-ray.yml.j2,sha256=cOQ-qdpxGA2FHajMMhTJI-SmlYzdPterX4Gsiq-nkb0,3587
|
255
255
|
sky/usage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
256
256
|
sky/usage/constants.py,sha256=8xpg9vhDU9A3eObtpkNFjwa42oCazqGEv4yw_vJSO7U,590
|
@@ -271,7 +271,7 @@ sky/utils/kubernetes_enums.py,sha256=imGqHSa8O07zD_6xH1SDMM7dBU5lF5fzFFlQuQy00QM
|
|
271
271
|
sky/utils/log_utils.py,sha256=xEbUZfDiIiZkyWoLHXwIcqVMCBDEENsLCiogEXMDLt0,14139
|
272
272
|
sky/utils/resources_utils.py,sha256=06Kx6AfbBdwBYGmIYFEY_qm6OBc2a5esZMPvIX7gCvc,7787
|
273
273
|
sky/utils/rich_utils.py,sha256=hmnI1X5dKvRIQzB7EyNb34FT97qFNve-0QHqM5r0mVk,3066
|
274
|
-
sky/utils/schemas.py,sha256=
|
274
|
+
sky/utils/schemas.py,sha256=50bzZfjseNky8jUqmrjRYaOQQxkaM3mzQYyLiRq0qfs,30482
|
275
275
|
sky/utils/subprocess_utils.py,sha256=YhtxqHoaZLw2M9TikTH56dTboZN3Qu2RsGeWo4uwJVA,12054
|
276
276
|
sky/utils/timeline.py,sha256=ebHxKJK2HX0utGArrUgSezTPkcwav3VETa_AQS34t-E,3925
|
277
277
|
sky/utils/ux_utils.py,sha256=CqyIFGDuSE8fQasPkna_loZMwtboC9KedR09WEQ7qz0,6502
|
@@ -289,9 +289,9 @@ sky/utils/kubernetes/k8s_gpu_labeler_job.yaml,sha256=k0TBoQ4zgf79-sVkixKSGYFHQ7Z
|
|
289
289
|
sky/utils/kubernetes/k8s_gpu_labeler_setup.yaml,sha256=VLKT2KKimZu1GDg_4AIlIt488oMQvhRZWwsj9vBbPUg,3812
|
290
290
|
sky/utils/kubernetes/rsync_helper.sh,sha256=h4YwrPFf9727CACnMJvF3EyK_0OeOYKKt4su_daKekw,1256
|
291
291
|
sky/utils/kubernetes/ssh_jump_lifecycle_manager.py,sha256=Kq1MDygF2IxFmu9FXpCxqucXLmeUrvs6OtRij6XTQbo,6554
|
292
|
-
skypilot_nightly-1.0.0.
|
293
|
-
skypilot_nightly-1.0.0.
|
294
|
-
skypilot_nightly-1.0.0.
|
295
|
-
skypilot_nightly-1.0.0.
|
296
|
-
skypilot_nightly-1.0.0.
|
297
|
-
skypilot_nightly-1.0.0.
|
292
|
+
skypilot_nightly-1.0.0.dev20250120.dist-info/LICENSE,sha256=emRJAvE7ngL6x0RhQvlns5wJzGI3NEQ_WMjNmd9TZc4,12170
|
293
|
+
skypilot_nightly-1.0.0.dev20250120.dist-info/METADATA,sha256=2AbDblEGahxEI-YkKiQHlbINuXCxQw3Z6-viIqLTZNk,20884
|
294
|
+
skypilot_nightly-1.0.0.dev20250120.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
295
|
+
skypilot_nightly-1.0.0.dev20250120.dist-info/entry_points.txt,sha256=StA6HYpuHj-Y61L2Ze-hK2IcLWgLZcML5gJu8cs6nU4,36
|
296
|
+
skypilot_nightly-1.0.0.dev20250120.dist-info/top_level.txt,sha256=qA8QuiNNb6Y1OF-pCUtPEr6sLEwy2xJX06Bd_CrtrHY,4
|
297
|
+
skypilot_nightly-1.0.0.dev20250120.dist-info/RECORD,,
|
File without changes
|
{skypilot_nightly-1.0.0.dev20250119.dist-info → skypilot_nightly-1.0.0.dev20250120.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|
File without changes
|