mirror of
https://github.com/grahampugh/macadmin-scripts.git
synced 2025-12-17 17:56:33 +00:00
Add search for DeviceID because UnsupportedModels is absent from macOS 11.* dist files
This commit is contained in:
parent
278f2fa889
commit
f8cdedd509
@ -105,6 +105,17 @@ def get_hw_model():
|
||||
return hw_model
|
||||
|
||||
|
||||
def get_bridge_id():
|
||||
"""Gets the local system DeviceID for T2 Macs"""
|
||||
remotectl_cmd = ["/usr/libexec/remotectl", "get-property", "localbridge", "HWModel"]
|
||||
try:
|
||||
remotectl_output = subprocess.check_output(remotectl_cmd)
|
||||
bridge_id = remotectl_output.decode("utf8").split(" ")[-1].split("\n")[0]
|
||||
except subprocess.CalledProcessError as err:
|
||||
raise ReplicationError(err)
|
||||
return bridge_id
|
||||
|
||||
|
||||
def get_current_build_info():
|
||||
"""Gets the local system build"""
|
||||
build_info = []
|
||||
@ -412,7 +423,7 @@ def get_server_metadata(catalog, product_key, workdir, ignore_cache=False):
|
||||
print("Could not replicate %s: %s" % (url, err), file=sys.stderr)
|
||||
return None
|
||||
except KeyError:
|
||||
# print('Malformed catalog.', file=sys.stderr)
|
||||
# print("No metadata for %s.\n" % product_key, file=sys.stderr)
|
||||
return None
|
||||
|
||||
|
||||
@ -468,20 +479,36 @@ def get_board_ids(filename):
|
||||
with open(filename) as search:
|
||||
for line in search:
|
||||
line = line.rstrip() # remove '\n' at end of line
|
||||
# dist files for macOS 10.* list boardIDs whereas dist files for
|
||||
# macOS 11.* list supportedBoardIDs
|
||||
if "boardIds" in line:
|
||||
supported_board_ids = line.split(" ")[-1][:-1]
|
||||
supported_board_ids = line.lstrip("var boardIDs = ")
|
||||
elif "supportedBoardIDs" in line:
|
||||
supported_board_ids = line.lstrip("var supportedBoardIDs = ")
|
||||
return supported_board_ids
|
||||
|
||||
|
||||
def get_device_ids(filename):
|
||||
"""Parses a softwareupdate dist file, returning a list of supported
|
||||
Device IDs. These are used for identifying T2 chips in the dist files of macOS 11.* - not checked in older builds"""
|
||||
supported_device_ids = ""
|
||||
with open(filename) as search:
|
||||
for line in search:
|
||||
line = line.rstrip() # remove '\n' at end of line
|
||||
if "supportedDeviceIDs" in line:
|
||||
supported_device_ids = line.lstrip("var supportedDeviceIDs = ")
|
||||
return supported_device_ids
|
||||
|
||||
|
||||
def get_unsupported_models(filename):
|
||||
"""Parses a softwareupdate dist file, returning a list of non-supported
|
||||
ModelIdentifiers"""
|
||||
ModelIdentifiers. This is not used in macOS 11.*"""
|
||||
unsupported_models = ""
|
||||
with open(filename) as search:
|
||||
for line in search:
|
||||
line = line.rstrip() # remove '\n' at end of line
|
||||
if "nonSupportedModels" in line:
|
||||
unsupported_models = line.split(" ")[-1][:-1]
|
||||
unsupported_models = line.lstrip("var nonSupportedModels = ")
|
||||
return unsupported_models
|
||||
|
||||
|
||||
@ -527,18 +554,19 @@ def find_mac_os_installers(catalog):
|
||||
return mac_os_installer_products
|
||||
|
||||
|
||||
def os_installer_product_info(catalog, workdir, warnings, ignore_cache=False):
|
||||
def os_installer_product_info(catalog, workdir, ignore_cache=False):
|
||||
"""Returns a dict of info about products that look like macOS installers"""
|
||||
product_info = {}
|
||||
installer_products = find_mac_os_installers(catalog)
|
||||
for product_key in installer_products:
|
||||
product_info[product_key] = {}
|
||||
# get the localized title (e.g. "macOS Catalina Beta") and version
|
||||
# from ServerMetadataURL for macOS 10.*
|
||||
# For macOS 11.* we get these directly from the dist file
|
||||
filename = get_server_metadata(catalog, product_key, workdir)
|
||||
if filename:
|
||||
product_info[product_key] = parse_server_metadata(filename)
|
||||
else:
|
||||
if warnings:
|
||||
print("WARNING: No server metadata for %s\n" % product_key)
|
||||
product_info[product_key]["title"] = None
|
||||
product_info[product_key]["version"] = None
|
||||
|
||||
@ -559,6 +587,8 @@ def os_installer_product_info(catalog, workdir, warnings, ignore_cache=False):
|
||||
product_info[product_key]["UnsupportedModels"] = unsupported_models
|
||||
board_ids = get_board_ids(dist_path)
|
||||
product_info[product_key]["BoardIDs"] = board_ids
|
||||
device_ids = get_device_ids(dist_path)
|
||||
product_info[product_key]["DeviceIDs"] = device_ids
|
||||
product_info[product_key].update(dist_info)
|
||||
if not product_info[product_key]["title"]:
|
||||
product_info[product_key]["title"] = dist_info.get("title_from_dist")
|
||||
@ -745,6 +775,7 @@ def main():
|
||||
# show this Mac's info
|
||||
hw_model = get_hw_model()
|
||||
board_id = get_board_id()
|
||||
bridge_id = get_bridge_id()
|
||||
build_info = get_current_build_info()
|
||||
is_vm = is_a_vm()
|
||||
|
||||
@ -752,6 +783,7 @@ def main():
|
||||
if is_vm == True:
|
||||
print("Identified as a Virtual Machine")
|
||||
print("%-17s: %s" % ("Model Identifier", hw_model))
|
||||
print("%-17s: %s" % ("Bridge ID", bridge_id))
|
||||
print("%-17s: %s" % ("Board ID", board_id))
|
||||
print("%-17s: %s" % ("OS Version", build_info[0]))
|
||||
print("%-17s: %s\n" % ("Build ID", build_info[1]))
|
||||
@ -790,7 +822,7 @@ def main():
|
||||
su_catalog_url, args.workdir, ignore_cache=args.ignore_cache
|
||||
)
|
||||
product_info = os_installer_product_info(
|
||||
catalog, args.workdir, args.warnings, ignore_cache=args.ignore_cache
|
||||
catalog, args.workdir, ignore_cache=args.ignore_cache
|
||||
)
|
||||
if not product_info:
|
||||
print("No macOS installer products found in the sucatalog.", file=sys.stderr)
|
||||
@ -810,30 +842,25 @@ def main():
|
||||
"%2s %-15s %-10s %-8s %-11s %-30s %s"
|
||||
% ("#", "ProductID", "Version", "Build", "Post Date", "Title", validity_header)
|
||||
)
|
||||
# this is where we do checks for validity based on model type and version
|
||||
for index, product_id in enumerate(product_info):
|
||||
not_valid = ""
|
||||
if (
|
||||
not product_info[product_id]["UnsupportedModels"]
|
||||
and not product_info[product_id]["BoardIDs"]
|
||||
):
|
||||
not_valid = "No unsupported Model or supported Board ID data"
|
||||
else:
|
||||
if not product_info[product_id]["UnsupportedModels"]:
|
||||
not_valid = "No unsupported model data "
|
||||
else:
|
||||
if (
|
||||
hw_model in product_info[product_id]["UnsupportedModels"]
|
||||
and is_vm == False
|
||||
):
|
||||
not_valid = "Unsupported Model Identifier"
|
||||
if not product_info[product_id]["BoardIDs"]:
|
||||
not_valid += "No supported Board ID data "
|
||||
else:
|
||||
if (
|
||||
board_id not in product_info[product_id]["BoardIDs"]
|
||||
and is_vm == False
|
||||
):
|
||||
if is_vm == False:
|
||||
# first look for a BoardID (not present in modern hardware)
|
||||
if board_id and product_info[product_id]["BoardIDs"]:
|
||||
if board_id not in product_info[product_id]["BoardIDs"]:
|
||||
not_valid = "Unsupported Board ID"
|
||||
# if there's no Board ID there has to be a BridgeID:
|
||||
elif bridge_id and product_info[product_id]["DeviceIDs"]:
|
||||
if bridge_id not in product_info[product_id]["DeviceIDs"]:
|
||||
not_valid = "Unsupported Bridge ID"
|
||||
# finally we fall back on ModelIdentifiers for T1 and older
|
||||
elif hw_model and product_info[product_id]["UnsupportedModels"]:
|
||||
if hw_model in product_info[product_id]["UnsupportedModels"]:
|
||||
not_valid = "Unsupported Model Identifier"
|
||||
# if we don't have any of those matches, then we can't do a comparison
|
||||
else:
|
||||
not_valid = "No supported model data"
|
||||
if (
|
||||
get_latest_version(build_info[0], product_info[product_id]["version"])
|
||||
!= product_info[product_id]["version"]
|
||||
@ -841,6 +868,7 @@ def main():
|
||||
not_valid = "Unsupported macOS version"
|
||||
else:
|
||||
valid_build_found = True
|
||||
|
||||
validity_info = ""
|
||||
if args.warnings:
|
||||
validity_info = not_valid
|
||||
@ -863,7 +891,9 @@ def main():
|
||||
# skip if build is not suitable for current device
|
||||
# and a validation parameter was chosen
|
||||
if not_valid and (
|
||||
args.validate or (args.auto or args.version or args.os) and not args.beta
|
||||
args.validate
|
||||
or (args.auto or args.version or args.os)
|
||||
# and not args.beta # not needed now we have DeviceID check
|
||||
):
|
||||
continue
|
||||
|
||||
@ -1131,7 +1161,7 @@ def main():
|
||||
"Adding seeding program %s extended attribute to app"
|
||||
% seeding_program
|
||||
)
|
||||
xattr.setxattr(installer_app, "SeedProgram", 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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user