skypilot-nightly 1.0.0.dev20241025__py3-none-any.whl → 1.0.0.dev20241027__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.
Files changed (41) hide show
  1. sky/__init__.py +2 -2
  2. sky/backends/cloud_vm_ray_backend.py +15 -0
  3. sky/cli.py +1 -1
  4. sky/clouds/aws.py +4 -7
  5. sky/clouds/azure.py +7 -9
  6. sky/clouds/cloud.py +11 -7
  7. sky/clouds/cudo.py +4 -7
  8. sky/clouds/fluidstack.py +4 -7
  9. sky/clouds/gcp.py +2 -2
  10. sky/clouds/ibm.py +4 -7
  11. sky/clouds/kubernetes.py +4 -7
  12. sky/clouds/lambda_cloud.py +4 -7
  13. sky/clouds/oci.py +9 -8
  14. sky/clouds/paperspace.py +4 -7
  15. sky/clouds/runpod.py +4 -7
  16. sky/clouds/scp.py +4 -7
  17. sky/clouds/service_catalog/__init__.py +1 -1
  18. sky/clouds/service_catalog/aws_catalog.py +2 -2
  19. sky/clouds/service_catalog/azure_catalog.py +16 -5
  20. sky/clouds/service_catalog/common.py +15 -6
  21. sky/clouds/service_catalog/cudo_catalog.py +2 -2
  22. sky/clouds/service_catalog/data_fetchers/fetch_azure.py +21 -11
  23. sky/clouds/service_catalog/fluidstack_catalog.py +2 -2
  24. sky/clouds/service_catalog/ibm_catalog.py +2 -2
  25. sky/clouds/service_catalog/lambda_catalog.py +2 -2
  26. sky/clouds/service_catalog/oci_catalog.py +2 -2
  27. sky/clouds/service_catalog/paperspace_catalog.py +2 -2
  28. sky/clouds/service_catalog/runpod_catalog.py +2 -2
  29. sky/clouds/service_catalog/scp_catalog.py +2 -2
  30. sky/clouds/service_catalog/vsphere_catalog.py +2 -2
  31. sky/clouds/vsphere.py +4 -7
  32. sky/jobs/controller.py +29 -34
  33. sky/provision/kubernetes/instance.py +66 -2
  34. sky/resources.py +1 -1
  35. sky/utils/resources_utils.py +13 -1
  36. {skypilot_nightly-1.0.0.dev20241025.dist-info → skypilot_nightly-1.0.0.dev20241027.dist-info}/METADATA +1 -1
  37. {skypilot_nightly-1.0.0.dev20241025.dist-info → skypilot_nightly-1.0.0.dev20241027.dist-info}/RECORD +41 -41
  38. {skypilot_nightly-1.0.0.dev20241025.dist-info → skypilot_nightly-1.0.0.dev20241027.dist-info}/LICENSE +0 -0
  39. {skypilot_nightly-1.0.0.dev20241025.dist-info → skypilot_nightly-1.0.0.dev20241027.dist-info}/WHEEL +0 -0
  40. {skypilot_nightly-1.0.0.dev20241025.dist-info → skypilot_nightly-1.0.0.dev20241027.dist-info}/entry_points.txt +0 -0
  41. {skypilot_nightly-1.0.0.dev20241025.dist-info → skypilot_nightly-1.0.0.dev20241027.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,7 @@
1
1
  """Cudo Compute Offerings Catalog."""
2
2
 
3
3
  import typing
4
- from typing import Dict, List, Optional, Tuple
4
+ from typing import Dict, List, Optional, Tuple, Union
5
5
 
6
6
  from sky.clouds.service_catalog import common
7
7
  import sky.provision.cudo.cudo_machine_type as cudo_mt
@@ -66,7 +66,7 @@ def get_default_instance_type(cpus: Optional[str] = None,
66
66
 
67
67
 
68
68
  def get_accelerators_from_instance_type(
69
- instance_type: str) -> Optional[Dict[str, int]]:
69
+ instance_type: str) -> Optional[Dict[str, Union[int, float]]]:
70
70
  return common.get_accelerators_from_instance_type_impl(_df, instance_type)
71
71
 
72
72
 
@@ -93,14 +93,15 @@ def get_regions() -> List[str]:
93
93
  # We have to manually remove it.
94
94
  DEPRECATED_FAMILIES = ['standardNVSv2Family']
95
95
 
96
- # Some A10 instance types only contains a fractional of GPU. We temporarily
97
- # filter them out here to avoid using it as a whole A10 GPU.
98
- # TODO(zhwu,tian): support fractional GPUs, which can be done on
99
- # kubernetes as well.
96
+ # Azure has those fractional A10 instance types, which still shows has 1 A10 GPU
97
+ # in the API response. We manually changing the number of GPUs to a float here.
100
98
  # Ref: https://learn.microsoft.com/en-us/azure/virtual-machines/nva10v5-series
101
- FILTERED_A10_INSTANCE_TYPES = [
102
- f'Standard_NV{vcpu}ads_A10_v5' for vcpu in [6, 12, 18]
103
- ]
99
+ # TODO(zhwu,tian): Support fractional GPUs on k8s as well.
100
+ # TODO(tian): Maybe we should support literally fractional count, i.e. A10:1/6
101
+ # instead of float point count (A10:0.167).
102
+ AZURE_FRACTIONAL_A10_INS_TYPE_TO_NUM_GPUS = {
103
+ f'Standard_NV{vcpu}ads_A10_v5': round(vcpu / 36, 3) for vcpu in [6, 12, 18]
104
+ }
104
105
 
105
106
  USEFUL_COLUMNS = [
106
107
  'InstanceType', 'AcceleratorName', 'AcceleratorCount', 'vCPUs', 'MemoryGiB',
@@ -274,6 +275,19 @@ def get_all_regions_instance_types_df(region_set: Set[str]):
274
275
  axis='columns',
275
276
  )
276
277
 
278
+ def _upd_a10_gpu_count(row):
279
+ new_gpu_cnt = AZURE_FRACTIONAL_A10_INS_TYPE_TO_NUM_GPUS.get(
280
+ row['InstanceType'])
281
+ if new_gpu_cnt is not None:
282
+ return new_gpu_cnt
283
+ return row['AcceleratorCount']
284
+
285
+ # Manually update the GPU count for fractional A10 instance types.
286
+ # Those instance types have fractional GPU count, but Azure API returns
287
+ # 1 GPU count for them. We manually update the GPU count here.
288
+ df_ret['AcceleratorCount'] = df_ret.apply(_upd_a10_gpu_count,
289
+ axis='columns')
290
+
277
291
  # As of Dec 2023, a few H100 instance types fetched from Azure APIs do not
278
292
  # have pricing:
279
293
  #
@@ -299,10 +313,6 @@ def get_all_regions_instance_types_df(region_set: Set[str]):
299
313
  after_drop_len = len(df_ret)
300
314
  print(f'Dropped {before_drop_len - after_drop_len} duplicated rows')
301
315
 
302
- # Filter out instance types that only contain a fractional of GPU.
303
- df_ret = df_ret.loc[~df_ret['InstanceType'].isin(FILTERED_A10_INSTANCE_TYPES
304
- )]
305
-
306
316
  # Filter out deprecated families
307
317
  df_ret = df_ret.loc[~df_ret['family'].isin(DEPRECATED_FAMILIES)]
308
318
  df_ret = df_ret[USEFUL_COLUMNS]
@@ -4,7 +4,7 @@ This module loads the service catalog file and can be used to query
4
4
  instance types and pricing information for FluidStack.
5
5
  """
6
6
  import typing
7
- from typing import Dict, List, Optional, Tuple
7
+ from typing import Dict, List, Optional, Tuple, Union
8
8
 
9
9
  from sky.clouds.service_catalog import common
10
10
  from sky.utils import ux_utils
@@ -65,7 +65,7 @@ def get_default_instance_type(cpus: Optional[str] = None,
65
65
 
66
66
 
67
67
  def get_accelerators_from_instance_type(
68
- instance_type: str) -> Optional[Dict[str, int]]:
68
+ instance_type: str) -> Optional[Dict[str, Union[int, float]]]:
69
69
  return common.get_accelerators_from_instance_type_impl(_df, instance_type)
70
70
 
71
71
 
@@ -4,7 +4,7 @@ This module loads the service catalog file and can be used to query
4
4
  instance types and pricing information for IBM.
5
5
  """
6
6
 
7
- from typing import Dict, List, Optional, Tuple
7
+ from typing import Dict, List, Optional, Tuple, Union
8
8
 
9
9
  from sky import sky_logging
10
10
  from sky.adaptors import ibm
@@ -43,7 +43,7 @@ def get_vcpus_mem_from_instance_type(
43
43
 
44
44
 
45
45
  def get_accelerators_from_instance_type(
46
- instance_type: str) -> Optional[Dict[str, int]]:
46
+ instance_type: str) -> Optional[Dict[str, Union[int, float]]]:
47
47
  return common.get_accelerators_from_instance_type_impl(_df, instance_type)
48
48
 
49
49
 
@@ -4,7 +4,7 @@ This module loads the service catalog file and can be used to query
4
4
  instance types and pricing information for Lambda.
5
5
  """
6
6
  import typing
7
- from typing import Dict, List, Optional, Tuple
7
+ from typing import Dict, List, Optional, Tuple, Union
8
8
 
9
9
  from sky.clouds.service_catalog import common
10
10
  from sky.utils import resources_utils
@@ -72,7 +72,7 @@ def get_default_instance_type(
72
72
 
73
73
 
74
74
  def get_accelerators_from_instance_type(
75
- instance_type: str) -> Optional[Dict[str, int]]:
75
+ instance_type: str) -> Optional[Dict[str, Union[int, float]]]:
76
76
  return common.get_accelerators_from_instance_type_impl(_df, instance_type)
77
77
 
78
78
 
@@ -14,7 +14,7 @@ History:
14
14
  import logging
15
15
  import threading
16
16
  import typing
17
- from typing import Dict, List, Optional, Tuple
17
+ from typing import Dict, List, Optional, Tuple, Union
18
18
 
19
19
  from sky.adaptors import oci as oci_adaptor
20
20
  from sky.clouds import OCI
@@ -131,7 +131,7 @@ def get_default_instance_type(
131
131
 
132
132
 
133
133
  def get_accelerators_from_instance_type(
134
- instance_type: str) -> Optional[Dict[str, int]]:
134
+ instance_type: str) -> Optional[Dict[str, Union[int, float]]]:
135
135
  return common.get_accelerators_from_instance_type_impl(
136
136
  _get_df(), instance_type)
137
137
 
@@ -5,7 +5,7 @@ query instance types and pricing information for Paperspace.
5
5
  """
6
6
 
7
7
  import typing
8
- from typing import Dict, List, Optional, Tuple
8
+ from typing import Dict, List, Optional, Tuple, Union
9
9
 
10
10
  from sky.clouds.service_catalog import common
11
11
  from sky.utils import ux_utils
@@ -60,7 +60,7 @@ def get_default_instance_type(
60
60
 
61
61
 
62
62
  def get_accelerators_from_instance_type(
63
- instance_type: str) -> Optional[Dict[str, int]]:
63
+ instance_type: str) -> Optional[Dict[str, Union[int, float]]]:
64
64
  return common.get_accelerators_from_instance_type_impl(_df, instance_type)
65
65
 
66
66
 
@@ -5,7 +5,7 @@ query instance types and pricing information for RunPod.
5
5
  """
6
6
 
7
7
  import typing
8
- from typing import Dict, List, Optional, Tuple
8
+ from typing import Dict, List, Optional, Tuple, Union
9
9
 
10
10
  from sky.clouds.service_catalog import common
11
11
  from sky.utils import ux_utils
@@ -56,7 +56,7 @@ def get_default_instance_type(cpus: Optional[str] = None,
56
56
 
57
57
 
58
58
  def get_accelerators_from_instance_type(
59
- instance_type: str) -> Optional[Dict[str, int]]:
59
+ instance_type: str) -> Optional[Dict[str, Union[int, float]]]:
60
60
  return common.get_accelerators_from_instance_type_impl(_df, instance_type)
61
61
 
62
62
 
@@ -5,7 +5,7 @@ instance types and pricing information for SCP.
5
5
  """
6
6
 
7
7
  import typing
8
- from typing import Dict, List, Optional, Tuple
8
+ from typing import Dict, List, Optional, Tuple, Union
9
9
 
10
10
  from sky.clouds.service_catalog import common
11
11
  from sky.utils import resources_utils
@@ -67,7 +67,7 @@ def get_default_instance_type(
67
67
 
68
68
 
69
69
  def get_accelerators_from_instance_type(
70
- instance_type: str) -> Optional[Dict[str, int]]:
70
+ instance_type: str) -> Optional[Dict[str, Union[int, float]]]:
71
71
  return common.get_accelerators_from_instance_type_impl(_df, instance_type)
72
72
 
73
73
 
@@ -2,7 +2,7 @@
2
2
  import io
3
3
  import os
4
4
  import typing
5
- from typing import Dict, List, Optional, Tuple
5
+ from typing import Dict, List, Optional, Tuple, Union
6
6
 
7
7
  from sky.adaptors import common as adaptors_common
8
8
  from sky.clouds.service_catalog import common
@@ -85,7 +85,7 @@ def get_default_instance_type(
85
85
 
86
86
 
87
87
  def get_accelerators_from_instance_type(
88
- instance_type: str) -> Optional[Dict[str, int]]:
88
+ instance_type: str) -> Optional[Dict[str, Union[int, float]]]:
89
89
  return common.get_accelerators_from_instance_type_impl(
90
90
  _get_df(), instance_type)
91
91
 
sky/clouds/vsphere.py CHANGED
@@ -1,8 +1,7 @@
1
1
  """Vsphere cloud implementation."""
2
- import json
3
2
  import subprocess
4
3
  import typing
5
- from typing import Dict, Iterator, List, Optional, Tuple
4
+ from typing import Dict, Iterator, List, Optional, Tuple, Union
6
5
 
7
6
  import requests
8
7
 
@@ -152,7 +151,7 @@ class Vsphere(clouds.Cloud):
152
151
  def get_accelerators_from_instance_type(
153
152
  cls,
154
153
  instance_type: str,
155
- ) -> Optional[Dict[str, int]]:
154
+ ) -> Optional[Dict[str, Union[int, float]]]:
156
155
  return service_catalog.get_accelerators_from_instance_type(
157
156
  instance_type, clouds=_CLOUD_VSPHERE)
158
157
 
@@ -182,10 +181,8 @@ class Vsphere(clouds.Cloud):
182
181
  zone_names = [zone.name for zone in zones]
183
182
  r = resources
184
183
  acc_dict = self.get_accelerators_from_instance_type(r.instance_type)
185
- if acc_dict is not None:
186
- custom_resources = json.dumps(acc_dict, separators=(',', ':'))
187
- else:
188
- custom_resources = None
184
+ custom_resources = resources_utils.make_ray_custom_resources_str(
185
+ acc_dict)
189
186
 
190
187
  return {
191
188
  'instance_type': resources.instance_type,
sky/jobs/controller.py CHANGED
@@ -215,7 +215,7 @@ class JobsController:
215
215
  end_time=end_time,
216
216
  callback_func=callback_func)
217
217
  logger.info(
218
- f'Spot job {self._job_id} (task: {task_id}) SUCCEEDED. '
218
+ f'Managed job {self._job_id} (task: {task_id}) SUCCEEDED. '
219
219
  f'Cleaning up the cluster {cluster_name}.')
220
220
  # Only clean up the cluster, not the storages, because tasks may
221
221
  # share storages.
@@ -340,48 +340,28 @@ class JobsController:
340
340
  common_utils.format_exception(reason, use_bracket=True)
341
341
  for reason in e.reasons))
342
342
  logger.error(failure_reason)
343
- managed_job_state.set_failed(
344
- self._job_id,
345
- task_id=task_id,
346
- failure_type=managed_job_state.ManagedJobStatus.
347
- FAILED_PRECHECKS,
348
- failure_reason=failure_reason,
349
- callback_func=managed_job_utils.event_callback_func(
350
- job_id=self._job_id,
351
- task_id=task_id,
352
- task=self._dag.tasks[task_id]))
343
+ self._update_failed_task_state(
344
+ task_id, managed_job_state.ManagedJobStatus.FAILED_PRECHECKS,
345
+ failure_reason)
353
346
  except exceptions.ManagedJobReachedMaxRetriesError as e:
354
347
  # Please refer to the docstring of self._run for the cases when
355
348
  # this exception can occur.
356
- logger.error(common_utils.format_exception(e))
349
+ failure_reason = common_utils.format_exception(e)
350
+ logger.error(failure_reason)
357
351
  # The managed job should be marked as FAILED_NO_RESOURCE, as the
358
352
  # managed job may be able to launch next time.
359
- managed_job_state.set_failed(
360
- self._job_id,
361
- task_id=task_id,
362
- failure_type=managed_job_state.ManagedJobStatus.
363
- FAILED_NO_RESOURCE,
364
- failure_reason=common_utils.format_exception(e),
365
- callback_func=managed_job_utils.event_callback_func(
366
- job_id=self._job_id,
367
- task_id=task_id,
368
- task=self._dag.tasks[task_id]))
353
+ self._update_failed_task_state(
354
+ task_id, managed_job_state.ManagedJobStatus.FAILED_NO_RESOURCE,
355
+ failure_reason)
369
356
  except (Exception, SystemExit) as e: # pylint: disable=broad-except
370
357
  with ux_utils.enable_traceback():
371
358
  logger.error(traceback.format_exc())
372
- msg = ('Unexpected error occurred: '
373
- f'{common_utils.format_exception(e, use_bracket=True)}')
359
+ msg = ('Unexpected error occurred: ' +
360
+ common_utils.format_exception(e, use_bracket=True))
374
361
  logger.error(msg)
375
- managed_job_state.set_failed(
376
- self._job_id,
377
- task_id=task_id,
378
- failure_type=managed_job_state.ManagedJobStatus.
379
- FAILED_CONTROLLER,
380
- failure_reason=msg,
381
- callback_func=managed_job_utils.event_callback_func(
382
- job_id=self._job_id,
383
- task_id=task_id,
384
- task=self._dag.tasks[task_id]))
362
+ self._update_failed_task_state(
363
+ task_id, managed_job_state.ManagedJobStatus.FAILED_CONTROLLER,
364
+ msg)
385
365
  finally:
386
366
  # This will set all unfinished tasks to CANCELLING, and will not
387
367
  # affect the jobs in terminal states.
@@ -396,6 +376,21 @@ class JobsController:
396
376
  managed_job_state.set_cancelled(job_id=self._job_id,
397
377
  callback_func=callback_func)
398
378
 
379
+ def _update_failed_task_state(
380
+ self, task_id: int,
381
+ failure_type: managed_job_state.ManagedJobStatus,
382
+ failure_reason: str):
383
+ """Update the state of the failed task."""
384
+ managed_job_state.set_failed(
385
+ self._job_id,
386
+ task_id=task_id,
387
+ failure_type=failure_type,
388
+ failure_reason=failure_reason,
389
+ callback_func=managed_job_utils.event_callback_func(
390
+ job_id=self._job_id,
391
+ task_id=task_id,
392
+ task=self._dag.tasks[task_id]))
393
+
399
394
 
400
395
  def _run_controller(job_id: int, dag_yaml: str, retry_until_up: bool):
401
396
  """Runs the controller in a remote process for interruption."""
@@ -1,5 +1,6 @@
1
1
  """Kubernetes instance provisioning."""
2
2
  import copy
3
+ import json
3
4
  import time
4
5
  from typing import Any, Dict, List, Optional
5
6
  import uuid
@@ -425,6 +426,70 @@ def _label_pod(namespace: str, context: Optional[str], pod_name: str,
425
426
  _request_timeout=kubernetes.API_TIMEOUT)
426
427
 
427
428
 
429
+ def _create_namespaced_pod_with_retries(namespace: str, pod_spec: dict,
430
+ context: Optional[str]) -> Any:
431
+ """Attempts to create a Kubernetes Pod and handle any errors.
432
+
433
+ Currently, we handle errors due to the AppArmor annotation and retry if
434
+ it fails due to the `FieldValueForbidden` error.
435
+ See https://github.com/skypilot-org/skypilot/issues/4174 for details.
436
+
437
+ Returns: The created Pod object.
438
+ """
439
+ try:
440
+ # Attempt to create the Pod with the AppArmor annotation
441
+ pod = kubernetes.core_api(context).create_namespaced_pod(
442
+ namespace, pod_spec)
443
+ return pod
444
+ except kubernetes.api_exception() as e:
445
+ try:
446
+ error_body = json.loads(e.body)
447
+ error_message = error_body.get('message', '')
448
+ except json.JSONDecodeError:
449
+ error_message = str(e.body)
450
+ # Check if the error is due to the AppArmor annotation and retry.
451
+ # We add an AppArmor annotation to set it as unconfined in our
452
+ # base template in kubernetes-ray.yml.j2. This is required for
453
+ # FUSE to work in the pod on most Kubernetes distributions.
454
+ # However, some distributions do not support the AppArmor annotation
455
+ # and will fail to create the pod. In this case, we retry without
456
+ # the annotation.
457
+ if (e.status == 422 and 'FieldValueForbidden' in error_message and
458
+ 'AppArmorProfile: nil' in error_message):
459
+ logger.warning('AppArmor annotation caused pod creation to fail. '
460
+ 'Retrying without the annotation. '
461
+ 'Note: this may cause bucket mounting to fail.')
462
+
463
+ # Remove the AppArmor annotation
464
+ annotations = pod_spec.get('metadata', {}).get('annotations', {})
465
+ if ('container.apparmor.security.beta.kubernetes.io/ray-node'
466
+ in annotations):
467
+ del annotations[
468
+ 'container.apparmor.security.beta.kubernetes.io/ray-node']
469
+ pod_spec['metadata']['annotations'] = annotations
470
+ logger.info('AppArmor annotation removed from Pod spec.')
471
+ else:
472
+ logger.warning('AppArmor annotation not found in pod spec, '
473
+ 'retrying will not help. '
474
+ f'Current annotations: {annotations}')
475
+ raise e
476
+
477
+ # Retry Pod creation without the AppArmor annotation
478
+ try:
479
+ pod = kubernetes.core_api(context).create_namespaced_pod(
480
+ namespace, pod_spec)
481
+ logger.info(f'Pod {pod.metadata.name} created successfully '
482
+ 'without AppArmor annotation.')
483
+ return pod
484
+ except kubernetes.api_exception() as retry_exception:
485
+ logger.info('Failed to create Pod without AppArmor annotation: '
486
+ f'{retry_exception}')
487
+ raise retry_exception
488
+ else:
489
+ # Re-raise the exception if it's a different error
490
+ raise e
491
+
492
+
428
493
  def _create_pods(region: str, cluster_name_on_cloud: str,
429
494
  config: common.ProvisionConfig) -> common.ProvisionRecord:
430
495
  """Create pods based on the config."""
@@ -546,8 +611,7 @@ def _create_pods(region: str, cluster_name_on_cloud: str,
546
611
  }
547
612
  }
548
613
 
549
- pod = kubernetes.core_api(context).create_namespaced_pod(
550
- namespace, pod_spec)
614
+ pod = _create_namespaced_pod_with_retries(namespace, pod_spec, context)
551
615
  created_pods[pod.metadata.name] = pod
552
616
  if head_pod_name is None:
553
617
  head_pod_name = pod.metadata.name
sky/resources.py CHANGED
@@ -392,7 +392,7 @@ class Resources:
392
392
 
393
393
  @property
394
394
  @functools.lru_cache(maxsize=1)
395
- def accelerators(self) -> Optional[Dict[str, int]]:
395
+ def accelerators(self) -> Optional[Dict[str, Union[int, float]]]:
396
396
  """Returns the accelerators field directly or by inferring.
397
397
 
398
398
  For example, Resources(AWS, 'p3.2xlarge') has its accelerators field
@@ -2,9 +2,11 @@
2
2
  import dataclasses
3
3
  import enum
4
4
  import itertools
5
+ import json
6
+ import math
5
7
  import re
6
8
  import typing
7
- from typing import List, Optional, Set
9
+ from typing import Dict, List, Optional, Set, Union
8
10
 
9
11
  from sky import skypilot_config
10
12
  from sky.clouds import cloud_registry
@@ -163,6 +165,16 @@ def get_readable_resources_repr(handle: 'backends.CloudVmRayResourceHandle',
163
165
  return _DEFAULT_MESSAGE_HANDLE_INITIALIZING
164
166
 
165
167
 
168
+ def make_ray_custom_resources_str(
169
+ resource_dict: Optional[Dict[str, Union[int, float]]]) -> Optional[str]:
170
+ """Convert resources to Ray custom resources format."""
171
+ if resource_dict is None:
172
+ return None
173
+ # Ray does not allow fractional resources, so we need to ceil the values.
174
+ ceiled_dict = {k: math.ceil(v) for k, v in resource_dict.items()}
175
+ return json.dumps(ceiled_dict, separators=(',', ':'))
176
+
177
+
166
178
  @dataclasses.dataclass
167
179
  class FeasibleResources:
168
180
  """Feasible resources returned by cloud.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: skypilot-nightly
3
- Version: 1.0.0.dev20241025
3
+ Version: 1.0.0.dev20241027
4
4
  Summary: SkyPilot: An intercloud broker for the clouds
5
5
  Author: SkyPilot Team
6
6
  License: Apache 2.0
@@ -1,8 +1,8 @@
1
- sky/__init__.py,sha256=GSmePpdUEM88IzUu72hNEsvulpIRguwT7aXuz3ked5s,5882
1
+ sky/__init__.py,sha256=vpgIm3u2yoG-2u6WNprtRFZxBjFGPIJFMslH3OZwLLw,5882
2
2
  sky/admin_policy.py,sha256=hPo02f_A32gCqhUueF0QYy1fMSSKqRwYEg_9FxScN_s,3248
3
3
  sky/authentication.py,sha256=pAdCT60OxxiXI9KXDyP2lQ9u9vMc6aMtq5Xi2h_hbdw,20984
4
4
  sky/check.py,sha256=D3Y3saIFAYVvPxuBHnVgJEO0fUVDxgjwuMBaO-D778k,9472
5
- sky/cli.py,sha256=4HOGW3LTDlPNXHqvTykcM8iMWOCdAK90l6w34DYBIsg,210357
5
+ sky/cli.py,sha256=VoPwWKGeNZZcFNLvw3VPR_F0WpKnM5EvfffNS8kcKc0,210360
6
6
  sky/cloud_stores.py,sha256=RjFgmRhUh1Kk__f6g3KxzLp9s7dA0pFK4W1AukEuUaw,21153
7
7
  sky/core.py,sha256=DW9OGE2kS2CmsvQ1grrpRnNFS3woMGWSHu5GE99e-I4,38190
8
8
  sky/dag.py,sha256=WLFWr5hfrwjd31uYlNvI-zWUk7tLaT_gzJn4LzbVtkE,2780
@@ -10,7 +10,7 @@ sky/exceptions.py,sha256=KBIEJHgrw6OMBL8H65o-Gk6qYQEV1SR9gBwMjnMnxxg,8858
10
10
  sky/execution.py,sha256=CbrKMgfc2JgLqZqwPvmYKxbWAQKYqHpOLpUEOb-k2m0,24679
11
11
  sky/global_user_state.py,sha256=PywEmUutF97XBgRMClR6IS5_KM8JJC0oA1LsPUZebp0,28681
12
12
  sky/optimizer.py,sha256=OzxWiA6ZC0tyJ1eNMy4e72vitjfLKfbOLF9ywZOccXU,59343
13
- sky/resources.py,sha256=6Hhk4tdwr_pZ6m5iA4w4MZUYflAOJtJw6va3jSHsVOI,67464
13
+ sky/resources.py,sha256=bm004Ms2qlBqEr0N_TEUybDOXJVhLF8yOwkhoqb1t9c,67478
14
14
  sky/sky_logging.py,sha256=oLmTmwkuucIto3LHXLJfMcyRpYSkmZAZa5XzQPA5IHk,4434
15
15
  sky/skypilot_config.py,sha256=E3g65cX3P3dT9b5N0GgFBG6yB0FXwIGpisKoozmJmWU,9094
16
16
  sky/status_lib.py,sha256=J7Jb4_Dz0v2T64ttOdyUgpokvl4S0sBJrMfH7Fvo51A,1457
@@ -31,7 +31,7 @@ sky/adaptors/vsphere.py,sha256=zJP9SeObEoLrpgHW2VHvZE48EhgVf8GfAEIwBeaDMfM,2129
31
31
  sky/backends/__init__.py,sha256=UDjwbUgpTRApbPJnNfR786GadUuwgRk3vsWoVu5RB_c,536
32
32
  sky/backends/backend.py,sha256=wwfbrxPhjMPs6PSyy3tAHI8WJhl-xhgzWBsAZjmJJ6g,6249
33
33
  sky/backends/backend_utils.py,sha256=PA21DAXspXuTZDQ5qA3G5RGJ0oUTpJ7XatRRvhtmtt0,126993
34
- sky/backends/cloud_vm_ray_backend.py,sha256=9mCLLRUD-x3ksiiPbhrMDsZWIPNU9cVSQwwpmxSia7k,236881
34
+ sky/backends/cloud_vm_ray_backend.py,sha256=D9x5TT_4IE_WhzgLjj-I7nliRmnCY9DKVwcLuJicx7s,237775
35
35
  sky/backends/docker_utils.py,sha256=Hyw1YY20EyghhEbYx6O2FIMDcGkNzBzV9TM7LFynei8,8358
36
36
  sky/backends/local_docker_backend.py,sha256=0JL5m0YUgOmOL4aWEUe4tmt89dsxjk4_WXkPwgEKEis,16801
37
37
  sky/backends/wheel_utils.py,sha256=3QS4T_Ydvo4DbYhogtyADyNBEf04I6jUCL71M285shQ,7963
@@ -40,42 +40,42 @@ sky/benchmark/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
40
  sky/benchmark/benchmark_state.py,sha256=X8CXmuU9KgsDRhKedhFgjeRMUFWtQsjFs1qECvPG2yg,8723
41
41
  sky/benchmark/benchmark_utils.py,sha256=eb-i6zYoo-Zkod-T9qtCu1FcYLw--Yyos1SyibUPZNE,26194
42
42
  sky/clouds/__init__.py,sha256=WuNIJEnZmBO72tU5awgaaL3rdvFRSkgaYNNeuY68dXo,1356
43
- sky/clouds/aws.py,sha256=XJVbOSkVVUHp9HbHDp0rFdHX113JHbY-3sgokGdNJVE,49527
44
- sky/clouds/azure.py,sha256=FklG_CEvOXLkZVoEYSCcNtPsQpq-2w6AJovzbLKun0w,30162
45
- sky/clouds/cloud.py,sha256=BBu1G-gkmylffldL50cvJ2DkDJ8vjVPziOPUAsvgJ2o,34948
43
+ sky/clouds/aws.py,sha256=dVZ8auaa2z2Ifl9iiRT06IeEFaNtZhANKtHVLT6Gcno,49474
44
+ sky/clouds/azure.py,sha256=wgR78HMn64EwgQlU9Klv-j3neVbgo4NKycaBkNHyiBc,30158
45
+ sky/clouds/cloud.py,sha256=A5F4a71ciPyljWEs6vT-4RmdGT-AE9NkhS8gJ4Vgi_I,35165
46
46
  sky/clouds/cloud_registry.py,sha256=oLoYFjm_SDTgdHokY7b6A5Utq80HXRQNxV0fLjDdVsQ,2361
47
- sky/clouds/cudo.py,sha256=H4VyMo5wWGAv2MXZ3xsbWjlZA_cZYnt4ecNlTOOao8Y,13147
48
- sky/clouds/fluidstack.py,sha256=iOmoOx52yTrHKMzwBDaxFJCfNo79M61d5tj-Np24Lyc,12436
49
- sky/clouds/gcp.py,sha256=m_dH04HqgU-DdW4R9wrSr66IpPt9JMKHEvHEGGFpeRo,54655
50
- sky/clouds/ibm.py,sha256=M8QdjeSFlwssfoY2aOodxG4q5R3eT9K-4lTPDHYvEYI,21476
51
- sky/clouds/kubernetes.py,sha256=j3imm_sbtyyZXvJ6qbqZmXok2C9OQIcGpyulljbTSJ4,28696
52
- sky/clouds/lambda_cloud.py,sha256=11dKUSunHUgaPZ1t8O85X29_NJ-o26sCt5DjwAPFgl4,12697
53
- sky/clouds/oci.py,sha256=Ve3MqVHay9oHRuK6vaCd3Rxz8fD54nfM_DKA4Qzf8l4,26963
54
- sky/clouds/paperspace.py,sha256=lmUZPYAblaqiBmGQwCunccMiTF_dVA1o3vqY9Q_Nc28,10921
55
- sky/clouds/runpod.py,sha256=lstUC6f4JDhtcH9NfwkbpCJMmfmvMigoanhPXPbTYds,11540
56
- sky/clouds/scp.py,sha256=2KLTuNSMdBzK8CLwSesv7efOuiLidIMoyNG4AOt5Sqw,15870
57
- sky/clouds/vsphere.py,sha256=7eZFYIDtY5sX_ATr8h7kwwkY9t8Z-EYMJ9HCjoRBoxI,12309
58
- sky/clouds/service_catalog/__init__.py,sha256=e0K-c64jQV9d6zly5OnIXMsYaZXs_Ko9osAbDaRlOOw,14743
59
- sky/clouds/service_catalog/aws_catalog.py,sha256=1wX1-wOMw2LZ7RkV_Ah7c42RLRYm-m5_GAXzn32M5a8,13038
60
- sky/clouds/service_catalog/azure_catalog.py,sha256=DOAzAhI5eHRHTzYDBrlNmfh3YByAoR-A9kBVeh6ZXvs,7689
61
- sky/clouds/service_catalog/common.py,sha256=PA3llB0zZh4v0DO_gDDCKGhRIBx16CAp2WJZNxhjNOA,27266
47
+ sky/clouds/cudo.py,sha256=UiY273Sln7VOYDYx93yWiWH_RLlOKZ2cm7mA31ld4A8,13094
48
+ sky/clouds/fluidstack.py,sha256=ufve4wXo_VmaEkxqTw2Jnt-DORBDRnqUPU1kB_mD89s,12383
49
+ sky/clouds/gcp.py,sha256=BjCehW3s0IYkRDdEEDm0vYWXQDpOV8KU98OMVRPnQNg,54676
50
+ sky/clouds/ibm.py,sha256=w8bo1EIY_YWYNu0fy-OpAyr6DZviU0tpIXUsiV01rVE,21423
51
+ sky/clouds/kubernetes.py,sha256=WbbxJ9IIF3HtroGJhc4akZV-Pf3_sroVcHUxKIXIk5I,28643
52
+ sky/clouds/lambda_cloud.py,sha256=ExL_uixdFrF9qSL5JYXpaOXCZ9_eOA2q444kcmBHBXQ,12644
53
+ sky/clouds/oci.py,sha256=sHJrVhUhOKvJ-skbd2ZJ82IR63OXp43krmyPpM8BZqw,27084
54
+ sky/clouds/paperspace.py,sha256=4cjNua6jpuxmfidvLY4tSRX1oj_QaaHDinPMunGplyU,10868
55
+ sky/clouds/runpod.py,sha256=_4myVdGIvQshkka8fn6mBXHgz5TZqhrNhAEM2_HrCT8,11487
56
+ sky/clouds/scp.py,sha256=NivPvzQxA90R37QR3fgTup8ScGfxKsXAhH0xklAj5QU,15817
57
+ sky/clouds/vsphere.py,sha256=ZzlcQBzv0aaRYXwZOrdKIGFK94LaOfDSV3lJBg9xyc4,12256
58
+ sky/clouds/service_catalog/__init__.py,sha256=cFZ3HLdQVa42xOhK2XxuB_xPIX4X1UR89InR4y2y_78,14757
59
+ sky/clouds/service_catalog/aws_catalog.py,sha256=vTI7h5bjZg3lItT9RBaSwY1Fl0vX5UN1CgMDM6-C1pw,13059
60
+ sky/clouds/service_catalog/azure_catalog.py,sha256=5Q51x_WEKvQ2YSgJvZHRH3URlbwIstYuwpjaWW_wJlw,8149
61
+ sky/clouds/service_catalog/common.py,sha256=GcKjtJTuPbpHoqh6CKoTfDJ2EWB9yFiIRmRUgr6oJI4,27615
62
62
  sky/clouds/service_catalog/config.py,sha256=ylzqewdEBjDg4awvFek6ldYmFrnvD2bVGLZuLPvEVYA,1793
63
63
  sky/clouds/service_catalog/constants.py,sha256=ai2yOlsVqBnEpbxaEHXt61COsHBLwOfw6GZXntEPj7k,411
64
- sky/clouds/service_catalog/cudo_catalog.py,sha256=QXAOpx5fJ_cGCr5LbB7wpHMfKIla7G-q_mMJnv_ArTA,4652
65
- sky/clouds/service_catalog/fluidstack_catalog.py,sha256=c8MMTldG-q97MJ0zJymudQiOVQC_rxS7vqrZgLrgbQA,5038
64
+ sky/clouds/service_catalog/cudo_catalog.py,sha256=V_takvL6dWTGQaTLCEvjKIotCDPnMujiNUZ87kZKGVI,4673
65
+ sky/clouds/service_catalog/fluidstack_catalog.py,sha256=21-cvrYEYTIi7n3ZNF2e7_0QX-PF4BkhlVJUWQOvKrY,5059
66
66
  sky/clouds/service_catalog/gcp_catalog.py,sha256=v_5fsB3dB9oD8U7lBKnCe5ii6AUWEOiQjNarMnU_qLA,24379
67
- sky/clouds/service_catalog/ibm_catalog.py,sha256=0dzjmXABFECzaAuIa0E6pVINhVK6-G6U52Mj-L45gK8,4472
67
+ sky/clouds/service_catalog/ibm_catalog.py,sha256=1iK0KvbI82U7sySb7chr-qm_16x3tTnZ6nIo7o76ouc,4493
68
68
  sky/clouds/service_catalog/kubernetes_catalog.py,sha256=Eezfl-tx3obgy3d2Kz2XR-_ezj_y8Dxk4oOW7Hy_g-o,8599
69
- sky/clouds/service_catalog/lambda_catalog.py,sha256=BAhUGqHj8aVe1zUhEQNO7bQUhcd9jAespGvPyQubTJY,5281
70
- sky/clouds/service_catalog/oci_catalog.py,sha256=AG1mOgc-iWaX4zapONWMZPNd2RCKCsaNOyFc0eq_LFU,8551
71
- sky/clouds/service_catalog/paperspace_catalog.py,sha256=W8GgGlPbbWViELQ8EZfmIkxSbeQcCmMRUX4ecIIYDsk,3768
72
- sky/clouds/service_catalog/runpod_catalog.py,sha256=NwZlolzihZeRxQKYIDhoXeUkJ3BSH1S6B_DszNDXT1g,4184
73
- sky/clouds/service_catalog/scp_catalog.py,sha256=4XnaZE5Q4XrrNnDnVhsHkH6jxmWXBeQqa9QqKqHKjSI,5174
74
- sky/clouds/service_catalog/vsphere_catalog.py,sha256=yJLWu9SQep-PRn1YdeQ7ZoNqQHTAxJtxf7y6FBrfSW0,4391
69
+ sky/clouds/service_catalog/lambda_catalog.py,sha256=2R-ccu63BbdvO6X80MtxiniA-jLewXb6I0Ye1rYD9fY,5302
70
+ sky/clouds/service_catalog/oci_catalog.py,sha256=DQaP0iQlxZEHWJs862ilynUfUEQDIjCGltS7kSadgYo,8572
71
+ sky/clouds/service_catalog/paperspace_catalog.py,sha256=MOlfoGRChjEwMzu4nRAho8DrIwwUJ3QlRzrMA1RLqvE,3789
72
+ sky/clouds/service_catalog/runpod_catalog.py,sha256=oWYVgSMiK3DxBE5AgROyExIq9kCTaOr3hDLSc31kqTU,4205
73
+ sky/clouds/service_catalog/scp_catalog.py,sha256=nrtD0hAZd1rUDsFuHI1hrBgAVSE5YprdWoYSXQooIqU,5195
74
+ sky/clouds/service_catalog/vsphere_catalog.py,sha256=OV3Czi3vwRSW4lqVPHxU_GND0ox322gmhv3kb11Q8AM,4412
75
75
  sky/clouds/service_catalog/data_fetchers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
76
  sky/clouds/service_catalog/data_fetchers/analyze.py,sha256=VdksJQs3asFE8H5T3ZV1FJas2xD9WEX6c-V5p7y-wp4,2084
77
77
  sky/clouds/service_catalog/data_fetchers/fetch_aws.py,sha256=ro2zazdkDF6z9bE7QFyjoeb4VFxmbNZ1WK5IQrdoQWk,23003
78
- sky/clouds/service_catalog/data_fetchers/fetch_azure.py,sha256=jsSVqbSbBIw_IYmO-y2u4co20AJ-JF713KFjUKdO_VA,12272
78
+ sky/clouds/service_catalog/data_fetchers/fetch_azure.py,sha256=L1JsX1YrhpyI7ylzEPBBNE9XOZM0K0FIXbBUMj9h0MQ,12803
79
79
  sky/clouds/service_catalog/data_fetchers/fetch_cudo.py,sha256=52P48lvWN0s1ArjeLPeLemPRpxjSRcHincRle0nqdm4,3440
80
80
  sky/clouds/service_catalog/data_fetchers/fetch_fluidstack.py,sha256=35nO_VaDOgp5W13kt_lIANSk_CNf7gBiZGJ5fGyZu6o,6808
81
81
  sky/clouds/service_catalog/data_fetchers/fetch_gcp.py,sha256=5CbgU90ldiKVgaagQTnYBJVsgVGE3cMwtF7KpBiTtvU,29873
@@ -95,7 +95,7 @@ sky/data/storage.py,sha256=x8YYY4zVBdit_5oAR_MXV-TM9qDefV_ZV4z0irv6ZaU,163102
95
95
  sky/data/storage_utils.py,sha256=cM3kxlffYE7PnJySDu8huyUsMX_JYsf9uer8r5OYsjo,9556
96
96
  sky/jobs/__init__.py,sha256=yucibSB_ZimtJMvOhMxn6ZqwBIYNfcwmc6pSXtCqmNQ,1483
97
97
  sky/jobs/constants.py,sha256=YLgcCg_RHSYr_rfsI_4UIdXk78KKKOK29Oem88t5j8I,1350
98
- sky/jobs/controller.py,sha256=k28bbicxtML6p1YxSetk-1nhBHPCubpvLWJsh7TtU9c,26701
98
+ sky/jobs/controller.py,sha256=zSdawmXg-9SZ91jJg5_OSFVlntu9xupLs-CiPwG1QdQ,26412
99
99
  sky/jobs/core.py,sha256=RkBFaKDlovmdzqlOAgQ0xAimZFgo4pXq3qaQkAvGsGk,16908
100
100
  sky/jobs/recovery_strategy.py,sha256=UOEaVGSpRbCnCzlD8cgyjhCPIBIeBeCXCutoSic5aiA,25545
101
101
  sky/jobs/state.py,sha256=C6R5Yq7ftBqGPa_71tUjflBMKAaJ1FTTdbgjAwmbJsI,23231
@@ -137,7 +137,7 @@ sky/provision/gcp/instance_utils.py,sha256=veRBr6Oziv0KaUdC4acuWeaOremNV0gMYCCHa
137
137
  sky/provision/gcp/mig_utils.py,sha256=oFpcFZoapHMILSE4iIm8V5bxP1RhbMHRF7cciqq8qAk,7883
138
138
  sky/provision/kubernetes/__init__.py,sha256=y6yVfii81WYG3ROxv4hiIj-ydinS5-xGxLvXnARVQoI,719
139
139
  sky/provision/kubernetes/config.py,sha256=WEKcFXXhe89bLGAvoMiBvTDxdxkpTIA6ezrj2vmzldc,29072
140
- sky/provision/kubernetes/instance.py,sha256=FOt77bFSKwi12J1_1qXhUrKiCqLfKWFgcRa1cLlNFlU,38453
140
+ sky/provision/kubernetes/instance.py,sha256=1dN2vdh-ZdeIe39ZxH5DAnnc8kXHWpzD6q-f14-8cDE,41576
141
141
  sky/provision/kubernetes/network.py,sha256=EpNjRQ131CXepqbdkoRKFu4szVrm0oKEpv1l8EgOkjU,12364
142
142
  sky/provision/kubernetes/network_utils.py,sha256=t1FS3K400fetH7cBuRgQJZl5_jEeMshsvsYmnMUcq8k,11399
143
143
  sky/provision/kubernetes/utils.py,sha256=2N5c4yA7CEn4DjvCiUO73W4XDEjgixcJRVdgs913QQE,89523
@@ -254,7 +254,7 @@ sky/utils/db_utils.py,sha256=AOvMmBEN9cF4I7CoXihPCtus4mU2VDGjBQSVMMgzKlA,2786
254
254
  sky/utils/env_options.py,sha256=3oAaUPxowL6vI2XmxXrH56V7Myj9IJWsL-MXFmRFVdI,1294
255
255
  sky/utils/kubernetes_enums.py,sha256=imGqHSa8O07zD_6xH1SDMM7dBU5lF5fzFFlQuQy00QM,1384
256
256
  sky/utils/log_utils.py,sha256=ptv2sbsiJSgk4NvdccrMsUR-MvOKnbu4BQiRSishgk0,12472
257
- sky/utils/resources_utils.py,sha256=sJuPextjJKHhvDGAaOPEzeEkteryF2fGNgNgBLqnLic,7419
257
+ sky/utils/resources_utils.py,sha256=Xqi7gxPYw2y5wl5okUI5zx5LEij0hJF_V3Zi8q7TXYg,7890
258
258
  sky/utils/rich_utils.py,sha256=hmnI1X5dKvRIQzB7EyNb34FT97qFNve-0QHqM5r0mVk,3066
259
259
  sky/utils/schemas.py,sha256=qo9j1TJZXqgJlBgbQfqz1oIZAxc3CN8uWooKYPQXXIY,28878
260
260
  sky/utils/subprocess_utils.py,sha256=3R54Elc2n8DQeO6Y8MCDJ6N6v27HDGpbNMIfCquqXYQ,6552
@@ -274,9 +274,9 @@ sky/utils/kubernetes/k8s_gpu_labeler_job.yaml,sha256=k0TBoQ4zgf79-sVkixKSGYFHQ7Z
274
274
  sky/utils/kubernetes/k8s_gpu_labeler_setup.yaml,sha256=VLKT2KKimZu1GDg_4AIlIt488oMQvhRZWwsj9vBbPUg,3812
275
275
  sky/utils/kubernetes/rsync_helper.sh,sha256=hyYDaYSNxYaNvzUQBzC8AidB7nDeojizjkzc_CTxycY,1077
276
276
  sky/utils/kubernetes/ssh_jump_lifecycle_manager.py,sha256=RFLJ3k7MR5UN4SKHykQ0lV9SgXumoULpKYIAt1vh-HU,6560
277
- skypilot_nightly-1.0.0.dev20241025.dist-info/LICENSE,sha256=emRJAvE7ngL6x0RhQvlns5wJzGI3NEQ_WMjNmd9TZc4,12170
278
- skypilot_nightly-1.0.0.dev20241025.dist-info/METADATA,sha256=siLhZo4MgO_jZOW2C51DpjE_Uxw1MOaDZyaemct3w1g,19540
279
- skypilot_nightly-1.0.0.dev20241025.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
280
- skypilot_nightly-1.0.0.dev20241025.dist-info/entry_points.txt,sha256=StA6HYpuHj-Y61L2Ze-hK2IcLWgLZcML5gJu8cs6nU4,36
281
- skypilot_nightly-1.0.0.dev20241025.dist-info/top_level.txt,sha256=qA8QuiNNb6Y1OF-pCUtPEr6sLEwy2xJX06Bd_CrtrHY,4
282
- skypilot_nightly-1.0.0.dev20241025.dist-info/RECORD,,
277
+ skypilot_nightly-1.0.0.dev20241027.dist-info/LICENSE,sha256=emRJAvE7ngL6x0RhQvlns5wJzGI3NEQ_WMjNmd9TZc4,12170
278
+ skypilot_nightly-1.0.0.dev20241027.dist-info/METADATA,sha256=NgRbwJsa7En1a1R4r-0m6gYDcUNszvGA783Woi0LiPU,19540
279
+ skypilot_nightly-1.0.0.dev20241027.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
280
+ skypilot_nightly-1.0.0.dev20241027.dist-info/entry_points.txt,sha256=StA6HYpuHj-Y61L2Ze-hK2IcLWgLZcML5gJu8cs6nU4,36
281
+ skypilot_nightly-1.0.0.dev20241027.dist-info/top_level.txt,sha256=qA8QuiNNb6Y1OF-pCUtPEr6sLEwy2xJX06Bd_CrtrHY,4
282
+ skypilot_nightly-1.0.0.dev20241027.dist-info/RECORD,,