add a way to create a crash report
This commit is contained in:
parent
38dfeebde7
commit
74ef2ad8f6
|
@ -49,6 +49,7 @@ parts:
|
|||
- libsystemd0
|
||||
- iso-codes
|
||||
- lsb-release
|
||||
- python3-apport
|
||||
- python3-distutils-extra
|
||||
- python3-urwid
|
||||
- python3-requests
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import datetime
|
||||
import enum
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
|
||||
import apport
|
||||
import apport.crashdb
|
||||
|
@ -57,21 +57,10 @@ class ErrorReport:
|
|||
|
||||
@classmethod
|
||||
def new(cls, controller, kind):
|
||||
prefix = "installer.{}.{}".format(
|
||||
datetime.datetime.utcnow().isoformat(timespec='seconds'),
|
||||
kind.name.lower())
|
||||
i = 0
|
||||
while 1:
|
||||
base = "{}.{}".format(prefix, i)
|
||||
crash_path = os.path.join(
|
||||
controller.crash_directory, base + ".crash")
|
||||
try:
|
||||
crash_file = open(crash_path, 'xb')
|
||||
except FileExistsError:
|
||||
i += 1
|
||||
continue
|
||||
else:
|
||||
break
|
||||
base = "installer.{:.9f}.{}".format(time.time(), kind.name.lower())
|
||||
crash_file = open(
|
||||
os.path.join(controller.crash_directory, base + ".crash"),
|
||||
'wb')
|
||||
|
||||
pr = apport.Report('Bug')
|
||||
pr['CrashDB'] = repr(controller.crashdb_spec)
|
||||
|
|
|
@ -16,9 +16,16 @@
|
|||
import logging
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
import apport.hookutils
|
||||
|
||||
from subiquitycore.core import Application
|
||||
|
||||
from subiquity.controllers.error import (
|
||||
ErrorController,
|
||||
)
|
||||
from subiquity.models.subiquity import SubiquityModel
|
||||
from subiquity.snapd import (
|
||||
FakeSnapdConnection,
|
||||
|
@ -128,8 +135,49 @@ class Subiquity(Application):
|
|||
self.run_command_in_foreground(
|
||||
"bash", before_hook=_before, cwd='/')
|
||||
|
||||
def load_controllers(self):
|
||||
super().load_controllers()
|
||||
self.error_controller = ErrorController(self)
|
||||
|
||||
def start_controllers(self):
|
||||
super().start_controllers()
|
||||
self.error_controller.start()
|
||||
|
||||
def note_file_for_apport(self, key, path):
|
||||
self._apport_files.append((key, path))
|
||||
|
||||
def note_data_for_apport(self, key, value):
|
||||
self._apport_data.append((key, value))
|
||||
|
||||
def make_apport_report(self, kind, thing, *, wait=False):
|
||||
log.debug("generating crash report")
|
||||
|
||||
try:
|
||||
report = self.error_controller.create_report(kind)
|
||||
except Exception:
|
||||
log.exception("creating crash report failed")
|
||||
return
|
||||
|
||||
etype = sys.exc_info()[0]
|
||||
if etype is not None:
|
||||
report.pr["Title"] = "{} crashed with {}".format(
|
||||
thing, etype.__name__)
|
||||
report.pr['Traceback'] = traceback.format_exc()
|
||||
else:
|
||||
report.pr["Title"] = thing
|
||||
|
||||
apport_files = self._apport_files[:]
|
||||
apport_data = self._apport_data.copy()
|
||||
|
||||
def _bg_attach_hook():
|
||||
# Attach any stuff other parts of the code think we should know
|
||||
# about.
|
||||
for key, path in apport_files:
|
||||
apport.hookutils.attach_file_if_exists(report.pr, path, key)
|
||||
for key, value in apport_data:
|
||||
report.pr[key] = value
|
||||
|
||||
report.add_info(_bg_attach_hook, wait)
|
||||
|
||||
# In the fullness of time we should do the signature thing here.
|
||||
return report
|
||||
|
|
|
@ -570,6 +570,12 @@ class Application:
|
|||
orig, count)
|
||||
log.debug("load_controllers done")
|
||||
|
||||
def start_controllers(self):
|
||||
log.debug("starting controllers")
|
||||
for k in self.controllers:
|
||||
self.controller_instances[k].start()
|
||||
log.debug("controllers started")
|
||||
|
||||
def load_serialized_state(self):
|
||||
for k in self.controllers:
|
||||
state_path = os.path.join(self.state_dir, 'states', k)
|
||||
|
@ -631,10 +637,7 @@ class Application:
|
|||
0.05, select_initial_screen, initial_controller_index)
|
||||
self._connect_base_signals()
|
||||
|
||||
log.debug("starting controllers")
|
||||
for k in self.controllers:
|
||||
self.controller_instances[k].start()
|
||||
log.debug("controllers started")
|
||||
self.start_controllers()
|
||||
|
||||
self.loop.run()
|
||||
except Exception:
|
||||
|
|
Loading…
Reference in New Issue