[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Added xen-bugtool, an application that collects various system logs and can



# HG changeset patch
# User emellor@xxxxxxxxxxxxxxxxxxxxxx
# Node ID c5ee3b6f25b3edc4780a919a918648adfbc62585
# Parent  eb1169f92d8132ed513e059cace86d5510cdf692
Added xen-bugtool, an application that collects various system logs and can
save them as a tarball, or submit them to a pre-existing bugzilla bug.

Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>

diff -r eb1169f92d81 -r c5ee3b6f25b3 tools/misc/Makefile
--- a/tools/misc/Makefile       Sun Nov 27 13:09:46 2005
+++ b/tools/misc/Makefile       Mon Nov 28 01:47:28 2005
@@ -16,7 +16,7 @@
 TARGETS  = xenperf xc_shadow
 
 INSTALL_BIN  = $(TARGETS) xencons
-INSTALL_SBIN = netfix xm xend xenperf
+INSTALL_SBIN = netfix xm xen-bugtool xend xenperf
 
 all: build
 build: $(TARGETS)
diff -r eb1169f92d81 -r c5ee3b6f25b3 tools/misc/xen-bugtool
--- /dev/null   Sun Nov 27 13:09:46 2005
+++ b/tools/misc/xen-bugtool    Mon Nov 28 01:47:28 2005
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+
+#  -*- mode: python; -*-
+
+# Copyright (c) 2005, XenSource Ltd.
+
+import sys
+
+sys.path.append('/usr/lib/python')
+sys.path.append('/usr/lib64/python')
+
+from xen.util import bugtool
+
+
+if __name__ == "__main__":
+    try:
+        sys.exit(bugtool.main())
+    except KeyboardInterrupt:
+        print "\nInterrupted."
+        sys.exit(1)
diff -r eb1169f92d81 -r c5ee3b6f25b3 tools/python/xen/util/bugtool.py
--- /dev/null   Sun Nov 27 13:09:46 2005
+++ b/tools/python/xen/util/bugtool.py  Mon Nov 28 01:47:28 2005
@@ -0,0 +1,242 @@
+#!/usr/bin/env python
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+# Copyright (c) 2005, XenSource Ltd.
+
+
+import errno
+import getpass
+import httplib
+import re
+import os
+import os.path
+import sys
+import tarfile
+import tempfile
+import time
+import urllib
+
+import xen.lowlevel.xc
+
+from xen.xend import encode
+
+
+SERVER = 'bugzilla.xensource.com'
+SHOW_BUG_PATTERN = 'http://%s/bugzilla/show_bug.cgi?id=%%d' % SERVER
+ATTACH_PATTERN = \
+ 'http://%s/bugzilla/attachment.cgi?bugid=%%d&action=enter' % SERVER
+
+TITLE_RE = re.compile(r'<title>(.*)</title>')
+
+FILES_TO_SEND = [ '/var/log/syslog', '/var/log/messages', '/var/log/debug',
+                  '/var/log/xend.log', '/var/log/xend-debug.log',
+                  '/var/log/xenstored-trace.log' ]
+#FILES_TO_SEND = [  ]
+
+
+def main(argv = None):
+    if argv is None:
+        argv = sys.argv
+
+    print '''
+This application will collate the Xen dmesg output, details of the hardware
+configuration of your machine, information about the build of Xen that you are
+using, plus, if you allow it, various logs.  These logs may contain private
+information, and if you are at all worried about that, you should exit now.
+
+The information collated can either be posted to a Xen Bugzilla bug (this bug
+must already exist in the system, and you must be a registered user there), or
+it can be saved as a .tar.bz2 for sending or archiving.
+'''
+    
+    bugball = []
+
+    xc = xen.lowlevel.xc.xc()
+    bugball.append(string_iterator('xen-dmesg', xc.readconsolering()))
+    bugball.append(string_iterator('physinfo',  prettyDict(xc.physinfo())))
+    bugball.append(string_iterator('xeninfo',   prettyDict(xc.xeninfo())))
+    del xc
+
+    for filename in FILES_TO_SEND:
+        if not os.path.exists(filename):
+            continue
+
+        if yes('Include %s? [Y/n] ' % filename):
+            bugball.append(file(filename))
+
+    maybeAttach(bugball)
+
+    if (yes('''
+Do you wish to save these details as a tarball (.tar.bz2)? [Y/n] ''')):
+        tar(bugball)
+
+    return 0
+
+
+def maybeAttach(bugball):
+    if not yes('''
+Do you wish to attach these details to a Bugzilla bug? [Y/n] '''):
+        return
+
+    bug = int(raw_input('Bug number? '))
+
+    bug_title = getBugTitle(bug)
+
+    if bug_title == 'Search by bug number' or bug_title == 'Invalid Bug ID':
+        print >>sys.stderr, 'Bug %d does not exist!' % bug
+        maybeAttach(bugball)
+    elif yes('Are you sure that you want to attach to %s? [Y/n] ' %
+             bug_title):
+        attach(bug, bugball)
+    else:
+        maybeAttach(bugball)
+
+
+def attach(bug, bugball):
+    username = raw_input('Bugzilla username: ')
+    password = getpass.getpass('Bugzilla password: ')
+
+    conn = httplib.HTTPConnection(SERVER)
+    try:
+        for f in bugball:
+            send(bug, conn, f, f.name, username, password)
+    finally:
+        conn.close()
+
+
+def getBugTitle(bug):
+    f = urllib.urlopen(SHOW_BUG_PATTERN % bug)
+
+    try:
+        for line in f:
+            m = TITLE_RE.search(line)
+            if m:
+                return m.group(1)
+    finally:
+        f.close()
+
+    raise "Could not find title of bug %d!" % bug
+
+
+def send(bug, conn, fd, filename, username, password):
+
+    print "Attaching %s to bug %d." % (filename, bug)
+    
+    headers, data = encode.encode_data(
+        { 'bugid'                : str(bug),
+          'action'               : 'insert',
+          'data'                 : fd,
+          'description'          : '%s from %s' % (filename, username),
+          'contenttypeselection' : 'text/plain',
+          'contenttypemethod'    : 'list',
+          'ispatch'              : '0',
+          'GoAheadAndLogIn'      : '1',
+          'Bugzilla_login'       : username,
+          'Bugzilla_password'    : password,
+          })
+    
+    conn.request('POST',ATTACH_PATTERN % bug, data, headers)
+    response = conn.getresponse()
+    try:
+        body = response.read()
+        m = TITLE_RE.search(body)
+
+        if response.status != 200:
+            print >>sys.stderr, (
+                'Attach failed: %s %s.' % (response.status, response.reason))
+        elif not m or m.group(1) != 'Changes Submitted':
+            print >>sys.syderr, (
+                'Attach failed: got a page titled %s.' % m.group(1))
+        else:
+            print "Attaching %s to bug %d succeeded." % (filename, bug)
+    finally:
+        response.close()
+
+
+def tar(bugball):
+    filename = raw_input('Tarball destination filename? ')
+
+    now = time.time()
+
+    tf = tarfile.open(filename, 'w:bz2')
+
+    try:
+        for f in bugball:
+            ti = tarfile.TarInfo(f.name.split('/')[-1])
+            if hasattr(f, 'size'):
+                ti.size = f.size()
+            else:
+                ti.size = os.stat(f.name).st_size
+
+            ti.mtime = now
+            ti.type = tarfile.REGTYPE
+            ti.uid = 0
+            ti.gid = 0
+            ti.uname = 'root'
+            ti.gname = 'root'
+
+            f.seek(0) # If we've added this file to a bug, it will have been
+                      # read once already, so reset it.
+            tf.addfile(ti, f)
+    finally:
+        tf.close()
+
+    print 'Writing tarball %s successful.' % filename
+
+
+def prettyDict(d):
+    format = '%%-%ds: %%s' % max(map(len, [k for k, _ in d.items()]))
+    return '\n'.join([format % i for i in d.items()]) + '\n'
+
+
+class string_iterator:
+    def __init__(self, name, val):
+        self.name = name
+        self.val = val
+        self.vallist = val.splitlines(True)
+        self.line = 0
+    
+    def readlines(self):
+        return self.vallist
+
+    def readline(self):
+        result = self.vallist[line]
+        line += 1
+        return result
+
+    def read(self, n = None):
+        if n is None:
+            return self.val
+        else:
+            return self.val[0:n]
+
+    def close(self):
+        pass
+
+    def size(self):
+        return len(self.val)
+
+    def seek(self, _1, _2 = None):
+        pass
+
+
+def yes(prompt):
+    yn = raw_input(prompt)
+
+    return len(yn) == 0 or yn.lower()[0] == 'y'
+
+
+if __name__ == "__main__":
+    sys.exit(main())

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.