Add 'Secret Menu' to HW-Diags
*Begrudgingly
This commit is contained in:
parent
35286ddb8b
commit
13785ab502
3 changed files with 57 additions and 12 deletions
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue