https://t.me/AnonymousX5
Server : Apache
System : Linux cvar2.toservers.com 3.10.0-962.3.2.lve1.5.73.el7.x86_64 #1 SMP Wed Aug 24 21:31:23 UTC 2022 x86_64
User : njnconst ( 1116)
PHP Version : 8.4.18
Disable Function : NONE
Directory :  /usr/lib/python2.7/site-packages/redhat_support_tool/plugins/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //usr/lib/python2.7/site-packages/redhat_support_tool/plugins/btextract.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 optparse import Option
from redhat_support_tool.helpers.confighelper import _
from redhat_support_tool.helpers.constants import Constants
from redhat_support_tool.helpers.launchhelper import LaunchHelper
from redhat_support_tool.helpers.vmcorehelper import VMCore
from redhat_support_tool.plugins import InteractivePlugin, DisplayOption, \
                                        ObjectDisplayOption
from redhat_support_tool.plugins.add_attachment import AddAttachment
from redhat_support_tool.plugins.add_comment import AddComment
from redhat_support_tool.plugins.get_kerneldebug import GetKernelDebugPackages
from redhat_support_tool.plugins.diagnose import Diagnose
from redhat_support_tool.plugins.open_case import OpenCase
import logging
import os.path
import pydoc
import redhat_support_tool.helpers.common as common
import redhat_support_tool.helpers.apihelper as apihelper
import redhat_support_tool.helpers.vmcorehelper as vmcorehelper
import redhat_support_tool.helpers.confighelper as confighelper
# pylint: disable=W0402
import string
import subprocess
import tempfile

__author__ = 'Keith Robertson <kroberts@redhat.com>'
logger = logging.getLogger("redhat_support_tool.plugins.btextract")


class BTExtract(InteractivePlugin):
    plugin_name = 'btextract'
    _submenu_opts = None
    _sections = None
    end_of_entries = ''
    vmcore = None
    mkdumpfilepath = None
    # Should interactive_plugin/non_interactive_plugin skip output methods?
    no_submenu = False

    @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 [options] </path/to/vmcore>')

    @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 get a kernel stack backtrace and '
                 'other related information from a kernel core dump file. '
                 'The default behavior is to issue \'bt -a\'; however, there '
                 'are a variety of other \'crash\' '
                 'commands that can be run.') % 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:
  - %s /var/crash/vmcore""") \
  % (cls.plugin_name)

    @classmethod
    def get_options(cls):
        '''
        Subclasses that need command line options should override this method
        and return an array of optparse.Option(s) to be used by the
        OptionParser.

        Example:
         return [Option("-f", "--file", action="store",
                        dest="filename", help='Some file'),
                 Option("-c", "--case",
                        action="store", dest="casenumber",
                        help='A case')]

         Would produce the following:
         Command (? for help): help mycommand

         Usage: mycommand [options]

         Use the 'mycommand' command to find a knowledge base solution by ID
         Options:
           -h, --help  show this help message and exit
           -f, --file  Some file
           -c, --case  A case
         Example:
          - mycommand -c 12345 -f abc.txt

        '''
        return [Option('-c', '--case', dest='casenumber',
                        help=_('Add the collected data as a comment to the '
                               'provided case.'),
                        default=None),
                Option("-a", "--all", dest="all",
                    action="store_true",
                    help=_('Run all options. Equals -aeflpFi'),
                    default=False),
                Option("-e", "--exframe", dest="exframe",
                    action="store_true",
                    help=_('Search the stack for possible kernel and user '
                           'mode exception frames (ie. bt -e).'),
                    default=False),
                Option("-f", "--foreachbt", dest="foreachbt",
                    action="store_true",
                    help=_('Display the stack traces for all tasks '
                           '(ie. foreach bt).'),
                    default=False),
                Option("-l", "--log", dest="log",
                    action="store_true",
                    help=_('Dumps the kernel log_buf contents in '
                           'chronological order.'),
                    default=False),
                Option("-p", "--ps", dest="ps",
                    action="store_true",
                    help=_('Displays process status for selected processes '
                           'in the system.'),
                    default=False),
                Option("-F", "--files", dest="files",
                    action="store_true",
                    help=_('Displays information about open files.'),
                    default=False),
                Option("-i", "--cmdfile", dest="cmdfile",
                    help=_('Run a sequence of individual \'crash\' commands '
                           'from a file.'),
                    default=None)]

    def get_intro_text(self):
        return _('\nSelect the crash command output to view or \'e\' '
                 'to return to the previous menu.')

    def get_sub_menu_options(self):
        return self._submenu_opts

    def _check_vmcore(self, filename):
        '''
        Will create a VMCore object from a given core file
        or throw an exception if crash has a problem inspecting the
        core file for OSRELEASE.
        '''
        self.vmcore = VMCore(filename)

    def _find_debug_symbols(self):
        '''
        At this point self.vmcore had better be non-null.  This
        method will call vmcorehelper's get_debug_symbols which scans
        the designated debug symbols directory looking for debug symbols
        which match the given core file.  If symbols are found, the
        VMCore object will be passed a VMLinux object.
        '''
        kernelext_dir = confighelper.get_config_helper().get(
                                            option='kern_debug_dir')
        vmlinux = vmcorehelper.get_debug_symbols(
                                kernelext_dir, self.vmcore.getKernelVersion())
        if vmlinux:
            self.vmcore.setDebugSymbols(vmlinux)
        else:
            print _('WARNING: Debug symbols for %s were not found.') % \
                    self._args[0]
            line = raw_input(_('Would you like to install kernel-debuginfo-%s '
                    'from available debug repositories (y/n)? ') % \
                    self.vmcore.getKernelVersion())
            if str(line).strip().lower() == 'y':
                print _('Installing kernel-debuginfo-%s') % \
                    self.vmcore.getKernelVersion()
                lh = LaunchHelper(GetKernelDebugPackages)
                lh.run(self.vmcore.getKernelVersion(),
                       pt_exception=True)
                vmlinux = vmcorehelper.get_debug_symbols(
                                kernelext_dir, self.vmcore.getKernelVersion())
                if vmlinux:
                    self.vmcore.setDebugSymbols(vmlinux)
                else:
                    raise Exception(_('Installation of debug images failed, '
                                      'cannot proceed with debug session'))
            else:
                raise Exception('User elected not to install debug '
                                'packages for kernel-debuginfo-%s' % \
                                self.vmcore.getKernelVersion())

    def validate_args(self):
        if not self._args:
            msg = _('ERROR: %s requires the full path to a kernel core dump '
                    'file.') % self.plugin_name
            print msg
            raise Exception(msg)
        self._check_vmcore(self._args[0])
        try:
            self._find_debug_symbols()
        except Exception, e:
            logger.log(logging.DEBUG, e)
            if os.path.exists('/usr/sbin/makedumpfile'):
                self.mkdumpfilepath = '/usr/sbin/makedumpfile'
            elif os.path.exists('/sbin/makedumpfile'):
                self.mkdumpfilepath = '/sbin/makedumpfile'
            else:
                raise

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

        # If we had to fallback on makedumpfile, lets run it.
        if self.mkdumpfilepath:
            self._mkdumpfile_log_fallback()
        else:
            try:
                self._execute_bt_commands()
            except Exception, e:
                msg = _('ERROR: %s') % e
                print msg
                logger.log(logging.ERROR, msg)
                raise e

        try:
            if self._options['casenumber']:
                # pylint: disable=W0141
                for opt in self._submenu_opts:
                    # Remove nonprintable characters from the
                    # crash output.  Argh!!!!
                    filtered_string = filter(lambda x: x in string.printable,
                                             self._sections[opt])
                    msg = None

                    # If the filtered_string is too long (comments can only be
                    # ~30k when formatting is applied, plus 20k is a large
                    # chunk of text) attach it instead.
                    if len(filtered_string) > 20000:
                        try:
                            # Because we can't rename on the fly attachments,
                            # this filename is going to look 'odd'.
                            fd, temppath = tempfile.mkstemp(
                                                        prefix="vmcoreinfo-",
                                                        suffix="-rhst")
                            attachment = os.fdopen(fd, "w")
                            attachment.write(filtered_string)
                            attachment.close()
                            lh = LaunchHelper(AddAttachment)
                            lh.run('-c %s --description="%s" %s' % (
                                                self._options['casenumber'],
                                                opt.display_text.encode(
                                                        "UTF-8", 'replace'),
                                                temppath))

                            os.remove(temppath)
                            msg = 'The attachment %s was uploaded by Red Hat' \
                                  ' Support Tool from the VMCore %s' % \
                                  (os.path.basename(temppath),
                                   self.vmcore.coreFilename)
                        except:
                            print _('Unable to upload output to Red Hat'
                                    ' Customer Portal, reverting to displaying'
                                    ' output to console.')
                    else:
                        msg = '%s\nThe following comment was added by ' \
                              'Red Hat Support Tool\nVersion: %s\n' \
                              '%s\n\n%s' % \
                              (str(self.ruler * Constants.MAX_RULE),
                               apihelper.USER_AGENT,
                               str(self.ruler * Constants.MAX_RULE),
                               filtered_string)

                    if msg:
                        lh = LaunchHelper(AddComment)
                        lh.run('-c %s "%s"' % (self._options['casenumber'],
                                               msg))
                        self.no_submenu = True
        except Exception, e:
            msg = _('ERROR: %s') % e
            print msg
            logger.log(logging.ERROR, msg)
            raise e

    def non_interactive_action(self):
        if self.no_submenu:
            return

        doc = u''
        for opt in self._submenu_opts:
            doc += self._sections[opt]
        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 manifest 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):
        doc = self._sections[display_option]
        pydoc.pipepager(doc.encode("UTF-8", 'replace'), cmd='less -R')

    def _mkdumpfile_log_fallback(self):
        try:
            tempdir = tempfile.mkdtemp('-rhst')
            mkdumpcmd = [self.mkdumpfilepath, "--dump-dmesg",
                         self.vmcore.coreFilename, os.path.join(tempdir,
                                                                'dmesglog')]
            ret = subprocess.call(mkdumpcmd,
                                  stderr=subprocess.STDOUT,
                                  stdout=subprocess.PIPE)
            if ret != 0:
                msg = _("Unable to get core dmesg log using alternate method.")
                raise Exception(msg)

            output = open(os.path.join(tempdir, 'dmesglog')).read()
            disp_opt = DisplayOption(_('Kernel log buffer (dmesg) logs'),
                                     'interactive_action')
            self._submenu_opts.append(disp_opt)
            self._sections[disp_opt] = output

            # Open a support case
            disp_opt = ObjectDisplayOption(
                                _('Open a support case with dmesg logs'),
                                '_opencase',
                                output)
            self._submenu_opts.append(disp_opt)
            self._sections[disp_opt] = output
        except:
            raise

    def _send_to_shadowman(self, display_option=None):
        lh = LaunchHelper(Diagnose)
        lh.run('', display_option)

    def _opencase(self, display_option=None):
        lh = LaunchHelper(OpenCase)
        try:
            # Remove nonprintable characters from the
            # crash output.  Argh!!!!
            filtered_string = filter(lambda x: x in string.printable,
                                     display_option.stored_obj)
            filtered_string = str(filtered_string).replace('"', ' ')
            filtered_string = str(filtered_string).replace("'", ' ')
            msg = None

            # If the filtered_string is too long (comments can only be
            # ~30k when formatting is applied, plus 20k is a large
            # chunk of text) attach it instead.
            if len(filtered_string) > 20000:
                try:
                    # Because we can't rename on the fly attachments,
                    # this filename is going to look 'odd'.
                    fd, temppath = tempfile.mkstemp(
                                                prefix="vmcoreinfo-",
                                                suffix="-rhst")
                    attachment = os.fdopen(fd, "w")
                    attachment.write(filtered_string)
                    attachment.close()
                    lh.run('--attachment=%s' % (temppath))
                    os.remove(temppath)
                except:
                    print _('Unable to upload output to Red Hat'
                            ' Customer Portal, reverting to displaying'
                            ' output to console.')
            else:
                msg = '%s\nThe following comment was added by ' \
                      'Red Hat Support Tool\nVersion: %s\n' \
                      '%s\n\n%s' % \
                      (str(self.ruler * Constants.MAX_RULE),
                       apihelper.USER_AGENT,
                       str(self.ruler * Constants.MAX_RULE),
                       filtered_string)
                lh.run('-d \'%s\'' % msg)

        except Exception, e:
            msg = _('ERROR: %s') % e
            print msg
            logger.log(logging.ERROR, msg)

    def _execute_bt_commands(self):
        '''
        A utility method which executes the BT commands specified by the
        user.
        '''
        if self._options['all']:
            self._options['exframe'] = True
            self._options['foreachbt'] = True
            self._options['log'] = True
            self._options['ps'] = True
            self._options['files'] = True

        # Always do 'bt -a'
        output = self.vmcore.exe_crash_commands('bt -a')
        disp_opt = DisplayOption(_('Output from crash \'bt -a\''),
                                 'interactive_action')
        self._submenu_opts.append(disp_opt)
        self._sections[disp_opt] = output

        if common.is_interactive():
            # Send to Shadowman
            disp_opt = ObjectDisplayOption(_("Diagnose 'bt -a' output"),
                                           '_send_to_shadowman',
                                           output)
            self._submenu_opts.append(disp_opt)
            self._sections[disp_opt] = output

            # Open a support case
            disp_opt = ObjectDisplayOption(
                                _("Open a support case with 'bt -a' output"),
                                '_opencase',
                                output)
            self._submenu_opts.append(disp_opt)
            self._sections[disp_opt] = output

        if self._options['exframe']:
            output = self.vmcore.exe_crash_commands('bt -e')
            disp_opt = DisplayOption(_('Output from crash \'bt -e\''),
                                     'interactive_action')
            self._submenu_opts.append(disp_opt)
            self._sections[disp_opt] = output

        if self._options['foreachbt']:
            output = self.vmcore.exe_crash_commands('foreach bt')
            disp_opt = DisplayOption(_('Output from crash \'foreach bt\''),
                                     'interactive_action')
            self._submenu_opts.append(disp_opt)
            self._sections[disp_opt] = output

        if self._options['log']:
            output = self.vmcore.exe_crash_commands('log')
            disp_opt = DisplayOption(_('Output from crash \'log\''),
                                     'interactive_action')
            self._submenu_opts.append(disp_opt)
            self._sections[disp_opt] = output

        if self._options['ps']:
            output = self.vmcore.exe_crash_commands('ps')
            disp_opt = DisplayOption(_('Output from crash \'ps\''),
                                     'interactive_action')
            self._submenu_opts.append(disp_opt)
            self._sections[disp_opt] = output

        if self._options['files']:
            output = self.vmcore.exe_crash_commands('files')
            disp_opt = DisplayOption(_('Output from crash \'files\''),
                                     'interactive_action')
            self._submenu_opts.append(disp_opt)
            self._sections[disp_opt] = output

        if self._options['cmdfile']:
            try:
                file_contents = open(self._options['cmdfile'], 'r').read()
                output = self.vmcore.exe_crash_commands(file_contents)
                disp_opt = DisplayOption(_('Output from crash -i %s') % \
                                         self._options['files'],
                                         'interactive_action')
                self._submenu_opts.append(disp_opt)
                self._sections[disp_opt] = output
            except Exception, e:
                msg = _('Problem opening %s. Error is: %s') % \
                    (self._options['files'], e)
                logger.log(logging.ERROR, msg)
                raise Exception(msg)

https://t.me/AnonymousX5 - 2025