WizardKit/.bin/Scripts/debug/hw_diags.py

186 lines
4.4 KiB
Python

# Wizard Kit: Debug - HW Diagnostics
import base64
import requests
from functions.common import *
def debug_report_cpu(cpu_obj):
"""Generate report for CpuObj, returns list."""
report = []
# CPU Info
report.append('CPU: {}'.format(cpu_obj.name))
report.append('lscpu:')
for k, v in sorted(cpu_obj.lscpu.items()):
report.append(' {}: {}'.format(k, v))
# Tests
report.append('Tests:')
for k, v in cpu_obj.tests.items():
report.extend(debug_report_test(v, k))
# Done
return report
def debug_report_disk(disk_obj):
"""Generate report for DiskObj, returns list."""
report = []
expand = [
'lsblk',
'nvme_attributes',
'nvme_smart_notes',
'smart_attributes',
'smart_self_test',
'smartctl',
]
skip = [
'add_nvme_smart_note',
'calc_io_dd_values',
'check_attributes',
'check_smart_self_test',
'description',
'disable_test',
'generate_attribute_report',
'generate_disk_report',
'get_details',
'get_size',
'get_smart_details',
'name',
'safety_check',
'tests',
]
# Disk Info
report.append('Disk: {} {}'.format(
disk_obj.name, disk_obj.description))
for a in dir(disk_obj):
if a.startswith('_') or a in skip:
continue
if a in expand:
report.append('{}:'.format(a))
attr = getattr(disk_obj, a)
try:
for k, v in sorted(attr.items()):
report.append(' {}: {}'.format(k, v))
except Exception:
# Ignore
pass
else:
report.append('{}: {}'.format(a, getattr(disk_obj, a)))
# Tests
report.append('Tests:')
for k, v in disk_obj.tests.items():
report.extend(debug_report_test(v, k))
# Done
return report
def debug_report_state(state):
"""Generate report for State, returns list."""
report = []
# Devs
report.append('CPU: {}'.format(state.cpu))
report.append('Disks: {}'.format(state.disks))
# Settings
report.append('Progress Out: {}'.format(state.progress_out))
report.append('Quick Mode: {}'.format(state.quick_mode))
# Tests
report.append('Tests:')
for k, v in state.tests.items():
report.append(' {}:'.format(k))
for k2, v2 in sorted(v.items()):
report.append(' {}: {}'.format(k2, v2))
# tmux
if hasattr(state, 'tmux_layout'):
report.append('tmux Layout:')
for k, v in state.tmux_layout.items():
report.append(' {}: {}'.format(k, str(v)))
if hasattr(state, 'panes'):
report.append('tmux Panes:')
for k, v in state.panes.items():
report.append(' {}: {}'.format(k, str(v)))
# Done
return report
def debug_report_test(test_obj, test_name):
"""Generate report for TestObj, returns list."""
report = [' {}:'.format(test_name)]
skip = ['update_status']
# Attributes
for a in [a for a in dir(test_obj) if not a.startswith('_')]:
if a in skip:
continue
report.append(' {}: {}'.format(a, getattr(test_obj, a)))
# Done
return report
def save_debug_reports(state, global_vars):
"""Save debug reports if possible."""
debug_dest = '{}/debug'.format(global_vars['LogDir'])
os.makedirs(debug_dest, exist_ok=True)
# State
with open('{}/state.report'.format(debug_dest), 'a') as f:
for line in debug_report_state(state):
f.write('{}\n'.format(line))
# CPU
with open('{}/cpu.report'.format(debug_dest), 'a') as f:
for line in debug_report_cpu(state.cpu):
f.write('{}\n'.format(line))
# Disk(s)
for disk in state.disks:
with open('{}/disk_{}.report'.format(debug_dest, disk.name), 'a') as f:
for line in debug_report_disk(disk):
f.write('{}\n'.format(line))
def upload_logdir(global_vars, reason='Crash'):
"""Upload compressed LogDir to CRASH_SERVER."""
source = global_vars['LogDir']
source = source[source.rfind('/')+1:]
dest = 'HW-Diags_{reason}_{Date-Time}.txz'.format(
reason=reason,
**global_vars,
)
data = None
# Compress LogDir
os.chdir('{}/..'.format(global_vars['LogDir']))
cmd = ['tar', 'caf', dest, source]
run_program(cmd)
# Read file
with open(dest, 'rb') as f:
data = f.read()
# Upload data
url = '{}/{}'.format(CRASH_SERVER['Url'], dest)
r = requests.put(
url,
data=data,
headers={'X-Requested-With': 'XMLHttpRequest'},
auth=(CRASH_SERVER['User'], CRASH_SERVER['Pass']))
# Raise exception if upload NS
if not r.ok:
raise GenericError
if __name__ == '__main__':
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2