logging_handler.py: Reveal log on crash

This commit is contained in:
Mykola Grymalyuk
2023-05-25 11:25:13 -06:00
parent c031917a12
commit 4f0b605786
6 changed files with 45 additions and 12 deletions

View File

@@ -3,6 +3,16 @@
## 0.6.7 ## 0.6.7
- Backend changes: - Backend changes:
- Call `setpgrp()` to prevent app from being killed if parent process is killed (ie. LaunchAgents) - Call `setpgrp()` to prevent app from being killed if parent process is killed (ie. LaunchAgents)
- Rework logging handler:
- Implement formatted logging
- Allowing easier debugging
- Implement per-version file logging
- ex. OpenCore-Patcher-0.6.7.log
- Remove old logs after 1 week of inactivity
- Reduce log rollover to 1MB
- Reveal log file in Finder on main thread crash
- Resolve SharedSupport.dmg pathing error during macOS Installer Verification
- Applicable to systems with 2 (or more) USB Installers with the same name plugged in
## 0.6.6 ## 0.6.6
- Implement option to disable ColorSync downgrade on HD 3000 Macs - Implement option to disable ColorSync downgrade on HD 3000 Macs

View File

@@ -50,7 +50,7 @@ class arguments:
""" """
Enter validation mode Enter validation mode
""" """
logging.info("Set Validation Mode")
validation.PatcherValidation(self.constants) validation.PatcherValidation(self.constants)

View File

@@ -216,6 +216,9 @@ class InitializeLoggingSupport:
applescript.AppleScript(f'display dialog "{error_msg}" with title "OpenCore Legacy Patcher ({self.constants.patcher_version})" buttons {{"OK"}} default button "OK" with icon caution giving up after 30').run() applescript.AppleScript(f'display dialog "{error_msg}" with title "OpenCore Legacy Patcher ({self.constants.patcher_version})" buttons {{"OK"}} default button "OK" with icon caution giving up after 30').run()
# Open log location
subprocess.run(["open", "--reveal", self.log_filepath])
def custom_thread_excepthook(args) -> None: def custom_thread_excepthook(args) -> None:
""" """

View File

@@ -53,7 +53,7 @@ class InstallerCreation():
bool: True if successful, False otherwise bool: True if successful, False otherwise
""" """
logging.info("Extracting macOS installer from InstallAssistant.pkg\n This may take some time") logging.info("Extracting macOS installer from InstallAssistant.pkg")
try: try:
applescript.AppleScript( applescript.AppleScript(
f'''do shell script "installer -pkg {Path(download_path)}/InstallAssistant.pkg -target /"''' f'''do shell script "installer -pkg {Path(download_path)}/InstallAssistant.pkg -target /"'''
@@ -201,7 +201,6 @@ fi
if not any(all_disks[disk]['removable'] is False for partition in all_disks[disk]): if not any(all_disks[disk]['removable'] is False for partition in all_disks[disk]):
continue continue
logging.info(f"disk {disk}: {all_disks[disk]['name']} ({utilities.human_fmt(all_disks[disk]['size'])})")
list_disks.update({ list_disks.update({
disk: { disk: {
"identifier": all_disks[disk]["identifier"], "identifier": all_disks[disk]["identifier"],

View File

@@ -36,6 +36,8 @@ class macOSInstallerDownloadFrame(wx.Frame):
self.available_installers = None self.available_installers = None
self.available_installers_latest = None self.available_installers_latest = None
self.catalog_seed: macos_installer_handler.SeedType = macos_installer_handler.SeedType.DeveloperSeed
self.frame_modal = wx.Dialog(parent, title=title, size=(330, 200)) self.frame_modal = wx.Dialog(parent, title=title, size=(330, 200))
self._generate_elements(self.frame_modal) self._generate_elements(self.frame_modal)
@@ -102,7 +104,8 @@ class macOSInstallerDownloadFrame(wx.Frame):
# Grab installer catalog # Grab installer catalog
def _fetch_installers(): def _fetch_installers():
remote_obj = macos_installer_handler.RemoteInstallerCatalog(seed_override=macos_installer_handler.SeedType.DeveloperSeed) logging.info(f"Fetching installer catalog: {macos_installer_handler.SeedType(self.catalog_seed).name}")
remote_obj = macos_installer_handler.RemoteInstallerCatalog(seed_override=self.catalog_seed)
self.available_installers = remote_obj.available_apps self.available_installers = remote_obj.available_apps
self.available_installers_latest = remote_obj.available_apps_latest self.available_installers_latest = remote_obj.available_apps_latest
@@ -138,8 +141,9 @@ class macOSInstallerDownloadFrame(wx.Frame):
installers = self.available_installers_latest if show_full is False else self.available_installers installers = self.available_installers_latest if show_full is False else self.available_installers
if installers: if installers:
spacer = 0 spacer = 0
logging.info(f"Available installers on SUCatalog ({'All entries' if show_full else 'Latest only'}):")
for app in installers: for app in installers:
logging.info(f"macOS {installers[app]['Version']} ({installers[app]['Build']}):\n - Size: {utilities.human_fmt(installers[app]['Size'])}\n - Source: {installers[app]['Source']}\n - Variant: {installers[app]['Variant']}\n - Link: {installers[app]['Link']}\n") logging.info(f"- macOS {installers[app]['Version']} ({installers[app]['Build']}):\n - Size: {utilities.human_fmt(installers[app]['Size'])}\n - Source: {installers[app]['Source']}\n - Variant: {installers[app]['Variant']}\n - Link: {installers[app]['Link']}\n")
extra = " Beta" if installers[app]['Variant'] in ["DeveloperSeed" , "PublicSeed"] else "" extra = " Beta" if installers[app]['Variant'] in ["DeveloperSeed" , "PublicSeed"] else ""
installer_button = wx.Button(dialog, label=f"macOS {installers[app]['Version']}{extra} ({installers[app]['Build']} - {utilities.human_fmt(installers[app]['Size'])})", pos=(-1, subtitle_label.GetPosition()[1] + subtitle_label.GetSize()[1] + 5 + spacer), size=(270, 30)) installer_button = wx.Button(dialog, label=f"macOS {installers[app]['Version']}{extra} ({installers[app]['Build']} - {utilities.human_fmt(installers[app]['Size'])})", pos=(-1, subtitle_label.GetPosition()[1] + subtitle_label.GetSize()[1] + 5 + spacer), size=(270, 30))
@@ -172,6 +176,7 @@ class macOSInstallerDownloadFrame(wx.Frame):
""" """
Download macOS installer Download macOS installer
""" """
logging.info(f"Selected macOS {app['Version']} ({app['Build']})")
# Notify user whether their model is compatible with the selected installer # Notify user whether their model is compatible with the selected installer
problems = [] problems = []
@@ -185,6 +190,7 @@ class macOSInstallerDownloadFrame(wx.Frame):
problems.append("Lack of internal Keyboard/Mouse in macOS installer.") problems.append("Lack of internal Keyboard/Mouse in macOS installer.")
if problems: if problems:
logging.warning(f"Potential issues with {model} and {app['Version']} ({app['Build']}): {problems}")
problems = "\n".join(problems) problems = "\n".join(problems)
dlg = wx.MessageDialog(self.frame_modal, f"Your model ({model}) may not be fully supported by this installer. You may encounter the following issues:\n\n{problems}\n\nFor more information, see associated page. Otherwise, we recommend using macOS Monterey", "Potential Issues", wx.YES_NO | wx.CANCEL | wx.ICON_WARNING) dlg = wx.MessageDialog(self.frame_modal, f"Your model ({model}) may not be fully supported by this installer. You may encounter the following issues:\n\n{problems}\n\nFor more information, see associated page. Otherwise, we recommend using macOS Monterey", "Potential Issues", wx.YES_NO | wx.CANCEL | wx.ICON_WARNING)
dlg.SetYesNoCancelLabels("View Github Issue", "Download Anyways", "Cancel") dlg.SetYesNoCancelLabels("View Github Issue", "Download Anyways", "Cancel")
@@ -198,6 +204,7 @@ class macOSInstallerDownloadFrame(wx.Frame):
host_space = utilities.get_free_space() host_space = utilities.get_free_space()
needed_space = app['Size'] * 2 needed_space = app['Size'] * 2
if host_space < needed_space: if host_space < needed_space:
logging.error(f"Insufficient space to download and extract: {utilities.human_fmt(host_space)} available vs {utilities.human_fmt(needed_space)} required")
dlg = wx.MessageDialog(self.frame_modal, f"You do not have enough free space to download and extract this installer. Please free up some space and try again\n\n{utilities.human_fmt(host_space)} available vs {utilities.human_fmt(needed_space)} required", "Insufficient Space", wx.OK | wx.ICON_WARNING) dlg = wx.MessageDialog(self.frame_modal, f"You do not have enough free space to download and extract this installer. Please free up some space and try again\n\n{utilities.human_fmt(host_space)} available vs {utilities.human_fmt(needed_space)} required", "Insufficient Space", wx.OK | wx.ICON_WARNING)
dlg.ShowModal() dlg.ShowModal()
return return
@@ -249,6 +256,7 @@ class macOSInstallerDownloadFrame(wx.Frame):
chunklist_stream = network_handler.NetworkUtilities().get(chunklist_link).content chunklist_stream = network_handler.NetworkUtilities().get(chunklist_link).content
if chunklist_stream: if chunklist_stream:
logging.info("Validating macOS installer")
utilities.disable_sleep_while_running() utilities.disable_sleep_while_running()
chunk_obj = integrity_verification.ChunklistVerification(self.constants.payload_path / Path("InstallAssistant.pkg"), chunklist_stream) chunk_obj = integrity_verification.ChunklistVerification(self.constants.payload_path / Path("InstallAssistant.pkg"), chunklist_stream)
if chunk_obj.chunks: if chunk_obj.chunks:
@@ -265,10 +273,13 @@ class macOSInstallerDownloadFrame(wx.Frame):
wx.App.Get().Yield() wx.App.Get().Yield()
if chunk_obj.status == integrity_verification.ChunklistStatus.FAILURE: if chunk_obj.status == integrity_verification.ChunklistStatus.FAILURE:
wx.MessageBox("Chunklist validation failed.\n\nThis generally happens when downloading on unstable connections such as WiFi or cellular.\n\nPlease try redownloading again on a stable connection (ie. Ethernet)", "Corrupted Installer!", wx.OK | wx.ICON_ERROR) logging.error(f"Chunklist validation failed: Hash mismatch on {chunk_obj.current_chunk}")
wx.MessageBox(f"Chunklist validation failed: Hash mismatch on {chunk_obj.current_chunk}\n\nThis generally happens when downloading on unstable connections such as WiFi or cellular.\n\nPlease try redownloading again on a stable connection (ie. Ethernet)", "Corrupted Installer!", wx.OK | wx.ICON_ERROR)
self.on_return_to_main_menu() self.on_return_to_main_menu()
return return
logging.info("macOS installer validated")
# Extract installer # Extract installer
title_label.SetLabel("Extracting macOS Installer") title_label.SetLabel("Extracting macOS Installer")
title_label.Centre(wx.HORIZONTAL) title_label.Centre(wx.HORIZONTAL)

View File

@@ -132,6 +132,7 @@ class macOSInstallerFlashFrame(wx.Frame):
def on_select(self, installer: dict) -> None: def on_select(self, installer: dict) -> None:
logging.info(f"Selected installer: {installer['Short Name']} ({installer['Version']} ({installer['Build']}))")
self.frame_modal.Destroy() self.frame_modal.Destroy()
for child in self.GetChildren(): for child in self.GetChildren():
@@ -186,8 +187,9 @@ class macOSInstallerFlashFrame(wx.Frame):
if self.available_disks: if self.available_disks:
spacer = 5 spacer = 5
entries = len(self.available_disks) entries = len(self.available_disks)
logging.info("Available disks:")
for disk in self.available_disks: for disk in self.available_disks:
logging.info(f"{disk}: {self.available_disks[disk]['name']} - {utilities.human_fmt(self.available_disks[disk]['size'])}") logging.info(f" - {disk}: {self.available_disks[disk]['name']} - {utilities.human_fmt(self.available_disks[disk]['size'])}")
disk_button = wx.Button(self.frame_modal, label=f"{disk}: {self.available_disks[disk]['name']} - {utilities.human_fmt(self.available_disks[disk]['size'])}", pos=(-1, warning_label.GetPosition()[1] + warning_label.GetSize()[1] + spacer), size=(300, 30)) disk_button = wx.Button(self.frame_modal, label=f"{disk}: {self.available_disks[disk]['name']} - {utilities.human_fmt(self.available_disks[disk]['size'])}", pos=(-1, warning_label.GetPosition()[1] + warning_label.GetSize()[1] + spacer), size=(300, 30))
disk_button.Bind(wx.EVT_BUTTON, lambda event, temp=disk: self.on_select_disk(self.available_disks[temp], installer)) disk_button.Bind(wx.EVT_BUTTON, lambda event, temp=disk: self.on_select_disk(self.available_disks[temp], installer))
disk_button.Centre(wx.HORIZONTAL) disk_button.Centre(wx.HORIZONTAL)
@@ -222,6 +224,8 @@ class macOSInstallerFlashFrame(wx.Frame):
if answer != wx.YES: if answer != wx.YES:
return return
logging.info(f"Selected disk: {disk['name']}")
self.frame_modal.Destroy() self.frame_modal.Destroy()
for child in self.GetChildren(): for child in self.GetChildren():
@@ -262,6 +266,7 @@ class macOSInstallerFlashFrame(wx.Frame):
# Prepare resources # Prepare resources
if self._prepare_resources(installer['Path'], disk['identifier']) is False: if self._prepare_resources(installer['Path'], disk['identifier']) is False:
logging.error("Failed to prepare resources, cannot continue.")
wx.MessageBox("Failed to prepare resources, cannot continue.", "Error", wx.OK | wx.ICON_ERROR) wx.MessageBox("Failed to prepare resources, cannot continue.", "Error", wx.OK | wx.ICON_ERROR)
self.on_return_to_main_menu() self.on_return_to_main_menu()
return return
@@ -281,6 +286,7 @@ class macOSInstallerFlashFrame(wx.Frame):
initial_bytes_written = float(utilities.monitor_disk_output(root_disk)) initial_bytes_written = float(utilities.monitor_disk_output(root_disk))
self.result = False self.result = False
def _flash(): def _flash():
logging.info(f"Flashing {installer['Path']} to {root_disk}")
self.result = self._flash_installer(root_disk) self.result = self._flash_installer(root_disk)
thread = threading.Thread(target=_flash) thread = threading.Thread(target=_flash)
@@ -298,6 +304,7 @@ class macOSInstallerFlashFrame(wx.Frame):
wx.Yield() wx.Yield()
if self.result is False: if self.result is False:
logging.error("Failed to flash installer, cannot continue.")
self.on_return_to_main_menu() self.on_return_to_main_menu()
return return
@@ -522,12 +529,15 @@ class macOSInstallerFlashFrame(wx.Frame):
kdk_dmg_path.unlink() kdk_dmg_path.unlink()
def _validate_installer_pkg(self, disk: str) -> bool: def _validate_installer_pkg(self, disk: str) -> bool:
verification_success = False logging.info("Validating installer pkg")
error_message = "" error_message = ""
def _integrity_check(): def _integrity_check():
nonlocal error_message nonlocal error_message
path = utilities.grab_mount_point_from_disk(disk + "s2") for folder in Path(utilities.grab_mount_point_from_disk(disk + "s2")).glob("*.app"):
dmg_path = path + f"/{path.split('/')[2]}.app/Contents/SharedSupport/SharedSupport.dmg" if folder.is_dir():
dmg_path = folder / "Contents" / "SharedSupport" / "SharedSupport.dmg"
break
if not Path(dmg_path).exists(): if not Path(dmg_path).exists():
logging.error(f"Failed to find {dmg_path}") logging.error(f"Failed to find {dmg_path}")
error_message = f"Failed to find {dmg_path}" error_message = f"Failed to find {dmg_path}"
@@ -547,10 +557,10 @@ class macOSInstallerFlashFrame(wx.Frame):
while thread.is_alive(): while thread.is_alive():
wx.Yield() wx.Yield()
if verification_success: if error_message == "":
logging.info("Installer pkg validated")
return error_message return error_message
logging.error(error_message)
return error_message return error_message