skypilot-nightly 1.0.0.dev20250105__py3-none-any.whl → 1.0.0.dev20250106__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 = '4ab8e1668053fef8ae87ba9c832073c444078e49'
8
+ _SKYPILOT_COMMIT_SHA = '38a822ac6b553df0e784e559715ee4269c21f780'
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.dev20250105'
38
+ __version__ = '1.0.0.dev20250106'
39
39
  __root_dir__ = os.path.dirname(os.path.abspath(__file__))
40
40
 
41
41
 
@@ -650,6 +650,42 @@ def _replace_yaml_dicts(
650
650
  return common_utils.dump_yaml_str(new_config)
651
651
 
652
652
 
653
+ def get_expirable_clouds(
654
+ enabled_clouds: Sequence[clouds.Cloud]) -> List[clouds.Cloud]:
655
+ """Returns a list of clouds that use local credentials and whose credentials can expire.
656
+
657
+ This function checks each cloud in the provided sequence to determine if it uses local credentials
658
+ and if its credentials can expire. If both conditions are met, the cloud is added to the list of
659
+ expirable clouds.
660
+
661
+ Args:
662
+ enabled_clouds (Sequence[clouds.Cloud]): A sequence of cloud objects to check.
663
+
664
+ Returns:
665
+ list[clouds.Cloud]: A list of cloud objects that use local credentials and whose credentials can expire.
666
+ """
667
+ expirable_clouds = []
668
+ local_credentials_value = schemas.RemoteIdentityOptions.LOCAL_CREDENTIALS.value
669
+ for cloud in enabled_clouds:
670
+ remote_identities = skypilot_config.get_nested(
671
+ (str(cloud).lower(), 'remote_identity'), None)
672
+ if remote_identities is None:
673
+ remote_identities = schemas.get_default_remote_identity(
674
+ str(cloud).lower())
675
+
676
+ local_credential_expiring = cloud.can_credential_expire()
677
+ if isinstance(remote_identities, str):
678
+ if remote_identities == local_credentials_value and local_credential_expiring:
679
+ expirable_clouds.append(cloud)
680
+ elif isinstance(remote_identities, list):
681
+ for profile in remote_identities:
682
+ if list(profile.values(
683
+ ))[0] == local_credentials_value and local_credential_expiring:
684
+ expirable_clouds.append(cloud)
685
+ break
686
+ return expirable_clouds
687
+
688
+
653
689
  # TODO: too many things happening here - leaky abstraction. Refactor.
654
690
  @timeline.event
655
691
  def write_cluster_config(
@@ -26,6 +26,7 @@ import filelock
26
26
 
27
27
  import sky
28
28
  from sky import backends
29
+ from sky import check as sky_check
29
30
  from sky import cloud_stores
30
31
  from sky import clouds
31
32
  from sky import exceptions
@@ -1996,6 +1997,22 @@ class RetryingVmProvisioner(object):
1996
1997
  skip_unnecessary_provisioning else None)
1997
1998
 
1998
1999
  failover_history: List[Exception] = list()
2000
+ # If the user is using local credentials which may expire, the
2001
+ # controller may leak resources if the credentials expire while a job
2002
+ # is running. Here we check the enabled clouds and expiring credentials
2003
+ # and raise a warning to the user.
2004
+ if task.is_controller_task():
2005
+ enabled_clouds = sky_check.get_cached_enabled_clouds_or_refresh()
2006
+ expirable_clouds = backend_utils.get_expirable_clouds(
2007
+ enabled_clouds)
2008
+
2009
+ if len(expirable_clouds) > 0:
2010
+ warnings = (f'\033[93mWarning: Credentials used for '
2011
+ f'{expirable_clouds} may expire. Clusters may be '
2012
+ f'leaked if the credentials expire while jobs '
2013
+ f'are running. It is recommended to use credentials'
2014
+ f' that never expire or a service account.\033[0m')
2015
+ logger.warning(warnings)
1999
2016
 
2000
2017
  # Retrying launchable resources.
2001
2018
  while True:
sky/cloud_stores.py CHANGED
@@ -113,8 +113,16 @@ class GcsCloudStorage(CloudStorage):
113
113
  @property
114
114
  def _gsutil_command(self):
115
115
  gsutil_alias, alias_gen = data_utils.get_gsutil_command()
116
- return (f'{alias_gen}; GOOGLE_APPLICATION_CREDENTIALS='
117
- f'{gcp.DEFAULT_GCP_APPLICATION_CREDENTIAL_PATH} {gsutil_alias}')
116
+ return (
117
+ f'{alias_gen}; GOOGLE_APPLICATION_CREDENTIALS='
118
+ f'{gcp.DEFAULT_GCP_APPLICATION_CREDENTIAL_PATH}; '
119
+ # Explicitly activate service account. Unlike the gcp packages
120
+ # and other GCP commands, gsutil does not automatically pick up
121
+ # the default credential keys when it is a service account.
122
+ 'gcloud auth activate-service-account '
123
+ '--key-file=$GOOGLE_APPLICATION_CREDENTIALS '
124
+ '2> /dev/null || true; '
125
+ f'{gsutil_alias}')
118
126
 
119
127
  def is_directory(self, url: str) -> bool:
120
128
  """Returns whether 'url' is a directory.
sky/clouds/aws.py CHANGED
@@ -103,6 +103,24 @@ class AWSIdentityType(enum.Enum):
103
103
  # region us-east-1 config-file ~/.aws/config
104
104
  SHARED_CREDENTIALS_FILE = 'shared-credentials-file'
105
105
 
106
+ def can_credential_expire(self) -> bool:
107
+ """Check if the AWS identity type can expire.
108
+
109
+ SSO,IAM_ROLE and CONTAINER_ROLE are temporary credentials and refreshed
110
+ automatically. ENV and SHARED_CREDENTIALS_FILE are short-lived
111
+ credentials without refresh.
112
+ IAM ROLE:
113
+ https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html
114
+ SSO/Container-role refresh token:
115
+ https://docs.aws.amazon.com/solutions/latest/dea-api/auth-refreshtoken.html
116
+ """
117
+ # TODO(hong): Add a CLI based check for the expiration of the temporary
118
+ # credentials
119
+ expirable_types = {
120
+ AWSIdentityType.ENV, AWSIdentityType.SHARED_CREDENTIALS_FILE
121
+ }
122
+ return self in expirable_types
123
+
106
124
 
107
125
  @clouds.CLOUD_REGISTRY.register
108
126
  class AWS(clouds.Cloud):
@@ -860,6 +878,12 @@ class AWS(clouds.Cloud):
860
878
  if os.path.exists(os.path.expanduser(f'~/.aws/{filename}'))
861
879
  }
862
880
 
881
+ @functools.lru_cache(maxsize=1)
882
+ def can_credential_expire(self) -> bool:
883
+ identity_type = self._current_identity_type()
884
+ return identity_type is not None and identity_type.can_credential_expire(
885
+ )
886
+
863
887
  def instance_type_exists(self, instance_type):
864
888
  return service_catalog.instance_type_exists(instance_type, clouds='aws')
865
889
 
sky/clouds/cloud.py CHANGED
@@ -536,6 +536,10 @@ class Cloud:
536
536
  """
537
537
  raise NotImplementedError
538
538
 
539
+ def can_credential_expire(self) -> bool:
540
+ """Returns whether the cloud credential can expire."""
541
+ return False
542
+
539
543
  @classmethod
540
544
  def get_image_size(cls, image_id: str, region: Optional[str]) -> float:
541
545
  """Check the image size from the cloud.
sky/clouds/gcp.py CHANGED
@@ -132,6 +132,9 @@ class GCPIdentityType(enum.Enum):
132
132
 
133
133
  SHARED_CREDENTIALS_FILE = ''
134
134
 
135
+ def can_credential_expire(self) -> bool:
136
+ return self == GCPIdentityType.SHARED_CREDENTIALS_FILE
137
+
135
138
 
136
139
  @clouds.CLOUD_REGISTRY.register
137
140
  class GCP(clouds.Cloud):
@@ -863,6 +866,12 @@ class GCP(clouds.Cloud):
863
866
  pass
864
867
  return credentials
865
868
 
869
+ @functools.lru_cache(maxsize=1)
870
+ def can_credential_expire(self) -> bool:
871
+ identity_type = self._get_identity_type()
872
+ return identity_type is not None and identity_type.can_credential_expire(
873
+ )
874
+
866
875
  @classmethod
867
876
  def _get_identity_type(cls) -> Optional[GCPIdentityType]:
868
877
  try:
sky/data/data_utils.py CHANGED
@@ -523,10 +523,14 @@ def get_gsutil_command() -> Tuple[str, str]:
523
523
 
524
524
  def run_upload_cli(command: str, access_denied_message: str, bucket_name: str,
525
525
  log_path: str):
526
- returncode, stdout, stderr = log_lib.run_with_log(command,
527
- log_path,
528
- shell=True,
529
- require_outputs=True)
526
+ returncode, stdout, stderr = log_lib.run_with_log(
527
+ command,
528
+ log_path,
529
+ shell=True,
530
+ require_outputs=True,
531
+ # We need to use bash as some of the cloud commands uses bash syntax,
532
+ # such as [[ ... ]]
533
+ executable='/bin/bash')
530
534
  if access_denied_message in stderr:
531
535
  with ux_utils.print_exception_no_traceback():
532
536
  raise PermissionError('Failed to upload files to '
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: skypilot-nightly
3
- Version: 1.0.0.dev20250105
3
+ Version: 1.0.0.dev20250106
4
4
  Summary: SkyPilot: An intercloud broker for the clouds
5
5
  Author: SkyPilot Team
6
6
  License: Apache 2.0
@@ -1,9 +1,9 @@
1
- sky/__init__.py,sha256=UoBoRY8FBsGpIYqv73ApHzYdoqEugRBHQpfhO4yHS9s,5944
1
+ sky/__init__.py,sha256=d2_OP2RdLE8E1NdAW66KSdhUWo7AO5U-VL6NEhkMqTQ,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=s8deMVL-k9y8gd519K7NWZc3DqWsEySwiAr0uH3Vvcc,9459
5
5
  sky/cli.py,sha256=KbvwSMgQJyW-XuX-N_-JFvBRVAEvy295j4UcxypwbyU,214398
6
- sky/cloud_stores.py,sha256=WKy9u-ZVs07A4tQIFK9UVKI-NUUM6lD75r8TwTbDfWs,23276
6
+ sky/cloud_stores.py,sha256=PcLT57_8SZy7o6paAluElfBynaLkbaOq3l-8dNg1AVM,23672
7
7
  sky/core.py,sha256=CPwNZQlC5WKLzTb2Tjo2Uogg0EvOt-yLCRlegqK_92A,38598
8
8
  sky/dag.py,sha256=f3sJlkH4bE6Uuz3ozNtsMhcBpRx7KmC9Sa4seDKt4hU,3104
9
9
  sky/exceptions.py,sha256=rUi_au7QBNn3_wvwa8Y_MSHN3QDRpVLry8Mfa56LyGk,9197
@@ -31,8 +31,8 @@ sky/adaptors/runpod.py,sha256=4Nt_BfZhJAKQNA3wO8cxvvNI8x4NsDGHu_4EhRDlGYQ,225
31
31
  sky/adaptors/vsphere.py,sha256=zJP9SeObEoLrpgHW2VHvZE48EhgVf8GfAEIwBeaDMfM,2129
32
32
  sky/backends/__init__.py,sha256=UDjwbUgpTRApbPJnNfR786GadUuwgRk3vsWoVu5RB_c,536
33
33
  sky/backends/backend.py,sha256=iBs5gnMaaUoH2OIQ3xhAjWdrJWqj8T61Za9TGsBFpvQ,7515
34
- sky/backends/backend_utils.py,sha256=3sJAV99BobQmy2_aFm4H1IONcN83kRAc6qO4QNv-Iyw,135722
35
- sky/backends/cloud_vm_ray_backend.py,sha256=ou2MfE1aLz-k3ODL2GAaFLw6JUm3kYV99KgRcPrMXr8,239251
34
+ sky/backends/backend_utils.py,sha256=Eeew8YV0VYSYxozqzadNMZrjhEMjlE3yuzTRP7YSl50,137348
35
+ sky/backends/cloud_vm_ray_backend.py,sha256=W8xnBEdJ7GJngR_w1tdUqFFFXJoAPlqB9AlAf-Tfe20,240243
36
36
  sky/backends/docker_utils.py,sha256=Hyw1YY20EyghhEbYx6O2FIMDcGkNzBzV9TM7LFynei8,8358
37
37
  sky/backends/local_docker_backend.py,sha256=nSYCjms3HOPjPNOrcCqsUKm1WV3AAovRFjEQ7hcEXW4,17021
38
38
  sky/backends/wheel_utils.py,sha256=5BUzBqfYz7p1ME6_0PXGmcsAkLVb8NrFt317p7a4X8s,8278
@@ -41,14 +41,14 @@ sky/benchmark/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
41
  sky/benchmark/benchmark_state.py,sha256=X8CXmuU9KgsDRhKedhFgjeRMUFWtQsjFs1qECvPG2yg,8723
42
42
  sky/benchmark/benchmark_utils.py,sha256=mP8Ox2WiKfthq6LcUAZnHknFQ0n8v9o_rCh1LXLgkqc,26192
43
43
  sky/clouds/__init__.py,sha256=iORaV6auqMxa6-6FKgt1C9f3UqRk1GASUtakua3tb9A,1395
44
- sky/clouds/aws.py,sha256=2_0zUYs0-f15G9lo5_eTMNLrfuOHiie_9vxLiL8iCbw,51880
44
+ sky/clouds/aws.py,sha256=K9U_nKb2_bJcZ3adarUjIaIzIr8fQiDu470I_yG3Syo,52893
45
45
  sky/clouds/azure.py,sha256=KtnnNZn4ZEr7xndBHxX91v0YXSI1QWPgIefuM1zDUBA,30784
46
- sky/clouds/cloud.py,sha256=NIODnzroLwMA3VJq3DOFt1voUoZJB8aielpDkX61iD0,35240
46
+ sky/clouds/cloud.py,sha256=5_ZduUcyCEY1JnX_h0PrJ5xwtPP4oor4jf6cICgSArc,35370
47
47
  sky/clouds/cloud_registry.py,sha256=oLoYFjm_SDTgdHokY7b6A5Utq80HXRQNxV0fLjDdVsQ,2361
48
48
  sky/clouds/cudo.py,sha256=TjlgTklsNhbzpTaqEZ5TudnH7YW9aJpkt4xyAhyaKj0,13094
49
49
  sky/clouds/do.py,sha256=zqibtq1gxNPSNkSkZFPfP5yplfIKCwBss3ry0o4C17c,11198
50
50
  sky/clouds/fluidstack.py,sha256=u2I6jXEtTqgqRWi2EafMsKqc8VkUq1cR6CSDUvk72_U,12407
51
- sky/clouds/gcp.py,sha256=GYlMsM9gAg0tfZF7pGcw4cFxsLPUSwMC8rCL3-Cyw8Q,54674
51
+ sky/clouds/gcp.py,sha256=6QOnefFsYiLCcnajjduLHsayqJ641bBu42jPTpvy7Mc,55007
52
52
  sky/clouds/ibm.py,sha256=0ArRTQx1_DpTNGByFhukzFedEDzmVjBsGiiques1bQ0,21447
53
53
  sky/clouds/kubernetes.py,sha256=OSkglBxvSimmdR8rctb3PfSzkIf5I7vLb5vT0Z18lkw,31544
54
54
  sky/clouds/lambda_cloud.py,sha256=42AmcN2X_wdBMuAw606nR_pQCBAy5QFiAo711_WRqDE,12672
@@ -92,7 +92,7 @@ sky/clouds/utils/oci_utils.py,sha256=jHIaKwS2H7AO3OgLg6kkUXlBCbPP4GJ8hgcrqQo98B8
92
92
  sky/clouds/utils/scp_utils.py,sha256=r4lhRLtNgoz5nmkfN2ctAXYugF_-Et8TYH6ZlbbFfo8,15791
93
93
  sky/data/__init__.py,sha256=Nhaf1NURisXpZuwWANa2IuCyppIuc720FRwqSE2oEwY,184
94
94
  sky/data/data_transfer.py,sha256=wixC4_3_JaeJFdGKOp-O5ulcsMugDSgrCR0SnPpugGc,8946
95
- sky/data/data_utils.py,sha256=GbHJy52f-iPmuWDGcwS4ftAXtFNR7xiDceUvY_ElN8c,28851
95
+ sky/data/data_utils.py,sha256=HjcgMDuWRR_fNQ9gjuROi9GgPVvTGApiJwxGtdb2_UU,28860
96
96
  sky/data/mounting_utils.py,sha256=FfOYpu4Rvj8WT4NNLAZPP8nj5k9MQQCXlEgmoid_lus,14455
97
97
  sky/data/storage.py,sha256=07ccD5YaQ9j6R_zPkvNk7qXnW3awDkCn9V-Sx-KXGvo,201715
98
98
  sky/data/storage_utils.py,sha256=cM3kxlffYE7PnJySDu8huyUsMX_JYsf9uer8r5OYsjo,9556
@@ -288,9 +288,9 @@ sky/utils/kubernetes/k8s_gpu_labeler_job.yaml,sha256=k0TBoQ4zgf79-sVkixKSGYFHQ7Z
288
288
  sky/utils/kubernetes/k8s_gpu_labeler_setup.yaml,sha256=VLKT2KKimZu1GDg_4AIlIt488oMQvhRZWwsj9vBbPUg,3812
289
289
  sky/utils/kubernetes/rsync_helper.sh,sha256=h4YwrPFf9727CACnMJvF3EyK_0OeOYKKt4su_daKekw,1256
290
290
  sky/utils/kubernetes/ssh_jump_lifecycle_manager.py,sha256=Kq1MDygF2IxFmu9FXpCxqucXLmeUrvs6OtRij6XTQbo,6554
291
- skypilot_nightly-1.0.0.dev20250105.dist-info/LICENSE,sha256=emRJAvE7ngL6x0RhQvlns5wJzGI3NEQ_WMjNmd9TZc4,12170
292
- skypilot_nightly-1.0.0.dev20250105.dist-info/METADATA,sha256=XuIhqjBCHH8ZZV2I2ozhi3dyfGlzAsk1M7t4lX1_N64,20439
293
- skypilot_nightly-1.0.0.dev20250105.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
294
- skypilot_nightly-1.0.0.dev20250105.dist-info/entry_points.txt,sha256=StA6HYpuHj-Y61L2Ze-hK2IcLWgLZcML5gJu8cs6nU4,36
295
- skypilot_nightly-1.0.0.dev20250105.dist-info/top_level.txt,sha256=qA8QuiNNb6Y1OF-pCUtPEr6sLEwy2xJX06Bd_CrtrHY,4
296
- skypilot_nightly-1.0.0.dev20250105.dist-info/RECORD,,
291
+ skypilot_nightly-1.0.0.dev20250106.dist-info/LICENSE,sha256=emRJAvE7ngL6x0RhQvlns5wJzGI3NEQ_WMjNmd9TZc4,12170
292
+ skypilot_nightly-1.0.0.dev20250106.dist-info/METADATA,sha256=wkld8ofQ1T9Wg883Si2tX0T4ecnO575YXntxtl4mvv0,20439
293
+ skypilot_nightly-1.0.0.dev20250106.dist-info/WHEEL,sha256=A3WOREP4zgxI0fKrHUG8DC8013e3dK3n7a6HDbcEIwE,91
294
+ skypilot_nightly-1.0.0.dev20250106.dist-info/entry_points.txt,sha256=StA6HYpuHj-Y61L2Ze-hK2IcLWgLZcML5gJu8cs6nU4,36
295
+ skypilot_nightly-1.0.0.dev20250106.dist-info/top_level.txt,sha256=qA8QuiNNb6Y1OF-pCUtPEr6sLEwy2xJX06Bd_CrtrHY,4
296
+ skypilot_nightly-1.0.0.dev20250106.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.6.0)
2
+ Generator: setuptools (75.7.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5