| 5 | # Using the techniques outlined by wolfmannight here: https://www.insanelymac.com/forum/topic/338810-create-legit-copy-of-macos-from-apple-catalog/ |
| 6 | |
| 7 | class buildMacOSInstallApp: |
| 8 | def __init__(self): |
| 9 | self.r = run.Run() |
| 10 | self.u = utils.Utils("Build macOS Install App") |
| 11 | self.target_files = [ |
| 12 | "BaseSystem.dmg", |
| 13 | "BaseSystem.chunklist", |
| 14 | "InstallESDDmg.pkg", |
| 15 | "InstallInfo.plist", |
| 16 | "AppleDiagnostics.dmg", |
| 17 | "AppleDiagnostics.chunklist" |
| 18 | ] |
| 19 | # Verify we're on macOS - this doesn't work anywhere else |
| 20 | if not sys.platform == "darwin": |
| 21 | self.u.head("WARNING") |
| 22 | print("") |
| 23 | print("This script only runs on macOS!") |
| 24 | print("") |
| 25 | exit(1) |
| 26 | |
| 27 | def mount_dmg(self, dmg, no_browse = False): |
| 28 | # Mounts the passed dmg and returns the mount point(s) |
| 29 | args = ["/usr/bin/hdiutil", "attach", dmg, "-plist", "-noverify"] |
| 30 | if no_browse: |
| 31 | args.append("-nobrowse") |
| 32 | out = self.r.run({"args":args}) |
| 33 | if out[2] != 0: |
| 34 | # Failed! |
| 35 | raise Exception("Mount Failed!", "{} failed to mount:\n\n{}".format(os.path.basename(dmg), out[1])) |
| 36 | # Get the plist data returned, and locate the mount points |
| 37 | try: |
| 38 | plist_data = plist.loads(out[0]) |
| 39 | mounts = [x["mount-point"] for x in plist_data.get("system-entities", []) if "mount-point" in x] |
| 40 | return mounts |
| 41 | except: |
| 42 | raise Exception("Mount Failed!", "No mount points returned from {}".format(os.path.basename(dmg))) |
| 43 | |
| 44 | def unmount_dmg(self, mount_point): |
| 45 | # Unmounts the passed dmg or mount point - retries with force if failed |
| 46 | # Can take either a single point or a list |
| 47 | if not type(mount_point) is list: |
| 48 | mount_point = [mount_point] |
| 49 | unmounted = [] |
| 50 | for m in mount_point: |
| 51 | args = ["/usr/bin/hdiutil", "detach", m] |
| 52 | out = self.r.run({"args":args}) |
| 53 | if out[2] != 0: |
| 54 | # Polite failed, let's crush this b! |
| 55 | args.append("-force") |
| 56 | out = self.r.run({"args":args}) |
| 57 | if out[2] != 0: |
| 58 | # Oh... failed again... onto the next... |
| 59 | print(out[1]) |
| 60 | continue |
| 61 | unmounted.append(m) |
| 62 | return unmounted |
| 63 | |
| 64 | def main(self): |
no outgoing calls
no test coverage detected