mirror of
https://github.com/grahampugh/macadmin-scripts.git
synced 2025-12-18 10:16:37 +00:00
Add SeedProgram xattr to Install macOS app; making a compressed read-only dmg is now the default
This commit is contained in:
parent
aca77ebbf2
commit
314eca5f23
@ -31,6 +31,7 @@ import plistlib
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import urlparse
|
import urlparse
|
||||||
|
import xattr
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
from xml.parsers.expat import ExpatError
|
from xml.parsers.expat import ExpatError
|
||||||
|
|
||||||
@ -40,15 +41,27 @@ DEFAULT_SUCATALOG = (
|
|||||||
'index-10.13seed-10.13-10.12-10.11-10.10-10.9'
|
'index-10.13seed-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.gz')
|
||||||
|
|
||||||
|
SEED_CATALOGS_PLIST = (
|
||||||
|
'/System/Library/PrivateFrameworks/Seeding.framework/Versions/Current/'
|
||||||
|
'Resources/SeedCatalogs.plist'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_seeding_program(sucatalog_url):
|
||||||
|
'''Returns a seeding program name based on the sucatalog_url'''
|
||||||
|
try:
|
||||||
|
seed_catalogs = plistlib.readPlist(SEED_CATALOGS_PLIST)
|
||||||
|
for key, value in seed_catalogs.items():
|
||||||
|
if sucatalog_url == value:
|
||||||
|
return key
|
||||||
|
except (OSError, ExpatError, AttributeError, KeyError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_seed_catalog():
|
def get_seed_catalog():
|
||||||
'''Returns the developer seed sucatalog'''
|
'''Returns the developer seed sucatalog'''
|
||||||
seed_catalogs_plist = (
|
|
||||||
'/System/Library/PrivateFrameworks/Seeding.framework/Versions/Current/'
|
|
||||||
'Resources/SeedCatalogs.plist'
|
|
||||||
)
|
|
||||||
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('DeveloperSeed', DEFAULT_SUCATALOG)
|
||||||
except (OSError, ExpatError, AttributeError, KeyError):
|
except (OSError, ExpatError, AttributeError, KeyError):
|
||||||
return DEFAULT_SUCATALOG
|
return DEFAULT_SUCATALOG
|
||||||
@ -352,6 +365,15 @@ def replicate_product(catalog, product_id, workdir, ignore_cache=False):
|
|||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
|
|
||||||
|
def find_installer_app(mountpoint):
|
||||||
|
'''Returns the path to the Install macOS app on the mountpoint'''
|
||||||
|
applications_dir = os.path.join(mountpoint, 'Applications')
|
||||||
|
for item in os.listdir(applications_dir):
|
||||||
|
if item.endswith('.app'):
|
||||||
|
return os.path.join(applications_dir, item)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
'''Do the main thing here'''
|
'''Do the main thing here'''
|
||||||
if os.getuid() != 0:
|
if os.getuid() != 0:
|
||||||
@ -369,7 +391,13 @@ def main():
|
|||||||
'directory.')
|
'directory.')
|
||||||
parser.add_argument('--compress', action='store_true',
|
parser.add_argument('--compress', action='store_true',
|
||||||
help='Output a read-only compressed disk image with '
|
help='Output a read-only compressed disk image with '
|
||||||
'the Install macOS app at the root.')
|
'the Install macOS app at the root. This is now the '
|
||||||
|
'default. Use --raw to get a read-write sparse image '
|
||||||
|
'with the app in the Applications directory.')
|
||||||
|
parser.add_argument('--raw', action='store_true',
|
||||||
|
help='Output a read-write sparse image '
|
||||||
|
'with the app in the Applications directory. Requires '
|
||||||
|
'less available disk space and is faster.')
|
||||||
parser.add_argument('--ignore-cache', action='store_true',
|
parser.add_argument('--ignore-cache', action='store_true',
|
||||||
help='Ignore any previously cached files.')
|
help='Ignore any previously cached files.')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
@ -431,22 +459,25 @@ def main():
|
|||||||
print >> sys.stderr, 'Product installation failed.'
|
print >> sys.stderr, 'Product installation failed.'
|
||||||
unmountdmg(mountpoint)
|
unmountdmg(mountpoint)
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
# add the seeding program xattr to the app if applicable
|
||||||
|
seeding_program = get_seeding_program(args.catalogurl)
|
||||||
|
if seeding_program:
|
||||||
|
installer_app = find_installer_app(mountpoint)
|
||||||
|
if installer_app:
|
||||||
|
xattr.setxattr(installer_app, 'SeedProgram', seeding_program)
|
||||||
print 'Product downloaded and installed to %s' % sparse_diskimage_path
|
print 'Product downloaded and installed to %s' % sparse_diskimage_path
|
||||||
if not args.compress:
|
if args.raw:
|
||||||
unmountdmg(mountpoint)
|
unmountdmg(mountpoint)
|
||||||
else:
|
else:
|
||||||
# if --compress option given, create a r/o compressed diskimage
|
# if --raw option not given, create a r/o compressed diskimage
|
||||||
# containing the Install macOS app
|
# containing the Install macOS app
|
||||||
compressed_diskimagepath = os.path.join(
|
compressed_diskimagepath = os.path.join(
|
||||||
args.workdir, volname + '.dmg')
|
args.workdir, volname + '.dmg')
|
||||||
if os.path.exists(compressed_diskimagepath):
|
if os.path.exists(compressed_diskimagepath):
|
||||||
os.unlink(compressed_diskimagepath)
|
os.unlink(compressed_diskimagepath)
|
||||||
applications_dir = os.path.join(mountpoint, 'Applications')
|
app_path = find_installer_app(mountpoint)
|
||||||
for item in os.listdir(applications_dir):
|
if app_path:
|
||||||
if item.endswith('.app'):
|
make_compressed_dmg(app_path, compressed_diskimagepath)
|
||||||
app_path = os.path.join(applications_dir, item)
|
|
||||||
make_compressed_dmg(app_path, compressed_diskimagepath)
|
|
||||||
break
|
|
||||||
# unmount sparseimage
|
# unmount sparseimage
|
||||||
unmountdmg(mountpoint)
|
unmountdmg(mountpoint)
|
||||||
# delete sparseimage since we don't need it any longer
|
# delete sparseimage since we don't need it any longer
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user