skypilot-nightly 1.0.0.dev20250615__py3-none-any.whl → 1.0.0.dev20250617__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 (62) hide show
  1. sky/__init__.py +2 -4
  2. sky/backends/cloud_vm_ray_backend.py +43 -60
  3. sky/cli.py +55 -637
  4. sky/client/cli.py +55 -637
  5. sky/clouds/kubernetes.py +3 -0
  6. sky/clouds/scp.py +7 -26
  7. sky/clouds/utils/scp_utils.py +177 -124
  8. sky/dashboard/out/404.html +1 -1
  9. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-36bc0962129f72df.js +6 -0
  10. sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-cf490d1fa38f3740.js +16 -0
  11. sky/dashboard/out/_next/static/{R07f8gwfXT1U0zRznq4Lg → vA3PPpkBwpRTRNBHFYAw_}/_buildManifest.js +1 -1
  12. sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
  13. sky/dashboard/out/clusters/[cluster].html +1 -1
  14. sky/dashboard/out/clusters.html +1 -1
  15. sky/dashboard/out/config.html +1 -1
  16. sky/dashboard/out/index.html +1 -1
  17. sky/dashboard/out/infra/[context].html +1 -1
  18. sky/dashboard/out/infra.html +1 -1
  19. sky/dashboard/out/jobs/[job].html +1 -1
  20. sky/dashboard/out/jobs.html +1 -1
  21. sky/dashboard/out/users.html +1 -1
  22. sky/dashboard/out/workspace/new.html +1 -1
  23. sky/dashboard/out/workspaces/[name].html +1 -1
  24. sky/dashboard/out/workspaces.html +1 -1
  25. sky/jobs/controller.py +98 -31
  26. sky/jobs/scheduler.py +37 -29
  27. sky/jobs/server/core.py +36 -3
  28. sky/jobs/state.py +69 -9
  29. sky/jobs/utils.py +11 -0
  30. sky/provision/__init__.py +1 -0
  31. sky/provision/scp/__init__.py +15 -0
  32. sky/provision/scp/config.py +93 -0
  33. sky/provision/scp/instance.py +528 -0
  34. sky/resources.py +164 -29
  35. sky/skylet/constants.py +39 -0
  36. sky/skylet/job_lib.py +8 -0
  37. sky/task.py +171 -21
  38. sky/templates/kubernetes-ray.yml.j2 +51 -4
  39. sky/templates/scp-ray.yml.j2 +3 -50
  40. sky/users/permission.py +19 -36
  41. sky/utils/command_runner.py +1 -1
  42. sky/utils/common_utils.py +16 -14
  43. sky/utils/context.py +1 -1
  44. sky/utils/controller_utils.py +12 -3
  45. sky/utils/dag_utils.py +17 -4
  46. sky/utils/kubernetes/deploy_remote_cluster.py +17 -8
  47. sky/utils/schemas.py +43 -5
  48. {skypilot_nightly-1.0.0.dev20250615.dist-info → skypilot_nightly-1.0.0.dev20250617.dist-info}/METADATA +1 -1
  49. {skypilot_nightly-1.0.0.dev20250615.dist-info → skypilot_nightly-1.0.0.dev20250617.dist-info}/RECORD +54 -57
  50. sky/benchmark/__init__.py +0 -0
  51. sky/benchmark/benchmark_state.py +0 -295
  52. sky/benchmark/benchmark_utils.py +0 -641
  53. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-59950b2f83b66e48.js +0 -6
  54. sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-b3dbf38b51cb29be.js +0 -16
  55. sky/skylet/providers/scp/__init__.py +0 -2
  56. sky/skylet/providers/scp/config.py +0 -149
  57. sky/skylet/providers/scp/node_provider.py +0 -578
  58. /sky/dashboard/out/_next/static/{R07f8gwfXT1U0zRznq4Lg → vA3PPpkBwpRTRNBHFYAw_}/_ssgManifest.js +0 -0
  59. {skypilot_nightly-1.0.0.dev20250615.dist-info → skypilot_nightly-1.0.0.dev20250617.dist-info}/WHEEL +0 -0
  60. {skypilot_nightly-1.0.0.dev20250615.dist-info → skypilot_nightly-1.0.0.dev20250617.dist-info}/entry_points.txt +0 -0
  61. {skypilot_nightly-1.0.0.dev20250615.dist-info → skypilot_nightly-1.0.0.dev20250617.dist-info}/licenses/LICENSE +0 -0
  62. {skypilot_nightly-1.0.0.dev20250615.dist-info → skypilot_nightly-1.0.0.dev20250617.dist-info}/top_level.txt +0 -0
sky/clouds/kubernetes.py CHANGED
@@ -646,6 +646,9 @@ class Kubernetes(clouds.Cloud):
646
646
  (constants.PERSISTENT_SETUP_SCRIPT_PATH),
647
647
  'k8s_high_availability_deployment_run_script_dir':
648
648
  (constants.PERSISTENT_RUN_SCRIPT_DIR),
649
+ 'k8s_high_availability_restarting_signal_file':
650
+ (constants.PERSISTENT_RUN_RESTARTING_SIGNAL_FILE),
651
+ 'sky_python_cmd': constants.SKY_PYTHON_CMD,
649
652
  'k8s_high_availability_storage_class_name':
650
653
  (k8s_ha_storage_class_name),
651
654
  'avoid_label_keys': avoid_label_keys,
sky/clouds/scp.py CHANGED
@@ -59,14 +59,15 @@ class SCP(clouds.Cloud):
59
59
  clouds.CloudImplementationFeatures.CUSTOM_NETWORK_TIER:
60
60
  ('Custom network tier is currently not supported in '
61
61
  f'{_REPR}.'),
62
- clouds.CloudImplementationFeatures.OPEN_PORTS:
63
- (f'Opening ports is currently not supported on {_REPR}.'),
64
62
  clouds.CloudImplementationFeatures.HIGH_AVAILABILITY_CONTROLLERS:
65
63
  (f'High availability controllers are not supported on {_REPR}.'),
66
64
  }
67
65
 
68
66
  _INDENT_PREFIX = ' '
69
67
 
68
+ PROVISIONER_VERSION = clouds.ProvisionerVersion.SKYPILOT
69
+ STATUS_VERSION = clouds.StatusVersion.SKYPILOT
70
+
70
71
  @classmethod
71
72
  def _unsupported_features_for_resources(
72
73
  cls, resources: 'resources_lib.Resources'
@@ -243,7 +244,7 @@ class SCP(clouds.Cloud):
243
244
  clouds='scp')
244
245
  if acc is not None:
245
246
  assert len(acc) == 1, acc
246
- image_id = catalog.get_image_id_from_tag('skypilot:gpu-ubuntu-1804',
247
+ image_id = catalog.get_image_id_from_tag('skypilot:gpu-ubuntu-2204',
247
248
  region_name,
248
249
  clouds='scp')
249
250
  if image_id is not None:
@@ -325,7 +326,7 @@ class SCP(clouds.Cloud):
325
326
  """Checks if the user has access credentials to
326
327
  SCP's compute service."""
327
328
  try:
328
- scp_utils.SCPClient().list_instances()
329
+ scp_utils.SCPClient().get_instances()
329
330
  except (AssertionError, KeyError, scp_utils.SCPClientError,
330
331
  scp_utils.SCPCreationFailError):
331
332
  return False, (
@@ -374,25 +375,5 @@ class SCP(clouds.Cloud):
374
375
  region: Optional[str], zone: Optional[str],
375
376
  **kwargs) -> List[status_lib.ClusterStatus]:
376
377
  del tag_filters, region, zone, kwargs # Unused.
377
-
378
- # TODO: Multi-node is not supported yet.
379
-
380
- status_map = {
381
- 'CREATING': status_lib.ClusterStatus.INIT,
382
- 'EDITING': status_lib.ClusterStatus.INIT,
383
- 'RUNNING': status_lib.ClusterStatus.UP,
384
- 'STARTING': status_lib.ClusterStatus.INIT,
385
- 'RESTARTING': status_lib.ClusterStatus.INIT,
386
- 'STOPPING': status_lib.ClusterStatus.STOPPED,
387
- 'STOPPED': status_lib.ClusterStatus.STOPPED,
388
- 'TERMINATING': None,
389
- 'TERMINATED': None,
390
- }
391
- status_list = []
392
- vms = scp_utils.SCPClient().list_instances()
393
- for node in vms:
394
- if node['virtualServerName'] == name:
395
- node_status = status_map[node['virtualServerState']]
396
- if node_status is not None:
397
- status_list.append(node_status)
398
- return status_list
378
+ # TODO: deprecate this method
379
+ assert False, 'This code path should not be used.'
@@ -184,7 +184,7 @@ class SCPClient:
184
184
 
185
185
  def create_instance(self, instance_config):
186
186
  """Launch new instances."""
187
- url = f'{API_ENDPOINT}/virtual-server/v3/virtual-servers'
187
+ url = f'{API_ENDPOINT}/virtual-server/v4/virtual-servers'
188
188
  return self._post(url, instance_config)
189
189
 
190
190
  @_retry
@@ -226,105 +226,113 @@ class SCPClient:
226
226
  raise_scp_error(response)
227
227
  return response.json()
228
228
 
229
- def create_security_group(self, zone_id, vpc, sg_name):
229
+ def create_security_group(self, zone_id, vpc_id, sg_name):
230
230
  url = f'{API_ENDPOINT}/security-group/v3/security-groups'
231
231
  request_body = {
232
232
  'loggable': False,
233
233
  'securityGroupName': sg_name,
234
234
  'serviceZoneId': zone_id,
235
- 'vpcId': vpc,
236
- 'securityGroupDescription': 'skypilot sg'
235
+ 'vpcId': vpc_id,
236
+ 'securityGroupDescription': 'sky security group'
237
237
  }
238
238
  return self._post(url, request_body)
239
239
 
240
- def add_security_group_in_rule(self, sg_id):
241
- url = f'{API_ENDPOINT}/security-group/v2/security-groups/{sg_id}/rules'
242
- request_body = {
243
- 'ruleDirection': 'IN',
244
- 'services': [{
245
- 'serviceType': 'TCP',
246
- 'serviceValue': '22'
247
- }],
248
- 'sourceIpAddresses': ['0.0.0.0/0'],
249
- 'ruleDescription': 'skypilot ssh rule'
250
- }
251
- return self._post(url, request_body)
252
-
253
- def add_security_group_out_rule(self, sg_id):
254
- url = f'{API_ENDPOINT}/security-group/v2/security-groups/{sg_id}/rules'
255
- request_body = {
256
- 'ruleDirection': 'OUT',
257
- 'services': [{
258
- 'serviceType': 'TCP',
259
- 'serviceValue': '21'
260
- }, {
261
- 'serviceType': 'TCP',
262
- 'serviceValue': '22'
263
- }, {
264
- 'serviceType': 'TCP',
265
- 'serviceValue': '80'
266
- }, {
267
- 'serviceType': 'TCP',
268
- 'serviceValue': '443'
269
- }],
270
- 'destinationIpAddresses': ['0.0.0.0/0'],
271
- 'ruleDescription': 'skypilot out rule'
272
- }
273
- return self._post(url, request_body)
274
-
275
- def add_firewall_inbound_rule(self, firewall_id, internal_ip):
276
- url = f'{API_ENDPOINT}/firewall/v2/firewalls/{firewall_id}/rules'
277
- request_body = {
278
- 'sourceIpAddresses': ['0.0.0.0/0'],
279
- 'destinationIpAddresses': [internal_ip],
280
- 'services': [{
281
- 'serviceType': 'TCP',
282
- 'serviceValue': '22'
283
- }],
284
- 'ruleDirection': 'IN',
285
- 'ruleAction': 'ALLOW',
286
- 'isRuleEnabled': True,
287
- 'ruleLocationType': 'FIRST',
288
- 'ruleDescription': 'description'
289
- }
290
- return self._post(url, request_body)
291
-
292
- def add_firewall_outbound_rule(self, firewall_id, internal_ip):
293
- url = f'{API_ENDPOINT}/firewall/v2/firewalls/{firewall_id}/rules'
294
- request_body = {
295
- 'sourceIpAddresses': [internal_ip],
296
- 'destinationIpAddresses': ['0.0.0.0/0'],
297
- 'services': [{
298
- 'serviceType': 'TCP',
299
- 'serviceValue': '21'
300
- }, {
301
- 'serviceType': 'TCP',
302
- 'serviceValue': '22'
303
- }, {
304
- 'serviceType': 'TCP',
305
- 'serviceValue': '80'
306
- }, {
307
- 'serviceType': 'TCP',
308
- 'serviceValue': '443'
309
- }],
310
- 'ruleDirection': 'OUT',
311
- 'ruleAction': 'ALLOW',
312
- 'isRuleEnabled': True,
313
- 'ruleLocationType': 'FIRST',
314
- 'ruleDescription': 'description'
315
- }
316
- return self._post(url, request_body)
240
+ def _security_group_rule_not_exist(self, sg_id, direction, ports):
241
+ response = self.get_security_group_rules(sg_id)
242
+ rules = []
243
+ for rule in response:
244
+ rule_direction = rule['ruleDirection']
245
+ if rule_direction == direction:
246
+ rules.append(rule)
247
+ for rule in rules:
248
+ port_list = ','.join(rule['tcpServices'])
249
+ port = ','.join(ports)
250
+ if port == port_list:
251
+ return False
252
+ return True
253
+
254
+ def add_security_group_rule(self, sg_id, direction,
255
+ ports: Optional[List[str]]):
256
+ if ports is None:
257
+ if direction == 'IN':
258
+ ports = ['22']
259
+ else:
260
+ ports = ['21', '22', '80', '443']
261
+ services = []
262
+ for port in ports:
263
+ services.append({'serviceType': 'TCP', 'serviceValue': port})
264
+ if self._security_group_rule_not_exist(sg_id, direction, ports):
265
+ url = f'{API_ENDPOINT}/security-group/v2/security-groups/{sg_id}/rules' # pylint: disable=line-too-long
266
+ if direction == 'IN':
267
+ target_address = 'sourceIpAddresses'
268
+ else:
269
+ target_address = 'destinationIpAddresses'
270
+ request_body = {
271
+ 'ruleDirection': direction,
272
+ 'services': services,
273
+ target_address: ['0.0.0.0/0'],
274
+ 'ruleDescription': 'sky security group rule'
275
+ }
276
+ return self._post(url, request_body)
277
+
278
+ def _firewall_rule_not_exist(self, firewall_id, internal_ip, direction,
279
+ ports):
280
+ response = self.get_firewall_rules(firewall_id)
281
+ rules = []
282
+ for rule in response:
283
+ if direction == 'IN':
284
+ if internal_ip == rule['destinationIpAddresses'][0]:
285
+ rules.append(rule)
286
+ else:
287
+ if internal_ip == rule['sourceIpAddresses'][0]:
288
+ rules.append(rule)
289
+ for rule in rules:
290
+ port_list = ','.join(rule['tcpServices'])
291
+ port = ','.join(ports)
292
+ if port == port_list:
293
+ return False
294
+ return True
295
+
296
+ def add_firewall_rule(self, firewall_id, internal_ip, direction, ports):
297
+ if ports is None:
298
+ if direction == 'IN':
299
+ ports = ['22']
300
+ else:
301
+ ports = ['21', '22', '80', '443']
302
+ services = []
303
+ for port in ports:
304
+ services.append({'serviceType': 'TCP', 'serviceValue': port})
305
+ if self._firewall_rule_not_exist(firewall_id, internal_ip, direction,
306
+ ports):
307
+ url = f'{API_ENDPOINT}/firewall/v2/firewalls/{firewall_id}/rules'
308
+ if direction == 'IN':
309
+ source_ip = '0.0.0.0/0'
310
+ destination_ip = internal_ip
311
+ else:
312
+ source_ip = internal_ip
313
+ destination_ip = '0.0.0.0/0'
314
+ request_body = {
315
+ 'sourceIpAddresses': [source_ip],
316
+ 'destinationIpAddresses': [destination_ip],
317
+ 'services': services,
318
+ 'ruleDirection': direction,
319
+ 'ruleAction': 'ALLOW',
320
+ 'isRuleEnabled': True,
321
+ 'ruleLocationType': 'FIRST',
322
+ 'ruleDescription': 'sky firewall rule'
323
+ }
324
+ return self._post(url, request_body)
317
325
 
318
- def terminate_instance(self, vm_id):
319
- url = f'{API_ENDPOINT}/virtual-server/v2/virtual-servers/{vm_id}'
326
+ def terminate_instance(self, instance_id):
327
+ url = f'{API_ENDPOINT}/virtual-server/v2/virtual-servers/{instance_id}'
320
328
  return self._delete(url)
321
329
 
322
- def list_instances(self) -> List[dict]:
330
+ def get_instances(self) -> List[dict]:
323
331
  """List existing instances."""
324
332
  url = f'{API_ENDPOINT}/virtual-server/v2/virtual-servers'
325
333
  return self._get(url)
326
334
 
327
- def list_catalog(self) -> Dict[str, Any]:
335
+ def get_catalog(self) -> Dict[str, Any]:
328
336
  """List offered instances and their availability."""
329
337
  response = requests.get(f'{API_ENDPOINT}/instance-types',
330
338
  headers=self.headers)
@@ -362,89 +370,134 @@ class SCPClient:
362
370
  self.headers['X-Cmp-Timestamp'] = self.timestamp
363
371
 
364
372
  def set_signature(self, method: str, url: str) -> None:
365
-
366
373
  self.signature = self.get_signature(url=url, method=method)
367
374
  self.headers['X-Cmp-Signature'] = self.signature
368
375
 
369
- def list_nic_details(self, virtual_server_id) -> List[dict]:
370
- """List existing instances."""
371
- url = f'{API_ENDPOINT}/virtual-server/v2/virtual-servers/{virtual_server_id}/nics' # pylint: disable=line-too-long
376
+ def get_nic(self, instance_id) -> List[dict]:
377
+ url = f'{API_ENDPOINT}/virtual-server/v2/virtual-servers/{instance_id}/nics' # pylint: disable=line-too-long
372
378
  return self._get(url)
373
379
 
374
- def get_external_ip(self, virtual_server_id, ip):
375
- nic_details_list = self.list_nic_details(
376
- virtual_server_id=virtual_server_id)
377
- for nic_details in nic_details_list:
378
- if (nic_details['ip'] == ip and
379
- nic_details['subnetType'] == 'PUBLIC'):
380
- return nic_details['natIp']
380
+ def get_external_ip(self, instance_id, ip):
381
+ nics = self.get_nic(instance_id=instance_id)
382
+ for nic in nics:
383
+ if (nic['ip'] == ip and nic['subnetType'] == 'PUBLIC'):
384
+ return nic['natIp']
381
385
  return None
382
386
 
383
- def list_zones(self) -> List[dict]:
387
+ def get_zones(self) -> List[dict]:
384
388
  url = f'{API_ENDPOINT}/project/v3/projects/{self.project_id}/zones'
385
389
  return self._get(url)
386
390
 
387
- def list_products(self, service_zone_id) -> List[dict]:
388
- url = f'{API_ENDPOINT}/product/v2/zones/{service_zone_id}/products'
389
- return self._get(url)
390
-
391
- def list_product_groups(self, service_zone_id) -> List[dict]:
392
- url = f'{API_ENDPOINT}/product/v2/zones/{service_zone_id}/product-groups' # pylint: disable=line-too-long
393
- return self._get(url)
394
-
395
- def list_vpcs(self, service_zone_id) -> List[dict]:
391
+ def get_vpcs(self, service_zone_id) -> List[dict]:
396
392
  url = f'{API_ENDPOINT}/vpc/v2/vpcs?serviceZoneId={service_zone_id}'
397
393
  return self._get(url)
398
394
 
399
- def list_subnets(self) -> List[dict]:
395
+ def get_subnets(self) -> List[dict]:
400
396
  url = f'{API_ENDPOINT}/subnet/v2/subnets?subnetTypes=PUBLIC'
401
397
  return self._get(url)
402
398
 
403
- def del_security_group(self, sg_id):
399
+ def delete_security_group(self, sg_id):
404
400
  url = f'{API_ENDPOINT}/security-group/v2/security-groups/{sg_id}'
405
401
  return self._delete(url)
406
402
 
407
- def del_firwall_rules(self, firewall_id, rule_id_list):
403
+ def delete_firewall_rule(self, firewall_id, rule_ids):
408
404
  url = f'{API_ENDPOINT}/firewall/v2/firewalls/{firewall_id}/rules'
409
- request_body = {'ruleDeletionType': 'PARTIAL', 'ruleIds': rule_id_list}
405
+ request_body = {'ruleDeletionType': 'PARTIAL', 'ruleIds': rule_ids}
410
406
  return self._delete(url, request_body=request_body)
411
407
 
412
- def list_security_groups(self, vpc_id=None, sg_name=None):
408
+ def get_security_groups(self, vpc_id=None, sg_name=None):
413
409
  url = f'{API_ENDPOINT}/security-group/v2/security-groups'
414
410
  parameter = []
415
411
  if vpc_id is not None:
416
412
  parameter.append('vpcId=' + vpc_id)
417
413
  if sg_name is not None:
418
414
  parameter.append('securityGroupName=' + sg_name)
419
- if parameter:
415
+ if len(parameter) > 0:
420
416
  url = url + '?' + '&'.join(parameter)
421
417
  return self._get(url)
422
418
 
423
- def list_igw(self):
419
+ def get_internet_gateway(self):
424
420
  url = f'{API_ENDPOINT}/internet-gateway/v2/internet-gateways'
425
421
  return self._get(url)
426
422
 
427
- def get_vm_info(self, vm_id):
428
- url = f'{API_ENDPOINT}/virtual-server/v3/virtual-servers/{vm_id}'
429
- return self._get(url, contents_key=None)
430
-
431
- def get_firewal_rule_info(self, firewall_id, rule_id):
423
+ def get_firewall_rule_info(self, firewall_id, rule_id):
432
424
  url = f'{API_ENDPOINT}/firewall/v2/firewalls/{firewall_id}/rules/{rule_id}' # pylint: disable=line-too-long
433
425
  return self._get(url, contents_key=None)
434
426
 
435
- def list_firwalls(self):
427
+ def get_firewalls(self):
436
428
  url = f'{API_ENDPOINT}/firewall/v2/firewalls'
437
429
  return self._get(url)
438
430
 
439
- def list_service_zone_names(self):
431
+ def get_service_zone_names(self):
440
432
  url = f'{API_ENDPOINT}/project/v3/projects/{self.project_id}/zones'
441
433
  zone_contents = self._get(url)
442
434
  return [content['serviceZoneName'] for content in zone_contents]
443
435
 
444
- def start_instance(self, vm_id):
445
- url = f'{API_ENDPOINT}/virtual-server/v2/virtual-servers/{vm_id}/start'
436
+ def start_instance(self, instance_id):
437
+ url = f'{API_ENDPOINT}/virtual-server/v2/virtual-servers/{instance_id}/start' # pylint: disable=line-too-long
446
438
  return self._post(url=url, request_body={})
447
439
 
448
- def stop_instance(self, vm_id):
449
- url = f'{API_ENDPOINT}/virtual-server/v2/virtual-servers/{vm_id}/stop'
440
+ def stop_instance(self, instance_id):
441
+ url = f'{API_ENDPOINT}/virtual-server/v2/virtual-servers/{instance_id}/stop' # pylint: disable=line-too-long
450
442
  return self._post(url=url, request_body={})
443
+
444
+ def get_security_group_rules(self, sg_id):
445
+ url = f'{API_ENDPOINT}/security-group/v2/security-groups/{sg_id}/rules'
446
+ return self._get(url)
447
+
448
+ def get_firewall_rules(self, firewall_id):
449
+ url = f'{API_ENDPOINT}/firewall/v2/firewalls/{firewall_id}/rules'
450
+ return self._get(url)
451
+
452
+ def get_instance_info(self, instance_id):
453
+ url = f'{API_ENDPOINT}/virtual-server/v3/virtual-servers/{instance_id}'
454
+ return self._get(url=url, contents_key=None)
455
+
456
+ def create_vpc(self, zone_id):
457
+ vpc_name = 'skyvpc' + zone_id[5:10]
458
+ request_body = {
459
+ 'serviceZoneId': zone_id,
460
+ 'vpcName': vpc_name,
461
+ 'vpcDescription': 'sky vpc'
462
+ }
463
+ url = f'{API_ENDPOINT}/vpc/v3/vpcs'
464
+ return self._post(url, request_body)
465
+
466
+ def create_subnet(self, vpc_id, zone_id):
467
+ subnet_name = 'skysubnet' + zone_id[5:10]
468
+ request_body = {
469
+ 'subnetCidrBlock': '192.168.0.0/24',
470
+ 'subnetName': subnet_name,
471
+ 'subnetType': 'PUBLIC',
472
+ 'vpcId': vpc_id,
473
+ 'subnetDescription': 'sky subnet'
474
+ }
475
+ url = f'{API_ENDPOINT}/subnet/v2/subnets'
476
+ return self._post(url, request_body)
477
+
478
+ def create_internet_gateway(self, vpc_id):
479
+ request_body = {
480
+ 'firewallEnabled': True,
481
+ 'firewallLoggable': False,
482
+ 'internetGatewayType': 'SHARED',
483
+ 'vpcId': vpc_id,
484
+ 'internetGatewayDescription': 'sky internet gateway'
485
+ }
486
+ url = f'{API_ENDPOINT}/internet-gateway/v4/internet-gateways'
487
+ return self._post(url, request_body)
488
+
489
+ def get_vpc_info(self, vpc_id):
490
+ url = f'{API_ENDPOINT}/vpc/v2/vpcs/{vpc_id}'
491
+ return self._get(url=url, contents_key=None)
492
+
493
+ def get_subnet_info(self, subnet_id):
494
+ url = f'{API_ENDPOINT}/subnet/v2/subnets/{subnet_id}'
495
+ return self._get(url=url, contents_key=None)
496
+
497
+ def get_internet_gateway_info(self, internet_gateway_id):
498
+ url = f'{API_ENDPOINT}/internet-gateway/v2/internet-gateways/{internet_gateway_id}' # pylint: disable=line-too-long
499
+ return self._get(url=url, contents_key=None)
500
+
501
+ def get_key_pairs(self):
502
+ url = f'{API_ENDPOINT}/key-pair/v1/key-pairs'
503
+ return self._get(url=url, contents_key=None)
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/8e97adcaacc15293.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/8e97adcaacc15293.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-1b69b196a4dbffef.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-32b2caae3445bf3b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_error-1be831200e60c5c0.js" defer=""></script><script src="/dashboard/_next/static/R07f8gwfXT1U0zRznq4Lg/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/R07f8gwfXT1U0zRznq4Lg/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"R07f8gwfXT1U0zRznq4Lg","assetPrefix":"/dashboard","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/8e97adcaacc15293.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/8e97adcaacc15293.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-1b69b196a4dbffef.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-32b2caae3445bf3b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_error-1be831200e60c5c0.js" defer=""></script><script src="/dashboard/_next/static/vA3PPpkBwpRTRNBHFYAw_/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/vA3PPpkBwpRTRNBHFYAw_/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"vA3PPpkBwpRTRNBHFYAw_","assetPrefix":"/dashboard","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
@@ -0,0 +1,6 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[722],{8706:function(e,s,t){(window.__NEXT_P=window.__NEXT_P||[]).push(["/clusters/[cluster]",function(){return t(6996)}])},6639:function(e,s,t){"use strict";t.d(s,{Z:function(){return r}});/**
2
+ * @license lucide-react v0.407.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */let r=(0,t(998).Z)("ChevronRight",[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]])},4303:function(e,s,t){"use strict";t.d(s,{_q:function(){return n},pJ:function(){return i}});var r=t(1272);let n=e=>{if(!e)return"No YAML available";try{let s=r.ZP.load(e),t=r.ZP.dump(s,{lineWidth:-1,styles:{"!!str":"literal"},quotingType:"'",forceQuotes:!1,noRefs:!0,sortKeys:!1,condenseFlow:!1,indent:2}).split("\n"),n=[],a=-1;for(let e=0;e<t.length;e++){let s=t[e],r=s.search(/\S/);0===r&&a>=0&&e>0&&n.push(""),n.push(s),a=r}return n.join("\n").trim()}catch(s){return console.error("YAML formatting error:",s),e}},a=e=>"string"==typeof e?e.substring(0,50)+"...":e&&e.name?"name: ".concat(e.name):e&&e.resources?"Task configuration":"YAML document",l=(e,s)=>{try{let t=r.ZP.load(e),n=r.ZP.dump(t,{lineWidth:-1,styles:{"!!str":"literal"},quotingType:"'",forceQuotes:!1,noRefs:!0,sortKeys:!1,condenseFlow:!1,indent:2}).split("\n"),l=[],i=-1;for(let e=0;e<n.length;e++){let s=n[e],t=s.search(/\S/);0===t&&i>=0&&e>0&&l.push(""),l.push(s),i=t}return{index:s,content:l.join("\n").trim(),preview:a(t)}}catch(t){return console.error("YAML formatting error for document ".concat(s,":"),t),{index:s,content:e,preview:"Invalid YAML"}}},i=e=>{if(!e)return[];try{let s=[],t=e.split(/^---$/m);for(let e=0;e<t.length;e++){let r=t[e].trim();r&&""!==r&&s.push(r)}return(s.length>1?s.slice(1):s).map((e,s)=>l(e,s))}catch(s){return console.error("YAML formatting error:",s),[{index:0,content:e,preview:"Invalid YAML"}]}}},6996:function(e,s,t){"use strict";t.r(s);var r=t(5893),n=t(7294),a=t(8799),l=t(938),i=t(1163);t(9470);var c=t(1664),o=t.n(c),d=t(9037),m=t(9307),x=t(7673),u=t(3266),h=t(3626),j=t(282),f=t(8671),N=t(5895),y=t(6639);t(1272);var v=t(6989),p=t(9284),b=t(3001),g=t(9008),w=t.n(g),k=t(4303);let _=(e,s)=>{let t="",r="";return e>=0&&(t=e+"m",r=" "),s&&(t+="".concat(r,"(down)")),""===t&&(t="-"),t};function C(e){let{clusterData:s,clusterJobData:t,clusterJobsLoading:a,refreshClusterJobsOnly:i}=e,[c,d]=(0,n.useState)(!1),[u,h]=(0,n.useState)(!1),[p,b]=(0,n.useState)(!1),g=async()=>{try{let e=(0,k._q)(s.task_yaml);await navigator.clipboard.writeText(e),h(!0),setTimeout(()=>h(!1),2e3)}catch(e){console.error("Failed to copy YAML to clipboard:",e)}},w=async()=>{try{await navigator.clipboard.writeText(s.command),b(!0),setTimeout(()=>b(!1),2e3)}catch(e){console.error("Failed to copy command to clipboard:",e)}},C=(null==s?void 0:s.command)||(null==s?void 0:s.task_yaml);return(0,r.jsxs)("div",{children:[(0,r.jsx)("div",{className:"mb-6",children:(0,r.jsxs)(x.Zb,{children:[(0,r.jsx)("div",{className:"flex items-center justify-between px-4 pt-4",children:(0,r.jsx)("h3",{className:"text-lg font-semibold",children:"Details"})}),(0,r.jsx)("div",{className:"p-4",children:(0,r.jsxs)("div",{className:"grid grid-cols-2 gap-6",children:[(0,r.jsxs)("div",{children:[(0,r.jsx)("div",{className:"text-gray-600 font-medium text-base",children:"Status"}),(0,r.jsx)("div",{className:"text-base mt-1",children:(0,r.jsx)(m.OE,{status:s.status})})]}),(0,r.jsxs)("div",{children:[(0,r.jsx)("div",{className:"text-gray-600 font-medium text-base",children:"Cluster"}),(0,r.jsx)("div",{className:"text-base mt-1",children:s.cluster})]}),(0,r.jsxs)("div",{children:[(0,r.jsx)("div",{className:"text-gray-600 font-medium text-base",children:"User"}),(0,r.jsx)("div",{className:"text-base mt-1",children:s.user})]}),(0,r.jsxs)("div",{children:[(0,r.jsx)("div",{className:"text-gray-600 font-medium text-base",children:"Infra"}),(0,r.jsx)("div",{className:"text-base mt-1",children:s.infra?(0,r.jsx)(v.Md,{content:s.full_infra||s.infra,className:"text-sm text-muted-foreground",children:(0,r.jsxs)("span",{children:[(0,r.jsx)(o(),{href:"/infra",className:"text-blue-600 hover:underline",children:s.cloud||s.infra.split("(")[0].trim()}),s.infra.includes("(")&&(0,r.jsx)("span",{children:" "+s.infra.substring(s.infra.indexOf("("))})]})}):"N/A"})]}),(0,r.jsxs)("div",{children:[(0,r.jsx)("div",{className:"text-gray-600 font-medium text-base",children:"Resources"}),(0,r.jsx)("div",{className:"text-base mt-1",children:s.resources_str_full||s.resources_str||"N/A"})]}),(0,r.jsxs)("div",{children:[(0,r.jsx)("div",{className:"text-gray-600 font-medium text-base",children:"Started"}),(0,r.jsx)("div",{className:"text-base mt-1",children:s.time?new Date(s.time).toLocaleString():"N/A"})]}),(0,r.jsxs)("div",{children:[(0,r.jsx)("div",{className:"text-gray-600 font-medium text-base",children:"Autostop"}),(0,r.jsx)("div",{className:"text-base mt-1",children:_(s.autostop,s.to_down)})]}),C&&(0,r.jsxs)("div",{className:"col-span-2",children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)("div",{className:"text-gray-600 font-medium text-base",children:"Entrypoint"}),s.command&&(0,r.jsx)(v.WH,{content:p?"Copied!":"Copy command",className:"text-muted-foreground",children:(0,r.jsx)("button",{onClick:w,className:"flex items-center text-gray-500 hover:text-gray-700 transition-colors duration-200 p-1 ml-2",children:p?(0,r.jsx)(j.Z,{className:"w-4 h-4 text-green-600"}):(0,r.jsx)(f.Z,{className:"w-4 h-4"})})})]}),(0,r.jsxs)("div",{className:"space-y-4 mt-3",children:[s.command&&(0,r.jsx)("div",{children:(0,r.jsx)("div",{className:"bg-gray-50 border border-gray-200 rounded-md p-3",children:(0,r.jsx)("code",{className:"text-sm text-gray-800 font-mono break-all",children:s.command})})}),s.task_yaml&&"{}"!==s.task_yaml&&!s.cluster.startsWith("sky-jobs-controller-")&&!s.cluster.startsWith("sky-serve-controller-")&&(0,r.jsxs)("div",{children:[(0,r.jsxs)("div",{className:"flex items-center mb-2",children:[(0,r.jsxs)("button",{onClick:()=>{d(!c)},className:"flex items-center text-left focus:outline-none text-gray-700 hover:text-gray-900 transition-colors duration-200",children:[c?(0,r.jsx)(N.Z,{className:"w-4 h-4 mr-1"}):(0,r.jsx)(y.Z,{className:"w-4 h-4 mr-1"}),(0,r.jsx)("span",{className:"text-base",children:"Show SkyPilot YAML"})]}),(0,r.jsx)(v.WH,{content:u?"Copied!":"Copy YAML",className:"text-muted-foreground",children:(0,r.jsx)("button",{onClick:g,className:"flex items-center text-gray-500 hover:text-gray-700 transition-colors duration-200 p-1 ml-2",children:u?(0,r.jsx)(j.Z,{className:"w-4 h-4 text-green-600"}):(0,r.jsx)(f.Z,{className:"w-4 h-4"})})})]}),c&&(0,r.jsx)("div",{className:"bg-gray-50 border border-gray-200 rounded-md p-3 max-h-96 overflow-y-auto",children:(0,r.jsx)("pre",{className:"text-sm text-gray-800 font-mono whitespace-pre-wrap",children:(0,k._q)(s.task_yaml)})})]})]})]})]})})]})}),(0,r.jsx)("div",{className:"mb-8",children:(0,r.jsx)(l.ClusterJobs,{clusterName:s.cluster,clusterJobData:t,loading:a,refreshClusterJobsOnly:i})})]})}s.default=function(){let e=(0,i.useRouter)(),{cluster:s}=e.query,[t,l]=(0,n.useState)(!1),[c,m]=(0,n.useState)(!0),[x,j]=(0,n.useState)(!1),[f,N]=(0,n.useState)(!1),y=(0,b.X)(),{clusterData:g,clusterJobData:k,loading:_,clusterDetailsLoading:S,clusterJobsLoading:L,refreshData:Z,refreshClusterJobsOnly:A}=(0,u.QL)({cluster:s});n.useEffect(()=>{!S&&c&&m(!1)},[S,c]);let M=async()=>{l(!0),await Z(),l(!1)};if(!e.isReady)return(0,r.jsx)("div",{children:"Loading..."});let O=s?"Cluster: ".concat(s," | SkyPilot Dashboard"):"Cluster Details | SkyPilot Dashboard";return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(w(),{children:(0,r.jsx)("title",{children:O})}),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"flex items-center justify-between mb-4 h-5",children:[(0,r.jsxs)("div",{className:"text-base flex items-center",children:[(0,r.jsx)(o(),{href:"/clusters",className:"text-sky-blue hover:underline",children:"Sky Clusters"}),(0,r.jsx)("span",{className:"mx-2 text-gray-500",children:"›"}),(0,r.jsx)(o(),{href:"/clusters/".concat(s),className:"text-sky-blue hover:underline",children:s})]}),(0,r.jsx)("div",{className:"text-sm flex items-center",children:(0,r.jsxs)("div",{className:"text-sm flex items-center",children:[(S||t)&&(0,r.jsxs)("div",{className:"flex items-center mr-4",children:[(0,r.jsx)(a.Z,{size:15,className:"mt-0"}),(0,r.jsx)("span",{className:"ml-2 text-gray-500",children:"Loading..."})]}),g&&(0,r.jsxs)("div",{className:"flex items-center space-x-4",children:[(0,r.jsx)(v.WH,{content:"Refresh",className:"text-sm text-muted-foreground",children:(0,r.jsxs)("button",{onClick:M,disabled:S||t,className:"text-sky-blue hover:text-sky-blue-bright font-medium inline-flex items-center",children:[(0,r.jsx)(h.Z,{className:"w-4 h-4 mr-1.5"}),!y&&(0,r.jsx)("span",{children:"Refresh"})]})}),(0,r.jsx)(d.Status2Actions,{withLabel:!0,cluster:g.cluster,status:g.status,onOpenSSHModal:()=>{j(!0)},onOpenVSCodeModal:()=>{N(!0)}})]})]})})]}),S&&c?(0,r.jsxs)("div",{className:"flex justify-center items-center py-12",children:[(0,r.jsx)(a.Z,{size:24,className:"mr-2"}),(0,r.jsx)("span",{className:"text-gray-500",children:"Loading cluster details..."})]}):g?(0,r.jsx)(C,{clusterData:g,clusterJobData:k,clusterJobsLoading:L,refreshClusterJobsOnly:A}):null,(0,r.jsx)(p.Oh,{isOpen:x,onClose:()=>j(!1),cluster:s}),(0,r.jsx)(p._R,{isOpen:f,onClose:()=>N(!1),cluster:s})]})]})}},9008:function(e,s,t){e.exports=t(7219)}},function(e){e.O(0,[616,760,799,804,664,798,947,470,901,969,856,973,938,37,888,774,179],function(){return e(e.s=8706)}),_N_E=e.O()}]);
@@ -0,0 +1,16 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[315,350],{479:function(e,t,s){(window.__NEXT_P=window.__NEXT_P||[]).push(["/jobs/[job]",function(){return s(8099)}])},6639:function(e,t,s){"use strict";s.d(t,{Z:function(){return r}});/**
2
+ * @license lucide-react v0.407.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */let r=(0,s(998).Z)("ChevronRight",[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]])},8671:function(e,t,s){"use strict";s.d(t,{Z:function(){return r}});/**
7
+ * @license lucide-react v0.407.0 - ISC
8
+ *
9
+ * This source code is licensed under the ISC license.
10
+ * See the LICENSE file in the root directory of this source tree.
11
+ */let r=(0,s(998).Z)("Copy",[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]])},3626:function(e,t,s){"use strict";s.d(t,{Z:function(){return r}});/**
12
+ * @license lucide-react v0.407.0 - ISC
13
+ *
14
+ * This source code is licensed under the ISC license.
15
+ * See the LICENSE file in the root directory of this source tree.
16
+ */let r=(0,s(998).Z)("RotateCw",[["path",{d:"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8",key:"1p45f6"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}]])},9307:function(e,t,s){"use strict";s.d(t,{Cl:function(){return c},OE:function(){return d}});var r=s(5893);s(7294);var n=s(8799),a=s(6989),l=s(3850);let c=e=>{switch(e){case"LAUNCHING":return"bg-blue-100 text-sky-blue";case"RUNNING":return"bg-green-50 text-green-700";case"STOPPED":return"bg-yellow-100 text-yellow-800";case"TERMINATED":default:return"bg-gray-100 text-gray-800";case"PENDING":case"CANCELLED":case"CANCELLING":return"bg-yellow-50 text-yellow-700";case"SUCCEEDED":return"bg-blue-50 text-blue-700";case"FAILED":case"FAILED_PRECHECKS":case"FAILED_NO_RESOURCE":case"FAILED_CONTROLLER":return"bg-red-50 text-red-700";case"RECOVERING":return"bg-orange-50 text-orange-700";case"SUBMITTED":return"bg-indigo-50 text-indigo-700";case"STARTING":return"bg-cyan-50 text-cyan-700";case"FAILED_SETUP":return"bg-pink-50 text-pink-700"}},o=e=>{switch(e){case"LAUNCHING":case"STARTING":return(0,r.jsx)(n.Z,{size:12,className:"w-3 h-3 mr-1"});case"RUNNING":default:return(0,r.jsx)(l.W2,{className:"w-3 h-3 mr-1"});case"STOPPED":return(0,r.jsx)(l.fp,{className:"w-3 h-3 mr-1"});case"TERMINATED":case"FAILED":case"CANCELLED":return(0,r.jsx)(l.Ps,{className:"w-3 h-3 mr-1"});case"SUCCEEDED":return(0,r.jsx)(l.Ye,{className:"w-3 h-3 mr-1"});case"PENDING":case"RECOVERING":case"SUBMITTED":case"CANCELLING":case"FAILED_SETUP":case"FAILED_PRECHECKS":case"FAILED_NO_RESOURCE":case"FAILED_CONTROLLER":return(0,r.jsx)(l.J$,{className:"w-3 h-3 mr-1"})}},i=e=>{let t=c(e),s=o(e);return(0,r.jsxs)("span",{className:"".concat("inline-flex items-center px-2 py-1 rounded-full text-sm"," ").concat(t),children:[s,e]})},d=e=>{let{status:t}=e;return(0,r.jsx)(a.WH,{content:t,className:"text-muted-foreground text-sm",children:(0,r.jsx)("span",{children:i(t)})})}},7673:function(e,t,s){"use strict";s.d(t,{Ol:function(){return i},Zb:function(){return o},aY:function(){return m},eW:function(){return x},ll:function(){return d}});var r=s(5893),n=s(7294),a=s(5697),l=s.n(a),c=s(2350);let o=n.forwardRef((e,t)=>{let{className:s,children:n,...a}=e;return(0,r.jsx)("div",{ref:t,className:(0,c.cn)("rounded-lg border bg-card text-card-foreground shadow-sm",s),...a,children:n})});o.displayName="Card",o.propTypes={className:l().string,children:l().node};let i=n.forwardRef((e,t)=>{let{className:s,children:n,...a}=e;return(0,r.jsx)("div",{ref:t,className:(0,c.cn)("flex flex-col space-y-1.5 p-6",s),...a,children:n})});i.displayName="CardHeader",i.propTypes={className:l().string,children:l().node};let d=n.forwardRef((e,t)=>{let{className:s,children:n,...a}=e;return(0,r.jsx)("h3",{ref:t,className:(0,c.cn)("text-2xl font-semibold leading-none tracking-tight",s),...a,children:n})});d.displayName="CardTitle",d.propTypes={className:l().string,children:l().node};let u=n.forwardRef((e,t)=>{let{className:s,children:n,...a}=e;return(0,r.jsx)("p",{ref:t,className:(0,c.cn)("text-sm text-muted-foreground",s),...a,children:n})});u.displayName="CardDescription",u.propTypes={className:l().string,children:l().node};let m=n.forwardRef((e,t)=>{let{className:s,children:n,...a}=e;return(0,r.jsx)("div",{ref:t,className:(0,c.cn)("p-6 pt-0",s),...a,children:n})});m.displayName="CardContent",m.propTypes={className:l().string,children:l().node};let x=n.forwardRef((e,t)=>{let{className:s,children:n,...a}=e;return(0,r.jsx)("div",{ref:t,className:(0,c.cn)("flex items-center p-6 pt-0",s),...a,children:n})});x.displayName="CardFooter",x.propTypes={className:l().string,children:l().node}},7145:function(e,t,s){"use strict";s.d(t,{x:function(){return n}});var r=s(3225);let n={fetch:async(e,t)=>{let s=window.location.origin,n="".concat(s).concat(r.f4).concat(e),a=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),l=a.headers.get("X-Skypilot-Request-ID")||a.headers.get("X-Request-ID"),c=await fetch("".concat(s).concat(r.f4,"/api/get?request_id=").concat(l)),o=await c.json();return o.return_value?JSON.parse(o.return_value):[]},post:async(e,t)=>{let s=window.location.origin,n="".concat(s).concat(r.f4).concat(e);return await fetch(n,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})},stream:async(e,t,s)=>{let r=(await n.post(e,t)).body.getReader();try{for(;;){let{done:e,value:t}=await r.read();if(e)break;let n=new TextDecoder().decode(t);s(n)}}catch(e){throw console.error("Error in stream:",e),e}},get:async e=>{let t=window.location.origin,s="".concat(t).concat(r.f4).concat(e);return await fetch(s)}}},2350:function(e,t,s){"use strict";s.d(t,{cn:function(){return a}});var r=s(512),n=s(8388);function a(){for(var e=arguments.length,t=Array(e),s=0;s<e;s++)t[s]=arguments[s];return(0,n.m6)((0,r.W)(t))}},4303:function(e,t,s){"use strict";s.d(t,{_q:function(){return n},pJ:function(){return c}});var r=s(1272);let n=e=>{if(!e)return"No YAML available";try{let t=r.ZP.load(e),s=r.ZP.dump(t,{lineWidth:-1,styles:{"!!str":"literal"},quotingType:"'",forceQuotes:!1,noRefs:!0,sortKeys:!1,condenseFlow:!1,indent:2}).split("\n"),n=[],a=-1;for(let e=0;e<s.length;e++){let t=s[e],r=t.search(/\S/);0===r&&a>=0&&e>0&&n.push(""),n.push(t),a=r}return n.join("\n").trim()}catch(t){return console.error("YAML formatting error:",t),e}},a=e=>"string"==typeof e?e.substring(0,50)+"...":e&&e.name?"name: ".concat(e.name):e&&e.resources?"Task configuration":"YAML document",l=(e,t)=>{try{let s=r.ZP.load(e),n=r.ZP.dump(s,{lineWidth:-1,styles:{"!!str":"literal"},quotingType:"'",forceQuotes:!1,noRefs:!0,sortKeys:!1,condenseFlow:!1,indent:2}).split("\n"),l=[],c=-1;for(let e=0;e<n.length;e++){let t=n[e],s=t.search(/\S/);0===s&&c>=0&&e>0&&l.push(""),l.push(t),c=s}return{index:t,content:l.join("\n").trim(),preview:a(s)}}catch(s){return console.error("YAML formatting error for document ".concat(t,":"),s),{index:t,content:e,preview:"Invalid YAML"}}},c=e=>{if(!e)return[];try{let t=[],s=e.split(/^---$/m);for(let e=0;e<s.length;e++){let r=s[e].trim();r&&""!==r&&t.push(r)}return(t.length>1?t.slice(1):t).map((e,t)=>l(e,t))}catch(t){return console.error("YAML formatting error:",t),[{index:0,content:e,preview:"Invalid YAML"}]}}},8099:function(e,t,s){"use strict";s.r(t);var r=s(5893),n=s(7294),a=s(8799),l=s(1163);s(9470);var c=s(7673),o=s(8969),i=s(1664),d=s.n(i),u=s(3626),m=s(282),x=s(8671),f=s(5895),g=s(6639),h=s(6989),p=s(9307),j=s(3001),y=s(9008),N=s.n(y),b=s(4303);function v(e){let{jobData:t,activeTab:s,setIsLoadingLogs:l,setIsLoadingControllerLogs:c,isLoadingLogs:i,isLoadingControllerLogs:u,refreshFlag:j}=e,[y,N]=(0,n.useState)(""),[v,w]=(0,n.useState)(""),[E,L]=(0,n.useState)(!1),[C,S]=(0,n.useState)({}),[R,T]=(0,n.useState)(!1),[I,k]=(0,n.useState)(!1),[A,D]=(0,n.useState)(0),[_,Z]=(0,n.useState)(0),[P,O]=(0,n.useState)(!1),[q,F]=(0,n.useState)(!1),[M,U]=(0,n.useState)(!1),[G,W]=(0,n.useState)(!1),H=(0,n.useRef)(null),J=(0,n.useRef)(null),Y=(0,n.useRef)(new WeakSet),B=(0,n.useRef)(null),z=(0,n.useRef)(null),$=(0,n.useRef)(""),V=(0,n.useRef)(""),X=(0,n.useRef)(null);(0,n.useRef)(0);let K=(0,n.useCallback)(function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"request";if(e){if(Y.current.has(e)){console.log("".concat(t," controller already aborted previously, skipping"));return}try{if("function"!=typeof e.abort){console.warn("Controller for ".concat(t," does not have abort method"));return}if(e.signal&&e.signal.aborted){console.log("".concat(t," already aborted via signal, skipping")),Y.current.add(e);return}e.abort(),Y.current.add(e),console.log("Successfully aborted ".concat(t))}catch(s){console.log("Caught error while aborting ".concat(t,":"),s.name,s.message),Y.current.add(e),"AbortError"!==s.name&&"InvalidStateError"!==s.name&&console.warn("Unexpected error aborting ".concat(t,":"),s)}}},[]),Q=(0,n.useCallback)(e=>{let t="logs"===e?B:z;if(t.current)for(let s of[()=>t.current.querySelector(".logs-container"),()=>t.current.querySelector('[class*="logs-container"]'),()=>t.current.querySelector('div[style*="overflow"]'),()=>t.current]){let t=s();if(t&&t.scrollHeight>t.clientHeight){t.scrollTop=t.scrollHeight,console.log("Auto-scrolled ".concat(e," to bottom"));break}}},[]),ee=["PENDING","SUBMITTED","STARTING"].includes(t.status),et=["PENDING","SUBMITTED"].includes(t.status),es=["RECOVERING"].includes(t.status),er=e=>{S(t=>({...t,[e]:!t[e]}))},en=async()=>{try{let e=(0,b.pJ)(t.dag_yaml),s="";s=1===e.length?e[0].content:e.length>1?e.map(e=>e.content).join("\n---\n"):t.dag_yaml,await navigator.clipboard.writeText(s),T(!0),setTimeout(()=>T(!1),2e3)}catch(e){console.error("Failed to copy YAML to clipboard:",e)}},ea=async()=>{try{await navigator.clipboard.writeText(t.entrypoint),k(!0),setTimeout(()=>k(!1),2e3)}catch(e){console.error("Failed to copy command to clipboard:",e)}};(0,n.useEffect)(()=>{N(""),D(0),W(!1)},[s,t.id]),(0,n.useEffect)(()=>{w(""),Z(0),W(!1)},[s,t.id]);let el=(0,n.useCallback)(function(e,t,s,r){let n=arguments.length>4&&void 0!==arguments[4]&&arguments[4],a="logs"===e?H:J;if(a.current)return console.log("Request already active for ".concat(e,", skipping...")),()=>{};let l=!0,c=new AbortController;return"logs"===e&&(ee||es)?(r(!1),n&&O(!1),()=>{}):"controllerlogs"===e&&et?(r(!1),n&&F(!1),()=>{}):t?(a.current=c,r(!0),U(!0),n&&(s(""),"logs"===e?D(0):Z(0)),(0,o.NJ)({jobId:t,controller:"controllerlogs"===e,signal:c.signal,onNewLog:t=>{if(l){let s=(0,h.q8)(t);G||W(!0),ec(e,s),"logs"===e?D(e=>e+s.length):Z(e=>e+s.length)}}}).then(()=>{l&&(r(!1),n&&("logs"===e?O(!1):F(!1)),requestAnimationFrame(()=>{Q(e)}))}).catch(t=>{l&&("AbortError"!==t.name&&(console.error("Error streaming ".concat(e,":"),t),t.message&&s(e=>e+"Error fetching logs: ".concat(t.message,"\n"))),r(!1),n&&("logs"===e?O(!1):F(!1)))}).finally(()=>{console.log("Cleaning up ".concat(e," request")),l=!1,a.current===c&&(K(c,e),a.current=null),"logs"===e?$.current="":V.current="",X.current&&(clearTimeout(X.current),X.current=null)}),()=>{console.log("Cleaning up ".concat(e," request")),l=!1,a.current===c&&(K(c,"".concat(e," cleanup")),a.current=null),"logs"===e?$.current="":V.current="",X.current&&(clearTimeout(X.current),X.current=null)}):()=>{l=!1}},[ee,et,es,G,K]);(0,n.useEffect)(()=>{if(H.current&&(K(H.current,"logs"),H.current=null),!ee&&!es)return el("logs",t.id,N,l)},[t.id,el,l,ee,es,K]),(0,n.useEffect)(()=>{if(J.current&&(K(J.current,"controller logs"),J.current=null),!et)return el("controllerlogs",t.id,w,c)},[t.id,el,c,et,K]),(0,n.useEffect)(()=>{if(j>0&&"logs"===s)return H.current&&(K(H.current,"logs refresh"),H.current=null),O(!0),el("logs",t.id,N,l,!0)},[j,s,t.id,el,l,K]),(0,n.useEffect)(()=>{if(j>0&&"controllerlogs"===s)return J.current&&(K(J.current,"controller logs refresh"),J.current=null),F(!0),el("controllerlogs",t.id,w,c,!0)},[j,s,t.id,el,c,K]),(0,n.useEffect)(()=>()=>{console.log("Cleaning up managed job log requests..."),H.current&&(K(H.current,"logs cleanup"),H.current=null),J.current&&(K(J.current,"controller logs cleanup"),J.current=null),X.current&&(clearTimeout(X.current),X.current=null),$.current="",V.current="",l(!1),c(!1),O(!1),F(!1)},[K]),(0,n.useEffect)(()=>{let e=()=>{document.hidden?(console.log("Page hidden - pausing log streaming for performance"),X.current&&(clearTimeout(X.current),X.current=null)):console.log("Page visible - resuming normal operation")};return document.addEventListener("visibilitychange",e),()=>{document.removeEventListener("visibilitychange",e)}},[]),(0,n.useEffect)(()=>{let e=()=>{("logs"===s&&y||"controllerlogs"===s&&v)&&Q("logs"===s?"logs":"controllerlogs")};requestAnimationFrame(()=>{requestAnimationFrame(e)})},[s,y,v,Q]);let ec=(0,n.useCallback)((e,t)=>{("logs"===e?N:w)(e=>e+t),requestAnimationFrame(()=>{Q(e)})},[Q]);return"logs"===s?(0,r.jsx)("div",{className:"max-h-96 overflow-y-auto",ref:B,children:ee?(0,r.jsx)("div",{className:"bg-[#f7f7f7] flex items-center justify-center py-4 text-gray-500",children:(0,r.jsx)("span",{children:"Waiting for the job to start, please refresh after a while"})}):es?(0,r.jsx)("div",{className:"bg-[#f7f7f7] flex items-center justify-center py-4 text-gray-500",children:(0,r.jsx)("span",{children:"Waiting for the job to recover, please refresh after a while"})}):G||y?(0,r.jsx)(h.$B,{logs:y}):i?(0,r.jsxs)("div",{className:"flex items-center justify-center py-4",children:[(0,r.jsx)(a.Z,{size:20,className:"mr-2"}),(0,r.jsx)("span",{children:"Loading logs..."})]}):(0,r.jsx)(h.$B,{logs:y})}):"controllerlogs"===s?(0,r.jsx)("div",{className:"max-h-96 overflow-y-auto",ref:z,children:et?(0,r.jsx)("div",{className:"bg-[#f7f7f7] flex items-center justify-center py-4 text-gray-500",children:(0,r.jsx)("span",{children:"Waiting for the job controller process to start, please refresh after a while"})}):G||v?(0,r.jsx)(h.$B,{logs:v,controller:!0}):u?(0,r.jsxs)("div",{className:"flex items-center justify-center py-4",children:[(0,r.jsx)(a.Z,{size:20,className:"mr-2"}),(0,r.jsx)("span",{children:"Loading logs..."})]}):(0,r.jsx)(h.$B,{logs:v,controller:!0})}):(0,r.jsxs)("div",{className:"grid grid-cols-2 gap-6",children:[(0,r.jsxs)("div",{children:[(0,r.jsx)("div",{className:"text-gray-600 font-medium text-base",children:"Job ID (Name)"}),(0,r.jsxs)("div",{className:"text-base mt-1",children:[t.id," ",t.name?"(".concat(t.name,")"):""]})]}),(0,r.jsxs)("div",{children:[(0,r.jsx)("div",{className:"text-gray-600 font-medium text-base",children:"Status"}),(0,r.jsxs)("div",{className:"text-base mt-1 flex items-center",children:[(0,r.jsx)(p.OE,{status:t.status}),t.priority&&(0,r.jsxs)("span",{className:"ml-2",children:[" (Priority: ",t.priority,")"]})]})]}),(0,r.jsxs)("div",{children:[(0,r.jsx)("div",{className:"text-gray-600 font-medium text-base",children:"User"}),(0,r.jsx)("div",{className:"text-base mt-1",children:t.user})]}),(0,r.jsxs)("div",{children:[(0,r.jsx)("div",{className:"text-gray-600 font-medium text-base",children:"Requested Resources"}),(0,r.jsx)("div",{className:"text-base mt-1",children:t.requested_resources||"N/A"})]}),(0,r.jsxs)("div",{children:[(0,r.jsx)("div",{className:"text-gray-600 font-medium text-base",children:"Infra"}),(0,r.jsx)("div",{className:"text-base mt-1",children:t.infra?(0,r.jsx)(h.Md,{content:t.full_infra||t.infra,className:"text-sm text-muted-foreground",children:(0,r.jsxs)("span",{children:[(0,r.jsx)(d(),{href:"/infra",className:"text-blue-600 hover:underline",children:t.cloud||t.infra.split("(")[0].trim()}),t.infra.includes("(")&&(0,r.jsx)("span",{children:" "+t.infra.substring(t.infra.indexOf("("))})]})}):"-"})]}),(0,r.jsxs)("div",{children:[(0,r.jsx)("div",{className:"text-gray-600 font-medium text-base",children:"Resources"}),(0,r.jsx)("div",{className:"text-base mt-1",children:t.resources_str_full||t.resources_str||"-"})]}),(t.entrypoint||t.dag_yaml)&&(0,r.jsxs)("div",{className:"col-span-2",children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)("div",{className:"text-gray-600 font-medium text-base",children:"Entrypoint"}),t.entrypoint&&(0,r.jsx)(h.WH,{content:I?"Copied!":"Copy command",className:"text-muted-foreground",children:(0,r.jsx)("button",{onClick:ea,className:"flex items-center text-gray-500 hover:text-gray-700 transition-colors duration-200 p-1 ml-2",children:I?(0,r.jsx)(m.Z,{className:"w-4 h-4 text-green-600"}):(0,r.jsx)(x.Z,{className:"w-4 h-4"})})})]}),(0,r.jsxs)("div",{className:"space-y-4 mt-3",children:[t.entrypoint&&(0,r.jsx)("div",{children:(0,r.jsx)("div",{className:"bg-gray-50 border border-gray-200 rounded-md p-3",children:(0,r.jsx)("code",{className:"text-sm text-gray-800 font-mono break-all",children:t.entrypoint})})}),t.dag_yaml&&"{}"!==t.dag_yaml&&(0,r.jsxs)("div",{children:[(0,r.jsxs)("div",{className:"flex items-center mb-2",children:[(0,r.jsxs)("button",{onClick:()=>{L(!E)},className:"flex items-center text-left focus:outline-none text-gray-700 hover:text-gray-900 transition-colors duration-200",children:[E?(0,r.jsx)(f.Z,{className:"w-4 h-4 mr-1"}):(0,r.jsx)(g.Z,{className:"w-4 h-4 mr-1"}),(0,r.jsx)("span",{className:"text-base",children:"Show SkyPilot YAML"})]}),(0,r.jsx)(h.WH,{content:R?"Copied!":"Copy YAML",className:"text-muted-foreground",children:(0,r.jsx)("button",{onClick:en,className:"flex items-center text-gray-500 hover:text-gray-700 transition-colors duration-200 p-1 ml-2",children:R?(0,r.jsx)(m.Z,{className:"w-4 h-4 text-green-600"}):(0,r.jsx)(x.Z,{className:"w-4 h-4"})})})]}),E&&(0,r.jsx)("div",{className:"bg-gray-50 border border-gray-200 rounded-md p-3 max-h-96 overflow-y-auto",children:(()=>{let e=(0,b.pJ)(t.dag_yaml);return 0===e.length?(0,r.jsx)("div",{className:"text-gray-500",children:"No YAML available"}):1===e.length?(0,r.jsx)("pre",{className:"text-sm text-gray-800 font-mono whitespace-pre-wrap",children:e[0].content}):(0,r.jsx)("div",{className:"space-y-4",children:e.map((e,t)=>(0,r.jsxs)("div",{className:"border-b border-gray-200 pb-4 last:border-b-0",children:[(0,r.jsx)("button",{onClick:()=>er(t),className:"flex items-center justify-between w-full text-left focus:outline-none",children:(0,r.jsxs)("div",{className:"flex items-center",children:[C[t]?(0,r.jsx)(f.Z,{className:"w-4 h-4 mr-2"}):(0,r.jsx)(g.Z,{className:"w-4 h-4 mr-2"}),(0,r.jsxs)("span",{className:"text-sm font-medium text-gray-700",children:["Task ",t+1,": ",e.preview]})]})}),C[t]&&(0,r.jsx)("div",{className:"mt-3 ml-6",children:(0,r.jsx)("pre",{className:"text-sm text-gray-800 font-mono whitespace-pre-wrap",children:e.content})})]},t))})})()})]})]})]})]})}t.default=function(){var e;let t=(0,l.useRouter)(),{job:s,tab:i}=t.query,[m,x]=(0,n.useState)(0),{jobData:f,loading:g}=(0,o.UA)(s,m),[p,y]=(0,n.useState)(!1),[b,w]=(0,n.useState)(!0),[E,L]=(0,n.useState)(!1),[C,S]=(0,n.useState)(!1),[R,T]=(0,n.useState)(!1),[I,k]=(0,n.useState)(!1),[A,D]=(0,n.useState)(!1),[_,Z]=(0,n.useState)(0),[P,O]=(0,n.useState)(0),q=(0,j.X)();n.useEffect(()=>{!g&&b&&w(!1)},[g,b]);let F=e=>{let t=document.getElementById(e);t&&t.scrollIntoView({behavior:"smooth"})};(0,n.useEffect)(()=>{k(!0)},[]),(0,n.useEffect)(()=>{if(!A){let e=new MutationObserver(()=>{let t=document.getElementById("logs-section"),s=document.getElementById("controller-logs-section");("logs"===i&&t||"controllerlogs"===i&&s)&&(D(!0),e.disconnect())});return e.observe(document.body,{childList:!0,subtree:!0}),()=>e.disconnect()}},[A,i]),(0,n.useEffect)(()=>{if(t.isReady&&I&&A&&!R){let e=setTimeout(()=>{"logs"===i?(F("logs-section"),T(!0)):"controllerlogs"===i&&(F("controller-logs-section"),T(!0))},800);return()=>clearTimeout(e)}},[t.isReady,i,R,I,A]),(0,n.useEffect)(()=>{T(!1),D(!1)},[i]);let M=async()=>{y(!0);try{x(e=>e+1),Z(e=>e+1),O(e=>e+1)}catch(e){console.error("Error refreshing data:",e)}finally{y(!1)}};if(!t.isReady)return(0,r.jsx)("div",{children:"Loading..."});let U=null==f?void 0:null===(e=f.jobs)||void 0===e?void 0:e.find(e=>String(e.id)===String(s)),G=s?"Job: ".concat(s," | SkyPilot Dashboard"):"Job Details | SkyPilot Dashboard";return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(N(),{children:(0,r.jsx)("title",{children:G})}),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[(0,r.jsxs)("div",{className:"text-base flex items-center",children:[(0,r.jsx)(d(),{href:"/jobs",className:"text-sky-blue hover:underline",children:"Managed Jobs"}),(0,r.jsx)("span",{className:"mx-2 text-gray-500",children:"›"}),(0,r.jsxs)(d(),{href:"/jobs/".concat(s),className:"text-sky-blue hover:underline",children:[s," ",(null==U?void 0:U.name)?"(".concat(U.name,")"):""]})]}),(0,r.jsxs)("div",{className:"text-sm flex items-center",children:[(g||p||E||C)&&(0,r.jsxs)("div",{className:"flex items-center mr-4",children:[(0,r.jsx)(a.Z,{size:15,className:"mt-0"}),(0,r.jsx)("span",{className:"ml-2 text-gray-500",children:"Loading..."})]}),(0,r.jsx)(h.WH,{content:"Refresh",className:"text-muted-foreground",children:(0,r.jsxs)("button",{onClick:M,disabled:g||p,className:"text-sky-blue hover:text-sky-blue-bright font-medium inline-flex items-center h-8",children:[(0,r.jsx)(u.Z,{className:"w-4 h-4 mr-1.5"}),!q&&(0,r.jsx)("span",{children:"Refresh"})]})})]})]}),g&&b?(0,r.jsxs)("div",{className:"flex items-center justify-center py-32",children:[(0,r.jsx)(a.Z,{size:20,className:"mr-2"}),(0,r.jsx)("span",{children:"Loading..."})]}):U?(0,r.jsxs)("div",{className:"space-y-8",children:[(0,r.jsx)("div",{id:"details-section",children:(0,r.jsxs)(c.Zb,{children:[(0,r.jsx)("div",{className:"flex items-center justify-between px-4 pt-4",children:(0,r.jsx)("h3",{className:"text-lg font-semibold",children:"Details"})}),(0,r.jsx)("div",{className:"p-4",children:(0,r.jsx)(v,{jobData:U,activeTab:"info",setIsLoadingLogs:L,setIsLoadingControllerLogs:S,isLoadingLogs:E,isLoadingControllerLogs:C,refreshFlag:0})})]})}),(0,r.jsx)("div",{id:"logs-section",className:"mt-6",children:(0,r.jsxs)(c.Zb,{children:[(0,r.jsxs)("div",{className:"flex items-center justify-between px-4 pt-4",children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)("h3",{className:"text-lg font-semibold",children:"Logs"}),(0,r.jsx)("span",{className:"ml-2 text-xs text-gray-500",children:"(Logs are not streaming; click refresh to fetch the latest logs.)"})]}),(0,r.jsx)(h.WH,{content:"Refresh logs",className:"text-muted-foreground",children:(0,r.jsx)("button",{onClick:()=>{Z(e=>e+1)},disabled:E,className:"text-sky-blue hover:text-sky-blue-bright flex items-center",children:(0,r.jsx)(u.Z,{className:"w-4 h-4 ".concat(E?"animate-spin":"")})})})]}),(0,r.jsx)("div",{className:"p-4",children:(0,r.jsx)(v,{jobData:U,activeTab:"logs",setIsLoadingLogs:L,setIsLoadingControllerLogs:S,isLoadingLogs:E,isLoadingControllerLogs:C,refreshFlag:_})})]})}),(0,r.jsx)("div",{id:"controller-logs-section",className:"mt-6",children:(0,r.jsxs)(c.Zb,{children:[(0,r.jsxs)("div",{className:"flex items-center justify-between px-4 pt-4",children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)("h3",{className:"text-lg font-semibold",children:"Controller Logs"}),(0,r.jsx)("span",{className:"ml-2 text-xs text-gray-500",children:"(Logs are not streaming; click refresh to fetch the latest logs.)"})]}),(0,r.jsx)(h.WH,{content:"Refresh controller logs",className:"text-muted-foreground",children:(0,r.jsx)("button",{onClick:()=>{O(e=>e+1)},disabled:C,className:"text-sky-blue hover:text-sky-blue-bright flex items-center",children:(0,r.jsx)(u.Z,{className:"w-4 h-4 ".concat(C?"animate-spin":"")})})})]}),(0,r.jsx)("div",{className:"p-4",children:(0,r.jsx)(v,{jobData:U,activeTab:"controllerlogs",setIsLoadingLogs:L,setIsLoadingControllerLogs:S,isLoadingLogs:E,isLoadingControllerLogs:C,refreshFlag:P})})]})})]}):(0,r.jsx)("div",{className:"flex items-center justify-center py-32",children:(0,r.jsx)("span",{children:"Job not found"})})]})]})}},9008:function(e,t,s){e.exports=s(7219)}},function(e){e.O(0,[616,760,799,804,664,798,470,969,888,774,179],function(){return e(e.s=479)}),_N_E=e.O()}]);
@@ -1 +1 @@
1
- self.__BUILD_MANIFEST=function(s,c,e,a,t,n,r,u,b,i,j,k,f){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/":["static/chunks/pages/index-6b0d9e5031b70c58.js"],"/_error":["static/chunks/pages/_error-1be831200e60c5c0.js"],"/clusters":["static/chunks/pages/clusters-82a651dbad53ec6e.js"],"/clusters/[cluster]":[s,c,e,a,t,r,b,n,i,u,j,k,f,"static/chunks/37-824c707421f6f003.js","static/chunks/pages/clusters/[cluster]-59950b2f83b66e48.js"],"/clusters/[cluster]/[job]":[s,c,e,a,t,n,"static/chunks/pages/clusters/[cluster]/[job]-89216c616dbaa9c5.js"],"/config":["static/chunks/pages/config-497a35a7ed49734a.js"],"/infra":["static/chunks/pages/infra-780860bcc1103945.js"],"/infra/[context]":["static/chunks/pages/infra/[context]-d2910be98e9227cb.js"],"/jobs":["static/chunks/pages/jobs-336ab80e270ce2ce.js"],"/jobs/[job]":[s,c,e,a,t,r,n,u,"static/chunks/pages/jobs/[job]-b3dbf38b51cb29be.js"],"/users":["static/chunks/pages/users-c69ffcab9d6e5269.js"],"/workspace/new":["static/chunks/pages/workspace/new-31aa8bdcb7592635.js"],"/workspaces":["static/chunks/pages/workspaces-82e6601baa5dd280.js"],"/workspaces/[name]":[s,c,e,a,t,r,b,n,i,u,j,k,f,"static/chunks/843-ab9c4f609239155f.js","static/chunks/pages/workspaces/[name]-c8c2191328532b7d.js"],sortedPages:["/","/_app","/_error","/clusters","/clusters/[cluster]","/clusters/[cluster]/[job]","/config","/infra","/infra/[context]","/jobs","/jobs/[job]","/users","/workspace/new","/workspaces","/workspaces/[name]"]}}("static/chunks/616-d6128fa9e7cae6e6.js","static/chunks/760-a89d354797ce7af5.js","static/chunks/799-3625946b2ec2eb30.js","static/chunks/804-4c9fc53aa74bc191.js","static/chunks/664-047bc03493fda379.js","static/chunks/470-4d1a5dbe58a8a2b9.js","static/chunks/798-c0525dc3f21e488d.js","static/chunks/969-20d54a9d998dc102.js","static/chunks/947-6620842ef80ae879.js","static/chunks/901-b424d293275e1fd7.js","static/chunks/856-c2c39c0912285e54.js","static/chunks/973-c807fc34f09c7df3.js","static/chunks/938-385d190b95815e11.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
1
+ self.__BUILD_MANIFEST=function(s,c,a,e,t,n,r,u,i,j,k,b,f){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/":["static/chunks/pages/index-6b0d9e5031b70c58.js"],"/_error":["static/chunks/pages/_error-1be831200e60c5c0.js"],"/clusters":["static/chunks/pages/clusters-82a651dbad53ec6e.js"],"/clusters/[cluster]":[s,c,a,e,t,r,i,n,j,u,k,b,f,"static/chunks/37-824c707421f6f003.js","static/chunks/pages/clusters/[cluster]-36bc0962129f72df.js"],"/clusters/[cluster]/[job]":[s,c,a,e,t,n,"static/chunks/pages/clusters/[cluster]/[job]-89216c616dbaa9c5.js"],"/config":["static/chunks/pages/config-497a35a7ed49734a.js"],"/infra":["static/chunks/pages/infra-780860bcc1103945.js"],"/infra/[context]":["static/chunks/pages/infra/[context]-d2910be98e9227cb.js"],"/jobs":["static/chunks/pages/jobs-336ab80e270ce2ce.js"],"/jobs/[job]":[s,c,a,e,t,r,n,u,"static/chunks/pages/jobs/[job]-cf490d1fa38f3740.js"],"/users":["static/chunks/pages/users-c69ffcab9d6e5269.js"],"/workspace/new":["static/chunks/pages/workspace/new-31aa8bdcb7592635.js"],"/workspaces":["static/chunks/pages/workspaces-82e6601baa5dd280.js"],"/workspaces/[name]":[s,c,a,e,t,r,i,n,j,u,k,b,f,"static/chunks/843-ab9c4f609239155f.js","static/chunks/pages/workspaces/[name]-c8c2191328532b7d.js"],sortedPages:["/","/_app","/_error","/clusters","/clusters/[cluster]","/clusters/[cluster]/[job]","/config","/infra","/infra/[context]","/jobs","/jobs/[job]","/users","/workspace/new","/workspaces","/workspaces/[name]"]}}("static/chunks/616-d6128fa9e7cae6e6.js","static/chunks/760-a89d354797ce7af5.js","static/chunks/799-3625946b2ec2eb30.js","static/chunks/804-4c9fc53aa74bc191.js","static/chunks/664-047bc03493fda379.js","static/chunks/470-4d1a5dbe58a8a2b9.js","static/chunks/798-c0525dc3f21e488d.js","static/chunks/969-20d54a9d998dc102.js","static/chunks/947-6620842ef80ae879.js","static/chunks/901-b424d293275e1fd7.js","static/chunks/856-c2c39c0912285e54.js","static/chunks/973-c807fc34f09c7df3.js","static/chunks/938-385d190b95815e11.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/8e97adcaacc15293.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/8e97adcaacc15293.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-1b69b196a4dbffef.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-32b2caae3445bf3b.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-d6128fa9e7cae6e6.js" defer=""></script><script src="/dashboard/_next/static/chunks/760-a89d354797ce7af5.js" defer=""></script><script src="/dashboard/_next/static/chunks/799-3625946b2ec2eb30.js" defer=""></script><script src="/dashboard/_next/static/chunks/804-4c9fc53aa74bc191.js" defer=""></script><script src="/dashboard/_next/static/chunks/664-047bc03493fda379.js" defer=""></script><script src="/dashboard/_next/static/chunks/470-4d1a5dbe58a8a2b9.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters/%5Bcluster%5D/%5Bjob%5D-89216c616dbaa9c5.js" defer=""></script><script src="/dashboard/_next/static/R07f8gwfXT1U0zRznq4Lg/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/R07f8gwfXT1U0zRznq4Lg/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters/[cluster]/[job]","query":{},"buildId":"R07f8gwfXT1U0zRznq4Lg","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/8e97adcaacc15293.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/8e97adcaacc15293.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-1b69b196a4dbffef.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-32b2caae3445bf3b.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-d6128fa9e7cae6e6.js" defer=""></script><script src="/dashboard/_next/static/chunks/760-a89d354797ce7af5.js" defer=""></script><script src="/dashboard/_next/static/chunks/799-3625946b2ec2eb30.js" defer=""></script><script src="/dashboard/_next/static/chunks/804-4c9fc53aa74bc191.js" defer=""></script><script src="/dashboard/_next/static/chunks/664-047bc03493fda379.js" defer=""></script><script src="/dashboard/_next/static/chunks/470-4d1a5dbe58a8a2b9.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters/%5Bcluster%5D/%5Bjob%5D-89216c616dbaa9c5.js" defer=""></script><script src="/dashboard/_next/static/vA3PPpkBwpRTRNBHFYAw_/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/vA3PPpkBwpRTRNBHFYAw_/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters/[cluster]/[job]","query":{},"buildId":"vA3PPpkBwpRTRNBHFYAw_","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>