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:
2Shirt 2018-07-14 22:52:18 -06:00
parent 8b1e19fa4b
commit 667223b3c2
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C

View file

@ -1,6 +1,7 @@
# Wizard Kit: Functions - ddrescue
import json
import pathlib
import re
from functions.common import *
@ -12,9 +13,99 @@ USAGE=""" {script_name} clone [source [destination]]
"""
# 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):
"""ddrescue cloning menu."""
source_is_image = False
source_dev_path = None
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):
"""Main ddrescue loop/menu."""
@ -45,6 +136,7 @@ def menu_ddrescue(*args):
exit_script()
def menu_image(source_path, dest_path):
"""ddrescue imaging menu."""
print_success('GNU ddrescue: Imaging Menu')
pass