Skip to content

Commit 3eae412

Browse files
authored
[202311][Mellanox] CMIS host management script for (#19526)
Why I did it Added a script for CMIS Host Management enabling and disabling. Prevents bugs caused by wrong configuration of the feature More convenient for costumers to configure the feature This is PR is for 202311. Original PR (for Master and 202405): #19509 How I did it Add the script to /usr/bin/ that supports two options: --enable - receives paths to config files for Port SI parameters and Module SI parameters: media_settings.json, optics_si_settings.json, and enables the feature --disable - disables the feature
1 parent 2e341f1 commit 3eae412

File tree

2 files changed

+173
-0
lines changed

2 files changed

+173
-0
lines changed

files/build_templates/sonic_debian_extension.j2

+2
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,8 @@ sudo cp $files_path/$MLNX_FFB_SCRIPT $FILESYSTEM_ROOT/usr/bin/mlnx-ffb.sh
972972
sudo cp $files_path/$MLNX_ONIE_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/$MLNX_ONIE_FW_UPDATE
973973
sudo cp $files_path/$MLNX_SSD_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/$MLNX_SSD_FW_UPDATE
974974
sudo cp $files_path/$MLNX_INSTALL_PENDING_FW $FILESYSTEM_ROOT/usr/bin/$MLNX_INSTALL_PENDING_FW
975+
sudo cp platform/mellanox/cmis_host_mgmt/cmis_host_mgmt.py $FILESYSTEM_ROOT/usr/bin/cmis_host_mgmt.py
976+
sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/cmis_host_mgmt.py
975977
j2 platform/mellanox/mlnx-fw-upgrade.j2 | sudo tee $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh
976978
sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh
977979

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES.
4+
# Apache-2.0
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
19+
import shutil
20+
import click
21+
import re
22+
import os
23+
import subprocess
24+
25+
26+
class CMISHostMgmtActivator:
27+
PARAMS = {
28+
"sai_profile": {
29+
"file_name": "sai.profile",
30+
"enabled_param": "SAI_INDEPENDENT_MODULE_MODE=1",
31+
"disabled_param": "SAI_INDEPENDENT_MODULE_MODE=0"
32+
},
33+
"pmon_daemon_control": {
34+
"file_name": "pmon_daemon_control.json",
35+
"enabled_param": "\"skip_xcvrd_cmis_mgr\": false",
36+
"disabled_param": "\"skip_xcvrd_cmis_mgr\": true",
37+
},
38+
"sai_xml": {
39+
"file_name": "sai_<>.xml", # will be filled at main, since we can't know the SKU here
40+
"enabled_param": "<late-create-all-ports>1</late-create-all-ports>",
41+
"disabled_param": "<late-create-all-ports>1</late-create-all-ports>" # Shouldn't be called
42+
}
43+
}
44+
45+
@staticmethod
46+
def change_param(param, path, action):
47+
file_path = '{}/{}'.format(path, CMISHostMgmtActivator.PARAMS[param]["file_name"])
48+
lines = None
49+
50+
try:
51+
with open(file_path, 'r') as param_file:
52+
lines = param_file.read()
53+
54+
if lines:
55+
if action == "disable":
56+
lines = re.sub(CMISHostMgmtActivator.PARAMS[param]["enabled_param"],
57+
CMISHostMgmtActivator.PARAMS[param]["disabled_param"],
58+
lines)
59+
elif action == "enable":
60+
if param == "sai_profile" and not re.search(CMISHostMgmtActivator.PARAMS[param]["disabled_param"], lines):
61+
if not re.search(CMISHostMgmtActivator.PARAMS[param]["enabled_param"], lines):
62+
with open(file_path, 'a') as param_file:
63+
param_file.write(CMISHostMgmtActivator.PARAMS[param]["enabled_param"])
64+
return
65+
66+
lines = re.sub(CMISHostMgmtActivator.PARAMS[param]["disabled_param"],
67+
CMISHostMgmtActivator.PARAMS[param]["enabled_param"],
68+
lines)
69+
70+
with open(file_path, 'w') as param_file:
71+
param_file.write(lines)
72+
73+
except FileNotFoundError as e:
74+
print('Missing file: {}'.format(e.filename))
75+
76+
77+
@staticmethod
78+
def parse_show_platform_summary():
79+
summary = subprocess.check_output(['show', 'platform', 'summary'])
80+
summary = summary.decode('utf-8')
81+
summary = [x for x in summary.split('\n') if x]
82+
83+
for field in summary:
84+
key, value = field.split(": ")
85+
86+
if key == 'Platform':
87+
platform = value
88+
89+
elif key == 'HwSKU':
90+
sku = value
91+
92+
return platform, sku
93+
94+
95+
@staticmethod
96+
def remove_file(file_path):
97+
if os.path.isfile(file_path):
98+
os.remove(file_path)
99+
100+
101+
@staticmethod
102+
def copy_file(src_path, dest_path):
103+
if os.path.isfile(src_path):
104+
shutil.copy(src_path, dest_path)
105+
106+
107+
@staticmethod
108+
def is_spc_supported(spc):
109+
return int(spc) >= 4000
110+
111+
@staticmethod
112+
def disable():
113+
platform, sku = CMISHostMgmtActivator.parse_show_platform_summary()
114+
sku_path = '/usr/share/sonic/device/{0}/{1}'.format(platform, sku)
115+
platform_path = '/usr/share/sonic/device/{0}'.format(platform)
116+
CMISHostMgmtActivator.change_param("sai_profile", sku_path, 'disable')
117+
118+
if os.path.isfile('{0}/{1}'.format(platform_path, 'pmon_daemon_control.json')):
119+
CMISHostMgmtActivator.change_param("pmon_daemon_control", platform_path, 'disable')
120+
CMISHostMgmtActivator.remove_file('{0}/{1}'.format(sku_path, 'pmon_daemon_control.json'))
121+
else:
122+
CMISHostMgmtActivator.change_param("pmon_daemon_control", sku_path, 'disable')
123+
124+
CMISHostMgmtActivator.remove_file('{0}/{1}'.format(sku_path, 'media_settings.json'))
125+
CMISHostMgmtActivator.remove_file('{0}/{1}'.format(sku_path,'optics_si_settings.json'))
126+
CMISHostMgmtActivator.remove_file('{0}/{1}'.format(platform_path, 'media_settings.json'))
127+
CMISHostMgmtActivator.remove_file('{0}/{1}'.format(platform_path, 'optics_si_settings.json'))
128+
129+
130+
@staticmethod
131+
def enable(args):
132+
platform, sku = CMISHostMgmtActivator.parse_show_platform_summary()
133+
sku_path = '/usr/share/sonic/device/{0}/{1}'.format(platform, sku)
134+
platform_path = '/usr/share/sonic/device/{0}'.format(platform)
135+
136+
sku_num = re.search('[0-9]{4}', sku).group()
137+
138+
if not CMISHostMgmtActivator.is_spc_supported(sku_num):
139+
print("Error: unsupported platform - feature is supported on SPC3 and higher.")
140+
141+
CMISHostMgmtActivator.PARAMS["sai_xml"]["file_name"] = "sai_{0}.xml".format(sku_num)
142+
143+
CMISHostMgmtActivator.copy_file(args[0], sku_path)
144+
CMISHostMgmtActivator.copy_file(args[1], sku_path)
145+
CMISHostMgmtActivator.copy_file('{0}/{1}'.format(platform_path, 'pmon_daemon_control.json'), sku_path)
146+
147+
CMISHostMgmtActivator.change_param("sai_profile", sku_path, 'enable')
148+
CMISHostMgmtActivator.change_param("pmon_daemon_control", sku_path, 'enable')
149+
CMISHostMgmtActivator.change_param("sai_xml", sku_path, 'enable')
150+
151+
152+
@click.command()
153+
@click.option('--disable', is_flag=True, help='Disable CMIS Host Management')
154+
@click.option('--enable', nargs=2, type=click.Path(), help='Enable CMIS Host Management, receives two arguments: media_settings.json path, and optics_si_settings.json path')
155+
def main(disable, enable):
156+
157+
if disable and enable:
158+
print("Error: can't use both options, please choose one.")
159+
return
160+
161+
if disable:
162+
CMISHostMgmtActivator.disable()
163+
164+
elif enable:
165+
CMISHostMgmtActivator.enable(enable)
166+
167+
else:
168+
print("Error: no option was provided - nothing to execute.")
169+
170+
if __name__ == '__main__':
171+
main()

0 commit comments

Comments
 (0)