mirror of
https://github.com/grahampugh/macadmin-scripts.git
synced 2025-12-17 17:56:33 +00:00
commit
2b720a4ad8
@ -560,25 +560,34 @@ def download_and_parse_sucatalog(sucatalog, workdir, ignore_cache=False):
|
|||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
|
|
||||||
def find_mac_os_installers(catalog):
|
def find_mac_os_installers(catalog, installassistant_pkg_only=False):
|
||||||
"""Return a list of product identifiers for what appear to be macOS
|
"""Return a list of product identifiers for what appear to be macOS
|
||||||
installers"""
|
installers"""
|
||||||
mac_os_installer_products = []
|
mac_os_installer_products = []
|
||||||
if "Products" in catalog:
|
if "Products" in catalog:
|
||||||
for product_key in catalog["Products"].keys():
|
for product_key in catalog["Products"].keys():
|
||||||
product = catalog["Products"][product_key]
|
product = catalog["Products"][product_key]
|
||||||
try:
|
# account for args.pkg
|
||||||
if product["ExtendedMetaInfo"]["InstallAssistantPackageIdentifiers"]:
|
if installassistant_pkg_only:
|
||||||
mac_os_installer_products.append(product_key)
|
try:
|
||||||
except KeyError:
|
if product['ExtendedMetaInfo']['InstallAssistantPackageIdentifiers']:
|
||||||
continue
|
if product['ExtendedMetaInfo']['InstallAssistantPackageIdentifiers']['SharedSupport'] == 'com.apple.pkg.InstallAssistant.macOSBigSur':
|
||||||
|
mac_os_installer_products.append(product_key)
|
||||||
|
except KeyError:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
if product["ExtendedMetaInfo"]["InstallAssistantPackageIdentifiers"]:
|
||||||
|
mac_os_installer_products.append(product_key)
|
||||||
|
except KeyError:
|
||||||
|
continue
|
||||||
return mac_os_installer_products
|
return mac_os_installer_products
|
||||||
|
|
||||||
|
|
||||||
def os_installer_product_info(catalog, workdir, ignore_cache=False):
|
def os_installer_product_info(catalog, workdir, installassistant_pkg_only, ignore_cache=False):
|
||||||
"""Returns a dict of info about products that look like macOS installers"""
|
"""Returns a dict of info about products that look like macOS installers"""
|
||||||
product_info = {}
|
product_info = {}
|
||||||
installer_products = find_mac_os_installers(catalog)
|
installer_products = find_mac_os_installers(catalog, installassistant_pkg_only)
|
||||||
for product_key in installer_products:
|
for product_key in installer_products:
|
||||||
product_info[product_key] = {}
|
product_info[product_key] = {}
|
||||||
# get the localized title (e.g. "macOS Catalina Beta") and version
|
# get the localized title (e.g. "macOS Catalina Beta") and version
|
||||||
@ -791,6 +800,11 @@ def main():
|
|||||||
help="Selects the latest valid build ID matching "
|
help="Selects the latest valid build ID matching "
|
||||||
"the selected OS version (e.g. 10.14).",
|
"the selected OS version (e.g. 10.14).",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--pkg",
|
||||||
|
action="store_true",
|
||||||
|
help="Search only for InstallAssistant packages (macOS Big Sur only)",
|
||||||
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# show this Mac's info
|
# show this Mac's info
|
||||||
@ -855,7 +869,7 @@ def main():
|
|||||||
su_catalog_url, args.workdir, ignore_cache=args.ignore_cache
|
su_catalog_url, args.workdir, ignore_cache=args.ignore_cache
|
||||||
)
|
)
|
||||||
product_info = os_installer_product_info(
|
product_info = os_installer_product_info(
|
||||||
catalog, args.workdir, ignore_cache=args.ignore_cache
|
catalog, args.workdir, args.pkg, ignore_cache=args.ignore_cache
|
||||||
)
|
)
|
||||||
if not product_info:
|
if not product_info:
|
||||||
print("No macOS installer products found in the sucatalog.", file=sys.stderr)
|
print("No macOS installer products found in the sucatalog.", file=sys.stderr)
|
||||||
@ -1160,58 +1174,82 @@ def main():
|
|||||||
print("Exiting.")
|
print("Exiting.")
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
# download all the packages for the selected product
|
# shortened workflow if we just want a macOS Big Sur+ package
|
||||||
replicate_product(catalog, product_id, args.workdir, ignore_cache=args.ignore_cache)
|
# taken from @scriptingosx's Fetch-Installer-Pkg project
|
||||||
|
# (https://github.com/scriptingosx/fetch-installer-pkg)
|
||||||
|
if args.pkg:
|
||||||
|
product = catalog['Products'][product_id]
|
||||||
|
|
||||||
|
# determine the InstallAssistant pkg url
|
||||||
|
for package in product['Packages']:
|
||||||
|
package_url = package['URL']
|
||||||
|
if package_url.endswith('InstallAssistant.pkg'):
|
||||||
|
break
|
||||||
|
|
||||||
|
# print("Package URL is %s" % package_url)
|
||||||
|
download_pkg = replicate_url(package_url, args.workdir, True, ignore_cache=args.ignore_cache)
|
||||||
|
|
||||||
|
pkg_name = ('InstallAssistant-%s-%s.pkg' % (product_info[product_id]['version'],
|
||||||
|
product_info[product_id]['BUILD']))
|
||||||
|
|
||||||
|
# hard link the downloaded file to cwd
|
||||||
|
local_pkg = os.path.join(args.workdir, pkg_name)
|
||||||
|
os.link(download_pkg, local_pkg)
|
||||||
|
print("Package downloaded to: %s" % local_pkg)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# download all the packages for the selected product
|
||||||
|
replicate_product(catalog, product_id, args.workdir, ignore_cache=args.ignore_cache)
|
||||||
|
|
||||||
# generate a name for the sparseimage
|
# generate a name for the sparseimage
|
||||||
volname = "Install_macOS_%s-%s" % (
|
volname = "Install_macOS_%s-%s" % (
|
||||||
product_info[product_id]["version"],
|
product_info[product_id]["version"],
|
||||||
product_info[product_id]["BUILD"],
|
product_info[product_id]["BUILD"],
|
||||||
)
|
|
||||||
sparse_diskimage_path = os.path.join(args.workdir, volname + ".sparseimage")
|
|
||||||
if os.path.exists(sparse_diskimage_path):
|
|
||||||
os.unlink(sparse_diskimage_path)
|
|
||||||
|
|
||||||
# make an empty sparseimage and mount it
|
|
||||||
print("Making empty sparseimage...")
|
|
||||||
sparse_diskimage_path = make_sparse_image(volname, sparse_diskimage_path)
|
|
||||||
mountpoint = mountdmg(sparse_diskimage_path)
|
|
||||||
if mountpoint:
|
|
||||||
# install the product to the mounted sparseimage volume
|
|
||||||
success = install_product(
|
|
||||||
product_info[product_id]["DistributionPath"], mountpoint
|
|
||||||
)
|
)
|
||||||
if not success:
|
sparse_diskimage_path = os.path.join(args.workdir, volname + ".sparseimage")
|
||||||
print("Product installation failed.", file=sys.stderr)
|
if os.path.exists(sparse_diskimage_path):
|
||||||
unmountdmg(mountpoint)
|
|
||||||
exit(-1)
|
|
||||||
# add the seeding program xattr to the app if applicable
|
|
||||||
seeding_program = get_seeding_program(su_catalog_url)
|
|
||||||
if seeding_program:
|
|
||||||
installer_app = find_installer_app(mountpoint)
|
|
||||||
if installer_app:
|
|
||||||
print(
|
|
||||||
"Adding seeding program %s extended attribute to app"
|
|
||||||
% seeding_program
|
|
||||||
)
|
|
||||||
xattr.setxattr(installer_app, "SeedProgram", seeding_program.encode())
|
|
||||||
print("Product downloaded and installed to %s" % sparse_diskimage_path)
|
|
||||||
if args.raw:
|
|
||||||
unmountdmg(mountpoint)
|
|
||||||
else:
|
|
||||||
# if --raw option not given, create a r/o compressed diskimage
|
|
||||||
# containing the Install macOS app
|
|
||||||
compressed_diskimagepath = os.path.join(args.workdir, volname + ".dmg")
|
|
||||||
if os.path.exists(compressed_diskimagepath):
|
|
||||||
os.unlink(compressed_diskimagepath)
|
|
||||||
app_path = find_installer_app(mountpoint)
|
|
||||||
if app_path:
|
|
||||||
make_compressed_dmg(app_path, compressed_diskimagepath, volname)
|
|
||||||
# unmount sparseimage
|
|
||||||
unmountdmg(mountpoint)
|
|
||||||
# delete sparseimage since we don't need it any longer
|
|
||||||
os.unlink(sparse_diskimage_path)
|
os.unlink(sparse_diskimage_path)
|
||||||
|
|
||||||
|
# make an empty sparseimage and mount it
|
||||||
|
print("Making empty sparseimage...")
|
||||||
|
sparse_diskimage_path = make_sparse_image(volname, sparse_diskimage_path)
|
||||||
|
mountpoint = mountdmg(sparse_diskimage_path)
|
||||||
|
if mountpoint:
|
||||||
|
# install the product to the mounted sparseimage volume
|
||||||
|
success = install_product(
|
||||||
|
product_info[product_id]["DistributionPath"], mountpoint
|
||||||
|
)
|
||||||
|
if not success:
|
||||||
|
print("Product installation failed.", file=sys.stderr)
|
||||||
|
unmountdmg(mountpoint)
|
||||||
|
exit(-1)
|
||||||
|
# add the seeding program xattr to the app if applicable
|
||||||
|
seeding_program = get_seeding_program(su_catalog_url)
|
||||||
|
if seeding_program:
|
||||||
|
installer_app = find_installer_app(mountpoint)
|
||||||
|
if installer_app:
|
||||||
|
print(
|
||||||
|
"Adding seeding program %s extended attribute to app"
|
||||||
|
% seeding_program
|
||||||
|
)
|
||||||
|
xattr.setxattr(installer_app, "SeedProgram", seeding_program.encode())
|
||||||
|
print("Product downloaded and installed to %s" % sparse_diskimage_path)
|
||||||
|
if args.raw:
|
||||||
|
unmountdmg(mountpoint)
|
||||||
|
else:
|
||||||
|
# if --raw option not given, create a r/o compressed diskimage
|
||||||
|
# containing the Install macOS app
|
||||||
|
compressed_diskimagepath = os.path.join(args.workdir, volname + ".dmg")
|
||||||
|
if os.path.exists(compressed_diskimagepath):
|
||||||
|
os.unlink(compressed_diskimagepath)
|
||||||
|
app_path = find_installer_app(mountpoint)
|
||||||
|
if app_path:
|
||||||
|
make_compressed_dmg(app_path, compressed_diskimagepath, volname)
|
||||||
|
# unmount sparseimage
|
||||||
|
unmountdmg(mountpoint)
|
||||||
|
# delete sparseimage since we don't need it any longer
|
||||||
|
os.unlink(sparse_diskimage_path)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user