From d7788540d9c3b95fab018adf5f7db2a06f5e3350 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Mon, 11 Apr 2022 16:11:33 -0600 Subject: [PATCH 01/21] Initial Commit --- .../workflows/build-app-wxpython-offline.yml | 6 + payloads/Config/config.plist | 18 + .../InstallPackage/OCLP-Install-Setup.pkgproj | 874 ++++++++++++++++++ payloads/InstallPackage/postinstall.sh | 12 + .../AutoPkgInstaller-v1.0.0-DEBUG.zip | Bin 0 -> 12468 bytes .../AutoPkgInstaller-v1.0.0-RELEASE.zip | Bin 0 -> 10955 bytes ...a.opencore-legacy-patcher.auto-patch.plist | 15 + resources/arguments.py | 5 +- resources/build.py | 20 +- resources/constants.py | 19 + resources/sys_patch.py | 62 +- resources/sys_patch_auto.py | 99 ++ resources/utilities.py | 10 +- 13 files changed, 1122 insertions(+), 18 deletions(-) create mode 100644 payloads/InstallPackage/OCLP-Install-Setup.pkgproj create mode 100755 payloads/InstallPackage/postinstall.sh create mode 100644 payloads/Kexts/Acidanthera/AutoPkgInstaller-v1.0.0-DEBUG.zip create mode 100644 payloads/Kexts/Acidanthera/AutoPkgInstaller-v1.0.0-RELEASE.zip create mode 100644 payloads/com.dortania.opencore-legacy-patcher.auto-patch.plist create mode 100644 resources/sys_patch_auto.py diff --git a/.github/workflows/build-app-wxpython-offline.yml b/.github/workflows/build-app-wxpython-offline.yml index ef6a67576..caf6aa968 100644 --- a/.github/workflows/build-app-wxpython-offline.yml +++ b/.github/workflows/build-app-wxpython-offline.yml @@ -22,12 +22,18 @@ jobs: - run: 'codesign -s "Developer ID Application: Mykola Grymalyuk (S74BDJXQMD)" -v --force --deep --timestamp --entitlements ./payloads/entitlements.plist -o runtime "dist/OpenCore-Patcher.app"' - run: cd dist; zip -r ../OpenCore-Patcher-wxPython.app.zip OpenCore-Patcher.app - run: ./../sign-wxpython.sh + - run: packagesbuild ./payloads/InstallPackage/OCLP-Install-Setup.pkgproj - run: mv ./OpenCore-Patcher-wxPython.app.zip ./OpenCore-Patcher-GUI-Offline.app.zip - name: Upload App to Artifacts uses: actions/upload-artifact@v2 with: name: OpenCore-Patcher.app (GUI Offline) path: OpenCore-Patcher-GUI-Offline.app.zip + - name: Upload Package to Artifacts + uses: actions/upload-artifact@v2 + with: + name: OCLP-Install.pkg + path: ./dist/OCLP-Install.pkg - name: Upload to Release if: github.event_name == 'release' uses: svenstaro/upload-release-action@e74ff71f7d8a4c4745b560a485cc5fdb9b5b999d diff --git a/payloads/Config/config.plist b/payloads/Config/config.plist index 4aa2950bd..ea7cf418d 100644 --- a/payloads/Config/config.plist +++ b/payloads/Config/config.plist @@ -1203,6 +1203,24 @@ PlistPath Contents/Info.plist + + Arch + x86_64 + BundlePath + AutoPkgInstaller.kext + Comment + Chainload OpenCore-Patcher installation + Enabled + + ExecutablePath + Contents/MacOS/AutoPkgInstaller + MaxKernel + + MinKernel + 20.0.0 + PlistPath + Contents/Info.plist + Block diff --git a/payloads/InstallPackage/OCLP-Install-Setup.pkgproj b/payloads/InstallPackage/OCLP-Install-Setup.pkgproj new file mode 100644 index 000000000..52fd13e28 --- /dev/null +++ b/payloads/InstallPackage/OCLP-Install-Setup.pkgproj @@ -0,0 +1,874 @@ + + + + + PACKAGES + + + MUST-CLOSE-APPLICATION-ITEMS + + MUST-CLOSE-APPLICATIONS + + PACKAGE_FILES + + DEFAULT_INSTALL_LOCATION + / + HIERARCHY + + CHILDREN + + + CHILDREN + + GID + 80 + PATH + Applications + PATH_TYPE + 0 + PERMISSIONS + 509 + TYPE + 1 + UID + 0 + + + CHILDREN + + + CHILDREN + + + CHILDREN + + + BUNDLE_CAN_DOWNGRADE + + BUNDLE_POSTINSTALL_PATH + + PATH_TYPE + 0 + + BUNDLE_PREINSTALL_PATH + + PATH_TYPE + 0 + + CHILDREN + + GID + 80 + PATH + ../../dist/OpenCore-Patcher.app + PATH_TYPE + 1 + PERMISSIONS + 493 + TYPE + 3 + UID + 0 + + + GID + 80 + PATH + Dortania + PATH_TYPE + 2 + PERMISSIONS + 509 + TYPE + 2 + UID + 0 + + + GID + 80 + PATH + Application Support + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Automator + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Documentation + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Extensions + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Filesystems + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Frameworks + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Input Methods + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Internet Plug-Ins + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Keyboard Layouts + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + + CHILDREN + + GID + 0 + PATH + /Users/mykolagrymalyuk/Developer/OpenCore-Legacy-Patcher/payloads/com.dortania.opencore-legacy-patcher.auto-patch.plist + PATH_TYPE + 0 + PERMISSIONS + 420 + TYPE + 3 + UID + 0 + + + GID + 0 + PATH + LaunchAgents + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + LaunchDaemons + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + PreferencePanes + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Preferences + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 80 + PATH + Printers + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + PrivilegedHelperTools + PATH_TYPE + 0 + PERMISSIONS + 1005 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + QuickLook + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + QuickTime + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Screen Savers + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Scripts + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Services + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Widgets + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + GID + 0 + PATH + Library + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + + CHILDREN + + GID + 0 + PATH + Shared + PATH_TYPE + 0 + PERMISSIONS + 1023 + TYPE + 1 + UID + 0 + + + GID + 80 + PATH + Users + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + GID + 0 + PATH + / + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + PAYLOAD_TYPE + 0 + PRESERVE_EXTENDED_ATTRIBUTES + + SHOW_INVISIBLE + + SPLIT_FORKS + + TREAT_MISSING_FILES_AS_WARNING + + VERSION + 5 + + PACKAGE_SCRIPTS + + POSTINSTALL_PATH + + PATH + postinstall.sh + PATH_TYPE + 1 + + PREINSTALL_PATH + + PATH_TYPE + 0 + + RESOURCES + + + PACKAGE_SETTINGS + + AUTHENTICATION + 1 + CONCLUSION_ACTION + 0 + FOLLOW_SYMBOLIC_LINKS + + IDENTIFIER + com.mygreatcompany.pkg.OCLP-Install + LOCATION + 0 + NAME + OCLP-Install + OVERWRITE_PERMISSIONS + + PAYLOAD_SIZE + -1 + REFERENCE_PATH + + RELOCATABLE + + USE_HFS+_COMPRESSION + + VERSION + 1.0 + + TYPE + 0 + UUID + 4312D78E-7981-41F2-A0E9-5C7E11AC61C5 + + + PROJECT + + PROJECT_COMMENTS + + NOTES + + + + PROJECT_PRESENTATION + + BACKGROUND + + APPAREANCES + + DARK_AQUA + + LIGHT_AQUA + + + SHARED_SETTINGS_FOR_ALL_APPAREANCES + + + INSTALLATION_STEPS + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewIntroductionController + INSTALLER_PLUGIN + Introduction + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewReadMeController + INSTALLER_PLUGIN + ReadMe + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewLicenseController + INSTALLER_PLUGIN + License + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewDestinationSelectController + INSTALLER_PLUGIN + TargetSelect + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewInstallationTypeController + INSTALLER_PLUGIN + PackageSelection + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewInstallationController + INSTALLER_PLUGIN + Install + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewSummaryController + INSTALLER_PLUGIN + Summary + LIST_TITLE_KEY + InstallerSectionTitle + + + INTRODUCTION + + LOCALIZATIONS + + + LICENSE + + LOCALIZATIONS + + MODE + 0 + + README + + LOCALIZATIONS + + + TITLE + + LOCALIZATIONS + + + LANGUAGE + English + VALUE + OCLP-Install + + + + + PROJECT_REQUIREMENTS + + LIST + + RESOURCES + + ROOT_VOLUME_ONLY + + + PROJECT_SETTINGS + + BUILD_FORMAT + 0 + BUILD_PATH + + PATH + ../../dist + PATH_TYPE + 1 + + EXCLUDED_FILES + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + .DS_Store + TYPE + 0 + + + PROTECTED + + PROXY_NAME + Remove .DS_Store files + PROXY_TOOLTIP + Remove ".DS_Store" files created by the Finder. + STATE + + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + .pbdevelopment + TYPE + 0 + + + PROTECTED + + PROXY_NAME + Remove .pbdevelopment files + PROXY_TOOLTIP + Remove ".pbdevelopment" files created by ProjectBuilder or Xcode. + STATE + + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + CVS + TYPE + 1 + + + REGULAR_EXPRESSION + + STRING + .cvsignore + TYPE + 0 + + + REGULAR_EXPRESSION + + STRING + .cvspass + TYPE + 0 + + + REGULAR_EXPRESSION + + STRING + .svn + TYPE + 1 + + + REGULAR_EXPRESSION + + STRING + .git + TYPE + 1 + + + REGULAR_EXPRESSION + + STRING + .gitignore + TYPE + 0 + + + PROTECTED + + PROXY_NAME + Remove SCM metadata + PROXY_TOOLTIP + Remove helper files and folders used by the CVS, SVN or Git Source Code Management systems. + STATE + + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + classes.nib + TYPE + 0 + + + REGULAR_EXPRESSION + + STRING + designable.db + TYPE + 0 + + + REGULAR_EXPRESSION + + STRING + info.nib + TYPE + 0 + + + PROTECTED + + PROXY_NAME + Optimize nib files + PROXY_TOOLTIP + Remove "classes.nib", "info.nib" and "designable.nib" files within .nib bundles. + STATE + + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + Resources Disabled + TYPE + 1 + + + PROTECTED + + PROXY_NAME + Remove Resources Disabled folders + PROXY_TOOLTIP + Remove "Resources Disabled" folders. + STATE + + + + SEPARATOR + + + + NAME + OCLP-Install + PAYLOAD_ONLY + + TREAT_MISSING_PRESENTATION_DOCUMENTS_AS_WARNING + + + + TYPE + 0 + VERSION + 2 + + diff --git a/payloads/InstallPackage/postinstall.sh b/payloads/InstallPackage/postinstall.sh new file mode 100755 index 000000000..cebecc0e7 --- /dev/null +++ b/payloads/InstallPackage/postinstall.sh @@ -0,0 +1,12 @@ +#!/bin/sh +app_path="/Library/Application Support/Dortania/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher" +args="--patch_sys_vol" +"$app_path" "$args" > "/Users/Shared/.OCLP-AutoPatcher-Log-$(date +"%Y_%m_%d_%I_%M_%p").txt" +log show --last boot > "/Users/Shared/.System-Log-$(date +"%Y_%m_%d_%I_%M_%p").txt" +dmesg > "/Users/Shared/.Kernel-Log-$(date +"%Y_%m_%d_%I_%M_%p").txt" +ps aux > "/Users/Shared/.Process-List-$(date +"%Y_%m_%d_%I_%M_%p").txt" +ls -l "/System/Volumes/Update/mnt1/System/Library/KernelCollections" > "/Users/Shared/.Kernel-Collections-$(date +"%Y_%m_%d_%I_%M_%p").txt" +kmutil showloaded > "/Users/Shared/.Loaded-Kexts-$(date +"%Y_%m_%d_%I_%M_%p").txt" +kmutil inspect -B "/System/Volumes/Update/mnt1/System/Library/KernelCollections/BootKernelExtensions.kc" > "/Users/Shared/.BootKernelExtensions-$(date +"%Y_%m_%d_%I_%M_%p").txt" +kmutil inspect -S "/System/Volumes/Update/mnt1/System/Library/KernelCollections/SystemKernelExtensions.kc" > "/Users/Shared/.SystemKernelExtensions-$(date +"%Y_%m_%d_%I_%M_%p").txt" +reboot \ No newline at end of file diff --git a/payloads/Kexts/Acidanthera/AutoPkgInstaller-v1.0.0-DEBUG.zip b/payloads/Kexts/Acidanthera/AutoPkgInstaller-v1.0.0-DEBUG.zip new file mode 100644 index 0000000000000000000000000000000000000000..ff0cd0f17884368e3ee6d62a5a8c057724f4bc31 GIT binary patch literal 12468 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 bKM%HlMJo2Ahiqur4{wTx6BEq)cl3V%i_ZA( literal 0 HcmV?d00001 diff --git a/payloads/Kexts/Acidanthera/AutoPkgInstaller-v1.0.0-RELEASE.zip b/payloads/Kexts/Acidanthera/AutoPkgInstaller-v1.0.0-RELEASE.zip new file mode 100644 index 0000000000000000000000000000000000000000..23cbded43581b354cea5f534ff41e4d15e5098e1 GIT binary patch literal 10955 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 + + + + Label + com.dortania.opencore-legacy-patcher.auto-patch + ProgramArguments + + /Library/Application Support/Dortania/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher + --auto_patch + + RunAtLoad + + + diff --git a/resources/arguments.py b/resources/arguments.py index 649e025d9..d6699a5c1 100644 --- a/resources/arguments.py +++ b/resources/arguments.py @@ -1,5 +1,5 @@ import sys -from resources import defaults, build, utilities, validation, sys_patch +from resources import defaults, build, utilities, validation, sys_patch, sys_patch_auto from data import model_array # Generic building args @@ -105,3 +105,6 @@ If you plan to create the USB for another machine, please select the "Change Mod elif self.args.unpatch_sys_vol: print("- Set System Volume unpatching") sys_patch.PatchSysVolume(settings.custom_model or settings.computer.real_model, settings, None).start_unpatch() + elif self.args.auto_patch: + print("- Set Auto patching") + sys_patch_auto.AutomaticSysPatch.start_auto_patch(settings) \ No newline at end of file diff --git a/resources/build.py b/resources/build.py index bbf538434..109e44f38 100644 --- a/resources/build.py +++ b/resources/build.py @@ -858,20 +858,20 @@ class BuildOpenCore: print("- Setting Vault configuration") self.config["Misc"]["Security"]["Vault"] = "Secure" self.get_efi_binary_by_path("OpenShell.efi", "Misc", "Tools")["Enabled"] = False - if self.constants.custom_sip_value: - print(f"- Setting SIP value to: {self.constants.custom_sip_value}") - self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["csr-active-config"] = utilities.string_to_hex(self.constants.custom_sip_value.lstrip("0x")) - # Work-around 12.3 bug where Electron apps no longer launch with SIP lowered - # Unknown whether this is intended behavior or not, revisit with 12.4 - print("- Adding ipc_control_port_options=0 to boot-args") - self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " ipc_control_port_options=0" - elif self.constants.sip_status is False: - print("- Set SIP to allow Root Volume patching") - self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["csr-active-config"] = binascii.unhexlify("02080000") + if self.constants.sip_status is False or self.constants.custom_sip_value: # Work-around 12.3 bug where Electron apps no longer launch with SIP lowered # Unknown whether this is intended behavior or not, revisit with 12.4 print("- Adding ipc_control_port_options=0 to boot-args") self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " ipc_control_port_options=0" + # Adds AutoPkgInstaller for Automatic OpenCore-Patcher installation + self.enable_kext("AutoPkgInstaller.kext", self.constants.autopkg_version, self.constants.autopkg_path) + if self.constants.custom_sip_value: + print(f"- Setting SIP value to: {self.constants.custom_sip_value}") + self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["csr-active-config"] = utilities.string_to_hex(self.constants.custom_sip_value.lstrip("0x")) + elif self.constants.sip_status is False: + print("- Set SIP to allow Root Volume patching") + self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["csr-active-config"] = binascii.unhexlify("02080000") + # if self.constants.amfi_status is False: # print("- Disabling AMFI") # self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " amfi_get_out_of_my_way=1" diff --git a/resources/constants.py b/resources/constants.py index 1b96421e7..76ec8a1f4 100644 --- a/resources/constants.py +++ b/resources/constants.py @@ -23,6 +23,7 @@ class Constants: self.repo_link = "https://github.com/dortania/OpenCore-Legacy-Patcher" self.repo_link_latest = f"{self.repo_link}/releases/tag/{self.patcher_version}" self.copyright_date = "Copyright © 2020-2022 Dortania" + self.installer_pkg_url = f"{self.repo_link_latest}/OCLP-Install.pkg" # OpenCore Versioning # https://github.com/acidanthera/OpenCorePkg @@ -44,6 +45,7 @@ class Constants: self.cpufriend_version = "1.2.4" # CPUFriend self.bluetool_version = "2.6.1" # BlueToolFixup (BrcmPatchRAM) self.cslvfixup_version = "2.6.1" # CSLVFixup + self.autopkg_version = "1.0.0" # AutoPkgInstaller ## Apple ## https://www.apple.com @@ -211,6 +213,11 @@ class Constants: @property def payload_mnt1_path(self): return self.payload_path / Path("mnt1") + + # Launch Agent + @property + def auto_patch_launch_agent_path(self): + return self.payload_path / Path("com.dortania.opencore-legacy-patcher.auto-patch.plist") # ACPI @property @@ -378,6 +385,10 @@ class Constants: @property def cslvfixup_path(self): return self.payload_kexts_path / Path(f"Acidanthera/CSLVFixup-v{self.cslvfixup_version}.zip") + + @property + def autopkg_path(self): + return self.payload_kexts_path / Path(f"Acidanthera/AutoPkgInstaller-v{self.autopkg_version}-{self.kext_variant}.zip") @property def innie_path(self): @@ -549,6 +560,14 @@ class Constants: @property def gui_path(self): return self.payload_path / Path("Icon/Resources.zip") + + @property + def postinstall_script_path(self): + return self.payload_path / Path("InstallPackage/postinstall") + + @property + def installer_pkg_path(self): + return self.payload_path / Path("InstallPackage/OCLP-Install.pkg") # Apple Payloads Paths diff --git a/resources/sys_patch.py b/resources/sys_patch.py index ecc09e82e..301fb7c82 100644 --- a/resources/sys_patch.py +++ b/resources/sys_patch.py @@ -10,7 +10,6 @@ import shutil import subprocess import zipfile from pathlib import Path -import sys from resources import constants, utilities, generate_smbios, sys_patch_download, sys_patch_detect from data import sip_data, sys_patch_data, os_data @@ -247,7 +246,7 @@ class PatchSysVolume: if result.returncode != 0 or (self.constants.detected_os < os_data.os_data.catalina and "KernelCache ID" not in result.stdout.decode()): self.success_status = False print("- Unable to build new kernel cache") - print("\nReason for Patch Failure:") + print(f"\nReason for Patch Failure({result.returncode}):") print(result.stdout.decode()) print("") print("\nPlease reboot the machine to avoid potential issues rerunning the patcher") @@ -283,8 +282,13 @@ class PatchSysVolume: input("\nPress [ENTER] to continue") def unmount_drive(self): - print("- Unmounting Root Volume (Don't worry if this fails)") - utilities.elevated(["diskutil", "unmount", self.root_mount_path], stdout=subprocess.PIPE).stdout.decode().strip().encode() + # When we detect we're chainloaded in the Installer, skip unmounting + # We have logging in place to pull additional info after we're done + if not "Library/InstallerSandboxes/" in self.constants.payload_path: + print("- Unmounting Root Volume (Don't worry if this fails)") + utilities.elevated(["diskutil", "unmount", self.root_mount_path], stdout=subprocess.PIPE).stdout.decode().strip().encode() + else: + print("- Skipping snapshot unmount due to Installer environment") def delete_old_binaries(self, vendor_patch): for delete_current_kext in vendor_patch: @@ -306,6 +310,51 @@ class PatchSysVolume: utilities.process_status(utilities.elevated(["chmod", "-Rf", "755", f"{self.mount_extensions}/{add_current_kext}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) utilities.process_status(utilities.elevated(["chown", "-Rf", "root:wheel", f"{self.mount_extensions}/{add_current_kext}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + def install_auto_patcher_launch_agent(self): + # Installs the following: + # - OpenCore-Patcher.app in /Library/Application Support/Dortania/ + # - com.dortania.opencore-legacy-patcher.auto-patch.plist in /Library/LaunchAgents/ + if self.constants.launcher_script is None: + # Verify our binary isn't located in '/Library/Application Support/Dortania/' + # As we'd simply be duplicating ourselves + if not self.constants.launcher_binary.startswith("/Library/Application Support/Dortania/"): + print("- Installing Auto Patcher Launch Agent") + + if not Path("Library/Application Support/Dortania").exists(): + print("- Creating /Library/Application Support/Dortania/") + utilities.process_status(utilities.elevated(["mkdir", "-p", "/Library/Application Support/Dortania"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + + print("- Copying OpenCore Patcher to /Library/Application Support/Dortania/") + if Path("/Library/Application Support/Dortania/OpenCore-Patcher.app").exists(): + print("- Deleting existing OpenCore-Patcher") + utilities.process_status(utilities.elevated(["rm", "-R", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + + # Strip everything after OpenCore-Patcher.app + path = self.constants.launcher_binary.split("OpenCore-Patcher.app")[0] + "OpenCore-Patcher.app" + print(f"- Copying {path} to /Library/Application Support/Dortania/") + utilities.process_status(utilities.elevated(["cp", "-R", path, "/Library/Application Support/Dortania/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + + # Copy over our launch agent + print("- Copying auto-patch.plist Launch Agent to /Library/LaunchAgents/") + if Path("/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist").exists(): + print("- Deleting existing auto-patch.plist") + utilities.process_status(utilities.elevated(["rm", "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + utilities.process_status(utilities.elevated(["cp", self.constants.auto_patch_launch_agent_path, "/Library/LaunchAgents/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + + # Set the permissions on the com.dortania.opencore-legacy-patcher.auto-patch.plist + print("- Setting permissions on auto-patch.plist") + utilities.process_status(utilities.elevated(["chmod", "644", "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + utilities.process_status(utilities.elevated(["chown", "root:wheel", "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + + # Making app alias + # Simply an easy way for users to notice the app + # If there's already an alias or exiting app, skip + if not Path("/Applications/OpenCore-Patcher.app").exists(): + print("- Making app alias") + utilities.process_status(utilities.elevated(["ln", "-s", "/Library/Application Support/Dortania/OpenCore-Patcher.app", "/Applications/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + else: + print("- Skipping Auto Patcher Launch Agent, not supported when running from source") + def clean_skylight_plugins(self): if (Path(self.mount_application_support) / Path("SkyLightPlugins/")).exists(): print("- Found SkylightPlugins folder, removing") @@ -649,6 +698,9 @@ class PatchSysVolume: print("- Installing Legacy Mux Brightness support") self.add_legacy_mux_patch() + if self.constants.wxpython_variant is True and self.constants.detected_os >= os_data.os_data.big_sur: + self.install_auto_patcher_launch_agent() + if self.validate is False: self.rebuild_snapshot() @@ -667,7 +719,7 @@ class PatchSysVolume: return output def download_files(self): - if self.constants.gui_mode is False: + if self.constants.gui_mode is False or (self.constants.wxpython_variant is True and "Library/InstallerSandboxes/" in self.constants.payload_path): download_result, os_ver, link = sys_patch_download.grab_patcher_support_pkg(self.constants).download_files() else: download_result = True diff --git a/resources/sys_patch_auto.py b/resources/sys_patch_auto.py new file mode 100644 index 000000000..ceb68cae7 --- /dev/null +++ b/resources/sys_patch_auto.py @@ -0,0 +1,99 @@ +# Auto Patching's main purpose is to try and tell the user they're missing root patches +# New users may not realize OS updates remove our patches, so we try and run when nessasary +# Conditions for running: +# - Verify running GUI (TUI users can write their own scripts) +# - Verify the Snapshot Seal is in tact (if not, assume user is running patches) +# - Verify this model needs patching (if not, assume user upgraded hardware and OCLP was not removed) +# - Verify there are no updates for OCLP (ensure we have the latest patch sets) +# If all these tests pass, start Root Patcher +# Copyright (C) 2022, Mykola Grymalyuk + +import subprocess +import webbrowser +from resources import sys_patch_detect, utilities, sys_patch_detect, updates + +class AutomaticSysPatch: + def start_auto_patch(settings): + print("- Starting Automatic Patching") + if settings.wxpython_variant is True: + if utilities.check_seal() is True: + print("- Detected Snapshot seal in tact, detecting patches") + patches = sys_patch_detect.detect_root_patch(settings.computer.real_model, settings).detect_patch_set() + if not any(not patch.startswith("Settings") and not patch.startswith("Validation") and patches[patch] is True for patch in patches): + patches = [] + if patches: + print("- Detected applicable patches, determining whether possible to patch") + if patches["Validation: Patching Possible"] is True: + print("- Determined patching is possible, checking for OCLP updates") + patch_string = "" + for patch in patches: + if patches[patch] is True and not patch.startswith("Settings") and not patch.startswith("Validation"): + patch_string += f"- {patch}\n" + # Check for updates + dict = updates.check_binary_updates(settings).check_binary_updates() + if not dict: + print("- No new binaries found on Github, proceeding with patching") + if settings.launcher_script is None: + args_string = f"'{settings.launcher_binary}' --gui_patch" + else: + args_string = f"{settings.launcher_binary} {settings.launcher_script} --gui_patch" + + warning_str = "" + if utilities.verify_network_connection("https://api.github.com/repos/dortania/OpenCore-Legacy-Patcher/releases/latest") is False: + warning_str = f"""\n\nWARNING: We're unable to verify whether there are any new releases of OpenCore Legacy Patcher on Github. Be aware that you may be using an outdated version for this OS. If you're unsure, verify on Github that OpenCore Legacy Patcher {settings.patcher_version} is the latest official release""" + + args = [ + "osascript", + "-e", + f"""display dialog "OpenCore Legacy Patcher has detected you're running without Root Patches, and would like to install them.\n\nmacOS wipes all root patches during OS installs and updates, so they need to be reinstalled.\n\nFollowing Patches have been detected for your system: \n{patch_string}\nWould you like to apply these patches?{warning_str}" """ + f'with icon POSIX file "{settings.app_icon_path}"', + ] + output = subprocess.run( + args, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT + ) + if output.returncode == 0: + args = [ + "osascript", + "-e", + f'''do shell script "{args_string}"''' + f' with prompt "OpenCore Legacy Patcher would like to patch your root volume"' + " with administrator privileges" + " without altering line endings" + ] + subprocess.run( + args, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT + ) + else: + for entry in dict: + version = dict[entry]["Version"] + github_link = dict[entry]["Github Link"] + print(f"- Found new version: {version}") + + # launch oascript to ask user if they want to apply the update + # if yes, open the link in the default browser + # we never want to run the root patcher if there are updates available + args = [ + "osascript", + "-e", + f"""display dialog "OpenCore Legacy Patcher has detected you're running without Root Patches, and would like to install them.\n\nHowever we've detected a new version of OCLP on Github. Would you like to view this?\n\nCurrent Version: {settings.patcher_version}\nRemote Version: {version}" """ + f'with icon POSIX file "{settings.app_icon_path}"', + ] + output = subprocess.run( + args, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT + ) + if output.returncode == 0: + webbrowser.open(github_link) + else: + print("- Cannot run patching") + else: + print("- No patches detected") + else: + print("- Detected Snapshot seal not in tact, skipping") + else: + print("- Auto Patch option is not supported on TUI, please use GUI") \ No newline at end of file diff --git a/resources/utilities.py b/resources/utilities.py index 81a88fa4f..8ee0fd219 100644 --- a/resources/utilities.py +++ b/resources/utilities.py @@ -11,7 +11,7 @@ import os import binascii import argparse from ctypes import CDLL, c_uint, byref -import sys, time +import time try: import requests @@ -397,6 +397,10 @@ def download_file(link, location, is_gui=None, verify_checksum=False): print(link) return None +def grab_mount_point_from_disk(disk): + data = plistlib.loads(subprocess.run(f"diskutil info -plist {disk}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode()) + return data["MountPoint"] + def monitor_disk_output(disk): # Returns MB written on drive output = subprocess.check_output(["iostat", "-Id", disk]) @@ -455,8 +459,10 @@ def check_cli_args(): # GUI args parser.add_argument("--gui_patch", help="Starts GUI in Root Patcher", action="store_true", required=False) parser.add_argument("--gui_unpatch", help="Starts GUI in Root Unpatcher", action="store_true", required=False) + parser.add_argument("--auto_patch", help="Check if patches are needed and prompt user", action="store_true", required=False) + args = parser.parse_args() - if not (args.build or args.patch_sys_vol or args.unpatch_sys_vol or args.validate): + if not (args.build or args.patch_sys_vol or args.unpatch_sys_vol or args.validate or args.auto_patch): return None else: return args From 45a08245152fd43d63896e05433e4b5f3e7bbfa4 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Mon, 11 Apr 2022 16:21:50 -0600 Subject: [PATCH 02/21] OCLP-Install-Setup: Use relative path --- payloads/InstallPackage/OCLP-Install-Setup.pkgproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/payloads/InstallPackage/OCLP-Install-Setup.pkgproj b/payloads/InstallPackage/OCLP-Install-Setup.pkgproj index 52fd13e28..c07c92f83 100644 --- a/payloads/InstallPackage/OCLP-Install-Setup.pkgproj +++ b/payloads/InstallPackage/OCLP-Install-Setup.pkgproj @@ -235,9 +235,9 @@ GID 0 PATH - /Users/mykolagrymalyuk/Developer/OpenCore-Legacy-Patcher/payloads/com.dortania.opencore-legacy-patcher.auto-patch.plist + ../com.dortania.opencore-legacy-patcher.auto-patch.plist PATH_TYPE - 0 + 1 PERMISSIONS 420 TYPE From 27d2b7500a327c6bc76a44572f97c51022239a12 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Mon, 11 Apr 2022 17:05:47 -0600 Subject: [PATCH 03/21] gui_main.py: Add remaining patches --- .gitignore | 2 ++ gui/gui_main.py | 22 ++++++++++++++++++++++ resources/constants.py | 4 ++++ 3 files changed, 28 insertions(+) diff --git a/.gitignore b/.gitignore index a3eb7db80..462303e51 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ __pycache__/ /payloads/Installer.sh /payloads/Info.plist /payloads/seed.plist +/payloads/InstallPackage/OCLP-Install.pkg +/payloads/InstallPackage/OCLP-Install.pkg.zip diff --git a/gui/gui_main.py b/gui/gui_main.py index eda0d0626..d445cccf3 100644 --- a/gui/gui_main.py +++ b/gui/gui_main.py @@ -11,6 +11,7 @@ import os import wx.adv from wx.lib.agw import hyperlink import threading +from pathlib import Path from resources import constants, defaults, build, install, installer, sys_patch_download, utilities, sys_patch_detect, sys_patch, run, generate_smbios, updates from data import model_array, os_data, smbios_data, sip_data @@ -1420,6 +1421,8 @@ class wx_python_gui: time.sleep(1) thread = threading.Thread(target=self.start_script) thread.start() + download_thread = threading.Thread(target=self.download_and_unzip_pkg) + download_thread.start() disk = disk[5:] default_output = float(utilities.monitor_disk_output(disk)) while True: @@ -1432,6 +1435,11 @@ class wx_python_gui: self.progress_label.Centre(wx.HORIZONTAL) wx.GetApp().Yield() else: + while download_thread.is_alive(): + # wait for download_thread to finish + # though highly unlikely this thread is still alive (flashing an Installer will take a while) + time.sleep(0.1) + self.install_installer_pkg(disk) break self.progress_bar.SetValue(16000) self.progress_label.SetLabel(f"Finished Running Installer Creation Script") @@ -1453,6 +1461,20 @@ class wx_python_gui: popup = wx.MessageDialog(self.frame, f"Failed to create macOS installer\n\nOutput: {output}\n\nError: {error}", "Error", wx.OK | wx.ICON_ERROR) popup.ShowModal() + + def download_and_unzip_pkg(self): + # Remove this URL overwrite when released + self.constants.installer_pkg_url = "https://github.com/khronokernel/Storage/releases/download/1.0/OCLP-Install.pkg.zip" + if utilities.download_file(self.constants.installer_pkg_url, self.constants.installer_pkg_zip_path): + subprocess.run(["unzip", "-o", self.constants.installer_pkg_zip_path, "-d", self.constants.installer_pkg_path]) + + def install_installer_pkg(self, disk): + disk = disk + "s2" # ESP sits at 1, and we know macOS will have created the main partition at 2 + if Path(self.constants.installer_pkg_zip_path).exists(): + path = utilities.grab_mount_point_from_disk(disk) + subprocess.run(["mkdir", "-p", f"{path}/Library/Packages/"]) + subprocess.run(["cp", f"{self.constants.installer_pkg_path}/OCLP-Install.pkg", f"{path}/Library/Packages/"]) + def settings_menu(self, event=None): # Define Menu # - Header: Settings diff --git a/resources/constants.py b/resources/constants.py index 76ec8a1f4..11c3ffdd9 100644 --- a/resources/constants.py +++ b/resources/constants.py @@ -568,6 +568,10 @@ class Constants: @property def installer_pkg_path(self): return self.payload_path / Path("InstallPackage/OCLP-Install.pkg") + + @property + def installer_pkg_zip_path(self): + return self.payload_path / Path("InstallPackage/OCLP-Install.pkg.zip") # Apple Payloads Paths From a72b2ffb2342f829018800c8b7b2588ae2f4d440 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Mon, 11 Apr 2022 17:11:52 -0600 Subject: [PATCH 04/21] CI: Move Validation to Offline TUI workflow --- .github/workflows/build-app-offline.yml | 2 ++ .github/workflows/build-app-wxpython-offline.yml | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-app-offline.yml b/.github/workflows/build-app-offline.yml index da45755ea..c34fe5af1 100644 --- a/.github/workflows/build-app-offline.yml +++ b/.github/workflows/build-app-offline.yml @@ -38,3 +38,5 @@ jobs: file: OpenCore-Patcher-TUI-Offline.app.zip tag: ${{ github.ref }} file_glob: true + - name: Validate OpenCore + run: ./dist/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher --validate diff --git a/.github/workflows/build-app-wxpython-offline.yml b/.github/workflows/build-app-wxpython-offline.yml index caf6aa968..3254ac265 100644 --- a/.github/workflows/build-app-wxpython-offline.yml +++ b/.github/workflows/build-app-wxpython-offline.yml @@ -41,6 +41,4 @@ jobs: repo_token: ${{ secrets.GITHUB_TOKEN }} file: OpenCore-Patcher-GUI-Offline.app.zip tag: ${{ github.ref }} - file_glob: true - - name: Validate OpenCore - run: ./dist/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher --validate \ No newline at end of file + file_glob: true \ No newline at end of file From c717b7ea9cbc486fc912f4c869134b5659097216 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Mon, 11 Apr 2022 20:52:22 -0600 Subject: [PATCH 05/21] sys_patch.py: Fix path string comparison --- payloads/InstallPackage/postinstall.sh | 16 ++++++++-------- resources/sys_patch.py | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/payloads/InstallPackage/postinstall.sh b/payloads/InstallPackage/postinstall.sh index cebecc0e7..8eb3e1751 100755 --- a/payloads/InstallPackage/postinstall.sh +++ b/payloads/InstallPackage/postinstall.sh @@ -1,12 +1,12 @@ #!/bin/sh app_path="/Library/Application Support/Dortania/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher" args="--patch_sys_vol" -"$app_path" "$args" > "/Users/Shared/.OCLP-AutoPatcher-Log-$(date +"%Y_%m_%d_%I_%M_%p").txt" -log show --last boot > "/Users/Shared/.System-Log-$(date +"%Y_%m_%d_%I_%M_%p").txt" -dmesg > "/Users/Shared/.Kernel-Log-$(date +"%Y_%m_%d_%I_%M_%p").txt" -ps aux > "/Users/Shared/.Process-List-$(date +"%Y_%m_%d_%I_%M_%p").txt" -ls -l "/System/Volumes/Update/mnt1/System/Library/KernelCollections" > "/Users/Shared/.Kernel-Collections-$(date +"%Y_%m_%d_%I_%M_%p").txt" -kmutil showloaded > "/Users/Shared/.Loaded-Kexts-$(date +"%Y_%m_%d_%I_%M_%p").txt" -kmutil inspect -B "/System/Volumes/Update/mnt1/System/Library/KernelCollections/BootKernelExtensions.kc" > "/Users/Shared/.BootKernelExtensions-$(date +"%Y_%m_%d_%I_%M_%p").txt" -kmutil inspect -S "/System/Volumes/Update/mnt1/System/Library/KernelCollections/SystemKernelExtensions.kc" > "/Users/Shared/.SystemKernelExtensions-$(date +"%Y_%m_%d_%I_%M_%p").txt" +"$app_path" "$args" &> "/Users/Shared/.OCLP-AutoPatcher-Log-$(date +"%Y_%m_%d_%I_%M_%p").txt" +log show --last boot > "/Users/Shared/.OCLP-System-Log-$(date +"%Y_%m_%d_%I_%M_%p").txt" +dmesg > "/Users/Shared/.OCLP-Kernel-Log-$(date +"%Y_%m_%d_%I_%M_%p").txt" +ps aux > "/Users/Shared/.OCLP-Process-List-$(date +"%Y_%m_%d_%I_%M_%p").txt" +ls -l "/System/Volumes/Update/mnt1/System/Library/KernelCollections" > "/Users/Shared/.OCLP-Kernel-Collections-$(date +"%Y_%m_%d_%I_%M_%p").txt" +kmutil showloaded > "/Users/Shared/.OCLP-Loaded-Kexts-$(date +"%Y_%m_%d_%I_%M_%p").txt" +kmutil inspect -B "/System/Volumes/Update/mnt1/System/Library/KernelCollections/BootKernelExtensions.kc" > "/Users/Shared/.OCLP-BootKernelExtensions-$(date +"%Y_%m_%d_%I_%M_%p").txt" +kmutil inspect -S "/System/Volumes/Update/mnt1/System/Library/KernelCollections/SystemKernelExtensions.kc" > "/Users/Shared/.OCLP-SystemKernelExtensions-$(date +"%Y_%m_%d_%I_%M_%p").txt" reboot \ No newline at end of file diff --git a/resources/sys_patch.py b/resources/sys_patch.py index 301fb7c82..55d2b9775 100644 --- a/resources/sys_patch.py +++ b/resources/sys_patch.py @@ -284,7 +284,7 @@ class PatchSysVolume: def unmount_drive(self): # When we detect we're chainloaded in the Installer, skip unmounting # We have logging in place to pull additional info after we're done - if not "Library/InstallerSandboxes/" in self.constants.payload_path: + if not "Library/InstallerSandboxes/" in str(self.constants.payload_path): print("- Unmounting Root Volume (Don't worry if this fails)") utilities.elevated(["diskutil", "unmount", self.root_mount_path], stdout=subprocess.PIPE).stdout.decode().strip().encode() else: @@ -719,7 +719,7 @@ class PatchSysVolume: return output def download_files(self): - if self.constants.gui_mode is False or (self.constants.wxpython_variant is True and "Library/InstallerSandboxes/" in self.constants.payload_path): + if self.constants.gui_mode is False or (self.constants.wxpython_variant is True and "Library/InstallerSandboxes/" in str(self.constants.payload_path)): download_result, os_ver, link = sys_patch_download.grab_patcher_support_pkg(self.constants).download_files() else: download_result = True From 945ba18652043ed0ebad0ae5ae79a01215e69e98 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Mon, 11 Apr 2022 21:30:12 -0600 Subject: [PATCH 06/21] sys_patch.py: Handle non-standard app names --- resources/sys_patch.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/resources/sys_patch.py b/resources/sys_patch.py index 55d2b9775..e5b8f21fc 100644 --- a/resources/sys_patch.py +++ b/resources/sys_patch.py @@ -330,10 +330,17 @@ class PatchSysVolume: utilities.process_status(utilities.elevated(["rm", "-R", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) # Strip everything after OpenCore-Patcher.app - path = self.constants.launcher_binary.split("OpenCore-Patcher.app")[0] + "OpenCore-Patcher.app" + path = str(self.constants.launcher_binary).split("/Contents/MacOS/OpenCore-Patcher")[0] print(f"- Copying {path} to /Library/Application Support/Dortania/") utilities.process_status(utilities.elevated(["cp", "-R", path, "/Library/Application Support/Dortania/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - + + if not Path("/Library/Application Support/Dortania/OpenCore-Patcher.app").exists(): + # Sometimes the binary the user launches maye have a suffix (ie. OpenCore-Patcher 3.app) + # We'll want to rename it to OpenCore-Patcher.app + path = path.split("/")[-1] + print(f"- Renaming {path} to OpenCore-Patcher.app") + utilities.process_status(utilities.elevated(["mv", f"/Library/Application Support/Dortania/{path}", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + # Copy over our launch agent print("- Copying auto-patch.plist Launch Agent to /Library/LaunchAgents/") if Path("/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist").exists(): From 42c4ed17bcdc1a39b0709c9d454f52a01a914b7d Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Wed, 13 Apr 2022 16:21:02 -0600 Subject: [PATCH 07/21] Work-around Root Volume unmounting --- resources/arguments.py | 13 ++++++++++++- resources/sys_patch.py | 12 ++++++++---- resources/utilities.py | 23 +++++++++++++++++++++++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/resources/arguments.py b/resources/arguments.py index d6699a5c1..9fa372340 100644 --- a/resources/arguments.py +++ b/resources/arguments.py @@ -1,6 +1,8 @@ import sys from resources import defaults, build, utilities, validation, sys_patch, sys_patch_auto from data import model_array +import threading +import time # Generic building args class arguments: @@ -101,7 +103,16 @@ If you plan to create the USB for another machine, please select the "Change Mod print("- Set Mojave/Catalina root patch configuration") settings.moj_cat_accel = True print("- Set System Volume patching") - sys_patch.PatchSysVolume(settings.custom_model or settings.computer.real_model, settings, None).start_patch() + + if "Library/InstallerSandboxes/" in str(self.constants.payload_path): + print("- Running from Installer Sandbox") + thread = threading.Thread(target=sys_patch.PatchSysVolume(settings.custom_model or settings.computer.real_model, settings, None).start_patch) + thread.start() + while thread.is_alive(): + utilities.block_os_updaters() + time.sleep(1) + else: + sys_patch.PatchSysVolume(settings.custom_model or settings.computer.real_model, settings, None).start_patch() elif self.args.unpatch_sys_vol: print("- Set System Volume unpatching") sys_patch.PatchSysVolume(settings.custom_model or settings.computer.real_model, settings, None).start_unpatch() diff --git a/resources/sys_patch.py b/resources/sys_patch.py index e5b8f21fc..85d2f7909 100644 --- a/resources/sys_patch.py +++ b/resources/sys_patch.py @@ -241,9 +241,13 @@ class PatchSysVolume: else: result = utilities.elevated(["kextcache", "-i", f"{self.mount_location}/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - # kextcache always returns 0, even if it fails - # Check the output for 'KernelCache ID' to see if the cache was successfully rebuilt - if result.returncode != 0 or (self.constants.detected_os < os_data.os_data.catalina and "KernelCache ID" not in result.stdout.decode()): + # kextcache notes: + # - kextcache always returns 0, even if it fails + # - Check the output for 'KernelCache ID' to see if the cache was successfully rebuilt + # kmutil notes: + # - kmutil will return 71 on failure to build KCs + # - kmutil will sometimes have a stroke and return a negative value even if it succeeds + if result.returncode > 0 or (self.constants.detected_os < os_data.os_data.catalina and "KernelCache ID" not in result.stdout.decode()): self.success_status = False print("- Unable to build new kernel cache") print(f"\nReason for Patch Failure({result.returncode}):") @@ -254,7 +258,7 @@ class PatchSysVolume: input("Press [ENTER] to continue") else: self.success_status = True - print("- Successfully built new kernel cache") + print(f"- Successfully built new kernel cache({result.returncode})") if self.root_supports_snapshot is True: print("- Creating new APFS snapshot") bless = utilities.elevated( diff --git a/resources/utilities.py b/resources/utilities.py index 8ee0fd219..3fc22304e 100644 --- a/resources/utilities.py +++ b/resources/utilities.py @@ -410,6 +410,29 @@ def monitor_disk_output(disk): output = output[-2] return output + +def block_os_updaters(): + # Disables any processes that would be likely to mess with + # the root volume while we're working with it. + bad_processes = [ + "softwareupdate", + "SoftwareUpdate", + "Software Update", + "MobileSoftwareUpdate", + ] + output = subprocess.check_output(["ps", "-ax"]) + lines = output.splitlines() + for line in lines: + entry = line.split() + pid = entry[0] + process_name = entry[3].decode() + for process in bad_processes: + if process in process_name: + if pid != "": + print(f"Killing PID: {pid}") + print(f"Process: {process_name}") + subprocess.run(["kill", "-9", pid]) + def check_boot_mode(): # Check whether we're in Safe Mode or not sys_plist = plistlib.loads(subprocess.run(["system_profiler", "SPSoftwareDataType"], stdout=subprocess.PIPE).stdout) From 2973f0b6aba6c2a50daa2a5e795dc95ae52debe8 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Wed, 13 Apr 2022 18:08:09 -0600 Subject: [PATCH 08/21] arguments.py: Fix typo --- resources/arguments.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/arguments.py b/resources/arguments.py index 9fa372340..ad46b79a6 100644 --- a/resources/arguments.py +++ b/resources/arguments.py @@ -104,7 +104,7 @@ If you plan to create the USB for another machine, please select the "Change Mod settings.moj_cat_accel = True print("- Set System Volume patching") - if "Library/InstallerSandboxes/" in str(self.constants.payload_path): + if "Library/InstallerSandboxes/" in str(settings.payload_path): print("- Running from Installer Sandbox") thread = threading.Thread(target=sys_patch.PatchSysVolume(settings.custom_model or settings.computer.real_model, settings, None).start_patch) thread.start() From 45a29d26170399dc5bfb79e67f304bd07b885a50 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Wed, 13 Apr 2022 21:53:53 -0600 Subject: [PATCH 09/21] utilities.py: clean block logic --- resources/utilities.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/resources/utilities.py b/resources/utilities.py index 3fc22304e..249bdc820 100644 --- a/resources/utilities.py +++ b/resources/utilities.py @@ -424,14 +424,14 @@ def block_os_updaters(): lines = output.splitlines() for line in lines: entry = line.split() - pid = entry[0] - process_name = entry[3].decode() - for process in bad_processes: - if process in process_name: + pid = entry[0].decode() + current_process = entry[3].decode() + for bad_process in bad_processes: + if bad_process in current_process: if pid != "": - print(f"Killing PID: {pid}") - print(f"Process: {process_name}") + print(f"- Killing Process: {pid} - {current_process.split('/')[-1]}") subprocess.run(["kill", "-9", pid]) + break def check_boot_mode(): # Check whether we're in Safe Mode or not From 9e61380aec866798fdd4b5f50afd75e8159ce593 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Thu, 14 Apr 2022 09:24:05 -0600 Subject: [PATCH 10/21] postinstall.sh: Drop extra logging --- payloads/InstallPackage/postinstall.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/payloads/InstallPackage/postinstall.sh b/payloads/InstallPackage/postinstall.sh index 8eb3e1751..f530f6e79 100755 --- a/payloads/InstallPackage/postinstall.sh +++ b/payloads/InstallPackage/postinstall.sh @@ -3,10 +3,4 @@ app_path="/Library/Application Support/Dortania/OpenCore-Patcher.app/Contents/Ma args="--patch_sys_vol" "$app_path" "$args" &> "/Users/Shared/.OCLP-AutoPatcher-Log-$(date +"%Y_%m_%d_%I_%M_%p").txt" log show --last boot > "/Users/Shared/.OCLP-System-Log-$(date +"%Y_%m_%d_%I_%M_%p").txt" -dmesg > "/Users/Shared/.OCLP-Kernel-Log-$(date +"%Y_%m_%d_%I_%M_%p").txt" -ps aux > "/Users/Shared/.OCLP-Process-List-$(date +"%Y_%m_%d_%I_%M_%p").txt" -ls -l "/System/Volumes/Update/mnt1/System/Library/KernelCollections" > "/Users/Shared/.OCLP-Kernel-Collections-$(date +"%Y_%m_%d_%I_%M_%p").txt" -kmutil showloaded > "/Users/Shared/.OCLP-Loaded-Kexts-$(date +"%Y_%m_%d_%I_%M_%p").txt" -kmutil inspect -B "/System/Volumes/Update/mnt1/System/Library/KernelCollections/BootKernelExtensions.kc" > "/Users/Shared/.OCLP-BootKernelExtensions-$(date +"%Y_%m_%d_%I_%M_%p").txt" -kmutil inspect -S "/System/Volumes/Update/mnt1/System/Library/KernelCollections/SystemKernelExtensions.kc" > "/Users/Shared/.OCLP-SystemKernelExtensions-$(date +"%Y_%m_%d_%I_%M_%p").txt" reboot \ No newline at end of file From b32cbe06ef8d43dd88f94903141a55aba0b851b9 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Thu, 14 Apr 2022 09:27:45 -0600 Subject: [PATCH 11/21] Remove unneeded code --- resources/constants.py | 4 ---- resources/sys_patch.py | 11 +++-------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/resources/constants.py b/resources/constants.py index 11c3ffdd9..7b502dae3 100644 --- a/resources/constants.py +++ b/resources/constants.py @@ -560,10 +560,6 @@ class Constants: @property def gui_path(self): return self.payload_path / Path("Icon/Resources.zip") - - @property - def postinstall_script_path(self): - return self.payload_path / Path("InstallPackage/postinstall") @property def installer_pkg_path(self): diff --git a/resources/sys_patch.py b/resources/sys_patch.py index 85d2f7909..7a767b2b9 100644 --- a/resources/sys_patch.py +++ b/resources/sys_patch.py @@ -286,13 +286,8 @@ class PatchSysVolume: input("\nPress [ENTER] to continue") def unmount_drive(self): - # When we detect we're chainloaded in the Installer, skip unmounting - # We have logging in place to pull additional info after we're done - if not "Library/InstallerSandboxes/" in str(self.constants.payload_path): - print("- Unmounting Root Volume (Don't worry if this fails)") - utilities.elevated(["diskutil", "unmount", self.root_mount_path], stdout=subprocess.PIPE).stdout.decode().strip().encode() - else: - print("- Skipping snapshot unmount due to Installer environment") + print("- Unmounting Root Volume (Don't worry if this fails)") + utilities.elevated(["diskutil", "unmount", self.root_mount_path], stdout=subprocess.PIPE).stdout.decode().strip().encode() def delete_old_binaries(self, vendor_patch): for delete_current_kext in vendor_patch: @@ -730,7 +725,7 @@ class PatchSysVolume: return output def download_files(self): - if self.constants.gui_mode is False or (self.constants.wxpython_variant is True and "Library/InstallerSandboxes/" in str(self.constants.payload_path)): + if self.constants.gui_mode is False or "Library/InstallerSandboxes/" in str(self.constants.payload_path): download_result, os_ver, link = sys_patch_download.grab_patcher_support_pkg(self.constants).download_files() else: download_result = True From dc15a53e857fdc508b4f1e0c1c9418b35ac5ec77 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Thu, 14 Apr 2022 09:53:45 -0600 Subject: [PATCH 12/21] gui_main.py: Fix pkg file check --- gui/gui_main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/gui_main.py b/gui/gui_main.py index d445cccf3..542c4ac31 100644 --- a/gui/gui_main.py +++ b/gui/gui_main.py @@ -1470,7 +1470,7 @@ class wx_python_gui: def install_installer_pkg(self, disk): disk = disk + "s2" # ESP sits at 1, and we know macOS will have created the main partition at 2 - if Path(self.constants.installer_pkg_zip_path).exists(): + if Path(self.constants.installer_pkg_path).exists(): path = utilities.grab_mount_point_from_disk(disk) subprocess.run(["mkdir", "-p", f"{path}/Library/Packages/"]) subprocess.run(["cp", f"{self.constants.installer_pkg_path}/OCLP-Install.pkg", f"{path}/Library/Packages/"]) From 28769098fda885f14d0c768262381e374bd72ede Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Fri, 15 Apr 2022 18:06:03 -0600 Subject: [PATCH 13/21] sys_patch.py: Clean kmutil comments --- resources/sys_patch.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/sys_patch.py b/resources/sys_patch.py index 7a767b2b9..5eb1afe02 100644 --- a/resources/sys_patch.py +++ b/resources/sys_patch.py @@ -245,9 +245,9 @@ class PatchSysVolume: # - kextcache always returns 0, even if it fails # - Check the output for 'KernelCache ID' to see if the cache was successfully rebuilt # kmutil notes: - # - kmutil will return 71 on failure to build KCs - # - kmutil will sometimes have a stroke and return a negative value even if it succeeds - if result.returncode > 0 or (self.constants.detected_os < os_data.os_data.catalina and "KernelCache ID" not in result.stdout.decode()): + # - will return 71 on failure to build KCs + # - will return -10 if the volume is missing (ie. unmounted by another process) + if result.returncode != 0 or (self.constants.detected_os < os_data.os_data.catalina and "KernelCache ID" not in result.stdout.decode()): self.success_status = False print("- Unable to build new kernel cache") print(f"\nReason for Patch Failure({result.returncode}):") @@ -258,7 +258,7 @@ class PatchSysVolume: input("Press [ENTER] to continue") else: self.success_status = True - print(f"- Successfully built new kernel cache({result.returncode})") + print("- Successfully built new kernel cache") if self.root_supports_snapshot is True: print("- Creating new APFS snapshot") bless = utilities.elevated( From 3e8f28a2dbfcb8449befba6d578e8f56291856c7 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Sat, 16 Apr 2022 09:51:23 -0600 Subject: [PATCH 14/21] Add Proper .pkg link fallbacks --- .../workflows/build-app-wxpython-offline.yml | 10 +++++++++- gui/gui_main.py | 20 ++++++++++++++++--- resources/constants.py | 1 + resources/utilities.py | 10 ++++++++++ 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-app-wxpython-offline.yml b/.github/workflows/build-app-wxpython-offline.yml index 3254ac265..e51bed106 100644 --- a/.github/workflows/build-app-wxpython-offline.yml +++ b/.github/workflows/build-app-wxpython-offline.yml @@ -34,11 +34,19 @@ jobs: with: name: OCLP-Install.pkg path: ./dist/OCLP-Install.pkg - - name: Upload to Release + - name: Upload Binary to Release if: github.event_name == 'release' uses: svenstaro/upload-release-action@e74ff71f7d8a4c4745b560a485cc5fdb9b5b999d with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: OpenCore-Patcher-GUI-Offline.app.zip tag: ${{ github.ref }} + file_glob: true + - name: Upload Package to Release + if: github.event_name == 'release' + uses: svenstaro/upload-release-action@e74ff71f7d8a4c4745b560a485cc5fdb9b5b999d + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: ./dist/OCLP-Install.pkg + tag: ${{ github.ref }} file_glob: true \ No newline at end of file diff --git a/gui/gui_main.py b/gui/gui_main.py index 542c4ac31..ea589156d 100644 --- a/gui/gui_main.py +++ b/gui/gui_main.py @@ -1463,9 +1463,23 @@ class wx_python_gui: def download_and_unzip_pkg(self): - # Remove this URL overwrite when released - self.constants.installer_pkg_url = "https://github.com/khronokernel/Storage/releases/download/1.0/OCLP-Install.pkg.zip" - if utilities.download_file(self.constants.installer_pkg_url, self.constants.installer_pkg_zip_path): + # Function's main goal is to grab the correct OCLP-Install.pkg and unzip it + # Note the following: + # - When running a release build, pull from Github's release page with the same versioning + # - When running from source/unable to find on Github, use the nightly.link variant + # - If nightly also fails, fall back to the manually uploaded variant + link = self.constants.installer_pkg_url + if not utilities.validate_link(link): + print("- Stock Install.pkg is missing on Github, falling back to Nightly") + link = self.constants.installer_pkg_url_nightly + if not utilities.validate_link(link): + print("- Nightly Install.pkg is missing on Github, falling back to manual backup") + link = "https://github.com/khronokernel/Storage/releases/download/1.0/OCLP-Install.pkg.zip" + if not utilities.validate_link(link): + print("- Manual backup is missing on Github, no more fallbacks remaining. Quitting") + return + + if utilities.download_file(link, self.constants.installer_pkg_zip_path): subprocess.run(["unzip", "-o", self.constants.installer_pkg_zip_path, "-d", self.constants.installer_pkg_path]) def install_installer_pkg(self, disk): diff --git a/resources/constants.py b/resources/constants.py index 7b502dae3..2b86d5131 100644 --- a/resources/constants.py +++ b/resources/constants.py @@ -24,6 +24,7 @@ class Constants: self.repo_link_latest = f"{self.repo_link}/releases/tag/{self.patcher_version}" self.copyright_date = "Copyright © 2020-2022 Dortania" self.installer_pkg_url = f"{self.repo_link_latest}/OCLP-Install.pkg" + self.installer_pkg_url_nightly = "https://nightly.link/dortania/OpenCore-Legacy-Patcher/workflows/build-app-wxpython-offline/main/OCLP-Install.pkg" # OpenCore Versioning # https://github.com/acidanthera/OpenCorePkg diff --git a/resources/utilities.py b/resources/utilities.py index 249bdc820..70740c85e 100644 --- a/resources/utilities.py +++ b/resources/utilities.py @@ -410,6 +410,16 @@ def monitor_disk_output(disk): output = output[-2] return output +def validate_link(link): + # Check if link is 404 + try: + response = requests.head(link, timeout=5) + if response.status_code == 404: + return False + else: + return True + except (requests.exceptions.Timeout, requests.exceptions.TooManyRedirects, requests.exceptions.ConnectionError, requests.exceptions.HTTPError): + return False def block_os_updaters(): # Disables any processes that would be likely to mess with From 26bc5fa4c59baa6a455753b8539a3b201194a58c Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Sat, 16 Apr 2022 12:40:16 -0600 Subject: [PATCH 15/21] gui_main.py: Add non-zip handling --- gui/gui_main.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/gui/gui_main.py b/gui/gui_main.py index ea589156d..d900acdda 100644 --- a/gui/gui_main.py +++ b/gui/gui_main.py @@ -1478,9 +1478,14 @@ class wx_python_gui: if not utilities.validate_link(link): print("- Manual backup is missing on Github, no more fallbacks remaining. Quitting") return - - if utilities.download_file(link, self.constants.installer_pkg_zip_path): - subprocess.run(["unzip", "-o", self.constants.installer_pkg_zip_path, "-d", self.constants.installer_pkg_path]) + + if link.endswith("zip"): + if utilities.download_file(link, self.constants.installer_pkg_zip_path): + if Path(self.constants.installer_pkg_path).exists(): + os.remove(self.constants.installer_pkg_path) + subprocess.run(["unzip", "-o", self.constants.installer_pkg_zip_path, "-d", self.constants.installer_pkg_path]) + else: + utilities.download_file(link, self.constants.installer_pkg_path) def install_installer_pkg(self, disk): disk = disk + "s2" # ESP sits at 1, and we know macOS will have created the main partition at 2 From 681174ac30c35500e6f976b13e36b4efef27812d Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Sun, 17 Apr 2022 10:25:58 -0600 Subject: [PATCH 16/21] Fix Links --- .github/workflows/build-app-wxpython-offline.yml | 5 +++-- gui/gui_main.py | 11 ++++------- resources/constants.py | 2 +- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build-app-wxpython-offline.yml b/.github/workflows/build-app-wxpython-offline.yml index e51bed106..669d6b2dc 100644 --- a/.github/workflows/build-app-wxpython-offline.yml +++ b/.github/workflows/build-app-wxpython-offline.yml @@ -23,6 +23,7 @@ jobs: - run: cd dist; zip -r ../OpenCore-Patcher-wxPython.app.zip OpenCore-Patcher.app - run: ./../sign-wxpython.sh - run: packagesbuild ./payloads/InstallPackage/OCLP-Install-Setup.pkgproj + - run: zip -r ./OCLP-Install.pkg.zip ./dist/OCLP-Install.pkg - run: mv ./OpenCore-Patcher-wxPython.app.zip ./OpenCore-Patcher-GUI-Offline.app.zip - name: Upload App to Artifacts uses: actions/upload-artifact@v2 @@ -33,7 +34,7 @@ jobs: uses: actions/upload-artifact@v2 with: name: OCLP-Install.pkg - path: ./dist/OCLP-Install.pkg + file: OCLP-Install.pkg.zip - name: Upload Binary to Release if: github.event_name == 'release' uses: svenstaro/upload-release-action@e74ff71f7d8a4c4745b560a485cc5fdb9b5b999d @@ -47,6 +48,6 @@ jobs: uses: svenstaro/upload-release-action@e74ff71f7d8a4c4745b560a485cc5fdb9b5b999d with: repo_token: ${{ secrets.GITHUB_TOKEN }} - file: ./dist/OCLP-Install.pkg + file: OCLP-Install.pkg.zip tag: ${{ github.ref }} file_glob: true \ No newline at end of file diff --git a/gui/gui_main.py b/gui/gui_main.py index d900acdda..f79fd4a74 100644 --- a/gui/gui_main.py +++ b/gui/gui_main.py @@ -1479,13 +1479,10 @@ class wx_python_gui: print("- Manual backup is missing on Github, no more fallbacks remaining. Quitting") return - if link.endswith("zip"): - if utilities.download_file(link, self.constants.installer_pkg_zip_path): - if Path(self.constants.installer_pkg_path).exists(): - os.remove(self.constants.installer_pkg_path) - subprocess.run(["unzip", "-o", self.constants.installer_pkg_zip_path, "-d", self.constants.installer_pkg_path]) - else: - utilities.download_file(link, self.constants.installer_pkg_path) + if utilities.download_file(link, self.constants.installer_pkg_zip_path): + if Path(self.constants.installer_pkg_path).exists(): + os.remove(self.constants.installer_pkg_path) + subprocess.run(["unzip", "-o", self.constants.installer_pkg_zip_path, "-d", self.constants.installer_pkg_path]) def install_installer_pkg(self, disk): disk = disk + "s2" # ESP sits at 1, and we know macOS will have created the main partition at 2 diff --git a/resources/constants.py b/resources/constants.py index 2b86d5131..75bfabeb9 100644 --- a/resources/constants.py +++ b/resources/constants.py @@ -23,7 +23,7 @@ class Constants: self.repo_link = "https://github.com/dortania/OpenCore-Legacy-Patcher" self.repo_link_latest = f"{self.repo_link}/releases/tag/{self.patcher_version}" self.copyright_date = "Copyright © 2020-2022 Dortania" - self.installer_pkg_url = f"{self.repo_link_latest}/OCLP-Install.pkg" + self.installer_pkg_url = f"{self.repo_link_latest}/OCLP-Install.pkg.zip" self.installer_pkg_url_nightly = "https://nightly.link/dortania/OpenCore-Legacy-Patcher/workflows/build-app-wxpython-offline/main/OCLP-Install.pkg" # OpenCore Versioning From e16e8540cffcd466ed526d5041c56ca97322e1bf Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Sun, 17 Apr 2022 12:18:39 -0600 Subject: [PATCH 17/21] CI: Fix formatting --- .github/workflows/build-app-wxpython-offline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-app-wxpython-offline.yml b/.github/workflows/build-app-wxpython-offline.yml index 669d6b2dc..5f8a516dd 100644 --- a/.github/workflows/build-app-wxpython-offline.yml +++ b/.github/workflows/build-app-wxpython-offline.yml @@ -34,7 +34,7 @@ jobs: uses: actions/upload-artifact@v2 with: name: OCLP-Install.pkg - file: OCLP-Install.pkg.zip + path: OCLP-Install.pkg.zip - name: Upload Binary to Release if: github.event_name == 'release' uses: svenstaro/upload-release-action@e74ff71f7d8a4c4745b560a485cc5fdb9b5b999d From 39bc49639dba576e697011489d76a8a1d5c2eb14 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Mon, 18 Apr 2022 09:43:21 -0600 Subject: [PATCH 18/21] gui_main.py: Streamline pkg installation --- gui/gui_main.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/gui/gui_main.py b/gui/gui_main.py index f79fd4a74..c051a8fd9 100644 --- a/gui/gui_main.py +++ b/gui/gui_main.py @@ -24,6 +24,7 @@ class wx_python_gui: self.constants.gui_mode = True self.walkthrough_mode = False self.finished_auto_patch = False + self.target_disk = "" # Backup stdout for usage with wxPython self.stock_stdout = sys.stdout @@ -1419,27 +1420,23 @@ class wx_python_gui: print("- Starting creation script as admin") wx.GetApp().Yield() time.sleep(1) - thread = threading.Thread(target=self.start_script) - thread.start() - download_thread = threading.Thread(target=self.download_and_unzip_pkg) - download_thread.start() disk = disk[5:] + self.target_disk = disk + install_thread = threading.Thread(target=self.start_script) + install_thread.start() + self.download_thread = threading.Thread(target=self.download_and_unzip_pkg) + self.download_thread.start() default_output = float(utilities.monitor_disk_output(disk)) while True: time.sleep(0.1) output = float(utilities.monitor_disk_output(disk)) bytes_written = output - default_output - if thread.is_alive(): + if install_thread.is_alive(): self.progress_bar.SetValue(bytes_written) self.progress_label.SetLabel(f"Bytes Written: {round(bytes_written, 2)}MB") self.progress_label.Centre(wx.HORIZONTAL) wx.GetApp().Yield() else: - while download_thread.is_alive(): - # wait for download_thread to finish - # though highly unlikely this thread is still alive (flashing an Installer will take a while) - time.sleep(0.1) - self.install_installer_pkg(disk) break self.progress_bar.SetValue(16000) self.progress_label.SetLabel(f"Finished Running Installer Creation Script") @@ -1454,6 +1451,12 @@ class wx_python_gui: output, error, returncode = run.Run()._stream_output(comm=args) if "Install media now available at" in output: print("- Sucessfully created macOS installer") + while self.download_thread.is_alive(): + # wait for download_thread to finish + # though highly unlikely this thread is still alive (flashing an Installer will take a while) + time.sleep(0.1) + print("- Installing Root Patcher to drive") + self.install_installer_pkg(self.target_disk) popup_message = wx.MessageDialog(self.frame, "Sucessfully created a macOS installer!\nYou can now install OpenCore onto this drive", "Success", wx.OK) popup_message.ShowModal() else: @@ -1481,7 +1484,7 @@ class wx_python_gui: if utilities.download_file(link, self.constants.installer_pkg_zip_path): if Path(self.constants.installer_pkg_path).exists(): - os.remove(self.constants.installer_pkg_path) + subprocess.run(["sudo", "rm", self.constants.installer_pkg_path]) subprocess.run(["unzip", "-o", self.constants.installer_pkg_zip_path, "-d", self.constants.installer_pkg_path]) def install_installer_pkg(self, disk): From 6f48f388142256c450f806d1e3a66ce1f3b55b7b Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Wed, 20 Apr 2022 10:04:44 -0600 Subject: [PATCH 19/21] Fix redirects --- .gitignore | 4 ++-- gui/gui_main.py | 11 ++++------- resources/constants.py | 6 +++--- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 462303e51..5f5c657a8 100644 --- a/.gitignore +++ b/.gitignore @@ -24,5 +24,5 @@ __pycache__/ /payloads/Installer.sh /payloads/Info.plist /payloads/seed.plist -/payloads/InstallPackage/OCLP-Install.pkg -/payloads/InstallPackage/OCLP-Install.pkg.zip +/payloads/OCLP-Install.pkg +/payloads/OCLP-Install.pkg.zip diff --git a/gui/gui_main.py b/gui/gui_main.py index c051a8fd9..9edcdbcca 100644 --- a/gui/gui_main.py +++ b/gui/gui_main.py @@ -1476,15 +1476,12 @@ class wx_python_gui: print("- Stock Install.pkg is missing on Github, falling back to Nightly") link = self.constants.installer_pkg_url_nightly if not utilities.validate_link(link): - print("- Nightly Install.pkg is missing on Github, falling back to manual backup") - link = "https://github.com/khronokernel/Storage/releases/download/1.0/OCLP-Install.pkg.zip" - if not utilities.validate_link(link): - print("- Manual backup is missing on Github, no more fallbacks remaining. Quitting") - return + print("- Nightly Install.pkg is missing on Github, exiting") + return if utilities.download_file(link, self.constants.installer_pkg_zip_path): if Path(self.constants.installer_pkg_path).exists(): - subprocess.run(["sudo", "rm", self.constants.installer_pkg_path]) + subprocess.run(["rm", self.constants.installer_pkg_path]) subprocess.run(["unzip", "-o", self.constants.installer_pkg_zip_path, "-d", self.constants.installer_pkg_path]) def install_installer_pkg(self, disk): @@ -1492,7 +1489,7 @@ class wx_python_gui: if Path(self.constants.installer_pkg_path).exists(): path = utilities.grab_mount_point_from_disk(disk) subprocess.run(["mkdir", "-p", f"{path}/Library/Packages/"]) - subprocess.run(["cp", f"{self.constants.installer_pkg_path}/OCLP-Install.pkg", f"{path}/Library/Packages/"]) + subprocess.run(["cp", "-r", self.constants.installer_pkg_path, f"{path}/Library/Packages/"]) def settings_menu(self, event=None): # Define Menu diff --git a/resources/constants.py b/resources/constants.py index cf0125ca7..7977fc3b4 100644 --- a/resources/constants.py +++ b/resources/constants.py @@ -24,7 +24,7 @@ class Constants: self.repo_link_latest = f"{self.repo_link}/releases/tag/{self.patcher_version}" self.copyright_date = "Copyright © 2020-2022 Dortania" self.installer_pkg_url = f"{self.repo_link_latest}/OCLP-Install.pkg.zip" - self.installer_pkg_url_nightly = "https://nightly.link/dortania/OpenCore-Legacy-Patcher/workflows/build-app-wxpython-offline/main/OCLP-Install.pkg" + self.installer_pkg_url_nightly = "http://nightly.link/dortania/OpenCore-Legacy-Patcher/workflows/build-app-wxpython-offline/main/OCLP-Install.pkg.zip" # OpenCore Versioning # https://github.com/acidanthera/OpenCorePkg @@ -564,11 +564,11 @@ class Constants: @property def installer_pkg_path(self): - return self.payload_path / Path("InstallPackage/OCLP-Install.pkg") + return self.payload_path / Path("OCLP-Install.pkg") @property def installer_pkg_zip_path(self): - return self.payload_path / Path("InstallPackage/OCLP-Install.pkg.zip") + return self.payload_path / Path("OCLP-Install.pkg.zip") # Apple Payloads Paths From cf8c8f72a4a9d71f1fbbeefa5a9e06f464115aa9 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Wed, 20 Apr 2022 11:27:35 -0600 Subject: [PATCH 20/21] CI: Upload just as pkg --- .github/workflows/build-app-wxpython-offline.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-app-wxpython-offline.yml b/.github/workflows/build-app-wxpython-offline.yml index 5f8a516dd..e51bed106 100644 --- a/.github/workflows/build-app-wxpython-offline.yml +++ b/.github/workflows/build-app-wxpython-offline.yml @@ -23,7 +23,6 @@ jobs: - run: cd dist; zip -r ../OpenCore-Patcher-wxPython.app.zip OpenCore-Patcher.app - run: ./../sign-wxpython.sh - run: packagesbuild ./payloads/InstallPackage/OCLP-Install-Setup.pkgproj - - run: zip -r ./OCLP-Install.pkg.zip ./dist/OCLP-Install.pkg - run: mv ./OpenCore-Patcher-wxPython.app.zip ./OpenCore-Patcher-GUI-Offline.app.zip - name: Upload App to Artifacts uses: actions/upload-artifact@v2 @@ -34,7 +33,7 @@ jobs: uses: actions/upload-artifact@v2 with: name: OCLP-Install.pkg - path: OCLP-Install.pkg.zip + path: ./dist/OCLP-Install.pkg - name: Upload Binary to Release if: github.event_name == 'release' uses: svenstaro/upload-release-action@e74ff71f7d8a4c4745b560a485cc5fdb9b5b999d @@ -48,6 +47,6 @@ jobs: uses: svenstaro/upload-release-action@e74ff71f7d8a4c4745b560a485cc5fdb9b5b999d with: repo_token: ${{ secrets.GITHUB_TOKEN }} - file: OCLP-Install.pkg.zip + file: ./dist/OCLP-Install.pkg tag: ${{ github.ref }} file_glob: true \ No newline at end of file From 64daaf3e4ba48ee8b1fe525352fc23076ed84a69 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Wed, 20 Apr 2022 12:10:09 -0600 Subject: [PATCH 21/21] gui_main.py: use ditto for unzips --- gui/gui_main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/gui_main.py b/gui/gui_main.py index 9edcdbcca..d3c3176b4 100644 --- a/gui/gui_main.py +++ b/gui/gui_main.py @@ -1482,7 +1482,7 @@ class wx_python_gui: if utilities.download_file(link, self.constants.installer_pkg_zip_path): if Path(self.constants.installer_pkg_path).exists(): subprocess.run(["rm", self.constants.installer_pkg_path]) - subprocess.run(["unzip", "-o", self.constants.installer_pkg_zip_path, "-d", self.constants.installer_pkg_path]) + subprocess.run(["ditto", "-V", "-x", "-k", "--sequesterRsrc", "--rsrc", self.constants.installer_pkg_zip_path, self.constants.payload_path]) def install_installer_pkg(self, disk): disk = disk + "s2" # ESP sits at 1, and we know macOS will have created the main partition at 2