예제 #1
0
    def preInstallCheck(self, eggInstall=True):
        """Check that prerequisite zenpacks are installed.
        Return True if no prereqs specified or if they are present.
        False otherwise.
        """
        if eggInstall:
            installedPacks = dict((pack.id, pack.version) \
                             for pack in self.dataroot.ZenPackManager.packs())

            if self.options.installPackName.lower().endswith('.egg'):
                # standard prebuilt egg
                if not os.path.exists(self.options.installPackName):
                    raise ZenPackNotFoundException("Unable to find ZenPack named '%s'" % \
                                           self.options.installPackName)
                zf = ZipFile(self.options.installPackName)
                if 'EGG-INFO/requires.txt' in zf.namelist():
                    reqZenpacks = zf.read('EGG-INFO/requires.txt').split('\n')
                else:
                    return True
            else:
                # source egg, no prebuilt egg-info
                with get_temp_dir() as tempEggDir:
                    cmd = '%s setup.py egg_info -e %s' % \
                                                (binPath('python'), tempEggDir)
                    subprocess.call(cmd,
                                    shell=True,
                                    stdout=open('/dev/null', 'w'),
                                    cwd=self.options.installPackName)

                    eggRequires = os.path.join(
                        tempEggDir, self.options.installPackName + '.egg-info',
                        'requires.txt')
                    if os.path.isfile(eggRequires):
                        reqZenpacks = open(eggRequires, 'r').read().split('\n')
                    else:
                        return True

            prereqsMet = True
            for req in reqZenpacks:
                if not req.startswith('ZenPacks'):
                    continue
                for parsed_req in parse_requirements([req]):
                    installed_version = installedPacks.get(
                        parsed_req.project_name, None)
                    if installed_version is None:
                        self.log.error('Zenpack %s requires %s',
                                       self.options.installPackName,
                                       parsed_req)
                        prereqsMet = False
                    else:
                        if not installed_version in parsed_req:
                            self.log.error('Zenpack %s requires %s, found: %s',
                                           self.options.installPackName,
                                           parsed_req, installed_version)
                            prereqsMet = False
            return prereqsMet

        if os.path.isfile(self.options.installPackName):
            zf = ZipFile(self.options.installPackName)
            for name in zf.namelist():
                if name.endswith == '/%s' % CONFIG_FILE:
                    sio = StringIO(zf.read(name))
            else:
                return True
        else:
            name = os.path.join(self.options.installPackName, CONFIG_FILE)
            if os.path.isfile(name):
                fp = open(name)
                sio = StringIO(fp.read())
                fp.close()
            else:
                return True

        parser = ConfigParser.SafeConfigParser()
        parser.readfp(sio, name)
        if parser.has_section(CONFIG_SECTION_ABOUT) \
            and parser.has_option(CONFIG_SECTION_ABOUT, 'requires'):
            requires = eval(parser.get(CONFIG_SECTION_ABOUT, 'requires'))
            if not isinstance(requires, list):
                requires = [zp.strip() for zp in requires.split(',')]
            missing = [
                zp for zp in requires
                if zp not in self.dataroot.ZenPackManager.packs.objectIds()
            ]
            if missing:
                self.log.error('ZenPack %s was not installed because',
                               self.options.installPackName,
                               ' it requires the following ZenPack(s): %s',
                               ', '.join(missing))
                return False
        return True
    def manage_installZenPack(self, zenpack=None, REQUEST=None):
        """
        Installs the given zenpack.  Zenpack is a file upload from the browser.
        """
        import re
        import time
        from subprocess import Popen, PIPE, STDOUT

        from Products.ZenUtils.Utils import get_temp_dir

        ZENPACK_INSTALL_TIMEOUT = 10 * 60  # 10 minutes

        if not getattr(self.dmd, 'ZenPackManager'):
            msg = 'Your Zenoss database appears to be out of date. Try ' \
                    'running zenmigrate to update.'
            if REQUEST:
                messaging.IMessageSender(self).sendToBrowser(
                    'Error', msg, priority=messaging.WARNING)
                return self.callZenScreen(REQUEST)
            from ZenPack import ZenPackNeedMigrateException
            raise ZenPackNeedMigrateException(msg)

        msg = ''
        with get_temp_dir() as tempDir:
            # zenpack.filename gives us filename of the zenpack with the
            # path as it exists on the client. We need just the filename.
            base_filename = re.split(r"\\|/", zenpack.filename)[-1]
            # Macs (and other broswers/OSs) always append a .zip to files they
            # believe to be zip files. Remedy that:
            if base_filename.endswith('.egg.zip'):
                base_filename = base_filename[:-7] + 'egg'

            # Write the zenpack to the filesystem
            tFile = open(os.path.join(tempDir, base_filename), 'wb')
            tFile.write(zenpack.read())
            tFile.close()

            p = None  # zenpack install process
            # ZEN-1781: Redirect to a temporary file so the stdout buffer
            # doesn't fill up and block till you read from it.
            outFile = None
            try:
                outFile = tempfile.SpooledTemporaryFile()
                # Run zenpack install
                cmd = 'zenpack --install %s --fromui' % tFile.name
                p = Popen(cmd, shell=True, stdout=outFile, stderr=STDOUT)

                endWait = time.time() + ZENPACK_INSTALL_TIMEOUT
                # Wait for install to complete, fail, or time out
                while p.poll() is None and time.time() < endWait:
                    time.sleep(1)

                if p.poll() is not None:
                    outFile.seek(0)
                    msg = outFile.read()
            finally:
                if outFile:
                    outFile.close()
                if p and p.poll() is None:
                    p.kill()
                    msg += 'Zenpack install killed due to timeout'

        if REQUEST:
            # TODO: show the output in a scrollable window.
            # format command result for HTML
            #msg = '<br>'.join(line.strip() for line in msg.split('\n') if line.strip())
            log.info("Output from installing ZenPack %s:\n%s" %
                     (zenpack.filename, msg))
            success = 'ERROR' not in msg
            msg = "Successfully installed ZenPack %s" % zenpack.filename if success \
                    else "Failed to install ZenPack %s. " \
                         "See event.log for details." % zenpack.filename
            messaging.IMessageSender(self).sendToBrowser(
                'Zenpack',
                msg,
                priority=messaging.INFO if success else messaging.CRITICAL)
            return self.callZenScreen(REQUEST)
예제 #3
0
    def manage_installZenPack(self, zenpack=None, REQUEST=None):
        """
        Installs the given zenpack.  Zenpack is a file upload from the browser.
        """
        import re
        import time
        from subprocess import Popen, PIPE, STDOUT

        from Products.ZenUtils.Utils import get_temp_dir

        ZENPACK_INSTALL_TIMEOUT = 10 * 60  # 10 minutes

        if not getattr(self.dmd, "ZenPackManager"):
            msg = "Your Zenoss database appears to be out of date. Try " "running zenmigrate to update."
            if REQUEST:
                messaging.IMessageSender(self).sendToBrowser("Error", msg, priority=messaging.WARNING)
                return self.callZenScreen(REQUEST)
            from ZenPack import ZenPackNeedMigrateException

            raise ZenPackNeedMigrateException(msg)

        msg = ""
        with get_temp_dir() as tempDir:
            # zenpack.filename gives us filename of the zenpack with the
            # path as it exists on the client. We need just the filename.
            base_filename = re.split(r"\\|/", zenpack.filename)[-1]
            # Macs (and other broswers/OSs) always append a .zip to files they
            # believe to be zip files. Remedy that:
            if base_filename.endswith(".egg.zip"):
                base_filename = base_filename[:-7] + "egg"

            # Write the zenpack to the filesystem
            tFile = open(os.path.join(tempDir, base_filename), "wb")
            tFile.write(zenpack.read())
            tFile.close()

            p = None  # zenpack install process
            # ZEN-1781: Redirect to a temporary file so the stdout buffer
            # doesn't fill up and block till you read from it.
            outFile = None
            try:
                outFile = tempfile.SpooledTemporaryFile()
                # Run zenpack install
                cmd = "zenpack --install %s --fromui" % tFile.name
                p = Popen(cmd, shell=True, stdout=outFile, stderr=STDOUT)

                endWait = time.time() + ZENPACK_INSTALL_TIMEOUT
                # Wait for install to complete, fail, or time out
                while p.poll() is None and time.time() < endWait:
                    time.sleep(1)

                if p.poll() is not None:
                    outFile.seek(0)
                    msg = outFile.read()
            finally:
                if outFile:
                    outFile.close()
                if p and p.poll() is None:
                    p.kill()
                    msg += "Zenpack install killed due to timeout"

        if REQUEST:
            # TODO: show the output in a scrollable window.
            # format command result for HTML
            # msg = '<br>'.join(line.strip() for line in msg.split('\n') if line.strip())
            log.info("Output from installing ZenPack %s:\n%s" % (zenpack.filename, msg))
            success = "ERROR" not in msg
            msg = (
                "Successfully installed ZenPack %s" % zenpack.filename
                if success
                else "Failed to install ZenPack %s. " "See event.log for details." % zenpack.filename
            )
            messaging.IMessageSender(self).sendToBrowser(
                "Zenpack", msg, priority=messaging.INFO if success else messaging.CRITICAL
            )
            return self.callZenScreen(REQUEST)
예제 #4
0
파일: zenpack.py 프로젝트: c0ns0le/zenoss-4
    def preInstallCheck(self, eggInstall=True):
        """Check that prerequisite zenpacks are installed.
        Return True if no prereqs specified or if they are present.
        False otherwise.
        """
        if eggInstall:
            installedPacks = dict((pack.id, pack.version) \
                             for pack in self.dataroot.ZenPackManager.packs())

            if self.options.installPackName.lower().endswith('.egg'):
                # standard prebuilt egg
                zf = ZipFile(self.options.installPackName)
                if 'EGG-INFO/requires.txt' in zf.namelist():
                    reqZenpacks = zf.read('EGG-INFO/requires.txt').split('\n')
                else:
                    return True
            else:
                # source egg, no prebuilt egg-info
                with get_temp_dir() as tempEggDir:
                    cmd = '%s setup.py egg_info -e %s' % \
                                                (binPath('python'), tempEggDir)
                    subprocess.call(cmd, shell=True,
                                    stdout=open('/dev/null', 'w'),
                                    cwd=self.options.installPackName)

                    eggRequires = os.path.join(tempEggDir,
                                    self.options.installPackName + '.egg-info',
                                    'requires.txt')
                    if os.path.isfile(eggRequires):
                        reqZenpacks = open(eggRequires, 'r').read().split('\n')
                    else:
                        return True

            prereqsMet = True
            for req in reqZenpacks:
                for parsed_req in parse_requirements([req]):
                    installed_version = installedPacks.get(parsed_req.project_name, None)
                    if installed_version is None:
                        self.log.error('Zenpack %s requires %s' %
                              (self.options.installPackName, parsed_req))
                        prereqsMet = False
                    else:
                        if not installed_version in parsed_req:
                            self.log.error(
                                'Zenpack %s requires %s, found: %s' %
                                (self.options.installPackName, parsed_req, installed_version))
                            prereqsMet = False
            return prereqsMet

        if os.path.isfile(self.options.installPackName):
            zf = ZipFile(self.options.installPackName)
            for name in zf.namelist():
                if name.endswith == '/%s' % CONFIG_FILE:
                    sio = StringIO(zf.read(name))
            else:
                return True
        else:
            name = os.path.join(self.options.installPackName, CONFIG_FILE)
            if os.path.isfile(name):
                fp = open(name)
                sio = StringIO(fp.read())
                fp.close()
            else:
                return True

        parser = ConfigParser.SafeConfigParser()
        parser.readfp(sio, name)
        if parser.has_section(CONFIG_SECTION_ABOUT) \
            and parser.has_option(CONFIG_SECTION_ABOUT, 'requires'):
            requires = eval(parser.get(CONFIG_SECTION_ABOUT, 'requires'))
            if not isinstance(requires, list):
                requires = [zp.strip() for zp in requires.split(',')]
            missing = [zp for zp in requires
                    if zp not in self.dataroot.ZenPackManager.packs.objectIds()]
            if missing:
                self.log.error('ZenPack %s was not installed because'
                                % self.options.installPackName
                                + ' it requires the following ZenPack(s): %s'
                                % ', '.join(missing))
                return False
        return True