Update function docstrings
This commit is contained in:
parent
89c343943f
commit
96c6997a44
9 changed files with 68 additions and 3 deletions
|
|
@ -11,6 +11,7 @@ REGEX_BAD_PATH_NAMES = re.compile(
|
||||||
re.IGNORECASE)
|
re.IGNORECASE)
|
||||||
|
|
||||||
def backup_partition(disk, par):
|
def backup_partition(disk, par):
|
||||||
|
"""Create a backup image of a partition."""
|
||||||
if par.get('Image Exists', False) or par['Number'] in disk['Bad Partitions']:
|
if par.get('Image Exists', False) or par['Number'] in disk['Bad Partitions']:
|
||||||
raise GenericAbort
|
raise GenericAbort
|
||||||
|
|
||||||
|
|
@ -28,9 +29,15 @@ def backup_partition(disk, par):
|
||||||
run_program(cmd)
|
run_program(cmd)
|
||||||
|
|
||||||
def fix_path(path):
|
def fix_path(path):
|
||||||
|
"""Replace invalid filename characters with underscores."""
|
||||||
return REGEX_BAD_PATH_NAMES.sub('_', path)
|
return REGEX_BAD_PATH_NAMES.sub('_', path)
|
||||||
|
|
||||||
def prep_disk_for_backup(destination, disk, ticket_number):
|
def prep_disk_for_backup(destination, disk, ticket_number):
|
||||||
|
"""Gather details about the disk and its partitions.
|
||||||
|
|
||||||
|
This includes partitions that can't be backed up,
|
||||||
|
whether backups already exist on the BACKUP_SERVER,
|
||||||
|
partition names/sizes/used space, etc."""
|
||||||
disk['Clobber Risk'] = []
|
disk['Clobber Risk'] = []
|
||||||
width = len(str(len(disk['Partitions'])))
|
width = len(str(len(disk['Partitions'])))
|
||||||
|
|
||||||
|
|
@ -102,7 +109,7 @@ def prep_disk_for_backup(destination, disk, ticket_number):
|
||||||
disk['Backup Warnings'] = warnings
|
disk['Backup Warnings'] = warnings
|
||||||
|
|
||||||
def select_backup_destination(auto_select=True):
|
def select_backup_destination(auto_select=True):
|
||||||
# Build menu
|
"""Select a backup destination from a menu, returns server dict."""
|
||||||
destinations = [s for s in BACKUP_SERVERS if s['Mounted']]
|
destinations = [s for s in BACKUP_SERVERS if s['Mounted']]
|
||||||
actions = [
|
actions = [
|
||||||
{'Name': 'Main Menu', 'Letter': 'M'},
|
{'Name': 'Main Menu', 'Letter': 'M'},
|
||||||
|
|
@ -136,6 +143,7 @@ def select_backup_destination(auto_select=True):
|
||||||
return destinations[int(selection)-1]
|
return destinations[int(selection)-1]
|
||||||
|
|
||||||
def verify_wim_backup(partition):
|
def verify_wim_backup(partition):
|
||||||
|
"""Verify WIM integrity."""
|
||||||
if not os.path.exists(partition['Image Path']):
|
if not os.path.exists(partition['Image Path']):
|
||||||
raise PathNotFoundError
|
raise PathNotFoundError
|
||||||
cmd = [
|
cmd = [
|
||||||
|
|
|
||||||
|
|
@ -399,6 +399,7 @@ def print_warning(*args, **kwargs):
|
||||||
print_standard(*args, color=COLORS['YELLOW'], **kwargs)
|
print_standard(*args, color=COLORS['YELLOW'], **kwargs)
|
||||||
|
|
||||||
def print_log(message='', end='\n', timestamp=True):
|
def print_log(message='', end='\n', timestamp=True):
|
||||||
|
"""Writes message to a log if LogFile is set."""
|
||||||
time_str = time.strftime("%Y-%m-%d %H%M%z: ") if timestamp else ''
|
time_str = time.strftime("%Y-%m-%d %H%M%z: ") if timestamp else ''
|
||||||
if 'LogFile' in global_vars and global_vars['LogFile']:
|
if 'LogFile' in global_vars and global_vars['LogFile']:
|
||||||
with open(global_vars['LogFile'], 'a', encoding='utf-8') as f:
|
with open(global_vars['LogFile'], 'a', encoding='utf-8') as f:
|
||||||
|
|
@ -526,6 +527,9 @@ def try_and_print(message='Trying...',
|
||||||
return {'CS': not bool(err), 'Error': err, 'Out': out}
|
return {'CS': not bool(err), 'Error': err, 'Out': out}
|
||||||
|
|
||||||
def upload_crash_details():
|
def upload_crash_details():
|
||||||
|
"""Upload log and runtime data to the CRASH_SERVER.
|
||||||
|
|
||||||
|
Intended for uploading to a public Nextcloud share."""
|
||||||
if not ENABLED_UPLOAD_DATA:
|
if not ENABLED_UPLOAD_DATA:
|
||||||
raise GenericError
|
raise GenericError
|
||||||
|
|
||||||
|
|
@ -762,6 +766,9 @@ def set_common_vars():
|
||||||
**global_vars)
|
**global_vars)
|
||||||
|
|
||||||
def set_linux_vars():
|
def set_linux_vars():
|
||||||
|
"""Set common variables in a Linux environment.
|
||||||
|
|
||||||
|
These assume we're running under a WK-Linux build."""
|
||||||
result = run_program(['mktemp', '-d'])
|
result = run_program(['mktemp', '-d'])
|
||||||
global_vars['TmpDir'] = result.stdout.decode().strip()
|
global_vars['TmpDir'] = result.stdout.decode().strip()
|
||||||
global_vars['Date'] = time.strftime("%Y-%m-%d")
|
global_vars['Date'] = time.strftime("%Y-%m-%d")
|
||||||
|
|
|
||||||
|
|
@ -353,6 +353,7 @@ def run_wimextract(source, items, dest):
|
||||||
run_program(cmd)
|
run_program(cmd)
|
||||||
|
|
||||||
def list_source_items(source_obj, rel_path=None):
|
def list_source_items(source_obj, rel_path=None):
|
||||||
|
"""List items in a dir or WIM, returns a list of SourceItem objects."""
|
||||||
items = []
|
items = []
|
||||||
rel_path = '{}{}'.format(os.sep, rel_path) if rel_path else ''
|
rel_path = '{}{}'.format(os.sep, rel_path) if rel_path else ''
|
||||||
if source_obj.is_dir():
|
if source_obj.is_dir():
|
||||||
|
|
@ -470,6 +471,7 @@ def scan_source(source_obj, dest_path, rel_path='', interactive=True):
|
||||||
return selected_items
|
return selected_items
|
||||||
|
|
||||||
def get_source_item_obj(source_obj, rel_path, item_path):
|
def get_source_item_obj(source_obj, rel_path, item_path):
|
||||||
|
"""Check if the item exists and return a SourceItem object if it does."""
|
||||||
item_obj = None
|
item_obj = None
|
||||||
item_path = re.sub(r'(\\|/)', os.sep, item_path)
|
item_path = re.sub(r'(\\|/)', os.sep, item_path)
|
||||||
if source_obj.is_dir():
|
if source_obj.is_dir():
|
||||||
|
|
@ -481,6 +483,8 @@ def get_source_item_obj(source_obj, rel_path, item_path):
|
||||||
rel_path,
|
rel_path,
|
||||||
os.sep if rel_path else '',
|
os.sep if rel_path else '',
|
||||||
item_path))
|
item_path))
|
||||||
|
if not os.path.exists(item_obj.path):
|
||||||
|
item_obj = None
|
||||||
else:
|
else:
|
||||||
# Assuming WIM file
|
# Assuming WIM file
|
||||||
if psutil.WINDOWS:
|
if psutil.WINDOWS:
|
||||||
|
|
@ -734,12 +738,12 @@ def transfer_source(source_obj, dest_path, selected_items):
|
||||||
raise GenericError
|
raise GenericError
|
||||||
|
|
||||||
def umount_backup_shares():
|
def umount_backup_shares():
|
||||||
"""Unnount the backup shares regardless of current status."""
|
"""Unmount the backup shares regardless of current status."""
|
||||||
for server in BACKUP_SERVERS:
|
for server in BACKUP_SERVERS:
|
||||||
umount_network_share(server)
|
umount_network_share(server)
|
||||||
|
|
||||||
def umount_network_share(server):
|
def umount_network_share(server):
|
||||||
"""Unnount a network share defined by server."""
|
"""Unmount a network share defined by server."""
|
||||||
cmd = r'net use \\{IP}\{Share} /delete'.format(**server)
|
cmd = r'net use \\{IP}\{Share} /delete'.format(**server)
|
||||||
cmd = cmd.split(' ')
|
cmd = cmd.split(' ')
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ REGEX_DISK_MBR = re.compile(r'Disk ID: [A-Z0-9]+', re.IGNORECASE)
|
||||||
REGEX_DISK_RAW = re.compile(r'Disk ID: 00000000', re.IGNORECASE)
|
REGEX_DISK_RAW = re.compile(r'Disk ID: 00000000', re.IGNORECASE)
|
||||||
|
|
||||||
def assign_volume_letters():
|
def assign_volume_letters():
|
||||||
|
"""Assign a volume letter to all available volumes."""
|
||||||
remove_volume_letters()
|
remove_volume_letters()
|
||||||
|
|
||||||
# Write script
|
# Write script
|
||||||
|
|
@ -24,6 +25,7 @@ def assign_volume_letters():
|
||||||
run_diskpart(script)
|
run_diskpart(script)
|
||||||
|
|
||||||
def get_boot_mode():
|
def get_boot_mode():
|
||||||
|
"""Check if the boot mode was UEFI or legacy."""
|
||||||
boot_mode = 'Legacy'
|
boot_mode = 'Legacy'
|
||||||
try:
|
try:
|
||||||
reg_key = winreg.OpenKey(
|
reg_key = winreg.OpenKey(
|
||||||
|
|
@ -37,6 +39,7 @@ def get_boot_mode():
|
||||||
return boot_mode
|
return boot_mode
|
||||||
|
|
||||||
def get_disk_details(disk):
|
def get_disk_details(disk):
|
||||||
|
"""Get disk details using DiskPart."""
|
||||||
details = {}
|
details = {}
|
||||||
script = [
|
script = [
|
||||||
'select disk {}'.format(disk['Number']),
|
'select disk {}'.format(disk['Number']),
|
||||||
|
|
@ -61,6 +64,7 @@ def get_disk_details(disk):
|
||||||
return details
|
return details
|
||||||
|
|
||||||
def get_disks():
|
def get_disks():
|
||||||
|
"""Get list of attached disks using DiskPart."""
|
||||||
disks = []
|
disks = []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -79,6 +83,7 @@ def get_disks():
|
||||||
return disks
|
return disks
|
||||||
|
|
||||||
def get_partition_details(disk, partition):
|
def get_partition_details(disk, partition):
|
||||||
|
"""Get partition details using DiskPart and fsutil."""
|
||||||
details = {}
|
details = {}
|
||||||
script = [
|
script = [
|
||||||
'select disk {}'.format(disk['Number']),
|
'select disk {}'.format(disk['Number']),
|
||||||
|
|
@ -157,6 +162,7 @@ def get_partition_details(disk, partition):
|
||||||
return details
|
return details
|
||||||
|
|
||||||
def get_partitions(disk):
|
def get_partitions(disk):
|
||||||
|
"""Get list of partition using DiskPart."""
|
||||||
partitions = []
|
partitions = []
|
||||||
script = [
|
script = [
|
||||||
'select disk {}'.format(disk['Number']),
|
'select disk {}'.format(disk['Number']),
|
||||||
|
|
@ -179,6 +185,7 @@ def get_partitions(disk):
|
||||||
return partitions
|
return partitions
|
||||||
|
|
||||||
def get_table_type(disk):
|
def get_table_type(disk):
|
||||||
|
"""Get disk partition table type using DiskPart."""
|
||||||
part_type = 'Unknown'
|
part_type = 'Unknown'
|
||||||
script = [
|
script = [
|
||||||
'select disk {}'.format(disk['Number']),
|
'select disk {}'.format(disk['Number']),
|
||||||
|
|
@ -200,6 +207,7 @@ def get_table_type(disk):
|
||||||
return part_type
|
return part_type
|
||||||
|
|
||||||
def get_volumes():
|
def get_volumes():
|
||||||
|
"""Get list of volumes using DiskPart."""
|
||||||
vols = []
|
vols = []
|
||||||
try:
|
try:
|
||||||
result = run_diskpart(['list volume'])
|
result = run_diskpart(['list volume'])
|
||||||
|
|
@ -214,9 +222,11 @@ def get_volumes():
|
||||||
return vols
|
return vols
|
||||||
|
|
||||||
def is_bad_partition(par):
|
def is_bad_partition(par):
|
||||||
|
"""Check if the partition is accessible."""
|
||||||
return 'Letter' not in par or REGEX_BAD_PARTITION.search(par['FileSystem'])
|
return 'Letter' not in par or REGEX_BAD_PARTITION.search(par['FileSystem'])
|
||||||
|
|
||||||
def prep_disk_for_formatting(disk=None):
|
def prep_disk_for_formatting(disk=None):
|
||||||
|
"""Gather details about the disk and its partitions."""
|
||||||
disk['Format Warnings'] = '\n'
|
disk['Format Warnings'] = '\n'
|
||||||
width = len(str(len(disk['Partitions'])))
|
width = len(str(len(disk['Partitions'])))
|
||||||
|
|
||||||
|
|
@ -261,6 +271,7 @@ def prep_disk_for_formatting(disk=None):
|
||||||
partition['Display String'] = display
|
partition['Display String'] = display
|
||||||
|
|
||||||
def reassign_volume_letter(letter, new_letter='I'):
|
def reassign_volume_letter(letter, new_letter='I'):
|
||||||
|
"""Assign a new letter to a volume using DiskPart."""
|
||||||
if not letter:
|
if not letter:
|
||||||
# Ignore
|
# Ignore
|
||||||
return None
|
return None
|
||||||
|
|
@ -276,6 +287,7 @@ def reassign_volume_letter(letter, new_letter='I'):
|
||||||
return new_letter
|
return new_letter
|
||||||
|
|
||||||
def remove_volume_letters(keep=None):
|
def remove_volume_letters(keep=None):
|
||||||
|
"""Remove all assigned volume letters using DiskPart."""
|
||||||
if not keep:
|
if not keep:
|
||||||
keep = ''
|
keep = ''
|
||||||
|
|
||||||
|
|
@ -292,6 +304,7 @@ def remove_volume_letters(keep=None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def run_diskpart(script):
|
def run_diskpart(script):
|
||||||
|
"""Run DiskPart script."""
|
||||||
tempfile = r'{}\diskpart.script'.format(global_vars['Env']['TMP'])
|
tempfile = r'{}\diskpart.script'.format(global_vars['Env']['TMP'])
|
||||||
|
|
||||||
# Write script
|
# Write script
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ TESTS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_smart_details(dev):
|
def get_smart_details(dev):
|
||||||
|
"""Get SMART data for dev if possible, returns dict."""
|
||||||
cmd = 'sudo smartctl --all --json /dev/{}'.format(dev).split()
|
cmd = 'sudo smartctl --all --json /dev/{}'.format(dev).split()
|
||||||
result = run_program(cmd, check=False)
|
result = run_program(cmd, check=False)
|
||||||
try:
|
try:
|
||||||
|
|
@ -51,6 +52,7 @@ def get_smart_details(dev):
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def get_status_color(s):
|
def get_status_color(s):
|
||||||
|
"""Get color based on status, returns str."""
|
||||||
color = COLORS['CLEAR']
|
color = COLORS['CLEAR']
|
||||||
if s in ['Denied', 'NS', 'OVERRIDE', 'Unknown']:
|
if s in ['Denied', 'NS', 'OVERRIDE', 'Unknown']:
|
||||||
color = COLORS['RED']
|
color = COLORS['RED']
|
||||||
|
|
@ -61,6 +63,7 @@ def get_status_color(s):
|
||||||
return color
|
return color
|
||||||
|
|
||||||
def menu_diags(*args):
|
def menu_diags(*args):
|
||||||
|
"""Main HW-Diagnostic menu."""
|
||||||
diag_modes = [
|
diag_modes = [
|
||||||
{'Name': 'All tests',
|
{'Name': 'All tests',
|
||||||
'Tests': ['Prime95', 'NVMe/SMART', 'badblocks']},
|
'Tests': ['Prime95', 'NVMe/SMART', 'badblocks']},
|
||||||
|
|
@ -133,6 +136,7 @@ def menu_diags(*args):
|
||||||
break
|
break
|
||||||
|
|
||||||
def run_badblocks():
|
def run_badblocks():
|
||||||
|
"""Run a read-only test for all detected disks."""
|
||||||
aborted = False
|
aborted = False
|
||||||
clear_screen()
|
clear_screen()
|
||||||
print_log('\nStart badblocks test(s)\n')
|
print_log('\nStart badblocks test(s)\n')
|
||||||
|
|
@ -191,6 +195,7 @@ def run_badblocks():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def run_mprime():
|
def run_mprime():
|
||||||
|
"""Run Prime95 for MPRIME_LIMIT minutes while showing the temps."""
|
||||||
aborted = False
|
aborted = False
|
||||||
clear_screen()
|
clear_screen()
|
||||||
print_log('\nStart Prime95 test')
|
print_log('\nStart Prime95 test')
|
||||||
|
|
@ -282,6 +287,7 @@ def run_mprime():
|
||||||
run_program('tmux kill-pane -a'.split())
|
run_program('tmux kill-pane -a'.split())
|
||||||
|
|
||||||
def run_nvme_smart():
|
def run_nvme_smart():
|
||||||
|
"""Run the built-in NVMe or SMART test for all detected disks."""
|
||||||
aborted = False
|
aborted = False
|
||||||
clear_screen()
|
clear_screen()
|
||||||
print_log('\nStart NVMe/SMART test(s)\n')
|
print_log('\nStart NVMe/SMART test(s)\n')
|
||||||
|
|
@ -376,6 +382,7 @@ def run_nvme_smart():
|
||||||
run_program('tmux kill-pane -a'.split(), check=False)
|
run_program('tmux kill-pane -a'.split(), check=False)
|
||||||
|
|
||||||
def run_tests(tests):
|
def run_tests(tests):
|
||||||
|
"""Run selected hardware test(s)."""
|
||||||
print_log('Starting Hardware Diagnostics')
|
print_log('Starting Hardware Diagnostics')
|
||||||
print_log('\nRunning tests: {}'.format(', '.join(tests)))
|
print_log('\nRunning tests: {}'.format(', '.join(tests)))
|
||||||
# Enable selected tests
|
# Enable selected tests
|
||||||
|
|
@ -414,6 +421,7 @@ def run_tests(tests):
|
||||||
pause('Press Enter to exit...')
|
pause('Press Enter to exit...')
|
||||||
|
|
||||||
def scan_disks():
|
def scan_disks():
|
||||||
|
"""Scan for disks eligible for hardware testing."""
|
||||||
clear_screen()
|
clear_screen()
|
||||||
|
|
||||||
# Get eligible disk list
|
# Get eligible disk list
|
||||||
|
|
@ -489,6 +497,7 @@ def scan_disks():
|
||||||
TESTS['badblocks']['Devices'] = devs
|
TESTS['badblocks']['Devices'] = devs
|
||||||
|
|
||||||
def show_disk_details(dev):
|
def show_disk_details(dev):
|
||||||
|
"""Display disk details."""
|
||||||
dev_name = dev['lsblk']['name']
|
dev_name = dev['lsblk']['name']
|
||||||
# Device description
|
# Device description
|
||||||
print_info('Device: /dev/{}'.format(dev['lsblk']['name']))
|
print_info('Device: /dev/{}'.format(dev['lsblk']['name']))
|
||||||
|
|
@ -566,6 +575,7 @@ def show_disk_details(dev):
|
||||||
print_success(raw_str, timestamp=False)
|
print_success(raw_str, timestamp=False)
|
||||||
|
|
||||||
def show_results():
|
def show_results():
|
||||||
|
"""Show results for selected test(s)."""
|
||||||
clear_screen()
|
clear_screen()
|
||||||
print_log('\n───────────────────────────')
|
print_log('\n───────────────────────────')
|
||||||
print_standard('Hardware Diagnostic Results')
|
print_standard('Hardware Diagnostic Results')
|
||||||
|
|
@ -629,6 +639,7 @@ def show_results():
|
||||||
run_program('tmux kill-pane -a'.split())
|
run_program('tmux kill-pane -a'.split())
|
||||||
|
|
||||||
def update_progress():
|
def update_progress():
|
||||||
|
"""Update progress file."""
|
||||||
if 'Progress Out' not in TESTS:
|
if 'Progress Out' not in TESTS:
|
||||||
TESTS['Progress Out'] = '{}/progress.out'.format(global_vars['LogDir'])
|
TESTS['Progress Out'] = '{}/progress.out'.format(global_vars['LogDir'])
|
||||||
output = []
|
output = []
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ def is_connected():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def show_valid_addresses():
|
def show_valid_addresses():
|
||||||
|
"""Show all valid private IP addresses assigned to the system."""
|
||||||
devs = psutil.net_if_addrs()
|
devs = psutil.net_if_addrs()
|
||||||
for dev, families in sorted(devs.items()):
|
for dev, families in sorted(devs.items()):
|
||||||
for family in families:
|
for family in families:
|
||||||
|
|
@ -62,6 +63,7 @@ def show_valid_addresses():
|
||||||
show_data(message=dev, data=family.address)
|
show_data(message=dev, data=family.address)
|
||||||
|
|
||||||
def speedtest():
|
def speedtest():
|
||||||
|
"""Run a network speedtest using speedtest-cli."""
|
||||||
result = run_program(['speedtest-cli', '--simple'])
|
result = run_program(['speedtest-cli', '--simple'])
|
||||||
output = [line.strip() for line in result.stdout.decode().splitlines()
|
output = [line.strip() for line in result.stdout.decode().splitlines()
|
||||||
if line.strip()]
|
if line.strip()]
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ from settings.music import *
|
||||||
from settings.sources import *
|
from settings.sources import *
|
||||||
|
|
||||||
def compress_and_remove_item(item):
|
def compress_and_remove_item(item):
|
||||||
|
"""Compress and delete an item unless an error is encountered."""
|
||||||
try:
|
try:
|
||||||
compress_item(item)
|
compress_item(item)
|
||||||
except:
|
except:
|
||||||
|
|
@ -17,6 +18,7 @@ def compress_and_remove_item(item):
|
||||||
remove_item(item.path)
|
remove_item(item.path)
|
||||||
|
|
||||||
def compress_item(item):
|
def compress_item(item):
|
||||||
|
"""Compress an item in a 7-Zip archive using the ARCHIVE_PASSWORD."""
|
||||||
# Prep
|
# Prep
|
||||||
prev_dir = os.getcwd()
|
prev_dir = os.getcwd()
|
||||||
dest = '{}.7z'.format(item.path)
|
dest = '{}.7z'.format(item.path)
|
||||||
|
|
@ -58,9 +60,11 @@ def download_generic(out_dir, out_name, source_url):
|
||||||
raise GenericError('Failed to download file.')
|
raise GenericError('Failed to download file.')
|
||||||
|
|
||||||
def download_to_temp(out_name, source_url):
|
def download_to_temp(out_name, source_url):
|
||||||
|
"""Download a file to the TmpDir."""
|
||||||
download_generic(global_vars['TmpDir'], out_name, source_url)
|
download_generic(global_vars['TmpDir'], out_name, source_url)
|
||||||
|
|
||||||
def extract_generic(source, dest, mode='x', sz_args=[]):
|
def extract_generic(source, dest, mode='x', sz_args=[]):
|
||||||
|
"""Extract a file to a destination."""
|
||||||
cmd = [
|
cmd = [
|
||||||
global_vars['Tools']['SevenZip'],
|
global_vars['Tools']['SevenZip'],
|
||||||
mode, source, r'-o{}'.format(dest),
|
mode, source, r'-o{}'.format(dest),
|
||||||
|
|
@ -70,11 +74,13 @@ def extract_generic(source, dest, mode='x', sz_args=[]):
|
||||||
run_program(cmd)
|
run_program(cmd)
|
||||||
|
|
||||||
def extract_temp_to_bin(source, item, mode='x', sz_args=[]):
|
def extract_temp_to_bin(source, item, mode='x', sz_args=[]):
|
||||||
|
"""Extract a file to the .bin folder."""
|
||||||
source = r'{}\{}'.format(global_vars['TmpDir'], source)
|
source = r'{}\{}'.format(global_vars['TmpDir'], source)
|
||||||
dest = r'{}\{}'.format(global_vars['BinDir'], item)
|
dest = r'{}\{}'.format(global_vars['BinDir'], item)
|
||||||
extract_generic(source, dest, mode, sz_args)
|
extract_generic(source, dest, mode, sz_args)
|
||||||
|
|
||||||
def extract_temp_to_cbin(source, item, mode='x', sz_args=[]):
|
def extract_temp_to_cbin(source, item, mode='x', sz_args=[]):
|
||||||
|
"""Extract a file to the .cbin folder."""
|
||||||
source = r'{}\{}'.format(global_vars['TmpDir'], source)
|
source = r'{}\{}'.format(global_vars['TmpDir'], source)
|
||||||
dest = r'{}\{}'.format(global_vars['CBinDir'], item)
|
dest = r'{}\{}'.format(global_vars['CBinDir'], item)
|
||||||
include_path = r'{}\_include\{}'.format(global_vars['CBinDir'], item)
|
include_path = r'{}\_include\{}'.format(global_vars['CBinDir'], item)
|
||||||
|
|
@ -83,6 +89,7 @@ def extract_temp_to_cbin(source, item, mode='x', sz_args=[]):
|
||||||
extract_generic(source, dest, mode, sz_args)
|
extract_generic(source, dest, mode, sz_args)
|
||||||
|
|
||||||
def generate_launcher(section, name, options):
|
def generate_launcher(section, name, options):
|
||||||
|
"""Generate a launcher script."""
|
||||||
# Prep
|
# Prep
|
||||||
dest = r'{}\{}'.format(global_vars['BaseDir'], section)
|
dest = r'{}\{}'.format(global_vars['BaseDir'], section)
|
||||||
if section == '(Root)':
|
if section == '(Root)':
|
||||||
|
|
@ -119,6 +126,7 @@ def generate_launcher(section, name, options):
|
||||||
f.write('\n'.join(out_text))
|
f.write('\n'.join(out_text))
|
||||||
|
|
||||||
def remove_item(item_path):
|
def remove_item(item_path):
|
||||||
|
"""Delete a file or folder."""
|
||||||
if os.path.exists(item_path):
|
if os.path.exists(item_path):
|
||||||
if os.path.isdir(item_path):
|
if os.path.isdir(item_path):
|
||||||
shutil.rmtree(item_path, ignore_errors=True)
|
shutil.rmtree(item_path, ignore_errors=True)
|
||||||
|
|
@ -126,6 +134,7 @@ def remove_item(item_path):
|
||||||
os.remove(item_path)
|
os.remove(item_path)
|
||||||
|
|
||||||
def remove_from_kit(item):
|
def remove_from_kit(item):
|
||||||
|
"""Delete a file or folder from the .bin/.cbin folders."""
|
||||||
item_locations = []
|
item_locations = []
|
||||||
for p in [global_vars['BinDir'], global_vars['CBinDir']]:
|
for p in [global_vars['BinDir'], global_vars['CBinDir']]:
|
||||||
item_locations.append(r'{}\{}'.format(p, item))
|
item_locations.append(r'{}\{}'.format(p, item))
|
||||||
|
|
@ -134,6 +143,7 @@ def remove_from_kit(item):
|
||||||
remove_item(item_path)
|
remove_item(item_path)
|
||||||
|
|
||||||
def remove_from_temp(item):
|
def remove_from_temp(item):
|
||||||
|
"""Delete a file or folder from the TmpDir folder."""
|
||||||
item_path = r'{}\{}'.format(global_vars['TmpDir'], item)
|
item_path = r'{}\{}'.format(global_vars['TmpDir'], item)
|
||||||
remove_item(item_path)
|
remove_item(item_path)
|
||||||
|
|
||||||
|
|
@ -159,6 +169,7 @@ def resolve_dynamic_url(source_url, regex):
|
||||||
return url
|
return url
|
||||||
|
|
||||||
def scan_for_net_installers(server, family_name, min_year):
|
def scan_for_net_installers(server, family_name, min_year):
|
||||||
|
"""Scan network shares for installers."""
|
||||||
if not server['Mounted']:
|
if not server['Mounted']:
|
||||||
mount_network_share(server)
|
mount_network_share(server)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,7 @@ def mount_windows_share():
|
||||||
mount_network_share(WINDOWS_SERVER, read_write=True)
|
mount_network_share(WINDOWS_SERVER, read_write=True)
|
||||||
|
|
||||||
def select_windows_version():
|
def select_windows_version():
|
||||||
|
"""Select Windows version from a menu, returns dict."""
|
||||||
actions = [
|
actions = [
|
||||||
{'Name': 'Main Menu', 'Letter': 'M'},
|
{'Name': 'Main Menu', 'Letter': 'M'},
|
||||||
]
|
]
|
||||||
|
|
@ -178,6 +179,7 @@ def select_windows_version():
|
||||||
raise GenericAbort
|
raise GenericAbort
|
||||||
|
|
||||||
def setup_windows(windows_image, windows_version):
|
def setup_windows(windows_image, windows_version):
|
||||||
|
"""Apply a Windows image to W:\"""
|
||||||
cmd = [
|
cmd = [
|
||||||
global_vars['Tools']['wimlib-imagex'],
|
global_vars['Tools']['wimlib-imagex'],
|
||||||
'apply',
|
'apply',
|
||||||
|
|
@ -189,6 +191,7 @@ def setup_windows(windows_image, windows_version):
|
||||||
run_program(cmd)
|
run_program(cmd)
|
||||||
|
|
||||||
def setup_windows_re(windows_version, windows_letter='W', tools_letter='T'):
|
def setup_windows_re(windows_version, windows_letter='W', tools_letter='T'):
|
||||||
|
"""Setup the WinRE partition."""
|
||||||
win = r'{}:\Windows'.format(windows_letter)
|
win = r'{}:\Windows'.format(windows_letter)
|
||||||
winre = r'{}\System32\Recovery\WinRE.wim'.format(win)
|
winre = r'{}\System32\Recovery\WinRE.wim'.format(win)
|
||||||
dest = r'{}:\Recovery\WindowsRE'.format(tools_letter)
|
dest = r'{}:\Recovery\WindowsRE'.format(tools_letter)
|
||||||
|
|
@ -206,6 +209,7 @@ def setup_windows_re(windows_version, windows_letter='W', tools_letter='T'):
|
||||||
run_program(cmd)
|
run_program(cmd)
|
||||||
|
|
||||||
def update_boot_partition(system_letter='S', windows_letter='W', mode='ALL'):
|
def update_boot_partition(system_letter='S', windows_letter='W', mode='ALL'):
|
||||||
|
"""Setup the Windows boot partition."""
|
||||||
cmd = [
|
cmd = [
|
||||||
r'{}\Windows\System32\bcdboot.exe'.format(
|
r'{}\Windows\System32\bcdboot.exe'.format(
|
||||||
global_vars['Env']['SYSTEMDRIVE']),
|
global_vars['Env']['SYSTEMDRIVE']),
|
||||||
|
|
@ -215,6 +219,7 @@ def update_boot_partition(system_letter='S', windows_letter='W', mode='ALL'):
|
||||||
run_program(cmd)
|
run_program(cmd)
|
||||||
|
|
||||||
def wim_contains_image(filename, imagename):
|
def wim_contains_image(filename, imagename):
|
||||||
|
"""Check if an ESD/WIM contains the specified image, returns bool."""
|
||||||
cmd = [
|
cmd = [
|
||||||
global_vars['Tools']['wimlib-imagex'],
|
global_vars['Tools']['wimlib-imagex'],
|
||||||
'info',
|
'info',
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ PE_TOOLS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
def check_pe_tools():
|
def check_pe_tools():
|
||||||
|
"""Fix tool paths for WinPE layout."""
|
||||||
for k in PE_TOOLS.keys():
|
for k in PE_TOOLS.keys():
|
||||||
PE_TOOLS[k]['Path'] = r'{}\{}'.format(
|
PE_TOOLS[k]['Path'] = r'{}\{}'.format(
|
||||||
global_vars['BinDir'], PE_TOOLS[k]['Path'])
|
global_vars['BinDir'], PE_TOOLS[k]['Path'])
|
||||||
|
|
@ -203,6 +204,7 @@ def menu_backup():
|
||||||
pause('\nPress Enter to return to main menu... ')
|
pause('\nPress Enter to return to main menu... ')
|
||||||
|
|
||||||
def menu_root():
|
def menu_root():
|
||||||
|
"""Main WinPE menu."""
|
||||||
check_pe_tools()
|
check_pe_tools()
|
||||||
menus = [
|
menus = [
|
||||||
{'Name': 'Create Backups', 'Menu': menu_backup},
|
{'Name': 'Create Backups', 'Menu': menu_backup},
|
||||||
|
|
@ -381,6 +383,7 @@ def menu_setup():
|
||||||
pause('\nPress Enter to return to main menu... ')
|
pause('\nPress Enter to return to main menu... ')
|
||||||
|
|
||||||
def menu_tools():
|
def menu_tools():
|
||||||
|
"""Tool launcher menu."""
|
||||||
tools = [{'Name': k} for k in sorted(PE_TOOLS.keys())]
|
tools = [{'Name': k} for k in sorted(PE_TOOLS.keys())]
|
||||||
actions = [{'Name': 'Main Menu', 'Letter': 'M'},]
|
actions = [{'Name': 'Main Menu', 'Letter': 'M'},]
|
||||||
set_title(KIT_NAME_FULL)
|
set_title(KIT_NAME_FULL)
|
||||||
|
|
@ -409,6 +412,7 @@ def menu_tools():
|
||||||
break
|
break
|
||||||
|
|
||||||
def select_minidump_path():
|
def select_minidump_path():
|
||||||
|
"""Select BSOD minidump path from a menu."""
|
||||||
dumps = []
|
dumps = []
|
||||||
|
|
||||||
# Assign volume letters first
|
# Assign volume letters first
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue