Skip to content

Commit 4c8c81e

Browse files
Create config and input file : Dynamically generates device specific
configuration and input files. This code supports to dynamically create "configuration file" and "input file" for virtual interface with few required parameters. Signed-off-by: Shaik Abdulla <abdulla1@linux.vnet.ibm.com>
1 parent 3e4b86c commit 4c8c81e

File tree

1 file changed

+236
-105
lines changed

1 file changed

+236
-105
lines changed

pci_info.py

+236-105
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
# Copyright: 2023 IBM
1515
# Author: Narasimhan V <sim@linux.vnet.ibm.com>
1616
# Author: Manvanthara Puttashankar <manvanth@linux.vnet.ibm.com>
17+
# Author: Shaik Abdulla <abdulla1@linux.vom>
1718

1819
from pprint import pprint
1920
from lib import pci
21+
from lib import virtual
2022
import argparse
2123
import shutil
2224
import os
@@ -38,109 +40,195 @@
3840

3941
logger = logger_init(filepath=BASE_PATH).getlogger()
4042

41-
42-
def create_config(pci_list):
43+
def create_config_inputs(orig_cfg, new_cfg, inputfile, interface, config_type):
4344
"""
44-
Creates avocado test suite / config file, and input file needed for yaml files in that config files.
45+
1. Creates modified configuration file name according to type of interface from original configuration file
46+
2. Generates string with "input file option" along with input file,
47+
3. Generates input parametes of specific device type interface.
48+
49+
Parameters:
50+
orig_cfg (str): The name of the original configuration file.
51+
new_cfg (str): The name of the new configuration file to be generated with
52+
according to interface type.
53+
inputfile (str): The path to the input file containing configuration data.
54+
interface (list): The details of Interface in list format.
55+
config_type (str): The type of configuration to generate. Ex: PCI, vNIC etc.
56+
57+
Returns:
58+
test_suites :: A list, having configuration[cfg] files of different set.
59+
input_file_string :: A string, with extension of "--input-file" option.
60+
input_params:: A list, of different input parameters of specific interface.
4561
"""
4662
test_suites = []
4763
input_file_string = ""
4864
input_params = []
4965
additional_params = args.add_params.split()
50-
for pci in pci_list:
51-
if pci['is_root_disk']:
52-
logger.debug(
53-
"ignoring pci address %s as it contains root disk", pci['pci_root'])
54-
continue
66+
if len(additional_params) != 0:
67+
additional_params = args.add_params.split(",")
68+
69+
# Exclude input parameters when vNIC has been created manually, as these parameters are not needed.
70+
# exclude_inputs_params = ["manageSystem","sriov", "hmc_pwd", "hmc_username", "vios_ip","vios_username",
71+
# "vios_pwd","slot_num", "vios_names","sriov_adapters", "sriov_ports",
72+
# "priority", "auto_failover", "bandwidth"]
73+
74+
# Exclude test-cases from test bucket when vNIC created manually.
75+
exclude_test_cases = ["NetworkVirtualization.test_add", "NetworkVirtualization.test_backingdevadd",
76+
"NetworkVirtualization.test_backingdevremove", "NetworkVirtualization.test_remove"]
77+
78+
# when vNIC created manually, Read the orignal configuration file and write only required test-cases in new configuration file.
79+
if config_type == 'vnic':
80+
test_cases = []
81+
with open("config/tests/host/%s.cfg" % orig_cfg, 'r') as file:
82+
83+
lines = file.readlines()
84+
for testcases in lines:
85+
if not any(exclude_test_case in testcases for exclude_test_case in exclude_test_cases):
86+
test_cases.append(testcases)
87+
88+
with open("config/tests/host/%s.cfg" % new_cfg, 'w+') as output_file:
89+
output_file.write("".join(test_cases))
90+
else:
91+
shutil.copy("config/tests/host/%s.cfg" % orig_cfg, "config/tests/host/%s.cfg" % new_cfg)
92+
93+
test_suites.append("host_%s" % new_cfg)
94+
95+
# adding info to input file
96+
if not CONFIGFILE.has_section(orig_cfg) and not additional_params:
97+
return
98+
input_params = CONFIGFILE.items(orig_cfg)
99+
if not input_params:
100+
return
101+
102+
INPUTFILE.add_section(new_cfg)
103+
104+
# read the input file content and store in dict
105+
inputfile_dict = {}
106+
with open(inputfile, 'r') as file:
107+
for line in file:
108+
# Check if the line starts with '#' or '[' and skip it
109+
if line.startswith('#') or line.startswith('['):
110+
continue
55111

56-
# copy template cfg files and create new ones
57-
cfg_name = "_".join(pci['pci_root'].split(':'))
58-
if pci['adapter_type'] == 'nvmf' and is_rhel8():
59-
orig_cfg = "io_%s_rhel8_fvt" % pci['adapter_type']
60-
new_cfg = "io_%s_rhel8_%s_fvt" % (pci['adapter_type'], cfg_name)
61-
inputfile = "%s/io_%s_rhel8_input.txt" % (
62-
BASE_INPUTFILE_PATH, pci['adapter_type'])
112+
# Split each line by '=' to separate key and value
113+
parts = line.strip().split('=')
114+
115+
# Ensure there are exactly two parts (key and value)
116+
if len(parts) == 2:
117+
inputkey, inputvalue = parts[0].strip(), parts[1].strip()
118+
inputfile_dict[inputkey] = inputvalue
119+
120+
# input params
121+
for param in input_params:
122+
try:
123+
key = param[0]
124+
if ':' not in param[1]:
125+
value = interface[param[1]]
126+
else:
127+
index = param[1].split(':')[0]
128+
index_exact = param[1].split(':')[1]
129+
if index_exact == 'all':
130+
131+
# adding only first two available vNIC interfaces when
132+
# multiple vNIC interfaces are available in system.
133+
if config_type in ('vnic', 'veth', 'hnv'):
134+
value = " ".join(str(item) for item in interface[index][:2])
135+
else:
136+
value = " ".join(interface[index])
137+
else:
138+
value = interface[index][int(index_exact)]
139+
if len(interface[index]) > 1:
140+
del interface[index][int(index_exact)]
141+
# remove the duplicate inputfile enteries
142+
if key in inputfile_dict:
143+
del inputfile_dict[key]
144+
INPUTFILE.set(new_cfg, key, "\"%s\"" % value)
145+
146+
except:
147+
pass
148+
149+
# exclude input parameters when vNIC has been created manually.
150+
# if config_type == 'vnic':
151+
# for key in list(inputfile_dict.keys()):
152+
# if any(key.startswith(exclude) for exclude in exclude_inputs_params):
153+
# del inputfile_dict[key]
154+
155+
# additional params
156+
for param in additional_params:
157+
key = param.split('=')[0]
158+
# handling additional params per pci
159+
if '::' in key:
160+
pci_root = key.split('::')[0].split('.')[0]
161+
if pci_root != pci['pci_root']:
162+
continue
163+
key = key.split('::')[1]
164+
165+
# check if the newly added additional param is same
166+
# as inputfile assign the values directly
167+
if key in inputfile_dict:
168+
inputfile_dict[key] = param.split('=')[1]
63169
else:
64-
orig_cfg = "io_%s_fvt" % pci['adapter_type']
65-
new_cfg = "io_%s_%s_fvt" % (pci['adapter_type'], cfg_name)
66-
inputfile = "%s/io_%s_input.txt" % (
67-
BASE_INPUTFILE_PATH, pci['adapter_type'])
170+
# if it is completly new then directly write to new input file
171+
value = param.split('=')[1]
172+
INPUTFILE.set(new_cfg, key, "\"%s\"" % value)
173+
174+
# append the remaining input file entries to the new input file
175+
for inputkey, inputvalue in inputfile_dict.items():
176+
INPUTFILE.set(new_cfg, inputkey, "%s" % inputvalue)
177+
178+
return test_suites, input_file_string, input_params
179+
180+
181+
def create_config_file(interface_details, config_type):
182+
"""
183+
Creates avocado test suite / config file, and input file needed for yaml files in that config files.
184+
185+
Parameters:
186+
interface_details(list): The detailed differnet Interface parameters in list format.
187+
config_type (str): The type of configuration to generate. Ex: vNIC, HNV, vETH etc.
188+
"""
189+
for virtual in interface_details:
190+
cfg_name = virtual['adapter_type']
191+
orig_cfg = "io_%s_fvt" % virtual['adapter_type']
192+
new_cfg = "io_%s_stress_fvt" % virtual['adapter_type']
193+
inputfile = "%s/io_%s_input.txt" % (BASE_INPUTFILE_PATH, virtual['adapter_type'])
194+
68195
if not os.path.exists("config/tests/host/%s.cfg" % orig_cfg):
69-
logger.debug("ignoring pci address %s as there is no cfg for %s",
70-
pci['pci_root'], pci['adapter_type'])
196+
logger.debug("ignoring hnv address as there is no cfg for %s", virtual['adapter_type'])
71197
continue
72-
shutil.copy("config/tests/host/%s.cfg" %
73-
orig_cfg, "config/tests/host/%s.cfg" % new_cfg)
74-
test_suites.append("host_%s" % new_cfg)
75198

76-
# adding info to input file
77-
if not CONFIGFILE.has_section(orig_cfg) and not additional_params:
78-
continue
79-
input_params = CONFIGFILE.items(orig_cfg)
80-
if not input_params:
81-
continue
82-
INPUTFILE.add_section(new_cfg)
83-
84-
# read the input file content and store in dict
85-
inputfile_dict = {}
86-
with open(inputfile, 'r') as file:
87-
for line in file:
88-
# Check if the line starts with '#' or '[' and skip it
89-
if line.startswith('#') or line.startswith('['):
90-
continue
91-
92-
# Split each line by '=' to separate key and value
93-
parts = line.strip().split('=')
94-
95-
# Ensure there are exactly two parts (key and value)
96-
if len(parts) == 2:
97-
inputkey, inputvalue = parts[0].strip(), parts[1].strip()
98-
inputfile_dict[inputkey] = inputvalue
99-
100-
# input params
101-
for param in input_params:
102-
try:
103-
key = param[0]
104-
if ':' not in param[1]:
105-
value = pci[param[1]]
106-
else:
107-
index = param[1].split(':')[0]
108-
index_exact = param[1].split(':')[1]
109-
if index_exact == 'all':
110-
value = " ".join(pci[index])
111-
else:
112-
value = pci[index][int(index_exact)]
113-
if len(pci[index]) > 1 and not key == 'pci_device':
114-
del pci[index][int(index_exact)]
115-
# remove the duplicate inputfile enteries
116-
if key in inputfile_dict:
117-
del inputfile_dict[key]
118-
INPUTFILE.set(new_cfg, key, "\"%s\"" % value)
119-
except:
120-
pass
121-
122-
# additional params
123-
for param in additional_params:
124-
key = param.split('=')[0]
125-
# handling additional params per pci
126-
if '::' in key:
127-
pci_root = key.split('::')[0].split('.')[0]
128-
if pci_root != pci['pci_root']:
129-
continue
130-
key = key.split('::')[1]
131-
132-
# check if the newly added additional param is same
133-
# as inputfile assign the values directly
134-
if key in inputfile_dict:
135-
inputfile_dict[key] = param.split('=')[1]
199+
return create_config_inputs(orig_cfg, new_cfg, inputfile, virtual, config_type=config_type)
200+
201+
def create_config(interface_details, config_type):
202+
"""
203+
Creates avocado test suite / config file, and input file needed for yaml files in that config files.
204+
"""
205+
if config_type == 'pci':
206+
for pci in interface_details:
207+
if pci['is_root_disk']:
208+
logger.debug(
209+
"ignoring pci address %s as it contains root disk", pci['pci_root'])
210+
continue
211+
212+
# copy template cfg files and create new ones
213+
cfg_name = "_".join(pci['pci_root'].split(':'))
214+
if pci['adapter_type'] == 'nvmf' and is_rhel8():
215+
orig_cfg = "io_%s_rhel8_fvt" % pci['adapter_type']
216+
new_cfg = "io_%s_rhel8_%s_fvt" % (pci['adapter_type'], cfg_name)
217+
inputfile = "%s/io_%s_rhel8_input.txt" % (
218+
BASE_INPUTFILE_PATH, pci['adapter_type'])
136219
else:
137-
# if it is completly new then directly write to new input file
138-
value = param.split('=')[1]
139-
INPUTFILE.set(new_cfg, key, "\"%s\"" % value)
220+
orig_cfg = "io_%s_fvt" % pci['adapter_type']
221+
new_cfg = "io_%s_%s_fvt" % (pci['adapter_type'], cfg_name)
222+
inputfile = "%s/io_%s_input.txt" % (
223+
BASE_INPUTFILE_PATH, pci['adapter_type'])
224+
if not os.path.exists("config/tests/host/%s.cfg" % orig_cfg):
225+
logger.debug("ignoring pci address %s as there is no cfg for %s",
226+
pci['pci_root'], pci['adapter_type'])
227+
continue
228+
test_suites, input_file_string, input_params = create_config_inputs(orig_cfg, new_cfg, inputfile, pci, config_type='pci')
140229

141-
# append the remaining input file entries to the new input file
142-
for inputkey, inputvalue in inputfile_dict.items():
143-
INPUTFILE.set(new_cfg, inputkey, "%s" % inputvalue)
230+
if config_type in ('vnic', 'veth', 'hnv'):
231+
test_suites, input_file_string, input_params = create_config_file(interface_details, config_type)
144232

145233
test_suites = ",".join(test_suites)
146234

@@ -152,17 +240,21 @@ def create_config(pci_list):
152240

153241
# generate avocado-setup command line
154242
if test_suites:
155-
cmd = "python avocado-setup.py --run-suite %s %s" % (
156-
test_suites, input_file_string)
243+
cmd = "python avocado-setup.py --run-suite %s %s" % (test_suites, input_file_string)
157244
return cmd
158245
return ""
159246

160-
161247
if __name__ == '__main__':
162248
parser = argparse.ArgumentParser()
163249
parser.add_argument('--pci-address', dest='pci_addr',
164250
action='store', default='',
165251
help='pci address, comma separated')
252+
parser.add_argument('--vnic', dest='vnic_int', action='store', nargs='?', const='vnic_default', default=None,
253+
help='vNIC interface name')
254+
parser.add_argument('--veth', dest='veth_int', action='store', nargs='?', const='veth_default', default=None,
255+
help='vETH interface name')
256+
parser.add_argument('--hnv', dest='hnv_int', action='store', nargs='?', const='hnv_default', default=None,
257+
help='HNV interface name')
166258
parser.add_argument('--pci-address-blocklist', dest='pci_addr_blocklist',
167259
action='store', default='',
168260
help='pci address which need not be considered, comma separated')
@@ -185,19 +277,58 @@ def create_config(pci_list):
185277
action='store', default='',
186278
help='Additional parameters(key=value) to the input file, space separated')
187279
args = parser.parse_args()
188-
if args.pci_addr:
189-
pci_details = pci.pci_info(args.pci_addr, pci_type=args.pci_type,
190-
pci_blocklist=args.pci_addr_blocklist, type_blocklist=args.type_blocklist)
191-
else:
192-
pci_details = pci.all_pci_info(
193-
pci_type=args.pci_type, pci_blocklist=args.pci_addr_blocklist, type_blocklist=args.type_blocklist)
194-
if not pci_details:
195-
logger.info("No PCI Found")
280+
281+
#if no interfaces name is provided for vNIC ,vETH or HNV, get the first aavailable interface.
282+
if args.vnic_int == 'vnic_default':
283+
args.vnic_int = virtual.get_vnic_interface_names()[0]
284+
285+
if args.veth_int == 'veth_default':
286+
args.veth_int = virtual.get_veth_interface_names()[0]
287+
288+
if args.hnv_int == 'hnv_default':
289+
args.hnv_int = virtual.get_hnv_interface_names()[0]
290+
291+
try:
292+
if args.vnic_int:
293+
vnic_details = virtual.virtual_info(args.vnic_int)
294+
elif args.veth_int:
295+
veth_details = virtual.virtual_info(args.veth_int)
296+
elif args.hnv_int:
297+
hnv_details = virtual.virtual_info(args.hnv_int)
298+
elif args.pci_addr:
299+
pci_details = pci.pci_info(args.pci_addr, pci_type=args.pci_type, pci_blocklist=args.pci_addr_blocklist, type_blocklist=args.type_blocklist)
300+
else:
301+
pci_details = pci.all_pci_info(pci_type=args.pci_type, pci_blocklist=args.pci_addr_blocklist, type_blocklist=args.type_blocklist)
302+
except Exception as e:
303+
if args.vnic_int:
304+
logger.info("vNIC interface not found")
305+
else:
306+
logger.info("No PCI Found")
196307
sys.exit(0)
308+
197309
if args.show_info:
198-
pprint(pci_details)
310+
if args.pci_addr:
311+
pprint(pci_details)
312+
elif args.vnic_int:
313+
pprint(vnic_details)
314+
elif args.veth_int:
315+
pprint(veth_details)
316+
elif args.hnv_int:
317+
pprint(hnv_details)
318+
199319
if args.create_cfg:
200-
cmd = create_config(pci_details)
201-
logger.info(cmd)
320+
if args.vnic_int:
321+
cmd = create_config(interface_details=vnic_details, config_type='vnic')
322+
logger.info(cmd)
323+
elif args.veth_int:
324+
cmd = create_config(interface_details=veth_details, config_type='veth')
325+
logger.info(cmd)
326+
elif args.hnv_int:
327+
cmd = create_config(interface_details=hnv_details, config_type='hnv')
328+
logger.info(cmd)
329+
else:
330+
cmd = create_config(interface_details=pci_details, config_type='pci')
331+
logger.info(cmd)
332+
202333
if args.run_test:
203-
os.system(cmd)
334+
os.system(cmd)

0 commit comments

Comments
 (0)