summaryrefslogtreecommitdiffstats
path: root/exception.py
diff options
context:
space:
mode:
Diffstat (limited to 'exception.py')
-rw-r--r--exception.py136
1 files changed, 108 insertions, 28 deletions
diff --git a/exception.py b/exception.py
index ab01ecdf7..4572eefb7 100644
--- a/exception.py
+++ b/exception.py
@@ -51,6 +51,8 @@ class AnacondaExceptionDump:
self.value = value
self.tb = tb
+ self.tbFile = None
+
self._dumpHash = {}
# Reverse the order that tracebacks are printed so people will hopefully quit
@@ -219,6 +221,12 @@ class AnacondaExceptionDump:
return hashlib.sha256(s).hexdigest()
+ def write(self, anaconda):
+ self.tbFile = "/tmp/anacdump.txt"
+ fd = open(self.tbFile, "w")
+ self.dump(fd, anaconda)
+ fd.close()
+
# Save the traceback to a removable storage device, such as a floppy disk
# or a usb/firewire drive. If there's no filesystem on the disk/partition,
# write a vfat one.
@@ -273,8 +281,99 @@ def copyExceptionToDisk(anaconda, device):
isys.umount("/tmp/crash")
return True
-def runSaveDialog(anaconda, longTracebackFile):
- saveWin = anaconda.intf.saveExceptionWindow(anaconda, longTracebackFile)
+def saveToBugzilla(anaconda, exn, dest):
+ import bugzilla, xmlrpclib
+ import product, rpmUtils
+
+ if dest[0].strip() == "" or dest[1].strip() == "" or dest[2].strip() == "":
+ anaconda.intf.messageWindow(_("Invalid Bug Information"),
+ _("Please provide a valid username, "
+ "password, and short bug description."))
+ return False
+
+ hash = exn.hash()
+
+ if product.bugUrl.startswith("http://"):
+ bugUrl = "https://" + product.bugUrl[7:]
+ elif product.bugUrl.startswith("https://"):
+ bugUrl = product.bugUrl
+ else:
+ anaconda.intf.messageWindow(_("No bugzilla URL"),
+ _("Your distribution does not provide a "
+ "bug reporting URL, so you cannot save "
+ "your exception to a remote bug tracking "
+ "system."))
+ return False
+
+ if not exn.tbFile:
+ exn.write(anaconda)
+
+ bz = bugzilla.Bugzilla(url = "%s/xmlrpc.cgi" % bugUrl)
+
+ if not bz.login(dest[0], dest[1]):
+ anaconda.intf.messageWindow(_("Unable To Login"),
+ _("There was an error logging into %s "
+ "using the provided username and "
+ "password.") % product.bugUrl)
+ return False
+
+ # Are there any existing bugs with this hash value? If so we will just
+ # add this traceback to the bug report and put the reporter on the CC
+ # list. Otherwise, we need to create a new bug.
+ try:
+ buglist = bz.query({'status_whiteboard': hash})
+ except xmlrpclib.ProtocolError, e:
+ anaconda.intf.messageWindow(_("Unable To File Bug"),
+ _("Your bug could not be filed due to the "
+ "following error when communicating with "
+ "bugzilla:\n\n%s" % str(e)))
+ return False
+
+ # FIXME: need to handle all kinds of errors here
+ if len(buglist) == 0:
+ bug = bz.createbug(product=product.productName,
+ component="anaconda",
+ version=product.productVersion,
+ rep_platform=rpmUtils.arch.getBaseArch(),
+ bug_severity="medium",
+ priority="medium",
+ op_sys="Linux",
+ bug_file_loc="http://",
+ short_desc=dest[2],
+ comment="This bug was filed automatically by anaconda.")
+ bug.setwhiteboard("anaconda_trace_hash:%s" % hash, which="status")
+ bz.attachfile(bug.bug_id, exn.tbFile, "Attached traceback automatically from anaconda.",
+ contenttype="text/plain")
+
+ # Tell the user we created a new bug for them and that they should
+ # go add a descriptive comment.
+ anaconda.intf.messageWindow(_("Bug Created"),
+ _("A new bug has been created with your traceback attached. "
+ "Please add additional information such as what you were doing "
+ "when you encountered the bug, screenshots, and whatever else "
+ "is appropriate to the following bug:\n\n%s/%s") % (bugUrl, bug.bug_id),
+ type="custom", custom_icon="info",
+ custom_buttons=[_("_Exit installer")])
+ sys.exit(0)
+ else:
+ id = buglist[0].bug_id
+ bz.attachfile(id, exn.tbFile, "Attached traceback automatically from anaconda.",
+ contenttype="text/plain")
+ bz._updatecc(id, [dest[0]], "add")
+
+ # Tell the user which bug they've been CC'd on and that they should
+ # go add a descriptive comment.
+ anaconda.intf.messageWindow(_("Bug Updated"),
+ _("A bug with your information already exists. Your account has "
+ "been added to the CC list and your traceback added as a "
+ "comment. Please add additional descriptive information to the "
+ "following bug:\n\n%s/%s") % (bugUrl, id),
+ type="custom", custom_icon="info",
+ custom_buttons=[_("_Exit installer")])
+ sys.exit(0)
+
+def runSaveDialog(anaconda, exn):
+ saveWin = anaconda.intf.saveExceptionWindow(anaconda, exn.tbFile)
if not saveWin:
anaconda.intf.__del__()
os.kill(os.getpid(), signal.SIGKILL)
@@ -303,7 +402,7 @@ def runSaveDialog(anaconda, longTracebackFile):
elif saveWin.saveToLocal():
dest = saveWin.getDest()
try:
- shutil.copyfile("/tmp/anacdump.txt", "%s/InstallError.txt" %(dest,))
+ shutil.copyfile(exn.tbFile, "%s/InstallError.txt" %(dest,))
anaconda.intf.messageWindow(_("Dump Written"),
_("Your system's state has been successfully written to "
"the disk. The installer will now exit."),
@@ -311,30 +410,14 @@ def runSaveDialog(anaconda, longTracebackFile):
custom_buttons=[_("_Exit installer")])
sys.exit(0)
except Exception, e:
- log.error("Failed to copy anacdump.txt to %s/anacdump.txt: %s" %(dest, e))
+ log.error("Failed to copy %s to %s/anacdump.txt: %s" %(exn.tbFile, dest, e))
else:
anaconda.intf.messageWindow(_("Dump Not Written"),
_("There was a problem writing the system state to the "
"disk."))
continue
else:
- if not hasActiveNetDev() and not anaconda.intf.enableNetwork(anaconda):
- scpSucceeded = False
- else:
- scpInfo = saveWin.getDest()
- scpSucceeded = copyExceptionToRemote(anaconda.intf, scpInfo)
-
- if scpSucceeded:
- anaconda.intf.messageWindow(_("Dump Written"),
- _("Your system's state has been successfully written to "
- "the remote host. The installer will now exit."),
- type="custom", custom_icon="info",
- custom_buttons=[_("_Exit installer")])
- sys.exit(0)
- else:
- anaconda.intf.messageWindow(_("Dump Not Written"),
- _("There was a problem writing the system state to the "
- "remote host."))
+ if not saveToBugzilla(anaconda, exn, saveWin.getDest()):
continue
elif rc == EXN_CANCEL:
break
@@ -348,14 +431,11 @@ def handleException(anaconda, (type, value, tb)):
# restore original exception handler
sys.excepthook = sys.__excepthook__
+ # Save the exception file to local storage first.
exn = AnacondaExceptionDump(type, value, tb)
+ exn.write(anaconda)
text = str(exn)
- # save to local storage first
- out = open("/tmp/anacdump.txt", "w")
- exn.dump(out, anaconda)
- out.close()
-
# see if /mnt/sysimage is present and put exception there as well
if os.access("/mnt/sysimage/root", os.X_OK):
try:
@@ -371,7 +451,7 @@ def handleException(anaconda, (type, value, tb)):
except:
pass
- mainWin = anaconda.intf.mainExceptionWindow(text, "/tmp/anacdump.txt")
+ mainWin = anaconda.intf.mainExceptionWindow(text, exn.tbFile)
if not mainWin:
anaconda.intf.__del__()
os.kill(os.getpid(), signal.SIGKILL)
@@ -415,4 +495,4 @@ def handleException(anaconda, (type, value, tb)):
pdb.post_mortem (tb)
os.kill(os.getpid(), signal.SIGKILL)
elif rc == EXN_SAVE:
- runSaveDialog(anaconda, "/tmp/anacdump.txt")
+ runSaveDialog(anaconda, exn)