mirror of
https://github.com/grahampugh/macadmin-scripts.git
synced 2025-12-17 17:56:33 +00:00
Merge branch 'master' of https://github.com/munki/macadmin-scripts
This commit is contained in:
commit
8d9449a053
10
README.md
10
README.md
@ -20,7 +20,11 @@ This command converts the output of Imagr's `make nbi` into a bootable external
|
|||||||
|
|
||||||
This script can create disk images containing macOS Installer applications available via Apple's softwareupdate catalogs.
|
This script can create disk images containing macOS Installer applications available via Apple's softwareupdate catalogs.
|
||||||
|
|
||||||
It does this by downloading the packages from Apple's softwareupdate servers and then installing them into a new empty disk image.
|
Run `./installinstallmacos.py --help` to see the available options.
|
||||||
|
|
||||||
|
The tool assembles "Install macOS" applications by downloading the packages from Apple's softwareupdate servers and then installing them into a new empty disk image.
|
||||||
|
|
||||||
|
If `/usr/bin/installer` returns errors during this process, it can be useful to examine `/var/log/install.log` for clues.
|
||||||
|
|
||||||
Since it is using Apple's installer, any install check or volume check scripts are run. This means that you can only use this tool to create a diskimage containing the versions of macOS that will run on the exact machine you are running the script on.
|
Since it is using Apple's installer, any install check or volume check scripts are run. This means that you can only use this tool to create a diskimage containing the versions of macOS that will run on the exact machine you are running the script on.
|
||||||
|
|
||||||
@ -37,9 +41,7 @@ Command '['/usr/sbin/installer', '-pkg', './content/downloads/07/20/091-95774/aw
|
|||||||
Product installation failed.
|
Product installation failed.
|
||||||
```
|
```
|
||||||
|
|
||||||
Use a compatible Mac or select a different build compatible with your current hardware and try again.
|
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.
|
||||||
|
|
||||||
Run `./installinstallmacos.py --help` to see the available options.
|
|
||||||
|
|
||||||
#### make_firmwareupdater_pkg.sh
|
#### make_firmwareupdater_pkg.sh
|
||||||
|
|
||||||
|
|||||||
@ -31,7 +31,6 @@ import plistlib
|
|||||||
import subprocess
|
import subprocess
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import time
|
|
||||||
import urlparse
|
import urlparse
|
||||||
import xattr
|
import xattr
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
@ -40,10 +39,15 @@ from operator import itemgetter
|
|||||||
from distutils.version import LooseVersion
|
from distutils.version import LooseVersion
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_SUCATALOG = (
|
DEFAULT_SUCATALOGS = {
|
||||||
'https://swscan.apple.com/content/catalogs/others/'
|
'17': 'https://swscan.apple.com/content/catalogs/others/'
|
||||||
'index-10.14seed-10.14-10.13-10.12-10.11-10.10-10.9'
|
'index-10.13-10.12-10.11-10.10-10.9'
|
||||||
'-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz')
|
'-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog',
|
||||||
|
'18': 'https://swscan.apple.com/content/catalogs/others/'
|
||||||
|
'index-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 = (
|
||||||
'/System/Library/PrivateFrameworks/Seeding.framework/Versions/Current/'
|
'/System/Library/PrivateFrameworks/Seeding.framework/Versions/Current/'
|
||||||
@ -99,17 +103,24 @@ def get_seeding_program(sucatalog_url):
|
|||||||
for key, value in seed_catalogs.items():
|
for key, value in seed_catalogs.items():
|
||||||
if sucatalog_url == value:
|
if sucatalog_url == value:
|
||||||
return key
|
return key
|
||||||
|
return ''
|
||||||
except (OSError, ExpatError, AttributeError, KeyError):
|
except (OSError, ExpatError, AttributeError, KeyError):
|
||||||
return None
|
return ''
|
||||||
|
|
||||||
|
|
||||||
def get_seed_catalog():
|
def get_seed_catalog(seedname='DeveloperSeed'):
|
||||||
'''Returns the developer seed sucatalog'''
|
'''Returns the developer seed sucatalog'''
|
||||||
try:
|
try:
|
||||||
seed_catalogs = plistlib.readPlist(SEED_CATALOGS_PLIST)
|
seed_catalogs = plistlib.readPlist(SEED_CATALOGS_PLIST)
|
||||||
return seed_catalogs.get('DeveloperSeed', DEFAULT_SUCATALOG)
|
return seed_catalogs.get(seedname)
|
||||||
except (OSError, ExpatError, AttributeError, KeyError):
|
except (OSError, ExpatError, AttributeError, KeyError):
|
||||||
return DEFAULT_SUCATALOG
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
def get_default_catalog():
|
||||||
|
'''Returns the default softwareupdate catalog for the current OS'''
|
||||||
|
darwin_major = os.uname()[2].split('.')[0]
|
||||||
|
return DEFAULT_SUCATALOGS.get(darwin_major)
|
||||||
|
|
||||||
|
|
||||||
def make_sparse_image(volume_name, output_path):
|
def make_sparse_image(volume_name, output_path):
|
||||||
@ -207,8 +218,11 @@ class ReplicationError(Exception):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def replicate_url(full_url, root_dir='/tmp',
|
def replicate_url(full_url,
|
||||||
show_progress=False, ignore_cache=False):
|
root_dir='/tmp',
|
||||||
|
show_progress=False,
|
||||||
|
ignore_cache=False,
|
||||||
|
attempt_resume=False):
|
||||||
'''Downloads a URL and stores it in the same relative path on our
|
'''Downloads a URL and stores it in the same relative path on our
|
||||||
filesystem. Returns a path to the replicated file.'''
|
filesystem. Returns a path to the replicated file.'''
|
||||||
|
|
||||||
@ -224,6 +238,8 @@ def replicate_url(full_url, root_dir='/tmp',
|
|||||||
'-o', local_file_path]
|
'-o', local_file_path]
|
||||||
if not ignore_cache and os.path.exists(local_file_path):
|
if not ignore_cache and os.path.exists(local_file_path):
|
||||||
curl_cmd.extend(['-z', local_file_path])
|
curl_cmd.extend(['-z', local_file_path])
|
||||||
|
if attempt_resume:
|
||||||
|
curl_cmd.extend(['-C', '-'])
|
||||||
curl_cmd.append(full_url)
|
curl_cmd.append(full_url)
|
||||||
# print "Downloading %s..." % full_url
|
# print "Downloading %s..." % full_url
|
||||||
try:
|
try:
|
||||||
@ -346,8 +362,8 @@ def download_and_parse_sucatalog(sucatalog, workdir, ignore_cache=False):
|
|||||||
print >> sys.stderr, 'Could not replicate %s: %s' % (sucatalog, err)
|
print >> sys.stderr, 'Could not replicate %s: %s' % (sucatalog, err)
|
||||||
exit(-1)
|
exit(-1)
|
||||||
if os.path.splitext(localcatalogpath)[1] == '.gz':
|
if os.path.splitext(localcatalogpath)[1] == '.gz':
|
||||||
with gzip.open(localcatalogpath) as f:
|
with gzip.open(localcatalogpath) as the_file:
|
||||||
content = f.read()
|
content = the_file.read()
|
||||||
try:
|
try:
|
||||||
catalog = plistlib.readPlistFromString(content)
|
catalog = plistlib.readPlistFromString(content)
|
||||||
return catalog
|
return catalog
|
||||||
@ -430,7 +446,8 @@ def replicate_product(catalog, product_id, workdir, ignore_cache=False):
|
|||||||
try:
|
try:
|
||||||
replicate_url(
|
replicate_url(
|
||||||
package['URL'], root_dir=workdir,
|
package['URL'], root_dir=workdir,
|
||||||
show_progress=True, ignore_cache=ignore_cache)
|
show_progress=True, ignore_cache=ignore_cache,
|
||||||
|
attempt_resume=(not ignore_cache))
|
||||||
except ReplicationError, err:
|
except ReplicationError, err:
|
||||||
print >> sys.stderr, (
|
print >> sys.stderr, (
|
||||||
'Could not replicate %s: %s' % (package['URL'], err))
|
'Could not replicate %s: %s' % (package['URL'], err))
|
||||||
@ -468,9 +485,12 @@ def main():
|
|||||||
'run again with sudo or as root.')
|
'run again with sudo or as root.')
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('--catalogurl', metavar='sucatalog_url',
|
parser.add_argument('--seedprogram', default='',
|
||||||
default=get_seed_catalog(),
|
help='Which Seed Program catalog to use. Valid values '
|
||||||
help='Software Update catalog URL.')
|
'are CustomerSeed, DeveloperSeed, and PublicSeed.')
|
||||||
|
parser.add_argument('--catalogurl', default='',
|
||||||
|
help='Software Update catalog URL. This option '
|
||||||
|
'overrides any seedprogram option.')
|
||||||
parser.add_argument('--workdir', metavar='path_to_working_dir',
|
parser.add_argument('--workdir', metavar='path_to_working_dir',
|
||||||
default='.',
|
default='.',
|
||||||
help='Path to working directory on a volume with over '
|
help='Path to working directory on a volume with over '
|
||||||
@ -519,9 +539,25 @@ def main():
|
|||||||
print "%-17s: %s" % ('OS Version', build_info[0])
|
print "%-17s: %s" % ('OS Version', build_info[0])
|
||||||
print "%-17s: %s\n" % ('Build ID', build_info[1])
|
print "%-17s: %s\n" % ('Build ID', build_info[1])
|
||||||
|
|
||||||
|
if args.catalogurl:
|
||||||
|
su_catalog_url = args.catalogurl
|
||||||
|
elif args.seedprogram:
|
||||||
|
su_catalog_url = get_seed_catalog(args.seedprogram)
|
||||||
|
if not su_catalog_url:
|
||||||
|
print >> sys.stderr, (
|
||||||
|
'Could not find a catalog url for seed program %s'
|
||||||
|
% args.seedprogram)
|
||||||
|
exit(-1)
|
||||||
|
else:
|
||||||
|
su_catalog_url = get_default_catalog()
|
||||||
|
if not su_catalog_url:
|
||||||
|
print >> sys.stderr, (
|
||||||
|
'Could not find a default catalog url for this OS version.')
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
# download sucatalog and look for products that are for macOS installers
|
# download sucatalog and look for products that are for macOS installers
|
||||||
catalog = download_and_parse_sucatalog(
|
catalog = download_and_parse_sucatalog(
|
||||||
args.catalogurl, 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, ignore_cache=args.ignore_cache)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user