HEX
Server: Apache
System: Linux whois01.turboservers.com.au 3.10.0-962.3.2.lve1.5.87.el7.x86_64 #1 SMP Tue Jan 28 09:38:56 UTC 2025 x86_64
User: ultimatemeditati (1528)
PHP: 5.6.40
Disabled: exec,passthru,shell_exec,system
Upload Files
File: //usr/lib/python2.7/site-packages/redhat_support_tool/plugins/diagnose.py
# -*- coding: utf-8 -*-

#
# Copyright (c) 2012 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#           http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from collections import deque
from redhat_support_lib.infrastructure.errors import RequestError, \
    ConnectionError
from redhat_support_tool.helpers.confighelper import EmptyValueError, _
from redhat_support_tool.helpers.constants import Constants
from redhat_support_tool.helpers.launchhelper import LaunchHelper
from redhat_support_tool.plugins import InteractivePlugin, ObjectDisplayOption
from redhat_support_tool.plugins.kb import Kb
from urlparse import urlparse
import os
import pydoc
import redhat_support_tool.helpers.apihelper as apihelper
import redhat_support_tool.helpers.common as common
import tempfile
import logging

__author__ = 'Keith Robertson <[email protected]>'
__author__ = 'Spenser Shumaker <[email protected]>'
logger = logging.getLogger("redhat_support_tool.plugins.diagnose")


class Diagnose(InteractivePlugin):
    plugin_name = 'diagnose'
    ALL = _("Diagnose a problem")
    _submenu_opts = None
    _sections = None
    _pAry = None

    @classmethod
    def get_usage(cls):
        '''
        The usage statement that will be printed by OptionParser.

        Example:
            - %prog -c CASENUMBER [options] <comment text here>
        Important: %prog is a OptionParser built-in.  Use it!
        '''
        return _('%prog <keywords, file, or directory containing log files>')

    @classmethod
    def get_desc(cls):
        '''
        The description statement that will be printed by OptionParser.

        Example:
            - 'Use the \'%s\' command to add a comment to a case.'\
             % cls.plugin_name
        '''
        return _('Use the \'%s\' command to send a file, a directory '
                 'containing files, or plain text to Shadowman for '
                 'analysis.') % cls.plugin_name

    @classmethod
    def get_epilog(cls):
        '''
        The epilog string that will be printed by OptionParser.  Usually
        used to print an example of how to use the program.

        Example:
         Examples:
          - %s -c 12345678 Lorem ipsum dolor sit amet, consectetur adipisicing
          - %s -c 12345678
        '''
        return _("Examples:\n"
                 "- %s /var/log/jbossas/rhevm-slimmed/boot.log\n"
                 "- %s /var/spool/abrt/ccpp-2012-09-28-09:53:26-4080\n"
                 "- %s /var/log/messages\n"
                 "- %s libvirt error code: 1, message: internal error HTTP "
                 "response code 404\n") % \
                 (cls.plugin_name, cls.plugin_name,
                  cls.plugin_name, cls.plugin_name)

    def get_intro_text(self):
        return _('\nType the number of the solution to view or \'e\' '
                 'to return to the previous menu.')

    def get_prompt_text(self):
        return _('Select a Solution: ')

    def get_sub_menu_options(self):
        return self._submenu_opts

    def _check_input(self):
        msg = _("ERROR: %s requires a file, directory, or text.")\
                    % self.plugin_name

        if not self._line:
            if common.is_interactive():
                userinput = []
                try:
                    print _('Please provide the file, directory, or text '
                            'to be analyzed: Ctrl-d on an empty line to '
                            'submit:')
                    while True:
                        userinput.append(raw_input())
                except EOFError:
                    # User pressed Ctrl-d
                    self._line = str('\n'.join(userinput)).strip().decode(
                                                                    'utf-8')
            else:
                print msg
                raise Exception(msg)

    def insert_obj(self, symptom):
        '''
        Allow insertion of a package object by launchhelper (when selecting
        from the list generated by list_kerneldebugs.py)
        '''
        # Expand yumdict into our YumDownloadHelper and package
        self._line = symptom

    def validate_args(self):
        # Check for required arguments.
        self._check_input()

    def postinit(self):
        self._submenu_opts = deque()
        self._sections = {}
        api = None

        try:
            api = apihelper.get_api()
            if not os.path.isfile(self._line):
                self._pAry = api.problems.diagnoseStr(self._line)
            else:
                report_file = os.path.expanduser(self._line)
                self._pAry = api.problems.diagnoseFile(report_file)

            if len(self._pAry) > 0:
                if not self._parse_problem():
                    raise Exception()
            else:
                raise Exception()
        except EmptyValueError, eve:
            msg = _('ERROR: %s') % str(eve)
            print msg
            logger.log(logging.WARNING, msg)
            raise
        except RequestError, re:
            msg = _('Unable to connect to support services API. '
                    'Reason: %s') % re.reason
            print msg
            logger.log(logging.WARNING, msg)
            raise
        except ConnectionError:
            msg = _('Problem connecting to the support services '
                    'API.  Is the service accessible from this host?')
            print msg
            logger.log(logging.WARNING, msg)
            raise
        except Exception:
            msg = _("Unable to find solutions to %s") % self._line
            print msg
            logger.log(logging.WARNING, msg)
            raise

    def non_interactive_action(self):
        doc = u''
        for opt in self._submenu_opts:
            if opt.display_text != self.ALL:
                doc += self._sections[opt]
        if doc != u'':
            try:
                print doc.encode("UTF-8", 'replace')
            # pylint: disable=W0703
            except Exception, e:
                # There are some truly bizarre errors when you pipe
                # the output from python's 'print' function with sys encoding
                # set to ascii. These errors seem to manifes when you pipe
                # to something like 'more' or 'less'.  You'll get encoding
                # errors. Curiously, you don't see them with 'grep' or
                # even simply piping to terminal.  WTF :(
                logger.log(logging.WARNING, e)
                import sys
                print doc.encode(sys.getdefaultencoding(),
                                 'replace')

    def interactive_action(self, display_option=None):
        if display_option.display_text == self.ALL:
            doc = u''
            for opt in self._submenu_opts:
                if opt.display_text != self.ALL:
                    doc += self._sections[opt]
            pydoc.pipepager(doc.encode("UTF-8", 'replace'),
                            cmd='less -R')
        else:
            sol_id = display_option.stored_obj
            lh = LaunchHelper(Kb)
            lh.run(sol_id)

    def _parse_problem(self,):
        '''
        Use this for non-interactive display of results.aAry
        '''
        # There can be duplicates in the problem array.
        # Remove them in the simplest way possible that works
        # in 2.4, 2.7, etc...
        solutions = set()

        def comparison(newsol, oldsol):
            newid = os.path.basename(newsol.get_uri())
            oldid = os.path.basename(oldsol.get_uri())
            if newid == oldid:
                return True
            else:
                return False

        try:
            for prob in self._pAry:
                links = prob.get_link()
                for link in links:
                    if len(solutions) == 0:
                        solutions.add(link)
                    else:
                        duplicate = False
                        for li in solutions:
                            if comparison(link, li):
                                duplicate = True
                                break
                        if not duplicate:
                            solutions.add(link)

            doc = u''
            for link in solutions:
                doc = u''
                parsed = urlparse(link.get_uri())
                sol_id = os.path.basename(parsed[2])
                doc += '%-8s %-70s\n' % ('%s:' % Constants.TITLE,
                                           link.get_value())
                doc += '%-8s %-70s\n' % (Constants.ID, sol_id)
                doc += '%-8s %-70s' % (Constants.URL,
                                         link.get_uri())
                doc += '\n\n%s%s%s\n\n' % (Constants.BOLD,
                                           str('-' * Constants.MAX_RULE),
                                           Constants.END)

                disp_opt_text = '[%7s] %s' % (sol_id, link.get_value())
                disp_opt = ObjectDisplayOption(disp_opt_text,
                                               'interactive_action',
                                               sol_id)
                self._submenu_opts.append(disp_opt)
                self._sections[disp_opt] = doc
                #disp_opt = DisplayOption('[' + os.path.basename(parsed[2]) +
                #                         ']  ' + link.get_value(),
                #                         'interactive_action')
                #self._submenu_opts.append(disp_opt)
                #self._sections[disp_opt] = doc
        # pylint: disable=W0703
        except Exception, e:
            msg = _('ERROR: problem parsing the attachments.')
            print msg
            logger.log(logging.WARNING, msg)
            logger.log(logging.WARNING, e)
            return False
        if(disp_opt):
            return True
        return False