Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
2Shirt 2023-07-05 15:51:24 -07:00
commit 0af8be2c47
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
5 changed files with 52 additions and 52 deletions

View file

@ -87,11 +87,6 @@ REGEX_REMAINING_TIME = re.compile(
r'\s*(?P<na>n/a)?', r'\s*(?P<na>n/a)?',
re.IGNORECASE re.IGNORECASE
) )
PANE_RATIOS = (
12, # SMART
22, # ddrescue progress
4, # Journal (kernel messages)
)
PLATFORM = std.PLATFORM PLATFORM = std.PLATFORM
RECOMMENDED_FSTYPES = re.compile(r'^(ext[234]|ntfs|xfs)$') RECOMMENDED_FSTYPES = re.compile(r'^(ext[234]|ntfs|xfs)$')
if PLATFORM == 'Darwin': if PLATFORM == 'Darwin':
@ -2094,19 +2089,22 @@ def run_ddrescue(state, block_pair, pass_name, settings, dry_run=True) -> None:
'Press Enter to return to main menu...', end='', flush=True, 'Press Enter to return to main menu...', end='', flush=True,
) )
def _update_smart_pane() -> None: def _update_smart_panes() -> None:
"""Update SMART pane every 30 seconds.""" """Update SMART panes every 30 seconds."""
update_smart_details(state.source)
now = datetime.datetime.now(tz=TIMEZONE).strftime('%Y-%m-%d %H:%M %Z') now = datetime.datetime.now(tz=TIMEZONE).strftime('%Y-%m-%d %H:%M %Z')
with open(f'{state.log_dir}/smart.out', 'w', encoding='utf-8') as _f: for dev_str in ('source', 'destination'):
_f.write( dev = getattr(state, dev_str)
ansi.color_string( out_path = f'{state.log_dir}/smart_{dev_str}.out'
['SMART Attributes', f'Updated: {now}\n'], update_smart_details(dev)
['BLUE', 'YELLOW'], with open(out_path, 'w', encoding='utf-8') as _f:
sep='\t\t', _f.write(
), ansi.color_string(
) ['SMART Attributes', f'Updated: {now}\n'],
_f.write('\n'.join(state.source.generate_report(header=False))) ['BLUE', 'YELLOW'],
sep='\t\t',
),
)
_f.write('\n'.join(dev.generate_report(header=False)))
# Dry run # Dry run
if dry_run: if dry_run:
@ -2129,7 +2127,7 @@ def run_ddrescue(state, block_pair, pass_name, settings, dry_run=True) -> None:
while True: while True:
if _i % 30 == 0: if _i % 30 == 0:
# Update SMART pane # Update SMART pane
_update_smart_pane() _update_smart_panes()
# Check destination # Check destination
warning_message = check_destination_health(state.destination) warning_message = check_destination_health(state.destination)
@ -2226,7 +2224,12 @@ def run_recovery(state: State, main_menu, settings_menu, dry_run=True) -> None:
state.ui.add_info_pane( state.ui.add_info_pane(
percent=50, percent=50,
update_layout=False, update_layout=False,
watch_file=f'{state.log_dir}/smart.out', watch_file=f'{state.log_dir}/smart_source.out',
)
state.ui.add_info_pane(
percent=50,
update_layout=False,
watch_file=f'{state.log_dir}/smart_destination.out',
) )
if PLATFORM == 'Linux': if PLATFORM == 'Linux':
state.ui.add_worker_pane(lines=4, cmd='journal-datarec-monitor') state.ui.add_worker_pane(lines=4, cmd='journal-datarec-monitor')

View file

@ -56,18 +56,12 @@ class Disk:
ssd: bool = field(init=False) ssd: bool = field(init=False)
tests: list[Test] = field(init=False, default_factory=list) tests: list[Test] = field(init=False, default_factory=list)
trim: bool = field(init=False) trim: bool = field(init=False)
use_sat: bool = field(init=False, default=False)
def __post_init__(self): def __post_init__(self):
self.path = pathlib.Path(self.path_str).resolve() self.path = pathlib.Path(self.path_str).resolve()
self.update_details() self.update_details()
self.set_description() self.set_description()
self.known_attributes = get_known_disk_attributes(self.model) self.known_attributes = get_known_disk_attributes(self.model)
if not self.attributes and self.bus == 'USB':
# Try using SAT
LOG.warning('Using SAT for smartctl for %s', self.path)
self.notes = []
self.use_sat = True
self.initial_attributes = copy.deepcopy(self.attributes) self.initial_attributes = copy.deepcopy(self.attributes)
if not self.is_4k_aligned(): if not self.is_4k_aligned():
self.add_note('One or more partitions are not 4K aligned', 'YELLOW') self.add_note('One or more partitions are not 4K aligned', 'YELLOW')

View file

@ -104,7 +104,7 @@ def enable_smart(dev) -> None:
cmd = [ cmd = [
'sudo', 'sudo',
'smartctl', 'smartctl',
f'--device={"sat,auto" if dev.use_sat else "auto"}', '--device=auto',
'--tolerance=permissive', '--tolerance=permissive',
'--smart=on', '--smart=on',
dev.path, dev.path,
@ -461,7 +461,7 @@ def update_smart_details(dev) -> None:
cmd = [ cmd = [
'sudo', 'sudo',
'smartctl', 'smartctl',
f'--device={"sat,auto" if dev.use_sat else "auto"}', '--device=auto',
'--tolerance=verypermissive', '--tolerance=verypermissive',
'--all', '--all',
'--json', '--json',

View file

@ -73,7 +73,7 @@ def fix_layout(
avail_vertical -= layout[group].get('height', 0) + 1 avail_vertical -= layout[group].get('height', 0) + 1
num_workers = len(layout['Workers']['Panes']) num_workers = len(layout['Workers']['Panes'])
avail_vertical -= num_workers * (layout['Workers'].get('height', 0) + 1) avail_vertical -= num_workers * (layout['Workers'].get('height', 0) + 1)
avail_horizontal -= layout['Started']['width'] + 1 avail_horizontal -= layout['Progress']['width'] + 1
# Fix heights # Fix heights
for group, data in layout.items(): for group, data in layout.items():
@ -89,16 +89,17 @@ def fix_layout(
) )
# Fix widths # Fix widths
for group in ('Started', 'Progress'): resize_kwargs.append(
resize_kwargs.append( {'pane_id': layout['Progress']['Panes'][0], 'width': layout['Progress']['width']}
{'pane_id': layout[group]['Panes'][0], 'width': layout[group]['width']} )
) resize_kwargs.append(
{'pane_id': layout['Started']['Panes'][0], 'height': layout['Started']['height']}
)
for group, data in layout.items(): for group, data in layout.items():
num_panes = len(data['Panes']) num_panes = len(data['Panes'])
if num_panes < 2 or group not in ('Title', 'Subtitle', 'Info'): if num_panes < 2 or group not in ('Title', 'Subtitle', 'Info'):
continue continue
avail_horizontal -= (num_panes - 1) pane_width, remainder = divmod(avail_horizontal - (num_panes-1), num_panes)
pane_width, remainder = divmod(avail_horizontal, num_panes)
for pane_id in data['Panes']: for pane_id in data['Panes']:
new_width = pane_width new_width = pane_width
if remainder > 0: if remainder > 0:

View file

@ -23,7 +23,7 @@ TMUX_LAYOUT = { # NOTE: This needs to be in order from top to bottom
'Info': {'Panes': []}, 'Info': {'Panes': []},
'Current': {'Panes': [environ.get('TMUX_PANE', None)]}, 'Current': {'Panes': [environ.get('TMUX_PANE', None)]},
'Workers': {'Panes': []}, 'Workers': {'Panes': []},
'Started': {'Panes': [], 'width': TMUX_SIDE_WIDTH}, 'Started': {'Panes': [], 'height': TMUX_TITLE_HEIGHT},
'Progress': {'Panes': [], 'width': TMUX_SIDE_WIDTH}, 'Progress': {'Panes': [], 'width': TMUX_SIDE_WIDTH},
} }
@ -204,6 +204,25 @@ class TUI():
self.layout.clear() self.layout.clear()
self.layout.update(deepcopy(TMUX_LAYOUT)) self.layout.update(deepcopy(TMUX_LAYOUT))
# Progress
self.layout['Progress']['Panes'].append(tmux.split_window(
lines=TMUX_SIDE_WIDTH,
text=' ',
))
# Started
self.layout['Started']['Panes'].append(tmux.split_window(
behind=True,
lines=2,
target_id=self.layout['Progress']['Panes'][0],
text=ansi.color_string(
['Started', time.strftime("%Y-%m-%d %H:%M %Z")],
['BLUE', None],
sep='\n',
),
vertical=True,
))
# Title # Title
self.layout['Title']['Panes'].append(tmux.split_window( self.layout['Title']['Panes'].append(tmux.split_window(
behind=True, behind=True,
@ -216,23 +235,6 @@ class TUI():
), ),
)) ))
# Started
self.layout['Started']['Panes'].append(tmux.split_window(
lines=TMUX_SIDE_WIDTH,
target_id=self.layout['Title']['Panes'][0],
text=ansi.color_string(
['Started', time.strftime("%Y-%m-%d %H:%M %Z")],
['BLUE', None],
sep='\n',
),
))
# Progress
self.layout['Progress']['Panes'].append(tmux.split_window(
lines=TMUX_SIDE_WIDTH,
text=' ',
))
def remove_all_info_panes(self) -> None: def remove_all_info_panes(self) -> None:
"""Remove all info panes and update layout.""" """Remove all info panes and update layout."""
self.layout['Info'].pop('height', None) self.layout['Info'].pop('height', None)