Created
February 21, 2013 16:17
-
-
Save timsutton/5005855 to your computer and use it in GitHub Desktop.
TaskExecutor.py helper script from Adobe's abominable Reader 10 update pkg
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import sys,os,plistlib,pwd,grp,stat,urllib,subprocess,traceback,re | |
taskPlist = unicode(sys.argv[2], sys.getfilesystemencoding()) | |
appPath = unicode(sys.argv[3], sys.getfilesystemencoding()) | |
patchStore = unicode(sys.argv[4], sys.getfilesystemencoding()) | |
binaryPath = unicode(sys.argv[5], sys.getfilesystemencoding()) | |
CLI_mode = sys.argv[6] | |
title = sys.argv[7] | |
rollbackStore = '' | |
if len(sys.argv) == 9: | |
rollbackStore = unicode(sys.argv[8], sys.getfilesystemencoding()) | |
rollbackTask =[] | |
errorCodeDict = { | |
"PathAbsentForAttributesChange":108, | |
"ChangeOwnershipFailed":109, | |
"ChangePermissionFailed":110, | |
"OverwriteFileFailed":111, | |
"RemovePathFailed":112, | |
"FailedAttributesCheck":113, | |
"FailedChecksumMatch":114, | |
"RollbackError":115, | |
"GenericError":116, | |
} | |
def log(str): | |
try: | |
print repr(str) | |
except Exception, err: | |
print "Unable to log some text." | |
return | |
def runCmd(cmd, logOutput): | |
''' | |
execute a command | |
''' | |
status = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
(output,error) = status.communicate() | |
returncode = status.returncode | |
if returncode != 0 or error != '' or (logOutput == True and output != '') or enable_debug_logs == 1: | |
log((" cmd: %s") %(cmd)) | |
log((" cmdRetCode [%d], cmdErrMsg [%s], cmdOutput [%s]") %(returncode, error.strip() , output.strip())) | |
return (output,error,returncode) | |
def installLocFromPkgId(pkgId): | |
''' | |
get installation location from package identifier | |
''' | |
installpath = '' | |
if pkgId == 'com.adobe.acrobat.10.viewer.app.pkg' or pkgId == 'com.adobe.acrobat.reader.10.reader.app.pkg': | |
installpath = os.path.dirname(appPath) | |
elif pkgId == 'com.adobe.acrobat.10.viewer.browser.pkg' or pkgId == 'com.adobe.acrobat.reader.10.reader.browser.pkg': | |
installpath = "/Library/Internet Plug-Ins" | |
elif pkgId == 'com.adobe.acrobat.10.viewer.appsupport.pkg' or pkgId == 'com.adobe.acrobat.reader.10.reader.appsupport.pkg': | |
installpath = "/Library/Application Support" | |
elif pkgId == 'com.adobe.acrobat.10.viewer.print_pdf_services.pkg': | |
installpath = "/Library/PDF Services" | |
elif pkgId == 'com.adobe.acrobat.10.viewer.print_automator.pkg': | |
installpath = "/Library/Automator" | |
elif pkgId == 'com.adobe.acrobat.10.viewer.preferences.pkg': | |
installpath = "/Library/Preferences" | |
else: | |
log(("Invalid package identifier obtained:%s.") %(pkgId)) | |
raise Exception("GenericError") | |
return installpath | |
def replaceWithRenamedApplication(src,dest): | |
''' | |
if user has renamed the application | |
''' | |
destModified='' | |
if src.rfind("Adobe Acrobat Pro.app") != -1 and appPath.rfind("Adobe Acrobat Pro.app") == -1: | |
index = dest.rfind("Adobe Acrobat Pro.app") | |
destModified=dest[0:index] + dest[index:len(dest)].replace("Adobe Acrobat Pro.app",os.path.basename(appPath)) | |
if src.rfind("Adobe Reader.app") != -1 and appPath.rfind("Adobe Reader.app") == -1: | |
index = dest.rfind("Adobe Reader.app") | |
destModified=dest[0:index] + dest[index:len(dest)].replace("Adobe Reader.app",os.path.basename(appPath)) | |
if destModified != '': | |
return destModified | |
else: | |
return dest | |
def getSourceAndDestination(plistEntry): | |
pkgId = plistEntry["TargetPackageId"] | |
relativePath = plistEntry["RelativePath"] | |
langId = plistEntry["LangId"] | |
if langId != '' and langId is not None: | |
src = os.path.join(os.path.join(os.path.join(patchStore,langId),plistEntry["StagingRootDir"]),relativePath) | |
else: #if no langId then use the en_US directory from patchStore | |
src = os.path.join(os.path.join(os.path.join(patchStore,"en_US"),plistEntry["StagingRootDir"]),relativePath) | |
dest = os.path.join(installLocFromPkgId(pkgId),relativePath) | |
dest = replaceWithRenamedApplication(src,dest) | |
return (src,dest) | |
def verifyConditionForChangeAttributes(dest,isDir): | |
''' | |
file should exist for changing attributes | |
''' | |
if isDir == 0: | |
if os.path.islink(dest): | |
return | |
elif os.path.isfile(dest): | |
return | |
else: | |
if os.path.isdir(dest): | |
return | |
log(("ERROR: The path %s is invalid, for attributes change operation.") %(dest)) | |
raise Exception("PathAbsentForAttributesChange",dest) | |
def verifyConditionForRemove(): | |
return | |
def verifyConditionForOverwrite(dest,isDir): | |
''' | |
for overwriting a directory file with same name should not exist and vice versa | |
''' | |
if isDir == 0: | |
if os.path.isdir(dest): | |
log(("ERROR: The path %s is a directory which is supposed to be a file.") %(dest)) | |
raise Exception("GenericError") | |
else: | |
if os.path.isfile(dest) or os.path.islink(dest): | |
log(("ERROR: The path %s is a file which is supposed to be a directory.") %(dest)) | |
raise Exception("GenericError") | |
def verifyConditionForAdd(dest,isDir): | |
verifyConditionForOverwrite(dest,isDir) | |
def validatePreCondition(plistEntry): | |
''' | |
check for necessary condition before executing the tasks | |
''' | |
taskType = plistEntry["TaskType"] | |
isDir = plistEntry["IsDirectory"] | |
(src,dest) = getSourceAndDestination(plistEntry) | |
if taskType == 'ChangeAttributes': | |
verifyConditionForChangeAttributes(dest,isDir) | |
elif taskType == 'Remove': | |
verifyConditionForRemove() | |
elif taskType == 'Overwrite': | |
verifyConditionForOverwrite(dest,isDir) | |
elif taskType == 'Add': | |
verifyConditionForAdd(dest,isDir) | |
else: | |
log(("ERROR: %s:Invalid task type obtained.") %(taskType)) | |
raise Exception ("GenericError") | |
def checkEncodedURLForBrowserPlugin(pdfViewer,plugin): | |
''' | |
upgrade only if pdfviewer.plist has the selected application path and plugin exists | |
''' | |
log("Info: Checking for browser plugin.") | |
if os.path.isdir(plugin) == False: | |
log(("Info: The plugin %s does not exist.") %(plugin)) | |
return False | |
if os.path.isfile(pdfViewer+".plist"): | |
cmd = '/usr/bin/defaults read ' + '"' + pdfViewer + '"' + ' WebBrowserUsePath' | |
(output,error,returncode) = runCmd(cmd, False) | |
if returncode == 0 and output != '': | |
urlOfApppath = output.rstrip('\n') | |
urlOfApppath = urllib.unquote(urlOfApppath) | |
if urlOfApppath.find("file://localhost") == -1: | |
log(("ERROR: Cannot find the string file://localhost in encoded url.")) | |
raise Exception("GenericError") | |
else: | |
urlOfApppath = urlOfApppath.split("file://localhost")[1] | |
else: | |
log(("ERROR: Unable to read WebBrowserUsePath from file: %s.") %(pdfViewer)) | |
return False | |
urlOfApppath = unicode(urlOfApppath, sys.getfilesystemencoding()) | |
log(("Info: The path obtained from %s is %s.") %(pdfViewer, urlOfApppath)) | |
if urlOfApppath == appPath+"/": | |
return True | |
else: | |
return False | |
else: | |
log(("Info: The file %s does not exist.") %(pdfViewer+".plist")) | |
return False | |
def checkMajorVersion(path): | |
log(("Info: checking if major version is 10 in %s") %(path)) | |
if os.path.isdir(path) == False: | |
log(("Info: Path %s not found.") %(path)) | |
return False | |
infoPlist = os.path.join(os.path.join(path,"Contents"),"Info") | |
if os.path.isfile(infoPlist+".plist") == False: | |
log(("Info: The file %s does not exist.") %(infoPlist+".plist")) | |
return False | |
else: | |
cmd = '/usr/bin/defaults read ' + '"' + infoPlist + '"' + ' CFBundleVersion' | |
(output,error,returncode) = runCmd(cmd,True) | |
if returncode != 0 or output == '': | |
log(("ERROR: Encountered failure in reading %s.") %(infoPlist+".plist")) | |
raise Exception("GenericError") | |
if output.rstrip('\n').split(".")[0] == "10": | |
return True | |
else: | |
return False | |
def taskApplicable(plistEntry,shouldUpdateBrowserplugin,shouldUpdatePrintAutomator,shouldUpdatePrintPDFServices): | |
''' | |
perform task only if it is applicable | |
''' | |
pkgId = plistEntry["TargetPackageId"] | |
if pkgId == "com.adobe.acrobat.10.viewer.print_automator.pkg": | |
return shouldUpdatePrintAutomator | |
elif pkgId == "com.adobe.acrobat.10.viewer.print_pdf_services.pkg": | |
return shouldUpdatePrintPDFServices | |
elif pkgId == "com.adobe.acrobat.10.viewer.browser.pkg" or pkgId == "com.adobe.acrobat.reader.10.reader.browser.pkg": | |
return shouldUpdateBrowserplugin | |
else: | |
return True | |
def checkLanguage(plistEntry,langObtained): | |
''' | |
check if language is valid | |
''' | |
langId = plistEntry["LangId"] | |
if langId != '' and langId is not None: | |
if langObtained == langId: | |
return True | |
else: | |
return False | |
else: | |
return True | |
def assignAttributes(dest,plistEntry): | |
''' | |
path is invalid if there is no file, directory or link with that name | |
''' | |
if os.path.isfile(dest) == False and os.path.isdir(dest) == False and os.path.islink(dest) == False: | |
log(("ERROR: The path %s does not exist for changing the attributes.") %(dest)) | |
raise Exception("PathAbsentForAttributesChange",dest) | |
owner = plistEntry["FileAttributes"]["NSFileOwnerAccountName"] | |
group = plistEntry["FileAttributes"]["NSFileGroupOwnerAccountName"] | |
perms = plistEntry["FileAttributes"]["NSFilePosixPermissions"] | |
perms = ("%o") %(perms) | |
cmd = '/usr/sbin/chown -h ' + '"' + owner + '"' + ':' + '"' + group + '"' + ' ' + '"' + dest + '"' | |
(out,err,returncode) = runCmd(cmd, True) | |
if returncode != 0: | |
log(("ERROR: This command failed: %s.") %(cmd)) | |
log(("ERROR: The ChangeAttributes operation could not be completed for %s.") %(dest)) | |
raise Exception("ChangeOwnershipFailed",dest) | |
cmd = '/bin/chmod -h ' + str(perms) + ' ' + '"' + dest + '"' | |
(out,err,returncode) = runCmd(cmd, True) | |
if returncode != 0: | |
log(("ERROR: This command failed: %s.") %(cmd)) | |
log(("ERROR: The ChangeAttributes operation could not be completed for %s.") %(dest)) | |
raise Exception("ChangePermissionFailed",dest) | |
def overwriteFile(src,dest,isDir): | |
if isDir == 0: | |
if os.path.islink(src): | |
cmd = '/bin/cp -fR ' + '"' + src + '"' + ' ' + '"' + dest + '"' | |
(out,err,returncode) = runCmd(cmd, True) | |
if returncode != 0: | |
log(("ERROR: This command failed: %s.") %(cmd)) | |
log(("ERROR: The Overwrite operation could not be completed for %s.") %(dest)) | |
raise Exception("OverwriteFileFailed",dest) | |
elif os.path.isfile(src): | |
cmd = '/usr/bin/ditto --rsrc ' + '"' + src + '"' + ' ' + '"' + dest + '"' | |
(out,err,returncode) = runCmd(cmd, True) | |
if returncode != 0: | |
log(("ERROR: This command failed: %s.") %(cmd)) | |
raise Exception("OverwriteFileFailed",dest) | |
else: | |
log(("ERROR: The source file %s does not exist.") %(src)) | |
log(("ERROR: The Overwrite operation could not be completed for %s.") %(dest)) | |
raise Exception("OverwriteFileFailed",dest) | |
else: | |
if os.path.isdir(dest) == False: | |
cmd = '/bin/mkdir -p ' + '"' + dest + '"' | |
(out,err,returncode) = runCmd(cmd, True) | |
if returncode != 0: | |
log(("ERROR: This command failed: %s.") %(cmd)) | |
log(("ERROR: The Overwrite operation could not be completed for %s.") %(dest)) | |
raise Exception("OverwriteFileFailed",dest) | |
def removeFile(dest,isDir): | |
if isDir == 0: | |
if os.path.isfile(dest) or os.path.islink(dest): | |
cmd = '/bin/rm -f ' + '"' + dest + '"' | |
(out,err,returncode) = runCmd(cmd, True) | |
if returncode != 0: | |
log(("ERROR: This command failed: %s.") %(cmd)) | |
log(("ERROR: The Remove operation could not be completed for %s.") %(dest)) | |
raise Exception("RemovePathFailed",dest) | |
else: | |
if os.path.isdir(dest): | |
if len(os.listdir(dest)) > 0: | |
log(("Info: The directory %s is not empty.") %(dest)) | |
return | |
else: | |
cmd = '/bin/rmdir ' + '"' + dest + '"' | |
(out,err,returncode) = runCmd(cmd, True) | |
if returncode != 0: | |
log(("ERROR: This command failed: %s.") %(cmd)) | |
log(("ERROR: The Remove operation could not be completed for %s.") %(dest)) | |
raise Exception("RemovePathFailed",dest) | |
def addFile(src,dest,isDir): | |
overwriteFile(src,dest,isDir) | |
def doOperation(plistEntry): | |
taskType = plistEntry["TaskType"] | |
isDir = plistEntry["IsDirectory"] | |
(src,dest) = getSourceAndDestination(plistEntry) | |
if taskType == 'Overwrite': | |
overwriteFile(src,dest,isDir) | |
assignAttributes(dest,plistEntry) | |
elif taskType == 'Remove': | |
err = removeFile(dest,isDir) | |
elif taskType == 'ChangeAttributes': | |
assignAttributes(dest,plistEntry) | |
elif taskType == 'Add': | |
addFile(src,dest,isDir) | |
assignAttributes(dest,plistEntry) | |
else: | |
log(("ERROR: Invalid task type obtained [%s].") %(taskType)) | |
raise Exception("GenericError") | |
def getAttributesOfPath(dest): | |
stat_info = os.lstat(dest) | |
userObtained = stat_info.st_uid | |
groupObtained = stat_info.st_gid | |
permsObtained = stat.S_IMODE(stat_info.st_mode) | |
permsObtained = ("%o") %(permsObtained) | |
return (userObtained,groupObtained,permsObtained) | |
def checkAttributes(dest,plistEntry): | |
owner = plistEntry["FileAttributes"]["NSFileOwnerAccountName"] | |
group = plistEntry["FileAttributes"]["NSFileGroupOwnerAccountName"] | |
perms = plistEntry["FileAttributes"]["NSFilePosixPermissions"] | |
perms = ("%o") %(perms) | |
(ownerObtained,groupObtained,permsObtained) = getAttributesOfPath(dest) | |
ownerID = pwd.getpwnam(owner)[2] | |
groupID = grp.getgrnam(group)[2] | |
if ownerID != ownerObtained: | |
log(("ERROR: The attributes verification failed for user id for %s. Required userId = %d. Obtained userId = %d.") %(dest,ownerID,ownerObtained)) | |
raise Exception("FailedAttributesCheck",dest) | |
if groupID != groupObtained: | |
log(("ERROR: The attributes verification failed for group id for %s. Required groupId = %d. Obtained groupId = %d.") %(dest,groupID,groupObtained)) | |
raise Exception("FailedAttributesCheck",dest) | |
if perms != permsObtained: | |
log(("ERROR: The attributes verification failed for permissions for %s. Required permissions = %d. Obtained permissions = %d.") %(dest,perms,permsObtained)) | |
raise Exception("FailedAttributesCheck",dest) | |
def verifyChecksum(dest,plistEntry): | |
cmd = '/usr/bin/cksum ' + ' "' + dest + '\"' | |
(output,error,returncode) = runCmd(cmd, False) | |
if returncode == 0 and output != '': | |
checksumObtained = output.rstrip('\n').split(' ')[0] | |
else: | |
log(("ERROR: This call failed: %s") %(cmd)) | |
raise Exception("FailedChecksumMatch",dest) | |
checksum = plistEntry["ChecksumAfter"] | |
if checksum != int(checksumObtained): | |
log(("ERROR: The checksum verification failed. Required checksum = %d. Obtained checksum = %d.") %(checksum, int(checksumObtained))) | |
raise Exception("FailedChecksumMatch",dest) | |
def checkFileExists(src,dest,plistEntry,isDir): | |
if isDir == 0: | |
if os.path.islink(dest) == False and os.path.islink(src): | |
log(("ERROR: The link %s does not exist.") %(dest)) | |
raise Exception("OverwriteFileFailed",dest) | |
elif os.path.isfile(dest) == False and os.path.isfile(src): | |
log(("ERROR: The file %s does not exist.") %(dest)) | |
raise Exception("OverwriteFileFailed",dest) | |
checkAttributes(dest,plistEntry) | |
if os.path.isfile(dest) and os.path.islink(dest) == False: #validate checksum if the path is a genuine file and not a link | |
verifyChecksum(dest,plistEntry) | |
else: | |
if os.path.isdir(dest) == False: | |
log(("ERROR: The directory %s does not exist.") %(dest)) | |
raise Exception("OverwriteFileFailed",dest) | |
def checkFileRemoved(dest,isDir): | |
if isDir == 0: | |
if os.path.islink(dest): | |
log(("ERROR: The link %s is not removed.") %(dest)) | |
raise Exception("RemovePathFailed",dest) | |
if os.path.isfile(dest): | |
log(("ERROR: The file %s is not removed.") %(dest)) | |
raise Exception("RemovePathFailed",dest) | |
def validatePostCondition(plistEntry): | |
taskType = plistEntry["TaskType"] | |
isDir = plistEntry["IsDirectory"] | |
(src,dest) = getSourceAndDestination(plistEntry) | |
if taskType == 'Overwrite': | |
checkFileExists(src,dest,plistEntry,isDir) | |
elif taskType == 'Remove': | |
checkFileRemoved(dest,isDir) | |
elif taskType == 'ChangeAttributes': | |
checkAttributes(dest,plistEntry) | |
elif taskType == 'Add': | |
checkFileExists(src,dest,plistEntry,isDir) | |
else: | |
log(("ERROR: Invalid task type obtained [%s].") %(taskType)) | |
raise Exception("GenericError") | |
def printTaskDetails(plistEntry): | |
''' | |
executed in case of error to print details of task which failed | |
''' | |
log("Info: The details of the failed task are") | |
log((" TaskType = %s") %(plistEntry["TaskType"])) | |
log((" StagingRootDir = %s") %(plistEntry["StagingRootDir"])) | |
log((" RelativePath = %s") %(plistEntry["RelativePath"])) | |
log((" IsDirectory = %s") %(plistEntry["IsDirectory"])) | |
log((" TargetPackageId = %s") %(plistEntry["TargetPackageId"])) | |
log((" LangId = %s") %(plistEntry["LangId"])) | |
log((" ChecksumBefore = %s") %(plistEntry["ChecksumBefore"])) | |
log((" ChecksumAfter = %s") %(plistEntry["ChecksumAfter"])) | |
if plistEntry["TaskType"] != "Remove": | |
log((" NSFileOwnerAccountName = %s") %(plistEntry["FileAttributes"]["NSFileOwnerAccountName"])) | |
log((" NSFilePosixPermissions = %s") %(plistEntry["FileAttributes"]["NSFilePosixPermissions"])) | |
log((" NSFileGroupOwnerAccountName = %s") %(plistEntry["FileAttributes"]["NSFileGroupOwnerAccountName"])) | |
def checkAcroLocalePresent(): | |
log("Info: Getting installed application locale") | |
acroLocalePlist = os.path.join(os.path.join(appPath,"Contents"),"AcroLocale") | |
if os.path.isfile(acroLocalePlist+".plist") == False: | |
log(("ERROR: The file %s does not exist.") %(acroLocalePlist+".plist")) | |
raise Exception("GenericError") | |
cmd = '/usr/bin/defaults read ' + '"' + acroLocalePlist + '"' + ' AcroInstallLocaleID' | |
(output,error,returncode) = runCmd(cmd, True) | |
if returncode == 0 and output != '': | |
acroLocalLang = output.rstrip('\n').split(' ')[0] | |
log(("Info: The installed app language obtained [%s].") %(acroLocalLang)) | |
else: | |
log("ERROR: Unable to get the installed application locale") | |
raise Exception("GenericError") | |
return acroLocalLang | |
def prepareRollbackForChangeAttributes(dest,isDir,tasknum): | |
(ownerObtained,groupObtained,permsObtained) = getAttributesOfPath(dest) | |
rollbackDict = dict( #restore old attributes during rollback | |
task = "RollbackChangeAttributes", | |
path = dest, | |
owner = ownerObtained, | |
group = groupObtained, | |
permissions = permsObtained, | |
dir = isDir, | |
tasknumber = tasknum, | |
) | |
if enable_debug_logs == 1: | |
log((" Rollback dictionary: %d %s %s %s %s %s %d") %(rollbackDict["tasknumber"], rollbackDict["task"],rollbackDict["path"],rollbackDict["owner"],rollbackDict["group"],rollbackDict["permissions"],rollbackDict["dir"])) | |
rollbackTask.append(rollbackDict) | |
def prepareRollbackForRemove(dest,isDir,tasknum): | |
if os.path.lexists(dest): | |
(ownerObtained,groupObtained,permsObtained) = getAttributesOfPath(dest) | |
rollbackDict = dict( #if path existed before removal copy it in temporary location and put back during rollback | |
task = "RollbackOverwrite", | |
path = dest, | |
owner = ownerObtained, | |
group = groupObtained, | |
permissions = permsObtained, | |
dir = isDir, | |
tasknumber = tasknum, | |
) | |
if enable_debug_logs == 1: | |
log((" Rollback dictionary: %d %s %s %s %s %s %d") %(rollbackDict["tasknumber"], rollbackDict["task"],rollbackDict["path"],rollbackDict["owner"],rollbackDict["group"],rollbackDict["permissions"],rollbackDict["dir"])) | |
rollbackTask.append(rollbackDict) | |
rollbackPath = dest.lstrip('/') | |
if isDir == 0: | |
cmd = '/bin/mkdir -p ' + '"' + os.path.dirname(os.path.join(rollbackStore,rollbackPath)) + '"' | |
(out,err,returncode) = runCmd(cmd, True) | |
if returncode != 0: | |
log(("ERROR : The rollback preparation command %s failed.") %(cmd)) | |
raise Exception("GenericError") | |
if os.path.islink(dest): | |
cmd = '/bin/cp -fR ' + '"' + dest + '"' + ' ' + '"' + os.path.join(rollbackStore,rollbackPath) + '"' | |
else: | |
cmd = '/usr/bin/ditto -rsrc ' + '"' + dest + '"' + ' ' + '"' + os.path.join(rollbackStore,rollbackPath) + '"' | |
(out,err,returncode) = runCmd(cmd, True) | |
if returncode != 0: | |
log(("ERROR : The rollback preparation command %s failed.") %(cmd)) | |
raise Exception("GenericError") | |
#no need for backup in case of directory since we have the directory name and attributes | |
else: | |
return | |
def prepareRollbackForOverwrite(dest,isDir,tasknum): | |
if os.path.lexists(dest): | |
(ownerObtained,groupObtained,permsObtained) = getAttributesOfPath(dest) | |
rollbackDict = dict( #copy path in temporary location and put back during overwrite if path existed before overwriting | |
task = "RollbackOverwrite", | |
path = dest, | |
owner = ownerObtained, | |
group = groupObtained, | |
permissions = permsObtained, | |
dir = isDir, | |
tasknumber = tasknum, | |
) | |
if enable_debug_logs == 1: | |
log((" Rollback dictionary: %d %s %s %s %s %s %d") %(rollbackDict["tasknumber"], rollbackDict["task"],rollbackDict["path"],rollbackDict["owner"],rollbackDict["group"],rollbackDict["permissions"],rollbackDict["dir"])) | |
rollbackTask.append(rollbackDict) | |
rollbackPath = dest.lstrip('/') | |
if isDir == 0: | |
cmd = '/bin/mkdir -p ' + '"' + os.path.dirname(os.path.join(rollbackStore,rollbackPath)) + '"' | |
(out,err,returncode) = runCmd(cmd, True) | |
if returncode != 0: | |
log(("ERROR : The rollback preparation command %s failed.") %(cmd)) | |
raise Exception("GenericError") | |
if os.path.islink(dest): | |
cmd = '/bin/cp -fR ' + '"' + dest + '"' + ' ' + '"' + os.path.join(rollbackStore,rollbackPath) + '"' | |
else: | |
cmd = '/usr/bin/ditto -rsrc ' + '"' + dest + '"' + ' ' + '"' + os.path.join(rollbackStore,rollbackPath) + '"' | |
(out,err,returncode) = runCmd(cmd, True) | |
if returncode != 0: | |
log(("ERROR : The rollback preparation command %s failed.") %(cmd)) | |
raise Exception("GenericError") | |
else: | |
rollbackDict = dict( #if path did not exist then remove it during rollback | |
task = "RollbackRemove", | |
path = dest, | |
owner = '', | |
group = '', | |
permissions = '', | |
dir = isDir, | |
tasknumber = tasknum, | |
) | |
if enable_debug_logs == 1: | |
log((" Rollback dictionary: %d %s %s %s %s %s %d") %(rollbackDict["tasknumber"], rollbackDict["task"],rollbackDict["path"],rollbackDict["owner"],rollbackDict["group"],rollbackDict["permissions"],rollbackDict["dir"])) | |
rollbackTask.append(rollbackDict) | |
def prepareRollbackForAdd(dest,isDir,tasknum): | |
prepareRollbackForOverwrite(dest,isDir,tasknum) | |
def prepareForRollback(plistEntry,tasknum): | |
taskType = plistEntry["TaskType"] | |
isDir = plistEntry["IsDirectory"] | |
(src,dest) = getSourceAndDestination(plistEntry) | |
if taskType == 'Overwrite': | |
prepareRollbackForOverwrite(dest,isDir,tasknum) | |
elif taskType == 'Remove': | |
prepareRollbackForRemove(dest,isDir,tasknum) | |
elif taskType == 'ChangeAttributes': | |
prepareRollbackForChangeAttributes(dest,isDir,tasknum) | |
elif taskType == 'Add': | |
prepareRollbackForAdd(dest,isDir,tasknum) | |
else: | |
log(("ERROR: Invalid task type obtained [%s].") %(taskType)) | |
raise Exception ("GenericError") | |
def validatePlistFile(plist): | |
if plist is None: | |
log(("ERROR: The plist is obtained as None.")) | |
raise Exception("GenericError") | |
i=0 | |
for entry in plist: | |
if 'TaskType' not in entry: | |
log(("ERROR: The key TaskType is missing in node %d.") %(i)) | |
raise Exception("GenericError") | |
if entry['TaskType'] == '': | |
log(("ERROR: The value for key Tasktype is null in node %d.") %(i)) | |
raise Exception("GenericError") | |
if 'StagingRootDir' not in entry: | |
log(("ERROR: The key StagingRootDir is missing in node %d.") %(i)) | |
raise Exception("GenericError") | |
if entry['StagingRootDir'] == '': | |
log(("ERROR: The value for key StagingRootDir is null in node %d.") %(i)) | |
raise Exception("GenericError") | |
if 'RelativePath' not in entry: | |
log(("ERROR: The key RelativePath is missing in node %d.") %(i)) | |
raise Exception("GenericError") | |
if entry['RelativePath'] == '': | |
log(("ERROR: The value for key RelativePath is null in node %d.") %(i)) | |
raise Exception("GenericError") | |
if 'IsDirectory' not in entry: | |
log(("ERROR: The key IsDirectory is missing in node %d.") %(i)) | |
raise Exception("GenericError") | |
if entry['IsDirectory'] != 0 and entry['IsDirectory'] != 1: | |
log(("ERROR: The value for key IsDirectory is neither 0 nor 1 in node %d.") %(i)) | |
raise Exception("GenericError") | |
if 'TargetPackageId' not in entry: | |
log(("ERROR: The key TargetPackageId is missing in node %d.") %(i)) | |
raise Exception("GenericError") | |
if entry['TargetPackageId'] == '': | |
log(("ERROR: The value for key TargetPackageId is null in node %d.") %(i)) | |
raise Exception("GenericError") | |
if 'LangId' not in entry: | |
log(("ERROR: The key LangId is missing in node %d.") %(i)) | |
raise Exception("GenericError") | |
if 'ChecksumBefore' not in entry: | |
log(("ERROR: The key ChecksumBefore is missing in node %d.") %(i)) | |
raise Exception("GenericError") | |
if 'ChecksumAfter' not in entry: | |
log(("ERROR: The key ChecksumAfter is missing in node %d.") %(i)) | |
raise Exception("GenericError") | |
if entry['TaskType'] != 'Remove': | |
if 'FileAttributes' not in entry: | |
log(("ERROR: The key FileAttributes is missing in node %d.") %(i)) | |
raise Exception("GenericError") | |
else: | |
if 'NSFileOwnerAccountName' not in entry['FileAttributes']: | |
log(("ERROR: The key NSFileOwnerAccountName is missing in FileAttributes in node %d.") %(i)) | |
raise Exception("GenericError") | |
if entry['FileAttributes']['NSFileOwnerAccountName'] == '': | |
log(("ERROR: The value for key NSFileOwnerAccountName is null in node %d.") %(i)) | |
raise Exception("GenericError") | |
if 'NSFilePosixPermissions' not in entry['FileAttributes']: | |
log(("ERROR: The key NSFilePosixPermissions is missing in FileAttributes in node %d.") %(i)) | |
raise Exception("GenericError") | |
if 'NSFileGroupOwnerAccountName' not in entry['FileAttributes']: | |
log(("ERROR: The key NSFileGroupOwnerAccountName is missing in FileAttributes in node %d.") %(i)) | |
raise Exception("GenericError") | |
if entry['FileAttributes']['NSFileGroupOwnerAccountName'] == '': | |
log(("ERROR: The key NSFileGroupOwnerAccountName is missing in FileAttributes in node %d.") %(i)) | |
raise Exception("GenericError") | |
i = i + 1 | |
log(("Info: Task plist file validation successful, file path: %s") %(taskPlist)) | |
def doRollbackForRollbackTaskOverwrite(rollbackEntry): | |
''' | |
copy path stored in temporary area to original path | |
''' | |
dest = rollbackEntry["path"] | |
src = os.path.join(rollbackStore,dest.lstrip('/')) | |
isDir = rollbackEntry["dir"] | |
tasknum = rollbackEntry["tasknumber"] | |
shouldChangeAttributes = False | |
if isDir == 0: | |
if os.path.islink(src): | |
cmd = '/bin/cp -fR ' + '"' + src + '"' + ' ' + '"' + dest + '"' | |
shouldChangeAttributes = True | |
else: | |
cmd = '/usr/bin/ditto -rsrc ' + '"' + src + '"' + ' ' + '"' + dest + '"' | |
else: | |
cmd = '/bin/mkdir -p ' + '"' + dest + '"' | |
shouldChangeAttributes = True | |
(out,err,returncode) = runCmd(cmd, True) | |
if returncode != 0: | |
log(cmd) | |
log(("ERROR: Rollback failed for task %d.") %(tasknum)) | |
if err != '': | |
log(err) | |
return False | |
if shouldChangeAttributes == True: | |
return doRollbackForRollbackTaskChangeAttributes(rollbackEntry) | |
else: | |
return True | |
def doRollbackForRollbackTaskRemove(rollbackEntry): | |
''' | |
delete path during rollback | |
''' | |
dest = rollbackEntry["path"] | |
tasknum = rollbackEntry["tasknumber"] | |
if os.path.lexists(dest) == False: | |
return True | |
cmd = '/bin/rm -rf ' + '"' + dest + '"' | |
(out,err,returncode) = runCmd(cmd, True) | |
if returncode != 0: | |
log(cmd) | |
log(("ERROR: Rollback failed for task %d.") %(tasknum)) | |
if err != '': | |
log(err) | |
return False | |
return True | |
def doRollbackForRollbackTaskChangeAttributes(rollbackEntry): | |
''' | |
restore old attributes during rollback | |
''' | |
dest = rollbackEntry["path"] | |
owner = rollbackEntry["owner"] | |
group = rollbackEntry["group"] | |
perms = rollbackEntry["permissions"] | |
tasknum = rollbackEntry["tasknumber"] | |
cmd = '/usr/sbin/chown -h ' + '"' + str(owner) + '"' + ':' + '"' + str(group) + '"' + ' ' + '"' + dest + '"' | |
(out,err,returncode) = runCmd(cmd, True) | |
if returncode: | |
log(cmd) | |
log(("ERROR: Rollback failed for task %d.") %(tasknum)) | |
if err != '': | |
log(err) | |
return False | |
cmd = '/bin/chmod -h ' + str(perms) + ' ' + '"' + dest + '"' | |
(out,err,returncode) = runCmd(cmd, True) | |
if returncode != 0: | |
log(cmd) | |
log(("ERROR: Rollback failed for task %d.") %(tasknum)) | |
if err != '': | |
log(err) | |
return False | |
return True | |
def doRollback(rollbackEntry): | |
rolledBack = True | |
task = rollbackEntry["task"] | |
if task == 'RollbackOverwrite': | |
rolledBack = doRollbackForRollbackTaskOverwrite(rollbackEntry) | |
elif task == 'RollbackRemove': | |
rolledBack = doRollbackForRollbackTaskRemove(rollbackEntry) | |
elif task == 'RollbackChangeAttributes': | |
rolledBack = doRollbackForRollbackTaskChangeAttributes(rollbackEntry) | |
return rolledBack | |
def printInvalidTasksNumbers(invalidTasks): | |
if len(invalidTasks) > 0: | |
prev = invalidTasks[0] | |
curr = invalidTasks[0] | |
i = 1 | |
while i < len(invalidTasks): | |
if invalidTasks[i] != curr + 1: | |
if prev != curr: | |
log(("Info: Tasks %d to %d are not applicable.") %(prev,curr)) | |
else: | |
log(("Info: Task %d is not applicable.") %(prev)) | |
prev = invalidTasks[i] | |
curr = invalidTasks[i] | |
else: | |
curr = invalidTasks[i] | |
i = i + 1 | |
if prev != curr: | |
log(("Info: Tasks %d to %d are not applicable.") %(prev,curr)) | |
else: | |
log(("Info: Task %d is not applicable.") %(curr)) | |
def killAdobeResourceSynchronizer(): | |
cmd = '/bin/ps -x -c -A | grep ' + 'AdobeResourceSynchronizer' | |
(output,error,returncode) = runCmd(cmd, True) | |
if output != '': | |
log("Info: AdobeResourceSynchronizer is running, trying to kill.") | |
appsToKill = output.split('\n') | |
for app in appsToKill: | |
parts = app.split() | |
if parts != []: | |
cmd = 'kill -s 15 ' + parts[0] | |
(output,error,returncode) = runCmd(cmd, True) | |
if returncode != 0: | |
log("Unable to kill AdobeResourceSynchronizer.") | |
if error != '': | |
log(error) | |
def printStacktrace(traceback): | |
funcnames = traceback.split('\n') | |
for func in funcnames: | |
log(func) | |
def doInitialProcessing(plist): | |
langObtained = checkAcroLocalePresent() | |
validatePlistFile(plist) | |
shouldUpdateBrowserplugin = False | |
shouldUpdatePrintAutomator = False | |
shouldUpdatePrintPDFServices = False | |
isBrowserPluginPrefOK = checkEncodedURLForBrowserPlugin("/Library/Preferences/com.adobe.acrobat.pdfviewer","/Library/Internet Plug-Ins/AdobePDFViewer.plugin") | |
isBrowserPluginVerOK = checkMajorVersion("/Library/Internet Plug-Ins/AdobePDFViewer.plugin") | |
shouldUpdateBrowserplugin = isBrowserPluginPrefOK and isBrowserPluginVerOK | |
if title == "TitleAcrobat": | |
shouldUpdatePrintAutomator = checkMajorVersion("/Library/Automator/Save as Adobe PDF.action") | |
shouldUpdatePrintPDFServices = checkMajorVersion("/Library/PDF Services/Save as Adobe PDF.app") | |
if shouldUpdateBrowserplugin == True: | |
log("Info: Browser Plugin should be updated.") | |
else: | |
log("Info: Skip updating Browser Plugin.") | |
if shouldUpdatePrintAutomator == True: | |
log("Info: Print Automator should be updated.") | |
else: | |
log("Info: Skip updating Print Automator.") | |
if shouldUpdatePrintPDFServices == True: | |
log("Info: Print PDF Service should be updated.") | |
else: | |
log("Info: Skip updating Print PDF Service.") | |
return (langObtained,shouldUpdateBrowserplugin,shouldUpdatePrintAutomator,shouldUpdatePrintPDFServices) | |
def restoreSignatureForPlugin(browserPlugin): | |
isBrowserPluginVerOK = checkMajorVersion(browserPlugin) | |
log("Info: Performing signature validation for Browser Plugin.") | |
if isBrowserPluginVerOK != True: | |
log("Info: Browser Plugin version not matched, skipping action.") | |
return True | |
cmd = '/usr/bin/codesign -v ' + '"' + browserPlugin + '"' | |
(output,error,returncode) = runCmd(cmd,True) | |
if returncode != 0 and re.search('invalid', error): | |
log(("Info: Signature seems broken for Browser plugin [%s].") %(browserPlugin)) | |
log("Info: Try to restore the signature of the bundle.") | |
pluginResourcePath=browserPlugin+'/Contents/Resources' | |
for dirItem in os.listdir(pluginResourcePath): | |
resourceDirToProcess=pluginResourcePath + "/" + dirItem | |
log(("Info: Checking resource folder [%s].") %(resourceDirToProcess)) | |
if os.path.isdir(resourceDirToProcess) and not os.path.islink(resourceDirToProcess) and re.search('\.lproj$',resourceDirToProcess): | |
log(("Info: Processing resource folder [%s].") %(resourceDirToProcess)) | |
removeOldStyleStringFileInFolder(resourceDirToProcess, "InfoPlist.strings", "Localizable.strings") | |
else: | |
log("Info: Signature is Valid.") | |
return True | |
def removeOldStyleStringFileInFolder(resourceDirToProcess, fileToCheckAndDelete, fileToCheckOnly): | |
filePathToCheckAndDelete =resourceDirToProcess+"/"+fileToCheckAndDelete | |
filePathToCheckOnly =resourceDirToProcess+"/"+fileToCheckOnly | |
if os.path.lexists(filePathToCheckAndDelete) and os.path.isfile(filePathToCheckAndDelete) and not os.path.islink(filePathToCheckAndDelete): | |
if os.path.lexists(filePathToCheckOnly) and os.path.isfile(filePathToCheckOnly) and not os.path.islink(filePathToCheckOnly): | |
log("Info: Both old and new style string resources present.") | |
log(("Info: Removing old style string resources [%s].") %(filePathToCheckAndDelete)) | |
if not os.remove(filePathToCheckAndDelete): | |
log("Info: Removed old style string resources.") | |
return True | |
else: | |
log("Info: Fail to removed old style string resources.") | |
return False | |
else: | |
log("Info: Only old style String resources present.") | |
else: | |
log("Info: Old style String resources not present.") | |
log("Info: No need to remove any string file.") | |
return False | |
def updatePDFSettingsPlist(): | |
acroPDFSettingsPlistFile = 'com.adobe.PDFAdminSettings.plist' | |
acroPDFSettingsPlistFilePath = '/Library/Preferences/com.adobe.PDFAdminSettings.plist' | |
installerAcroSettingsPlistFile = 'PDFAdminSettings.plist' | |
tmpPlistFile = 'com.adobe.PDFAdminSettingsTmp.plist' | |
finalPlistFile = 'com.adobe.PDFAdminSettingsFinal.plist' | |
installerAcroSettingsPlistFilePath = os.path.join( os.path.dirname(taskPlist), installerAcroSettingsPlistFile) | |
if os.path.lexists(installerAcroSettingsPlistFilePath): | |
log("Info: Processing PDFAdminSettings.plist file.") | |
else: | |
log("Info: Processing PDFAdminSettings.plist file is done only for Acrobat.") | |
log("Info: Skip Processing PDFAdminSettings.plist file.") | |
return False | |
if os.path.lexists(acroPDFSettingsPlistFilePath): | |
(ownerObtained,groupObtained,permsObtained) = getAttributesOfPath(acroPDFSettingsPlistFilePath) | |
else: | |
log(("ERROR: File not found %s.") %(acroPDFSettingsPlistFilePath)) | |
log(("ERROR: Skip updating File %s.") %(acroPDFSettingsPlistFilePath)) | |
return False | |
src = acroPDFSettingsPlistFilePath | |
dest = os.path.join(rollbackStore,acroPDFSettingsPlistFile) | |
addFile(src,dest,0) | |
tmpPlistFilePath = os.path.join(rollbackStore,tmpPlistFile) | |
addFile(dest,tmpPlistFilePath,0) | |
# Do processing on tmpPlistFilePath | |
finalPlistFilePath = os.path.join(rollbackStore,finalPlistFile) | |
if os.path.lexists(installerAcroSettingsPlistFilePath) and os.path.lexists(tmpPlistFilePath) : | |
installerAcroSettingPlist = plistlib.readPlist(installerAcroSettingsPlistFilePath) | |
# Convert the file format to xml before processing. | |
cmd = '/usr/bin/plutil -convert xml1 ' + '"' + tmpPlistFilePath + '"' | |
(out,err,returncode) = runCmd(cmd, True) | |
if returncode != 0: | |
log(cmd) | |
log("ERROR: plutil failed for PDFSettings plist file %s.") %(tmpPlistFilePath) | |
if err != '': | |
log(err) | |
return False | |
tmpPlist = plistlib.readPlist(tmpPlistFilePath) | |
isUpdated = False | |
if tmpPlist.get("PDFSettingsPath") is None: | |
tmpPlist["PDFSettingsPath"] = installerAcroSettingPlist["PDFSettingsPath"] | |
isUpdated = True | |
log("Info: Updating PDFSettingsPath.") | |
if tmpPlist.get("PDFSettings") is None: | |
tmpPlist["PDFSettings"] = installerAcroSettingPlist["PDFSettings"] | |
isUpdated = True | |
log("Info: Updating PDFSettings.") | |
if isUpdated == True: | |
plistlib.writePlist(tmpPlist, finalPlistFilePath) | |
else: | |
log(("ERROR: Unable to find installer AcroSettingsPlist File [%s] or [%s].") %(installAcroSettingsPlistFilePath, tmpPlistFilePath)) | |
log(("ERROR: Skip updating File %s.") %(acroPDFSettingsPlistFilePath)) | |
return False | |
# we get the final updated plist file in rollback store. | |
if isUpdated == True: | |
if os.path.lexists(finalPlistFilePath) : | |
log("Info: Intermediate file created successfully.") | |
overwriteFile(finalPlistFilePath, acroPDFSettingsPlistFilePath, 0) | |
else: | |
log(("ERROR: Unable to create updated AcroSettingsPlist File [%s].") %(finalPlistFilePath)) | |
log(("ERROR: Skip updating File %s.") %(acroPDFSettingsPlistFilePath)) | |
return False | |
log("Info: Updated PDFAdminSettings.plist file, Now setting the permissions.") | |
cmd = '/usr/sbin/chown -h ' + '"' + str(ownerObtained) + '"' + ':' + '"' + str(groupObtained) + '"' + ' ' + '"' + acroPDFSettingsPlistFilePath + '"' | |
(out,err,returncode) = runCmd(cmd, True) | |
if returncode != 0: | |
log(cmd) | |
log("ERROR: chown failed for PDFSettings plist file %s.") %(acroPDFSettingsPlistFilePath) | |
if err != '': | |
log(err) | |
return False | |
cmd = '/bin/chmod -h ' + str(permsObtained) + ' ' + '"' + acroPDFSettingsPlistFilePath + '"' | |
(out,err,returncode) = runCmd(cmd, True) | |
if returncode != 0: | |
log(cmd) | |
log(("ERROR: chmod failed for PDFSettings plist file %s.") %(acroPDFSettingsPlistFilePath)) | |
if err != '': | |
log(err) | |
return False | |
else: | |
log(("Info: File [%s] is already updated, skip updating file.") %(acroPDFSettingsPlistFilePath)) | |
log("Info: Done Processing PDFAdminSettings.plist file.") | |
return True | |
def beginScan(isPreinstall): | |
retval = 0 | |
plist = '' | |
sudoCmd = 'sudo ' | |
try: | |
if os.environ['USER'] != '': | |
sudoCmd = sudoCmd + '-u ' + os.environ['USER'] | |
except Exception, e: | |
sudoCmd = 'sudo ' | |
try: | |
plist = plistlib.readPlist(taskPlist) | |
(langObtained,shouldUpdateBrowserplugin,shouldUpdatePrintAutomator,shouldUpdatePrintPDFServices) = doInitialProcessing(plist) | |
except Exception, err: | |
log("EXCEPTION: Caught an exception during initial processing.") | |
printStacktrace(traceback.format_exc()) | |
retval = errorCodeDict["GenericError"] | |
if CLI_mode == "0": | |
cmdline = sudoCmd + ' ' + binaryPath + ' ShowTaskError ' + title + ' ' + 'GenericError' | |
try: | |
runCmd(cmdline, True) | |
except Exception, e: | |
log("ERROR: Fail to show UI alert.") | |
if e != '': | |
log(e) | |
return retval | |
if isPreinstall == True: | |
i = 0 | |
try: | |
invalidTasks = [] | |
log("Info: Pre-validating all the tasks.") | |
while i < len(plist): | |
if taskApplicable(plist[i], shouldUpdateBrowserplugin, shouldUpdatePrintAutomator,shouldUpdatePrintPDFServices) == True and checkLanguage(plist[i],langObtained) == True: | |
validatePreCondition(plist[i]) | |
else: | |
invalidTasks.append(i) | |
i = i + 1 | |
printInvalidTasksNumbers(invalidTasks) | |
log("Info: Pre-validation for all tasks successful.") | |
except Exception, err: | |
log(("EXCEPTION: Caught an exception while validating precondition for task %d.") %(i)) | |
failedTask = i | |
printStacktrace(traceback.format_exc()) | |
failureFilePath = '' | |
if not err.args[0] in errorCodeDict: | |
errorType = "GenericError" | |
else: | |
errorType = err.args[0] | |
if len(err.args) == 2: | |
failurefilepath = err.args[1] | |
log(("Info: Failure file path %s") %(failureFilePath)) | |
retval = errorCodeDict[errorType] | |
if CLI_mode == "0": | |
if failureFilePath != '': | |
cmdline = sudoCmd + ' ' + binaryPath + ' ShowTaskError ' + title + ' ' + errorType + ' ' + '"' + failureFilePath + '"' | |
else: | |
cmdline = sudoCmd + ' ' + binaryPath + ' ShowTaskError ' + title + ' ' + errorType | |
try: | |
runCmd(cmdline, True) | |
except Exception, e: | |
log("ERROR: Fail to show UI alert.") | |
if e != '': | |
log(e) | |
printTaskDetails(plist[failedTask]) | |
return retval | |
if isPreinstall == False: | |
i = 0 | |
validTasks = [] | |
try: | |
log("Info: Preparing for Rollback for all the valid tasks.") | |
while i < len(plist): | |
if taskApplicable(plist[i],shouldUpdateBrowserplugin,shouldUpdatePrintAutomator,shouldUpdatePrintPDFServices) == True and checkLanguage(plist[i],langObtained) == True: | |
validTasks.append(i) | |
prepareForRollback(plist[i],i) | |
i = i + 1 | |
log("Info: Rollback preparation successful.") | |
except Exception, err: | |
log(("EXCEPTION: Caught an exception while preparing for rollback for task %d.") %(i)) | |
failedTask = i | |
printStacktrace(traceback.format_exc()) | |
if CLI_mode == "0": | |
cmdline = sudoCmd + ' ' + binaryPath + ' ShowTaskError ' + title + ' ' + 'GenericError' | |
retval = errorCodeDict["GenericError"] | |
try: | |
runCmd(cmdline, True) | |
except Exception, e: | |
log("ERROR: Fail to show UI alert.") | |
if e != '': | |
log(e) | |
printTaskDetails(plist[failedTask]) | |
return retval | |
try: | |
j = 0 | |
numberOfRollbacks = 0 | |
log("Info: Executing all valid tasks.") | |
while j < len(validTasks): | |
i = validTasks[j] | |
numberOfRollbacks = j | |
if (plist[i]['TaskType'] == 'Remove'): | |
log((" Executing task %d : %s : %s.") %(i, plist[i]["TaskType"], plist[i]["RelativePath"])) | |
else: | |
perms = plist[i]["FileAttributes"]["NSFilePosixPermissions"] | |
perms = ("%o") %(perms) | |
log((" Executing task %d : %s : %s : %s.") %(i, plist[i]["TaskType"], plist[i]["RelativePath"], perms)) | |
doOperation(plist[i]) | |
j = j + 1 | |
log("Info: Executed all valid tasks successfully.") | |
log("Info: Validating executed tasks.") | |
j = 0 | |
while j < len(validTasks): | |
i = validTasks[j] | |
validatePostCondition(plist[i]) | |
j = j + 1 | |
log("Info: Validated executed tasks successfully.") | |
except Exception, err: | |
log(("EXCEPTION: Caught an exception while executing task %d.") %(i)) | |
failedTask = i | |
printStacktrace(traceback.format_exc()) | |
i = numberOfRollbacks | |
fatalError = False | |
failureFilePath = '' | |
log(("Info: Performing rollback operation. The number of rollbacks to perform - %d.") %(numberOfRollbacks + 1)) | |
while i >= 0: | |
if (rollbackTask[i]['task'] == 'Remove'): | |
log((" Rolling back task %d : %s : %s.") %( rollbackTask[i]["tasknumber"], rollbackTask[i]["task"], rollbackTask[i]["path"])) | |
else: | |
log((" Rolling back task %d : %s : %s : %s.") %( rollbackTask[i]["tasknumber"], rollbackTask[i]["task"], rollbackTask[i]["path"], rollbackTask[i]["permissions"])) | |
didRollback = doRollback(rollbackTask[i]) | |
i = i - 1 | |
if didRollback == False: | |
fatalError = True | |
printTaskDetails(plist[rollbackTask[i]["tasknumber"]]) | |
if fatalError == False: | |
log("Info: Rollback operation successful. Application state is restored.") | |
# Rollback is successful, now do processing for failed task | |
if not err.args[0] in errorCodeDict: | |
errorType = "GenericError" | |
else: | |
errorType = err.args[0] | |
if len(err.args) == 2: | |
failureFilePath = err.args[1] | |
log(("Info: Failure file path %s") %(failureFilePath)) | |
retval = errorCodeDict[errorType] | |
if CLI_mode == "0": | |
if failureFilePath != '': | |
cmdline = sudoCmd + ' ' + binaryPath + ' ShowTaskError ' + title + ' ' + errorType + ' ' + '"' + failureFilePath + '"' | |
else: | |
cmdline = sudoCmd + ' ' + binaryPath + ' ShowTaskError ' + title + ' ' + errorType | |
try: | |
runCmd(cmdline, True) | |
except Exception, e: | |
log("ERROR: Fail to show the UI alert.") | |
if e != '': | |
log(e) | |
else: | |
log("ERROR: Rollback operation has failed. Application state might be corrupted.") | |
retval = errorCodeDict["RollbackError"] | |
if CLI_mode == "0": | |
cmdline = sudoCmd + ' ' + binaryPath + ' ShowTaskError ' + title + ' RollbackError ' | |
try: | |
runCmd(cmdline, True) | |
except Exception, e: | |
log("ERROR: Fail to show the UI alert.") | |
if e != '': | |
log(e) | |
printTaskDetails(plist[failedTask]) | |
return retval | |
updatePDFSettingsPlist() | |
# Fix for bug #2955103, try to restore signing of AdobePDFViewerPlugin, being broken by the old style String files. | |
restoreSignatureForPlugin("/Library/Internet Plug-Ins/AdobePDFViewer.plugin") | |
return retval | |
if __name__=='__main__': | |
global enable_debug_logs | |
enable_debug_logs = 0 | |
# For setting the LogLevel, run following command | |
# $ sudo defaults write "/Library/Application Support/Adobe/Acrobat/10.0/com.adobe.Acrobat.InstallerOverrides" AcroPatchLogLevel debug | |
log(" INFO: For creating debug logs, please run following command in terminal") | |
log(" $ sudo defaults write \"/Library/Application Support/Adobe/Acrobat/10.0/com.adobe.Acrobat.InstallerOverrides\" AcroPatchLogLevel debug") | |
# Get the LogLevel setting | |
defaults_cmd = '/usr/bin/defaults read \"/Library/Application Support/Adobe/Acrobat/10.0/com.adobe.Acrobat.InstallerOverrides" AcroPatchLogLevel' | |
(out,err,ret_code) = runCmd(defaults_cmd, True) | |
if( ret_code == 0): | |
out = out.strip() | |
out = out.upper() | |
if (out == 'DEBUG'): | |
enable_debug_logs = 1 | |
log('Info: Debug logs are enabled') | |
isPreinstall = sys.argv[1] | |
log(("Info: App. path is obtained as %s.") %(appPath)) | |
if isPreinstall == "1": | |
isPreinstall = True | |
killAdobeResourceSynchronizer() | |
else: | |
isPreinstall = False | |
retval = beginScan(isPreinstall) | |
sys.exit(retval) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment