Skip to content

Commit 9e69a52

Browse files
committed
R2026a release!
1 parent 02cc929 commit 9e69a52

22 files changed

Lines changed: 644 additions & 227 deletions

packer/v1/build-parallel-server-ami.pkr.hcl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ variable "STARTUP_SCRIPTS" {
8080
"60_Sync-MJS-Files.ps1",
8181
"65_Run-Optional-User-Command.ps1",
8282
"70_Start-MJS.ps1",
83-
"80_Add-SpotInstanceMonitoring.ps1"
83+
"80_Add-SpotInstanceMonitoring.ps1",
84+
"90_Setup-Autoscaling.ps1",
85+
"Setup-MJSHostname.ps1"
8486
]
8587
description = "The list of startup scripts Packer will copy to the remote machine image builder, which can be used during the CloudFormation Stack creation."
8688
}

packer/v1/release-config/R2023a.pkrvars.hcl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ STARTUP_SCRIPTS = [
1414
"60_Sync-MJS-Files.ps1",
1515
"65_Run-Optional-User-Command.ps1",
1616
"70_Start-MJS.ps1",
17-
"80_Add-SpotInstanceMonitoring.ps1"
17+
"80_Add-SpotInstanceMonitoring.ps1",
18+
"90_Setup-Autoscaling.ps1",
19+
"Setup-MJSHostname.ps1"
1820
]
1921
RUNTIME_SCRIPTS = [
2022
"autoscaling",

packer/v1/release-config/R2023b.pkrvars.hcl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ STARTUP_SCRIPTS = [
1414
"60_Sync-MJS-Files.ps1",
1515
"65_Run-Optional-User-Command.ps1",
1616
"70_Start-MJS.ps1",
17-
"80_Add-SpotInstanceMonitoring.ps1"
17+
"80_Add-SpotInstanceMonitoring.ps1",
18+
"90_Setup-Autoscaling.ps1",
19+
"Setup-MJSHostname.ps1"
1820
]
1921
RUNTIME_SCRIPTS = [
2022
"autoscaling",

packer/v1/release-config/R2024a.pkrvars.hcl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ STARTUP_SCRIPTS = [
1414
"60_Sync-MJS-Files.ps1",
1515
"65_Run-Optional-User-Command.ps1",
1616
"70_Start-MJS.ps1",
17-
"80_Add-SpotInstanceMonitoring.ps1"
17+
"80_Add-SpotInstanceMonitoring.ps1",
18+
"90_Setup-Autoscaling.ps1",
19+
"Setup-MJSHostname.ps1"
1820
]
1921
RUNTIME_SCRIPTS = [
2022
"autoscaling",

packer/v1/release-config/R2024b.pkrvars.hcl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ STARTUP_SCRIPTS = [
1414
"60_Sync-MJS-Files.ps1",
1515
"65_Run-Optional-User-Command.ps1",
1616
"70_Start-MJS.ps1",
17-
"80_Add-SpotInstanceMonitoring.ps1"
17+
"80_Add-SpotInstanceMonitoring.ps1",
18+
"90_Setup-Autoscaling.ps1",
19+
"Setup-MJSHostname.ps1"
1820
]
1921
RUNTIME_SCRIPTS = [
2022
"autoscaling",

packer/v1/release-config/R2025a.pkrvars.hcl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ STARTUP_SCRIPTS = [
1414
"60_Sync-MJS-Files.ps1",
1515
"65_Run-Optional-User-Command.ps1",
1616
"70_Start-MJS.ps1",
17-
"80_Add-SpotInstanceMonitoring.ps1"
17+
"80_Add-SpotInstanceMonitoring.ps1",
18+
"90_Setup-Autoscaling.ps1",
19+
"Setup-MJSHostname.ps1"
1820
]
1921
RUNTIME_SCRIPTS = [
2022
"autoscaling",

packer/v1/release-config/R2025b.pkrvars.hcl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ STARTUP_SCRIPTS = [
1414
"60_Sync-MJS-Files.ps1",
1515
"65_Run-Optional-User-Command.ps1",
1616
"70_Start-MJS.ps1",
17-
"80_Add-SpotInstanceMonitoring.ps1"
17+
"80_Add-SpotInstanceMonitoring.ps1",
18+
"90_Setup-Autoscaling.ps1",
19+
"Setup-MJSHostname.ps1"
1820
]
1921
RUNTIME_SCRIPTS = [
2022
"autoscaling",

packer/v1/release-config/R2026a.pkrvars.hcl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ STARTUP_SCRIPTS = [
1414
"60_Sync-MJS-Files.ps1",
1515
"65_Run-Optional-User-Command.ps1",
1616
"70_Start-MJS.ps1",
17-
"80_Add-SpotInstanceMonitoring.ps1"
17+
"80_Add-SpotInstanceMonitoring.ps1",
18+
"90_Setup-Autoscaling.ps1",
19+
"Setup-MJSHostname.ps1"
1820
]
1921
RUNTIME_SCRIPTS = [
2022
"autoscaling",
Lines changed: 60 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python3
22

3-
# Copyright 2022 The MathWorks, Inc.
3+
# Copyright 2022-2026 The MathWorks, Inc.
44

55
from mwplatforminterfaces import CloudInterface
66
from mwplatforminterfaces import OSInterface
@@ -9,19 +9,40 @@
99
import health_check
1010
import scale_in_protection
1111

12+
import argparse
1213
from datetime import datetime
1314
import logging
1415
from logging.handlers import RotatingFileHandler
1516
import sys
1617

1718

19+
logger = logging.getLogger('mw.autoscaling')
20+
1821
STATUS_SUCCESS = 0
1922
STATUS_CLOUD_ISSUE = 1
2023
STATUS_CLUSTER_ISSUE = 2
2124
STATUS_CLOUD_AND_CLUSTER_ISSUE = 3
2225

2326

24-
def main() -> int:
27+
def parse_args(args=None):
28+
"""Parse command-line arguments."""
29+
parser = argparse.ArgumentParser(description='Execute autoscaling routine.')
30+
parser.add_argument(
31+
'--use-private-ip-mapping',
32+
type=lambda x: x.lower() == 'true',
33+
default=False,
34+
help='Use private IP addresses for hostname mapping (True/False).'
35+
)
36+
parser.add_argument(
37+
'--dns-search-suffix',
38+
type=str,
39+
default='',
40+
help='DNS search suffix to append to worker hostnames.'
41+
)
42+
return parser.parse_args(args)
43+
44+
45+
def main(use_private_ip_mapping: bool = False, dns_search_suffix: str = '') -> int:
2546
"""Execute autoscaling routine.
2647
2748
The routine has three stages:
@@ -32,47 +53,63 @@ def main() -> int:
3253
3. Scale-in protection: Ensures that we do not terminate nodes with
3354
ongoing work.
3455
56+
Args:
57+
use_private_ip_mapping (bool): Use private IP addresses for node mapping.
58+
dns_search_suffix (str): DNS search suffix to append to hostnames.
59+
3560
Returns:
3661
status (int): Status code of program.
3762
0: Successful
3863
1: Faced an issue with cloud provider
3964
2: Faced an issue with cluster
4065
3: Faced an issue with both
4166
"""
42-
# Retrieving capacity information
43-
print('Connecting to the cloud computing platform')
44-
cloud_interface = CloudInterface()
67+
logger.info('Connecting to the cloud computing platform')
68+
cloud_interface = CloudInterface(
69+
dns_search_suffix=dns_search_suffix,
70+
use_private_ip_mapping=use_private_ip_mapping,
71+
)
4572

46-
print('Connecting to cluster')
73+
logger.info('Connecting to cluster')
4774
os_interface = OSInterface()
4875

49-
print('# Starting capacity control')
76+
logger.info('Starting capacity control')
5077
status_cc = capacity_control.main(cloud_interface, os_interface)
51-
print(f'# Finished capacity control: {status_cc}')
78+
logger.info('Finished capacity control: %s', status_cc)
5279

53-
print('# Starting health check')
80+
logger.info('Starting health check')
5481
status_hc = health_check.main(cloud_interface, os_interface)
55-
print(f'# Finished health check: {status_hc}')
82+
logger.info('Finished health check: %s', status_hc)
5683

57-
print('# Starting scale-in protection')
84+
logger.info('Starting scale-in protection')
5885
status_sp = scale_in_protection.main(cloud_interface, os_interface)
59-
print(f'# Finished scale-in protection: {status_sp}')
86+
logger.info('Finished scale-in protection: %s', status_sp)
6087

6188
return max(status_cc, status_hc, status_sp)
6289

6390

6491
if __name__ == '__main__':
65-
# Create logger
66-
logger = logging.getLogger('mw.autoscaling')
92+
args = parse_args()
93+
6794
log_file = 'C:\\ProgramData\\MathWorks\\autoscaling.log'
68-
log_handler = RotatingFileHandler(log_file, maxBytes=1e6, backupCount=5)
69-
log_handler.terminator = ''
70-
logger.addHandler(log_handler)
71-
logger.setLevel(logging.INFO)
72-
sys.stdout.write, sys.stderr.write = logger.info, logger.warning
73-
74-
print(f'## Starting autoscaling: {datetime.now():%Y-%m-%d %H:%M:%S}')
75-
status = main()
76-
print(f'## Finished autoscaling: {datetime.now():%Y-%m-%d %H:%M:%S}\n')
95+
log_handler = RotatingFileHandler(
96+
log_file, maxBytes=1_000_000, backupCount=5
97+
)
98+
log_formatter = logging.Formatter(
99+
'%(asctime)s [%(levelname)s] %(name)s: %(message)s',
100+
datefmt='%Y-%m-%d %H:%M:%S'
101+
)
102+
log_handler.setFormatter(log_formatter)
103+
104+
root_logger = logging.getLogger('mw')
105+
root_logger.addHandler(log_handler)
106+
root_logger.setLevel(logging.DEBUG)
107+
108+
logger.info('Starting autoscaling: %s', datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
109+
status = main(
110+
use_private_ip_mapping=args.use_private_ip_mapping,
111+
dns_search_suffix=args.dns_search_suffix
112+
)
113+
logger.info('Finished autoscaling: %s', datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
77114

78115
sys.exit(status)

packer/v1/runtime/autoscaling/capacity_control.py

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
#!/usr/bin/env python3
22

3-
# Copyright 2021-2022 The MathWorks, Inc.
3+
# Copyright 2021-2026 The MathWorks, Inc.
44

55
from mwplatforminterfaces import CloudInterface
66
from mwplatforminterfaces import OSInterface
77

8+
import logging
89
from math import ceil
910

1011

12+
logger = logging.getLogger('mw.autoscaling.capacity_control')
13+
1114
STATUS_SUCCESS = 0
1215
STATUS_CLOUD_ISSUE = 1
1316
STATUS_CLUSTER_ISSUE = 2
@@ -36,62 +39,59 @@ def main(cloud_interface: CloudInterface, os_interface: OSInterface) -> int:
3639
2: Faced an issue with cluster
3740
3: Faced an issue with both
3841
"""
39-
# Retrieving capacity information
4042
cloud_capacity = cloud_interface.get_cloud_capacity()
4143
if cloud_capacity is None:
42-
print('There was an issue retrieving cloud capacities, exiting.')
44+
logger.error('There was an issue retrieving cloud capacities, exiting.')
4345
return STATUS_CLOUD_ISSUE
4446

45-
print(f'Current cloud capacities: {cloud_capacity}')
47+
logger.info('Current cloud capacities: %s', cloud_capacity)
4648

4749
cluster_capacity = os_interface.get_cluster_capacity()
4850
if cluster_capacity is None:
49-
print('There was an issue retrieving cluster capacities, exiting.')
51+
logger.error('There was an issue retrieving cluster capacities, exiting.')
5052
return STATUS_CLUSTER_ISSUE
5153

52-
print(f'Current cluster capacities: {cluster_capacity}')
53-
54-
# Setting capacity information
54+
logger.info('Current cluster capacities: %s', cluster_capacity)
5555

56-
# Updating the jobmanager's maximum possible number of workers
5756
maximum_workers_requested = get_worker_count_from_nodes(
5857
cloud_capacity.maximum_nodes,
5958
cloud_capacity.workers_per_node
6059
)
61-
print(f'Maximum: {cloud_capacity.maximum_nodes} nodes ->'
62-
f' {maximum_workers_requested} workers')
60+
logger.info('Maximum: %d nodes -> %d workers',
61+
cloud_capacity.maximum_nodes, maximum_workers_requested)
6362
cluster_issue = False
6463
if maximum_workers_requested != cluster_capacity.maximum_workers:
6564
cluster_capacity_was_set = os_interface.set_cluster_capacity(
6665
maximum_workers_requested
6766
)
6867
if cluster_capacity_was_set:
69-
print('> Updated the cluster\'s maximum capacity')
68+
logger.info('Updated the cluster\'s maximum capacity')
7069
else:
71-
print('~ Failed to update the cluster\'s maximum capacity')
70+
logger.warning('Failed to update the cluster\'s maximum capacity')
7271
cluster_issue = True
7372

74-
# Updating the cloud computing platform's desired number of nodes
7573
desired_nodes_requested = get_node_count_from_workers(
7674
cluster_capacity.desired_workers,
7775
cloud_capacity.workers_per_node,
7876
cloud_capacity.minimum_nodes,
7977
cloud_capacity.maximum_nodes
8078
)
81-
print(f'Desired: {cluster_capacity.desired_workers} workers ->'
82-
f' {desired_nodes_requested} nodes')
79+
logger.info('Desired: %d workers -> %d nodes',
80+
cluster_capacity.desired_workers, desired_nodes_requested)
8381
cloud_issue = False
84-
if any(desired_nodes_requested != n
85-
for n in (cloud_capacity.desired_nodes,
86-
cloud_capacity.current_nodes)):
82+
83+
if desired_nodes_requested != cloud_capacity.desired_nodes:
8784
cloud_capacity_was_set = cloud_interface.set_cloud_capacity(
8885
desired_nodes_requested
8986
)
9087
if cloud_capacity_was_set:
91-
print('> Updated the cloud platform\'s desired capacity')
88+
logger.info('Updated the cloud platform\'s desired capacity')
9289
else:
93-
print('~ Failed to update the cloud platform\'s desired capacity')
90+
logger.warning('Failed to update the cloud platform\'s desired capacity')
9491
cloud_issue = True
92+
else:
93+
logger.info("Requested capacity: %d nodes matches the cloud platform's "
94+
"current desired capacity", desired_nodes_requested)
9595

9696
if cloud_issue and cluster_issue:
9797
return STATUS_CLOUD_AND_CLUSTER_ISSUE

0 commit comments

Comments
 (0)