From bbcf7aa6ab43171e9d55bf99b00ad30e14a53b31 Mon Sep 17 00:00:00 2001 From: Christophe Varoqui Date: Mon, 4 Nov 2019 19:00:46 +0100 Subject: [PATCH] Fix drop of events on objects being deleted Don't expand a path selection to validate the events against, because this path selection does not include the objects being deleted, which cause the event to be unduely dropped. Use instead a event's path match against the selector expression. --- lib/osvcd_lsnr.py | 23 +++++++++++------------ lib/osvcd_shared.py | 12 +++++++++--- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/lib/osvcd_lsnr.py b/lib/osvcd_lsnr.py index 9baa0c024a..57d1760b0e 100644 --- a/lib/osvcd_lsnr.py +++ b/lib/osvcd_lsnr.py @@ -506,26 +506,25 @@ def filter_event(self, event, thr): # root and no selector => fast path return event namespaces = thr.get_namespaces() - paths = self.object_selector(thr.selector if thr.selector is not None else "**", namespaces=namespaces) if event.get("kind") == "patch": - return self.filter_patch_event(event, thr, paths, namespaces) + return self.filter_patch_event(event, thr, namespaces) else: - return self.filter_event_event(event, thr, paths) + return self.filter_event_event(event, thr, namespaces) - def filter_event_event(self, event, thr, paths): + def filter_event_event(self, event, thr, namespaces): def valid(change): try: path = event["data"]["path"] except KeyError: return True - if thr.selector and path not in paths: + if thr.selector and not self.match_object_selector(thr.selector, namespaces=namespaces, path=path): return False return False if valid(event): return event return None - def filter_patch_event(self, event, thr, paths, namespaces): + def filter_patch_event(self, event, thr, namespaces): def filter_change(change): try: key, value = change @@ -551,9 +550,9 @@ def filter_change(change): if key_len == 2: if value is None: return change - value = dict((k, v) for k, v in value.items() if k in paths) + value = dict((k, v) for k, v in value.items() if self.match_object_selector(thr.selector, namespaces=namespaces, path=k)) return [key, value] - if key[2] in paths: + if self.match_object_selector(thr.selector, namespaces=namespaces, path=key[2]): return change else: return @@ -578,9 +577,9 @@ def filter_change(change): if key_len == 5: if value is None: return change - value = dict((k, v) for k, v in value.items() if k in paths) + value = dict((k, v) for k, v in value.items() if self.match_object_selector(thr.selector, namespaces=namespaces, path=k)) return [key, value] - if key[5] in paths: + if self.match_object_selector(thr.selector, namespaces=namespaces, path=key[5]): return change else: return @@ -588,9 +587,9 @@ def filter_change(change): if key_len == 5: if value is None: return change - value = dict((k, v) for k, v in value.items() if k in paths) + value = dict((k, v) for k, v in value.items() if self.match_object_selector(thr.selector, namespaces=namespaces, path=k)) return [key, value] - if key[5] in paths: + if self.match_object_selector(thr.selector, namespaces=namespaces, path=key[5]): return change else: return diff --git a/lib/osvcd_shared.py b/lib/osvcd_shared.py index 6676d05800..a7fa076dc3 100644 --- a/lib/osvcd_shared.py +++ b/lib/osvcd_shared.py @@ -1515,7 +1515,12 @@ def filter_daemon_status(self, data, namespace=None, namespaces=None, selector=N del data["monitor"]["services"][path] return data - def object_selector(self, selector=None, namespace=None, namespaces=None): + def match_object_selector(self, selector=None, namespace=None, namespaces=None, path=None): + if selector is None: + selector = "**" + return path in self.object_selector(selector=selector, namespace=namespace, namespaces=namespaces, paths=[path]) + + def object_selector(self, selector=None, namespace=None, namespaces=None, paths=None): if not selector: return [] if namespace: @@ -1525,8 +1530,9 @@ def object_selector(self, selector=None, namespace=None, namespaces=None): if "root" in namespaces: namespaces.add(None) - # all objects - paths = [p for p in AGG if split_path(p)[1] in namespaces] + if paths is None: + # all objects + paths = [p for p in AGG if split_path(p)[1] in namespaces] if selector == "**": return paths