From 1a26aead442f179b99c260d1e3e985aa0eb92f9f Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Tue, 28 Jan 2020 18:38:33 -0700
Subject: [PATCH 01/18] Network test working under macOS
---
scripts/wk/hw/diags.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/scripts/wk/hw/diags.py b/scripts/wk/hw/diags.py
index 03e9628a..3dd7a189 100644
--- a/scripts/wk/hw/diags.py
+++ b/scripts/wk/hw/diags.py
@@ -431,10 +431,10 @@ def build_menu(cli_mode=False, quick_mode=False):
# Compatibility checks
if PLATFORM != 'Linux':
- for name in ('Audio Test', 'Keyboard Test', 'Network Test'):
+ for name in ('Audio Test', 'Keyboard Test'):
menu.actions[name]['Disabled'] = True
if PLATFORM not in ('Darwin', 'Linux'):
- for name in ('Matrix', 'Tubes'):
+ for name in ('Matrix', 'Network Test', 'Tubes'):
menu.actions[name]['Disabled'] = True
# Done
From 98032a0fed70b90d6a38b5d5ffb2d2ba17d3ee12 Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Tue, 28 Jan 2020 19:00:47 -0700
Subject: [PATCH 02/18] Removed stale TODO statements
---
scripts/wk/hw/diags.py | 1 -
scripts/wk/hw/obj.py | 1 -
scripts/wk/kit/ufd.py | 3 ---
scripts/wk/net.py | 1 -
scripts/wk/os/linux.py | 1 -
scripts/wk/os/win.py | 2 +-
6 files changed, 1 insertion(+), 8 deletions(-)
diff --git a/scripts/wk/hw/diags.py b/scripts/wk/hw/diags.py
index 3dd7a189..9aab1887 100644
--- a/scripts/wk/hw/diags.py
+++ b/scripts/wk/hw/diags.py
@@ -383,7 +383,6 @@ def audio_test():
"""Run an OS-specific audio test."""
if PLATFORM == 'Linux':
audio_test_linux()
- # TODO: Add tests for other OS
def audio_test_linux():
diff --git a/scripts/wk/hw/obj.py b/scripts/wk/hw/obj.py
index eca9a4db..1d9dbde6 100644
--- a/scripts/wk/hw/obj.py
+++ b/scripts/wk/hw/obj.py
@@ -385,7 +385,6 @@ class Disk(BaseObj):
aligned = is_4k_aligned_macos(self.details)
elif PLATFORM == 'Linux':
aligned = is_4k_aligned_linux(self.path, self.details['phy-sec'])
- #TODO: Add checks for other OS
return aligned
diff --git a/scripts/wk/kit/ufd.py b/scripts/wk/kit/ufd.py
index 6df842de..9c792b3b 100644
--- a/scripts/wk/kit/ufd.py
+++ b/scripts/wk/kit/ufd.py
@@ -1,8 +1,5 @@
"""WizardKit: UFD Functions"""
# vim: sts=2 sw=2 ts=2
-# TODO: Replace some lsblk usage with hw_obj?
-# TODO: Reduce imports if possible
-# TODO: Needs testing
import logging
import os
diff --git a/scripts/wk/net.py b/scripts/wk/net.py
index 8b930c3b..e8e763b5 100644
--- a/scripts/wk/net.py
+++ b/scripts/wk/net.py
@@ -181,7 +181,6 @@ def share_is_mounted(details):
if row['source'] == f'//{details["Address"]}/{details["Share"]}':
mounted = True
break
- #TODO: Check mount status under Windows
#elif PLATFORM == 'Windows':
# Done
diff --git a/scripts/wk/os/linux.py b/scripts/wk/os/linux.py
index 7c38a03f..e4aefab8 100644
--- a/scripts/wk/os/linux.py
+++ b/scripts/wk/os/linux.py
@@ -179,7 +179,6 @@ def running_as_root():
def scan_corestorage_container(container, timeout=300):
"""Scan CoreStorage container for inner volumes, returns list."""
- # TODO: Test Scanning CoreStorage containers
detected_volumes = {}
inner_volumes = []
log_path = format_log_path(log_name=f'{container.path.name}_testdisk')
diff --git a/scripts/wk/os/win.py b/scripts/wk/os/win.py
index f367e40f..7f17af37 100644
--- a/scripts/wk/os/win.py
+++ b/scripts/wk/os/win.py
@@ -15,7 +15,7 @@ from wk.std import GenericError, GenericWarning, sleep
# STATIC VARIABLES
LOG = logging.getLogger(__name__)
-OS_VERSION = float(platform.win32_ver()[0]) # TODO: Check if Win8.1 returns '8'
+OS_VERSION = float(platform.win32_ver()[0])
REG_MSISERVER = r'HKLM\SYSTEM\CurrentControlSet\Control\SafeBoot\Network\MSIServer'
SLMGR = pathlib.Path(f'{os.environ.get("SYSTEMROOT")}/System32/slmgr.vbs')
From 41130a38edf14b66cc7c1fa447d45d2699de540a Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Thu, 30 Jan 2020 13:02:41 -0700
Subject: [PATCH 03/18] Fix running tmux in live macOS env
---
scripts/launch-in-tmux | 28 +++++++++++++++++-----------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/scripts/launch-in-tmux b/scripts/launch-in-tmux
index 2be76959..f0940b00 100755
--- a/scripts/launch-in-tmux
+++ b/scripts/launch-in-tmux
@@ -2,6 +2,12 @@
#
## Wizard Kit: TMUX Launcher
+# Live macOS env workaround
+tmux_args=()
+if [[ -e "/.wk-live-macos" ]]; then
+ tmux_args=(-f "/etc/tmux.conf" -S "$(mktemp).socket")
+fi
+
function ask() {
while :; do
read -p "$1 [Y/N] " -r answer
@@ -25,24 +31,24 @@ function launch_in_tmux() {
[[ -n "${TMUX_CMD:-}" ]] || return $(err "Required variable missing (TMUX_CMD)")
# Check for running session
- if tmux list-session | grep -q "$SESSION_NAME"; then
+ if tmux "${tmux_args[@]}" list-session | grep -q "$SESSION_NAME"; then
echo "WARNING: tmux session $SESSION_NAME already exists."
echo ""
if ask "Connect to current session?"; then
if [[ -n "${TMUX:-}" ]]; then
# Running inside TMUX, switch to session
- tmux switch-client -t "$SESSION_NAME"
+ tmux "${tmux_args[@]}" switch-client -t "$SESSION_NAME"
if ! jobs %% >/dev/null 2>&1; then
# No running jobs, try exiting abandoned tmux session
exit 0
fi
else
# Running outside TMUX, attach to session
- tmux attach-session -t "$SESSION_NAME"
+ tmux "${tmux_args[@]}" attach-session -t "$SESSION_NAME"
fi
return 0
elif ask "Kill current session and start new session?"; then
- tmux kill-session -t "$SESSION_NAME" || \
+ tmux "${tmux_args[@]}" kill-session -t "$SESSION_NAME" || \
die "Failed to kill session: $SESSION_NAME"
else
echo "Aborted."
@@ -53,16 +59,16 @@ function launch_in_tmux() {
# Start session
if [[ -n "${TMUX:-}" ]]; then
# Running inside TMUX, save current session/window names
- ORIGINAL_SESSION_NAME="$(tmux display-message -p '#S')"
- ORIGINAL_WINDOW_NAME="$(tmux display-message -p '#W')"
- tmux rename-session "$SESSION_NAME"
- tmux rename-window "$WINDOW_NAME"
+ ORIGINAL_SESSION_NAME="$(tmux "${tmux_args[@]}" display-message -p '#S')"
+ ORIGINAL_WINDOW_NAME="$(tmux "${tmux_args[@]}" display-message -p '#W')"
+ tmux "${tmux_args[@]}" rename-session "$SESSION_NAME"
+ tmux "${tmux_args[@]}" rename-window "$WINDOW_NAME"
"$TMUX_CMD" "$@"
# Restore previous session/window names
- tmux rename-session "${ORIGINAL_SESSION_NAME}"
- tmux rename-window "${ORIGINAL_WINDOW_NAME}"
+ tmux "${tmux_args[@]}" rename-session "${ORIGINAL_SESSION_NAME}"
+ tmux "${tmux_args[@]}" rename-window "${ORIGINAL_WINDOW_NAME}"
else
# Running outside TMUX, start/attach to session
- tmux new-session -s "$SESSION_NAME" -n "$WINDOW_NAME" "$TMUX_CMD" "$@"
+ tmux "${tmux_args[@]}" new-session -s "$SESSION_NAME" -n "$WINDOW_NAME" "$TMUX_CMD" "$@"
fi
}
From e1943b9fb48354fca955eb0bbc24a27c4f7ce537 Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Thu, 30 Jan 2020 13:03:21 -0700
Subject: [PATCH 04/18] Strip sudo use if running as root on Linux/macOS
* Allows running under live macOS
---
scripts/wk/exe.py | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/scripts/wk/exe.py b/scripts/wk/exe.py
index 17f49249..e49b51d6 100644
--- a/scripts/wk/exe.py
+++ b/scripts/wk/exe.py
@@ -3,6 +3,7 @@
import json
import logging
+import os
import re
import subprocess
@@ -77,6 +78,10 @@ def build_cmd_kwargs(cmd, minimized=False, pipe=True, shell=False, **kwargs):
'shell': shell,
}
+ # Strip sudo if appropriate
+ if cmd[0] == 'sudo' and os.name == 'posix' and os.geteuid() == 0:
+ cmd.pop(0)
+
# Add additional kwargs if applicable
for key in 'check cwd encoding errors stderr stdin stdout'.split():
if key in kwargs:
From c7d57ff2667a2de170510255cdcc2bb0e7fbd6f7 Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Thu, 30 Jan 2020 13:07:04 -0700
Subject: [PATCH 05/18] Fixed logging under live macOS
---
scripts/wk/log.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/scripts/wk/log.py b/scripts/wk/log.py
index ee512c95..2cb39764 100644
--- a/scripts/wk/log.py
+++ b/scripts/wk/log.py
@@ -13,7 +13,10 @@ from wk.io import non_clobber_path
# STATIC VARIABLES
-if os.name == 'nt':
+if os.path.exists('/.wk-live-macos'):
+ # Workaround for live macOS env
+ DEFAULT_LOG_DIR = '/var/log/WizardKit'
+elif os.name == 'nt':
# Example: "C:\WK\1955-11-05\WizardKit"
DEFAULT_LOG_DIR = (
f'{os.environ.get("SYSTEMDRIVE", "C:")}/'
From 4a3981e10c123ab038975dcbb239a18d66ae6201 Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Thu, 30 Jan 2020 13:08:13 -0700
Subject: [PATCH 06/18] Adjusted menus under live macOS
---
scripts/wk/std.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/scripts/wk/std.py b/scripts/wk/std.py
index 4e84a25e..60c110f9 100644
--- a/scripts/wk/std.py
+++ b/scripts/wk/std.py
@@ -134,6 +134,8 @@ class Menu():
checkmark = '*'
if 'DISPLAY' in os.environ or PLATFORM == 'Darwin':
checkmark = '✓'
+ if os.path.exists('/.wk-live-macos'):
+ checkmark = '*'
display_name = f'{index if index else name[:1].upper()}: '
if not (index and index >= 10):
display_name = f' {display_name}'
From 417241acb51428c7ac8d5f7c0f57263a6a063973 Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Thu, 30 Jan 2020 13:09:57 -0700
Subject: [PATCH 07/18] Fixed clearing the screen under live macOS
---
scripts/wk/std.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/scripts/wk/std.py b/scripts/wk/std.py
index 60c110f9..b25b7b9f 100644
--- a/scripts/wk/std.py
+++ b/scripts/wk/std.py
@@ -728,7 +728,11 @@ def choice(choices, prompt='答えろ!'):
def clear_screen():
"""Simple wrapper for clear/cls."""
cmd = 'cls' if os.name == 'nt' else 'clear'
- subprocess.run(cmd, check=False, shell=True, stderr=subprocess.PIPE)
+ proc = subprocess.run(cmd, check=False, shell=True, stderr=subprocess.PIPE)
+
+ # Workaround for live macOS env
+ if proc.returncode != 0:
+ print('\033c')
def color_string(strings, colors, sep=' '):
From 86f0f1e5fdc611ff54d79f590db37e221754fa33 Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Thu, 30 Jan 2020 13:16:48 -0700
Subject: [PATCH 08/18] Avoid rare crash concerning disk attributes
* Crash would occur under these circumstances:
* Disk Attributes test was not selected
* One or more other disk tests were selected
* A non-blocking attribute error was detected
---
scripts/wk/hw/diags.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/scripts/wk/hw/diags.py b/scripts/wk/hw/diags.py
index 9aab1887..87b4ec27 100644
--- a/scripts/wk/hw/diags.py
+++ b/scripts/wk/hw/diags.py
@@ -198,7 +198,11 @@ class State():
)
else:
# No blocking errors encountered, check for minor attribute failures
- if not disk.check_attributes(only_blocking=False):
+ if ('Disk Attributes' in disk.tests:
+ and not disk.tests['Disk Attributes'].failed
+ and not disk.check_attributes(only_blocking=False)):
+ # Mid-diag failure detected
+ LOG.warning('Disk attributes failure detected during diagnostics')
disk.tests['Disk Attributes'].failed = True
disk.tests['Disk Attributes'].set_status('Failed')
From c8f95d866a572ead485e11380aa32dfc15d48fcc Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Thu, 30 Jan 2020 13:24:49 -0700
Subject: [PATCH 09/18] Typo fix
---
scripts/wk/hw/diags.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/wk/hw/diags.py b/scripts/wk/hw/diags.py
index 87b4ec27..f36b5471 100644
--- a/scripts/wk/hw/diags.py
+++ b/scripts/wk/hw/diags.py
@@ -198,7 +198,7 @@ class State():
)
else:
# No blocking errors encountered, check for minor attribute failures
- if ('Disk Attributes' in disk.tests:
+ if ('Disk Attributes' in disk.tests
and not disk.tests['Disk Attributes'].failed
and not disk.check_attributes(only_blocking=False)):
# Mid-diag failure detected
From dc6dcfb84528f5f28f683c11603a3dbac7278298 Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Thu, 30 Jan 2020 13:25:46 -0700
Subject: [PATCH 10/18] Revert "Avoid crash during SMART self-test"
This reverts commit cc8c0992f659c89127c24baf420313d0a9f3decc.
---
scripts/wk/hw/obj.py | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/scripts/wk/hw/obj.py b/scripts/wk/hw/obj.py
index 1d9dbde6..7087fda9 100644
--- a/scripts/wk/hw/obj.py
+++ b/scripts/wk/hw/obj.py
@@ -368,13 +368,9 @@ class Disk(BaseObj):
try:
details = self.smartctl['ata_smart_data']['self_test']
except (KeyError, TypeError):
- # Assuming disk lacks SMART support, ignore and return nearly empty dict.
+ # Assuming disk lacks SMART support, ignore and return empty dict.
pass
- # Ensure status is present even if empty
- if 'status' not in details:
- details['status'] = {}
-
# Done
return details
From 385b2158fd11e150362b6f5aa3064cf75c17b798 Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Thu, 30 Jan 2020 13:28:52 -0700
Subject: [PATCH 11/18] Improved method to avoid crash during self-tests
---
scripts/wk/hw/obj.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/scripts/wk/hw/obj.py b/scripts/wk/hw/obj.py
index 7087fda9..a8719358 100644
--- a/scripts/wk/hw/obj.py
+++ b/scripts/wk/hw/obj.py
@@ -497,11 +497,11 @@ class Disk(BaseObj):
_f.write(f'{header_str}\nSMART self-test status:\n {status_str}')
# Check if finished
- if 'remaining_percent' not in test_details['status']:
+ if 'remaining_percent' not in test_details.get('status', {}):
finished = True
break
- elif 'remaining_percent' in test_details['status']:
+ elif 'remaining_percent' in test_details.get('status', {}):
started = True
# Check result
From 06d1f0551b0960fdfbf304b21f7473cd968d9e92 Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Thu, 30 Jan 2020 13:31:34 -0700
Subject: [PATCH 12/18] Dropped oblogout usage in opembox menu
---
.../linux/include_x/airootfs/etc/skel/.config/openbox/menu.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/setup/linux/include_x/airootfs/etc/skel/.config/openbox/menu.xml b/setup/linux/include_x/airootfs/etc/skel/.config/openbox/menu.xml
index 2d560235..2e8fd4a2 100644
--- a/setup/linux/include_x/airootfs/etc/skel/.config/openbox/menu.xml
+++ b/setup/linux/include_x/airootfs/etc/skel/.config/openbox/menu.xml
@@ -234,7 +234,7 @@
-
- oblogout
+ wk-exit
From 154acc52802bb293f74ef70bb7a1e47cde5936e7 Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Thu, 30 Jan 2020 13:36:43 -0700
Subject: [PATCH 13/18] Run build-ufd as current user
* sudo is used for elevated commands instead
* Avoids splitting logs between root and current user
* Addresses issue #150
---
scripts/wk/kit/ufd.py | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/scripts/wk/kit/ufd.py b/scripts/wk/kit/ufd.py
index 9c792b3b..b703fd43 100644
--- a/scripts/wk/kit/ufd.py
+++ b/scripts/wk/kit/ufd.py
@@ -53,11 +53,6 @@ def build_ufd():
try_print.catch_all = False
try_print.indent = 2
- # Check if running with root permissions
- if not linux.running_as_root():
- std.print_error('This script is meant to be run as root')
- std.abort()
-
# Show header
std.print_success(KIT_NAME_FULL)
std.print_warning('UFD Build Tool')
@@ -218,6 +213,7 @@ def copy_source(source, items, overwrite=False):
def create_table(dev_path, use_mbr=False):
"""Create GPT or DOS partition table."""
cmd = [
+ 'sudo',
'parted', dev_path,
'--script',
'--',
@@ -254,6 +250,7 @@ def find_first_partition(dev_path):
def format_partition(dev_path, label):
"""Format first partition on device FAT32."""
cmd = [
+ 'sudo',
'mkfs.vfat',
'-F', '32',
'-n', label,
@@ -287,13 +284,14 @@ def hide_items(ufd_dev, items):
# Hide items
for item in items:
- cmd = [f'yes | mattrib +h "U:/{item}"']
- run_program(cmd, check=False, shell=True)
+ cmd = [f'yes | sudo mattrib +h "U:/{item}"']
+ run_program(cmd, shell=True)
def install_syslinux_to_dev(ufd_dev, use_mbr):
"""Install Syslinux to UFD (dev)."""
cmd = [
+ 'sudo',
'dd',
'bs=440',
'count=1',
@@ -306,6 +304,7 @@ def install_syslinux_to_dev(ufd_dev, use_mbr):
def install_syslinux_to_partition(partition):
"""Install Syslinux to UFD (partition)."""
cmd = [
+ 'sudo',
'syslinux',
'--install',
'--directory',
@@ -335,6 +334,7 @@ def is_valid_path(path_obj, path_type):
def set_boot_flag(dev_path, use_mbr=False):
"""Set modern or legacy boot flag."""
cmd = [
+ 'sudo',
'parted', dev_path,
'set', '1',
'boot' if use_mbr else 'legacy_boot',
@@ -410,6 +410,7 @@ def update_boot_entries():
# Use UUID instead of label
cmd = [
+ 'sudo',
'sed',
'--in-place',
'--regexp-extended',
@@ -428,6 +429,7 @@ def update_boot_entries():
# Entry found, update config files
cmd = [
+ 'sudo',
'sed',
'--in-place',
f's/#{b_comment}#//',
@@ -476,6 +478,7 @@ def verify_ufd(dev_path):
def zero_device(dev_path):
"""Zero-out first 64MB of device."""
cmd = [
+ 'sudo',
'dd',
'bs=4M',
'count=16',
From 64db679a4dc5119e3da077eb8c07afb6f1faad34 Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Thu, 30 Jan 2020 13:47:59 -0700
Subject: [PATCH 14/18] Allow setting verbose value for TryAndPrint obj
* Instead of strictly per-call
---
scripts/wk/std.py | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/scripts/wk/std.py b/scripts/wk/std.py
index b25b7b9f..c715706a 100644
--- a/scripts/wk/std.py
+++ b/scripts/wk/std.py
@@ -388,6 +388,7 @@ class Menu():
class TryAndPrint():
+ # pylint: disable=too-many-instance-attributes
"""Object used to standardize running functions and returning the result.
The errors and warning attributes are used to allow fine-tuned results
@@ -396,11 +397,12 @@ class TryAndPrint():
def __init__(self, msg_bad='FAILED', msg_good='SUCCESS'):
self.catch_all = True
self.indent = INDENT
- self.msg_bad = msg_bad
- self.msg_good = msg_good
- self.width = WIDTH
self.list_errors = ['GenericError']
self.list_warnings = ['GenericWarning']
+ self.msg_bad = msg_bad
+ self.msg_good = msg_good
+ self.verbose = False
+ self.width = WIDTH
def _format_exception_message(self, _exception):
"""Format using the exception's args or name, returns str."""
@@ -525,13 +527,13 @@ class TryAndPrint():
def run(
self, message, function, *args,
- catch_all=None, msg_good=None, verbose=False, **kwargs):
+ catch_all=None, msg_good=None, verbose=None, **kwargs):
# pylint: disable=catching-non-exception
"""Run a function and print the results, returns results as dict.
If catch_all is True then (nearly) all exceptions will be caught.
Otherwise if an exception occurs that wasn't specified it will be
- re-raised. If passed it will override self.catch_all for this call.
+ re-raised.
If the function returns data it will be used instead of msg_good,
msg_bad, or exception text.
@@ -542,6 +544,9 @@ class TryAndPrint():
If verbose is True then exception names or messages will be used for
the result message. Otherwise it will simply be set to result_bad.
+ If catch_all and/or verbose are passed it will override
+ self.catch_all and/or self.verbose for this call.
+
args and kwargs are passed to the function.
"""
LOG.debug('function: %s.%s', function.__module__, function.__name__)
@@ -558,6 +563,8 @@ class TryAndPrint():
result_msg = 'UNKNOWN'
if catch_all is None:
catch_all = self.catch_all
+ if verbose is None:
+ verbose = self.verbose
# Build exception tuples
e_exceptions = tuple(self._get_exception(e) for e in self.list_errors)
From 6eb75c38a3d33a93c0bc19aff078ec60b6de08eb Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Thu, 30 Jan 2020 13:48:51 -0700
Subject: [PATCH 15/18] Report if item(s) are missing during build-ufd
---
scripts/wk/kit/ufd.py | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/scripts/wk/kit/ufd.py b/scripts/wk/kit/ufd.py
index b703fd43..483e2fbb 100644
--- a/scripts/wk/kit/ufd.py
+++ b/scripts/wk/kit/ufd.py
@@ -50,7 +50,9 @@ def build_ufd():
args = docopt(DOCSTRING)
log.update_log_path(dest_name='build-ufd', timestamp=True)
try_print = std.TryAndPrint()
+ try_print.add_error(FileNotFoundError)
try_print.catch_all = False
+ try_print.verbose = True
try_print.indent = 2
# Show header
@@ -190,6 +192,7 @@ def confirm_selections(update=False):
def copy_source(source, items, overwrite=False):
"""Copy source items to /mnt/UFD."""
is_image = source.is_file()
+ items_not_found = False
# Mount source if necessary
if is_image:
@@ -202,13 +205,15 @@ def copy_source(source, items, overwrite=False):
try:
io.recursive_copy(i_source, i_dest, overwrite=overwrite)
except FileNotFoundError:
- # Going to assume (hope) that this is fine
- pass
+ items_not_found = True
# Unmount source if necessary
if is_image:
linux.unmount('/mnt/Source')
+ # Raise exception if item(s) were not found
+ raise FileNotFoundError('One or more items not found')
+
def create_table(dev_path, use_mbr=False):
"""Create GPT or DOS partition table."""
From ad1adba837bf432c15888d73afe8fcc9f1b9dc0b Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Thu, 30 Jan 2020 13:51:23 -0700
Subject: [PATCH 16/18] Add APFS and HFS/HFS+ to RECOMMENDED_MAP_FSTYPES
---
scripts/wk/hw/ddrescue.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/scripts/wk/hw/ddrescue.py b/scripts/wk/hw/ddrescue.py
index f9b0d023..fe47461e 100644
--- a/scripts/wk/hw/ddrescue.py
+++ b/scripts/wk/hw/ddrescue.py
@@ -82,7 +82,9 @@ PANE_RATIOS = (
)
PLATFORM = std.PLATFORM
RECOMMENDED_FSTYPES = re.compile(r'^(ext[234]|ntfs|xfs)$')
-RECOMMENDED_MAP_FSTYPES = re.compile(r'^(cifs|ext[234]|ntfs|vfat|xfs)$')
+RECOMMENDED_MAP_FSTYPES = re.compile(
+ r'^(apfs|cifs|ext[234]|hfs.?|ntfs|vfat|xfs)$'
+ )
SETTING_PRESETS = (
'Default',
'Fast',
From ebbdedef6cfa0ac5528fc513c7eee909ce7b739a Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Thu, 30 Jan 2020 13:59:12 -0700
Subject: [PATCH 17/18] Added get_fstype_macos()
---
scripts/wk/hw/ddrescue.py | 28 +++++++++++++++++++++++++---
scripts/wk/hw/obj.py | 1 +
2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/scripts/wk/hw/ddrescue.py b/scripts/wk/hw/ddrescue.py
index fe47461e..e3433598 100644
--- a/scripts/wk/hw/ddrescue.py
+++ b/scripts/wk/hw/ddrescue.py
@@ -727,6 +727,8 @@ class State():
self.update_progress_pane('Idle')
self.confirm_selections('Start recovery?')
+ # TODO: Unmount source and/or destination under macOS
+
# Prep destination
if self.mode == 'Clone':
self.prep_destination(source_parts, dry_run=docopt_args['--dry-run'])
@@ -1196,7 +1198,6 @@ def build_directory_report(path):
line = f'{path:<{width}}{line}'
report.append(line)
else:
- # TODO Get dir details under macOS
report.append(std.color_string('PATH', 'BLUE'))
report.append(str(path))
@@ -1449,8 +1450,11 @@ def fstype_is_ok(path, map_dir=False):
# Get fstype
if PLATFORM == 'Darwin':
- # TODO: Determine fstype under macOS
- pass
+ try:
+ fstype = get_fstype_macos(path)
+ except (IndexError, TypeError, ValueError):
+ # Ignore for now
+ pass
elif PLATFORM == 'Linux':
cmd = [
'findmnt',
@@ -1517,6 +1521,24 @@ def get_etoc():
return etoc
+def get_fstype_macos(path):
+ """Get fstype for path under macOS, returns str.
+
+ NOTE: This method is not very effecient.
+ """
+ cmd = ['df', path]
+
+ # Get device based on the path
+ proc = exe.run_program(cmd, check=False)
+ dev = proc.stdout.splitlines()[1].split()[0]
+
+ # Get device details
+ dev = hw_obj.Disk(dev)
+
+ # Done
+ return dev.details['fstype']
+
+
def get_object(path):
"""Get object based on path, returns obj."""
obj = None
diff --git a/scripts/wk/hw/obj.py b/scripts/wk/hw/obj.py
index a8719358..dc6175ea 100644
--- a/scripts/wk/hw/obj.py
+++ b/scripts/wk/hw/obj.py
@@ -321,6 +321,7 @@ class Disk(BaseObj):
self.details['bus'] = str(self.details.get('bus', '???')).upper()
self.details['bus'] = self.details['bus'].replace('IMAGE', 'Image')
self.details['bus'] = self.details['bus'].replace('NVME', 'NVMe')
+ self.details['fstype'] = self.details.get('fstype', 'Unknown')
self.details['log-sec'] = self.details.get('log-sec', 512)
self.details['model'] = self.details.get('model', 'Unknown Model')
self.details['name'] = self.details.get('name', self.path)
From a66c27be84a002f44fe91ebebb9a9cdc6966741e Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Thu, 30 Jan 2020 14:01:30 -0700
Subject: [PATCH 18/18] Updated get_disk_details_macos()
---
scripts/wk/hw/obj.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/scripts/wk/hw/obj.py b/scripts/wk/hw/obj.py
index dc6175ea..0c33296e 100644
--- a/scripts/wk/hw/obj.py
+++ b/scripts/wk/hw/obj.py
@@ -656,12 +656,15 @@ def get_disk_details_macos(path):
dev['label'] = dev.pop('VolumeName', '')
dev['model'] = dev.pop('MediaName', 'Unknown')
dev['mountpoint'] = dev.pop('MountPoint', '')
+ dev['name'] = dev.get('name', str(dev['path']))
dev['phy-sec'] = dev.pop('DeviceBlockSize', 512)
dev['serial'] = get_disk_serial_macos(dev['path'])
dev['size'] = dev.pop('Size', -1)
dev['ssd'] = dev.pop('SolidState', False)
dev['vendor'] = ''
- if not dev.get('WholeDisk', True):
+ if dev.get('WholeDisk', True):
+ dev['parent'] = None
+ else:
dev['parent'] = dev.pop('ParentWholeDisk', None)
# Done