Merge branch 'main' of https://github.com/munki/macadmin-scripts into munki-main

This commit is contained in:
Graham Pugh 2025-08-21 12:47:49 +02:00
commit 4410b44f7b
3 changed files with 88 additions and 6 deletions

View File

@ -3,9 +3,9 @@
Some scripts that might be of use to macOS admins. Might be related to Munki; Some scripts that might be of use to macOS admins. Might be related to Munki;
might not. might not.
These are currently only supported using Apple's Python on macOS. There is no support for running these on Windows or Linux. These are only supported on macOS. There is no support for running these on Windows or Linux.
In macOS 12.3, Apple will be removing its Python 2.7 install. You'll need to provide your own Python to use these scripts. You may also need to install additional Python modules. In macOS 12.3, Apple stopped providung Python as part of macOS. You'll need to provide your own Python to use these scripts. You may also need to install additional Python modules.
#### getmacosipsws.py #### getmacosipsws.py
@ -39,7 +39,7 @@ Product installation failed.
Use a compatible Mac or select a different build compatible with your current hardware and try again. You may also have success running the script in a VM; the InstallationCheck script in versions of the macOS installer to date skips the checks (and returns success) when run on a VM. Use a compatible Mac or select a different build compatible with your current hardware and try again. You may also have success running the script in a VM; the InstallationCheck script in versions of the macOS installer to date skips the checks (and returns success) when run on a VM.
##### Important note for Catalina+ ##### Important note for Catalina+
Catalina privacy protections might interfere with the operation of this tool if you run it from ~/Desktop, ~/Documents, ~/Downloads or other directories protected in Catalina. Consider using /Users/Shared (or subdirectory) as the "working space" for this tool. macOS privacy protections might interfere with the operation of this tool if you run it from ~/Desktop, ~/Documents, ~/Downloads or other directories protected in macOS Catalina or later. Consider using /Users/Shared (or subdirectory) as the "working space" for this tool.
##### Alternate implementations ##### Alternate implementations

View File

@ -105,6 +105,18 @@ DEFAULT_SUCATALOGS = {
"index-16seed-16-15-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9" "index-16seed-16-15-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9"
"-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog" "-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog"
), ),
"22": "https://swscan.apple.com/content/catalogs/others/"
"index-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9"
"-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog",
"23": "https://swscan.apple.com/content/catalogs/others/"
"index-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9"
"-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog",
"24": "https://swscan.apple.com/content/catalogs/others/"
"index-15-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9"
"-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog",
"25": "https://swscan.apple.com/content/catalogs/others/"
"index-26-15-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9"
"-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog",
} }
SEED_CATALOGS_PLIST = ( SEED_CATALOGS_PLIST = (
@ -285,11 +297,12 @@ def get_default_catalog(darwin_major=None):
def make_sparse_image(volume_name, output_path): def make_sparse_image(volume_name, output_path):
"""Make a sparse disk image we can install a product to""" """Make a sparse disk image we can install a product to"""
# note: for macOS 26 Tahoe we needed to increase the size
cmd = [ cmd = [
"/usr/bin/hdiutil", "/usr/bin/hdiutil",
"create", "create",
"-size", "-size",
"16g", "20g",
"-fs", "-fs",
"HFS+", "HFS+",
"-volname", "-volname",
@ -399,7 +412,12 @@ def install_product(dist_path, target_vol):
# set CM_BUILD env var to make Installer bypass eligibilty checks # set CM_BUILD env var to make Installer bypass eligibilty checks
# when installing packages (for machine-specific OS builds) # when installing packages (for machine-specific OS builds)
os.environ["CM_BUILD"] = "CM_BUILD" os.environ["CM_BUILD"] = "CM_BUILD"
cmd = ["/usr/sbin/installer", "-pkg", dist_path, "-target", target_vol] # cmd = ['/usr/sbin/installer', '-pkg', dist_path, '-target', target_vol]
# a hack to work around a change in macOS 15.6+ since installing a .dist
# file no longer works
dist_dir = os.path.dirname(dist_path)
install_asst_pkg = os.path.join(dist_dir, "InstallAssistant.pkg")
cmd = ["/usr/sbin/installer", "-pkg", install_asst_pkg, "-target", target_vol]
try: try:
subprocess.check_call(cmd) subprocess.check_call(cmd)
except subprocess.CalledProcessError as err: except subprocess.CalledProcessError as err:
@ -1379,7 +1397,9 @@ def main():
% seeding_program % seeding_program
) )
xattr.setxattr( xattr.setxattr(
installer_app, "SeedProgram", seeding_program.encode() installer_app,
"SeedProgram",
seeding_program.encode("UTF-8").encode(),
) )
print("Product downloaded and installed to %s" % sparse_diskimage_path) print("Product downloaded and installed to %s" % sparse_diskimage_path)
if args.raw: if args.raw:

62
munki_bundle_pkg_finder.py Executable file
View File

@ -0,0 +1,62 @@
#!/usr/local/munki/munki-python
import os
import plistlib
import sys
sys.path.append("/usr/local/munki")
from munkilib import dmgutils
from munkilib import pkgutils
if len(sys.argv) != 2:
print('Need exactly one parameter: path to a munki repo!', file=sys.stderr)
sys.exit(-1)
repo_path = sys.argv[1]
all_catalog = os.path.join(repo_path, "catalogs/all")
with open(all_catalog, mode="rb") as FILE:
all_items = plistlib.load(FILE)
dmg_items = [{"name": item["name"],
"version": item["version"],
"location": item["installer_item_location"],
"package_path": item.get("package_path", "")}
for item in all_items
if item.get("installer_item_location", "").endswith(".dmg") and
item.get("installer_type") is None]
items_with_bundle_style_pkgs = []
for item in dmg_items:
full_path = os.path.join(repo_path, "pkgs", item["location"])
print("Checking %s..." % full_path)
mountpoints = dmgutils.mountdmg(full_path)
if mountpoints:
pkg_path = item["package_path"]
if pkg_path:
itempath = os.path.join(mountpoints[0], pkg_path)
if os.path.isdir(itempath):
print("***** %s--%s has a bundle-style pkg"
% (item["name"], item["version"]))
items_with_bundle_style_pkgs.append(item)
else:
for file_item in os.listdir(mountpoints[0]):
if pkgutils.hasValidInstallerItemExt(file_item):
itempath = os.path.join(mountpoints[0], file_item)
if os.path.isdir(itempath):
print("***** %s--%s has a bundle-style pkg"
% (item["name"], item["version"]))
items_with_bundle_style_pkgs.append(item)
break
dmgutils.unmountdmg(mountpoints[0])
else:
print("No filesystems mounted from %s" % full_path)
continue
print("Found %s items with bundle-style pkgs."
% len(items_with_bundle_style_pkgs))
for item in sorted(items_with_bundle_style_pkgs, key=lambda d: d["name"]):
print("%s--%s"% (item["name"], item["version"]))
print(" %s" % item["location"])