Added Disk().generate_report()

* Uses new merged ATTRIBUTES config
This commit is contained in:
2Shirt 2019-10-28 20:15:58 -06:00
parent fbb480dae6
commit c7090e77c2
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
3 changed files with 116 additions and 4 deletions

View file

@ -1,5 +1,6 @@
"""WizardKit: cfg module init"""
from wk.cfg import hw
from wk.cfg import log
from wk.cfg import main
from wk.cfg import net

34
scripts/wk/cfg/hw.py Normal file
View file

@ -0,0 +1,34 @@
"""WizardKit: Config - Hardware"""
# pylint: disable=bad-whitespace,line-too-long
# vim: sts=2 sw=2 ts=2
ATTRIBUTES = {
# NVMe
'critical_warning': {'Critical': True, 'Ignore': False, 'Warning': None, 'Error': 1, 'Maximum': None, },
'media_errors': {'Critical': False, 'Ignore': False, 'Warning': None, 'Error': 1, 'Maximum': None, },
'power_on_hours': {'Critical': False, 'Ignore': True, 'Warning': 17532, 'Error': 26298, 'Maximum': None, },
'unsafe_shutdowns': {'Critical': False, 'Ignore': True, 'Warning': 1, 'Error': None, 'Maximum': None, },
# SMART
5: {'Hex': '05', 'Critical': True, 'Ignore': False, 'Warning': None, 'Error': 1, 'Maximum': None, },
9: {'Hex': '09', 'Critical': False, 'Ignore': True, 'Warning': 17532, 'Error': 26298, 'Maximum': None, },
10: {'Hex': '10', 'Critical': False, 'Ignore': False, 'Warning': 1, 'Error': 10, 'Maximum': 10000, },
184: {'Hex': 'B8', 'Critical': False, 'Ignore': False, 'Warning': 1, 'Error': 10, 'Maximum': 10000, },
187: {'Hex': 'BB', 'Critical': False, 'Ignore': False, 'Warning': 1, 'Error': 10, 'Maximum': 10000, },
188: {'Hex': 'BC', 'Critical': False, 'Ignore': False, 'Warning': 1, 'Error': 10, 'Maximum': 10000, },
196: {'Hex': 'C4', 'Critical': False, 'Ignore': False, 'Warning': 1, 'Error': 10, 'Maximum': 10000, },
197: {'Hex': 'C5', 'Critical': True, 'Ignore': False, 'Warning': None, 'Error': 1, 'Maximum': None, },
198: {'Hex': 'C6', 'Critical': True, 'Ignore': False, 'Warning': None, 'Error': 1, 'Maximum': None, },
199: {'Hex': 'C7', 'Critical': False, 'Ignore': True, 'Warning': None, 'Error': 1, 'Maximum': None, },
201: {'Hex': 'C9', 'Critical': False, 'Ignore': False, 'Warning': None, 'Error': 1, 'Maximum': 10000, },
}
ATTRIBUTE_COLORS = (
# NOTE: Ordered by ascending importance
('Warning', 'YELLOW'),
('Error', 'RED'),
('Maximum', 'PURPLE'),
)
if __name__ == '__main__':
print("This file is not meant to be called directly.")

View file

@ -1,4 +1,4 @@
"""WizardKit: Hardware objects (mostly)."""
"""WizardKit: Hardware objects (mostly)"""
# vim: sts=2 sw=2 ts=2
import logging
@ -9,6 +9,7 @@ import re
from collections import OrderedDict
from wk.cfg.hw import ATTRIBUTES, ATTRIBUTE_COLORS
from wk.exe import get_json_from_command, run_program
from wk.std import bytes_to_string, color_string, string_to_bytes
@ -93,8 +94,8 @@ class CpuRam():
f'{count}x {desc}' for desc, count in sorted(details.items())
]
def generate_cpu_report(self):
"""Generate CPU report with data from all tests."""
def generate_report(self):
"""Generate CPU & RAM report, returns list."""
report = []
report.append(color_string('Device', 'BLUE'))
report.append(f' {self.description}')
@ -116,7 +117,7 @@ class Disk():
self.attributes = {}
self.description = 'Unknown'
self.details = {}
self.nvme_smart_notes = {}
self.notes = {}
self.path = pathlib.Path(path).resolve()
self.smartctl = {}
self.tests = OrderedDict()
@ -137,6 +138,77 @@ class Disk():
]
run_program(cmd, check=False)
def generate_attribute_report(self):
"""Generate attribute report, returns list."""
report = []
for attr, value in sorted(self.attributes.items()):
note = ''
value_color = 'GREEN'
# Skip attributes not in our list
if attr not in ATTRIBUTES:
continue
# ID / Name
label = f'{attr:>3}'
if isinstance(attr, int):
# Assuming SMART, include hex ID and name
label += f' / {str(hex(attr))[2:].upper():0>2}: {value["name"]}'
label = f' {label.replace("_", " "):38}'
# Value color
for threshold, color in ATTRIBUTE_COLORS:
if value['raw'] >= ATTRIBUTES.get(threshold, float('inf')):
value_color = color
if threshold == 'Maximum':
note = '(invalid?)'
# 199/C7 warning
if str(attr) == '199' and value['raw'] > 0:
note = '(bad cable?)'
# Build colored string and append to report
line = color_string(
[label, value['raw_str'], note],
[None, value_color, 'YELLOW'],
)
report.append(line)
# Done
return report
def generate_report(self):
"""Generate Disk report, returns list."""
report = []
report.append(color_string(f'Device {self.path.name}', 'BLUE'))
report.append(f' {self.description}')
# Attributes
if self.attributes:
report.append(color_string('Attributes', 'BLUE'))
report.extend(self.generate_attribute_report())
else:
report.append(
color_string(' No NVMe or SMART data available', 'YELLOW'))
# Notes
if self.notes:
report.append(color_string('Notes', 'BLUE'))
for note in sorted(self.notes.keys()):
report.append(f' {note}')
# 4K alignment check
if not self.is_4k_aligned():
report.append(color_string('Warning', 'YELLOW'))
report.append(' One or more partitions are not 4K aligned')
# Tests
for test in self.tests.values():
report.extend(test.report)
return report
def get_details(self):
"""Get disk details using OS specific methods.
@ -187,6 +259,11 @@ class Disk():
# Done
return labels
def is_4k_aligned(self):
"""Check that all disk partitions are aligned, returns bool."""
#TODO: Make real
return True
def update_smart_details(self):
"""Update SMART details via smartctl."""
self.attributes = {}