Skip to content

Commit ec8185a

Browse files
Parse platform.json, hwsku.json for generate minigraph (#2887)
Description of PR After transition from port_config.ini to platform.json, hwsku.json, we can`t fully deprecate and remove port_config.ini cause of port_mgmt/ansible use port_config.ini for generate minigraph. So currently we have configuration(platform.json, hwsku.json) using by sonic for configure ports and configuration(port_config.ini) using by sonic_mgmt for generate minigraph. So changes in platform.json and hwsku.json will not affect minigraph because of port_config.ini so we have configuration mismatch. PR add functionality to sonic_mgmt for parse platform.json and hwsku.json and use this configuration for generation minigraph. Summary: Approach What is the motivation for this PR? fully deprecate and remove port_config.ini avoid mismatch configurations between port_config.ini and platform.json, hwsku.json How did you do it? Add functionality for parsing platform.json, hwsku.json and use this configuration for generate minigraph. How did you verify/test it? Compare generated minigraph/config_db configurations with platform.json, hwsku.json.
1 parent 1b8d3fe commit ec8185a

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

ansible/library/port_alias.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
import os
55
import traceback
66
import subprocess
7+
import json
8+
import ast
79
from operator import itemgetter
810
from itertools import groupby
911
from collections import defaultdict
12+
from collections import OrderedDict
1013

1114
try:
1215
from sonic_py_common import multi_asic
@@ -49,6 +52,8 @@
4952
FILE_PATH = '/usr/share/sonic/device'
5053
PORTMAP_FILE = 'port_config.ini'
5154
ALLOWED_HEADER = ['name', 'lanes', 'alias', 'index', 'asic_port_name', 'role', 'speed']
55+
PLATFORM_FILE = 'platform.json'
56+
HWSKU_FILE = 'hwsku.json'
5257

5358
MACHINE_CONF = '/host/machine.conf'
5459
ONIE_PLATFORM_KEY = 'onie_platform'
@@ -89,11 +94,98 @@ def get_portconfig_path(self, asic_id=None):
8994
return portconfig
9095
return None
9196

97+
def get_platform_path(self):
98+
platform = self.get_platform_type()
99+
if platform is None:
100+
return None
101+
platform_path = os.path.join(FILE_PATH, platform, PLATFORM_FILE)
102+
if os.path.exists(platform_path):
103+
return platform_path
104+
return None
105+
106+
def get_hwsku_path(self):
107+
platform = self.get_platform_type()
108+
if platform is None:
109+
return None
110+
hwsku_path = os.path.join(FILE_PATH, platform, self.hwsku, HWSKU_FILE)
111+
if os.path.exists(hwsku_path):
112+
return hwsku_path
113+
return None
114+
115+
def get_portmap_from_platform_hwsku(self, platform_file, hwsku_file, aliases, portmap, aliasmap, portspeed):
116+
decoder = json.JSONDecoder(object_pairs_hook=OrderedDict)
117+
brkout_pattern = r'(\d{1,3})x(\d{1,3}G)(\[\d{1,3}G\])?(\((\d{1,3})\))?'
118+
with open(platform_file) as f:
119+
data = json.load(f, object_pairs_hook=OrderedDict)
120+
platform_dict = decoder.decode(json.dumps(data))
121+
with open(hwsku_file) as f:
122+
data = json.load(f)
123+
hwsku_dict = ast.literal_eval(json.dumps(data))
124+
for interface in platform_dict["interfaces"]:
125+
if interface not in hwsku_dict["interfaces"]:
126+
raise Exception("interface {} not in hwsku dict".format(interface))
127+
alias_at_lanes = platform_dict["interfaces"][interface]['alias_at_lanes']
128+
lanes = platform_dict["interfaces"][interface]['lanes']
129+
breakout_mode = hwsku_dict["interfaces"][interface]["default_brkout_mode"]
130+
131+
# Asymmetric breakout mode
132+
if re.search("\+", breakout_mode) is not None:
133+
breakout_parts = breakout_mode.split("+")
134+
match_list = [re.match(brkout_pattern, i).groups() for i in breakout_parts]
135+
# Symmetric breakout mode
136+
else:
137+
match_list = [re.match(brkout_pattern, breakout_mode).groups()]
138+
139+
offset = 0
140+
parent_intf_id = int(re.search("Ethernet(\d+)", interface).group(1))
141+
for k in match_list:
142+
if k is None:
143+
continue
144+
num_lane_used, speed, assigned_lane = k[0], k[1], k[4]
145+
146+
if assigned_lane is None:
147+
assigned_lane = len(lanes.split(","))
148+
parent_intf_id = int(offset)+int(parent_intf_id)
149+
150+
alias_start = 0 + offset
151+
step = int(assigned_lane)//int(num_lane_used)
152+
for i in range(0, int(assigned_lane), step):
153+
intf_name = "Ethernet" + str(parent_intf_id)
154+
alias = alias_at_lanes.split(",")[alias_start]
155+
aliases.append(alias)
156+
portmap[intf_name] = alias
157+
aliasmap[alias] = intf_name
158+
if speed:
159+
speed_pat = re.search("^((\d+)G|\d+)$", speed.upper())
160+
if speed_pat is None:
161+
raise Exception('{} speed is not Supported...'.format(speed))
162+
speed_G, speed_orig = speed_pat.group(2), speed_pat.group(1)
163+
if speed_G:
164+
portspeed[intf_name] = str(int(speed_G)*1000)
165+
else:
166+
portspeed[intf_name] = speed_orig
167+
else:
168+
raise Exception('Regex return for speed is None...')
169+
170+
parent_intf_id += step
171+
alias_start += step
172+
parent_intf_id = 0
173+
offset = int(assigned_lane) + int(offset)
174+
92175
def get_portmap(self, asic_id=None):
93176
aliases = []
94177
portmap = {}
95178
aliasmap = {}
96179
portspeed = {}
180+
181+
# if platform.json and hwsku.json exist, than get portmap from hwsku
182+
platform_file = self.get_platform_path()
183+
hwsku_file = self.get_hwsku_path()
184+
if platform_file and hwsku_file:
185+
self.get_portmap_from_platform_hwsku(platform_file, hwsku_file, aliases, portmap, aliasmap, portspeed)
186+
return (aliases, portmap, aliasmap, portspeed)
187+
188+
# platform.json or hwsku.json does not exist so get portmap from port_config.ini
97189
filename = self.get_portconfig_path(asic_id)
98190
if filename is None:
99191
raise Exception("Something wrong when trying to find the portmap file, either the hwsku is not available or file location is not correct")

0 commit comments

Comments
 (0)