source: trunk/packages/xen-3.1/xen-3.1/tools/python/xen/util/bugtool.py @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

  • Property svn:mime-type set to text/script
File size: 6.4 KB
Line 
1#!/usr/bin/env python
2
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.
17
18
19import errno
20import getpass
21import httplib
22import re
23import os
24import os.path
25import StringIO
26import sys
27import tarfile
28import tempfile
29import time
30import urllib
31
32import xen.lowlevel.xc
33
34from xen.xend import encode
35
36
37SERVER = 'bugzilla.xensource.com'
38SHOW_BUG_PATTERN = 'http://%s/bugzilla/show_bug.cgi?id=%%d' % SERVER
39ATTACH_PATTERN = \
40 'http://%s/bugzilla/attachment.cgi?bugid=%%d&action=enter' % SERVER
41
42TITLE_RE = re.compile(r'<title>(.*)</title>')
43
44FILES_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 = [  ]
50
51
52def main(argv = None):
53    if argv is None:
54        argv = sys.argv
55
56    print '''
57This application will collate the Xen dmesg output, details of the hardware
58configuration of your machine, information about the build of Xen that you are
59using, plus, if you allow it, various logs.
60
61The information collated can either be posted to a Xen Bugzilla bug (this bug
62must already exist in the system, and you must be a registered user there), or
63it can be saved as a .tar.bz2 for sending or archiving.
64
65The collated logs may contain private information, and if you are at all
66worried about that, you should exit now, or you should explicitly exclude
67those logs from the archive.
68
69'''
70   
71    bugball = []
72
73    xc = xen.lowlevel.xc.xc()
74
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))
81
82    do('xen-dmesg', lambda: xc.readconsolering())
83    do('physinfo',  lambda: prettyDict(xc.physinfo()))
84    do('xeninfo',   lambda: prettyDict(xc.xeninfo()))
85
86    for filename in FILES_TO_SEND:
87        if not os.path.exists(filename):
88            continue
89
90        if yes('Include %s? [Y/n] ' % filename):
91            bugball.append(file(filename))
92
93    maybeAttach(bugball)
94
95    if (yes('''
96Do you wish to save these details as a tarball (.tar.bz2)? [Y/n] ''')):
97        tar(bugball)
98
99    return 0
100
101
102def maybeAttach(bugball):
103    if not yes('''
104Do you wish to attach these details to a Bugzilla bug? [Y/n] '''):
105        return
106
107    bug = int(raw_input('Bug number? '))
108
109    bug_title = getBugTitle(bug)
110
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)
119
120
121def attach(bug, bugball):
122    username = raw_input('Bugzilla username: ')
123    password = getpass.getpass('Bugzilla password: ')
124
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()
131
132
133def getBugTitle(bug):
134    f = urllib.urlopen(SHOW_BUG_PATTERN % bug)
135
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()
143
144    raise "Could not find title of bug %d!" % bug
145
146
147def send(bug, conn, fd, filename, username, password):
148
149    print "Attaching %s to bug %d." % (filename, bug)
150   
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          })
163   
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)
169
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()
180
181
182def tar(bugball):
183    filename = raw_input('Tarball destination filename? ')
184
185    now = time.time()
186
187    tf = tarfile.open(filename, 'w:bz2')
188
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
196
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'
203
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()
209
210    print 'Writing tarball %s successful.' % filename
211
212
213def 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'
216
217
218class string_iterator(StringIO.StringIO):
219    def __init__(self, name, val):
220        StringIO.StringIO.__init__(self, val)
221        self.name = name
222
223    def size(self):
224        return len(self.getvalue())
225
226
227def yes(prompt):
228    yn = raw_input(prompt)
229
230    return len(yn) == 0 or yn.lower()[0] == 'y'
231
232
233if __name__ == "__main__":
234    sys.exit(main())
Note: See TracBrowser for help on using the repository browser.