]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
pybind/mgr: support marking progress events as failed
authorJason Dillaman <dillaman@redhat.com>
Mon, 22 Jul 2019 15:00:47 +0000 (11:00 -0400)
committerJason Dillaman <dillaman@redhat.com>
Thu, 25 Jul 2019 12:58:37 +0000 (08:58 -0400)
The failed events can also include a failure message to indicate
the reason for the failure.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/pybind/mgr/progress/module.py

index 1a529a8121335503d6bc2e82b1d6bd704f9dfd36..049f616f802fb3f39d97e5cdafc554870af8a7a8 100644 (file)
@@ -54,6 +54,14 @@ class Event(object):
     def duration_str(self):
         return self._duration_str
 
+    @property
+    def failed(self):
+        return False
+
+    @property
+    def failure_message(self):
+        return None
+
     def summary(self):
         return "{0} {1} {2}".format(self.progress, self.message, self.duration_str)
 
@@ -100,23 +108,42 @@ class GhostEvent(Event):
     after the event is complete.
     """
 
-    def __init__(self, my_id, message, refs, started_at, finished_at=None):
+    def __init__(self, my_id, message, refs, started_at, finished_at=None,
+                 failed=False, failure_message=None):
         super(GhostEvent, self).__init__(message, refs, started_at)
         self.finished_at = finished_at if finished_at else time.time()
         self.id = my_id
 
+        if failed:
+            self._failed = True
+            self._failure_message = failure_message
+        else:
+            self._failed = False
+
     @property
     def progress(self):
         return 1.0
 
+    @property
+    def failed(self):
+        return self._failed
+
+    @property
+    def failure_message(self):
+        return self._failure_message if self._failed else None
+
     def to_json(self):
-        return {
+        d = {
             "id": self.id,
             "message": self.message,
             "refs": self._refs,
             "started_at": self.started_at,
             "finished_at": self.finished_at
         }
+        if self._failed:
+            d["failed"] = True
+            d["failure_message"] = self._failure_message
+        return d
 
 
 class RemoteEvent(Event):
@@ -130,16 +157,31 @@ class RemoteEvent(Event):
         super(RemoteEvent, self).__init__(message, refs)
         self.id = my_id
         self._progress = 0.0
+        self._failed = False
         self._refresh()
 
     def set_progress(self, progress):
         self._progress = progress
         self._refresh()
 
+    def set_failed(self, message):
+        self._progress = 1.0
+        self._failed = True
+        self._failure_message = message
+        self._refresh()
+
     @property
     def progress(self):
         return self._progress
 
+    @property
+    def failed(self):
+        return self._failed
+
+    @property
+    def failure_message(self):
+        return self._failure_message if self._failed else None
+
 
 class PgRecoveryEvent(Event):
     """
@@ -485,7 +527,9 @@ class Module(MgrModule):
         for ev in decoded['events']:
             self._completed_events.append(GhostEvent(ev['id'], ev['message'],
                                                      ev['refs'], ev['started_at'],
-                                                     ev['finished_at']))
+                                                     ev['finished_at'],
+                                                     ev.get('failed', False),
+                                                     ev.get('failure_message')))
 
         self._prune_completed_events()
 
@@ -550,7 +594,8 @@ class Module(MgrModule):
         self.complete_progress_event(ev.id)
 
         self._completed_events.append(
-            GhostEvent(ev.id, ev.message, ev.refs, ev.started_at))
+            GhostEvent(ev.id, ev.message, ev.refs, ev.started_at,
+                       failed=ev.failed, failure_message=ev.failure_message))
         del self._events[ev.id]
         self._prune_completed_events()
         self._dirty = True
@@ -569,6 +614,21 @@ class Module(MgrModule):
             self.log.warn("complete: ev {0} does not exist".format(ev_id))
             pass
 
+    def fail(self, ev_id, message):
+        """
+        For calling from other mgr modules to mark an event as failed (and
+        complete)
+        """
+        try:
+            ev = self._events[ev_id]
+            ev.set_failed(message)
+            self.log.info("fail: finished ev {0} ({1}): {2}".format(ev_id,
+                                                                    ev.message,
+                                                                    message))
+            self._complete(ev)
+        except KeyError:
+            self.log.warn("fail: ev {0} does not exist".format(ev_id))
+
     def _handle_ls(self):
         if len(self._events) or len(self._completed_events):
             out = ""
@@ -582,7 +642,8 @@ class Module(MgrModule):
                 # TODO: limit number of completed events to show
                 out += "\n"
                 for ev in self._completed_events:
-                    out += "[Complete]: {0}\n".format(ev.twoline_progress())
+                    out += "[{0}]: {1}\n".format("Complete" if not ev.failed else "Failed",
+                                                 ev.twoline_progress())
 
             return 0, out, ""
         else: