Check passed source
* If it's an image, setup loopback dev * If it's a child block dev, prompt with option to use parent block * Show selected source details
This commit is contained in:
parent
8b1e19fa4b
commit
667223b3c2
1 changed files with 93 additions and 1 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
# Wizard Kit: Functions - ddrescue
|
# Wizard Kit: Functions - ddrescue
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import pathlib
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from functions.common import *
|
from functions.common import *
|
||||||
|
|
@ -12,9 +13,99 @@ USAGE=""" {script_name} clone [source [destination]]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Functions
|
# Functions
|
||||||
|
def show_device_details(dev_path):
|
||||||
|
"""Display device details on screen."""
|
||||||
|
cmd = (
|
||||||
|
'lsblk', '--nodeps',
|
||||||
|
'--output', 'NAME,TRAN,TYPE,SIZE,VENDOR,MODEL,SERIAL',
|
||||||
|
dev_path)
|
||||||
|
result = run_program(cmd)
|
||||||
|
output = result.stdout.decode().splitlines()
|
||||||
|
print_info(output.pop(0))
|
||||||
|
for line in output:
|
||||||
|
print_standard(line)
|
||||||
|
|
||||||
|
# Children info
|
||||||
|
cmd = ('lsblk', '--output', 'NAME,SIZE,FSTYPE,LABEL,MOUNTPOINT', dev_path)
|
||||||
|
result = run_program(cmd)
|
||||||
|
output = result.stdout.decode().splitlines()
|
||||||
|
print_info(output.pop(0))
|
||||||
|
for line in output:
|
||||||
|
print_standard(line)
|
||||||
|
|
||||||
|
def get_device_details(dev_path):
|
||||||
|
"""Get device details via lsblk, returns JSON dict."""
|
||||||
|
try:
|
||||||
|
cmd = (
|
||||||
|
'lsblk',
|
||||||
|
'--json',
|
||||||
|
'--output-all',
|
||||||
|
'--paths',
|
||||||
|
dev_path)
|
||||||
|
result = run_program(cmd)
|
||||||
|
except CalledProcessError:
|
||||||
|
print_error('Failed to get device details for {}'.format(dev_path))
|
||||||
|
abort()
|
||||||
|
|
||||||
|
json_data = json.loads(result.stdout.decode())
|
||||||
|
# Just return the first device (there should only be one)
|
||||||
|
return json_data['blockdevices'][0]
|
||||||
|
|
||||||
|
def setup_loopback_device(source_path):
|
||||||
|
"""Setup a loopback device for source_path, returns dev_path as str."""
|
||||||
|
cmd = (
|
||||||
|
'losetup',
|
||||||
|
'--find',
|
||||||
|
'--partscan',
|
||||||
|
'--show',
|
||||||
|
source_path)
|
||||||
|
try:
|
||||||
|
out = run_program(cmd, check=True)
|
||||||
|
dev_path = out.stdout.decode().strip()
|
||||||
|
except CalledProcessError:
|
||||||
|
print_error('Failed to setup loopback device for source.')
|
||||||
|
abort()
|
||||||
|
else:
|
||||||
|
return dev_path
|
||||||
|
|
||||||
def menu_clone(source_path, dest_path):
|
def menu_clone(source_path, dest_path):
|
||||||
|
"""ddrescue cloning menu."""
|
||||||
|
source_is_image = False
|
||||||
|
source_dev_path = None
|
||||||
print_success('GNU ddrescue: Cloning Menu')
|
print_success('GNU ddrescue: Cloning Menu')
|
||||||
pass
|
|
||||||
|
# Select source if not preselected
|
||||||
|
if not source_path:
|
||||||
|
#TODO menu_select drive
|
||||||
|
print_warning('Select drive not implemented yet.')
|
||||||
|
source_path = ''
|
||||||
|
|
||||||
|
# Check source
|
||||||
|
source_path = os.path.realpath(source_path)
|
||||||
|
if pathlib.Path(source_path).is_block_device():
|
||||||
|
source_dev_path = source_path
|
||||||
|
elif pathlib.Path(source_path).is_file():
|
||||||
|
source_dev_path = setup_loopback_device(source_path)
|
||||||
|
source_is_image = True
|
||||||
|
else:
|
||||||
|
print_error('Invalid source "{}".'.format(source_path))
|
||||||
|
abort()
|
||||||
|
source_details = get_device_details(source_dev_path)
|
||||||
|
|
||||||
|
# Check source type
|
||||||
|
if source_details['pkname']:
|
||||||
|
print_warning('Source "{}" is a child device.'.format(source_dev_path))
|
||||||
|
if ask('Use parent device "{}" instead?'.format(
|
||||||
|
source_details['pkname'])):
|
||||||
|
source_dev_path = source_details['pkname']
|
||||||
|
source_details = get_device_details(source_dev_path)
|
||||||
|
|
||||||
|
# Show selection details
|
||||||
|
if source_is_image:
|
||||||
|
print_success('Using image file: {}'.format(source_path))
|
||||||
|
print_success(' (via loopback device: {})'.format(
|
||||||
|
source_dev_path))
|
||||||
|
show_device_details(source_dev_path)
|
||||||
|
|
||||||
def menu_ddrescue(*args):
|
def menu_ddrescue(*args):
|
||||||
"""Main ddrescue loop/menu."""
|
"""Main ddrescue loop/menu."""
|
||||||
|
|
@ -45,6 +136,7 @@ def menu_ddrescue(*args):
|
||||||
exit_script()
|
exit_script()
|
||||||
|
|
||||||
def menu_image(source_path, dest_path):
|
def menu_image(source_path, dest_path):
|
||||||
|
"""ddrescue imaging menu."""
|
||||||
print_success('GNU ddrescue: Imaging Menu')
|
print_success('GNU ddrescue: Imaging Menu')
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue