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/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.evaluate_scaling(
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
- elif (scaling_option.operator ==
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
- endpoint = backend_utils.get_endpoints(
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 endpoint is not None, 'Did not get endpoint for controller.'
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
 
@@ -27,10 +27,12 @@ class SkyServeLoadBalancer:
27
27
  policy.
28
28
  """
29
29
 
30
- def __init__(self,
31
- controller_url: str,
32
- load_balancer_port: int,
33
- load_balancing_policy_name: Optional[str] = None) -> None:
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'http://0.0.0.0:{self._load_balancer_port}')
246
+ f'{protocol}://0.0.0.0:{self._load_balancer_port}')
236
247
 
237
- uvicorn.run(self._app, host='0.0.0.0', port=self._load_balancer_port)
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(controller_addr: str,
241
- load_balancer_port: int,
242
- load_balancing_policy_name: Optional[str] = None) -> None:
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[:14]
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
- return endpoint
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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: skypilot-nightly
3
- Version: 1.0.0.dev20250119
3
+ Version: 1.0.0.dev20250120
4
4
  Summary: SkyPilot: An intercloud broker for the clouds
5
5
  Author: SkyPilot Team
6
6
  License: Apache 2.0
@@ -1,4 +1,4 @@
1
- sky/__init__.py,sha256=aC5XkRJ6V-eJ02IR9TVtzIZdM6O3RIr3pg2xI_Qb3jM,5944
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=N7yRGT9Ay5_yJUOkqaBGC7jG3eIdzA5d66i8kskGxZc,30351
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=R5iIEGEEFtbm_6MvSGelYZP-vSmW0cSFuy64OexUc4g,11719
194
- sky/serve/core.py,sha256=UAbbnxmOZ8GBT7vaeFvtFC7_qXu05TFsNIFcLrdT3Oo,33341
195
- sky/serve/load_balancer.py,sha256=nNvDPJPRIrBc_qsBYJz1zzKa_fXDgfi0VDUf4SJEuW8,12990
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=MAx63zlGOXaIgXedP9fUFlRxDKiez1shmyMetrJK6yQ,19756
199
- sky/serve/serve_utils.py,sha256=WgPcqEw3WyMOdgRTFg8DSsWyIG1xnRbRkI1-f09tNKg,39741
200
- sky/serve/service.py,sha256=7bvK9R9D48PZSYcOKSievXQ2mHUMk1d3AAIxtra7WOI,12083
201
- sky/serve/service_spec.py,sha256=mph-IRhamiFls4RX_8yhC0lTLzbIxGYbnvosy7VZTi4,14999
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=V1IiYhArv_D_7JzC3sVN4nKlSCCCL1AYtIdxFSa-f4c,1628
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=KcU6wSmLQ-2HhfE6m4RHN9D3mqMAc8X1j5vOb-bUki0,30064
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.dev20250119.dist-info/LICENSE,sha256=emRJAvE7ngL6x0RhQvlns5wJzGI3NEQ_WMjNmd9TZc4,12170
293
- skypilot_nightly-1.0.0.dev20250119.dist-info/METADATA,sha256=EMtxUVksl6PZt-fJt5k6PvgcWoaDL1pHzaQEc5K9iCU,20884
294
- skypilot_nightly-1.0.0.dev20250119.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
295
- skypilot_nightly-1.0.0.dev20250119.dist-info/entry_points.txt,sha256=StA6HYpuHj-Y61L2Ze-hK2IcLWgLZcML5gJu8cs6nU4,36
296
- skypilot_nightly-1.0.0.dev20250119.dist-info/top_level.txt,sha256=qA8QuiNNb6Y1OF-pCUtPEr6sLEwy2xJX06Bd_CrtrHY,4
297
- skypilot_nightly-1.0.0.dev20250119.dist-info/RECORD,,
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,,