예제 #1
0
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
예제 #2
0
def findBundleReceiptFromID(pkgid):
    '''Finds a bundle receipt in /Library/Receipts based on packageid.
    Some packages write bundle receipts under /Library/Receipts even on
    Snow Leopard; we need to be able to find them so we can remove them.
    Returns a path.'''
    if not pkgid:
        return ''
    receiptsdir = "/Library/Receipts"
    for item in munkicommon.listdir(receiptsdir):
        itempath = os.path.join(receiptsdir, item)
        if item.endswith('.pkg') and os.path.isdir(itempath):
            info = munkicommon.getOnePackageInfo(itempath)
            if info.get('packageid') == pkgid:
                return itempath

    #if we get here, not found
    return ''
예제 #3
0
def findBundleReceiptFromID(pkgid):
    '''Finds a bundle receipt in /Library/Receipts based on packageid.
    Some packages write bundle receipts under /Library/Receipts even on
    Snow Leopard; we need to be able to find them so we can remove them.
    Returns a path.'''
    if not pkgid:
        return ''
    receiptsdir = "/Library/Receipts"
    for item in munkicommon.listdir(receiptsdir):
        itempath = os.path.join(receiptsdir, item)
        if item.endswith('.pkg') and os.path.isdir(itempath):
            info = munkicommon.getOnePackageInfo(itempath)
            if info.get('packageid') == pkgid:
                return itempath

    #if we get here, not found
    return ''
예제 #4
0
def getPayloadInfo(dirpath):
    '''Parses Adobe payloads, pulling out info useful to munki'''
    payloadinfo = {}
    # look for .proxy.xml file dir
    if os.path.isdir(dirpath):
        for item in munkicommon.listdir(dirpath):
            if item.endswith('.proxy.xml'):
                xmlpath = os.path.join(dirpath, item)
                dom = minidom.parse(xmlpath)
                payload_info = dom.getElementsByTagName("PayloadInfo")
                if payload_info:
                    installer_properties = \
                      payload_info[0].getElementsByTagName(
                        "InstallerProperties")
                    if installer_properties:
                        properties = \
                          installer_properties[0].getElementsByTagName(
                                                                   "Property")
                        for prop in properties:
                            if 'name' in prop.attributes.keys():
                                propname = \
                                 prop.attributes['name'].value.encode('UTF-8')
                                propvalue = ''
                                for node in prop.childNodes:
                                    propvalue += node.nodeValue
                                if propname == 'AdobeCode':
                                    payloadinfo['AdobeCode'] = propvalue
                                if propname == 'ProductName':
                                    payloadinfo['display_name'] = propvalue
                                if propname == 'ProductVersion':
                                    payloadinfo['version'] = propvalue

                    installmetadata = \
                        payload_info[0].getElementsByTagName(
                                                 "InstallDestinationMetadata")
                    if installmetadata:
                        totalsizes = \
                          installmetadata[0].getElementsByTagName("TotalSize")
                        if totalsizes:
                            installsize = ''
                            for node in totalsizes[0].childNodes:
                                installsize += node.nodeValue
                            payloadinfo['installed_size'] = \
                                                         int(installsize)/1024

    return payloadinfo
예제 #5
0
def shouldRebuildDB(pkgdbpath):
    """
    Checks to see if our internal package DB should be rebuilt.
    If anything in /Library/Receipts, /Library/Receipts/boms, or
    /Library/Receipts/db/a.receiptdb has a newer modtime than our
    database, we should rebuild.
    """
    receiptsdir = "/Library/Receipts"
    bomsdir = "/Library/Receipts/boms"
    sl_receiptsdir = "/private/var/db/receipts"
    installhistory = "/Library/Receipts/InstallHistory.plist"
    applepkgdb = "/Library/Receipts/db/a.receiptdb"

    if not os.path.exists(pkgdbpath):
        return True

    packagedb_modtime = os.stat(pkgdbpath).st_mtime

    if os.path.exists(receiptsdir):
        receiptsdir_modtime = os.stat(receiptsdir).st_mtime
        if packagedb_modtime < receiptsdir_modtime:
            return True
        receiptlist = munkicommon.listdir(receiptsdir)
        for item in receiptlist:
            if item.endswith(".pkg"):
                pkgpath = os.path.join(receiptsdir, item)
                pkg_modtime = os.stat(pkgpath).st_mtime
                if packagedb_modtime < pkg_modtime:
                    return True

    if os.path.exists(bomsdir):
        bomsdir_modtime = os.stat(bomsdir).st_mtime
        if packagedb_modtime < bomsdir_modtime:
            return True
        bomlist = munkicommon.listdir(bomsdir)
        for item in bomlist:
            if item.endswith(".bom"):
                bompath = os.path.join(bomsdir, item)
                bom_modtime = os.stat(bompath).st_mtime
                if packagedb_modtime < bom_modtime:
                    return True

    if os.path.exists(sl_receiptsdir):
        receiptsdir_modtime = os.stat(sl_receiptsdir).st_mtime
        if packagedb_modtime < receiptsdir_modtime:
            return True
        receiptlist = munkicommon.listdir(sl_receiptsdir)
        for item in receiptlist:
            if item.endswith(".bom") or item.endswith(".plist"):
                pkgpath = os.path.join(sl_receiptsdir, item)
                pkg_modtime = os.stat(pkgpath).st_mtime
                if packagedb_modtime < pkg_modtime:
                    return True

    if os.path.exists(installhistory):
        installhistory_modtime = os.stat(installhistory).st_mtime
        if packagedb_modtime < installhistory_modtime:
            return True

    if os.path.exists(applepkgdb):
        applepkgdb_modtime = os.stat(applepkgdb).st_mtime
        if packagedb_modtime < applepkgdb_modtime:
            return True

    # if we got this far, we don't need to update the db
    return False
예제 #6
0
def removeFilesystemItems(removalpaths, forcedeletebundles):
    """
    Attempts to remove all the paths in the array removalpaths
    """
    # we sort in reverse because we can delete from the bottom up,
    # clearing a directory before we try to remove the directory itself
    removalpaths.sort(reverse=True)
    removalerrors = ""
    removalcount = len(removalpaths)
    munkicommon.display_status_minor('Removing %s filesystem items' %
                                     removalcount)

    itemcount = len(removalpaths)
    itemindex = 0
    munkicommon.display_percent_done(itemindex, itemcount)

    for item in removalpaths:
        itemindex += 1
        pathtoremove = "/" + item
        # use os.path.lexists so broken links return true
        # so we can remove them
        if os.path.lexists(pathtoremove):
            munkicommon.display_detail("Removing: " + pathtoremove)
            if (os.path.isdir(pathtoremove)
                    and not os.path.islink(pathtoremove)):
                diritems = munkicommon.listdir(pathtoremove)
                if diritems == ['.DS_Store']:
                    # If there's only a .DS_Store file
                    # we'll consider it empty
                    ds_storepath = pathtoremove + "/.DS_Store"
                    try:
                        os.remove(ds_storepath)
                    except (OSError, IOError):
                        pass
                    diritems = munkicommon.listdir(pathtoremove)
                if diritems == []:
                    # directory is empty
                    try:
                        os.rmdir(pathtoremove)
                    except (OSError, IOError), err:
                        msg = "Couldn't remove directory %s - %s" % (
                            pathtoremove, err)
                        munkicommon.display_error(msg)
                        removalerrors = removalerrors + "\n" + msg
                else:
                    # the directory is marked for deletion but isn't empty.
                    # if so directed, if it's a bundle (like .app), we should
                    # remove it anyway - no use having a broken bundle hanging
                    # around
                    if forcedeletebundles and isBundle(pathtoremove):
                        munkicommon.display_warning(
                            "Removing non-empty bundle: %s", pathtoremove)
                        retcode = subprocess.call(
                            ['/bin/rm', '-r', pathtoremove])
                        if retcode:
                            msg = "Couldn't remove bundle %s" % pathtoremove
                            munkicommon.display_error(msg)
                            removalerrors = removalerrors + "\n" + msg
                    else:
                        # if this path is inside a bundle, and we've been
                        # directed to force remove bundles,
                        # we don't need to warn because it's going to be
                        # removed with the bundle.
                        # Otherwise, we should warn about non-empty
                        # directories.
                        if not insideBundle(pathtoremove) or \
                           not forcedeletebundles:
                            msg = \
                              "Did not remove %s because it is not empty." % \
                               pathtoremove
                            munkicommon.display_error(msg)
                            removalerrors = removalerrors + "\n" + msg

            else:
                # not a directory, just unlink it
                # I was using rm instead of Python because I don't trust
                # handling of resource forks with Python
                #retcode = subprocess.call(['/bin/rm', pathtoremove])
                # but man that's slow.
                # I think there's a lot of overhead with the
                # subprocess call. I'm going to use os.remove.
                # I hope I don't regret it.
                retcode = ''
                try:
                    os.remove(pathtoremove)
                except (OSError, IOError), err:
                    msg = "Couldn't remove item %s: %s" % (pathtoremove, err)
                    munkicommon.display_error(msg)
                    removalerrors = removalerrors + "\n" + msg
예제 #7
0
def initDatabase(forcerebuild=False):
    """
    Builds or rebuilds our internal package database.
    """
    if not shouldRebuildDB(packagedb) and not forcerebuild:
        return True

    munkicommon.display_status_minor(
        'Gathering information on installed packages')

    if os.path.exists(packagedb):
        try:
            os.remove(packagedb)
        except (OSError, IOError):
            munkicommon.display_error(
                "Could not remove out-of-date receipt database.")
            return False

    os_version = munkicommon.getOsVersion(as_tuple=True)
    pkgcount = 0
    receiptsdir = "/Library/Receipts"
    bomsdir = "/Library/Receipts/boms"
    if os.path.exists(receiptsdir):
        receiptlist = munkicommon.listdir(receiptsdir)
        for item in receiptlist:
            if item.endswith(".pkg"):
                pkgcount += 1
    if os.path.exists(bomsdir):
        bomslist = munkicommon.listdir(bomsdir)
        for item in bomslist:
            if item.endswith(".bom"):
                pkgcount += 1

    if os_version >= (10, 6):  # Snow Leopard or later
        pkglist = []
        cmd = ['/usr/sbin/pkgutil', '--pkgs']
        proc = subprocess.Popen(cmd,
                                shell=False,
                                bufsize=1,
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        while True:
            line = proc.stdout.readline()
            if not line and (proc.poll() != None):
                break

            pkglist.append(line.rstrip('\n'))
            pkgcount += 1

    conn = sqlite3.connect(packagedb)
    conn.text_factory = str
    curs = conn.cursor()
    CreateTables(curs)

    currentpkgindex = 0
    munkicommon.display_percent_done(0, pkgcount)

    if os.path.exists(receiptsdir):
        receiptlist = munkicommon.listdir(receiptsdir)
        for item in receiptlist:
            if munkicommon.stopRequested():
                curs.close()
                conn.close()
                #our package db isn't valid, so we should delete it
                os.remove(packagedb)
                return False

            if item.endswith(".pkg"):
                receiptpath = os.path.join(receiptsdir, item)
                munkicommon.display_detail("Importing %s...", receiptpath)
                ImportPackage(receiptpath, curs)
                currentpkgindex += 1
                munkicommon.display_percent_done(currentpkgindex, pkgcount)

    if os.path.exists(bomsdir):
        bomslist = munkicommon.listdir(bomsdir)
        for item in bomslist:
            if munkicommon.stopRequested():
                curs.close()
                conn.close()
                #our package db isn't valid, so we should delete it
                os.remove(packagedb)
                return False

            if item.endswith(".bom"):
                bompath = os.path.join(bomsdir, item)
                munkicommon.display_detail("Importing %s...", bompath)
                ImportBom(bompath, curs)
                currentpkgindex += 1
                munkicommon.display_percent_done(currentpkgindex, pkgcount)
    if os_version >= (10, 6):  # Snow Leopard or later
        for pkg in pkglist:
            if munkicommon.stopRequested():
                curs.close()
                conn.close()
                #our package db isn't valid, so we should delete it
                os.remove(packagedb)
                return False

            munkicommon.display_detail("Importing %s...", pkg)
            ImportFromPkgutil(pkg, curs)
            currentpkgindex += 1
            munkicommon.display_percent_done(currentpkgindex, pkgcount)

    # in case we didn't quite get to 100% for some reason
    if currentpkgindex < pkgcount:
        munkicommon.display_percent_done(pkgcount, pkgcount)

    # commit and close the db when we're done.
    conn.commit()
    curs.close()
    conn.close()
    return True
예제 #8
0
 def listdir(self, path):
     '''Lists the contents of a repo directory.'''
     return listdir(os.path.join(self.path, path))
예제 #9
0
def shouldRebuildDB(pkgdbpath):
    """
    Checks to see if our internal package DB should be rebuilt.
    If anything in /Library/Receipts, /Library/Receipts/boms, or
    /Library/Receipts/db/a.receiptdb has a newer modtime than our
    database, we should rebuild.
    """
    receiptsdir = "/Library/Receipts"
    bomsdir = "/Library/Receipts/boms"
    sl_receiptsdir = "/private/var/db/receipts"
    installhistory = "/Library/Receipts/InstallHistory.plist"
    applepkgdb = "/Library/Receipts/db/a.receiptdb"

    if not os.path.exists(pkgdbpath):
        return True

    packagedb_modtime = os.stat(pkgdbpath).st_mtime

    if os.path.exists(receiptsdir):
        receiptsdir_modtime = os.stat(receiptsdir).st_mtime
        if packagedb_modtime < receiptsdir_modtime:
            return True
        receiptlist = munkicommon.listdir(receiptsdir)
        for item in receiptlist:
            if item.endswith(".pkg"):
                pkgpath = os.path.join(receiptsdir, item)
                pkg_modtime = os.stat(pkgpath).st_mtime
                if (packagedb_modtime < pkg_modtime):
                    return True

    if os.path.exists(bomsdir):
        bomsdir_modtime = os.stat(bomsdir).st_mtime
        if packagedb_modtime < bomsdir_modtime:
            return True
        bomlist = munkicommon.listdir(bomsdir)
        for item in bomlist:
            if item.endswith(".bom"):
                bompath = os.path.join(bomsdir, item)
                bom_modtime = os.stat(bompath).st_mtime
                if (packagedb_modtime < bom_modtime):
                    return True

    if os.path.exists(sl_receiptsdir):
        receiptsdir_modtime = os.stat(sl_receiptsdir).st_mtime
        if packagedb_modtime < receiptsdir_modtime:
            return True
        receiptlist = munkicommon.listdir(sl_receiptsdir)
        for item in receiptlist:
            if item.endswith(".bom") or item.endswith(".plist"):
                pkgpath = os.path.join(sl_receiptsdir, item)
                pkg_modtime = os.stat(pkgpath).st_mtime
                if (packagedb_modtime < pkg_modtime):
                    return True

    if os.path.exists(installhistory):
        installhistory_modtime = os.stat(installhistory).st_mtime
        if packagedb_modtime < installhistory_modtime:
            return True

    if os.path.exists(applepkgdb):
        applepkgdb_modtime = os.stat(applepkgdb).st_mtime
        if packagedb_modtime < applepkgdb_modtime:
            return True

    # if we got this far, we don't need to update the db
    return False
예제 #10
0
def removeFilesystemItems(removalpaths, forcedeletebundles):
    """
    Attempts to remove all the paths in the array removalpaths
    """
    # we sort in reverse because we can delete from the bottom up,
    # clearing a directory before we try to remove the directory itself
    removalpaths.sort(reverse=True)
    removalerrors = ""
    removalcount = len(removalpaths)
    munkicommon.display_status_minor(
        'Removing %s filesystem items' % removalcount)

    itemcount = len(removalpaths)
    itemindex = 0
    munkicommon.display_percent_done(itemindex, itemcount)

    for item in removalpaths:
        itemindex += 1
        pathtoremove = "/" + item
        # use os.path.lexists so broken links return true
        # so we can remove them
        if os.path.lexists(pathtoremove):
            munkicommon.display_detail("Removing: " + pathtoremove)
            if (os.path.isdir(pathtoremove) and \
               not os.path.islink(pathtoremove)):
                diritems = munkicommon.listdir(pathtoremove)
                if diritems == ['.DS_Store']:
                    # If there's only a .DS_Store file
                    # we'll consider it empty
                    ds_storepath = pathtoremove + "/.DS_Store"
                    try:
                        os.remove(ds_storepath)
                    except (OSError, IOError):
                        pass
                    diritems = munkicommon.listdir(pathtoremove)
                if diritems == []:
                    # directory is empty
                    try:
                        os.rmdir(pathtoremove)
                    except (OSError, IOError), err:
                        msg = "Couldn't remove directory %s - %s" % (
                            pathtoremove, err)
                        munkicommon.display_error(msg)
                        removalerrors = removalerrors + "\n" + msg
                else:
                    # the directory is marked for deletion but isn't empty.
                    # if so directed, if it's a bundle (like .app), we should
                    # remove it anyway - no use having a broken bundle hanging
                    # around
                    if (forcedeletebundles and isBundle(pathtoremove)):
                        munkicommon.display_warning(
                            "Removing non-empty bundle: %s", pathtoremove)
                        retcode = subprocess.call(['/bin/rm', '-r',
                                                   pathtoremove])
                        if retcode:
                            msg = "Couldn't remove bundle %s" % pathtoremove
                            munkicommon.display_error(msg)
                            removalerrors = removalerrors + "\n" + msg
                    else:
                        # if this path is inside a bundle, and we've been
                        # directed to force remove bundles,
                        # we don't need to warn because it's going to be
                        # removed with the bundle.
                        # Otherwise, we should warn about non-empty
                        # directories.
                        if not insideBundle(pathtoremove) or \
                           not forcedeletebundles:
                            msg = \
                              "Did not remove %s because it is not empty." % \
                               pathtoremove
                            munkicommon.display_error(msg)
                            removalerrors = removalerrors + "\n" + msg

            else:
                # not a directory, just unlink it
                # I was using rm instead of Python because I don't trust
                # handling of resource forks with Python
                #retcode = subprocess.call(['/bin/rm', pathtoremove])
                # but man that's slow.
                # I think there's a lot of overhead with the
                # subprocess call. I'm going to use os.remove.
                # I hope I don't regret it.
                retcode = ''
                try:
                    os.remove(pathtoremove)
                except (OSError, IOError), err:
                    msg = "Couldn't remove item %s: %s" % (pathtoremove, err)
                    munkicommon.display_error(msg)
                    removalerrors = removalerrors + "\n" + msg
예제 #11
0
def initDatabase(forcerebuild=False):
    """
    Builds or rebuilds our internal package database.
    """
    if not shouldRebuildDB(packagedb) and not forcerebuild:
        return True

    munkicommon.display_status_minor(
        'Gathering information on installed packages')

    if os.path.exists(packagedb):
        try:
            os.remove(packagedb)
        except (OSError, IOError):
            munkicommon.display_error(
                "Could not remove out-of-date receipt database.")
            return False

    os_version = munkicommon.getOsVersion(as_tuple=True)
    pkgcount = 0
    receiptsdir = "/Library/Receipts"
    bomsdir = "/Library/Receipts/boms"
    if os.path.exists(receiptsdir):
        receiptlist = munkicommon.listdir(receiptsdir)
        for item in receiptlist:
            if item.endswith(".pkg"):
                pkgcount += 1
    if os.path.exists(bomsdir):
        bomslist = munkicommon.listdir(bomsdir)
        for item in bomslist:
            if item.endswith(".bom"):
                pkgcount += 1

    if os_version >= (10, 6): # Snow Leopard or later
        pkglist = []
        cmd = ['/usr/sbin/pkgutil', '--pkgs']
        proc = subprocess.Popen(cmd, shell=False, bufsize=1,
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        while True:
            line =  proc.stdout.readline()
            if not line and (proc.poll() != None):
                break

            pkglist.append(line.rstrip('\n'))
            pkgcount += 1

    conn = sqlite3.connect(packagedb)
    conn.text_factory = str
    curs = conn.cursor()
    CreateTables(curs)

    currentpkgindex = 0
    munkicommon.display_percent_done(0, pkgcount)

    if os.path.exists(receiptsdir):
        receiptlist = munkicommon.listdir(receiptsdir)
        for item in receiptlist:
            if munkicommon.stopRequested():
                curs.close()
                conn.close()
                #our package db isn't valid, so we should delete it
                os.remove(packagedb)
                return False

            if item.endswith(".pkg"):
                receiptpath = os.path.join(receiptsdir, item)
                munkicommon.display_detail("Importing %s...", receiptpath)
                ImportPackage(receiptpath, curs)
                currentpkgindex += 1
                munkicommon.display_percent_done(currentpkgindex, pkgcount)

    if os.path.exists(bomsdir):
        bomslist = munkicommon.listdir(bomsdir)
        for item in bomslist:
            if munkicommon.stopRequested():
                curs.close()
                conn.close()
                #our package db isn't valid, so we should delete it
                os.remove(packagedb)
                return False

            if item.endswith(".bom"):
                bompath = os.path.join(bomsdir, item)
                munkicommon.display_detail("Importing %s...", bompath)
                ImportBom(bompath, curs)
                currentpkgindex += 1
                munkicommon.display_percent_done(currentpkgindex, pkgcount)
    if os_version >= (10, 6):  # Snow Leopard or later
        for pkg in pkglist:
            if munkicommon.stopRequested():
                curs.close()
                conn.close()
                #our package db isn't valid, so we should delete it
                os.remove(packagedb)
                return False

            munkicommon.display_detail("Importing %s...", pkg)
            ImportFromPkgutil(pkg, curs)
            currentpkgindex += 1
            munkicommon.display_percent_done(currentpkgindex, pkgcount)

    # in case we didn't quite get to 100% for some reason
    if currentpkgindex < pkgcount:
        munkicommon.display_percent_done(pkgcount, pkgcount)

    # commit and close the db when we're done.
    conn.commit()
    curs.close()
    conn.close()
    return True
예제 #12
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
예제 #13
0
def getAdobeSetupInfo(installroot):
    '''Given the root of mounted Adobe DMG,
    look for info about the installer or updater'''

    info = {}
    payloads = []

    # look for a payloads folder
    for (path, unused_dirs, unused_files) in os.walk(installroot):
        if path.endswith("/payloads"):
            driverfolder = ''
            mediaSignature = ''
            setupxml = os.path.join(path, "setup.xml")
            if os.path.exists(setupxml):
                dom = minidom.parse(setupxml)
                drivers =  dom.getElementsByTagName("Driver")
                if drivers:
                    driver = drivers[0]
                    if 'folder' in driver.attributes.keys():
                        driverfolder = \
                             driver.attributes['folder'].value.encode('UTF-8')
                if driverfolder == '':
                    # look for mediaSignature (CS5 AAMEE install)
                    setupElements = dom.getElementsByTagName("Setup")
                    if setupElements:
                        mediaSignatureElements = \
                            setupElements[0].getElementsByTagName(
                                                            "mediaSignature")
                        if mediaSignatureElements:
                            element = mediaSignatureElements[0]
                            for node in element.childNodes:
                                mediaSignature += node.nodeValue

            for item in munkicommon.listdir(path):
                payloadpath = os.path.join(path, item)
                payloadinfo = getPayloadInfo(payloadpath)
                if payloadinfo:
                    payloads.append(payloadinfo)
                    if (driverfolder and item == driverfolder) or \
                       (mediaSignature and
                            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

    if not payloads:
        # look for an extensions folder; almost certainly this is an Updater
        for (path, unused_dirs, unused_files) in os.walk(installroot):
            if path.endswith("/extensions"):
                for item in munkicommon.listdir(path):
                    #skip LanguagePacks
                    if item.find("LanguagePack") == -1:
                        itempath = os.path.join(path, item)
                        payloadinfo = getPayloadInfo(itempath)
                        if payloadinfo:
                            payloads.append(payloadinfo)

                # we found an extensions dir,
                # so no need to keep walking the install root
                break

    if payloads:
        if len(payloads) == 1:
            info['display_name'] = payloads[0]['display_name']
            info['version'] = payloads[0]['version']
        else:
            if not 'display_name' in info:
                info['display_name'] = "ADMIN: choose from payloads"
            if not 'version' in info:
                info['version'] = "ADMIN please set me"
        info['payloads'] = payloads
        installed_size = 0
        for payload in payloads:
            installed_size = installed_size + \
                             payload.get('installed_size',0)
        info['installed_size'] = installed_size
    return info