aws-parallelcluster-node 3.16.1__tar.gz → 3.16.2__tar.gz

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 (42) hide show
  1. {aws_parallelcluster_node-3.16.1/src/aws_parallelcluster_node.egg-info → aws_parallelcluster_node-3.16.2}/PKG-INFO +2 -2
  2. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/setup.py +2 -2
  3. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2/src/aws_parallelcluster_node.egg-info}/PKG-INFO +2 -2
  4. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/common/schedulers/slurm_commands.py +8 -1
  5. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/common/schedulers/slurm_reservation_commands.py +1 -1
  6. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/fleet_manager.py +61 -1
  7. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/slurm_resources.py +13 -4
  8. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/LICENSE.txt +0 -0
  9. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/NOTICE.txt +0 -0
  10. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/README.md +0 -0
  11. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/setup.cfg +0 -0
  12. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/aws/__init__.py +0 -0
  13. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/aws/common.py +0 -0
  14. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/aws/ec2.py +0 -0
  15. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/aws_parallelcluster_node.egg-info/SOURCES.txt +0 -0
  16. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/aws_parallelcluster_node.egg-info/dependency_links.txt +0 -0
  17. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/aws_parallelcluster_node.egg-info/entry_points.txt +0 -0
  18. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/aws_parallelcluster_node.egg-info/not-zip-safe +0 -0
  19. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/aws_parallelcluster_node.egg-info/requires.txt +0 -0
  20. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/aws_parallelcluster_node.egg-info/top_level.txt +0 -0
  21. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/common/__init__.py +0 -0
  22. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/common/ec2_utils.py +0 -0
  23. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/common/schedulers/__init__.py +0 -0
  24. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/common/time_utils.py +0 -0
  25. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/common/utils.py +0 -0
  26. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/__init__.py +0 -0
  27. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/capacity_block_manager.py +0 -0
  28. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/cluster_event_publisher.py +0 -0
  29. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/clustermgtd.py +0 -0
  30. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/common.py +0 -0
  31. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/computemgtd.py +0 -0
  32. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/console_logger.py +0 -0
  33. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/fleet_status_manager.py +0 -0
  34. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/instance_manager.py +0 -0
  35. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/logging/parallelcluster_clustermgtd_logging.conf +0 -0
  36. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/logging/parallelcluster_computemgtd_logging.conf +0 -0
  37. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/logging/parallelcluster_fleet_status_manager_logging.conf +0 -0
  38. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/logging/parallelcluster_resume_logging.conf +0 -0
  39. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/logging/parallelcluster_suspend_logging.conf +0 -0
  40. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/resume.py +0 -0
  41. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/suspend.py +0 -0
  42. {aws_parallelcluster_node-3.16.1 → aws_parallelcluster_node-3.16.2}/src/slurm_plugin/task_executor.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aws-parallelcluster-node
3
- Version: 3.16.1
3
+ Version: 3.16.2
4
4
  Summary: aws-parallelcluster-node provides the scripts for an AWS ParallelCluster node.
5
5
  Home-page: https://github.com/aws/aws-parallelcluster-node
6
6
  Author: Amazon Web Services
@@ -10,7 +10,7 @@ Classifier: Environment :: Console
10
10
  Classifier: Programming Language :: Python
11
11
  Classifier: Topic :: Scientific/Engineering
12
12
  Classifier: License :: OSI Approved :: Apache Software License
13
- Requires-Python: >=3.9
13
+ Requires-Python: >=3.14
14
14
  License-File: LICENSE.txt
15
15
  License-File: NOTICE.txt
16
16
  Requires-Dist: boto3>=1.7.55
@@ -32,7 +32,7 @@ console_scripts = [
32
32
  "clustermgtd = slurm_plugin.clustermgtd:main",
33
33
  "computemgtd = slurm_plugin.computemgtd:main",
34
34
  ]
35
- version = "3.16.1"
35
+ version = "3.16.2"
36
36
  requires = ["boto3>=1.7.55", "retrying>=1.3.3", "setuptools"]
37
37
 
38
38
  setup(
@@ -44,7 +44,7 @@ setup(
44
44
  license="Apache License 2.0",
45
45
  packages=find_packages("src", exclude=["tests"]),
46
46
  package_dir={"": "src"},
47
- python_requires=">=3.9",
47
+ python_requires=">=3.14",
48
48
  install_requires=requires,
49
49
  entry_points=dict(console_scripts=console_scripts),
50
50
  zip_safe=False,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aws-parallelcluster-node
3
- Version: 3.16.1
3
+ Version: 3.16.2
4
4
  Summary: aws-parallelcluster-node provides the scripts for an AWS ParallelCluster node.
5
5
  Home-page: https://github.com/aws/aws-parallelcluster-node
6
6
  Author: Amazon Web Services
@@ -10,7 +10,7 @@ Classifier: Environment :: Console
10
10
  Classifier: Programming Language :: Python
11
11
  Classifier: Topic :: Scientific/Engineering
12
12
  Classifier: License :: OSI Approved :: Apache Software License
13
- Requires-Python: >=3.9
13
+ Requires-Python: >=3.14
14
14
  License-File: LICENSE.txt
15
15
  License-File: NOTICE.txt
16
16
  Requires-Dist: boto3>=1.7.55
@@ -75,10 +75,15 @@ SCONTROL_NODE_INFO_FIELD_REGEX = re.compile(
75
75
  r"|(LastBusyTime=\S+)"
76
76
  r"|(ReservationName=\S+)"
77
77
  r"|(InstanceId=\S+)"
78
- r"|(Reason=.*)",
78
+ r"|(Reason=.*)"
79
+ r"|(Comment=.*)"
80
+ r"|(Extra=.*)",
79
81
  re.MULTILINE,
80
82
  )
81
83
 
84
+ # Fields matched up to the end of the line and discarded, to prevent their free-text content from being parsed as fields
85
+ SCONTROL_DISCARDED_FIELDS = ("Comment", "Extra")
86
+
82
87
  # Fields extracted from `scontrol show partitions` output. `(?<!Next)` ensures `State` is matched but
83
88
  # `NextState` is not.
84
89
  SCONTROL_PARTITION_INFO_FIELD_REGEX = re.compile(
@@ -426,6 +431,8 @@ def _extract_scontrol_records(raw_output: str, field_regex) -> List[Dict[str, st
426
431
  fields = {}
427
432
  for match in field_regex.finditer(record):
428
433
  key, _, value = match.group(0).partition("=")
434
+ if key in SCONTROL_DISCARDED_FIELDS:
435
+ continue
429
436
  fields[key] = value
430
437
  if fields:
431
438
  records.append(fields)
@@ -39,7 +39,7 @@ logger = logging.getLogger(__name__)
39
39
  # Fields extracted from raw `scontrol show reservations` output. Only `ReservationName` is anchored at the
40
40
  # start of a line; `(?<!Next)` ensures `State` is matched but `NextState` is not.
41
41
  SCONTROL_RESERVATION_INFO_FIELD_REGEX = re.compile(
42
- r"^(ReservationName=\S+)" r"|(?<!Next)(State=\S+)" r"|(Users=\S+)" r"|(Nodes=\S+)",
42
+ r"^(ReservationName=\S+)" r"|(?<!Next)(State=\S+)" r"|(Users=\S+)" r"|(Nodes=\S+)" r"|(Comment=.*)",
43
43
  re.MULTILINE,
44
44
  )
45
45
 
@@ -21,6 +21,7 @@ from common.ec2_utils import get_private_ip_address_and_dns_name
21
21
  from common.utils import setup_logging_filter
22
22
  from retrying import retry
23
23
  from slurm_plugin.common import print_with_count
24
+ from slurm_plugin.slurm_resources import SlurmNode
24
25
 
25
26
  logger = logging.getLogger(__name__)
26
27
 
@@ -30,6 +31,32 @@ logger = logging.getLogger(__name__)
30
31
  INSTANCE_INFO_RETRIEVAL_TIMEOUT_DEFAULT = 90
31
32
  INSTANCE_INFO_RETRIEVAL_MAX_BACKOFF = 30
32
33
 
34
+ # The only error code EC2 returns when a launch request is throttled, see
35
+ # https://docs.aws.amazon.com/ec2/latest/devguide/ec2-api-throttling.html
36
+ LAUNCH_THROTTLING_ERROR_CODE = "RequestLimitExceeded"
37
+
38
+ # An override that CreateFleet did not fulfill because another override failed is reported with this exact
39
+ # code and message pair, which points at the real error rather than being one.
40
+ UNFULFILLED_OVERRIDE_ERROR = (
41
+ "UnfulfillableCapacity",
42
+ "Failed to fulfill capacity. Please review errors in the response.",
43
+ )
44
+
45
+ # Errors confined to one instance type and subnet pool. Reported alongside throttling, they leave the throttled
46
+ # pools able to serve the batch once the rate limit refills, so the throttling is still retried. Any other error
47
+ # alongside throttling would fail the retry on every pool alike and is reported instead.
48
+ POOL_LEVEL_ERROR_CODES = frozenset(
49
+ SlurmNode.EC2_ICE_ERROR_CODES
50
+ | {
51
+ "InsufficientFreeAddressesInSubnet",
52
+ "InvalidSubnetID.NotFound",
53
+ "InvalidSubnet",
54
+ "InsufficientVolumeCapacity",
55
+ "VolumeTypeNotAvailableInZone",
56
+ "ServiceUnavailable",
57
+ }
58
+ )
59
+
33
60
 
34
61
  class EC2Instance:
35
62
  def __init__(self, id, private_ip, hostname, all_private_ips, launch_time):
@@ -430,7 +457,40 @@ class Ec2CreateFleetManager(FleetManager):
430
457
  if partial_instance_ids:
431
458
  logger.error("Unable to retrieve instance info for instances: %s", partial_instance_ids)
432
459
 
433
- if not instances and len(err_list) == 1:
460
+ if not instances:
461
+ # Drop the entries that only point at the real error, unless the response carries nothing else.
462
+ real_errors = [
463
+ err
464
+ for err in err_list
465
+ if (err.get("ErrorCode"), err.get("ErrorMessage")) != UNFULFILLED_OVERRIDE_ERROR
466
+ ]
467
+ if real_errors:
468
+ err_list = real_errors
469
+ # A single cause is normally left. Should there be several, throttling is retried only when every
470
+ # other cause is confined to a pool, since the throttled pools can then still serve the batch once the
471
+ # rate limit refills. Any other cause would fail the retry on every pool alike and is reported instead.
472
+ # For example:
473
+ # - [RequestLimitExceeded, InsufficientInstanceCapacity] -> retry, other pools can still serve the batch
474
+ # - [RequestLimitExceeded, VcpuLimitExceeded] -> report VcpuLimitExceeded, a retry hits the same limit
475
+ throttling = next(
476
+ (err for err in err_list if err.get("ErrorCode") == LAUNCH_THROTTLING_ERROR_CODE), None
477
+ )
478
+ if throttling:
479
+ blocking = next(
480
+ (
481
+ err
482
+ for err in err_list
483
+ if err.get("ErrorCode") != LAUNCH_THROTTLING_ERROR_CODE
484
+ and err.get("ErrorCode") not in POOL_LEVEL_ERROR_CODES
485
+ ),
486
+ None,
487
+ )
488
+ chosen = blocking or throttling
489
+ raise LaunchInstancesError(chosen.get("ErrorCode"), chosen.get("ErrorMessage"))
490
+ # Normally a single cause is left. Reporting the first one of several is a second safety net: the
491
+ # caller otherwise records a hardcoded InsufficientInstanceCapacity, and any code EC2 actually
492
+ # returned is more useful than an invented one, whichever of them the response happens to list first.
493
+ if not instances and err_list:
434
494
  raise LaunchInstancesError(err_list[0].get("ErrorCode"), err_list[0].get("ErrorMessage"))
435
495
  return {"Instances": instances}
436
496
  except ClientError as e:
@@ -126,8 +126,16 @@ class SlurmResumeJob(SlurmJob):
126
126
  reservation="",
127
127
  features="",
128
128
  extra="",
129
+ exclusive=None,
130
+ priority=None,
131
+ **unknown_fields,
129
132
  ):
130
- """Initialize Slurm job with attributes."""
133
+ """
134
+ Initialize Slurm job with attributes.
135
+
136
+ Slurm adds fields to the jobs of the Resume File over time (exclusive and priority in 26.05), so fields this
137
+ class does not know are ignored rather than rejected: rejecting them fails the resume of every node.
138
+ """
131
139
  super().__init__(
132
140
  job_id,
133
141
  )
@@ -139,9 +147,10 @@ class SlurmResumeJob(SlurmJob):
139
147
  self.reservation = reservation
140
148
  self.features = features
141
149
  self.extra = extra
142
-
143
- def is_exclusive(self):
144
- return self.oversubscribe == JobOversubscribe.NO
150
+ self.exclusive = exclusive
151
+ self.priority = priority
152
+ if unknown_fields:
153
+ logger.debug("Ignoring unknown fields of job %s in Slurm Resume File: %s", job_id, unknown_fields)
145
154
 
146
155
  def __eq__(self, other):
147
156
  """Compare 2 SlurmJob objects."""