Skip to content

Commit 6a17ab9

Browse files
skr31liushilongbuaa
authored andcommitted
[Mellanox] CMIS host management script (sonic-net#19509)
- Why I did it Added a script for CMIS Host Management enabling and disabling on a running switch. This intend to prevent issues caused by wrong configuration of the feature. The idea is to provide a more convenient way for users to configure the feature. - 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 92167c8 commit 6a17ab9

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
@@ -1060,6 +1060,8 @@ for MLNX_CPLD_ARCHIVE in $MLNX_CPLD_ARCHIVES; do
10601060
done
10611061
sudo cp platform/mellanox/get_component_versions/get_component_versions.py $FILESYSTEM_ROOT/usr/bin/get_component_versions.py
10621062
sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/get_component_versions.py
1063+
sudo cp platform/mellanox/cmis_host_mgmt/cmis_host_mgmt.py $FILESYSTEM_ROOT/usr/bin/cmis_host_mgmt.py
1064+
sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/cmis_host_mgmt.py
10631065
j2 platform/mellanox/mlnx-fw-upgrade.j2 | sudo tee $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh
10641066
sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh
10651067

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)