Example #1
0
def runAdobeSetup(dmgpath, uninstalling=False):
    '''Runs the Adobe setup tool in silent mode from
    an Adobe update DMG or an Adobe CS3 install DMG'''
    munkicommon.display_status_minor(
        'Mounting disk image %s' % os.path.basename(dmgpath))
    mountpoints = mountAdobeDmg(dmgpath)
    if mountpoints:
        setup_path = findSetupApp(mountpoints[0])
        if setup_path:
            # look for install.xml or uninstall.xml at root
            deploymentfile = None
            installxml = os.path.join(mountpoints[0], "install.xml")
            uninstallxml = os.path.join(mountpoints[0], "uninstall.xml")
            if uninstalling:
                if os.path.exists(uninstallxml):
                    deploymentfile = uninstallxml
                else:
                    # we've been asked to uninstall,
                    # but found no uninstall.xml
                    # so we need to bail
                    munkicommon.unmountdmg(mountpoints[0])
                    munkicommon.display_error(
                              "%s doesn't appear to contain uninstall info." %
                               os.path.basename(dmgpath))
                    return -1
            else:
                if os.path.exists(installxml):
                    deploymentfile = installxml

            # try to find and count the number of payloads
            # so we can give a rough progress indicator
            number_of_payloads = countPayloads(mountpoints[0])
            munkicommon.display_status_minor('Running Adobe Setup')
            adobe_setup = [ setup_path, '--mode=silent',
                            '--skipProcessCheck=1' ]
            if deploymentfile:
                adobe_setup.append('--deploymentFile=%s' % deploymentfile)

            retcode = runAdobeInstallTool(adobe_setup, number_of_payloads)

        else:
            munkicommon.display_error(
                '%s doesn\'t appear to contain Adobe Setup.' %
                 os.path.basename(dmgpath))
            retcode = -1

        munkicommon.unmountdmg(mountpoints[0])
        return retcode
    else:
        munkicommon.display_error('No mountable filesystems on %s' % dmgpath)
        return -1
Example #2
0
def runAdobeCS5PatchInstaller(dmgpath, copylocal=False):
    '''Runs the AdobePatchInstaller for CS5.
    Optionally can copy the DMG contents to the local disk
    to work around issues with the patcher.'''
    munkicommon.display_status_minor(
        'Mounting disk image %s' % os.path.basename(dmgpath))
    mountpoints = mountAdobeDmg(dmgpath)
    if mountpoints:
        if copylocal:
            # copy the update to the local disk before installing
            updatedir = tempfile.mkdtemp()
            retcode = subprocess.call(["/bin/cp", "-r",
                                            mountpoints[0], updatedir])
            # unmount diskimage
            munkicommon.unmountdmg(mountpoints[0])
            if retcode:
                munkicommon.display_error(
                                "Error copying items from %s" % dmgpath)
                return -1
            # remove the dmg file to free up space, since we don't need it
            # any longer
            unused_result = subprocess.call(["/bin/rm", dmgpath])
        else:
            updatedir = mountpoints[0]

        patchinstaller = findAdobePatchInstallerApp(updatedir)
        if patchinstaller:
            # try to find and count the number of payloads
            # so we can give a rough progress indicator
            number_of_payloads = countPayloads(updatedir)
            munkicommon.display_status_minor('Running Adobe Patch Installer')
            install_cmd = [ patchinstaller,
                            '--mode=silent',
                            '--skipProcessCheck=1' ]
            retcode = runAdobeInstallTool(install_cmd,
                                          number_of_payloads)
        else:
            munkicommon.display_error(
                    "%s doesn't appear to contain AdobePatchInstaller.app." %
                    os.path.basename(dmgpath))
            retcode = -1
        if copylocal:
            # clean up our mess
            unused_result = subprocess.call(["/bin/rm", "-rf", updatedir])
        else:
            munkicommon.unmountdmg(mountpoints[0])
        return retcode
    else:
        munkicommon.display_error("No mountable filesystems on %s" % dmgpath)
        return -1
Example #3
0
def runAdobeUberTool(dmgpath, pkgname='', uninstalling=False):
    '''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
    containing the AdobeUber tools and their XML files.'''

    munkicommon.display_status_minor(
        'Mounting disk image %s' % os.path.basename(dmgpath))
    mountpoints = mountAdobeDmg(dmgpath)
    if mountpoints:
        installroot = mountpoints[0]
        if uninstalling:
            ubertool = os.path.join(installroot, pkgname,
                                    "AdobeUberUninstaller")
        else:
            ubertool = os.path.join(installroot, pkgname,
                                    "AdobeUberInstaller")

        if os.path.exists(ubertool):
            info = getAdobePackageInfo(installroot)
            packagename = info['display_name']
            action = "Installing"
            if uninstalling:
                action = "Uninstalling"
            munkicommon.display_status_major('%s %s' % (action, packagename))
            if munkicommon.munkistatusoutput:
                munkistatus.detail('Starting %s' % os.path.basename(ubertool))

            # try to find and count the number of payloads
            # so we can give a rough progress indicator
            number_of_payloads = countPayloads(installroot)

            retcode = runAdobeInstallTool(
                [ubertool], number_of_payloads, killAdobeAIR=True)

        else:
            munkicommon.display_error("No %s found" % ubertool)
            retcode = -1

        munkicommon.unmountdmg(installroot)
        return retcode
    else:
        munkicommon.display_error("No mountable filesystems on %s" % dmgpath)
        return -1
Example #4
0
def updateAcrobatPro(dmgpath):
    """Uses the scripts and Resources inside the Acrobat Patch application
    bundle to silently update Acrobat Pro and related apps
    Why oh why does this use a different mechanism than the other Adobe
    apps?"""

    if munkicommon.munkistatusoutput:
        munkistatus.percent(-1)

    #first mount the dmg
    munkicommon.display_status_minor(
        'Mounting disk image %s' % os.path.basename(dmgpath))
    mountpoints = mountAdobeDmg(dmgpath)
    if mountpoints:
        installroot = mountpoints[0]
        pathToAcrobatPatchApp = findAcrobatPatchApp(installroot)
    else:
        munkicommon.display_error("No mountable filesystems on %s" % dmgpath)
        return -1

    if not pathToAcrobatPatchApp:
        munkicommon.display_error("No Acrobat Patch app at %s" %
                                   pathToAcrobatPatchApp)
        munkicommon.unmountdmg(installroot)
        return -1

    # some values needed by the patching script
    resourcesDir = os.path.join(pathToAcrobatPatchApp,
                                "Contents", "Resources")
    ApplyOperation = os.path.join(resourcesDir, "ApplyOperation.py")
    callingScriptPath = os.path.join(resourcesDir, "InstallUpdates.sh")

    appList = []
    appListFile = os.path.join(resourcesDir, "app_list.txt")
    if os.path.exists(appListFile):
        fileobj = open(appListFile, mode='r', buffering=1)
        if fileobj:
            for line in fileobj.readlines():
                appList.append(line)
            fileobj.close()

    if not appList:
        munkicommon.display_error("Did not find a list of apps to update.")
        munkicommon.unmountdmg(installroot)
        return -1

    payloadNum = -1
    for line in appList:
        payloadNum = payloadNum + 1
        if munkicommon.munkistatusoutput:
            munkistatus.percent(getPercent(payloadNum + 1, len(appList) + 1))

        (appname, status) = line.split("\t")
        munkicommon.display_status_minor('Searching for %s' % appname)
        # first look in the obvious place
        pathname = os.path.join("/Applications/Adobe Acrobat 9 Pro", appname)
        if os.path.exists(pathname):
            item = {}
            item['path'] = pathname
            candidates = [item]
        else:
            # use system_profiler to search for the app
            candidates = [item for item in munkicommon.getAppData()
                          if item['path'].endswith('/' + appname)]

        # hope there's only one!
        if len(candidates) == 0:
            if status == "optional":
                continue
            else:
                munkicommon.display_error("Cannot patch %s because it "
                                          "was not found on the startup "
                                          "disk." % appname)
                munkicommon.unmountdmg(installroot)
                return -1

        if len(candidates) > 1:
            munkicommon.display_error("Cannot patch %s because we found "
                                      "more than one copy on the "
                                      "startup disk." % appname)
            munkicommon.unmountdmg(installroot)
            return -1

        munkicommon.display_status_minor('Updating %s' % appname)
        apppath = os.path.dirname(candidates[0]["path"])
        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()
        if retcode != 0:
            munkicommon.display_error("Error patching %s: %s" %
                                       (appname, retcode))
            break
        else:
            munkicommon.display_status_minor(
                'Patching %s complete.' % appname)

    munkicommon.display_status_minor('Done.')
    if munkicommon.munkistatusoutput:
        munkistatus.percent(100)

    munkicommon.unmountdmg(installroot)
    return retcode
Example #5
0
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