def RemoveZenPack(dmd, packName, log=None, skipDepsCheck=False, leaveObjects=True, deleteFiles=True): if log: log.debug('Removing Pack "%s"', packName) if not skipDepsCheck: for pack in dmd.ZenPackManager.packs(): if packName in pack.requires: raise ZenPackException('Pack %s depends on pack %s, ' 'not removing' % (pack.id, packName)) zp = None try: zp = dmd.ZenPackManager.packs._getOb(packName) except AttributeError: # Pack not in zeo, might still exist in filesystem if log: log.debug('No ZenPack named %s in zeo', packName) if zp: try: # In 2.2 we added an additional parameter to the remove method. # Any ZenPack subclasses that haven't been updated to take the new # parameter will throw a TypeError. # The newer version of zenoss-supplied ZenPacks monkey patch # older installed versions during an upgrade so that the remove # accepts the leaveObjects method. zp.remove(dmd, leaveObjects=True) except TypeError: zp.remove(dmd) dmd.ZenPackManager.packs._delObject(packName) root = zenPath('Products', packName) if deleteFiles: if log: log.debug('Removing %s', root) recurse = "" if os.path.isdir(root): recurse = "r" os.system('rm -%sf %s' % (recurse, root)) cleanupSkins(dmd) return True
def RemoveZenPack(dmd, packName, log=None, skipDepsCheck=False, leaveObjects=True, deleteFiles=True): if log: log.debug('Removing Pack "%s"' % packName) if not skipDepsCheck: for pack in dmd.ZenPackManager.packs(): if packName in pack.requires: raise ZenPackException('Pack %s depends on pack %s, ' 'not removing' % (pack.id, packName)) zp = None try: zp = dmd.ZenPackManager.packs._getOb(packName) except AttributeError: # Pack not in zeo, might still exist in filesystem if log: log.debug('No ZenPack named %s in zeo' % packName) if zp: try: # In 2.2 we added an additional parameter to the remove method. # Any ZenPack subclasses that haven't been updated to take the new # parameter will throw a TypeError. # The newer version of zenoss-supplied ZenPacks monkey patch # older installed versions during an upgrade so that the remove # accepts the leaveObjects method. zp.remove(dmd, leaveObjects=True) except TypeError: zp.remove(dmd) dmd.ZenPackManager.packs._delObject(packName) root = zenPath('Products', packName) if deleteFiles: if log: log.debug('Removing %s' % root) recurse = "" if os.path.isdir(root): recurse = "r" os.system('rm -%sf %s' % (recurse, root)) cleanupSkins(dmd) return True
def RemoveZenPack(dmd, packName, filesOnly=False, skipDepsCheck=False, leaveObjects=False, sendEvent=True, forceNoFileDeletion=False, uninstallEgg=True): """ Remove the given ZenPack from Zenoss. Whether the ZenPack will be removed from the filesystem or not depends on the result of the ZenPack's shouldDeleteFilesOnRemoval method. """ try: if filesOnly: skipDepsCheck = True # Check for dependency implications here? if not skipDepsCheck: deps = GetDependents(dmd, packName) if deps: raise ZenPackDependentsException( '%s cannot be removed ' % packName + 'because it is required by %s' % ', '.join(deps)) if not filesOnly: # Fetch the zenpack, call its remove() and remove from packs zp = None try: zp = dmd.ZenPackManager.packs._getOb(packName) except AttributeError, ex: raise ZenPackNotFoundException( 'No ZenPack named %s is installed' % packName) # If zencatalog hasn't finished yet, we get ugly messages that don't # mean anything. Hide them. logFilter = None if not getattr(dmd.zport, '_zencatalog_completed', False): logFilter = CatalogLoggingFilter() logging.getLogger('Zope.ZCatalog').addFilter(logFilter) try: zp.remove(dmd, leaveObjects) dmd.ZenPackManager.packs._delObject(packName) transaction.commit() finally: # Remove our logging filter so we don't hide anything important if logFilter is not None: logging.getLogger('Zope.ZCatalog').removeFilter(logFilter) # Uninstall the egg and possibly delete it # If we can't find the distribution then apparently the zp egg itself is # missing. Continue on with the removal and swallow the # DistributionNotFound exception try: dist = zp.getDistribution() except pkg_resources.DistributionNotFound: dist = None if dist: # Determine deleteFiles before develop -u gets called. Once # it is called the egg has problems figuring out some of it's state. deleteFiles = zp.shouldDeleteFilesOnRemoval() if uninstallEgg: if zp.isDevelopment(): zenPackDir = zenPath('ZenPacks') cmd = ('%s setup.py develop -u ' % binPath('python') + '--site-dirs=%s ' % zenPackDir + '-d %s' % zenPackDir) p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, cwd=zp.eggPath()) out, err = p.communicate() code = p.wait() if code: raise ZenPackException(err) else: DoEasyUninstall(packName) # elif cleanupEasyInstallPth: # # Do we need to call easy_install -m here? It causes problems # # because it tries to install deps. Cleanup easy-install.pth # # ourselves instead. # # We don't want to cleanup easy-install.pth when a newer # # version of the egg has already been installed (when doing # # an upgrade or installing in new location.) # eggLink = './%s' % zp.eggName() # CleanupEasyInstallPth(eggLink) if deleteFiles and not forceNoFileDeletion: eggDir = zp.eggPath() if os.path.islink(eggDir): os.remove(eggDir) else: shutil.rmtree(eggDir) cleanupSkins(dmd) transaction.commit()
def transactional_actions(): # Instantiate ZenPack entryMap = pkg_resources.get_entry_map(dist, ZENPACK_ENTRY_POINT) if not entryMap or len(entryMap) > 1: raise ZenPackException( 'A ZenPack egg must contain exactly one' ' zenoss.zenpacks entry point. This egg appears to contain' ' %s such entry points.' % len(entryMap)) packName, packEntry = entryMap.items()[0] runExternalZenpack = True #if zenpack with same name exists we can't load both modules #installing new egg zenpack will be done in a sub process existing = dmd.ZenPackManager.packs._getOb(packName, None) if existing: log.info("Previous ZenPack exists with same name %s" % packName) if filesOnly or not existing: #running files only or zenpack by same name doesn't already exists # so no need to install the zenpack in an external process runExternalZenpack = False module = packEntry.load() if hasattr(module, 'ZenPack'): zenPack = module.ZenPack(packName) else: zenPack = ZenPack(packName) zenPack.eggPack = True CopyMetaDataToZenPackObject(dist, zenPack) if filesOnly: for loader in (ZPL.ZPLDaemons(), ZPL.ZPLBin(), ZPL.ZPLLibExec()): loader.load(zenPack, None) if fromUI and not zenPack.installableFromUI: raise ZenPackException( "This ZenPack cannot be installed through the UI.") if not filesOnly: # Look for an installed ZenPack to be upgraded. In this case # upgraded means that it is removed before the new one is installed # but that its objects are not removed and the packables are # copied to the new instance. existing = dmd.ZenPackManager.packs._getOb(packName, None) if not existing and zenPack.prevZenPackName: existing = dmd.ZenPackManager.packs._getOb( zenPack.prevZenPackName, None) deferFileDeletion = False packables = [] upgradingFrom = None if existing: upgradingFrom = existing.version for p in existing.packables(): packables.append(p) existing.packables.removeRelation(p) if existing.isEggPack(): forceNoFileDeletion = existing.eggPath() == dist.location RemoveZenPack(dmd, existing.id, skipDepsCheck=True, leaveObjects=True, forceNoFileDeletion=forceNoFileDeletion, uninstallEgg=False) else: # Don't delete files, might still be needed for # migrate scripts to be run below. deferFileDeletion = True oldzenpack.RemoveZenPack(dmd, existing.id, skipDepsCheck=True, leaveObjects=True, deleteFiles=False) if runExternalZenpack or forceRunExternal: log.info("installing zenpack %s; launching process" % packName) cmd = [binPath('zenpack')] if link: cmd += ["--link"] cmd += ["--install", eggPath] if upgradingFrom: cmd += ['--previousversion', upgradingFrom] if fromUI: cmd += ["--fromui"] cmdStr = " ".join(cmd) log.debug("launching sub process command: %s" % cmdStr) p = subprocess.Popen(cmdStr, shell=True) out, err = p.communicate() p.wait() if p.returncode: raise ZenPackException( 'Error installing the egg (%s): %s' % (p.returncode, err)) dmd._p_jar.sync() else: dmd.ZenPackManager.packs._setObject(packName, zenPack) zenPack = dmd.ZenPackManager.packs._getOb(packName) #hack because ZenPack.install is overridden by a lot of zenpacks #so we can't change the signature of install to take the #previousVerison zenPack.prevZenPackVersion = previousVersion zenPack.install(dmd) zenPack.prevZenPackVersion = None try: zenPack = dmd.ZenPackManager.packs._getOb(packName) for p in packables: pId = p.getPrimaryId() try: # make sure packable still exists; could be deleted by a # migrate getObjByPath(dmd, pId) log.debug("adding packable relation for id %s", pId) zenPack.packables.addRelation(p) except (KeyError, zExceptions.NotFound): log.debug('did not find packable %s', pId) except AttributeError, e: # If this happens in the child process or during the non-upgrade # flow, reraise the exception if not runExternalZenpack: raise # This specific error will occur when the version of the ZenPack # being installed subclasses Products.ZenModel.ZenPack, but the # previous version of the ZenPack did not. if str(e) == "'ZenPack' object has no attribute '__of__'": zenPack = ZenPack(packName) else: # This is the signature error of class-loading issues # during zenpack upgrade. The final state should be okay, # except that modified packables may be lost. message = "There has been an error during the post-" + \ "installation steps for the zenpack %s. In " + \ "most cases, no further action is required. If " + \ "issues persist, please reinstall this zenpack." message = message % packName log.warning(message) raise NonCriticalInstallError(message) cleanupSkins(dmd) return zenPack, deferFileDeletion, existing
# The newer version of zenoss-supplied ZenPacks monkey patch # older installed versions during an upgrade so that the remove # accepts the leaveObjects method. zp.remove(dmd, leaveObjects=True) except TypeError: zp.remove(dmd) dmd.ZenPackManager.packs._delObject(packName) root = zenPath('Products', packName) if deleteFiles: if log: log.debug('Removing %s' % root) recurse = "" if os.path.isdir(root): recurse = "r" os.system('rm -%sf %s' % (recurse, root)) cleanupSkins(dmd) return True class ZenPackCmd(ZenScriptBase): """Manage ZenPacks""" def _verifyZepRunning(self): zep = getFacade('zep') try: zep.getConfig() return True except ServiceException: return False def run(self): """Execute the user's request"""
def RemoveZenPack(dmd, packName, filesOnly=False, skipDepsCheck=False, leaveObjects=False, sendEvent=True, forceNoFileDeletion=False, uninstallEgg=True): """ Remove the given ZenPack from Zenoss. Whether the ZenPack will be removed from the filesystem or not depends on the result of the ZenPack's shouldDeleteFilesOnRemoval method. """ try: if filesOnly: skipDepsCheck = True # Check for dependency implications here? if not skipDepsCheck: deps = GetDependents(dmd, packName) if deps: raise ZenPackDependentsException('%s cannot be removed ' % packName + 'because it is required by %s' % ', '.join(deps)) if not filesOnly: # Fetch the zenpack, call its remove() and remove from packs zp = None try: zp = dmd.ZenPackManager.packs._getOb(packName) except AttributeError, ex: raise ZenPackNotFoundException('No ZenPack named %s is installed' % packName) # If zencatalog hasn't finished yet, we get ugly messages that don't # mean anything. Hide them. logFilter = None if not getattr(dmd.zport, '_zencatalog_completed', False): logFilter = CatalogLoggingFilter() logging.getLogger('Zope.ZCatalog').addFilter(logFilter) try: zp.remove(dmd, leaveObjects) dmd.ZenPackManager.packs._delObject(packName) transaction.commit() finally: # Remove our logging filter so we don't hide anything important if logFilter is not None: logging.getLogger('Zope.ZCatalog').removeFilter(logFilter) # Uninstall the egg and possibly delete it # If we can't find the distribution then apparently the zp egg itself is # missing. Continue on with the removal and swallow the # DistributionNotFound exception try: dist = zp.getDistribution() except pkg_resources.DistributionNotFound: dist = None if dist: # Determine deleteFiles before develop -u gets called. Once # it is called the egg has problems figuring out some of it's state. deleteFiles = zp.shouldDeleteFilesOnRemoval() if uninstallEgg: if zp.isDevelopment(): zenPackDir = zenPath('ZenPacks') cmd = ('%s setup.py develop -u ' % binPath('python') + '--site-dirs=%s ' % zenPackDir + '-d %s' % zenPackDir) p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, cwd=zp.eggPath()) out, err = p.communicate() code = p.wait() if code: raise ZenPackException(err) else: DoEasyUninstall(packName) # elif cleanupEasyInstallPth: # # Do we need to call easy_install -m here? It causes problems # # because it tries to install deps. Cleanup easy-install.pth # # ourselves instead. # # We don't want to cleanup easy-install.pth when a newer # # version of the egg has already been installed (when doing # # an upgrade or installing in new location.) # eggLink = './%s' % zp.eggName() # CleanupEasyInstallPth(eggLink) if deleteFiles and not forceNoFileDeletion: eggDir = zp.eggPath() if os.path.islink(eggDir): os.remove(eggDir) else: shutil.rmtree(eggDir) cleanupSkins(dmd) transaction.commit()
def transactional_actions(): # Instantiate ZenPack entryMap = pkg_resources.get_entry_map(dist, ZENPACK_ENTRY_POINT) if not entryMap or len(entryMap) > 1: raise ZenPackException('A ZenPack egg must contain exactly one' ' zenoss.zenpacks entry point. This egg appears to contain' ' %s such entry points.' % len(entryMap)) packName, packEntry = entryMap.items()[0] runExternalZenpack = True #if zenpack with same name exists we can't load both modules #installing new egg zenpack will be done in a sub process existing = dmd.ZenPackManager.packs._getOb(packName, None) if existing: log.info("Previous ZenPack exists with same name %s" % packName) if filesOnly or not existing: #running files only or zenpack by same name doesn't already exists # so no need to install the zenpack in an external process runExternalZenpack = False module = packEntry.load() if hasattr(module, 'ZenPack'): zenPack = module.ZenPack(packName) else: zenPack = ZenPack(packName) zenPack.eggPack = True CopyMetaDataToZenPackObject(dist, zenPack) if filesOnly: for loader in (ZPL.ZPLDaemons(), ZPL.ZPLBin(), ZPL.ZPLLibExec()): loader.load(zenPack, None) if fromUI and not zenPack.installableFromUI: raise ZenPackException("This ZenPack cannot be installed through the UI.") if not filesOnly: # Look for an installed ZenPack to be upgraded. In this case # upgraded means that it is removed before the new one is installed # but that its objects are not removed and the packables are # copied to the new instance. existing = dmd.ZenPackManager.packs._getOb(packName, None) if not existing and zenPack.prevZenPackName: existing = dmd.ZenPackManager.packs._getOb( zenPack.prevZenPackName, None) deferFileDeletion = False packables = [] upgradingFrom = None if existing: upgradingFrom = existing.version for p in existing.packables(): packables.append(p) existing.packables.removeRelation(p) if existing.isEggPack(): forceNoFileDeletion = existing.eggPath() == dist.location RemoveZenPack(dmd, existing.id, skipDepsCheck=True, leaveObjects=True, forceNoFileDeletion=forceNoFileDeletion, uninstallEgg=False) else: # Don't delete files, might still be needed for # migrate scripts to be run below. deferFileDeletion = True oldzenpack.RemoveZenPack(dmd, existing.id, skipDepsCheck=True, leaveObjects=True, deleteFiles=False) if runExternalZenpack or forceRunExternal: log.info("installing zenpack %s; launching process" % packName) cmd = [binPath('zenpack')] if link: cmd += ["--link"] cmd += ["--install", eggPath] if upgradingFrom: cmd += ['--previousversion', upgradingFrom] if fromUI: cmd += ["--fromui"] if serviceId: cmd += ['--service-id', serviceId] cmdStr = " ".join(cmd) log.debug("launching sub process command: %s" % cmdStr) p = subprocess.Popen(cmdStr, shell=True) out, err = p.communicate() p.wait() if p.returncode: raise ZenPackException('Error installing the egg (%s): %s' % (p.returncode, err)) dmd._p_jar.sync() else: dmd.ZenPackManager.packs._setObject(packName, zenPack) zenPack = dmd.ZenPackManager.packs._getOb(packName) #hack because ZenPack.install is overridden by a lot of zenpacks #so we can't change the signature of install to take the #previousVerison zenPack.prevZenPackVersion = previousVersion zenPack.install(dmd) zenPack.prevZenPackVersion = None try: zenPack = dmd.ZenPackManager.packs._getOb(packName) for p in packables: pId = p.getPrimaryId() try: # make sure packable still exists; could be deleted by a # migrate getObjByPath(dmd, pId) log.debug("adding packable relation for id %s", pId) zenPack.packables.addRelation(p) except (KeyError, zExceptions.NotFound): log.debug('did not find packable %s',pId) except AttributeError, e: # If this happens in the child process or during the non-upgrade # flow, reraise the exception if not runExternalZenpack: raise # This specific error will occur when the version of the ZenPack # being installed subclasses Products.ZenModel.ZenPack, but the # previous version of the ZenPack did not. if str(e) == "'ZenPack' object has no attribute '__of__'": zenPack = ZenPack(packName) else: # This is the signature error of class-loading issues # during zenpack upgrade. The final state should be okay, # except that modified packables may be lost. message = "There has been an error during the post-" + \ "installation steps for the zenpack %s. In " + \ "most cases, no further action is required. If " + \ "issues persist, please reinstall this zenpack." message = message % packName log.warning( message ) raise NonCriticalInstallError( message ) cleanupSkins(dmd) return zenPack, deferFileDeletion, existing
# The newer version of zenoss-supplied ZenPacks monkey patch # older installed versions during an upgrade so that the remove # accepts the leaveObjects method. zp.remove(dmd, leaveObjects=True) except TypeError: zp.remove(dmd) dmd.ZenPackManager.packs._delObject(packName) root = zenPath('Products', packName) if deleteFiles: if log: log.debug('Removing %s' % root) recurse = "" if os.path.isdir(root): recurse = "r" os.system('rm -%sf %s' % (recurse, root)) cleanupSkins(dmd) return True class ZenPackCmd(ZenScriptBase): """Manage ZenPacks""" def _verifyZepRunning(self): zep = getFacade('zep') try: zep.getConfig() return True except ServiceException: return False def run(self):