mirror of
https://github.com/munki/munki.git
synced 2026-05-04 19:39:22 -05:00
Added support for installcheck and managedinstaller to handle Apple Software Updates.
Moved some functions from makepkginfo to munkilib so installcheck could use them. Added checking to installcheck, managedinstaller, and removepackages.py so they warn and exit if run by a non-root user. Added checks to installcheck and mamangedinstaller so that they exit if the other is running. git-svn-id: http://munki.googlecode.com/svn/trunk@87 a4e17f2e-e282-11dd-95e1-755cbddbdd66
This commit is contained in:
+5
-119
@@ -44,120 +44,6 @@ import hashlib
|
||||
import munkilib
|
||||
|
||||
|
||||
def mountdmg(dmgpath):
|
||||
"""
|
||||
Attempts to mount the dmg at dmgpath
|
||||
and returns a list of mountpoints
|
||||
"""
|
||||
mountpoints = []
|
||||
dmgname = os.path.basename(dmgpath)
|
||||
p = subprocess.Popen(['/usr/bin/hdiutil', 'attach', dmgpath, '-mountRandom', '/tmp', '-nobrowse', '-plist'],
|
||||
bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
(plist, err) = p.communicate()
|
||||
if err:
|
||||
print >>sys.stderr, "Error %s mounting %s." % (err, dmgpath)
|
||||
if plist:
|
||||
pl = plistlib.readPlistFromString(plist)
|
||||
for entity in pl['system-entities']:
|
||||
if 'mount-point' in entity:
|
||||
mountpoints.append(entity['mount-point'])
|
||||
|
||||
return mountpoints
|
||||
|
||||
|
||||
def unmountdmg(mountpoint):
|
||||
"""
|
||||
Unmounts the dmg at mountpoint
|
||||
"""
|
||||
p = subprocess.Popen(['/usr/bin/hdiutil', 'detach', mountpoint],
|
||||
bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
(output, err) = p.communicate()
|
||||
if err:
|
||||
print >>sys.stderr, err
|
||||
p = subprocess.Popen(['/usr/bin/hdiutil', 'detach', mountpoint, '-force'],
|
||||
bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
(output, err) = p.communicate()
|
||||
|
||||
|
||||
def nameAndVersion(s):
|
||||
"""
|
||||
Splits a string into the name and version numbers:
|
||||
'TextWrangler2.3b1' becomes ('TextWrangler', '2.3b1')
|
||||
'AdobePhotoshopCS3-11.2.1' becomes ('AdobePhotoshopCS3', '11.2.1')
|
||||
'MicrosoftOffice2008v12.2.1' becomes ('MicrosoftOffice2008', '12.2.1')
|
||||
"""
|
||||
index = 0
|
||||
for char in s:
|
||||
if char in "0123456789":
|
||||
possibleVersion = s[index:]
|
||||
if not (" " in possibleVersion or "_" in possibleVersion or "-" in possibleVersion or "v" in possibleVersion):
|
||||
return (s[0:index].rstrip(" .-_v"), possibleVersion)
|
||||
index += 1
|
||||
# no version number found, just return original string and empty string
|
||||
return (s, '')
|
||||
|
||||
|
||||
def getCatalogInfo(pkgitem):
|
||||
"""
|
||||
The core function here. Queries an installer item (.pkg, .mpkg)
|
||||
and gets metadata. There are a lot of valid Apple package formats
|
||||
and this function may not deal with them all equally well.
|
||||
Standard bundle packages are probably the best understood and documented,
|
||||
so this code deals with those pretty well.
|
||||
|
||||
metadata items include:
|
||||
installer_item_size: size of the installer item (.dmg, .pkg, etc)
|
||||
installed_size: size of items that will be installed
|
||||
RestartAction: will a restart be needed after installation?
|
||||
name
|
||||
version
|
||||
description
|
||||
receipts: an array of packageids that may be installed (some may be optional)
|
||||
"""
|
||||
installedsize = 0
|
||||
installerinfo = munkilib.getInstallerPkgInfo(pkgitem)
|
||||
info = munkilib.getPkgInfo(pkgitem)
|
||||
|
||||
highestpkgversion = "0.0"
|
||||
for infoitem in info:
|
||||
if version.LooseVersion(infoitem['version']) > version.LooseVersion(highestpkgversion):
|
||||
highestpkgversion = infoitem['version']
|
||||
if "installed_size" in infoitem:
|
||||
# note this is in KBytes
|
||||
installedsize += infoitem['installed_size']
|
||||
|
||||
name = os.path.split(pkgitem)[1]
|
||||
shortname = os.path.splitext(name)[0]
|
||||
metaversion = nameAndVersion(shortname)[1]
|
||||
if not len(metaversion):
|
||||
metaversion = highestpkgversion
|
||||
elif highestpkgversion.startswith(metaversion):
|
||||
#for example, highestpkgversion is 2.0.3124.0, version in filename is 2.0
|
||||
metaversion = highestpkgversion
|
||||
|
||||
if 'installed_size' in installerinfo:
|
||||
if installerinfo['installed_size'] > 0:
|
||||
installedsize = installerinfo['installed_size']
|
||||
|
||||
cataloginfo = {}
|
||||
cataloginfo['name'] = nameAndVersion(shortname)[0]
|
||||
cataloginfo['version'] = metaversion
|
||||
for key in ('display_name', 'RestartAction', 'description'):
|
||||
if key in installerinfo:
|
||||
cataloginfo[key] = installerinfo[key]
|
||||
|
||||
if installedsize > 0:
|
||||
cataloginfo['installed_size'] = installedsize
|
||||
|
||||
cataloginfo['receipts'] = []
|
||||
for infoitem in info:
|
||||
pkginfo = {}
|
||||
pkginfo['packageid'] = infoitem['id']
|
||||
pkginfo['version'] = infoitem['version']
|
||||
cataloginfo['receipts'].append(pkginfo)
|
||||
return cataloginfo
|
||||
|
||||
|
||||
def getCatalogInfoFromDmg(dmgpath):
|
||||
"""
|
||||
* Mounts a disk image
|
||||
@@ -167,21 +53,21 @@ def getCatalogInfoFromDmg(dmgpath):
|
||||
To-do: handle multiple installer items on a disk image
|
||||
"""
|
||||
cataloginfo = None
|
||||
mountpoints = mountdmg(dmgpath)
|
||||
mountpoints = munkilib.mountdmg(dmgpath)
|
||||
for mountpoint in mountpoints:
|
||||
for fsitem in os.listdir(mountpoint):
|
||||
itempath = os.path.join(mountpoint, fsitem)
|
||||
if itempath.endswith('.pkg') or itempath.endswith('.mpkg'):
|
||||
cataloginfo = getCatalogInfo(itempath)
|
||||
cataloginfo = munkilib.getPackageMetaData(itempath)
|
||||
# get out of fsitem loop
|
||||
break
|
||||
if cataloginfo:
|
||||
# get out of moutpoint loop
|
||||
# get out of mountpoint loop
|
||||
break
|
||||
|
||||
#unmount all the mountpoints from the dmg
|
||||
for mountpoint in mountpoints:
|
||||
unmountdmg(mountpoint)
|
||||
munkilib.unmountdmg(mountpoint)
|
||||
return cataloginfo
|
||||
|
||||
|
||||
@@ -301,7 +187,7 @@ def main():
|
||||
if item.endswith('.dmg'):
|
||||
catinfo = getCatalogInfoFromDmg(item)
|
||||
elif item.endswith('.pkg') or item.endswith('.mpkg'):
|
||||
catinfo = getCatalogInfo(item)
|
||||
catinfo = munkilib.getPackageMetaData(item)
|
||||
else:
|
||||
print >>sys.stderr, "%s is not an installer package!" % item
|
||||
exit(-1)
|
||||
|
||||
Reference in New Issue
Block a user