Skip to content

Commit 18431a1

Browse files
Added N9300 switch memory check
1 parent 68f3673 commit 18431a1

11 files changed

Lines changed: 327 additions & 5 deletions

aci-preupgrade-validation-script.py

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -950,9 +950,7 @@ def start(self, timeout=5.0):
950950
timeout (float): How long we wait for the thread start event.
951951
5.0 sec by default.
952952
"""
953-
_active_limbo_lock = threading._active_limbo_lock
954-
_limbo = threading._limbo
955-
_start_new_thread = threading._start_new_thread
953+
_start_new_thread = getattr(threading, "_start_new_thread", None)
956954

957955
# Python2 uses name mangling
958956
if hasattr(self, "_Thread__initialized"):
@@ -968,6 +966,18 @@ def start(self, timeout=5.0):
968966
if self._started.is_set():
969967
raise RuntimeError("threads can only be started once")
970968

969+
# Python 3.14+ no longer exposes threading._start_new_thread.
970+
# In that case, defer to Thread.start() to keep internal join handles valid.
971+
if _start_new_thread is None:
972+
super(CustomThread, self).start()
973+
self._started.wait(timeout)
974+
if not self._started.is_set():
975+
raise RuntimeError("can't start new thread")
976+
return
977+
978+
_active_limbo_lock = threading._active_limbo_lock
979+
_limbo = threading._limbo
980+
971981
with _active_limbo_lock:
972982
_limbo[self] = self
973983
try:
@@ -1493,11 +1503,19 @@ def get_row(widths, values, spad=" ", lpad=""):
14931503

14941504
def prints(objects, sep=' ', end='\n'):
14951505
with open(RESULT_FILE, 'a') as f:
1496-
print(objects, sep=sep, end=end, file=sys.stdout)
1506+
stdout_ok = True
1507+
try:
1508+
print(objects, sep=sep, end=end, file=sys.stdout)
1509+
except (OSError, ValueError):
1510+
stdout_ok = False
14971511
if end == "\r":
14981512
end = "\n" # easier to read with \n in a log file
14991513
print(objects, sep=sep, end=end, file=f)
1500-
sys.stdout.flush()
1514+
if stdout_ok:
1515+
try:
1516+
sys.stdout.flush()
1517+
except (OSError, ValueError):
1518+
pass
15011519
f.flush()
15021520

15031521

@@ -5877,6 +5895,73 @@ def isis_database_byte_check(tversion, **kwargs):
58775895
return Result(result=result, headers=headers, data=data, recommended_action=recommended_action, doc_url=doc_url)
58785896

58795897

5898+
@check_wrapper(check_title='N9300 Switch Memory')
5899+
def n9300_switch_memory_check(tversion, fabric_nodes, **kwargs):
5900+
result = PASS
5901+
headers = ["NodeId", "Name", "Model", "Memory Detected (GB)"]
5902+
data = []
5903+
recommended_action = 'Increase the switch memory to at least 24GB before proceeding with the Cisco ACI software upgrade.'
5904+
doc_url = 'https://datacenter.github.io/ACI-Pre-Upgrade-Validation-Script/validations/#n9300-switch-memory'
5905+
min_memory_kb = 24 * 1024 * 1024
5906+
5907+
if not tversion:
5908+
return Result(result=MANUAL, msg=TVER_MISSING)
5909+
5910+
if tversion.major_version != '6.1':
5911+
return Result(result=NA, msg=VER_NOT_AFFECTED)
5912+
5913+
proc_mem_query = 'procMemUsage.json'
5914+
affected_nodes = [
5915+
node for node in fabric_nodes
5916+
if node.get('fabricNode', {}).get('attributes', {}).get('model', '').startswith('N9K-C93')
5917+
]
5918+
5919+
if not affected_nodes:
5920+
return Result(result=NA, msg='No N9300 switches found. Skipping.')
5921+
5922+
proc_mem_mos = icurl('class', proc_mem_query)
5923+
node_total_kb = {}
5924+
5925+
for memory_mo in proc_mem_mos:
5926+
attrs = memory_mo.get('procMemUsage', {}).get('attributes', {})
5927+
total = attrs.get('Total')
5928+
mem_dn = attrs.get('dn', '')
5929+
if not total or '/memusage-sup' not in mem_dn:
5930+
continue
5931+
dn_match = re.search(node_regex, mem_dn)
5932+
if not dn_match:
5933+
continue
5934+
try:
5935+
total_kb = int(total)
5936+
except ValueError:
5937+
continue
5938+
5939+
node_id = dn_match.group('node')
5940+
if node_id not in node_total_kb:
5941+
node_total_kb[node_id] = total_kb
5942+
5943+
for node in affected_nodes:
5944+
node_id = node['fabricNode']['attributes']['id']
5945+
total_kb = node_total_kb.get(node_id)
5946+
if total_kb is None:
5947+
continue
5948+
5949+
memory_in_gb = round(total_kb / 1048576, 2)
5950+
if total_kb < min_memory_kb:
5951+
result = FAIL_O
5952+
data.append([
5953+
node_id,
5954+
node['fabricNode']['attributes'].get('name', ''),
5955+
node['fabricNode']['attributes'].get('model', ''),
5956+
memory_in_gb,
5957+
])
5958+
5959+
if result == PASS:
5960+
return Result(result=result)
5961+
5962+
return Result(result=result, headers=headers, data=data, recommended_action=recommended_action, doc_url=doc_url)
5963+
5964+
58805965
# Subprocess check - cat + acidiag
58815966
@check_wrapper(check_title='APIC Database Size')
58825967
def apic_database_size_check(cversion, **kwargs):
@@ -6214,6 +6299,7 @@ class CheckManager:
62146299
pbr_high_scale_check,
62156300
standby_sup_sync_check,
62166301
isis_database_byte_check,
6302+
n9300_switch_memory_check,
62176303
configpush_shard_check,
62186304
auto_firmware_update_on_switch_check,
62196305

docs/docs/validations.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ Items | Defect | This Script
194194
[ISIS DTEPs Byte Size][d27] | CSCwp15375 | :white_check_mark: | :no_entry_sign:
195195
[Policydist configpushShardCont Crash][d28] | CSCwp95515 | :white_check_mark: | :no_entry_sign:
196196
[Auto Firmware Update on Switch Discovery][d29] | CSCwe83941 | :white_check_mark: | :no_entry_sign:
197+
[N9300 Switch Memory][d30] | - | :white_check_mark: | :no_entry_sign:
197198

198199
[d1]: #ep-announce-compatibility
199200
[d2]: #eventmgr-db-size-defect-susceptibility
@@ -224,6 +225,7 @@ Items | Defect | This Script
224225
[d27]: #isis-dteps-byte-size
225226
[d28]: #policydist-configpushshardcont-crash
226227
[d29]: #auto-firmware-update-on-switch-discovery
228+
[d30]: #n9300-switch-memory
227229

228230
## General Check Details
229231

@@ -2648,6 +2650,12 @@ Due to [CSCwp95515][59], upgrading to an affected version while having any `conf
26482650

26492651
If any instances of `configpushShardCont` are flagged by this script, Cisco TAC must be contacted to identify and resolve the underlying issue before performing the upgrade.
26502652

2653+
### N9300 Switch Memory
2654+
2655+
This check applies only when the target upgrade version is 6.1. It reviews `procMemUsage` for N9300-series switches and flags nodes with less than 24GB memory installed.
2656+
2657+
If any N9300-series switch is flagged by this check, increase the switch memory to at least 24GB before the upgrade.
2658+
26512659
### Auto Firmware Update on Switch Discovery
26522660

26532661
[Auto Firmware Update on Switch Discovery][63] automatically upgrades a new switch to the target firmware version before registering it to the ACI fabric. This feature activates in three scenarios:
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[
2+
{
3+
"fabricNode": {
4+
"attributes": {
5+
"dn": "topology/pod-1/node-201",
6+
"id": "201",
7+
"name": "leaf201",
8+
"model": "N9K-C9508",
9+
"role": "leaf"
10+
}
11+
}
12+
}
13+
]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[
2+
{
3+
"fabricNode": {
4+
"attributes": {
5+
"dn": "topology/pod-1/node-101",
6+
"id": "101",
7+
"name": "leaf101",
8+
"model": "N9K-C93180YC-FX3",
9+
"role": "leaf"
10+
}
11+
}
12+
}
13+
]
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[
2+
{
3+
"fabricNode": {
4+
"attributes": {
5+
"dn": "topology/pod-1/node-101",
6+
"id": "101",
7+
"name": "leaf101",
8+
"model": "N9K-C93180YC-FX3",
9+
"role": "leaf"
10+
}
11+
}
12+
},
13+
{
14+
"fabricNode": {
15+
"attributes": {
16+
"dn": "topology/pod-1/node-102",
17+
"id": "102",
18+
"name": "leaf102",
19+
"model": "N9K-C9364C",
20+
"role": "leaf"
21+
}
22+
}
23+
}
24+
]
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[
2+
{
3+
"procMemUsage": {
4+
"attributes": {
5+
"dn": "topology/pod-1/node-101/sys/procmem/memusage-sup",
6+
"Modname": "sup",
7+
"Total": "32535444"
8+
}
9+
}
10+
},
11+
{
12+
"procMemUsage": {
13+
"attributes": {
14+
"dn": "topology/pod-1/node-102/sys/procmem/memusage-sup",
15+
"Modname": "sup",
16+
"Total": "28535444"
17+
}
18+
}
19+
}
20+
]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[
2+
{
3+
"procMemUsage": {
4+
"attributes": {
5+
"dn": "topology/pod-1/node-101/sys/procmem/memusage-sup",
6+
"Modname": "sup",
7+
"Total": "26535444"
8+
}
9+
}
10+
}
11+
]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[
2+
{
3+
"procMemUsage": {
4+
"attributes": {
5+
"dn": "topology/pod-1/node-101/sys/procmem/memusage-sup",
6+
"Modname": "sup",
7+
"Total": "22535444"
8+
}
9+
}
10+
}
11+
]
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[
2+
{
3+
"procMemUsage": {
4+
"attributes": {
5+
"dn": "topology/pod-1/node-101/sys/procmem/memusage-sup",
6+
"Modname": "sup",
7+
"Total": "32535444"
8+
}
9+
}
10+
},
11+
{
12+
"procMemUsage": {
13+
"attributes": {
14+
"dn": "topology/pod-1/node-102/sys/procmem/memusage-sup",
15+
"Modname": "sup",
16+
"Total": "22535444"
17+
}
18+
}
19+
}
20+
]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[
2+
{
3+
"procMemUsage": {
4+
"attributes": {
5+
"dn": "topology/pod-1/node-201/sys/procmem/memusage-sup",
6+
"Modname": "sup",
7+
"Total": "28535444"
8+
}
9+
}
10+
}
11+
]

0 commit comments

Comments
 (0)