openbmc-tools: remove trailing spaces from all files
Change-Id: I1c71bf3359718226d27f34c9fb87723edd318814
Signed-off-by: Nagaraju Goruganti <ngorugan@in.ibm.com>
diff --git a/thalerj/openbmctool.py b/thalerj/openbmctool.py
index 2510db1..3f5d14a 100755
--- a/thalerj/openbmctool.py
+++ b/thalerj/openbmctool.py
@@ -33,12 +33,12 @@
def hilight(textToColor, color, bold):
"""
Used to add highlights to various text for displaying in a terminal
-
+
@param textToColor: string, the text to be colored
@param color: string, used to color the text red or green
@param bold: boolean, used to bold the textToColor
- @return: Buffered reader containing the modified string.
- """
+ @return: Buffered reader containing the modified string.
+ """
if(sys.platform.__contains__("win")):
if(color == "red"):
os.system('color 04')
@@ -61,15 +61,15 @@
attr.append('0')
return '\x1b[%sm%s\x1b[0m' % (';'.join(attr),textToColor)
-
+
def connectionErrHandler(jsonFormat, errorStr, err):
"""
Error handler various connection errors to bmcs
-
- @param jsonFormat: boolean, used to output in json format with an error code.
+
+ @param jsonFormat: boolean, used to output in json format with an error code.
@param errorStr: string, used to color the text red or green
- @param err: string, the text from the exception
- """
+ @param err: string, the text from the exception
+ """
if errorStr == "Timeout":
if not jsonFormat:
return("FQPSPIN0000M: Connection timed out. Ensure you have network connectivity to the bmc")
@@ -92,7 +92,7 @@
eventdict = {}
eventdict['event0'] = conerror
eventdict['numAlerts'] = '1'
-
+
errorMessageStr = errorMessageStr = json.dumps(eventdict, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False)
return(errorMessageStr)
elif errorStr == "ConnectionError":
@@ -117,7 +117,7 @@
eventdict = {}
eventdict['event0'] = conerror
eventdict['numAlerts'] = '1'
-
+
errorMessageStr = json.dumps(eventdict, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False)
return(errorMessageStr)
@@ -128,12 +128,12 @@
def setColWidth(keylist, numCols, dictForOutput, colNames):
"""
Sets the output width of the columns to display
-
- @param keylist: list, list of strings representing the keys for the dictForOutput
+
+ @param keylist: list, list of strings representing the keys for the dictForOutput
@param numcols: the total number of columns in the final output
@param dictForOutput: dictionary, contains the information to print to the screen
@param colNames: list, The strings to use for the column headings, in order of the keylist
- @return: A list of the column widths for each respective column.
+ @return: A list of the column widths for each respective column.
"""
colWidths = []
for x in range(0, numCols):
@@ -141,19 +141,19 @@
for key in dictForOutput:
for x in range(0, numCols):
colWidths[x] = max(colWidths[x], len(str(dictForOutput[key][keylist[x]])))
-
+
for x in range(0, numCols):
colWidths[x] = max(colWidths[x], len(colNames[x])) +2
-
+
return colWidths
def loadPolicyTable(pathToPolicyTable):
"""
loads a json based policy table into a dictionary
-
+
@param value: boolean, the value to convert
@return: A string of "Yes" or "No"
- """
+ """
policyTable = {}
if(os.path.exists(pathToPolicyTable)):
with open(pathToPolicyTable, 'r') as stream:
@@ -168,10 +168,10 @@
def boolToString(value):
"""
converts a boolean value to a human readable string value
-
+
@param value: boolean, the value to convert
@return: A string of "Yes" or "No"
- """
+ """
if(value):
return "Yes"
else:
@@ -180,7 +180,7 @@
def stringToInt(text):
"""
returns an integer if the string can be converted, otherwise returns the string
-
+
@param text: the string to try to convert to an integer
"""
if text.isdigit():
@@ -191,7 +191,7 @@
def naturalSort(text):
"""
provides a way to naturally sort a list
-
+
@param text: the key to convert for sorting
@return list containing the broken up string parts by integers and strings
"""
@@ -199,11 +199,11 @@
for c in re.split('(\d+)', text):
stringPartList.append(stringToInt(c))
return stringPartList
-
+
def tableDisplay(keylist, colNames, output):
"""
Logs into the BMC and creates a session
-
+
@param keylist: list, keys for the output dictionary, ordered by colNames
@param colNames: Names for the Table of the columns
@param output: The dictionary of data to display
@@ -216,7 +216,7 @@
if (i != 0): row = row + "| "
row = row + colNames[i].ljust(colWidth[i])
outputText += row + "\n"
-
+
output_keys = list(output.keys())
output_keys.sort(key=naturalSort)
for key in output_keys:
@@ -225,17 +225,17 @@
if (i != 0): row = row + "| "
row = row + output[key][keylist[i]].ljust(colWidth[i])
outputText += row + "\n"
-
+
return outputText
def checkFWactivation(host, args, session):
"""
- Checks the software inventory for an image that is being activated.
-
+ Checks the software inventory for an image that is being activated.
+
@return: True if an image is being activated, false is no activations are happening
"""
url="https://"+host+"/xyz/openbmc_project/software/enumerate"
- httpHeader = {'Content-Type':'application/json'}
+ httpHeader = {'Content-Type':'application/json'}
try:
resp = session.get(url, headers=httpHeader, verify=False, timeout=30)
except(requests.exceptions.Timeout):
@@ -250,15 +250,15 @@
if 'Activating' in fwInfo[key]['Activation'] or 'Activating' in fwInfo[key]['RequestedActivation']:
return True
return False
-
+
def login(host, username, pw,jsonFormat):
"""
Logs into the BMC and creates a session
-
+
@param host: string, the hostname or IP address of the bmc to log into
@param username: The user name for the bmc to log into
@param pw: The password for the BMC to log into
- @param jsonFormat: boolean, flag that will only allow relevant data from user command to be display. This function becomes silent when set to true.
+ @param jsonFormat: boolean, flag that will only allow relevant data from user command to be display. This function becomes silent when set to true.
@return: Session object
"""
if(jsonFormat==False):
@@ -269,7 +269,7 @@
r = mysess.post('https://'+host+'/login', headers=httpHeader, json = {"data": [username, pw]}, verify=False, timeout=30)
loginMessage = json.loads(r.text)
if (loginMessage['status'] != "ok"):
- print(loginMessage["data"]["description"].encode('utf-8'))
+ print(loginMessage["data"]["description"].encode('utf-8'))
sys.exit(1)
# if(sys.version_info < (3,0)):
# urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
@@ -281,67 +281,67 @@
except(requests.exceptions.ConnectionError) as err:
return (connectionErrHandler(jsonFormat, "ConnectionError", err))
-
+
def logout(host, username, pw, session, jsonFormat):
"""
Logs out of the bmc and terminates the session
-
+
@param host: string, the hostname or IP address of the bmc to log out of
@param username: The user name for the bmc to log out of
@param pw: The password for the BMC to log out of
@param session: the active session to use
- @param jsonFormat: boolean, flag that will only allow relevant data from user command to be display. This function becomes silent when set to true.
- """
+ @param jsonFormat: boolean, flag that will only allow relevant data from user command to be display. This function becomes silent when set to true.
+ """
httpHeader = {'Content-Type':'application/json'}
try:
r = session.post('https://'+host+'/logout', headers=httpHeader,json = {"data": [username, pw]}, verify=False, timeout=10)
except(requests.exceptions.Timeout):
print(connectionErrHandler(jsonFormat, "Timeout", None))
-
+
if(jsonFormat==False):
if('"message": "200 OK"' in r.text):
print('User ' +username + ' has been logged out')
-
+
def fru(host, args, session):
"""
prints out the system inventory. deprecated see fruPrint and fruList
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the fru sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
- """
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ """
#url="https://"+host+"/org/openbmc/inventory/system/chassis/enumerate"
-
+
#print(url)
#res = session.get(url, headers=httpHeader, verify=False)
#print(res.text)
#sample = res.text
-
+
#inv_list = json.loads(sample)["data"]
-
+
url="https://"+host+"/xyz/openbmc_project/inventory/enumerate"
httpHeader = {'Content-Type':'application/json'}
try:
res = session.get(url, headers=httpHeader, verify=False, timeout=40)
except(requests.exceptions.Timeout):
return(connectionErrHandler(args.json, "Timeout", None))
-
+
sample = res.text
# inv_list.update(json.loads(sample)["data"])
-#
+#
# #determine column width's
# colNames = ["FRU Name", "FRU Type", "Has Fault", "Is FRU", "Present", "Version"]
# colWidths = setColWidth(["FRU Name", "fru_type", "fault", "is_fru", "present", "version"], 6, inv_list, colNames)
-#
-# print("FRU Name".ljust(colWidths[0])+ "FRU Type".ljust(colWidths[1]) + "Has Fault".ljust(colWidths[2]) + "Is FRU".ljust(colWidths[3])+
+#
+# print("FRU Name".ljust(colWidths[0])+ "FRU Type".ljust(colWidths[1]) + "Has Fault".ljust(colWidths[2]) + "Is FRU".ljust(colWidths[3])+
# "Present".ljust(colWidths[4]) + "Version".ljust(colWidths[5]))
# format the output
# for key in sorted(inv_list.keys()):
# keyParts = key.split("/")
# isFRU = "True" if (inv_list[key]["is_fru"]==1) else "False"
-#
+#
# fruEntry = (keyParts[len(keyParts) - 1].ljust(colWidths[0]) + inv_list[key]["fru_type"].ljust(colWidths[1])+
# inv_list[key]["fault"].ljust(colWidths[2])+isFRU.ljust(colWidths[3])+
# inv_list[key]["present"].ljust(colWidths[4])+ inv_list[key]["version"].ljust(colWidths[5]))
@@ -356,16 +356,16 @@
# print (fruEntry)
return sample
-def fruPrint(host, args, session):
+def fruPrint(host, args, session):
"""
prints out all inventory
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the fru sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
- @return returns the total fru list.
- """
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ @return returns the total fru list.
+ """
url="https://"+host+"/xyz/openbmc_project/inventory/enumerate"
httpHeader = {'Content-Type':'application/json'}
try:
@@ -383,35 +383,35 @@
return(connectionErrHandler(args.json, "Timeout", None))
# print(res.text)
frulist = frulist +"\n" + res.text
-
+
return frulist
def fruList(host, args, session):
"""
prints out all inventory or only a specific specified item
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the fru sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
- """
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ """
if(args.items==True):
return fruPrint(host, args, session)
else:
return fruPrint(host, args, session)
-
+
def fruStatus(host, args, session):
"""
prints out the status of all FRUs
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the fru sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
- """
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ """
url="https://"+host+"/xyz/openbmc_project/inventory/enumerate"
httpHeader = {'Content-Type':'application/json'}
try:
@@ -433,7 +433,7 @@
fruName = keyPieces[-2] + '-' + keyPieces[-1]
if 'Functional' in component:
if('Present' in component):
-
+
if 'FieldReplaceable' in component:
if component['FieldReplaceable'] == 1:
isFru = True
@@ -483,23 +483,23 @@
return tableDisplay(keylist, colNames, frus)
else:
return str(json.dumps(frus, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False))
-
+
def sensor(host, args, session):
"""
prints out all sensors
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the sensor sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
- """
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ """
httpHeader = {'Content-Type':'application/json'}
url="https://"+host+"/xyz/openbmc_project/sensors/enumerate"
try:
res = session.get(url, headers=httpHeader, verify=False, timeout=30)
except(requests.exceptions.Timeout):
return(connectionErrHandler(args.json, "Timeout", None))
-
+
#Get OCC status
url="https://"+host+"/org/open_power/control/enumerate"
try:
@@ -519,13 +519,13 @@
senDict['units'] = sensors[key]['Unit'].split('.')[-1]
except KeyError:
senDict['units'] = "N/A"
- if('Scale' in sensors[key]):
- scale = 10 ** sensors[key]['Scale']
- else:
+ if('Scale' in sensors[key]):
+ scale = 10 ** sensors[key]['Scale']
+ else:
scale = 1
try:
senDict['value'] = str(sensors[key]['Value'] * scale)
- except KeyError:
+ except KeyError:
if 'value' in sensors[key]:
senDict['value'] = sensors[key]['value']
else:
@@ -535,19 +535,19 @@
else:
senDict['target'] = 'N/A'
output[senDict['sensorName']] = senDict
-
+
occstatus = json.loads(occres.text)["data"]
if '/org/open_power/control/occ0' in occstatus:
occ0 = occstatus["/org/open_power/control/occ0"]['OccActive']
- if occ0 == 1:
- occ0 = 'Active'
- else:
+ if occ0 == 1:
+ occ0 = 'Active'
+ else:
occ0 = 'Inactive'
output['OCC0'] = {'sensorName':'OCC0', 'type': 'Discrete', 'units': 'N/A', 'value': occ0, 'target': 'Active'}
occ1 = occstatus["/org/open_power/control/occ1"]['OccActive']
- if occ1 == 1:
- occ1 = 'Active'
- else:
+ if occ1 == 1:
+ occ1 = 'Active'
+ else:
occ1 = 'Inactive'
output['OCC1'] = {'sensorName':'OCC1', 'type': 'Discrete', 'units': 'N/A', 'value': occ0, 'target': 'Active'}
else:
@@ -558,16 +558,16 @@
return tableDisplay(keylist, colNames, output)
else:
return res.text + occres.text
-
+
def sel(host, args, session):
"""
prints out the bmc alerts
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the sel sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
- """
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ """
url="https://"+host+"/xyz/openbmc_project/logging/entry/enumerate"
httpHeader = {'Content-Type':'application/json'}
@@ -576,15 +576,15 @@
except(requests.exceptions.Timeout):
return(connectionErrHandler(args.json, "Timeout", None))
return res.text
-
-
+
+
def parseESEL(args, eselRAW):
"""
parses the esel data and gets predetermined search terms
-
+
@param eselRAW: string, the raw esel string from the bmc
@return: A dictionary containing the quick snapshot data unless args.fullEsel is listed then a full PEL log is returned
- """
+ """
eselParts = {}
esel_bin = binascii.unhexlify(''.join(eselRAW.split()[16:]))
#search terms contains the search term as the key and the return dictionary key as it's value
@@ -613,15 +613,15 @@
else:
print("machine architecture not supported for parsing eSELs")
return eselParts
-
+
if(os.path.exists(errlPath)):
output= subprocess.check_output([errlPath, '-d', '--file='+eselBinPath]).decode('utf-8')
# output = proc.communicate()[0]
lines = output.split('\n')
-
+
if(hasattr(args, 'fullEsel')):
return output
-
+
for i in range(0, len(lines)):
lineParts = lines[i].split(':')
if(len(lineParts)>1): #ignore multi lines, output formatting lines, and other information
@@ -644,8 +644,8 @@
os.remove(eselBinPath)
else:
print("errl file cannot be found")
-
- return eselParts
+
+ return eselParts
def getESELSeverity(esel):
@@ -682,13 +682,13 @@
def sortSELs(events):
"""
sorts the sels by timestamp, then log entry number
-
+
@param events: Dictionary containing events
@return: list containing a list of the ordered log entries, and dictionary of keys
- """
+ """
logNumList = []
timestampList = []
- eventKeyDict = {}
+ eventKeyDict = {}
eventsWithTimestamp = {}
logNum2events = {}
for key in events:
@@ -701,7 +701,7 @@
eventsWithTimestamp[timestamp].append(events[key]['logNum'])
#map logNumbers to the event dictionary keys
eventKeyDict[str(events[key]['logNum'])] = key
-
+
timestampList = list(eventsWithTimestamp.keys())
timestampList.sort()
for ts in timestampList:
@@ -711,18 +711,18 @@
logNumList = logNumList + tmplist
else:
logNumList = logNumList + eventsWithTimestamp[ts]
-
+
return [logNumList, eventKeyDict]
def parseAlerts(policyTable, selEntries, args):
"""
parses alerts in the IBM CER format, using an IBM policy Table
-
+
@param policyTable: dictionary, the policy table entries
@param selEntries: dictionary, the alerts retrieved from the bmc
@return: A dictionary of the parsed entries, in chronological order
- """
+ """
eventDict = {}
eventNum =""
count = 0
@@ -730,7 +730,7 @@
eselParts = {}
i2cdevice= ""
eselSeverity = None
-
+
'prepare and sort the event entries'
for key in selEntries:
if 'callout' not in key:
@@ -739,7 +739,7 @@
sortedEntries = sortSELs(selEntries)
logNumList = sortedEntries[0]
eventKeyDict = sortedEntries[1]
-
+
for logNum in logNumList:
key = eventKeyDict[logNum]
hasEsel=False
@@ -803,7 +803,7 @@
if("SENSOR_TYPE" in addDataPiece[i]):
calloutFound=True
fruCallout = str(addDataPiece[i]).split('=')[1].strip()
-
+
if(calloutFound):
if fruCallout != "":
policyKey = messageID +"||" + fruCallout
@@ -841,7 +841,7 @@
event['raweSEL'] = esel
event['logNum'] = key.split('/')[-1]
eventDict['event' + eventNum] = event
-
+
else:
severity = str(selEntries[key]['Severity']).split('.')[-1]
if severity == 'Error':
@@ -863,10 +863,10 @@
def selDisplay(events, args):
"""
displays alerts in human readable format
-
+
@param events: Dictionary containing events
- @return:
- """
+ @return:
+ """
activeAlerts = []
historyAlerts = []
sortedEntries = sortSELs(events)
@@ -906,17 +906,17 @@
else:
callout = msgPieces[1]
selDict['Message'] = polMsg +"policy table: "+ err + "||" + callout
- selDict['Serviceable'] = 'Unknown'
+ selDict['Serviceable'] = 'Unknown'
selDict['Severity'] = alert['Severity']
else:
selDict['Entry'] = alert['logNum']
selDict['ID'] = alert['CommonEventID']
selDict['Timestamp'] = datetime.datetime.fromtimestamp(int(alert['timestamp']/1000)).strftime("%Y-%m-%d %H:%M:%S")
- selDict['Message'] = alert['Message']
- selDict['Serviceable'] = alert['Serviceable']
+ selDict['Message'] = alert['Message']
+ selDict['Serviceable'] = alert['Serviceable']
selDict['Severity'] = alert['Severity']
-
-
+
+
eselOrder = ['refCode','signatureDescription', 'eselType', 'devdesc', 'calloutType', 'procedure']
if ('eselParts' in alert and args.devdebug):
eselOutput = ""
@@ -927,38 +927,38 @@
else:
if args.devdebug:
selDict['eSEL'] = "None"
-
+
if not alert['resolved']:
activeAlerts.append(selDict)
else:
historyAlerts.append(selDict)
mergedOutput = activeAlerts + historyAlerts
- colWidth = setColWidth(keylist, len(colNames), dict(enumerate(mergedOutput)), colNames)
-
+ colWidth = setColWidth(keylist, len(colNames), dict(enumerate(mergedOutput)), colNames)
+
output = ""
if(len(activeAlerts)>0):
- row = ""
+ row = ""
output +="----Active Alerts----\n"
for i in range(0, len(colNames)):
if i!=0: row =row + "| "
row = row + colNames[i].ljust(colWidth[i])
output += row + "\n"
-
+
for i in range(0,len(activeAlerts)):
row = ""
for j in range(len(activeAlerts[i])):
if (j != 0): row = row + "| "
row = row + activeAlerts[i][keylist[j]].ljust(colWidth[j])
output += row + "\n"
-
- if(len(historyAlerts)>0):
- row = ""
- output+= "----Historical Alerts----\n"
+
+ if(len(historyAlerts)>0):
+ row = ""
+ output+= "----Historical Alerts----\n"
for i in range(len(colNames)):
if i!=0: row =row + "| "
row = row + colNames[i].ljust(colWidth[i])
output += row + "\n"
-
+
for i in range(0, len(historyAlerts)):
row = ""
for j in range(len(historyAlerts[i])):
@@ -966,18 +966,18 @@
row = row + historyAlerts[i][keylist[j]].ljust(colWidth[j])
output += row + "\n"
# print(events[eventKeyDict[str(log)]])
- return output
+ return output
def selPrint(host, args, session):
"""
prints out all bmc alerts
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the fru sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
- """
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ """
if(args.policyTableLoc is None):
if os.path.exists('policyTable.json'):
ptableLoc = "policyTable.json"
@@ -996,7 +996,7 @@
rawselEntries = ''.join(selLines)
else:
print("Error: File not found")
- sys.exit(1)
+ sys.exit(1)
else:
rawselEntries = sel(host, args, session)
loadFailed = False
@@ -1015,7 +1015,7 @@
return("{\n\t\"numAlerts\": 0\n}")
else:
return("No log entries found")
-
+
else:
if(len(policyTable)>0):
events = parseAlerts(policyTable, selEntries, args)
@@ -1034,32 +1034,32 @@
else:
print("error: Policy Table not found.")
return selEntries
-
+
def selList(host, args, session):
"""
prints out all all bmc alerts, or only prints out the specified alerts
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the fru sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
- """
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ """
return(sel(host, args, session))
-
+
def selClear(host, args, session):
"""
clears all alerts
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the fru sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
- """
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ """
url="https://"+host+"/xyz/openbmc_project/logging/action/deleteAll"
httpHeader = {'Content-Type':'application/json'}
data = "{\"data\": [] }"
-
+
try:
res = session.post(url, headers=httpHeader, data=data, verify=False, timeout=30)
except(requests.exceptions.Timeout):
@@ -1086,12 +1086,12 @@
def selSetResolved(host, args, session):
"""
sets a sel entry to resolved
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the fru sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
- """
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ """
url="https://"+host+"/xyz/openbmc_project/logging/entry/" + str(args.selNum) + "/attr/Resolved"
httpHeader = {'Content-Type':'application/json'}
data = "{\"data\": 1 }"
@@ -1107,12 +1107,12 @@
def selResolveAll(host, args, session):
"""
sets a sel entry to resolved
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the fru sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
- """
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ """
rawselEntries = sel(host, args, session)
loadFailed = False
try:
@@ -1154,12 +1154,12 @@
def chassisPower(host, args, session):
"""
called by the chassis function. Controls the power state of the chassis, or gets the status
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the fru sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
- """
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ """
if(args.powcmd == 'on'):
if checkFWactivation(host, args, session):
return ("Chassis Power control disabled during firmware activation")
@@ -1229,11 +1229,11 @@
def chassisIdent(host, args, session):
"""
called by the chassis function. Controls the identify led of the chassis. Sets or gets the state
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the fru sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
"""
if(args.identcmd == 'on'):
print("Attempting to turn identify light on...:")
@@ -1277,12 +1277,12 @@
def chassis(host, args, session):
"""
controls the different chassis commands
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the fru sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
- """
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ """
if(hasattr(args, 'powcmd')):
result = chassisPower(host,args,session)
elif(hasattr(args, 'identcmd')):
@@ -1294,11 +1294,11 @@
def bmcDumpRetrieve(host, args, session):
"""
Downloads a dump file from the bmc
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the collectServiceData sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
"""
httpHeader = {'Content-Type':'application/json'}
dumpNum = args.dumpNum
@@ -1314,7 +1314,7 @@
if saveLoc[-1] != os.path.sep:
saveLoc = saveLoc + os.path.sep
filename = saveLoc + host+'-dump' + str(dumpNum) + '.tar.xz'
-
+
else:
return 'Invalid save location specified'
else:
@@ -1325,22 +1325,22 @@
if chunk:
f.write(chunk)
return 'Saved as ' + filename
-
+
except(requests.exceptions.Timeout):
return connectionErrHandler(args.json, "Timeout", None)
-
+
except(requests.exceptions.ConnectionError) as err:
return connectionErrHandler(args.json, "ConnectionError", err)
-def bmcDumpList(host, args, session):
+def bmcDumpList(host, args, session):
"""
Lists the number of dump files on the bmc
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the collectServiceData sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
- """
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ """
httpHeader = {'Content-Type':'application/json'}
url ='https://'+host+'/xyz/openbmc_project/dump/list'
try:
@@ -1349,18 +1349,18 @@
return r.text
except(requests.exceptions.Timeout):
return connectionErrHandler(args.json, "Timeout", None)
-
+
except(requests.exceptions.ConnectionError) as err:
- return connectionErrHandler(args.json, "ConnectionError", err)
-
+ return connectionErrHandler(args.json, "ConnectionError", err)
+
def bmcDumpDelete(host, args, session):
"""
Deletes BMC dump files from the bmc
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the collectServiceData sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
"""
httpHeader = {'Content-Type':'application/json'}
dumpList = []
@@ -1393,11 +1393,11 @@
def bmcDumpDeleteAll(host, args, session):
"""
Deletes All BMC dump files from the bmc
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the collectServiceData sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
"""
dumpResp = bmcDumpList(host, args, session)
if 'FQPSPIN0000M' in dumpResp or 'FQPSPIN0001M'in dumpResp:
@@ -1409,18 +1409,18 @@
if '/xyz/openbmc_project/dump/internal/manager' not in dump:
dumpNums.append(int(dump.strip().split('/')[-1]))
d['dumpNum'] = dumpNums
-
+
return bmcDumpDelete(host, args, session)
-
+
def bmcDumpCreate(host, args, session):
"""
Creates a bmc dump file
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the collectServiceData sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
"""
httpHeader = {'Content-Type':'application/json'}
url = 'https://'+host+'/xyz/openbmc_project/dump/action/CreateDump'
@@ -1434,20 +1434,20 @@
return connectionErrHandler(args.json, "Timeout", None)
except(requests.exceptions.ConnectionError) as err:
return connectionErrHandler(args.json, "ConnectionError", err)
-
-
-
+
+
+
def collectServiceData(host, args, session):
"""
Collects all data needed for service from the BMC
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the collectServiceData sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
"""
-
+
global toolVersion
#create a bmc dump
dumpcount = len(json.loads(bmcDumpList(host, args, session))['data'])
@@ -1455,8 +1455,8 @@
dumpcreated = bmcDumpCreate(host, args, session)
except Exception as e:
print('failed to create a bmc dump')
-
-
+
+
#Collect Inventory
try:
args.silent = True
@@ -1470,7 +1470,7 @@
filelist.append(myDir+'/inventory.txt')
except Exception as e:
print("Failed to collect inventory")
-
+
#Read all the sensor and OCC status
try:
sensorReadings = sensor(host, args, session)
@@ -1480,7 +1480,7 @@
filelist.append(myDir+'/sensorReadings.txt')
except Exception as e:
print("Failed to collect sensor readings")
-
+
#Collect all of the LEDs status
try:
url="https://"+host+"/xyz/openbmc_project/led/enumerate"
@@ -1492,7 +1492,7 @@
filelist.append(myDir+'/ledStatus.txt')
except Exception as e:
print("Failed to collect LED status")
-
+
#Collect the bmc logs
try:
sels = selPrint(host,args,session)
@@ -1501,7 +1501,7 @@
print("sel short list collected and stored in "+myDir +"/SELshortlist.txt")
filelist.append(myDir+'/SELshortlist.txt')
time.sleep(2)
-
+
d = vars(args)
d['json'] = True
d['fullSel'] = True
@@ -1513,8 +1513,8 @@
esel = ""
parsedfullsels[sortedSELs[1][str(log)]]['timestamp'] = datetime.datetime.fromtimestamp(int(parsedfullsels[sortedSELs[1][str(log)]]['timestamp']/1000)).strftime("%Y-%m-%d %H:%M:%S")
if ('raweSEL' in parsedfullsels[sortedSELs[1][str(log)]] and args.devdebug):
- esel = parsedfullsels[sortedSELs[1][str(log)]]['raweSEL']
- del parsedfullsels[sortedSELs[1][str(log)]]['raweSEL']
+ esel = parsedfullsels[sortedSELs[1][str(log)]]['raweSEL']
+ del parsedfullsels[sortedSELs[1][str(log)]]['raweSEL']
f.write(json.dumps(parsedfullsels[sortedSELs[1][str(log)]],sort_keys=True, indent=4, separators=(',', ': ')))
if(args.devdebug and esel != ""):
f.write(parseESEL(args, esel))
@@ -1523,9 +1523,9 @@
except Exception as e:
print("Failed to collect system event logs")
print(e)
-
+
#collect RAW bmc enumeration
- try:
+ try:
url="https://"+host+"/xyz/openbmc_project/enumerate"
print("Attempting to get a full BMC enumeration")
fullDump = session.get(url, headers=httpHeader, verify=False, timeout=120)
@@ -1535,11 +1535,11 @@
filelist.append(myDir+'/bmcFullRaw.txt')
except Exception as e:
print("Failed to collect bmc full enumeration")
-
- #collect the dump files
+
+ #collect the dump files
waitingForNewDump = True
count = 0;
- while(waitingForNewDump):
+ while(waitingForNewDump):
dumpList = json.loads(bmcDumpList(host, args, session))['data']
if len(dumpList) > dumpcount:
waitingForNewDump = False
@@ -1550,7 +1550,7 @@
else:
time.sleep(2)
count += 1
- try:
+ try:
print('Collecting bmc dump files')
d['dumpSaveLoc'] = myDir
dumpList = json.loads(bmcDumpList(host, args, session))['data']
@@ -1564,9 +1564,9 @@
except Exception as e:
print("Failed to collect bmc dump files")
print(e)
-
+
#create the zip file
- try:
+ try:
filename = myDir.split(tempfile.gettempdir()+os.sep)[-1] + "_" + toolVersion + '_openbmc.zip'
zf = zipfile.ZipFile(myDir+'/' + filename, 'w')
for myfile in filelist:
@@ -1580,20 +1580,20 @@
def healthCheck(host, args, session):
"""
runs a health check on the platform
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the bmc sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
- """
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ """
#check fru status and get as json to easily work through
d = vars(args)
useJson = d['json']
d['json'] = True
d['verbose']= False
-
+
frus = json.loads(fruStatus(host, args, session))
-
+
hwStatus= "OK"
performanceStatus = "OK"
for key in frus:
@@ -1618,8 +1618,8 @@
else:
output = ("Hardware Status: " + hwStatus +
"\nPerformance: " +performanceStatus )
-
-
+
+
#SW407886: Clear the duplicate entries
#collect the dups
d['devdebug'] = False
@@ -1664,32 +1664,32 @@
return output
-
+
def bmc(host, args, session):
"""
handles various bmc level commands, currently bmc rebooting
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the bmc sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
- """
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ """
if(args.type is not None):
return bmcReset(host, args, session)
if(args.info):
return "Not implemented at this time"
-
+
def bmcReset(host, args, session):
"""
- controls resetting the bmc. warm reset reboots the bmc, cold reset removes the configuration and reboots.
-
+ controls resetting the bmc. warm reset reboots the bmc, cold reset removes the configuration and reboots.
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the bmcReset sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
- """
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ """
if checkFWactivation(host, args, session):
return ("BMC reset control disabled during firmware activation")
if(args.type == "warm"):
@@ -1712,16 +1712,16 @@
def gardClear(host, args, session):
"""
clears the gard records from the bmc
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the gardClear sub command
@param session: the active session to use
- """
+ """
url="https://"+host+"/org/open_power/control/gard/action/Reset"
httpHeader = {'Content-Type':'application/json'}
data = '{"data":[]}'
try:
-
+
res = session.post(url, headers=httpHeader, data=data, verify=False, timeout=30)
if res.status_code == 404:
return "Command not supported by this firmware version"
@@ -1735,14 +1735,14 @@
def activateFWImage(host, args, session):
"""
activates a firmware image on the bmc
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the fwflash sub command
@param session: the active session to use
@param fwID: the unique ID of the fw image to activate
- """
+ """
fwID = args.imageID
-
+
#determine the existing versions
httpHeader = {'Content-Type':'application/json'}
url="https://"+host+"/xyz/openbmc_project/software/enumerate"
@@ -1764,13 +1764,13 @@
if 'Purpose' in existingSoftware[key]:
if versionType == existingSoftware[key]['Purpose']:
altVersionID = key.split('/')[-1]
-
-
-
-
+
+
+
+
url="https://"+host+"/xyz/openbmc_project/software/"+ fwID + "/attr/Priority"
url1="https://"+host+"/xyz/openbmc_project/software/"+ altVersionID + "/attr/Priority"
- data = "{\"data\": 0}"
+ data = "{\"data\": 0}"
data1 = "{\"data\": 1 }"
try:
resp = session.put(url, headers=httpHeader, data=data, verify=False, timeout=30)
@@ -1796,11 +1796,11 @@
def extractFWimage(path, imageType):
"""
extracts the bmc image and returns information about the package
-
+
@param path: the path and file name of the firmware image
@param imageType: The type of image the user is trying to flash. Host or BMC
@return: the image id associated with the package. returns an empty string on error.
- """
+ """
f = tempfile.TemporaryFile()
tmpDir = tempfile.gettempdir()
newImageID = ""
@@ -1815,7 +1815,7 @@
for line in imageInfo:
if 'purpose' in line:
purpose = line.split('=')[1]
- if imageType not in purpose.split('.')[-1]:
+ if imageType not in purpose.split('.')[-1]:
print('The specified image is not for ' + imageType)
print('Please try again with the image for ' + imageType)
return ""
@@ -1842,40 +1842,40 @@
else:
print('The filename and path provided are not valid.')
return newImageID
-
+
def getAllFWImageIDs(fwInvDict):
"""
gets a list of all the firmware image IDs
-
+
@param fwInvDict: the dictionary to search for FW image IDs
@return: list containing string representation of the found image ids
- """
+ """
idList = []
for key in fwInvDict:
if 'Version' in fwInvDict[key]:
idList.append(key.split('/')[-1])
- return idList
-
+ return idList
+
def fwFlash(host, args, session):
"""
updates the bmc firmware and pnor firmware
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the fwflash sub command
@param session: the active session to use
- """
+ """
d = vars(args)
if(args.type == 'bmc'):
purp = 'BMC'
else:
purp = 'Host'
-
- #check power state of the machine. No concurrent FW updates allowed
+
+ #check power state of the machine. No concurrent FW updates allowed
d['powcmd'] = 'status'
powerstate = chassisPower(host, args, session)
if 'Chassis Power State: On' in powerstate:
return("Aborting firmware update. Host is powered on. Please turn off the host and try again.")
-
+
#determine the existing images on the bmc
httpHeader = {'Content-Type':'application/json'}
url="https://"+host+"/xyz/openbmc_project/software/enumerate"
@@ -1886,16 +1886,16 @@
except(requests.exceptions.ConnectionError) as err:
return connectionErrHandler(args.json, "ConnectionError", err)
oldsoftware = json.loads(resp.text)['data']
-
+
#Extract the tar and get information from the manifest file
newversionID = extractFWimage(args.fileloc, purp)
if newversionID == "":
return "Unable to verify FW image."
-
-
+
+
#check if the new image is already on the bmc
if newversionID not in getAllFWImageIDs(oldsoftware):
-
+
#upload the file
httpHeader = {'Content-Type':'application/octet-stream'}
url="https://"+host+"/upload/image"
@@ -1911,7 +1911,7 @@
return "Failed to upload the file to the bmc"
else:
print("Upload complete.")
-
+
#verify bmc processed the image
software ={}
for i in range(0, 5):
@@ -1929,23 +1929,23 @@
break
else:
time.sleep(15)
-
+
#activate the new image
print("Activating new image: "+newversionID)
url="https://"+host+"/xyz/openbmc_project/software/"+ newversionID + "/attr/RequestedActivation"
- data = '{"data":"xyz.openbmc_project.Software.Activation.RequestedActivations.Active"}'
+ data = '{"data":"xyz.openbmc_project.Software.Activation.RequestedActivations.Active"}'
try:
resp = session.put(url, headers=httpHeader, data=data, verify=False, timeout=30)
except(requests.exceptions.Timeout):
return connectionErrHandler(args.json, "Timeout", None)
except(requests.exceptions.ConnectionError) as err:
return connectionErrHandler(args.json, "ConnectionError", err)
-
+
#wait for the activation to complete, timeout after ~1 hour
i=0
while i < 360:
url="https://"+host+"/xyz/openbmc_project/software/"+ newversionID
- data = '{"data":"xyz.openbmc_project.Software.Activation.RequestedActivations.Active"}'
+ data = '{"data":"xyz.openbmc_project.Software.Activation.RequestedActivations.Active"}'
try:
resp = session.get(url, headers=httpHeader, verify=False, timeout=30)
except(requests.exceptions.Timeout):
@@ -1963,14 +1963,14 @@
return "Firmware flash and activation completed. Please reboot the bmc and then boot the host OS for the changes to take effect. "
else:
print("This image has been found on the bmc. Activating image: " + newversionID)
-
+
d['imageID'] = newversionID
return activateFWImage(host, args, session)
def getFWInventoryAttributes(rawFWInvItem, ID):
"""
- gets and lists all of the firmware in the system.
-
+ gets and lists all of the firmware in the system.
+
@return: returns a dictionary containing the image attributes
"""
reqActivation = rawFWInvItem["RequestedActivation"].split('.')[-1]
@@ -1984,17 +1984,17 @@
"Version": rawFWInvItem["Version"],
"RequestedActivation": pendingActivation,
"ID": ID}}
-
+
if "ExtendedVersion" in rawFWInvItem:
firmwareAttr[ID]['ExtendedVersion'] = rawFWInvItem['ExtendedVersion'].split(',')
- else:
+ else:
firmwareAttr[ID]['ExtendedVersion'] = ""
return firmwareAttr
def parseFWdata(firmwareDict):
"""
- creates a dictionary with parsed firmware data
-
+ creates a dictionary with parsed firmware data
+
@return: returns a dictionary containing the image attributes
"""
firmwareInfoDict = {"Functional": {}, "Activated":{}, "NeedsActivated":{}}
@@ -2019,11 +2019,11 @@
for key in emptySections:
del firmwareInfoDict[key]
return firmwareInfoDict
-
+
def displayFWInvenory(firmwareInfoDict, args):
"""
- gets and lists all of the firmware in the system.
-
+ gets and lists all of the firmware in the system.
+
@return: returns a string containing all of the firmware information
"""
output = ""
@@ -2032,36 +2032,36 @@
for subkey in firmwareInfoDict[key]:
firmwareInfoDict[key][subkey]['ExtendedVersion'] = str(firmwareInfoDict[key][subkey]['ExtendedVersion'])
if not args.verbose:
- output = "---Running Images---\n"
+ output = "---Running Images---\n"
colNames = ["Purpose", "Version", "ID"]
keylist = ["Purpose", "Version", "ID"]
output += tableDisplay(keylist, colNames, firmwareInfoDict["Functional"])
if "Activated" in firmwareInfoDict:
- output += "\n---Available Images---\n"
+ output += "\n---Available Images---\n"
output += tableDisplay(keylist, colNames, firmwareInfoDict["Activated"])
if "NeedsActivated" in firmwareInfoDict:
- output += "\n---Needs Activated Images---\n"
+ output += "\n---Needs Activated Images---\n"
output += tableDisplay(keylist, colNames, firmwareInfoDict["NeedsActivated"])
-
+
else:
- output = "---Running Images---\n"
+ output = "---Running Images---\n"
colNames = ["Purpose", "Version", "ID", "Pending Activation", "Extended Version"]
keylist = ["Purpose", "Version", "ID", "RequestedActivation", "ExtendedVersion"]
output += tableDisplay(keylist, colNames, firmwareInfoDict["Functional"])
if "Activated" in firmwareInfoDict:
- output += "\n---Available Images---\n"
+ output += "\n---Available Images---\n"
output += tableDisplay(keylist, colNames, firmwareInfoDict["Activated"])
if "NeedsActivated" in firmwareInfoDict:
- output += "\n---Needs Activated Images---\n"
+ output += "\n---Needs Activated Images---\n"
output += tableDisplay(keylist, colNames, firmwareInfoDict["NeedsActivated"])
return output
else:
return str(json.dumps(firmwareInfoDict, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False))
-def firmwareList(host, args, session):
+def firmwareList(host, args, session):
"""
- gets and lists all of the firmware in the system.
-
+ gets and lists all of the firmware in the system.
+
@return: returns a string containing all of the firmware information
"""
httpHeader = {'Content-Type':'application/json'}
@@ -2071,22 +2071,22 @@
except(requests.exceptions.Timeout):
return(connectionErrHandler(args.json, "Timeout", None))
firmwareDict = json.loads(res.text)
-
+
#sort the received information
firmwareInfoDict = parseFWdata(firmwareDict)
-
+
#display the information
return displayFWInvenory(firmwareInfoDict, args)
-
-
+
+
def restLogging(host, args, session):
"""
Called by the logging function. Turns REST API logging on/off.
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the logging sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
"""
url="https://"+host+"/xyz/openbmc_project/logging/rest_api_logs/attr/Enabled"
@@ -2109,11 +2109,11 @@
def remoteLogging(host, args, session):
"""
Called by the logging function. View config information for/disable remote logging (rsyslog).
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the logging sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
"""
url="https://"+host+"/xyz/openbmc_project/logging/config/remote"
@@ -2135,11 +2135,11 @@
def remoteLoggingConfig(host, args, session):
"""
Called by the logging function. Configures remote logging (rsyslog).
-
+
@param host: string, the hostname or IP address of the bmc
@param args: contains additional arguments used by the logging sub command
@param session: the active session to use
- @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
+ @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption
"""
url="https://"+host+"/xyz/openbmc_project/logging/config/remote"
@@ -2273,9 +2273,9 @@
def createCommandParser():
"""
creates the parser for the command line along with help for each command and subcommand
-
+
@return: returns the parser for the command line
- """
+ """
parser = argparse.ArgumentParser(description='Process arguments')
parser.add_argument("-H", "--host", help='A hostname or IP for the BMC')
parser.add_argument("-U", "--user", help='The username to login with')
@@ -2288,7 +2288,7 @@
parser.add_argument('-T', '--procTime', action='store_true', help= argparse.SUPPRESS)
parser.add_argument('-V', '--version', action='store_true', help='Display the version number of the openbmctool')
subparsers = parser.add_subparsers(title='subcommands', description='valid subcommands',help="sub-command help", dest='command')
-
+
#fru command
parser_inv = subparsers.add_parser("fru", help='Work with platform inventory')
inv_subparser = parser_inv.add_subparsers(title='subcommands', description='valid inventory actions', help="valid inventory actions", dest='command')
@@ -2304,7 +2304,7 @@
inv_status = inv_subparser.add_parser("status", help="prints out the status of all FRUs")
inv_status.add_argument('-v', '--verbose', action='store_true', help='Verbose output')
inv_status.set_defaults(func=fruStatus)
-
+
#sensors command
parser_sens = subparsers.add_parser("sensors", help="Work with platform sensors")
sens_subparser=parser_sens.add_subparsers(title='subcommands', description='valid sensor actions', help='valid sensor actions', dest='command')
@@ -2316,8 +2316,8 @@
sens_list=sens_subparser.add_parser("list", help="Lists all Sensors in the platform. Specify a sensor for full details. ")
sens_list.add_argument("sensNum", nargs='?', help="The Sensor number to get full details on" )
sens_list.set_defaults(func=sensor)
-
-
+
+
#sel command
parser_sel = subparsers.add_parser("sel", help="Work with platform alerts")
sel_subparser = parser_sel.add_subparsers(title='subcommands', description='valid SEL actions', help = 'valid SEL actions', dest='command')
@@ -2328,73 +2328,73 @@
sel_print.add_argument('-v', '--verbose', action='store_true', help="Changes the output to being very verbose")
sel_print.add_argument('-f', '--fileloc', help='Parse a file instead of the BMC output')
sel_print.set_defaults(func=selPrint)
-
+
#sel list
sel_list = sel_subparser.add_parser("list", help="Lists all SELs in the platform. Specifying a specific number will pull all the details for that individual SEL")
sel_list.add_argument("selNum", nargs='?', type=int, help="The SEL entry to get details on")
sel_list.set_defaults(func=selList)
-
+
sel_get = sel_subparser.add_parser("get", help="Gets the verbose details of a specified SEL entry")
sel_get.add_argument('selNum', type=int, help="the number of the SEL entry to get")
sel_get.set_defaults(func=selList)
-
+
sel_clear = sel_subparser.add_parser("clear", help="Clears all entries from the SEL")
sel_clear.set_defaults(func=selClear)
-
+
sel_setResolved = sel_subparser.add_parser("resolve", help="Sets the sel entry to resolved")
sel_setResolved.add_argument('-n', '--selNum', type=int, help="the number of the SEL entry to resolve")
sel_ResolveAll_sub = sel_setResolved.add_subparsers(title='subcommands', description='valid subcommands',help="sub-command help", dest='command')
sel_ResolveAll = sel_ResolveAll_sub.add_parser('all', help='Resolve all SEL entries')
sel_ResolveAll.set_defaults(func=selResolveAll)
sel_setResolved.set_defaults(func=selSetResolved)
-
+
parser_chassis = subparsers.add_parser("chassis", help="Work with chassis power and status")
chas_sub = parser_chassis.add_subparsers(title='subcommands', description='valid subcommands',help="sub-command help", dest='command')
-
+
parser_chassis.add_argument('status', action='store_true', help='Returns the current status of the platform')
parser_chassis.set_defaults(func=chassis)
-
+
parser_chasPower = chas_sub.add_parser("power", help="Turn the chassis on or off, check the power state")
parser_chasPower.add_argument('powcmd', choices=['on','softoff', 'hardoff', 'status'], help='The value for the power command. on, off, or status')
parser_chasPower.set_defaults(func=chassisPower)
-
+
#control the chassis identify led
parser_chasIdent = chas_sub.add_parser("identify", help="Control the chassis identify led")
parser_chasIdent.add_argument('identcmd', choices=['on', 'off', 'status'], help='The control option for the led: on, off, blink, status')
parser_chasIdent.set_defaults(func=chassisIdent)
-
+
#collect service data
parser_servData = subparsers.add_parser("collect_service_data", help="Collect all bmc data needed for service")
parser_servData.add_argument('-d', '--devdebug', action='store_true', help=argparse.SUPPRESS)
parser_servData.set_defaults(func=collectServiceData)
-
+
#system quick health check
parser_healthChk = subparsers.add_parser("health_check", help="Work with platform sensors")
parser_healthChk.set_defaults(func=healthCheck)
-
+
#work with bmc dumps
parser_bmcdump = subparsers.add_parser("dump", help="Work with bmc dump files")
bmcDump_sub = parser_bmcdump.add_subparsers(title='subcommands', description='valid subcommands',help="sub-command help", dest='command')
bmcDump_sub.required = True
dump_Create = bmcDump_sub.add_parser('create', help="Create a bmc dump")
dump_Create.set_defaults(func=bmcDumpCreate)
-
+
dump_list = bmcDump_sub.add_parser('list', help="list all bmc dump files")
dump_list.set_defaults(func=bmcDumpList)
-
+
parserdumpdelete = bmcDump_sub.add_parser('delete', help="Delete bmc dump files")
parserdumpdelete.add_argument("-n", "--dumpNum", nargs='*', type=int, help="The Dump entry to delete")
parserdumpdelete.set_defaults(func=bmcDumpDelete)
-
+
bmcDumpDelsub = parserdumpdelete.add_subparsers(title='subcommands', description='valid subcommands',help="sub-command help", dest='command')
deleteAllDumps = bmcDumpDelsub.add_parser('all', help='Delete all bmc dump files')
deleteAllDumps.set_defaults(func=bmcDumpDeleteAll)
-
+
parser_dumpretrieve = bmcDump_sub.add_parser('retrieve', help='Retrieve a dump file')
parser_dumpretrieve.add_argument("dumpNum", type=int, help="The Dump entry to delete")
parser_dumpretrieve.add_argument("-s", "--dumpSaveLoc", help="The location to save the bmc dump file")
parser_dumpretrieve.set_defaults(func=bmcDumpRetrieve)
-
+
#bmc command for reseting the bmc
parser_bmc = subparsers.add_parser('bmc', help="Work with the bmc")
bmc_sub = parser_bmc.add_subparsers(title='subcommands', description='valid subcommands',help="sub-command help", dest='command')
@@ -2402,7 +2402,7 @@
parser_BMCReset.add_argument('type', choices=['warm','cold'], help="Warm: Reboot the BMC, Cold: CLEAR config and reboot bmc")
parser_bmc.add_argument('info', action='store_true', help="Displays information about the BMC hardware, including device revision, firmware revision, IPMI version supported, manufacturer ID, and information on additional device support.")
parser_bmc.set_defaults(func=bmc)
-
+
#add alias to the bmc command
parser_mc = subparsers.add_parser('mc', help="Work with the management controller")
mc_sub = parser_mc.add_subparsers(title='subcommands', description='valid subcommands',help="sub-command help", dest='command')
@@ -2412,40 +2412,40 @@
parser_mc.add_argument('info', action='store_true', help="Displays information about the BMC hardware, including device revision, firmware revision, IPMI version supported, manufacturer ID, and information on additional device support.")
parser_MCReset.set_defaults(func=bmcReset)
parser_mc.set_defaults(func=bmc)
-
+
#gard clear
parser_gc = subparsers.add_parser("gardclear", help="Used to clear gard records")
parser_gc.set_defaults(func=gardClear)
-
+
#firmware_flash
parser_fw = subparsers.add_parser("firmware", help="Work with the system firmware")
fwflash_subproc = parser_fw.add_subparsers(title='subcommands', description='valid firmware commands', help='sub-command help', dest='command')
fwflash_subproc.required = True
-
+
fwflash = fwflash_subproc.add_parser('flash', help="Flash the system firmware")
fwflash.add_argument('type', choices=['bmc', 'pnor'], help="image type to flash")
fwflash.add_argument('-f', '--fileloc', required=True, help="The absolute path to the firmware image")
fwflash.set_defaults(func=fwFlash)
-
+
fwActivate = fwflash_subproc.add_parser('activate', help="Activate existing image on the bmc")
fwActivate.add_argument('imageID', help="The image ID to activate from the firmware list. Ex: 63c95399")
fwActivate.set_defaults(func=activateFWImage)
-
+
fwActivateStatus = fwflash_subproc.add_parser('activation_status', help="Check Status of activations")
fwActivateStatus.set_defaults(func=activateStatus)
fwList = fwflash_subproc.add_parser('list', help="List all of the installed firmware")
fwList.add_argument('-v', '--verbose', action='store_true', help='Verbose output')
fwList.set_defaults(func=firmwareList)
-
+
fwprint = fwflash_subproc.add_parser('print', help="List all of the installed firmware")
fwprint.add_argument('-v', '--verbose', action='store_true', help='Verbose output')
fwprint.set_defaults(func=firmwareList)
-
+
#logging
parser_logging = subparsers.add_parser("logging", help="logging controls")
logging_sub = parser_logging.add_subparsers(title='subcommands', description='valid subcommands',help="sub-command help", dest='command')
-
+
#turn rest api logging on/off
parser_rest_logging = logging_sub.add_parser("rest_api", help="turn rest api logging on/off")
parser_rest_logging.add_argument('rest_logging', choices=['on', 'off'], help='The control option for rest logging: on, off')
@@ -2476,7 +2476,7 @@
certDelete.add_argument('type', choices=['server', 'client', 'authority'], help="certificate type to delete")
certDelete.add_argument('service', choices=['https', 'ldap'], help="Service to delete the certificate")
certDelete.set_defaults(func=certificateDelete)
-
+
# local users
parser_users = subparsers.add_parser("local_users", help="Work with local users")
parser_users.add_argument('local_users', choices=['disableall','enableall', 'queryenabled'], help="Disable, enable or query local user accounts")
@@ -2487,13 +2487,13 @@
def main(argv=None):
"""
- main function for running the command line utility as a sub application
- """
- global toolVersion
+ main function for running the command line utility as a sub application
+ """
+ global toolVersion
toolVersion = "1.08"
parser = createCommandParser()
args = parser.parse_args(argv)
-
+
totTimeStart = int(round(time.time()*1000))
if(sys.version_info < (3,0)):
@@ -2506,7 +2506,7 @@
if (hasattr(args, 'fileloc') and args.fileloc is not None and 'print' in args.command):
mysess = None
print(selPrint('N/A', args, mysess))
- else:
+ else:
if(hasattr(args, 'host') and hasattr(args,'user')):
if (args.askpw):
pw = getpass.getpass()
@@ -2526,14 +2526,14 @@
print(mysess)
sys.exit(1)
logintimeStop = int(round(time.time()*1000))
-
- commandTimeStart = int(round(time.time()*1000))
+
+ commandTimeStart = int(round(time.time()*1000))
output = args.func(args.host, args, mysess)
commandTimeStop = int(round(time.time()*1000))
print(output)
if (mysess is not None):
- logout(args.host, args.user, pw, mysess, args.json)
- if(args.procTime):
+ logout(args.host, args.user, pw, mysess, args.json)
+ if(args.procTime):
print("Total time: " + str(int(round(time.time()*1000))- totTimeStart))
print("loginTime: " + str(logintimeStop - logintimeStart))
print("command Time: " + str(commandTimeStop - commandTimeStart))
@@ -2544,15 +2544,15 @@
health_check,dump,bmc,mc,gardclear,firmware,logging}\n" +
"\t...\n" +
"openbmctool.py: error: the following arguments are required: -H/--host, -U/--user")
- sys.exit()
+ sys.exit()
if __name__ == '__main__':
"""
main function when called from the command line
-
- """
+
+ """
import sys
-
+
isTTY = sys.stdout.isatty()
assert sys.version_info >= (2,7)
main()