def runAdobeCS5AAMEEInstall(dmgpath): '''Installs a CS5 product using an AAMEE-generated package on a disk image.''' munkicommon.display_status_minor( 'Mounting disk image %s' % os.path.basename(dmgpath)) mountpoints = mountAdobeDmg(dmgpath) if not mountpoints: munkicommon.display_error("No mountable filesystems on %s" % dmgpath) return -1 deploymentmanager = findAdobeDeploymentManager(mountpoints[0]) 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. # 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() # 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")) 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)) optionXMLfile = os.path.join(basepath, "optionXML.xml") if (not munkicommon.getconsoleuser() or munkicommon.getconsoleuser() == u"loginwindow"): # we're at the loginwindow, so we need to run the deployment # manager in the loginwindow context using launchctl bsexec loginwindowPID = utils.getPIDforProcessName("loginwindow") cmd = ['/bin/launchctl', 'bsexec', loginwindowPID] else: cmd = [] cmd.extend([deploymentmanager, '--optXMLPath=%s' % optionXMLfile, '--setupBasePath=%s' % tmpdir, '--installDirPath=/', '--mode=install']) munkicommon.display_status_minor('Starting Adobe CS5 installer...') retcode = runAdobeInstallTool(cmd, number_of_payloads, killAdobeAIR=True) # now clean up our symlink hackfest unused_result = subprocess.call(["/bin/rm", "-rf", tmpdir]) else: munkicommon.display_error( "%s doesn't appear to contain AdobeDeploymentManager" % os.path.basename(dmgpath)) retcode = -1 munkicommon.unmountdmg(mountpoints[0]) return retcode
def runAdobeInstallTool(cmd, number_of_payloads=0, killAdobeAIR=False): '''An abstraction of the tasks for running Adobe Setup, AdobeUberInstaller, AdobeUberUninstaller, AdobeDeploymentManager, etc''' if munkicommon.munkistatusoutput and not number_of_payloads: # indeterminate progress bar munkistatus.percent(-1) proc = subprocess.Popen(cmd, shell=False, bufsize=1, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) old_payload_completed_count = 0 payloadname = "" while (proc.poll() == None): time.sleep(1) (payload_completed_count, payloadname) = \ getAdobeInstallProgressInfo(old_payload_completed_count, payloadname) if payload_completed_count > old_payload_completed_count: old_payload_completed_count = payload_completed_count if payloadname: payloadinfo = " - " + payloadname else: payloadinfo = "" if number_of_payloads: munkicommon.display_status_minor( 'Completed payload %s of %s%s' % (payload_completed_count, number_of_payloads, payloadinfo)) else: munkicommon.display_status_minor('Completed payload %s%s' % (payload_completed_count, payloadinfo)) if munkicommon.munkistatusoutput: munkistatus.percent(getPercent(payload_completed_count, number_of_payloads)) # Adobe AIR Installer workaround/hack # CSx installs at the loginwindow hang when Adobe AIR is installed. # So we check for this and kill the process. Ugly. # Hopefully we can disable this in the future. if killAdobeAIR: if (not munkicommon.getconsoleuser() or munkicommon.getconsoleuser() == u"loginwindow"): # we're at the loginwindow. killStupidProcesses() # run of tool completed retcode = proc.poll() #check output for errors output = proc.stdout.readlines() for line in output: line = line.rstrip("\n") if line.startswith("Error"): munkicommon.display_error(line) if line.startswith("Exit Code:"): if retcode == 0: try: retcode = int(line[11:]) except (ValueError, TypeError): retcode = -1 if retcode != 0 and retcode != 8: munkicommon.display_error("Adobe Setup error: %s: %s" % (retcode, adobeSetupError(retcode))) else: if munkicommon.munkistatusoutput: munkistatus.percent(100) munkicommon.display_status_minor('Done.') return retcode