Esempio n. 1
0
def downloadAvailableUpdates():
    '''Downloads the available Apple updates using our local
    filtered sucatalog. Returns True if successful, False otherwise.'''
    msg = "Downloading available Apple Software Updates..."
    if munkicommon.munkistatusoutput:
        munkistatus.message(msg)
        munkistatus.detail("")
        munkistatus.percent(-1)
        munkicommon.log(msg)
    else:
        munkicommon.display_status(msg)

    # use our filtered local catalog
    catalogpath = os.path.join(swupdCacheDir(),
        'content/catalogs/local_download.sucatalog')
    if not os.path.exists(catalogpath):
        munkicommon.display_error(
            'Missing local Software Update catalog at %s', catalogpath)
        return False

    catalogURL = 'file://localhost' + urllib2.quote(catalogpath)
    # get the OS version
    osvers = int(os.uname()[2].split('.')[0])
    if osvers == 9:
        retcode = leopardDownloadAvailableUpdates(catalogURL)
    else:
        retcode = run_softwareupdate(['--CatalogURL', catalogURL, '-d', '-a'])

    if retcode:
        # there was an error
        munkicommon.display_error("softwareupdate error: %s" % retcode)
        return False
    return True
Esempio n. 2
0
def downloadAvailableUpdates():
    '''Downloads the available Apple updates using our local
    filtered sucatalog. Returns True if successful, False otherwise.'''
    msg = "Downloading available Apple Software Updates..."
    if munkicommon.munkistatusoutput:
        munkistatus.message(msg)
        munkistatus.detail("")
        munkistatus.percent(-1)
        munkicommon.log(msg)
    else:
        munkicommon.display_status(msg)

    # use our filtered local catalog
    catalogpath = os.path.join(swupdCacheDir(),
                               'content/catalogs/local_download.sucatalog')
    if not os.path.exists(catalogpath):
        munkicommon.display_error(
            'Missing local Software Update catalog at %s', catalogpath)
        return False

    catalogURL = 'file://localhost' + urllib2.quote(catalogpath)
    # get the OS version
    osvers = int(os.uname()[2].split('.')[0])
    if osvers == 9:
        retcode = leopardDownloadAvailableUpdates(catalogURL)
    else:
        retcode = run_softwareupdate(['--CatalogURL', catalogURL, '-d', '-a'])

    if retcode:
        # there was an error
        munkicommon.display_error("softwareupdate error: %s" % retcode)
        return False
    return True
Esempio n. 3
0
def main():
    '''Used when calling removepackages.py directly from the command line.'''
    # command-line options
    p = optparse.OptionParser()
    p.set_usage('''Usage: %prog [options] package_id ...''')
    p.add_option('--forcedeletebundles', '-f', action='store_true',
                    help='Delete bundles even if they aren\'t empty.')
    p.add_option('--listfiles', '-l', action='store_true',
                    help='''List the filesystem objects to be removed,
                    but do not actually remove them.''')
    p.add_option('--rebuildpkgdb', action='store_true',
                    help='Force a rebuild of the internal package database.')
    p.add_option('--noremovereceipts', action='store_true',
                    help='''Do not remove receipts and boms from
                    /Library/Receipts and update internal package
                    database.''')
    p.add_option('--noupdateapplepkgdb', action='store_true',
                    help='''Do not update Apple\'s package database.
                    If --noremovereceipts is also given, this is implied''')
    p.add_option('--munkistatusoutput', '-m', action='store_true',
                    help='Output is formatted for use with MunkiStatus.')
    p.add_option('--verbose', '-v', action='count', default=1,
                    help='''More verbose output. May be specified multiple
                    times.''')

    # Get our options and our package names
    options, pkgnames = p.parse_args()

    # check to see if we're root
    if os.geteuid() != 0:
        munkicommon.display_error("You must run this as root!")
        exit(-1)

    # set the munkicommon globals
    munkicommon.munkistatusoutput = options.munkistatusoutput
    munkicommon.verbose = options.verbose

    if options.munkistatusoutput:
        pkgcount = len(pkgnames)
        munkistatus.message("Removing %s packages..." % pkgcount)
        munkistatus.detail("")

    retcode = removepackages(pkgnames,
                             forcedeletebundles=options.forcedeletebundles,
                             listfiles=options.listfiles,
                             rebuildpkgdb=options.rebuildpkgdb,
                             noremovereceipts=options.noremovereceipts,
                             noupdateapplepkgdb=options.noupdateapplepkgdb)
    if options.munkistatusoutput:
        munkistatus.quit()
    exit(retcode)
Esempio n. 4
0
def main():
    '''Used when calling removepackages.py directly from the command line.'''
    # command-line options
    parser = optparse.OptionParser()
    parser.set_usage('''Usage: %prog [options] package_id ...''')
    parser.add_option('--forcedeletebundles', '-f', action='store_true',
                      help='Delete bundles even if they aren\'t empty.')
    parser.add_option('--listfiles', '-l', action='store_true',
                      help='List the filesystem objects to be removed, '
                      'but do not actually remove them.')
    parser.add_option('--rebuildpkgdb', action='store_true',
                      help='Force a rebuild of the internal package database.')
    parser.add_option('--noremovereceipts', action='store_true',
                      help='''Do not remove receipts and boms from
                      /Library/Receipts and update internal package
                      database.''')
    parser.add_option('--noupdateapplepkgdb', action='store_true',
                      help='Do not update Apple\'s package database. '
                      'If --noremovereceipts is also given, this is implied')
    parser.add_option('--munkistatusoutput', '-m', action='store_true',
                      help='Output is formatted for use with MunkiStatus.')
    parser.add_option('--verbose', '-v', action='count', default=1,
                      help='More verbose output. May be specified multiple '
                      'times.')

    # Get our options and our package names
    options, pkgnames = parser.parse_args()

    # check to see if we're root
    if os.geteuid() != 0:
        munkicommon.display_error("You must run this as root!")
        exit(-1)

    # set the munkicommon globals
    munkicommon.munkistatusoutput = options.munkistatusoutput
    munkicommon.verbose = options.verbose

    if options.munkistatusoutput:
        pkgcount = len(pkgnames)
        munkistatus.message("Removing %s packages..." % pkgcount)
        munkistatus.detail("")

    retcode = removepackages(pkgnames,
                             forcedeletebundles=options.forcedeletebundles,
                             listfiles=options.listfiles,
                             rebuildpkgdb=options.rebuildpkgdb,
                             noremovereceipts=options.noremovereceipts,
                             noupdateapplepkgdb=options.noupdateapplepkgdb)
    if options.munkistatusoutput:
        munkistatus.quit()
    exit(retcode)
Esempio n. 5
0
def getAvailableUpdates():
    '''Returns a list of product IDs of available Apple updates'''
    msg = "Checking for available Apple Software Updates..."
    if munkicommon.munkistatusoutput:
        munkistatus.message(msg)
        munkistatus.detail("")
        munkistatus.percent(-1)
        munkicommon.log(msg)
    else:
        munkicommon.display_status(msg)

    applicable_updates = os.path.join(swupdCacheDir(),
                                      'ApplicableUpdates.plist')
    if os.path.exists(applicable_updates):
        # remove any old item
        try:
            os.unlink(applicable_updates)
        except (OSError, IOError):
            pass

    # use our locally-cached Apple catalog
    catalogpath = os.path.join(swupdCacheDir(),
                               'content/catalogs/apple_index.sucatalog')
    catalogURL = 'file://localhost' + urllib2.quote(catalogpath)
    su_options = ['--CatalogURL', catalogURL, '-l', '-f', applicable_updates]

    retcode = run_softwareupdate(su_options)
    if retcode:
        # there was an error
        osvers = int(os.uname()[2].split('.')[0])
        if osvers == 9:
            # always a non-zero retcode on Leopard
            pass
        else:
            munkicommon.display_error("softwareupdate error: %s" % retcode)
            return []

    if os.path.exists(applicable_updates):
        try:
            updatelist = FoundationPlist.readPlist(applicable_updates)
            if updatelist:
                results_array = updatelist.get('phaseResultsArray', [])
                return [
                    item['productKey'] for item in results_array
                    if 'productKey' in item
                ]
        except FoundationPlist.NSPropertyListSerializationException:
            return []
    return []
Esempio n. 6
0
def getAvailableUpdates():
    '''Returns a list of product IDs of available Apple updates'''
    msg = "Checking for available Apple Software Updates..."
    if munkicommon.munkistatusoutput:
        munkistatus.message(msg)
        munkistatus.detail("")
        munkistatus.percent(-1)
        munkicommon.log(msg)
    else:
        munkicommon.display_status(msg)

    applicable_updates = os.path.join(swupdCacheDir(),
                                      'ApplicableUpdates.plist')
    if os.path.exists(applicable_updates):
        # remove any old item
        try:
            os.unlink(applicable_updates)
        except (OSError, IOError):
            pass

    # use our locally-cached Apple catalog
    catalogpath = os.path.join(swupdCacheDir(),
        'content/catalogs/apple_index.sucatalog')
    catalogURL = 'file://localhost' + urllib2.quote(catalogpath)
    su_options = ['--CatalogURL', catalogURL, '-l', '-f', applicable_updates]

    retcode = run_softwareupdate(su_options)
    if retcode:
        # there was an error
        osvers = int(os.uname()[2].split('.')[0])
        if osvers == 9:
            # always a non-zero retcode on Leopard
            pass
        else:
            munkicommon.display_error("softwareupdate error: %s" % retcode)
            return []

    if os.path.exists(applicable_updates):
        try:
            updatelist = FoundationPlist.readPlist(applicable_updates)
            if updatelist:
                results_array = updatelist.get('phaseResultsArray', [])
                return [item['productKey'] for item in results_array
                        if 'productKey' in item]
        except FoundationPlist.NSPropertyListSerializationException:
            return []
    return []
Esempio n. 7
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
Esempio n. 8
0
def installAppleUpdates():
    '''Uses /usr/sbin/softwareupdate to install previously
    downloaded updates. Returns True if a restart is needed
    after install, False otherwise.'''
    msg = "Installing available Apple Software Updates..."
    if munkicommon.munkistatusoutput:
        munkistatus.message(msg)
        munkistatus.detail("")
        munkistatus.percent(-1)
        munkicommon.log(msg)
    else:
        munkicommon.display_status(msg)
    restartneeded = restartNeeded()
    # use our filtered local catalog
    catalogpath = os.path.join(swupdCacheDir(),
                               'content/catalogs/local_install.sucatalog')
    if not os.path.exists(catalogpath):
        munkicommon.display_error(
            'Missing local Software Update catalog at %s', catalogpath)
        # didn't do anything, so no restart needed
        return False

    installlist = getSoftwareUpdateInfo()
    installresults = {'installed': [], 'download': []}

    catalogURL = 'file://localhost' + urllib2.quote(catalogpath)
    retcode = run_softwareupdate(['--CatalogURL', catalogURL, '-i', '-a'],
                                 mode='install',
                                 results=installresults)

    if not 'InstallResults' in munkicommon.report:
        munkicommon.report['InstallResults'] = []

    for item in installlist:
        rep = {}
        rep['name'] = item.get('display_name')
        rep['version'] = item.get('version_to_install', '')
        rep['applesus'] = True
        rep['productKey'] = item.get('productKey', '')
        message = "Apple Software Update install of %s-%s: %s"
        if rep['name'] in installresults['installed']:
            rep['status'] = 0
            install_status = 'SUCCESSFUL'
        elif rep['name'] in installresults['download']:
            rep['status'] = -1
            install_status = 'FAILED due to missing package.'
            munkicommon.display_warning(
                'Apple update %s, %s failed. A sub-package was missing '
                'on disk at time of install.' %
                (rep['name'], rep['productKey']))
        else:
            rep['status'] = -2
            install_status = 'FAILED for unknown reason'
            munkicommon.display_warning(
                'Apple update %s, %s failed to install. No record of '
                'success or failure.' % (rep['name'], rep['productKey']))

        munkicommon.report['InstallResults'].append(rep)
        log_msg = message % (rep['name'], rep['version'], install_status)
        munkicommon.log(log_msg, "Install.log")

    if retcode:
        # there was an error
        munkicommon.display_error("softwareupdate error: %s" % retcode)
    # clean up our now stale local cache
    cachedir = os.path.join(swupdCacheDir())
    if os.path.exists(cachedir):
        unused_retcode = subprocess.call(['/bin/rm', '-rf', cachedir])
    # remove the now invalid appleUpdatesFile
    try:
        os.unlink(appleUpdatesFile())
    except OSError:
        pass
    # Also clear our pref value for last check date. We may have
    # just installed an update which is a pre-req for some other update.
    # Let's check again soon.
    munkicommon.set_pref('LastAppleSoftwareUpdateCheck', None)

    return restartneeded
Esempio n. 9
0
         percent = int(output[10:].rstrip('%'))
     except ValueError:
         percent = -1
     munkicommon.display_percent_done(percent, 100)
 elif output.startswith('Software Update Tool'):
     # don't display this
     pass
 elif output.startswith('Copyright 2'):
     # don't display this
     pass
 elif output.startswith('Installing ') and mode == 'install':
     item = output[11:]
     if item:
         if munkicommon.munkistatusoutput:
             munkistatus.message(output)
             munkistatus.detail("")
             munkistatus.percent(-1)
             munkicommon.log(output)
         else:
             munkicommon.display_status(output)
 elif output.startswith('Installed '):
     # 10.6 / 10.7. Successful install of package name.
     if mode == 'install':
         munkicommon.display_status(output)
         results['installed'].append(output[10:])
     else:
         pass
         # don't display.
         # softwareupdate logging "Installed" at the end of a
         # successful download-only session is odd.
 elif output.startswith('Done '):
Esempio n. 10
0
def installAppleUpdates():
    '''Uses /usr/sbin/softwareupdate to install previously
    downloaded updates. Returns True if a restart is needed
    after install, False otherwise.'''
    msg = "Installing available Apple Software Updates..."
    if munkicommon.munkistatusoutput:
        munkistatus.message(msg)
        munkistatus.detail("")
        munkistatus.percent(-1)
        munkicommon.log(msg)
    else:
        munkicommon.display_status(msg)
    restartneeded = restartNeeded()
    # use our filtered local catalog
    catalogpath = os.path.join(swupdCacheDir(),
        'content/catalogs/local_install.sucatalog')
    if not os.path.exists(catalogpath):
        munkicommon.display_error(
            'Missing local Software Update catalog at %s', catalogpath)
        # didn't do anything, so no restart needed
        return False

    installlist = getSoftwareUpdateInfo()
    installresults = {'installed':[], 'download':[]}

    catalogURL = 'file://localhost' + urllib2.quote(catalogpath)
    retcode = run_softwareupdate(['--CatalogURL', catalogURL, '-i', '-a'],
                                 mode='install', results=installresults)

    if not 'InstallResults' in munkicommon.report:
        munkicommon.report['InstallResults'] = []

    for item in installlist:
        rep = {}
        rep['name'] = item.get('display_name')
        rep['version'] = item.get('version_to_install', '')
        rep['applesus'] = True
        rep['productKey'] = item.get('productKey', '')
        message = "Apple Software Update install of %s-%s: %s"
        if rep['name'] in installresults['installed']:
            rep['status'] = 0
            install_status = 'SUCCESSFUL'
        elif rep['name'] in installresults['download']:
            rep['status'] = -1
            install_status = 'FAILED due to missing package.'
            munkicommon.display_warning(
                'Apple update %s, %s failed. A sub-package was missing '
                'on disk at time of install.'
                % (rep['name'], rep['productKey']))
        else:
            rep['status'] = -2
            install_status = 'FAILED for unknown reason'
            munkicommon.display_warning(
                'Apple update %s, %s failed to install. No record of '
                'success or failure.' % (rep['name'],rep['productKey']))

        munkicommon.report['InstallResults'].append(rep)
        log_msg = message % (rep['name'], rep['version'], install_status)
        munkicommon.log(log_msg, "Install.log")

    if retcode:
        # there was an error
        munkicommon.display_error("softwareupdate error: %s" % retcode)
    # clean up our now stale local cache
    cachedir = os.path.join(swupdCacheDir())
    if os.path.exists(cachedir):
        unused_retcode = subprocess.call(['/bin/rm', '-rf', cachedir])
    # remove the now invalid appleUpdatesFile
    try:
        os.unlink(appleUpdatesFile())
    except OSError:
        pass
    # Also clear our pref value for last check date. We may have
    # just installed an update which is a pre-req for some other update.
    # Let's check again soon.
    munkicommon.set_pref('LastAppleSoftwareUpdateCheck', None)

    return restartneeded
Esempio n. 11
0
         percent = int(output[10:].rstrip('%'))
     except ValueError:
         percent = -1
     munkicommon.display_percent_done(percent, 100)
 elif output.startswith('Software Update Tool'):
     # don't display this
     pass
 elif output.startswith('Copyright 2'):
     # don't display this
     pass
 elif output.startswith('Installing ') and mode == 'install':
     item = output[11:]
     if item:
         if munkicommon.munkistatusoutput:
             munkistatus.message(output)
             munkistatus.detail("")
             munkistatus.percent(-1)
             munkicommon.log(output)
         else:
             munkicommon.display_status(output)
 elif output.startswith('Installed '):
     # 10.6 / 10.7. Successful install of package name.
     if mode == 'install':
         munkicommon.display_status(output)
         results['installed'].append(output[10:])
     else:
         pass
         # don't display.
         # softwareupdate logging "Installed" at the end of a
         # successful download-only session is odd.
 elif output.startswith('Done '):
Esempio n. 12
0
def main():
    """Used when calling removepackages.py directly from the command line."""
    # command-line options
    parser = optparse.OptionParser()
    parser.set_usage("""Usage: %prog [options] package_id ...""")
    parser.add_option(
        "--forcedeletebundles", "-f", action="store_true", help="Delete bundles even if they aren't empty."
    )
    parser.add_option(
        "--listfiles",
        "-l",
        action="store_true",
        help="List the filesystem objects to be removed, " "but do not actually remove them.",
    )
    parser.add_option("--rebuildpkgdb", action="store_true", help="Force a rebuild of the internal package database.")
    parser.add_option(
        "--noremovereceipts",
        action="store_true",
        help="""Do not remove receipts and boms from
                      /Library/Receipts and update internal package
                      database.""",
    )
    parser.add_option(
        "--noupdateapplepkgdb",
        action="store_true",
        help="Do not update Apple's package database. " "If --noremovereceipts is also given, this is implied",
    )
    parser.add_option(
        "--munkistatusoutput", "-m", action="store_true", help="Output is formatted for use with MunkiStatus."
    )
    parser.add_option(
        "--verbose", "-v", action="count", default=1, help="More verbose output. May be specified multiple " "times."
    )

    # Get our options and our package names
    options, pkgnames = parser.parse_args()

    # check to see if we're root
    if os.geteuid() != 0:
        munkicommon.display_error("You must run this as root!")
        exit(-1)

    # set the munkicommon globals
    munkicommon.munkistatusoutput = options.munkistatusoutput
    munkicommon.verbose = options.verbose

    if options.munkistatusoutput:
        pkgcount = len(pkgnames)
        munkistatus.message("Removing %s packages..." % pkgcount)
        munkistatus.detail("")

    retcode = removepackages(
        pkgnames,
        forcedeletebundles=options.forcedeletebundles,
        listfiles=options.listfiles,
        rebuildpkgdb=options.rebuildpkgdb,
        noremovereceipts=options.noremovereceipts,
        noupdateapplepkgdb=options.noupdateapplepkgdb,
    )
    if options.munkistatusoutput:
        munkistatus.quit()
    exit(retcode)