mirror of
https://github.com/dortania/OpenCore-Legacy-Patcher.git
synced 2026-04-20 10:44:32 +10:00
Implement Root Volume backups
Closes https://github.com/dortania/OpenCore-Legacy-Patcher/issues/378
This commit is contained in:
@@ -64,6 +64,8 @@ class PatchSysVolume:
|
||||
if Path(self.mount_extensions).exists():
|
||||
print("- Root Volume is already mounted")
|
||||
if patch is True:
|
||||
if self.constants.detected_os < self.constants.big_sur or Utilities.check_seal() is True:
|
||||
self.backup_volume()
|
||||
self.patch_root_vol()
|
||||
return True
|
||||
else:
|
||||
@@ -76,6 +78,8 @@ class PatchSysVolume:
|
||||
if Path(self.mount_extensions).exists():
|
||||
print("- Successfully mounted the Root Volume")
|
||||
if patch is True:
|
||||
if self.constants.detected_os < self.constants.big_sur or Utilities.check_seal() is True:
|
||||
self.backup_volume()
|
||||
self.patch_root_vol()
|
||||
return True
|
||||
else:
|
||||
@@ -91,6 +95,95 @@ class PatchSysVolume:
|
||||
if self.constants.gui_mode is False:
|
||||
input("- Press [ENTER] to exit: ")
|
||||
|
||||
def backup_volume(self):
|
||||
for location in SysPatchArray.BackupLocations:
|
||||
Utilities.cls()
|
||||
print("Backing up root volume before patching (This may take some time)")
|
||||
print(f"- Attempting to backup {location}")
|
||||
location_zip = f"{location}-Backup.zip"
|
||||
location_zip_path = Path(self.mount_location) / Path(location_zip)
|
||||
|
||||
if location_zip_path.exists():
|
||||
print(f"- Found existing {location_zip}, skipping")
|
||||
else:
|
||||
print(f"- Backing up {location}")
|
||||
# cp -r ./Extensions ./Extensions-Backup
|
||||
# ditto -c -k --sequesterRsrc --keepParent ./Extensions-Backup ./Extensions-Backup.zip
|
||||
# rm -r ./Extensions-Backup
|
||||
|
||||
print("- Creating Backup folder")
|
||||
Utilities.process_status(
|
||||
self.elevated(
|
||||
["cp", "-r", f"{self.mount_location}/{location}", f"{self.mount_location}/{location}-Backup"],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
)
|
||||
)
|
||||
print("- Zipping Backup folder")
|
||||
Utilities.process_status(
|
||||
self.elevated(
|
||||
["ditto", "-c", "-k", "--sequesterRsrc", "--keepParent", f"{self.mount_location}/{location}-Backup", f"{self.mount_location}/{location_zip}"],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
)
|
||||
)
|
||||
|
||||
print("- Removing Backup folder")
|
||||
Utilities.process_status(
|
||||
self.elevated(
|
||||
["rm", "-r", f"{self.mount_location}/{location}-Backup"],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
)
|
||||
)
|
||||
|
||||
def manual_root_patch_revert(self):
|
||||
print("- Attempting to revert patches")
|
||||
if (Path(self.mount_location) / Path("System/Library/Extensions-Backup.zip")).exists():
|
||||
print("- Verified manual unpatching is available")
|
||||
|
||||
for location in SysPatchArray.BackupLocations:
|
||||
Utilities.cls()
|
||||
print("Reverting root volume patches (This may take some time)")
|
||||
|
||||
print(f"- Attempting to unpatch {location}")
|
||||
location_zip = f"{location}-Backup.zip"
|
||||
location_zip_path = Path(self.mount_location) / Path(location_zip)
|
||||
location_old_path = Path(self.mount_location) / Path(location)
|
||||
|
||||
if "PrivateFrameworks" in location:
|
||||
copy_path = Path(self.mount_location) / Path("System/Library/PrivateFrameworks")
|
||||
elif "Frameworks" in location:
|
||||
copy_path = Path(self.mount_location) / Path("System/Library/Frameworks")
|
||||
else:
|
||||
copy_path = Path(self.mount_location) / Path("System/Library")
|
||||
|
||||
if location_zip_path.exists():
|
||||
print(f"- Found {location_zip}")
|
||||
|
||||
print(f"- Unzipping {location_zip}")
|
||||
Utilities.process_status(self.elevated(["unzip", location_zip_path, "-d", copy_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
if location_old_path.exists():
|
||||
print(f"- Renaming {location}")
|
||||
Utilities.process_status(self.elevated(["mv", location_old_path, f"{location_old_path}-Patched"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
print(f"- Renaming {location}-Backup")
|
||||
Utilities.process_status(self.elevated(["mv", f"{location_old_path}-Backup", location_old_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
print(f"- Removing {location_old_path}-Patched")
|
||||
Utilities.process_status(self.elevated(["rm", "-r", f"{location_old_path}-Patched"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
# ditto will create a '__MACOSX' folder
|
||||
# print("- Removing __MACOSX folder")
|
||||
# Utilities.process_status(self.elevated(["rm", "-r", f"{copy_path}/__MACOSX"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
else:
|
||||
print(f"- Failed to find {location_zip}, unable to unpatch")
|
||||
self.rebuild_snapshot()
|
||||
else:
|
||||
print("- Could not find Extensions.zip, cannot manually unpatch root volume")
|
||||
|
||||
def unpatch_root_vol(self):
|
||||
if self.constants.detected_os > self.constants.catalina:
|
||||
print("- Reverting to last signed APFS snapshot")
|
||||
@@ -99,13 +192,13 @@ class PatchSysVolume:
|
||||
print("- Unable to revert root volume patches")
|
||||
print("Reason for unpatch Failure:")
|
||||
print(result.stdout.decode())
|
||||
# print("- Failed to revert snapshot via bless, falling back on manual restoration")
|
||||
# self.undo_root_patch()
|
||||
print("- Failed to revert snapshot via bless, falling back on manual restoration")
|
||||
self.manual_root_patch_revert()
|
||||
else:
|
||||
print("- Unpatching complete")
|
||||
print("\nPlease reboot the machine for patches to take effect")
|
||||
# else:
|
||||
# self.undo_root_patch()
|
||||
else:
|
||||
self.manual_root_patch_revert()
|
||||
|
||||
def rebuild_snapshot(self):
|
||||
if self.constants.gui_mode is False:
|
||||
|
||||
Reference in New Issue
Block a user