skypilot-nightly 1.0.0.dev20241220__py3-none-any.whl → 1.0.0.dev20241221__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 CHANGED
@@ -5,7 +5,7 @@ from typing import Optional
5
5
  import urllib.request
6
6
 
7
7
  # Replaced with the current commit when building the wheels.
8
- _SKYPILOT_COMMIT_SHA = 'a73a9cb37152c5f05d06bd1afe29a685ef86f85c'
8
+ _SKYPILOT_COMMIT_SHA = 'ee3cabd57247ff0f25cb65c0ee46bd35ead8d11a'
9
9
 
10
10
 
11
11
  def _get_git_commit():
@@ -35,7 +35,7 @@ def _get_git_commit():
35
35
 
36
36
 
37
37
  __commit__ = _get_git_commit()
38
- __version__ = '1.0.0.dev20241220'
38
+ __version__ = '1.0.0.dev20241221'
39
39
  __root_dir__ = os.path.dirname(os.path.abspath(__file__))
40
40
 
41
41
 
@@ -1234,7 +1234,8 @@ def construct_ssh_jump_command(
1234
1234
  '-o StrictHostKeyChecking=no '
1235
1235
  '-o UserKnownHostsFile=/dev/null '
1236
1236
  f'-o IdentitiesOnly=yes '
1237
- f'-W %h:%p {ssh_jump_user}@{ssh_jump_ip}')
1237
+ r'-W \[%h\]:%p '
1238
+ f'{ssh_jump_user}@{ssh_jump_ip}')
1238
1239
  if ssh_jump_port is not None:
1239
1240
  ssh_jump_proxy_command += f' -p {ssh_jump_port} '
1240
1241
  if proxy_cmd_path is not None:
sky/serve/core.py CHANGED
@@ -384,6 +384,17 @@ def update(
384
384
  with ux_utils.print_exception_no_traceback():
385
385
  raise RuntimeError(prompt)
386
386
 
387
+ original_lb_policy = service_record['load_balancing_policy']
388
+ assert task.service is not None, 'Service section not found.'
389
+ if original_lb_policy != task.service.load_balancing_policy:
390
+ logger.warning(
391
+ f'{colorama.Fore.YELLOW}Current load balancing policy '
392
+ f'{original_lb_policy!r} is different from the new policy '
393
+ f'{task.service.load_balancing_policy!r}. Updating the load '
394
+ 'balancing policy is not supported yet and it will be ignored. '
395
+ 'The service will continue to use the current load balancing '
396
+ f'policy.{colorama.Style.RESET_ALL}')
397
+
387
398
  with rich_utils.safe_status(
388
399
  ux_utils.spinner_message('Initializing service')):
389
400
  controller_utils.maybe_translate_local_file_mounts_and_sync_up(
@@ -581,9 +592,10 @@ def status(
581
592
  'status': (sky.ServiceStatus) service status,
582
593
  'controller_port': (Optional[int]) controller port,
583
594
  'load_balancer_port': (Optional[int]) load balancer port,
584
- 'policy': (Optional[str]) load balancer policy description,
595
+ 'policy': (Optional[str]) autoscaling policy description,
585
596
  'requested_resources_str': (str) str representation of
586
597
  requested resources,
598
+ 'load_balancing_policy': (str) load balancing policy name,
587
599
  'replica_info': (List[Dict[str, Any]]) replica information,
588
600
  }
589
601
 
@@ -45,6 +45,8 @@ class SkyServeLoadBalancer:
45
45
  # Use the registry to create the load balancing policy
46
46
  self._load_balancing_policy = lb_policies.LoadBalancingPolicy.make(
47
47
  load_balancing_policy_name)
48
+ logger.info('Starting load balancer with policy '
49
+ f'{load_balancing_policy_name}.')
48
50
  self._request_aggregator: serve_utils.RequestsAggregator = (
49
51
  serve_utils.RequestTimestamp())
50
52
  # TODO(tian): httpx.Client has a resource limit of 100 max connections
@@ -128,6 +130,7 @@ class SkyServeLoadBalancer:
128
130
  encountered if anything goes wrong.
129
131
  """
130
132
  logger.info(f'Proxy request to {url}')
133
+ self._load_balancing_policy.pre_execute_hook(url, request)
131
134
  try:
132
135
  # We defer the get of the client here on purpose, for case when the
133
136
  # replica is ready in `_proxy_with_retries` but refreshed before
@@ -147,11 +150,16 @@ class SkyServeLoadBalancer:
147
150
  content=await request.body(),
148
151
  timeout=constants.LB_STREAM_TIMEOUT)
149
152
  proxy_response = await client.send(proxy_request, stream=True)
153
+
154
+ async def background_func():
155
+ await proxy_response.aclose()
156
+ self._load_balancing_policy.post_execute_hook(url, request)
157
+
150
158
  return fastapi.responses.StreamingResponse(
151
159
  content=proxy_response.aiter_raw(),
152
160
  status_code=proxy_response.status_code,
153
161
  headers=proxy_response.headers,
154
- background=background.BackgroundTask(proxy_response.aclose))
162
+ background=background.BackgroundTask(background_func))
155
163
  except (httpx.RequestError, httpx.HTTPStatusError) as e:
156
164
  logger.error(f'Error when proxy request to {url}: '
157
165
  f'{common_utils.format_exception(e)}')
@@ -263,7 +271,7 @@ if __name__ == '__main__':
263
271
  parser.add_argument(
264
272
  '--load-balancing-policy',
265
273
  choices=available_policies,
266
- default='round_robin',
274
+ default=lb_policies.DEFAULT_LB_POLICY,
267
275
  help=f'The load balancing policy to use. Available policies: '
268
276
  f'{", ".join(available_policies)}.')
269
277
  args = parser.parse_args()
@@ -1,7 +1,9 @@
1
1
  """LoadBalancingPolicy: Policy to select endpoint."""
2
+ import collections
2
3
  import random
4
+ import threading
3
5
  import typing
4
- from typing import List, Optional
6
+ from typing import Dict, List, Optional
5
7
 
6
8
  from sky import sky_logging
7
9
 
@@ -13,6 +15,10 @@ logger = sky_logging.init_logger(__name__)
13
15
  # Define a registry for load balancing policies
14
16
  LB_POLICIES = {}
15
17
  DEFAULT_LB_POLICY = None
18
+ # Prior to #4439, the default policy was round_robin. We store the legacy
19
+ # default policy here to maintain backwards compatibility. Remove this after
20
+ # 2 minor release, i.e., 0.9.0.
21
+ LEGACY_DEFAULT_POLICY = 'round_robin'
16
22
 
17
23
 
18
24
  def _request_repr(request: 'fastapi.Request') -> str:
@@ -38,11 +44,17 @@ class LoadBalancingPolicy:
38
44
  DEFAULT_LB_POLICY = name
39
45
 
40
46
  @classmethod
41
- def make(cls, policy_name: Optional[str] = None) -> 'LoadBalancingPolicy':
42
- """Create a load balancing policy from a name."""
47
+ def make_policy_name(cls, policy_name: Optional[str]) -> str:
48
+ """Return the policy name."""
49
+ assert DEFAULT_LB_POLICY is not None, 'No default policy set.'
43
50
  if policy_name is None:
44
- policy_name = DEFAULT_LB_POLICY
51
+ return DEFAULT_LB_POLICY
52
+ return policy_name
45
53
 
54
+ @classmethod
55
+ def make(cls, policy_name: Optional[str] = None) -> 'LoadBalancingPolicy':
56
+ """Create a load balancing policy from a name."""
57
+ policy_name = cls.make_policy_name(policy_name)
46
58
  if policy_name not in LB_POLICIES:
47
59
  raise ValueError(f'Unknown load balancing policy: {policy_name}')
48
60
  return LB_POLICIES[policy_name]()
@@ -65,8 +77,16 @@ class LoadBalancingPolicy:
65
77
  def _select_replica(self, request: 'fastapi.Request') -> Optional[str]:
66
78
  raise NotImplementedError
67
79
 
80
+ def pre_execute_hook(self, replica_url: str,
81
+ request: 'fastapi.Request') -> None:
82
+ pass
83
+
84
+ def post_execute_hook(self, replica_url: str,
85
+ request: 'fastapi.Request') -> None:
86
+ pass
87
+
68
88
 
69
- class RoundRobinPolicy(LoadBalancingPolicy, name='round_robin', default=True):
89
+ class RoundRobinPolicy(LoadBalancingPolicy, name='round_robin'):
70
90
  """Round-robin load balancing policy."""
71
91
 
72
92
  def __init__(self) -> None:
@@ -90,3 +110,43 @@ class RoundRobinPolicy(LoadBalancingPolicy, name='round_robin', default=True):
90
110
  ready_replica_url = self.ready_replicas[self.index]
91
111
  self.index = (self.index + 1) % len(self.ready_replicas)
92
112
  return ready_replica_url
113
+
114
+
115
+ class LeastLoadPolicy(LoadBalancingPolicy, name='least_load', default=True):
116
+ """Least load load balancing policy."""
117
+
118
+ def __init__(self) -> None:
119
+ super().__init__()
120
+ self.load_map: Dict[str, int] = collections.defaultdict(int)
121
+ self.lock = threading.Lock()
122
+
123
+ def set_ready_replicas(self, ready_replicas: List[str]) -> None:
124
+ if set(self.ready_replicas) == set(ready_replicas):
125
+ return
126
+ with self.lock:
127
+ self.ready_replicas = ready_replicas
128
+ for r in self.ready_replicas:
129
+ if r not in ready_replicas:
130
+ del self.load_map[r]
131
+ for replica in ready_replicas:
132
+ self.load_map[replica] = self.load_map.get(replica, 0)
133
+
134
+ def _select_replica(self, request: 'fastapi.Request') -> Optional[str]:
135
+ del request # Unused.
136
+ if not self.ready_replicas:
137
+ return None
138
+ with self.lock:
139
+ return min(self.ready_replicas,
140
+ key=lambda replica: self.load_map.get(replica, 0))
141
+
142
+ def pre_execute_hook(self, replica_url: str,
143
+ request: 'fastapi.Request') -> None:
144
+ del request # Unused.
145
+ with self.lock:
146
+ self.load_map[replica_url] += 1
147
+
148
+ def post_execute_hook(self, replica_url: str,
149
+ request: 'fastapi.Request') -> None:
150
+ del request # Unused.
151
+ with self.lock:
152
+ self.load_map[replica_url] -= 1
sky/serve/serve_state.py CHANGED
@@ -11,6 +11,7 @@ from typing import Any, Dict, List, Optional, Tuple
11
11
  import colorama
12
12
 
13
13
  from sky.serve import constants
14
+ from sky.serve import load_balancing_policies as lb_policies
14
15
  from sky.utils import db_utils
15
16
 
16
17
  if typing.TYPE_CHECKING:
@@ -76,6 +77,8 @@ db_utils.add_column_to_table(_DB.cursor, _DB.conn, 'services',
76
77
  db_utils.add_column_to_table(_DB.cursor, _DB.conn, 'services',
77
78
  'active_versions',
78
79
  f'TEXT DEFAULT {json.dumps([])!r}')
80
+ db_utils.add_column_to_table(_DB.cursor, _DB.conn, 'services',
81
+ 'load_balancing_policy', 'TEXT DEFAULT NULL')
79
82
  _UNIQUE_CONSTRAINT_FAILED_ERROR_MSG = 'UNIQUE constraint failed: services.name'
80
83
 
81
84
 
@@ -241,7 +244,8 @@ _SERVICE_STATUS_TO_COLOR = {
241
244
 
242
245
 
243
246
  def add_service(name: str, controller_job_id: int, policy: str,
244
- requested_resources_str: str, status: ServiceStatus) -> bool:
247
+ requested_resources_str: str, load_balancing_policy: str,
248
+ status: ServiceStatus) -> bool:
245
249
  """Add a service in the database.
246
250
 
247
251
  Returns:
@@ -254,10 +258,10 @@ def add_service(name: str, controller_job_id: int, policy: str,
254
258
  """\
255
259
  INSERT INTO services
256
260
  (name, controller_job_id, status, policy,
257
- requested_resources_str)
258
- VALUES (?, ?, ?, ?, ?)""",
261
+ requested_resources_str, load_balancing_policy)
262
+ VALUES (?, ?, ?, ?, ?, ?)""",
259
263
  (name, controller_job_id, status.value, policy,
260
- requested_resources_str))
264
+ requested_resources_str, load_balancing_policy))
261
265
 
262
266
  except sqlite3.IntegrityError as e:
263
267
  if str(e) != _UNIQUE_CONSTRAINT_FAILED_ERROR_MSG:
@@ -324,7 +328,12 @@ def set_service_load_balancer_port(service_name: str,
324
328
  def _get_service_from_row(row) -> Dict[str, Any]:
325
329
  (current_version, name, controller_job_id, controller_port,
326
330
  load_balancer_port, status, uptime, policy, _, _, requested_resources_str,
327
- _, active_versions) = row[:13]
331
+ _, active_versions, load_balancing_policy) = row[:14]
332
+ if load_balancing_policy is None:
333
+ # This entry in database was added in #4439, and it will always be set
334
+ # to a str value. If it is None, it means it is an legacy entry and is
335
+ # using the legacy default policy.
336
+ load_balancing_policy = lb_policies.LEGACY_DEFAULT_POLICY
328
337
  return {
329
338
  'name': name,
330
339
  'controller_job_id': controller_job_id,
@@ -341,6 +350,7 @@ def _get_service_from_row(row) -> Dict[str, Any]:
341
350
  # integers in json format. This is mainly for display purpose.
342
351
  'active_versions': json.loads(active_versions),
343
352
  'requested_resources_str': requested_resources_str,
353
+ 'load_balancing_policy': load_balancing_policy,
344
354
  }
345
355
 
346
356
 
sky/serve/serve_utils.py CHANGED
@@ -811,7 +811,9 @@ def format_service_table(service_records: List[Dict[str, Any]],
811
811
  'NAME', 'VERSION', 'UPTIME', 'STATUS', 'REPLICAS', 'ENDPOINT'
812
812
  ]
813
813
  if show_all:
814
- service_columns.extend(['POLICY', 'REQUESTED_RESOURCES'])
814
+ service_columns.extend([
815
+ 'AUTOSCALING_POLICY', 'LOAD_BALANCING_POLICY', 'REQUESTED_RESOURCES'
816
+ ])
815
817
  service_table = log_utils.create_table(service_columns)
816
818
 
817
819
  replica_infos = []
@@ -832,6 +834,7 @@ def format_service_table(service_records: List[Dict[str, Any]],
832
834
  endpoint = get_endpoint(record)
833
835
  policy = record['policy']
834
836
  requested_resources_str = record['requested_resources_str']
837
+ load_balancing_policy = record['load_balancing_policy']
835
838
 
836
839
  service_values = [
837
840
  service_name,
@@ -842,7 +845,8 @@ def format_service_table(service_records: List[Dict[str, Any]],
842
845
  endpoint,
843
846
  ]
844
847
  if show_all:
845
- service_values.extend([policy, requested_resources_str])
848
+ service_values.extend(
849
+ [policy, load_balancing_policy, requested_resources_str])
846
850
  service_table.add_row(service_values)
847
851
 
848
852
  replica_table = _format_replica_table(replica_infos, show_all)
sky/serve/service.py CHANGED
@@ -150,6 +150,7 @@ def _start(service_name: str, tmp_task_yaml: str, job_id: int):
150
150
  controller_job_id=job_id,
151
151
  policy=service_spec.autoscaling_policy_str(),
152
152
  requested_resources_str=backend_utils.get_task_resources_str(task),
153
+ load_balancing_policy=service_spec.load_balancing_policy,
153
154
  status=serve_state.ServiceStatus.CONTROLLER_INIT)
154
155
  # Directly throw an error here. See sky/serve/api.py::up
155
156
  # for more details.
sky/serve/service_spec.py CHANGED
@@ -8,6 +8,7 @@ import yaml
8
8
 
9
9
  from sky import serve
10
10
  from sky.serve import constants
11
+ from sky.serve import load_balancing_policies as lb_policies
11
12
  from sky.utils import common_utils
12
13
  from sky.utils import schemas
13
14
  from sky.utils import ux_utils
@@ -327,5 +328,6 @@ class SkyServiceSpec:
327
328
  return self._use_ondemand_fallback
328
329
 
329
330
  @property
330
- def load_balancing_policy(self) -> Optional[str]:
331
- return self._load_balancing_policy
331
+ def load_balancing_policy(self) -> str:
332
+ return lb_policies.LoadBalancingPolicy.make_policy_name(
333
+ self._load_balancing_policy)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: skypilot-nightly
3
- Version: 1.0.0.dev20241220
3
+ Version: 1.0.0.dev20241221
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=v_p7xNUZF9frwvqSyWlYtzPH1cANA1dA83B7dzndVl0,5944
1
+ sky/__init__.py,sha256=PT4n67F3bRiUrj8lUmXPGOp1PG_ib48eEcF1y7gYmKQ,5944
2
2
  sky/admin_policy.py,sha256=hPo02f_A32gCqhUueF0QYy1fMSSKqRwYEg_9FxScN_s,3248
3
3
  sky/authentication.py,sha256=kACHmiZgWgRpYd1wx1ofbXRMErfMcFmWrkw4a9NxYrY,20988
4
4
  sky/check.py,sha256=Gg_62eCyNNYxu6oFiQTMr4XXJf7MjfZMdYOVS-v0SOc,9465
@@ -140,7 +140,7 @@ sky/provision/kubernetes/config.py,sha256=WEKcFXXhe89bLGAvoMiBvTDxdxkpTIA6ezrj2v
140
140
  sky/provision/kubernetes/instance.py,sha256=2pju1RDzH5vOXbOTgPzCToGdCjmqIouhA0wRUFytLnc,50257
141
141
  sky/provision/kubernetes/network.py,sha256=EpNjRQ131CXepqbdkoRKFu4szVrm0oKEpv1l8EgOkjU,12364
142
142
  sky/provision/kubernetes/network_utils.py,sha256=t1FS3K400fetH7cBuRgQJZl5_jEeMshsvsYmnMUcq8k,11399
143
- sky/provision/kubernetes/utils.py,sha256=PZ1hrgmzZnwtGGLNrT6PXG8Ke9geNGpdEr1OUew8sqQ,102869
143
+ sky/provision/kubernetes/utils.py,sha256=W5CMFkkU3QEB219yPUZNOulsNghj_gcPJC6DOlZBwGM,102907
144
144
  sky/provision/kubernetes/manifests/smarter-device-manager-configmap.yaml,sha256=AMzYzlY0JIlfBWj5eX054Rc1XDW2thUcLSOGMJVhIdA,229
145
145
  sky/provision/kubernetes/manifests/smarter-device-manager-daemonset.yaml,sha256=RtTq4F1QUmR2Uunb6zuuRaPhV7hpesz4saHjn3Ncsb4,2010
146
146
  sky/provision/lambda_cloud/__init__.py,sha256=6EEvSgtUeEiup9ivIFevHmgv0GqleroO2X0K7TRa2nE,612
@@ -182,14 +182,14 @@ sky/serve/__init__.py,sha256=Bqw8nB9u1QF3ryjbV797SPZq0DWAcjT94E_5B8J24ag,1808
182
182
  sky/serve/autoscalers.py,sha256=khY1oZ22PRaUQNsLCoNKH178X_NiJw0LSLOKr7_LNgY,30275
183
183
  sky/serve/constants.py,sha256=7MflfgTHO9gDSux93U4BmNeEMWXxZB4q7I54KUwgp-s,4651
184
184
  sky/serve/controller.py,sha256=R5iIEGEEFtbm_6MvSGelYZP-vSmW0cSFuy64OexUc4g,11719
185
- sky/serve/core.py,sha256=gSf5jsRKnmHvTBE28zYqQ6xOYzYMuO4prYz9boSLUBs,31602
186
- sky/serve/load_balancer.py,sha256=I4W66eh1t1kA_C_VaMPI76WeDTCl3Z6rFxF6rQIWd6E,12636
187
- sky/serve/load_balancing_policies.py,sha256=_k4tkwIvhulR02Ln9ixYB_b97KOypr2xfSjMx8_zky0,3143
185
+ sky/serve/core.py,sha256=YFwbow_36QJ6TE4POJhkDipmilULMY-HVCXTWo0MWyM,32308
186
+ sky/serve/load_balancer.py,sha256=nNvDPJPRIrBc_qsBYJz1zzKa_fXDgfi0VDUf4SJEuW8,12990
187
+ sky/serve/load_balancing_policies.py,sha256=XVj76qBgqh7h6wfx53RKQFzBefDWTE4TCdCEtFLLtI4,5398
188
188
  sky/serve/replica_managers.py,sha256=1xYDK9Te5wFEF5hUK0gyNIUib0MY-HScLHUBDlTSl-k,57774
189
- sky/serve/serve_state.py,sha256=Q7De4GoBEPxlN_t1Lpn-Y1fd94SeHZ3E-94f1OTuhpc,19086
190
- sky/serve/serve_utils.py,sha256=FYJdXaNvoMJFFt7x5Jua9PT-hLRL9J9nKI1BkkBtdxw,39452
191
- sky/serve/service.py,sha256=gVem2vX8XuR_1wTqwrzbszQAbjzjDP2ddd787aynT9g,12017
192
- sky/serve/service_spec.py,sha256=34dMQ37INHltBzWaxHl3y_o9X3wLOCWA5jUhmhH1II4,14740
189
+ sky/serve/serve_state.py,sha256=Q274Ttm1oQ9blMVclyqyPmBONsh7oIAsIow_Q9imzjk,19762
190
+ sky/serve/serve_utils.py,sha256=jmwpx6Oe6RL_VzLrp90yQffBFfMImT0cplvMvd0UNOE,39615
191
+ sky/serve/service.py,sha256=7bvK9R9D48PZSYcOKSievXQ2mHUMk1d3AAIxtra7WOI,12083
192
+ sky/serve/service_spec.py,sha256=2NHs4h_Bf8YcQ2LiOCDV47vMCm3pUmGMlUzVAwk_Qc0,14854
193
193
  sky/setup_files/MANIFEST.in,sha256=WF0T89NLichHxZDDSQzvSpiONtAEFyur2MPmGczgTIo,555
194
194
  sky/setup_files/dependencies.py,sha256=-_9ekkrmrU9vF7I9cqz_xP55qaSZ-qz2KfGVgQDQTTY,5903
195
195
  sky/setup_files/setup.py,sha256=HMqAIxHrhtQUOlm6_Iz5E_bL4dUvsYgXc9YVQIFayPs,7417
@@ -279,9 +279,9 @@ sky/utils/kubernetes/k8s_gpu_labeler_job.yaml,sha256=k0TBoQ4zgf79-sVkixKSGYFHQ7Z
279
279
  sky/utils/kubernetes/k8s_gpu_labeler_setup.yaml,sha256=VLKT2KKimZu1GDg_4AIlIt488oMQvhRZWwsj9vBbPUg,3812
280
280
  sky/utils/kubernetes/rsync_helper.sh,sha256=h4YwrPFf9727CACnMJvF3EyK_0OeOYKKt4su_daKekw,1256
281
281
  sky/utils/kubernetes/ssh_jump_lifecycle_manager.py,sha256=RFLJ3k7MR5UN4SKHykQ0lV9SgXumoULpKYIAt1vh-HU,6560
282
- skypilot_nightly-1.0.0.dev20241220.dist-info/LICENSE,sha256=emRJAvE7ngL6x0RhQvlns5wJzGI3NEQ_WMjNmd9TZc4,12170
283
- skypilot_nightly-1.0.0.dev20241220.dist-info/METADATA,sha256=uoKOU3FUyqPQueV1FoF8ied1VhOpu6GWNyaYAjCP6xw,20149
284
- skypilot_nightly-1.0.0.dev20241220.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
285
- skypilot_nightly-1.0.0.dev20241220.dist-info/entry_points.txt,sha256=StA6HYpuHj-Y61L2Ze-hK2IcLWgLZcML5gJu8cs6nU4,36
286
- skypilot_nightly-1.0.0.dev20241220.dist-info/top_level.txt,sha256=qA8QuiNNb6Y1OF-pCUtPEr6sLEwy2xJX06Bd_CrtrHY,4
287
- skypilot_nightly-1.0.0.dev20241220.dist-info/RECORD,,
282
+ skypilot_nightly-1.0.0.dev20241221.dist-info/LICENSE,sha256=emRJAvE7ngL6x0RhQvlns5wJzGI3NEQ_WMjNmd9TZc4,12170
283
+ skypilot_nightly-1.0.0.dev20241221.dist-info/METADATA,sha256=4844wOLUspN7oJE0chOWux3KrMtI_weLbd8tX7rYIeo,20149
284
+ skypilot_nightly-1.0.0.dev20241221.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
285
+ skypilot_nightly-1.0.0.dev20241221.dist-info/entry_points.txt,sha256=StA6HYpuHj-Y61L2Ze-hK2IcLWgLZcML5gJu8cs6nU4,36
286
+ skypilot_nightly-1.0.0.dev20241221.dist-info/top_level.txt,sha256=qA8QuiNNb6Y1OF-pCUtPEr6sLEwy2xJX06Bd_CrtrHY,4
287
+ skypilot_nightly-1.0.0.dev20241221.dist-info/RECORD,,