debuggers.hg

view tools/python/xen/util/bugtool.py @ 0:7d21f7218375

Exact replica of unstable on 051908 + README-this
author Mukesh Rathor
date Mon May 19 15:34:57 2008 -0700 (2008-05-19)
parents
children
line source
1 #!/usr/bin/env python
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of version 2.1 of the GNU Lesser General Public
5 # License as published by the Free Software Foundation.
6 #
7 # This library is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 # Lesser General Public License for more details.
11 #
12 # You should have received a copy of the GNU Lesser General Public
13 # License along with this library; if not, write to the Free Software
14 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 #
16 # Copyright (c) 2005, XenSource Ltd.
19 import errno
20 import getpass
21 import httplib
22 import re
23 import os
24 import os.path
25 import StringIO
26 import sys
27 import tarfile
28 import tempfile
29 import time
30 import urllib
32 import xen.lowlevel.xc
34 from xen.xend import encode
37 SERVER = 'bugzilla.xensource.com'
38 SHOW_BUG_PATTERN = 'http://%s/bugzilla/show_bug.cgi?id=%%d' % SERVER
39 ATTACH_PATTERN = \
40 'http://%s/bugzilla/attachment.cgi?bugid=%%d&action=enter' % SERVER
42 TITLE_RE = re.compile(r'<title>(.*)</title>')
44 FILES_TO_SEND = [ '/var/log/' + x for x in
45 [ 'syslog', 'messages', 'debug',
46 'xen/xend-debug.log', 'xen/xenstored-trace.log',
47 'xen/xen-hotplug.log', 'xen/xend.log' ] +
48 [ 'xen/xend.log.%d' % z for z in range(1,6) ] ]
49 #FILES_TO_SEND = [ ]
52 def main(argv = None):
53 if argv is None:
54 argv = sys.argv
56 print '''
57 This application will collate the Xen dmesg output, details of the hardware
58 configuration of your machine, information about the build of Xen that you are
59 using, plus, if you allow it, various logs.
61 The information collated can either be posted to a Xen Bugzilla bug (this bug
62 must already exist in the system, and you must be a registered user there), or
63 it can be saved as a .tar.bz2 for sending or archiving.
65 The collated logs may contain private information, and if you are at all
66 worried about that, you should exit now, or you should explicitly exclude
67 those logs from the archive.
69 '''
71 bugball = []
73 xc = xen.lowlevel.xc.xc()
75 def do(n, f):
76 try:
77 s = f()
78 except Exception, exn:
79 s = str(exn)
80 bugball.append(string_iterator(n, s))
82 do('xen-dmesg', lambda: xc.readconsolering())
83 do('physinfo', lambda: prettyDict(xc.physinfo()))
84 do('xeninfo', lambda: prettyDict(xc.xeninfo()))
86 for filename in FILES_TO_SEND:
87 if not os.path.exists(filename):
88 continue
90 if yes('Include %s? [Y/n] ' % filename):
91 bugball.append(file(filename))
93 maybeAttach(bugball)
95 if (yes('''
96 Do you wish to save these details as a tarball (.tar.bz2)? [Y/n] ''')):
97 tar(bugball)
99 return 0
102 def maybeAttach(bugball):
103 if not yes('''
104 Do you wish to attach these details to a Bugzilla bug? [Y/n] '''):
105 return
107 bug = int(raw_input('Bug number? '))
109 bug_title = getBugTitle(bug)
111 if bug_title == 'Search by bug number' or bug_title == 'Invalid Bug ID':
112 print >>sys.stderr, 'Bug %d does not exist!' % bug
113 maybeAttach(bugball)
114 elif yes('Are you sure that you want to attach to %s? [Y/n] ' %
115 bug_title):
116 attach(bug, bugball)
117 else:
118 maybeAttach(bugball)
121 def attach(bug, bugball):
122 username = raw_input('Bugzilla username: ')
123 password = getpass.getpass('Bugzilla password: ')
125 conn = httplib.HTTPConnection(SERVER)
126 try:
127 for f in bugball:
128 send(bug, conn, f, f.name, username, password)
129 finally:
130 conn.close()
133 def getBugTitle(bug):
134 f = urllib.urlopen(SHOW_BUG_PATTERN % bug)
136 try:
137 for line in f:
138 m = TITLE_RE.search(line)
139 if m:
140 return m.group(1)
141 finally:
142 f.close()
144 raise "Could not find title of bug %d!" % bug
147 def send(bug, conn, fd, filename, username, password):
149 print "Attaching %s to bug %d." % (filename, bug)
151 headers, data = encode.encode_data(
152 { 'bugid' : str(bug),
153 'action' : 'insert',
154 'data' : fd,
155 'description' : '%s from %s' % (filename, username),
156 'contenttypeselection' : 'text/plain',
157 'contenttypemethod' : 'list',
158 'ispatch' : '0',
159 'GoAheadAndLogIn' : '1',
160 'Bugzilla_login' : username,
161 'Bugzilla_password' : password,
162 })
164 conn.request('POST',ATTACH_PATTERN % bug, data, headers)
165 response = conn.getresponse()
166 try:
167 body = response.read()
168 m = TITLE_RE.search(body)
170 if response.status != 200:
171 print >>sys.stderr, (
172 'Attach failed: %s %s.' % (response.status, response.reason))
173 elif not m or m.group(1) != 'Changes Submitted':
174 print >>sys.stderr, (
175 'Attach failed: got a page titled %s.' % m.group(1))
176 else:
177 print "Attaching %s to bug %d succeeded." % (filename, bug)
178 finally:
179 response.close()
182 def tar(bugball):
183 filename = raw_input('Tarball destination filename? ')
185 now = time.time()
187 tf = tarfile.open(filename, 'w:bz2')
189 try:
190 for f in bugball:
191 ti = tarfile.TarInfo(f.name.split('/')[-1])
192 if hasattr(f, 'size'):
193 ti.size = f.size()
194 else:
195 ti.size = os.stat(f.name).st_size
197 ti.mtime = now
198 ti.type = tarfile.REGTYPE
199 ti.uid = 0
200 ti.gid = 0
201 ti.uname = 'root'
202 ti.gname = 'root'
204 f.seek(0) # If we've added this file to a bug, it will have been
205 # read once already, so reset it.
206 tf.addfile(ti, f)
207 finally:
208 tf.close()
210 print 'Writing tarball %s successful.' % filename
213 def prettyDict(d):
214 format = '%%-%ds: %%s' % max(map(len, [k for k, _ in d.items()]))
215 return '\n'.join([format % i for i in d.items()]) + '\n'
218 class string_iterator(StringIO.StringIO):
219 def __init__(self, name, val):
220 StringIO.StringIO.__init__(self, val)
221 self.name = name
223 def size(self):
224 return len(self.getvalue())
227 def yes(prompt):
228 yn = raw_input(prompt)
230 return len(yn) == 0 or yn.lower()[0] == 'y'
233 if __name__ == "__main__":
234 sys.exit(main())