ia64/xen-unstable

view tools/python/xen/util/bugtool.py @ 10720:8922c1fbe684

[XM][ACM] Add xm subcommands to work with security resource labels.

This patch adds new xm subcommands to support working with resource
labels. The new subcommands are 'xm resources', 'xm rmlabel', 'xm
getlabel' and 'xm dry-run'. In addition, the 'xm addlabel' subcommand
now uses an updated syntax to support labeling both domains and
resources. See the xm man page for details on each subcommand.

Beyond the new subcommands, this patch allows users to immediately see
when security checks will fail by pushing some basic security checking
into the beginning of 'xm create' and 'xm block-attach'. ACM security
attributes for block devices are added to XenStore in order to support
the final security enforcement, which will be performed in the kernel
and included in a separate patch.

Signed-off-by: Bryan D. Payne <bdpayne@us.ibm.com>
Signed-off-by: Reiner Sailer <sailer@us.ibm.com>
author kfraser@localhost.localdomain
date Mon Jul 10 17:18:07 2006 +0100 (2006-07-10)
parents 1caed7031f6b
children 3798ec84431d
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 'xend.log', 'xend-debug.log', 'xenstored-trace.log',
47 'xen-hotplug.log' ] ]
48 #FILES_TO_SEND = [ ]
51 def main(argv = None):
52 if argv is None:
53 argv = sys.argv
55 print '''
56 This application will collate the Xen dmesg output, details of the hardware
57 configuration of your machine, information about the build of Xen that you are
58 using, plus, if you allow it, various logs.
60 The information collated can either be posted to a Xen Bugzilla bug (this bug
61 must already exist in the system, and you must be a registered user there), or
62 it can be saved as a .tar.bz2 for sending or archiving.
64 The collated logs may contain private information, and if you are at all
65 worried about that, you should exit now, or you should explicitly exclude
66 those logs from the archive.
68 '''
70 bugball = []
72 xc = xen.lowlevel.xc.xc()
74 def do(n, f):
75 try:
76 s = f()
77 except Exception, exn:
78 s = str(exn)
79 bugball.append(string_iterator(n, s))
81 do('xen-dmesg', lambda: xc.readconsolering())
82 do('physinfo', lambda: prettyDict(xc.physinfo()))
83 do('xeninfo', lambda: prettyDict(xc.xeninfo()))
85 for filename in FILES_TO_SEND:
86 if not os.path.exists(filename):
87 continue
89 if yes('Include %s? [Y/n] ' % filename):
90 bugball.append(file(filename))
92 maybeAttach(bugball)
94 if (yes('''
95 Do you wish to save these details as a tarball (.tar.bz2)? [Y/n] ''')):
96 tar(bugball)
98 return 0
101 def maybeAttach(bugball):
102 if not yes('''
103 Do you wish to attach these details to a Bugzilla bug? [Y/n] '''):
104 return
106 bug = int(raw_input('Bug number? '))
108 bug_title = getBugTitle(bug)
110 if bug_title == 'Search by bug number' or bug_title == 'Invalid Bug ID':
111 print >>sys.stderr, 'Bug %d does not exist!' % bug
112 maybeAttach(bugball)
113 elif yes('Are you sure that you want to attach to %s? [Y/n] ' %
114 bug_title):
115 attach(bug, bugball)
116 else:
117 maybeAttach(bugball)
120 def attach(bug, bugball):
121 username = raw_input('Bugzilla username: ')
122 password = getpass.getpass('Bugzilla password: ')
124 conn = httplib.HTTPConnection(SERVER)
125 try:
126 for f in bugball:
127 send(bug, conn, f, f.name, username, password)
128 finally:
129 conn.close()
132 def getBugTitle(bug):
133 f = urllib.urlopen(SHOW_BUG_PATTERN % bug)
135 try:
136 for line in f:
137 m = TITLE_RE.search(line)
138 if m:
139 return m.group(1)
140 finally:
141 f.close()
143 raise "Could not find title of bug %d!" % bug
146 def send(bug, conn, fd, filename, username, password):
148 print "Attaching %s to bug %d." % (filename, bug)
150 headers, data = encode.encode_data(
151 { 'bugid' : str(bug),
152 'action' : 'insert',
153 'data' : fd,
154 'description' : '%s from %s' % (filename, username),
155 'contenttypeselection' : 'text/plain',
156 'contenttypemethod' : 'list',
157 'ispatch' : '0',
158 'GoAheadAndLogIn' : '1',
159 'Bugzilla_login' : username,
160 'Bugzilla_password' : password,
161 })
163 conn.request('POST',ATTACH_PATTERN % bug, data, headers)
164 response = conn.getresponse()
165 try:
166 body = response.read()
167 m = TITLE_RE.search(body)
169 if response.status != 200:
170 print >>sys.stderr, (
171 'Attach failed: %s %s.' % (response.status, response.reason))
172 elif not m or m.group(1) != 'Changes Submitted':
173 print >>sys.stderr, (
174 'Attach failed: got a page titled %s.' % m.group(1))
175 else:
176 print "Attaching %s to bug %d succeeded." % (filename, bug)
177 finally:
178 response.close()
181 def tar(bugball):
182 filename = raw_input('Tarball destination filename? ')
184 now = time.time()
186 tf = tarfile.open(filename, 'w:bz2')
188 try:
189 for f in bugball:
190 ti = tarfile.TarInfo(f.name.split('/')[-1])
191 if hasattr(f, 'size'):
192 ti.size = f.size()
193 else:
194 ti.size = os.stat(f.name).st_size
196 ti.mtime = now
197 ti.type = tarfile.REGTYPE
198 ti.uid = 0
199 ti.gid = 0
200 ti.uname = 'root'
201 ti.gname = 'root'
203 f.seek(0) # If we've added this file to a bug, it will have been
204 # read once already, so reset it.
205 tf.addfile(ti, f)
206 finally:
207 tf.close()
209 print 'Writing tarball %s successful.' % filename
212 def prettyDict(d):
213 format = '%%-%ds: %%s' % max(map(len, [k for k, _ in d.items()]))
214 return '\n'.join([format % i for i in d.items()]) + '\n'
217 class string_iterator(StringIO.StringIO):
218 def __init__(self, name, val):
219 StringIO.StringIO.__init__(self, val)
220 self.name = name
222 def size(self):
223 return len(self.getvalue())
226 def yes(prompt):
227 yn = raw_input(prompt)
229 return len(yn) == 0 or yn.lower()[0] == 'y'
232 if __name__ == "__main__":
233 sys.exit(main())