skypilot-nightly 1.0.0.dev20250623__py3-none-any.whl → 1.0.0.dev20250625__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 (165) hide show
  1. sky/__init__.py +2 -2
  2. sky/admin_policy.py +16 -5
  3. sky/backends/__init__.py +2 -1
  4. sky/backends/backend_utils.py +38 -11
  5. sky/backends/cloud_vm_ray_backend.py +52 -18
  6. sky/client/cli/command.py +264 -25
  7. sky/client/sdk.py +119 -85
  8. sky/clouds/aws.py +10 -7
  9. sky/clouds/azure.py +10 -7
  10. sky/clouds/cloud.py +2 -0
  11. sky/clouds/cudo.py +2 -0
  12. sky/clouds/do.py +10 -7
  13. sky/clouds/fluidstack.py +2 -0
  14. sky/clouds/gcp.py +10 -7
  15. sky/clouds/hyperbolic.py +10 -7
  16. sky/clouds/ibm.py +2 -0
  17. sky/clouds/kubernetes.py +27 -9
  18. sky/clouds/lambda_cloud.py +10 -7
  19. sky/clouds/nebius.py +10 -7
  20. sky/clouds/oci.py +10 -7
  21. sky/clouds/paperspace.py +10 -7
  22. sky/clouds/runpod.py +10 -7
  23. sky/clouds/scp.py +10 -7
  24. sky/clouds/vast.py +10 -7
  25. sky/clouds/vsphere.py +2 -0
  26. sky/core.py +89 -15
  27. sky/dag.py +14 -0
  28. sky/dashboard/out/404.html +1 -1
  29. sky/dashboard/out/_next/static/ZWdSYkqVe3WjnFR8ocqoG/_buildManifest.js +1 -0
  30. sky/dashboard/out/_next/static/chunks/230-d6e363362017ff3a.js +1 -0
  31. sky/dashboard/out/_next/static/chunks/310.2671028c20e892c7.js +16 -0
  32. sky/dashboard/out/_next/static/chunks/37-1f1e94f5a561202a.js +6 -0
  33. sky/dashboard/out/_next/static/chunks/42.bc85e5b1a4debf22.js +6 -0
  34. sky/dashboard/out/_next/static/chunks/470-92dd1614396389be.js +1 -0
  35. sky/dashboard/out/_next/static/chunks/{513.211357a2914a34b2.js → 513.309df9e18a9ff005.js} +1 -1
  36. sky/dashboard/out/_next/static/chunks/544.110e53813fb98e2e.js +1 -0
  37. sky/dashboard/out/_next/static/chunks/645.961f08e39b8ce447.js +1 -0
  38. sky/dashboard/out/_next/static/chunks/66-66ae330df2d3c1c7.js +1 -0
  39. sky/dashboard/out/_next/static/chunks/682.00e56a220dd26fe1.js +6 -0
  40. sky/dashboard/out/_next/static/chunks/697.6460bf72e760addd.js +20 -0
  41. sky/dashboard/out/_next/static/chunks/856-cdf66268ec878d0c.js +1 -0
  42. sky/dashboard/out/_next/static/chunks/938-068520cc11738deb.js +1 -0
  43. sky/dashboard/out/_next/static/chunks/969-d3a0b53f728d280a.js +1 -0
  44. sky/dashboard/out/_next/static/chunks/989-db34c16ad7ea6155.js +1 -0
  45. sky/dashboard/out/_next/static/chunks/pages/{_app-c416e87d5c2715cf.js → _app-0ef7418d1a3822f3.js} +1 -1
  46. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-aff040d7bc5d0086.js +6 -0
  47. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-32ce4f49f2261f55.js +6 -0
  48. sky/dashboard/out/_next/static/chunks/pages/clusters-4aa031d1f42723d8.js +1 -0
  49. sky/dashboard/out/_next/static/chunks/pages/config-3102d02a188f04b3.js +1 -0
  50. sky/dashboard/out/_next/static/chunks/pages/infra/[context]-6f1e02e31eecb5ce.js +1 -0
  51. sky/dashboard/out/_next/static/chunks/pages/infra-fd5dc8a91bd9169a.js +1 -0
  52. sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-e4b23128db0774cd.js +16 -0
  53. sky/dashboard/out/_next/static/chunks/pages/jobs-26da173e20af16e4.js +1 -0
  54. sky/dashboard/out/_next/static/chunks/pages/users-ce29e7420385563d.js +1 -0
  55. sky/dashboard/out/_next/static/chunks/pages/volumes-476b670ef33d1ecd.js +1 -0
  56. sky/dashboard/out/_next/static/chunks/pages/workspace/new-09ae0f6f972aa871.js +1 -0
  57. sky/dashboard/out/_next/static/chunks/pages/workspaces/{[name]-c4ff1ec05e2f3daf.js → [name]-0b4c662a25e4747a.js} +1 -1
  58. sky/dashboard/out/_next/static/chunks/pages/workspaces-862b120406461b10.js +1 -0
  59. sky/dashboard/out/_next/static/chunks/webpack-6133dc1e928bd0b5.js +1 -0
  60. sky/dashboard/out/_next/static/css/b23cb0257bf96c51.css +3 -0
  61. sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
  62. sky/dashboard/out/clusters/[cluster].html +1 -1
  63. sky/dashboard/out/clusters.html +1 -1
  64. sky/dashboard/out/config.html +1 -1
  65. sky/dashboard/out/index.html +1 -1
  66. sky/dashboard/out/infra/[context].html +1 -1
  67. sky/dashboard/out/infra.html +1 -1
  68. sky/dashboard/out/jobs/[job].html +1 -1
  69. sky/dashboard/out/jobs.html +1 -1
  70. sky/dashboard/out/users.html +1 -1
  71. sky/dashboard/out/volumes.html +1 -0
  72. sky/dashboard/out/workspace/new.html +1 -1
  73. sky/dashboard/out/workspaces/[name].html +1 -1
  74. sky/dashboard/out/workspaces.html +1 -1
  75. sky/data/storage_utils.py +2 -4
  76. sky/exceptions.py +26 -0
  77. sky/execution.py +5 -0
  78. sky/global_user_state.py +263 -20
  79. sky/jobs/client/sdk.py +13 -12
  80. sky/jobs/controller.py +5 -1
  81. sky/jobs/scheduler.py +4 -3
  82. sky/jobs/server/core.py +121 -51
  83. sky/jobs/state.py +15 -0
  84. sky/jobs/utils.py +114 -8
  85. sky/models.py +16 -0
  86. sky/provision/__init__.py +26 -0
  87. sky/provision/kubernetes/__init__.py +3 -0
  88. sky/provision/kubernetes/instance.py +38 -77
  89. sky/provision/kubernetes/utils.py +52 -2
  90. sky/provision/kubernetes/volume.py +147 -0
  91. sky/resources.py +20 -76
  92. sky/serve/client/sdk.py +13 -13
  93. sky/serve/server/core.py +5 -1
  94. sky/server/common.py +40 -5
  95. sky/server/constants.py +5 -1
  96. sky/server/metrics.py +105 -0
  97. sky/server/requests/executor.py +30 -14
  98. sky/server/requests/payloads.py +22 -3
  99. sky/server/requests/requests.py +59 -2
  100. sky/server/rest.py +152 -0
  101. sky/server/server.py +70 -19
  102. sky/server/state.py +20 -0
  103. sky/server/stream_utils.py +8 -3
  104. sky/server/uvicorn.py +153 -13
  105. sky/setup_files/dependencies.py +2 -0
  106. sky/skylet/constants.py +19 -14
  107. sky/task.py +141 -43
  108. sky/templates/jobs-controller.yaml.j2 +12 -1
  109. sky/templates/kubernetes-ray.yml.j2 +31 -2
  110. sky/users/permission.py +2 -0
  111. sky/utils/admin_policy_utils.py +5 -1
  112. sky/utils/cli_utils/status_utils.py +25 -17
  113. sky/utils/command_runner.py +118 -12
  114. sky/utils/command_runner.pyi +57 -0
  115. sky/utils/common_utils.py +9 -1
  116. sky/utils/context.py +3 -1
  117. sky/utils/controller_utils.py +1 -2
  118. sky/utils/resources_utils.py +66 -0
  119. sky/utils/rich_utils.py +6 -0
  120. sky/utils/schemas.py +180 -38
  121. sky/utils/status_lib.py +10 -0
  122. sky/utils/validator.py +11 -1
  123. sky/volumes/__init__.py +0 -0
  124. sky/volumes/client/__init__.py +0 -0
  125. sky/volumes/client/sdk.py +64 -0
  126. sky/volumes/server/__init__.py +0 -0
  127. sky/volumes/server/core.py +199 -0
  128. sky/volumes/server/server.py +85 -0
  129. sky/volumes/utils.py +158 -0
  130. sky/volumes/volume.py +198 -0
  131. {skypilot_nightly-1.0.0.dev20250623.dist-info → skypilot_nightly-1.0.0.dev20250625.dist-info}/METADATA +2 -1
  132. {skypilot_nightly-1.0.0.dev20250623.dist-info → skypilot_nightly-1.0.0.dev20250625.dist-info}/RECORD +139 -123
  133. sky/dashboard/out/_next/static/F4kiZ6Zh72jA6HzZ3ncFo/_buildManifest.js +0 -1
  134. sky/dashboard/out/_next/static/chunks/350.9e123a4551f68b0d.js +0 -1
  135. sky/dashboard/out/_next/static/chunks/37-3a4d77ad62932eaf.js +0 -6
  136. sky/dashboard/out/_next/static/chunks/42.d39e24467181b06b.js +0 -6
  137. sky/dashboard/out/_next/static/chunks/470-4d1a5dbe58a8a2b9.js +0 -1
  138. sky/dashboard/out/_next/static/chunks/641.c8e452bc5070a630.js +0 -1
  139. sky/dashboard/out/_next/static/chunks/682.4dd5dc116f740b5f.js +0 -6
  140. sky/dashboard/out/_next/static/chunks/760-a89d354797ce7af5.js +0 -1
  141. sky/dashboard/out/_next/static/chunks/856-c2c39c0912285e54.js +0 -1
  142. sky/dashboard/out/_next/static/chunks/901-b424d293275e1fd7.js +0 -1
  143. sky/dashboard/out/_next/static/chunks/938-1493ac755eadeb35.js +0 -1
  144. sky/dashboard/out/_next/static/chunks/969-20d54a9d998dc102.js +0 -1
  145. sky/dashboard/out/_next/static/chunks/984.ae8c08791d274ca0.js +0 -50
  146. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-89216c616dbaa9c5.js +0 -6
  147. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-36bc0962129f72df.js +0 -6
  148. sky/dashboard/out/_next/static/chunks/pages/clusters-82a651dbad53ec6e.js +0 -1
  149. sky/dashboard/out/_next/static/chunks/pages/config-497a35a7ed49734a.js +0 -1
  150. sky/dashboard/out/_next/static/chunks/pages/infra/[context]-d2910be98e9227cb.js +0 -1
  151. sky/dashboard/out/_next/static/chunks/pages/infra-780860bcc1103945.js +0 -1
  152. sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-cf490d1fa38f3740.js +0 -16
  153. sky/dashboard/out/_next/static/chunks/pages/jobs-336ab80e270ce2ce.js +0 -1
  154. sky/dashboard/out/_next/static/chunks/pages/users-928edf039219e47b.js +0 -1
  155. sky/dashboard/out/_next/static/chunks/pages/workspace/new-31aa8bdcb7592635.js +0 -1
  156. sky/dashboard/out/_next/static/chunks/pages/workspaces-82e6601baa5dd280.js +0 -1
  157. sky/dashboard/out/_next/static/chunks/webpack-0263b00d6a10e64a.js +0 -1
  158. sky/dashboard/out/_next/static/css/6c12ecc3bd2239b6.css +0 -3
  159. /sky/dashboard/out/_next/static/{F4kiZ6Zh72jA6HzZ3ncFo → ZWdSYkqVe3WjnFR8ocqoG}/_ssgManifest.js +0 -0
  160. /sky/dashboard/out/_next/static/chunks/{843-b3040e493f6e7947.js → 843-07d25a7e64462fd8.js} +0 -0
  161. /sky/dashboard/out/_next/static/chunks/{973-db3c97c2bfbceb65.js → 973-5b5019ba333e8d62.js} +0 -0
  162. {skypilot_nightly-1.0.0.dev20250623.dist-info → skypilot_nightly-1.0.0.dev20250625.dist-info}/WHEEL +0 -0
  163. {skypilot_nightly-1.0.0.dev20250623.dist-info → skypilot_nightly-1.0.0.dev20250625.dist-info}/entry_points.txt +0 -0
  164. {skypilot_nightly-1.0.0.dev20250623.dist-info → skypilot_nightly-1.0.0.dev20250625.dist-info}/licenses/LICENSE +0 -0
  165. {skypilot_nightly-1.0.0.dev20250623.dist-info → skypilot_nightly-1.0.0.dev20250625.dist-info}/top_level.txt +0 -0
sky/volumes/volume.py ADDED
@@ -0,0 +1,198 @@
1
+ """Volume types and access modes."""
2
+ import enum
3
+ import time
4
+ from typing import Any, Dict, Optional
5
+
6
+ from sky import exceptions
7
+ from sky import global_user_state
8
+ from sky import models
9
+ from sky.utils import common_utils
10
+ from sky.utils import infra_utils
11
+ from sky.utils import resources_utils
12
+ from sky.utils import schemas
13
+ from sky.utils import status_lib
14
+
15
+
16
+ class VolumeType(enum.Enum):
17
+ """Volume type."""
18
+ PVC = 'k8s-pvc'
19
+
20
+
21
+ class VolumeAccessMode(enum.Enum):
22
+ """Volume access mode."""
23
+ READ_WRITE_ONCE = 'ReadWriteOnce'
24
+ READ_WRITE_ONCE_POD = 'ReadWriteOncePod'
25
+ READ_WRITE_MANY = 'ReadWriteMany'
26
+ READ_ONLY_MANY = 'ReadOnlyMany'
27
+
28
+
29
+ class VolumeMount:
30
+ """Volume mount specification."""
31
+
32
+ def __init__(self, path: str, volume_name: str,
33
+ volume_config: models.VolumeConfig):
34
+ self.path: str = path
35
+ self.volume_name: str = volume_name
36
+ self.volume_config: models.VolumeConfig = volume_config
37
+
38
+ def pre_mount(self) -> None:
39
+ """Update the volume status before actual mounting."""
40
+ # TODO(aylei): for ReadWriteOnce volume, we also need to queue the
41
+ # mount request if the target volume is already mounted to another
42
+ # cluster. For now, we only support ReadWriteMany volume.
43
+ global_user_state.update_volume(self.volume_name,
44
+ last_attached_at=int(time.time()),
45
+ status=status_lib.VolumeStatus.IN_USE)
46
+
47
+ @classmethod
48
+ def resolve(cls, path: str, volume_name: str) -> 'VolumeMount':
49
+ """Resolve the volume mount by populating metadata of volume."""
50
+ record = global_user_state.get_volume_by_name(volume_name)
51
+ if record is None:
52
+ raise exceptions.VolumeNotFoundError(
53
+ f'Volume {volume_name} not found.')
54
+ assert 'handle' in record, 'Volume handle is None.'
55
+ volume_config: models.VolumeConfig = record['handle']
56
+ return cls(path, volume_name, volume_config)
57
+
58
+ @classmethod
59
+ def from_yaml_config(cls, config: Dict[str, Any]) -> 'VolumeMount':
60
+ common_utils.validate_schema(config, schemas.get_volume_mount_schema(),
61
+ 'Invalid volume mount config: ')
62
+
63
+ path = config.pop('path', None)
64
+ volume_name = config.pop('volume_name', None)
65
+ volume_config: models.VolumeConfig = models.VolumeConfig.model_validate(
66
+ config.pop('volume_config', None))
67
+ return cls(path, volume_name, volume_config)
68
+
69
+ def to_yaml_config(self) -> Dict[str, Any]:
70
+ return {
71
+ 'path': self.path,
72
+ 'volume_name': self.volume_name,
73
+ 'volume_config': self.volume_config.model_dump(),
74
+ }
75
+
76
+ def __repr__(self):
77
+ return (f'VolumeMount('
78
+ f'\n\tpath={self.path},'
79
+ f'\n\tvolume_name={self.volume_name},'
80
+ f'\n\tvolume_config={self.volume_config})')
81
+
82
+
83
+ class Volume:
84
+ """Volume specification."""
85
+
86
+ def __init__(
87
+ self,
88
+ name: Optional[str] = None,
89
+ type: Optional[str] = None, # pylint: disable=redefined-builtin
90
+ infra: Optional[str] = None,
91
+ size: Optional[str] = None,
92
+ resource_name: Optional[str] = None,
93
+ config: Optional[Dict[str, Any]] = None):
94
+ """Initialize a Volume instance.
95
+
96
+ Args:
97
+ name: Volume name
98
+ type: Volume type (e.g., 'k8s-pvc')
99
+ infra: Infrastructure specification
100
+ size: Volume size
101
+ config: Additional configuration
102
+ """
103
+ self.name = name
104
+ self.type = type
105
+ self.infra = infra
106
+ self.size = size
107
+ self.resource_name = resource_name
108
+ self.config = config or {}
109
+
110
+ self.cloud: Optional[str] = None
111
+ self.region: Optional[str] = None
112
+ self.zone: Optional[str] = None
113
+
114
+ @classmethod
115
+ def from_dict(cls, config_dict: Dict[str, Any]) -> 'Volume':
116
+ """Create a Volume instance from a dictionary."""
117
+ return cls(name=config_dict.get('name'),
118
+ type=config_dict.get('type'),
119
+ infra=config_dict.get('infra'),
120
+ size=config_dict.get('size'),
121
+ resource_name=config_dict.get('resource_name'),
122
+ config=config_dict.get('config', {}))
123
+
124
+ def to_dict(self) -> Dict[str, Any]:
125
+ """Convert the Volume to a dictionary."""
126
+ return {
127
+ 'name': self.name,
128
+ 'type': self.type,
129
+ 'infra': self.infra,
130
+ 'size': self.size,
131
+ 'resource_name': self.resource_name,
132
+ 'config': self.config,
133
+ 'cloud': self.cloud,
134
+ 'region': self.region,
135
+ 'zone': self.zone,
136
+ }
137
+
138
+ def normalize_config(
139
+ self,
140
+ name: Optional[str] = None,
141
+ infra: Optional[str] = None,
142
+ type: Optional[str] = None, # pylint: disable=redefined-builtin
143
+ size: Optional[str] = None) -> None:
144
+ """Override the volume config with CLI options,
145
+ adjust and validate the config.
146
+
147
+ Args:
148
+ name: Volume name to override
149
+ infra: Infrastructure to override
150
+ type: Volume type to override
151
+ size: Volume size to override
152
+ """
153
+ if name is not None:
154
+ self.name = name
155
+ if infra is not None:
156
+ self.infra = infra
157
+ if type is not None:
158
+ self.type = type
159
+ if size is not None:
160
+ self.size = size
161
+
162
+ # Validate schema
163
+ common_utils.validate_schema(self.to_dict(),
164
+ schemas.get_volume_schema(),
165
+ 'Invalid volumes config: ')
166
+
167
+ # Adjust the volume config (e.g., parse size)
168
+ self._adjust_config()
169
+
170
+ # Validate the volume config
171
+ self._validate_config()
172
+
173
+ # Resolve the infrastructure options to cloud, region, zone
174
+ infra_info = infra_utils.InfraInfo.from_str(self.infra)
175
+ self.cloud = infra_info.cloud
176
+ self.region = infra_info.region
177
+ self.zone = infra_info.zone
178
+
179
+ def _adjust_config(self) -> None:
180
+ """Adjust the volume config (e.g., parse size)."""
181
+ if self.size is None:
182
+ return
183
+ try:
184
+ size = resources_utils.parse_memory_resource(self.size,
185
+ 'size',
186
+ allow_rounding=True)
187
+ if size == '0':
188
+ raise ValueError('Size must be no less than 1Gi')
189
+ self.size = size
190
+ except ValueError as e:
191
+ raise ValueError(f'Invalid size {self.size}: {e}') from e
192
+
193
+ def _validate_config(self) -> None:
194
+ """Validate the volume config."""
195
+ if not self.resource_name and not self.size:
196
+ raise ValueError('Size is required for new volumes. '
197
+ 'Please specify the size in the YAML file or '
198
+ 'use the --size flag.')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: skypilot-nightly
3
- Version: 1.0.0.dev20250623
3
+ Version: 1.0.0.dev20250625
4
4
  Summary: SkyPilot: Run AI on Any Infra — Unified, Faster, Cheaper.
5
5
  Author: SkyPilot Team
6
6
  License: Apache 2.0
@@ -51,6 +51,7 @@ Requires-Dist: sqlalchemy
51
51
  Requires-Dist: psycopg2-binary
52
52
  Requires-Dist: casbin
53
53
  Requires-Dist: sqlalchemy_adapter
54
+ Requires-Dist: prometheus_client>=0.8.0
54
55
  Requires-Dist: passlib
55
56
  Provides-Extra: aws
56
57
  Requires-Dist: awscli>=1.27.10; extra == "aws"