Skip to content

Commit c6f9664

Browse files
authored
[202012] Minigraph parser changes to select mmu profiles based on SonicQosProfile attribute (#11383)
Signed-off-by: Neetha John <nejo@microsoft.com> Why I did it There is a need to select different mmu profiles based on deployment type How I did it There will be separate subfolders (RDMA-CENTRIC, TCP-CENTRIC, BALANCED) in each hwsku folder which contains deployment specific mmu and qos settings. SonicQosProfile attribute in the minigraph will be used to determine which settings to use. If that attribute is not present, the default settings that exist in the hwsku folder will be used
1 parent 550ab26 commit c6f9664

File tree

3 files changed

+57
-100
lines changed

3 files changed

+57
-100
lines changed

src/sonic-config-engine/minigraph.py

+32-2
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,7 @@ def parse_meta(meta, hname):
853853
kube_data = {}
854854
redundancy_type = None
855855
downstream_redundancy_types = None
856+
qos_profile = None
856857

857858
device_metas = meta.find(str(QName(ns, "Devices")))
858859
for device in device_metas.findall(str(QName(ns1, "DeviceMetadata"))):
@@ -892,7 +893,9 @@ def parse_meta(meta, hname):
892893
downstream_redundancy_types = value
893894
elif name == "RedundancyType":
894895
redundancy_type = value
895-
return syslog_servers, dhcp_servers, dhcpv6_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, downstream_subrole, kube_data, downstream_redundancy_types, redundancy_type
896+
elif name == "SonicQosProfile":
897+
qos_profile = value
898+
return syslog_servers, dhcp_servers, dhcpv6_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, downstream_subrole, kube_data, downstream_redundancy_types, redundancy_type, qos_profile
896899

897900
def parse_linkmeta(meta, hname):
898901
link = meta.find(str(QName(ns, "Link")))
@@ -1144,6 +1147,31 @@ def enable_internal_bgp_session(bgp_sessions, filename, asic_name):
11441147
(local_sub_role == BACKEND_ASIC_SUB_ROLE and peer_sub_role == FRONTEND_ASIC_SUB_ROLE)):
11451148
bgp_sessions[peer_ip].update({'admin_status': 'up'})
11461149

1150+
def select_mmu_profiles(profile, platform, hwsku):
1151+
"""
1152+
Select MMU files based on the device metadata attribute - SonicQosProfile
1153+
if no QosProfile exists in the minigraph, then no action is needed.
1154+
if a profile exists in the minigraph,
1155+
- create a dir path to search 1 level down from the base path.
1156+
- if no such dir path exists, no action is needed.
1157+
- if a dir path exists, check for the presence of each file from
1158+
the copy list in the dir path and copy it over to the base path.
1159+
"""
1160+
if not profile:
1161+
return
1162+
1163+
files_to_copy = ['pg_profile_lookup.ini', 'qos.json.j2', 'buffers_defaults_t0.j2', 'buffers_defaults_t1.j2']
1164+
1165+
path = os.path.join('/usr/share/sonic/device', platform, hwsku)
1166+
1167+
dir_path = os.path.join(path, profile)
1168+
if os.path.exists(dir_path):
1169+
for file_item in files_to_copy:
1170+
file_in_dir = os.path.join(dir_path, file_item)
1171+
if os.path.isfile(file_in_dir):
1172+
base_file = os.path.join(path, file_item)
1173+
exec_cmd("sudo cp {} {}".format(file_in_dir, base_file))
1174+
11471175
###############################################################################
11481176
#
11491177
# Main functions
@@ -1212,6 +1240,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
12121240
system_defaults = {}
12131241
downstream_redundancy_types = None
12141242
redundancy_type = None
1243+
qos_profile = None
12151244

12161245
hwsku_qn = QName(ns, "HwSku")
12171246
hostname_qn = QName(ns, "Hostname")
@@ -1242,7 +1271,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
12421271
elif child.tag == str(QName(ns, "UngDec")):
12431272
(u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname, None)
12441273
elif child.tag == str(QName(ns, "MetadataDeclaration")):
1245-
(syslog_servers, dhcp_servers, dhcpv6_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, downstream_subrole, kube_data, downstream_redundancy_types, redundancy_type) = parse_meta(child, hostname)
1274+
(syslog_servers, dhcp_servers, dhcpv6_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, downstream_subrole, kube_data, downstream_redundancy_types, redundancy_type, qos_profile) = parse_meta(child, hostname)
12461275
elif child.tag == str(QName(ns, "LinkMetadataDeclaration")):
12471276
linkmetas = parse_linkmeta(child, hostname)
12481277
elif child.tag == str(QName(ns, "DeviceInfos")):
@@ -1262,6 +1291,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
12621291
elif child.tag == str(QName(ns, "DeviceInfos")):
12631292
(port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku)
12641293

1294+
select_mmu_profiles(qos_profile, platform, hwsku)
12651295
# set the host device type in asic metadata also
12661296
device_type = [devices[key]['type'] for key in devices if key.lower() == hostname.lower()][0]
12671297
if asic_name is None:

src/sonic-config-engine/tests/sample-dell-6100-t0-minigraph.xml

+5
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,11 @@
731731
<a:Reference i:nil="true"/>
732732
<a:Value>True</a:Value>
733733
</a:DeviceProperty>
734+
<a:DeviceProperty>
735+
<a:Name>SonicQosProfile</a:Name>
736+
<a:Reference i:nil="true"/>
737+
<a:Value>RDMA-CENTRIC</a:Value>
738+
</a:DeviceProperty>
734739
</a:Properties>
735740
<a:Key>ARISTA01T1:Ethernet1;s6100-dev-1:fortyGigE1/1/1</a:Key>
736741
</a:LinkMetadata>

src/sonic-config-engine/tests/test_j2files.py

+20-98
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,9 @@ def setUp(self):
2121
self.t0_7050cx3_port_config = os.path.join(self.test_dir, 't0_7050cx3_d48c8_port_config.ini')
2222
self.t1_mlnx_minigraph = os.path.join(self.test_dir, 't1-sample-graph-mlnx.xml')
2323
self.mlnx_port_config = os.path.join(self.test_dir, 'sample-port-config-mlnx.ini')
24-
self.dell6100_t0_minigraph = os.path.join(self.test_dir, 'sample-dell-6100-t0-minigraph.xml')
25-
self.mellanox2700_t0_minigraph = os.path.join(self.test_dir, 'sample-mellanox-2700-t0-minigraph.xml')
26-
self.mellanox2410_t1_minigraph = os.path.join(self.test_dir, 'sample-mellanox-2410-t1-minigraph.xml')
27-
self.arista7050_t0_minigraph = os.path.join(self.test_dir, 'sample-arista-7050-t0-minigraph.xml')
2824
self.multi_asic_minigraph = os.path.join(self.test_dir, 'multi_npu_data', 'sample-minigraph.xml')
2925
self.multi_asic_port_config = os.path.join(self.test_dir, 'multi_npu_data', 'sample_port_config-0.ini')
3026
self.radv_test_minigraph = os.path.join(self.test_dir, 'radv-test-sample-graph.xml')
31-
self.dell9332_t1_minigraph = os.path.join(self.test_dir, 'sample-dell-9332-t1-minigraph.xml')
3227
self.output_file = os.path.join(self.test_dir, 'output')
3328
os.environ["CFGGEN_UNIT_TESTING"] = "2"
3429

@@ -235,120 +230,47 @@ def test_l2switch_template_dualtor(self):
235230
self.assertEqual(sample_output_json, output_json)
236231

237232
def test_qos_arista7050_render_template(self):
238-
arista_dir_path = os.path.join(self.test_dir, '..', '..', '..', 'device', 'arista', 'x86_64-arista_7050_qx32s', 'Arista-7050-QX-32S')
239-
qos_file = os.path.join(arista_dir_path, 'qos.json.j2')
240-
port_config_ini_file = os.path.join(arista_dir_path, 'port_config.ini')
241-
242-
# copy qos_config.j2 to the Arista 7050 directory to have all templates in one directory
243-
qos_config_file = os.path.join(self.test_dir, '..', '..', '..', 'files', 'build_templates', 'qos_config.j2')
244-
shutil.copy2(qos_config_file, arista_dir_path)
245-
246-
argument = '-m ' + self.arista7050_t0_minigraph + ' -p ' + port_config_ini_file + ' -t ' + qos_file + ' > ' + self.output_file
247-
self.run_script(argument)
248-
249-
# cleanup
250-
qos_config_file_new = os.path.join(arista_dir_path, 'qos_config.j2')
251-
os.remove(qos_config_file_new)
252-
253-
sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'qos-arista7050.json')
254-
assert utils.cmp(sample_output_file, self.output_file)
233+
self._test_qos_render_template('arista', 'x86_64-arista_7050_qx32s', 'Arista-7050-QX-32S', 'sample-arista-7050-t0-minigraph.xml', 'qos-arista7050.json')
255234

256235
def test_qos_dell9332_render_template(self):
257-
dell_dir_path = os.path.join(self.test_dir, '..', '..', '..', 'device', 'dell', 'x86_64-dellemc_z9332f_d1508-r0', 'DellEMC-Z9332f-O32')
258-
qos_file = os.path.join(dell_dir_path, 'qos.json.j2')
259-
port_config_ini_file = os.path.join(dell_dir_path, 'port_config.ini')
260-
261-
# copy qos_config.j2 to the Dell Z9332 directory to have all templates in one directory
262-
qos_config_file = os.path.join(self.test_dir, '..', '..', '..', 'files', 'build_templates', 'qos_config.j2')
263-
shutil.copy2(qos_config_file, dell_dir_path)
264-
265-
argument = '-m ' + self.dell9332_t1_minigraph + ' -p ' + port_config_ini_file + ' -t ' + qos_file + ' > ' + self.output_file
266-
self.run_script(argument)
267-
268-
# cleanup
269-
qos_config_file_new = os.path.join(dell_dir_path, 'qos_config.j2')
270-
os.remove(qos_config_file_new)
271-
272-
sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'qos-dell9332.json')
273-
assert utils.cmp(sample_output_file, self.output_file)
236+
self._test_qos_render_template('dell', 'x86_64-dellemc_z9332f_d1508-r0', 'DellEMC-Z9332f-O32', 'sample-dell-9332-t1-minigraph.xml', 'qos-dell9332.json')
274237

275238
def test_qos_dell6100_render_template(self):
276-
dell_dir_path = os.path.join(self.test_dir, '..', '..', '..', 'device', 'dell', 'x86_64-dell_s6100_c2538-r0', 'Force10-S6100')
277-
qos_file = os.path.join(dell_dir_path, 'qos.json.j2')
278-
port_config_ini_file = os.path.join(dell_dir_path, 'port_config.ini')
239+
self._test_qos_render_template('dell', 'x86_64-dell_s6100_c2538-r0', 'Force10-S6100', 'sample-dell-6100-t0-minigraph.xml', 'qos-dell6100.json')
279240

280-
# copy qos_config.j2 to the Dell S6100 directory to have all templates in one directory
241+
def _test_qos_render_template(self, vendor, platform, sku, minigraph, expected):
242+
file_exist, dir_exist = self.create_machine_conf(platform, vendor)
243+
dir_path = os.path.join(self.test_dir, '..', '..', '..', 'device', vendor, platform, sku)
244+
qos_file = os.path.join(dir_path, 'qos.json.j2')
245+
port_config_ini_file = os.path.join(dir_path, 'port_config.ini')
246+
247+
# copy qos_config.j2 to the SKU directory to have all templates in one directory
281248
qos_config_file = os.path.join(self.test_dir, '..', '..', '..', 'files', 'build_templates', 'qos_config.j2')
282-
shutil.copy2(qos_config_file, dell_dir_path)
249+
shutil.copy2(qos_config_file, dir_path)
283250

284-
argument = '-m ' + self.dell6100_t0_minigraph + ' -p ' + port_config_ini_file + ' -t ' + qos_file + ' > ' + self.output_file
251+
minigraph = os.path.join(self.test_dir, minigraph)
252+
argument = '-m ' + minigraph + ' -p ' + port_config_ini_file + ' -t ' + qos_file + ' > ' + self.output_file
285253
self.run_script(argument)
286254

287255
# cleanup
288-
qos_config_file_new = os.path.join(dell_dir_path, 'qos_config.j2')
256+
qos_config_file_new = os.path.join(dir_path, 'qos_config.j2')
289257
os.remove(qos_config_file_new)
290258

291-
sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'qos-dell6100.json')
259+
self.remove_machine_conf(file_exist, dir_exist)
260+
261+
sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, expected)
292262
assert utils.cmp(sample_output_file, self.output_file)
293263

294264
def test_buffers_dell6100_render_template(self):
295-
dell_dir_path = os.path.join(self.test_dir, '..', '..', '..', 'device', 'dell', 'x86_64-dell_s6100_c2538-r0', 'Force10-S6100')
296-
buffers_file = os.path.join(dell_dir_path, 'buffers.json.j2')
297-
port_config_ini_file = os.path.join(dell_dir_path, 'port_config.ini')
298-
299-
# copy buffers_config.j2 to the Dell S6100 directory to have all templates in one directory
300-
buffers_config_file = os.path.join(self.test_dir, '..', '..', '..', 'files', 'build_templates', 'buffers_config.j2')
301-
shutil.copy2(buffers_config_file, dell_dir_path)
302-
303-
argument = '-m ' + self.dell6100_t0_minigraph + ' -p ' + port_config_ini_file + ' -t ' + buffers_file + ' > ' + self.output_file
304-
self.run_script(argument)
305-
306-
# cleanup
307-
buffers_config_file_new = os.path.join(dell_dir_path, 'buffers_config.j2')
308-
os.remove(buffers_config_file_new)
309-
310-
sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'buffers-dell6100.json')
311-
assert utils.cmp(sample_output_file, self.output_file)
265+
self._test_buffers_render_template('dell', 'x86_64-dell_s6100_c2538-r0', 'Force10-S6100', 'sample-dell-6100-t0-minigraph.xml', 'buffers.json.j2', 'buffers-dell6100.json')
312266

313267
def test_buffers_mellanox2700_render_template(self):
314268
# Mellanox buffer template rendering for single ingress pool mode
315-
mellanox_dir_path = os.path.join(self.test_dir, '..', '..', '..', 'device', 'mellanox', 'x86_64-mlnx_msn2700-r0', 'Mellanox-SN2700-D48C8')
316-
buffers_file = os.path.join(mellanox_dir_path, 'buffers.json.j2')
317-
port_config_ini_file = os.path.join(mellanox_dir_path, 'port_config.ini')
318-
319-
# copy buffers_config.j2 to the Mellanox 2700 directory to have all templates in one directory
320-
buffers_config_file = os.path.join(self.test_dir, '..', '..', '..', 'files', 'build_templates', 'buffers_config.j2')
321-
shutil.copy2(buffers_config_file, mellanox_dir_path)
322-
323-
argument = '-m ' + self.mellanox2700_t0_minigraph + ' -p ' + port_config_ini_file + ' -t ' + buffers_file + ' > ' + self.output_file
324-
self.run_script(argument)
325-
326-
# cleanup
327-
buffers_config_file_new = os.path.join(mellanox_dir_path, 'buffers_config.j2')
328-
os.remove(buffers_config_file_new)
329-
330-
sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'buffers-mellanox2700.json')
331-
assert utils.cmp(sample_output_file, self.output_file)
269+
self._test_buffers_render_template('mellanox', 'x86_64-mlnx_msn2700-r0', 'Mellanox-SN2700-D48C8', 'sample-mellanox-2700-t0-minigraph.xml', 'buffers.json.j2', 'buffers-mellanox2700.json')
332270

333271
def test_buffers_mellanox2410_render_template(self):
334272
# Mellanox buffer template rendering for double ingress pools mode
335-
mellanox_dir_path = os.path.join(self.test_dir, '..', '..', '..', 'device', 'mellanox', 'x86_64-mlnx_msn2410-r0', 'ACS-MSN2410')
336-
buffers_file = os.path.join(mellanox_dir_path, 'buffers.json.j2')
337-
port_config_ini_file = os.path.join(mellanox_dir_path, 'port_config.ini')
338-
339-
# copy buffers_config.j2 to the Mellanox 2410 directory to have all templates in one directory
340-
buffers_config_file = os.path.join(self.test_dir, '..', '..', '..', 'files', 'build_templates', 'buffers_config.j2')
341-
shutil.copy2(buffers_config_file, mellanox_dir_path)
342-
343-
argument = '-m ' + self.mellanox2410_t1_minigraph + ' -p ' + port_config_ini_file + ' -t ' + buffers_file + ' > ' + self.output_file
344-
self.run_script(argument)
345-
346-
# cleanup
347-
buffers_config_file_new = os.path.join(mellanox_dir_path, 'buffers_config.j2')
348-
os.remove(buffers_config_file_new)
349-
350-
sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'buffers-mellanox2410.json')
351-
assert utils.cmp(sample_output_file, self.output_file)
273+
self._test_buffers_render_template('mellanox', 'x86_64-mlnx_msn2410-r0', 'ACS-MSN2410', 'sample-mellanox-2410-t1-minigraph.xml', 'buffers.json.j2', 'buffers-mellanox2410.json')
352274

353275
def test_config_brcm_render_template(self):
354276
if utils.PYvX_DIR != 'py3':

0 commit comments

Comments
 (0)