Add 'Secret Menu' to HW-Diags

*Begrudgingly
This commit is contained in:
2Shirt 2024-03-28 20:43:38 -07:00
parent 35286ddb8b
commit 13785ab502
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
3 changed files with 57 additions and 12 deletions

View file

@ -14,6 +14,7 @@ ATTRIBUTE_COLORS = (
# NOTE: Force 4K read block size for disks >= 3TB # NOTE: Force 4K read block size for disks >= 3TB
BADBLOCKS_EXTRA_LARGE_DISK = 15 * 1024**4 BADBLOCKS_EXTRA_LARGE_DISK = 15 * 1024**4
BADBLOCKS_LARGE_DISK = 3 * 1024**4 BADBLOCKS_LARGE_DISK = 3 * 1024**4
BADBLOCKS_MAX_ERRORS = 1
BADBLOCKS_REGEX = re.compile( BADBLOCKS_REGEX = re.compile(
r'^Pass completed, (\d+) bad blocks found. .(\d+)/(\d+)/(\d+) errors', r'^Pass completed, (\d+) bad blocks found. .(\d+)/(\d+)/(\d+) errors',
re.IGNORECASE, re.IGNORECASE,

View file

@ -11,7 +11,7 @@ import subprocess
from docopt import docopt from docopt import docopt
from wk import cfg, debug, exe, log, osticket, std from wk import cfg, debug, exe, log, osticket, std
from wk.cfg.hw import STATUS_COLORS from wk.cfg.hw import CPU_TEST_MINUTES, STATUS_COLORS
from wk.hw import benchmark as hw_benchmark from wk.hw import benchmark as hw_benchmark
from wk.hw import cpu as hw_cpu from wk.hw import cpu as hw_cpu
from wk.hw import disk as hw_disk from wk.hw import disk as hw_disk
@ -42,12 +42,6 @@ Options:
-h --help Show this page -h --help Show this page
-q --quick Skip menu and perform a quick check -q --quick Skip menu and perform a quick check
-t --test-mode Run diags in test mode -t --test-mode Run diags in test mode
--ignore-smart-errors NOT RECOMMENDED!
Only use if you have RTFM,
know what you're doing,
understand the risks,
and accept responsibililty.
''' '''
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
IO_SIZE_SKIP_NAME = ( IO_SIZE_SKIP_NAME = (
@ -77,7 +71,13 @@ MENU_ACTIONS = (
MENU_ACTIONS_SECRET = ( MENU_ACTIONS_SECRET = (
'Matrix', 'Matrix',
'Tubes', 'Tubes',
'?Secrets',
) )
MENU_OPTIONS_SECRET = {
'Ignore SMART errors': False,
'Override CPU Testing Time (minutes)': CPU_TEST_MINUTES,
'Override Surface Scan Error Limit': 1,
}
MENU_OPTIONS_QUICK = ('Disk Attributes',) MENU_OPTIONS_QUICK = ('Disk Attributes',)
MENU_SETS = { MENU_SETS = {
'Full Diagnostic': (*TEST_GROUPS,), 'Full Diagnostic': (*TEST_GROUPS,),
@ -107,6 +107,7 @@ class State():
self.log_dir: pathlib.Path | None = None self.log_dir: pathlib.Path | None = None
self.ost = osticket.osTicket() self.ost = osticket.osTicket()
self.progress_file: pathlib.Path | None = None self.progress_file: pathlib.Path | None = None
self.secret_menu = build_secret_menu()
self.sensors: hw_sensors.Sensors = hw_sensors.Sensors() self.sensors: hw_sensors.Sensors = hw_sensors.Sensors()
self.system: hw_system.System | None = None self.system: hw_system.System | None = None
self.test_groups: list[TestGroup] = [] self.test_groups: list[TestGroup] = []
@ -370,6 +371,24 @@ def build_menu(cli_mode=False, quick_mode=False) -> cli.Menu:
return menu return menu
def build_secret_menu() -> cli.Menu:
title_text = [
ansi.color_string(('Expert Settings', "(It's a secret to everyone!)"), ('ORANGE', None)),
' ',
ansi.color_string(
[' !!', 'These settings can cause', 'MAJOR DAMAGE', 'to systems'],
[None, 'YELLOW', 'RED', 'YELLOW'],
),
' !! Please read the manual before making changes',
' ',
]
menu = cli.Menu(title='\n'.join(title_text))
for option, value in MENU_OPTIONS_SECRET.items():
menu.add_option(option, {'Selected': False, 'Value': value})
menu.add_action('Main Menu')
return menu
def cpu_tests_init(state: State) -> None: def cpu_tests_init(state: State) -> None:
"""Initialize CPU tests.""" """Initialize CPU tests."""
sensors_out = pathlib.Path(f'{state.log_dir}/sensors.out') sensors_out = pathlib.Path(f'{state.log_dir}/sensors.out')
@ -426,6 +445,11 @@ def cpu_test_mprime(state: State, test_object, test_mode=False) -> None:
test_minutes = cfg.hw.CPU_TEST_MINUTES test_minutes = cfg.hw.CPU_TEST_MINUTES
if test_mode: if test_mode:
test_minutes = cfg.hw.TEST_MODE_CPU_LIMIT test_minutes = cfg.hw.TEST_MODE_CPU_LIMIT
if state.secret_menu.options.get(
'Override CPU Testing Time (minutes)')['Selected']:
test_minutes = int(
state.secret_menu.options.get('Override CPU Testing Time (minutes)')['Value'],
)
# Bail early # Bail early
if test_object.disabled: if test_object.disabled:
@ -502,6 +526,11 @@ def cpu_test_sysbench(state: State, test_object, test_mode=False) -> None:
test_minutes = cfg.hw.CPU_TEST_MINUTES test_minutes = cfg.hw.CPU_TEST_MINUTES
if test_mode: if test_mode:
test_minutes = cfg.hw.TEST_MODE_CPU_LIMIT test_minutes = cfg.hw.TEST_MODE_CPU_LIMIT
if state.secret_menu.options.get(
'Override CPU Testing Time (minutes)')['Selected']:
test_minutes = int(
state.secret_menu.options.get('Override CPU Testing Time (minutes)')['Value'],
)
# Bail early # Bail early
if test_object.disabled: if test_object.disabled:
@ -758,7 +787,12 @@ def disk_surface_scan(state: State, test_objects, test_mode=False) -> None:
"""Read-only disk surface scan using badblocks.""" """Read-only disk surface scan using badblocks."""
LOG.info('Disk Surface Scan (badblocks)') LOG.info('Disk Surface Scan (badblocks)')
aborted = False aborted = False
max_errors = 1
threads = [] threads = []
if state.secret_menu.options.get(
'Override Surface Scan Error Limit')['Selected']:
max_errors = state.secret_menu.options.get(
'Override Surface Scan Error Limit')['Value']
# Update panes # Update panes
state.update_title_text( state.update_title_text(
@ -775,7 +809,7 @@ def disk_surface_scan(state: State, test_objects, test_mode=False) -> None:
# Start thread # Start thread
test_log = f'{state.log_dir}/{test.dev.path.name}_badblocks.log' test_log = f'{state.log_dir}/{test.dev.path.name}_badblocks.log'
threads.append(exe.start_thread( threads.append(exe.start_thread(
hw_surface_scan.run_scan, args=(test, test_log, test_mode), hw_surface_scan.run_scan, args=(test, test_log, test_mode, max_errors),
)) ))
# Show progress # Show progress
@ -832,7 +866,6 @@ def main() -> None:
# Init # Init
menu = build_menu(cli_mode=args['--cli'], quick_mode=args['--quick']) menu = build_menu(cli_mode=args['--cli'], quick_mode=args['--quick'])
state = State(test_mode=args['--test-mode']) state = State(test_mode=args['--test-mode'])
state.override_all_smart_errors = args['--ignore-smart-errors']
# Quick Mode # Quick Mode
if args['--quick']: if args['--quick']:
@ -868,9 +901,11 @@ def main() -> None:
state.ui.update_clock() state.ui.update_clock()
# Secrets # Secrets
if '?Secrets' in selection:
state.secret_menu.settings_select()
if 'Matrix' in selection: if 'Matrix' in selection:
screensaver('matrix') screensaver('matrix')
elif 'Tubes' in selection: if 'Tubes' in selection:
# Tubes ≈≈ Pipes? # Tubes ≈≈ Pipes?
screensaver('pipes') screensaver('pipes')

View file

@ -70,7 +70,7 @@ def check_surface_scan_results(test_obj, log_path) -> None:
test_obj.set_status('Unknown') test_obj.set_status('Unknown')
def run_scan(test_obj, log_path, test_mode=False) -> None: def run_scan(test_obj, log_path, test_mode=False, max_errors=1) -> None:
"""Run surface scan and handle exceptions.""" """Run surface scan and handle exceptions."""
block_size = '1024' block_size = '1024'
dev = test_obj.dev dev = test_obj.dev
@ -89,8 +89,17 @@ def run_scan(test_obj, log_path, test_mode=False) -> None:
or dev.size >= BADBLOCKS_LARGE_DISK): or dev.size >= BADBLOCKS_LARGE_DISK):
block_size = '4096' block_size = '4096'
# Max errors
if int(max_errors) <= 0:
max_errors = ''
else:
max_errors = f'-e{max_errors}'
# Start scan # Start scan
cmd = ['sudo', 'badblocks', '-sv', '-b', block_size, '-e', '1', dev_path] cmd = ['sudo', 'badblocks', '-sv', '-b', block_size]
if max_errors:
cmd.append(max_errors)
cmd.append(dev_path)
if test_mode: if test_mode:
# Only test a limited scope instead of the whole device # Only test a limited scope instead of the whole device
cmd.append(TEST_MODE_BADBLOCKS_LIMIT) cmd.append(TEST_MODE_BADBLOCKS_LIMIT)