blob: 243df4e73bce0931ec2ea0fe159c34b2e82c55d3 [file] [log] [blame]
George Keishinge7e91712021-09-03 11:28:44 -05001#!/usr/bin/env python3
Michael Walsh19621ba2018-12-03 17:16:02 -06002
3r"""
4A python companion file for ipmi_client.robot.
5"""
6
Michael Walsh355197a2019-01-21 15:06:10 -06007import collections
Patrick Williams20f38712022-12-08 06:18:26 -06008
George Keishinge635ddc2022-12-08 07:38:02 -06009import gen_cmd as gc
Patrick Williams20f38712022-12-08 06:18:26 -060010import gen_print as gp
Michael Walsh19621ba2018-12-03 17:16:02 -060011from robot.libraries.BuiltIn import BuiltIn
12
Michael Walsh355197a2019-01-21 15:06:10 -060013# Set default values for required IPMI options.
Patrick Williams20f38712022-12-08 06:18:26 -060014ipmi_interface = "lanplus"
15ipmi_cipher_suite = BuiltIn().get_variable_value("${IPMI_CIPHER_LEVEL}", "17")
16ipmi_timeout = BuiltIn().get_variable_value("${IPMI_TIMEOUT}", "3")
17ipmi_port = BuiltIn().get_variable_value("${IPMI_PORT}", "623")
Michael Walsh355197a2019-01-21 15:06:10 -060018ipmi_username = BuiltIn().get_variable_value("${IPMI_USERNAME}", "root")
19ipmi_password = BuiltIn().get_variable_value("${IPMI_PASSWORD}", "0penBmc")
20ipmi_host = BuiltIn().get_variable_value("${OPENBMC_HOST}")
21
22# Create a list of the required IPMI options.
Patrick Williams20f38712022-12-08 06:18:26 -060023ipmi_required_options = ["I", "C", "N", "p", "U", "P", "H"]
Michael Walsh355197a2019-01-21 15:06:10 -060024# The following dictionary maps the ipmitool option names (e.g. "I") to our
25# more descriptive names (e.g. "interface") for the required options.
26ipmi_option_name_map = {
Patrick Williams20f38712022-12-08 06:18:26 -060027 "I": "interface",
28 "C": "cipher_suite",
29 "N": "timeout",
30 "p": "port",
31 "U": "username",
32 "P": "password",
33 "H": "host",
Michael Walsh355197a2019-01-21 15:06:10 -060034}
35
36
37def create_ipmi_ext_command_string(command, **options):
Michael Walsh19621ba2018-12-03 17:16:02 -060038 r"""
Michael Walsh355197a2019-01-21 15:06:10 -060039 Create and return an IPMI external command string which is fit to be run
40 from a bash command line.
Michael Walsh19621ba2018-12-03 17:16:02 -060041
Michael Walsh355197a2019-01-21 15:06:10 -060042 Example:
George Keishingf4027652019-01-10 23:58:29 -060043
Michael Walsh355197a2019-01-21 15:06:10 -060044 ipmi_ext_cmd = create_ipmi_ext_command_string('power status')
Michael Walsh19621ba2018-12-03 17:16:02 -060045
Michael Walsh355197a2019-01-21 15:06:10 -060046 Result:
George Keishinge33ad1d2019-12-09 11:17:36 -060047 ipmitool -I lanplus -C 3 -p 623 -P ******** -H x.x.x.x power status
Michael Walsh19621ba2018-12-03 17:16:02 -060048
Michael Walsh355197a2019-01-21 15:06:10 -060049 Example:
50
51 ipmi_ext_cmd = create_ipmi_ext_command_string('power status', C='4')
52
53 Result:
George Keishinge33ad1d2019-12-09 11:17:36 -060054 ipmitool -I lanplus -C 4 -p 623 -P ******** -H x.x.x.x power status
Michael Walsh19621ba2018-12-03 17:16:02 -060055
56 Description of argument(s):
Michael Walsh355197a2019-01-21 15:06:10 -060057 command The ipmitool command (e.g. 'power status').
58 options Any desired options that are understood by
59 ipmitool (see iptmitool's help text for a
60 complete list). If the caller does NOT
61 provide any of several required options
62 (e.g. "P", i.e. password), this function
63 will include them on the caller's behalf
64 using default values.
Michael Walsh19621ba2018-12-03 17:16:02 -060065 """
66
Michael Walsh355197a2019-01-21 15:06:10 -060067 new_options = collections.OrderedDict()
68 for option in ipmi_required_options:
George Keishing2b32c102021-03-29 14:59:00 -050069 # This is to prevent boot table "-N 10" vs user input timeout.
70 if " -N " in command and option == "N":
71 continue
Michael Walsh355197a2019-01-21 15:06:10 -060072 if option in options:
73 # If the caller has specified this particular option, use it in
74 # preference to the default value.
75 new_options[option] = options[option]
76 # Delete the value from the caller's options.
77 del options[option]
78 else:
79 # The caller hasn't specified this required option so specify it
80 # for them using the global value.
Patrick Williams20f38712022-12-08 06:18:26 -060081 var_name = "ipmi_" + ipmi_option_name_map[option]
Michael Walsh355197a2019-01-21 15:06:10 -060082 value = eval(var_name)
83 new_options[option] = value
84 # Include the remainder of the caller's options in the new options
85 # dictionary.
86 for key, value in options.items():
87 new_options[key] = value
Michael Walsh19621ba2018-12-03 17:16:02 -060088
Patrick Williams20f38712022-12-08 06:18:26 -060089 return gc.create_command_string("ipmitool", command, new_options)
Michael Walsh19621ba2018-12-03 17:16:02 -060090
Michael Walsh355197a2019-01-21 15:06:10 -060091
92def verify_ipmi_user_parm_accepted():
93 r"""
94 Deterimine whether the OBMC accepts the '-U' ipmitool option and adjust
95 the global ipmi_required_options accordingly.
96 """
97
98 # Assumption: "U" is in the global ipmi_required_options.
99 global ipmi_required_options
Michael Walsh19621ba2018-12-03 17:16:02 -0600100 print_output = 0
Michael Walsh355197a2019-01-21 15:06:10 -0600101
Patrick Williams20f38712022-12-08 06:18:26 -0600102 command_string = create_ipmi_ext_command_string("power status")
103 rc, stdout = gc.shell_cmd(
104 command_string, print_output=print_output, show_err=0, ignore_err=1
105 )
Michael Walsh355197a2019-01-21 15:06:10 -0600106 gp.qprint_var(rc, 1)
107 if rc == 0:
108 # The OBMC accepts the ipmitool "-U" option so new further work needs
109 # to be done.
Michael Walsh19621ba2018-12-03 17:16:02 -0600110 return
111
Michael Walsh355197a2019-01-21 15:06:10 -0600112 # Remove the "U" option from ipmi_required_options to allow us to create a
113 # command string without the "U" option.
Patrick Williams20f38712022-12-08 06:18:26 -0600114 if "U" in ipmi_required_options:
115 del ipmi_required_options[ipmi_required_options.index("U")]
116 command_string = create_ipmi_ext_command_string("power status")
117 rc, stdout = gc.shell_cmd(
118 command_string, print_output=print_output, show_err=0, ignore_err=1
119 )
Michael Walsh355197a2019-01-21 15:06:10 -0600120 gp.qprint_var(rc, 1)
121 if rc == 0:
122 # The "U" option has been removed from the ipmi_required_options
123 # global variable.
Michael Walsh19621ba2018-12-03 17:16:02 -0600124 return
125
Michael Walsh355197a2019-01-21 15:06:10 -0600126 message = "Unable to run ipmitool (with or without the '-U' option).\n"
127 gp.print_error(message)
128
129 # Revert to original ipmi_required_options by inserting 'U' right before
130 # 'P'.
Patrick Williams20f38712022-12-08 06:18:26 -0600131 ipmi_required_options.insert(ipmi_required_options.index("P"), "U")
Michael Walsh19621ba2018-12-03 17:16:02 -0600132
133
Michael Walsh355197a2019-01-21 15:06:10 -0600134def ipmi_setup():
135 r"""
136 Perform all required setup for running iptmitool commands.
137 """
138
139 verify_ipmi_user_parm_accepted()
140
141
142ipmi_setup()
143
144
145def process_ipmi_user_options(command):
146 r"""
George Keishinge16f1582022-12-15 07:32:21 -0600147 Return the buffer with any ipmi_user_options prepended.
Michael Walsh355197a2019-01-21 15:06:10 -0600148
149 Description of argument(s):
150 command An IPMI command (e.g. "power status").
151 """
152
Patrick Williams20f38712022-12-08 06:18:26 -0600153 ipmi_user_options = BuiltIn().get_variable_value(
154 "${IPMI_USER_OPTIONS}", ""
155 )
Michael Walsh355197a2019-01-21 15:06:10 -0600156 if ipmi_user_options == "":
157 return command
158 return ipmi_user_options + " " + command