From 3134530b4cbf873a3bc3e6ad9267082e718ae964 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Wed, 18 May 2022 19:41:13 -0600 Subject: [PATCH] Move payload reroutes to dedicated class --- gui/gui_main.py | 2 +- resources/main.py | 44 ++----------------------- resources/reroute_payloads.py | 61 +++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 43 deletions(-) create mode 100644 resources/reroute_payloads.py diff --git a/gui/gui_main.py b/gui/gui_main.py index 90e08344c..5b868071b 100644 --- a/gui/gui_main.py +++ b/gui/gui_main.py @@ -1288,7 +1288,7 @@ class wx_python_gui: thread_ia = threading.Thread(target=ia) thread_ia.start() - while thread_ia.is_alive(): + while thread_ia.is_alive() or self.constants.unpack_thread.is_alive(): self.pulse_alternative(self.progress_bar) wx.GetApp().Yield() available_installers = self.available_installers diff --git a/resources/main.py b/resources/main.py index 78798de25..47ac4ac4d 100644 --- a/resources/main.py +++ b/resources/main.py @@ -1,17 +1,14 @@ # Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk from __future__ import print_function -import plistlib import subprocess import sys -import tempfile from pathlib import Path -import atexit import time import threading -from resources import build, cli_menu, constants, utilities, device_probe, os_probe, defaults, arguments, install, tui_helpers +from resources import build, cli_menu, constants, utilities, device_probe, os_probe, defaults, arguments, install, tui_helpers, reroute_payloads from data import model_array class OpenCoreLegacyPatcher: @@ -45,7 +42,7 @@ class OpenCoreLegacyPatcher: launcher_script = launcher_script.replace("/resources/main.py", "/OpenCore-Patcher-GUI.command") self.constants.launcher_binary = launcher_binary self.constants.launcher_script = launcher_script - self.constants.unpack_thread = threading.Thread(target=self.reroute_payloads) + self.constants.unpack_thread = threading.Thread(target=reroute_payloads.reroute_payloads(self.constants).setup_tmp_disk_image) self.constants.unpack_thread.start() defaults.generate_defaults.probe(self.computer.real_model, True, self.constants) @@ -66,43 +63,6 @@ class OpenCoreLegacyPatcher: else: print(f"- No arguments present, loading {'GUI' if self.constants.wxpython_variant is True else 'TUI'} mode") - def reroute_payloads(self): - if self.constants.launcher_binary and self.constants.wxpython_variant is True and not self.constants.launcher_script: - print("- Running in Binary GUI mode, switching to tmp directory") - self.temp_dir = tempfile.TemporaryDirectory() - print(f"- New payloads location: {self.temp_dir.name}") - print("- Creating payloads directory") - Path(self.temp_dir.name / Path("payloads")).mkdir(parents=True, exist_ok=True) - self.clean_up() - output = subprocess.run( - [ - "hdiutil", "attach", "-noverify", f"{self.constants.payload_path}.dmg", "-mountpoint", Path(self.temp_dir.name / Path("payloads")), - "-nobrowse", "-shadow", Path(self.temp_dir.name / Path("payloads_overlay")), "-passphrase", "password" - ], - stdout=subprocess.PIPE, stderr=subprocess.STDOUT - ) - if output.returncode == 0: - print("- Mounted payloads.dmg") - self.constants.current_path = Path(self.temp_dir.name) - self.constants.payload_path = Path(self.temp_dir.name) / Path("payloads") - atexit.register(self.clean_up) - else: - print("- Failed to mount payloads.dmg") - print(f"Output: {output.stdout.decode()}") - print(f"Return Code: {output.returncode}") - print("- Exiting...") - sys.exit(1) - - def clean_up(self): - # Grab info on all dmgs mounted - dmg_info = subprocess.run(["hdiutil", "info", "-plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - dmg_info = plistlib.loads(dmg_info.stdout) - - for image in dmg_info["images"]: - if image["image-path"].endswith("payloads.dmg"): - print(f"- Unmounting payloads.dmg") - subprocess.run(["hdiutil", "detach", image["system-entities"][0]["dev-entry"], "-force"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - def main_menu(self): response = None diff --git a/resources/reroute_payloads.py b/resources/reroute_payloads.py new file mode 100644 index 000000000..2a407e60a --- /dev/null +++ b/resources/reroute_payloads.py @@ -0,0 +1,61 @@ +# Reoute binaries to tmp directory, and mount a disk image of the payloads +# Implements a shadowfile to avoid direct writes to the dmg +# Copyright (C) 2022, Mykola Grymalyuk + +import sys +import plistlib +from pathlib import Path +import subprocess +import tempfile +import atexit + +class reroute_payloads: + def __init__(self, constants): + self.constants = constants + + def setup_tmp_disk_image(self): + # Create a temp directory to mount the payloads.dmg + # Then reroute r/w to this new temp directory + # Currently only applicable for GUI variant + if self.constants.launcher_binary and self.constants.wxpython_variant is True and not self.constants.launcher_script: + print("- Running in Binary GUI mode, switching to tmp directory") + self.temp_dir = tempfile.TemporaryDirectory() + print(f"- New payloads location: {self.temp_dir.name}") + print("- Creating payloads directory") + Path(self.temp_dir.name / Path("payloads")).mkdir(parents=True, exist_ok=True) + self.unmount_active_dmgs() + output = subprocess.run( + [ + "hdiutil", "attach", "-noverify", f"{self.constants.payload_path}.dmg", + "-mountpoint", Path(self.temp_dir.name / Path("payloads")), + "-nobrowse", "-shadow", Path(self.temp_dir.name / Path("payloads_overlay")), + "-passphrase", "password" + ], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ) + if output.returncode == 0: + print("- Mounted payloads.dmg") + self.constants.current_path = Path(self.temp_dir.name) + self.constants.payload_path = Path(self.temp_dir.name) / Path("payloads") + atexit.register(self.unmount_active_dmgs) + else: + print("- Failed to mount payloads.dmg") + print(f"Output: {output.stdout.decode()}") + print(f"Return Code: {output.returncode}") + print("- Exiting...") + sys.exit(1) + + def unmount_active_dmgs(self): + # Find all DMGs that are mounted, and forcefully unmount them + # If our disk image was previously mounted, we need to unmount it to use again + # This can happen if we crash during a previous scession, however 'atexit' class should hopefully avoid this + dmg_info = subprocess.run(["hdiutil", "info", "-plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + dmg_info = plistlib.loads(dmg_info.stdout) + + for image in dmg_info["images"]: + if image["image-path"].endswith("payloads.dmg"): + print(f"- Unmounting payloads.dmg") + subprocess.run( + ["hdiutil", "detach", image["system-entities"][0]["dev-entry"], "-force"], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ) \ No newline at end of file