Merge remote-tracking branch 'upstream/dev' into dev
This commit is contained in:
commit
0af8be2c47
5 changed files with 52 additions and 52 deletions
|
|
@ -87,11 +87,6 @@ REGEX_REMAINING_TIME = re.compile(
|
|||
r'\s*(?P<na>n/a)?',
|
||||
re.IGNORECASE
|
||||
)
|
||||
PANE_RATIOS = (
|
||||
12, # SMART
|
||||
22, # ddrescue progress
|
||||
4, # Journal (kernel messages)
|
||||
)
|
||||
PLATFORM = std.PLATFORM
|
||||
RECOMMENDED_FSTYPES = re.compile(r'^(ext[234]|ntfs|xfs)$')
|
||||
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,
|
||||
)
|
||||
|
||||
def _update_smart_pane() -> None:
|
||||
"""Update SMART pane every 30 seconds."""
|
||||
update_smart_details(state.source)
|
||||
def _update_smart_panes() -> None:
|
||||
"""Update SMART panes every 30 seconds."""
|
||||
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:
|
||||
_f.write(
|
||||
ansi.color_string(
|
||||
['SMART Attributes', f'Updated: {now}\n'],
|
||||
['BLUE', 'YELLOW'],
|
||||
sep='\t\t',
|
||||
),
|
||||
)
|
||||
_f.write('\n'.join(state.source.generate_report(header=False)))
|
||||
for dev_str in ('source', 'destination'):
|
||||
dev = getattr(state, dev_str)
|
||||
out_path = f'{state.log_dir}/smart_{dev_str}.out'
|
||||
update_smart_details(dev)
|
||||
with open(out_path, 'w', encoding='utf-8') as _f:
|
||||
_f.write(
|
||||
ansi.color_string(
|
||||
['SMART Attributes', f'Updated: {now}\n'],
|
||||
['BLUE', 'YELLOW'],
|
||||
sep='\t\t',
|
||||
),
|
||||
)
|
||||
_f.write('\n'.join(dev.generate_report(header=False)))
|
||||
|
||||
# Dry run
|
||||
if dry_run:
|
||||
|
|
@ -2129,7 +2127,7 @@ def run_ddrescue(state, block_pair, pass_name, settings, dry_run=True) -> None:
|
|||
while True:
|
||||
if _i % 30 == 0:
|
||||
# Update SMART pane
|
||||
_update_smart_pane()
|
||||
_update_smart_panes()
|
||||
|
||||
# Check 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(
|
||||
percent=50,
|
||||
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':
|
||||
state.ui.add_worker_pane(lines=4, cmd='journal-datarec-monitor')
|
||||
|
|
|
|||
|
|
@ -56,18 +56,12 @@ class Disk:
|
|||
ssd: bool = field(init=False)
|
||||
tests: list[Test] = field(init=False, default_factory=list)
|
||||
trim: bool = field(init=False)
|
||||
use_sat: bool = field(init=False, default=False)
|
||||
|
||||
def __post_init__(self):
|
||||
self.path = pathlib.Path(self.path_str).resolve()
|
||||
self.update_details()
|
||||
self.set_description()
|
||||
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)
|
||||
if not self.is_4k_aligned():
|
||||
self.add_note('One or more partitions are not 4K aligned', 'YELLOW')
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ def enable_smart(dev) -> None:
|
|||
cmd = [
|
||||
'sudo',
|
||||
'smartctl',
|
||||
f'--device={"sat,auto" if dev.use_sat else "auto"}',
|
||||
'--device=auto',
|
||||
'--tolerance=permissive',
|
||||
'--smart=on',
|
||||
dev.path,
|
||||
|
|
@ -461,7 +461,7 @@ def update_smart_details(dev) -> None:
|
|||
cmd = [
|
||||
'sudo',
|
||||
'smartctl',
|
||||
f'--device={"sat,auto" if dev.use_sat else "auto"}',
|
||||
'--device=auto',
|
||||
'--tolerance=verypermissive',
|
||||
'--all',
|
||||
'--json',
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ def fix_layout(
|
|||
avail_vertical -= layout[group].get('height', 0) + 1
|
||||
num_workers = len(layout['Workers']['Panes'])
|
||||
avail_vertical -= num_workers * (layout['Workers'].get('height', 0) + 1)
|
||||
avail_horizontal -= layout['Started']['width'] + 1
|
||||
avail_horizontal -= layout['Progress']['width'] + 1
|
||||
|
||||
# Fix heights
|
||||
for group, data in layout.items():
|
||||
|
|
@ -89,16 +89,17 @@ def fix_layout(
|
|||
)
|
||||
|
||||
# Fix widths
|
||||
for group in ('Started', 'Progress'):
|
||||
resize_kwargs.append(
|
||||
{'pane_id': layout[group]['Panes'][0], 'width': layout[group]['width']}
|
||||
)
|
||||
resize_kwargs.append(
|
||||
{'pane_id': layout['Progress']['Panes'][0], 'width': layout['Progress']['width']}
|
||||
)
|
||||
resize_kwargs.append(
|
||||
{'pane_id': layout['Started']['Panes'][0], 'height': layout['Started']['height']}
|
||||
)
|
||||
for group, data in layout.items():
|
||||
num_panes = len(data['Panes'])
|
||||
if num_panes < 2 or group not in ('Title', 'Subtitle', 'Info'):
|
||||
continue
|
||||
avail_horizontal -= (num_panes - 1)
|
||||
pane_width, remainder = divmod(avail_horizontal, num_panes)
|
||||
pane_width, remainder = divmod(avail_horizontal - (num_panes-1), num_panes)
|
||||
for pane_id in data['Panes']:
|
||||
new_width = pane_width
|
||||
if remainder > 0:
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ TMUX_LAYOUT = { # NOTE: This needs to be in order from top to bottom
|
|||
'Info': {'Panes': []},
|
||||
'Current': {'Panes': [environ.get('TMUX_PANE', None)]},
|
||||
'Workers': {'Panes': []},
|
||||
'Started': {'Panes': [], 'width': TMUX_SIDE_WIDTH},
|
||||
'Started': {'Panes': [], 'height': TMUX_TITLE_HEIGHT},
|
||||
'Progress': {'Panes': [], 'width': TMUX_SIDE_WIDTH},
|
||||
}
|
||||
|
||||
|
|
@ -204,6 +204,25 @@ class TUI():
|
|||
self.layout.clear()
|
||||
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
|
||||
self.layout['Title']['Panes'].append(tmux.split_window(
|
||||
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:
|
||||
"""Remove all info panes and update layout."""
|
||||
self.layout['Info'].pop('height', None)
|
||||
|
|
|
|||
Loading…
Reference in a new issue