Support for installing AAMEE/CCP packages that include updates.

This commit is contained in:
Greg Neagle
2013-05-17 10:20:28 -07:00
parent cd15912feb
commit 5aff95e9cd
3 changed files with 225 additions and 212 deletions

View File

@@ -67,6 +67,39 @@ def convertDateStringToNSDate(datetime_string):
return None
iso_date_string = time.strftime(ISOFormat, dt)
return NSDate.dateWithString_(iso_date_string)
def getCatalogInfoFromPath(pkgpath, options):
"""Gets package metadata for the package at pathname.
Returns cataloginfo"""
cataloginfo = {}
if os.path.exists(pkgpath):
cataloginfo = munkicommon.getPackageMetaData(pkgpath)
if options.installer_choices_xml:
installer_choices_xml = munkicommon.getChoiceChangesXML(pkgpath)
if installer_choices_xml:
cataloginfo['installer_choices_xml'] = installer_choices_xml
if cataloginfo:
# we found a package, but let's see if it's an Adobe CS5 install
# (AAMEE) package
if 'receipts' in cataloginfo:
try:
pkgid = cataloginfo['receipts'][0].get('packageid')
except IndexError:
pkgid = ""
if pkgid.startswith("com.adobe.Enterprise.install"):
# we have an Adobe CS5 install package, process
# as Adobe install
#adobepkgname = cataloginfo['receipts'][0].get('filename')
cataloginfo = adobeutils.getAdobeCatalogInfo(pkgpath)
#mountpoints[0], adobepkgname)
else:
# maybe an Adobe installer/updater/patcher?
cataloginfo = adobeutils.getAdobeCatalogInfo(pkgpath,
options.pkgname or '')
return cataloginfo
def getCatalogInfoFromDmg(dmgpath, options):
@@ -85,49 +118,23 @@ def getCatalogInfoFromDmg(dmgpath, options):
if options.pkgname:
pkgpath = os.path.join(mountpoints[0], options.pkgname)
if os.path.exists(pkgpath):
cataloginfo = munkicommon.getPackageMetaData(pkgpath)
if options.installer_choices_xml:
installer_choices_xml = munkicommon.getChoiceChangesXML(pkgpath)
if installer_choices_xml:
cataloginfo['installer_choices_xml'] = installer_choices_xml
if cataloginfo:
cataloginfo['package_path'] = options.pkgname
cataloginfo = getCatalogInfoFromPath(pkgpath, options)
if cataloginfo:
cataloginfo['package_path'] = options.pkgname
elif not options.item:
# search for first package at root
for fsitem in munkicommon.listdir(mountpoints[0]):
itempath = os.path.join(mountpoints[0], fsitem)
if munkicommon.hasValidInstallerItemExt(itempath):
cataloginfo = munkicommon.getPackageMetaData(itempath)
if options.installer_choices_xml:
installer_choices_xml = munkicommon.getChoiceChangesXML(
itempath)
if installer_choices_xml:
cataloginfo['installer_choices_xml'] = \
installer_choices_xml
cataloginfo = getCatalogInfoFromPath(itempath, options)
# get out of fsitem loop
break
if cataloginfo:
# we found a package, but let's see if it's an Adobe CS5 install
# (AAMEE) package
if 'receipts' in cataloginfo:
try:
pkgid = cataloginfo['receipts'][0].get('packageid')
except IndexError:
pkgid = ""
if pkgid.startswith("com.adobe.Enterprise.install"):
# we have an Adobe CS5 install package, process
# as Adobe install
adobepkgname = cataloginfo['receipts'][0].get('filename')
cataloginfo = adobeutils.getAdobeCatalogInfo(
mountpoints[0], adobepkgname)
else:
# maybe an Adobe installer/updater/patcher?
cataloginfo = adobeutils.getAdobeCatalogInfo(mountpoints[0],
options.pkgname or '')
if not cataloginfo:
# look for one of the many possible Adobe installer/updaters
cataloginfo = adobeutils.getAdobeCatalogInfo(mountpoints[0],
options.pkgname or '')
if not cataloginfo:
# maybe this is a drag-n-drop dmg
# look for given item or an app at the top level of the dmg
@@ -731,12 +738,7 @@ def main():
exit(-1)
elif munkicommon.hasValidPackageExt(item):
catinfo = munkicommon.getPackageMetaData(item)
if options.installer_choices_xml:
installer_choices_xml = munkicommon.getChoiceChangesXML(
item)
if installer_choices_xml:
catinfo['installer_choices_xml'] = installer_choices_xml
catinfo = getCatalogInfoFromPath(item, options)
if not catinfo:
print >> sys.stderr, (
"%s doesn't appear to be a valid installer item!" %

View File

@@ -23,6 +23,7 @@ using the CS3/CS4/CS5 Deployment Toolkits.
#import sys
import os
import re
import subprocess
import time
from xml.dom import minidom
@@ -33,6 +34,92 @@ import munkicommon
import munkistatus
import utils
class AdobeInstallProgressMonitor(object):
"""A class to monitor installs/removals of Adobe products.
Finds the currently active installation log and scrapes data out of it.
Installations that install a product and updates may actually create
multiple logs."""
def __init__(self, kind='CS5', operation='install'):
'''Provide some hints as to what type of installer is running and
whether we are installing or removing'''
self.kind = kind
self.operation = operation
self.payload_count = {}
def get_current_log(self):
'''Returns the current Adobe install log'''
logpath = '/Library/Logs/Adobe/Installers'
# find the most recently-modified log file
proc = subprocess.Popen(['/bin/ls', '-t1', logpath],
bufsize=-1, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(output, unused_err) = proc.communicate()
if output:
firstitem = str(output).splitlines()[0]
if firstitem.endswith(".log"):
# return path of most recently modified log file
return os.path.join(logpath, firstitem)
return None
def info(self):
'''Returns the number of completed Adobe payloads,
and the AdobeCode of the most recently completed payload.'''
last_adobecode = ""
logfile = self.get_current_log()
if logfile:
if self.kind in ['CS6', 'CS5']:
regex = r'END TIMER :: \[Payload Operation :\{'
elif self.kind in ['CS3', 'CS4']:
if self.operation == 'install':
regex = r'Closed PCD cache session payload with ID'
else:
regex = r'Closed CAPS session for removal of payload'
else:
if self.operation == 'install':
regex = r'Completing installation for payload at '
else:
regex = r'Physical payload uninstall result '
cmd = ['/usr/bin/grep', '-E', regex, logfile]
proc = subprocess.Popen(cmd, bufsize=-1,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(output, unused_err) = proc.communicate()
if output:
lines = str(output).splitlines()
completed_payloads = len(lines)
if (not logfile in self.payload_count
or completed_payloads > self.payload_count[logfile]):
# record number of completed payloads
self.payload_count[logfile] = completed_payloads
# now try to get the AdobeCode of the most recently
# completed payload.
# this isn't 100% accurate, but it's mostly for show
# anyway...
regex = re.compile(r'[^{]*(\{[A-Fa-f0-9-]+\})')
lines.reverse()
for line in lines:
m = regex.match(line)
try:
last_adobecode = m.group(1)
break
except (IndexError, AttributeError):
pass
total_completed_payloads = 0
for key in self.payload_count.keys():
total_completed_payloads += self.payload_count[key]
return (total_completed_payloads, last_adobecode)
# dmg helper
# we need this instead of the one in munkicommon because the Adobe stuff
# needs the dmgs mounted under /Volumes. We can merge this later (or not).
@@ -49,7 +136,7 @@ def mountAdobeDmg(dmgpath):
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(pliststr, err) = proc.communicate()
if err:
munkicommon.display_error("Error %s mounting %s." % (err, dmgname))
munkicommon.display_error('Error %s mounting %s.' % (err, dmgname))
if pliststr:
plist = FoundationPlist.readPlistFromString(pliststr)
for entity in plist['system-entities']:
@@ -62,13 +149,13 @@ def mountAdobeDmg(dmgpath):
def getCS5uninstallXML(optionXMLfile):
'''Gets the uninstall deployment data from a CS5 installer'''
dom = minidom.parse(optionXMLfile)
DeploymentInfo = dom.getElementsByTagName("DeploymentInfo")
DeploymentInfo = dom.getElementsByTagName('DeploymentInfo')
if DeploymentInfo:
DeploymentUninstall = DeploymentInfo[0].getElementsByTagName(
"DeploymentUninstall")
'DeploymentUninstall')
if DeploymentUninstall:
deploymentData = DeploymentUninstall[0].getElementsByTagName(
"Deployment")
'Deployment')
if deploymentData:
Deployment = deploymentData[0]
return Deployment.toxml('UTF-8')
@@ -82,22 +169,22 @@ def getCS5mediaSignature(dirpath):
payloads_dir = ""
# look for a payloads folder
for (path, unused_dirs, unused_files) in os.walk(dirpath):
if path.endswith("/payloads"):
if path.endswith('/payloads'):
payloads_dir = path
# return empty-handed if we didn't find a payloads folder
if not payloads_dir:
return ""
return ''
# now look for setup.xml
setupxml = os.path.join(payloads_dir, "Setup.xml")
setupxml = os.path.join(payloads_dir, 'Setup.xml')
if os.path.exists(setupxml) and os.path.isfile(setupxml):
# parse the XML
dom = minidom.parse(setupxml)
setupElements = dom.getElementsByTagName("Setup")
setupElements = dom.getElementsByTagName('Setup')
if setupElements:
mediaSignatureElements = \
setupElements[0].getElementsByTagName("mediaSignature")
setupElements[0].getElementsByTagName('mediaSignature')
if mediaSignatureElements:
element = mediaSignatureElements[0]
elementvalue = ''
@@ -117,7 +204,7 @@ def getPayloadInfo(dirpath):
if item.endswith('.proxy.xml'):
xmlpath = os.path.join(dirpath, item)
dom = minidom.parse(xmlpath)
payload_info = dom.getElementsByTagName("PayloadInfo")
payload_info = dom.getElementsByTagName('PayloadInfo')
if payload_info:
installer_properties = \
payload_info[0].getElementsByTagName(
@@ -125,7 +212,7 @@ def getPayloadInfo(dirpath):
if installer_properties:
properties = \
installer_properties[0].getElementsByTagName(
"Property")
'Property')
for prop in properties:
if 'name' in prop.attributes.keys():
propname = \
@@ -142,10 +229,10 @@ def getPayloadInfo(dirpath):
installmetadata = \
payload_info[0].getElementsByTagName(
"InstallDestinationMetadata")
'InstallDestinationMetadata')
if installmetadata:
totalsizes = \
installmetadata[0].getElementsByTagName("TotalSize")
installmetadata[0].getElementsByTagName('TotalSize')
if totalsizes:
installsize = ''
for node in totalsizes[0].childNodes:
@@ -163,15 +250,15 @@ def getAdobeSetupInfo(installroot):
info = {}
payloads = []
# look for a payloads folder
# look for all the payloads folders
for (path, unused_dirs, unused_files) in os.walk(installroot):
if path.endswith("/payloads"):
if path.endswith('/payloads'):
driverfolder = ''
mediaSignature = ''
setupxml = os.path.join(path, "setup.xml")
setupxml = os.path.join(path, 'setup.xml')
if os.path.exists(setupxml):
dom = minidom.parse(setupxml)
drivers = dom.getElementsByTagName("Driver")
drivers = dom.getElementsByTagName('Driver')
if drivers:
driver = drivers[0]
if 'folder' in driver.attributes.keys():
@@ -179,11 +266,11 @@ def getAdobeSetupInfo(installroot):
driver.attributes['folder'].value.encode('UTF-8')
if driverfolder == '':
# look for mediaSignature (CS5 AAMEE install)
setupElements = dom.getElementsByTagName("Setup")
setupElements = dom.getElementsByTagName('Setup')
if setupElements:
mediaSignatureElements = \
setupElements[0].getElementsByTagName(
"mediaSignature")
'mediaSignature')
if mediaSignatureElements:
element = mediaSignatureElements[0]
for node in element.childNodes:
@@ -199,11 +286,7 @@ def getAdobeSetupInfo(installroot):
payloadinfo['AdobeCode'] == mediaSignature):
info['display_name'] = payloadinfo['display_name']
info['version'] = payloadinfo['version']
info['AdobeSetupType'] = "ProductInstall"
# we found a payloads directory,
# so no need to keep walking the installroot
break
info['AdobeSetupType'] = 'ProductInstall'
if not payloads:
# look for an extensions folder; almost certainly this is an Updater
@@ -286,92 +369,16 @@ def getAdobePackageInfo(installroot):
return info
def getAdobeInstallLog():
'''Returns the current Adobe install log'''
logpath = "/Library/Logs/Adobe/Installers"
# find the most recently-modified log file
proc = subprocess.Popen(['/bin/ls', '-t1', logpath],
bufsize=1, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(output, unused_err) = proc.communicate()
if output:
firstitem = str(output).splitlines()[0]
if firstitem.endswith(".log"):
# get the last line of the most recently modified log
return os.path.join(logpath, firstitem)
return None
def getAdobeInstallProgressInfo(previous_completedpayloads,
previous_payloadname):
'''Returns the number of completed Adobe payloads,
and the name of the most recentlly completed payload.'''
completedpayloads = previous_completedpayloads
lastpayloadname = previous_payloadname
logfile = getAdobeInstallLog()
if logfile:
# get number of completed payloads
regex = "(Completing installation for payload at )"
regex += "|"
regex += "(Physical payload uninstall result)"
cmd = ['/usr/bin/grep', '-c', "-E", regex, logfile]
proc = subprocess.Popen(cmd, bufsize=1,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(output, unused_err) = proc.communicate()
if output:
try:
completedpayloads = int(str(output).rstrip("\n"))
except (ValueError, TypeError):
completedpayloads = previous_completedpayloads
if completedpayloads > previous_completedpayloads:
# now try to get the name of the most recently completed payload
# this isn't 100% accurate, but it's mostly for show anyway...
regex = " for payload \{.*\} "
cmd = ['/usr/bin/grep', "-E", regex, logfile]
proc = subprocess.Popen(cmd, bufsize=1,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(output, unused_err) = proc.communicate()
if output:
# start with the last line of the output
# and work backwards until we find a name
lines = str(output).splitlines()
lines.reverse()
for line in lines:
parts = line.split("}", 1)
if len(parts) == 2:
if parts[1]:
name = parts[1].lstrip()
if not name.startswith("returned :"):
lastpayloadname = name
break
return (completedpayloads, lastpayloadname)
def countPayloads(dirpath):
'''Attempts to count the payloads in the Adobe installation item'''
for item in munkicommon.listdir(dirpath):
itempath = os.path.join(dirpath, item)
if os.path.isdir(itempath):
if item == "payloads":
count = 0
for subitem in munkicommon.listdir(itempath):
subitempath = os.path.join(itempath, subitem)
if os.path.isdir(subitempath):
count = count + 1
return count
else:
payloadcount = countPayloads(itempath)
if payloadcount:
return payloadcount
return 0
count = 0
for (path, unused_dirs, unused_files) in os.walk(dirpath):
if path.endswith("/payloads"):
for subitem in munkicommon.listdir(path):
subitempath = os.path.join(path, subitem)
if os.path.isdir(subitempath):
count = count + 1
return count
def getPercent(current, maximum):
@@ -464,9 +471,16 @@ def killStupidProcesses():
return
def runAdobeInstallTool(cmd, number_of_payloads=0, killAdobeAIR=False):
def runAdobeInstallTool(
cmd, number_of_payloads=0, killAdobeAIR=False, payloads=None,
kind="CS5", operation="install"):
'''An abstraction of the tasks for running Adobe Setup,
AdobeUberInstaller, AdobeUberUninstaller, AdobeDeploymentManager, etc'''
# initialize an AdobeInstallProgressMonitor object.
progress_monitor = AdobeInstallProgressMonitor(
kind=kind, operation=operation)
if munkicommon.munkistatusoutput and not number_of_payloads:
# indeterminate progress bar
munkistatus.percent(-1)
@@ -479,12 +493,16 @@ def runAdobeInstallTool(cmd, number_of_payloads=0, killAdobeAIR=False):
payloadname = ""
while (proc.poll() == None):
time.sleep(1)
(payload_completed_count, payloadname) = \
getAdobeInstallProgressInfo(old_payload_completed_count,
payloadname)
(payload_completed_count, adobe_code) = progress_monitor.info()
if payload_completed_count > old_payload_completed_count:
old_payload_completed_count = payload_completed_count
if payloadname:
if adobe_code and payloads:
matched_payloads = [payload for payload in payloads
if payload.get('AdobeCode') == adobe_code]
if matched_payloads:
payloadname = matched_payloads[0].get('display_name')
else:
payloadname = adobe_code
payloadinfo = " - " + payloadname
else:
payloadinfo = ""
@@ -537,7 +555,7 @@ def runAdobeInstallTool(cmd, number_of_payloads=0, killAdobeAIR=False):
return retcode
def runAdobeSetup(dmgpath, uninstalling=False):
def runAdobeSetup(dmgpath, uninstalling=False, payloads=None):
'''Runs the Adobe setup tool in silent mode from
an Adobe update DMG or an Adobe CS3 install DMG'''
munkicommon.display_status_minor(
@@ -551,6 +569,7 @@ def runAdobeSetup(dmgpath, uninstalling=False):
installxml = os.path.join(mountpoints[0], "install.xml")
uninstallxml = os.path.join(mountpoints[0], "uninstall.xml")
if uninstalling:
operation = 'uninstall'
if os.path.exists(uninstallxml):
deploymentfile = uninstallxml
else:
@@ -563,6 +582,7 @@ def runAdobeSetup(dmgpath, uninstalling=False):
os.path.basename(dmgpath))
return -1
else:
operation = 'install'
if os.path.exists(installxml):
deploymentfile = installxml
@@ -575,7 +595,9 @@ def runAdobeSetup(dmgpath, uninstalling=False):
if deploymentfile:
adobe_setup.append('--deploymentFile=%s' % deploymentfile)
retcode = runAdobeInstallTool(adobe_setup, number_of_payloads)
retcode = runAdobeInstallTool(
adobe_setup, number_of_payloads, payloads=payloads,
kind='CS3', operation=operation)
else:
munkicommon.display_error(
@@ -603,7 +625,7 @@ def writefile(stringdata, path):
return ""
def doAdobeCS5Uninstall(adobeInstallInfo):
def doAdobeCS5Uninstall(adobeInstallInfo, payloads=None):
'''Runs the locally-installed Adobe CS5 tools to remove CS5 products.
We need the uninstallxml and the CS5 Setup.app.'''
uninstallxml = adobeInstallInfo.get('uninstallxml')
@@ -626,10 +648,11 @@ def doAdobeCS5Uninstall(adobeInstallInfo):
'--skipProcessCheck=1',
'--deploymentFile=%s' % deploymentFile ]
munkicommon.display_status_minor('Running Adobe Uninstall')
return runAdobeInstallTool(uninstall_cmd, payloadcount)
return runAdobeInstallTool(uninstall_cmd, payloadcount, payloads=payloads,
kind='CS5', operation='uninstall')
def runAdobeCS5AAMEEInstall(dmgpath):
def runAdobeCS5AAMEEInstall(dmgpath, payloads=None):
'''Installs a CS5 product using an AAMEE-generated package on a
disk image.'''
munkicommon.display_status_minor(
@@ -643,13 +666,16 @@ def runAdobeCS5AAMEEInstall(dmgpath):
if deploymentmanager:
# big hack to convince the Adobe tools to install off a mounted
# disk image.
# For some reason, the Adobe install tools refuse to install when
# the payloads are on a "removable" disk, which includes mounted disk
# images.
#
# For some reason, some versions of the Adobe install tools refuse to
# install when the payloads are on a "removable" disk,
# which includes mounted disk images.
#
# we create a temporary directory on the local disk and then symlink
# some resources from the mounted disk image to the temporary
# directory. When we pass this temporary directory to the Adobe
# installation tools, they are now happy.
basepath = os.path.dirname(deploymentmanager)
number_of_payloads = countPayloads(basepath)
tmpdir = tempfile.mkdtemp(prefix='munki-', dir='/tmp')
@@ -657,14 +683,17 @@ def runAdobeCS5AAMEEInstall(dmgpath):
# make our symlinks
os.symlink(os.path.join(basepath,"ASU"), os.path.join(tmpdir, "ASU"))
os.symlink(os.path.join(basepath,"ProvisioningTool"),
os.path.join(tmpdir, "ProvisioningTool"))
os.path.join(tmpdir, "ProvisioningTool"))
realsetupdir = os.path.join(basepath,"Setup")
tmpsetupdir = os.path.join(tmpdir, "Setup")
os.mkdir(tmpsetupdir)
for item in munkicommon.listdir(realsetupdir):
os.symlink(os.path.join(realsetupdir, item),
os.path.join(tmpsetupdir, item))
for dir_name in ['Patches', 'Setup']:
realdir = os.path.join(basepath, dir_name)
if os.path.isdir(realdir):
tmpsubdir = os.path.join(tmpdir, dir_name)
os.mkdir(tmpsubdir)
for item in munkicommon.listdir(realdir):
os.symlink(
os.path.join(realdir, item),
os.path.join(tmpsubdir, item))
optionXMLfile = os.path.join(basepath, "optionXML.xml")
if (not munkicommon.getconsoleuser() or
@@ -677,12 +706,13 @@ def runAdobeCS5AAMEEInstall(dmgpath):
cmd = []
cmd.extend([deploymentmanager, '--optXMLPath=%s' % optionXMLfile,
'--setupBasePath=%s' % tmpdir, '--installDirPath=/',
'--mode=install'])
'--setupBasePath=%s' % basepath, '--installDirPath=/',
'--mode=install'])
munkicommon.display_status_minor('Starting Adobe installer...')
retcode = runAdobeInstallTool(cmd, number_of_payloads,
killAdobeAIR=True)
retcode = runAdobeInstallTool(
cmd, number_of_payloads, killAdobeAIR=True, payloads=payloads,
kind='CS5', operation='install')
# now clean up our symlink hackfest
unused_result = subprocess.call(["/bin/rm", "-rf", tmpdir])
else:
@@ -695,7 +725,7 @@ def runAdobeCS5AAMEEInstall(dmgpath):
return retcode
def runAdobeCS5PatchInstaller(dmgpath, copylocal=False):
def runAdobeCS5PatchInstaller(dmgpath, copylocal=False, payloads=None):
'''Runs the AdobePatchInstaller for CS5.
Optionally can copy the DMG contents to the local disk
to work around issues with the patcher.'''
@@ -730,7 +760,8 @@ def runAdobeCS5PatchInstaller(dmgpath, copylocal=False):
'--mode=silent',
'--skipProcessCheck=1' ]
retcode = runAdobeInstallTool(install_cmd,
number_of_payloads)
number_of_payloads, payloads=payloads,
kind='CS5', operation='install')
else:
munkicommon.display_error(
"%s doesn't appear to contain AdobePatchInstaller.app." %
@@ -747,7 +778,7 @@ def runAdobeCS5PatchInstaller(dmgpath, copylocal=False):
return -1
def runAdobeUberTool(dmgpath, pkgname='', uninstalling=False):
def runAdobeUberTool(dmgpath, pkgname='', uninstalling=False, payloads=None):
'''Runs either AdobeUberInstaller or AdobeUberUninstaller
from a disk image and provides progress feedback.
pkgname is the name of a directory at the top level of the dmg
@@ -769,8 +800,10 @@ def runAdobeUberTool(dmgpath, pkgname='', uninstalling=False):
info = getAdobePackageInfo(installroot)
packagename = info['display_name']
action = "Installing"
operation = "install"
if uninstalling:
action = "Uninstalling"
operation = "uninstall"
munkicommon.display_status_major('%s %s' % (action, packagename))
if munkicommon.munkistatusoutput:
munkistatus.detail('Starting %s' % os.path.basename(ubertool))
@@ -780,7 +813,8 @@ def runAdobeUberTool(dmgpath, pkgname='', uninstalling=False):
number_of_payloads = countPayloads(installroot)
retcode = runAdobeInstallTool(
[ubertool], number_of_payloads, killAdobeAIR=True)
[ubertool], number_of_payloads, killAdobeAIR=True,
payloads=payloads, kind='CS4', operation=operation)
else:
munkicommon.display_error("No %s found" % ubertool)
@@ -793,23 +827,6 @@ def runAdobeUberTool(dmgpath, pkgname='', uninstalling=False):
return -1
#lastpatchlogline = ''
#def getAcrobatPatchLogInfo(logpath):
# '''Gets info from the Adobe Acrobat patch log'''
# global lastpatchlogline
# if os.path.exists(logpath):
# proc = subprocess.Popen(['/usr/bin/tail', '-1', logpath],
# bufsize=1, stdout=subprocess.PIPE,
# stderr=subprocess.PIPE)
# (output, err) = proc.communicate()
# logline = output.rstrip('\n')
# # is it different than the last time we checked?
# if logline != lastpatchlogline:
# lastpatchlogline = logline
# return logline
# return ''
def findAcrobatPatchApp(dirpath):
'''Attempts to find an AcrobatPro patching application
in dirpath. If found, returns the path to the bundled
@@ -913,23 +930,12 @@ def updateAcrobatPro(dmgpath):
cmd = [ApplyOperation, apppath, appname, resourcesDir,
callingScriptPath, str(payloadNum)]
# figure out the log file path
#patchappname = os.path.basename(pathToAcrobatPatchApp)
#logfile_name = patchappname.split('.')[0] + str(payloadNum) + '.log'
#homePath = os.path.expanduser("~")
#logfile_dir = os.path.join(homePath, "Library", "Logs",
# "Adobe", "Acrobat")
#logfile_path = os.path.join(logfile_dir, logfile_name)
proc = subprocess.Popen(cmd, shell=False, bufsize=1,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
while (proc.poll() == None):
time.sleep(1)
#loginfo = getAcrobatPatchLogInfo(logfile_path)
#if loginfo:
# print loginfo
# run of patch tool completed
retcode = proc.poll()
@@ -1186,6 +1192,7 @@ def adobeSetupError(errorcode):
def doAdobeRemoval(item):
'''Wrapper for all the Adobe removal methods'''
uninstallmethod = item['uninstall_method']
payloads = item.get("payloads")
itempath = ""
if "uninstaller_item" in item:
managedinstallbase = munkicommon.pref('ManagedInstallDir')
@@ -1199,18 +1206,19 @@ def doAdobeRemoval(item):
if uninstallmethod == "AdobeSetup":
# CS3 uninstall
retcode = runAdobeSetup(itempath, uninstalling=True)
retcode = runAdobeSetup(itempath, uninstalling=True, payloads=payloads)
elif uninstallmethod == "AdobeUberUninstaller":
# CS4 uninstall
pkgname = item.get("adobe_package_name") or \
item.get("package_path","")
retcode = runAdobeUberTool(itempath, pkgname, uninstalling=True)
retcode = runAdobeUberTool(
itempath, pkgname, uninstalling=True, payloads=payloads)
elif uninstallmethod == "AdobeCS5AAMEEPackage":
# CS5 uninstall. Sheesh. Three releases, three methods.
adobeInstallInfo = item.get('adobe_install_info')
retcode = doAdobeCS5Uninstall(adobeInstallInfo)
retcode = doAdobeCS5Uninstall(adobeInstallInfo, payloads=payloads)
if retcode:
munkicommon.display_error("Uninstall of %s failed." % item['name'])
@@ -1228,24 +1236,25 @@ def doAdobeInstall(item):
'Cache',
item["installer_item"])
installer_type = item.get("installer_type","")
payloads = item.get("payloads")
if installer_type == "AdobeSetup":
# Adobe CS3/CS4 updater or Adobe CS3 installer
retcode = runAdobeSetup(itempath)
retcode = runAdobeSetup(itempath, payloads=payloads)
elif installer_type == "AdobeUberInstaller":
# Adobe CS4 installer
pkgname = item.get("adobe_package_name") or \
item.get("package_path","")
retcode = runAdobeUberTool(itempath, pkgname)
retcode = runAdobeUberTool(itempath, pkgname, payloads=payloads)
elif installer_type == "AdobeAcrobatUpdater":
# Acrobat Pro 9 updater
retcode = updateAcrobatPro(itempath)
elif installer_type == "AdobeCS5AAMEEPackage":
# Adobe CS5 AAMEE package
retcode = runAdobeCS5AAMEEInstall(itempath)
retcode = runAdobeCS5AAMEEInstall(itempath, payloads=payloads)
elif installer_type == "AdobeCS5PatchInstaller":
# Adobe CS5 updater
retcode = runAdobeCS5PatchInstaller(itempath,
copylocal=item.get("copy_local"))
copylocal=item.get("copy_local"), payloads=payloads)
return retcode

View File

@@ -1765,6 +1765,7 @@ def processInstall(manifestitem, cataloglist, installinfo):
'installs',
'requires',
'update_for',
'payloads',
'preinstall_script',
'postinstall_script',
'items_to_copy', # used w/ copy_from_dmg
@@ -2211,6 +2212,7 @@ def processRemoval(manifestitem, cataloglist, installinfo):
'installs',
'requires',
'update_for',
'payloads',
'preuninstall_script',
'postuninstall_script',
'apple_item']