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
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)
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)
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 []
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 []
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
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
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 '):
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
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)