karton-core 5.3.3__py3-none-any.whl → 5.3.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- __version__ = "5.3.3"
1
+ __version__ = "5.3.4"
karton/core/karton.py CHANGED
@@ -12,6 +12,7 @@ from .__version__ import __version__
12
12
  from .backend import KartonBackend, KartonBind, KartonMetrics
13
13
  from .base import KartonBase, KartonServiceBase
14
14
  from .config import Config
15
+ from .exceptions import TaskTimeoutError
15
16
  from .resource import LocalResource
16
17
  from .task import Task, TaskState
17
18
  from .utils import timeout
@@ -129,7 +130,10 @@ class Consumer(KartonServiceBase):
129
130
  self.current_task: Optional[Task] = None
130
131
  self._pre_hooks: List[Tuple[Optional[str], Callable[[Task], None]]] = []
131
132
  self._post_hooks: List[
132
- Tuple[Optional[str], Callable[[Task, Optional[Exception]], None]]
133
+ Tuple[
134
+ Optional[str],
135
+ Callable[[Task, Optional[BaseException]], None],
136
+ ]
133
137
  ] = []
134
138
 
135
139
  @abc.abstractmethod
@@ -179,14 +183,14 @@ class Consumer(KartonServiceBase):
179
183
  self.process(self.current_task)
180
184
  else:
181
185
  self.process(self.current_task)
182
- except Exception as exc:
186
+ except (Exception, TaskTimeoutError) as exc:
183
187
  saved_exception = exc
184
188
  raise
185
189
  finally:
186
190
  self._run_post_hooks(saved_exception)
187
191
 
188
192
  self.log.info("Task done - %s", self.current_task.uid)
189
- except Exception:
193
+ except (Exception, TaskTimeoutError):
190
194
  exc_info = sys.exc_info()
191
195
  exception_str = traceback.format_exception(*exc_info)
192
196
 
@@ -260,7 +264,7 @@ class Consumer(KartonServiceBase):
260
264
 
261
265
  def add_post_hook(
262
266
  self,
263
- callback: Callable[[Task, Optional[Exception]], None],
267
+ callback: Callable[[Task, Optional[BaseException]], None],
264
268
  name: Optional[str] = None,
265
269
  ) -> None:
266
270
  """
@@ -289,7 +293,7 @@ class Consumer(KartonServiceBase):
289
293
  else:
290
294
  self.log.exception("Pre-hook failed")
291
295
 
292
- def _run_post_hooks(self, exception: Optional[Exception]) -> None:
296
+ def _run_post_hooks(self, exception: Optional[BaseException]) -> None:
293
297
  """
294
298
  Run registered postprocessing hooks
295
299
 
@@ -431,7 +435,7 @@ class Karton(Consumer, Producer):
431
435
  self._send_signaling_status_task("task_begin")
432
436
 
433
437
  def _send_signaling_status_task_end(
434
- self, task: Task, ex: Optional[Exception]
438
+ self, task: Task, ex: Optional[BaseException]
435
439
  ) -> None:
436
440
  """Send a begin status signaling task.
437
441
 
karton/core/task.py CHANGED
@@ -212,38 +212,65 @@ class Task(object):
212
212
  :meta private:
213
213
  """
214
214
 
215
- matches = False
216
- for task_filter in filters:
217
- matched = []
218
- for filter_key, filter_value in task_filter.items():
219
- # Coerce to string for comparison
220
- header_value = self.headers.get(filter_key)
215
+ def test_filter(headers: Dict[str, Any], filter: Dict[str, Any]) -> int:
216
+ """
217
+ Filter match follows AND logic, but it's non-boolean because filters may be
218
+ negated (task:!platform).
219
+
220
+ Result values are as follows:
221
+ - 1 - positive match, no mismatched values in headers
222
+ (all matched)
223
+ - 0 - no match, found value that doesn't match to the filter
224
+ (some are not matched)
225
+ - -1 - negative match, found value that matches negated filter value
226
+ (all matched but found negative matches)
227
+ """
228
+ matches = 1
229
+ for filter_key, filter_value in filter.items():
230
+ # Coerce filter value to string
221
231
  filter_value_str = str(filter_value)
222
- header_value_str = str(header_value)
223
-
224
232
  negated = False
225
233
  if filter_value_str.startswith("!"):
226
234
  negated = True
227
235
  filter_value_str = filter_value_str[1:]
228
236
 
229
- if header_value is None:
230
- matched.append(negated)
231
- continue
237
+ # If expected key doesn't exist in headers
238
+ if filter_key not in headers:
239
+ # Negated filter ignores non-existent values
240
+ if negated:
241
+ continue
242
+ # But positive filter doesn't
243
+ return 0
232
244
 
245
+ # Coerce header value to string
246
+ header_value_str = str(headers[filter_key])
233
247
  # fnmatch is great for handling simple wildcard patterns (?, *, [abc])
234
248
  match = fnmatch.fnmatchcase(header_value_str, filter_value_str)
235
- # if matches, but it's negated then we can return straight away
236
- # since no matter the other filters
249
+ # If matches, but it's negated: it's negative match
237
250
  if match and negated:
238
- return False
239
-
240
- # else, apply a XOR logic to take care of negation matching
241
- matched.append(match != negated)
242
-
243
- # set the flag if all consumer filter fields match the task header.
244
- # It will be set to True only if at least one filter matches the header
245
- matches |= all(matched)
246
-
251
+ matches = -1
252
+ # If doesn't match but filter is not negated: it's not a match
253
+ if not match and not negated:
254
+ return 0
255
+ # If there are no mismatched values: filter is matched
256
+ return matches
257
+
258
+ # List of filter matches follow OR logic, but -1 is special
259
+ # If there is any -1, result is False
260
+ # (any matched, but it's negative match)
261
+ # If there is any 1, but no -1's: result is True
262
+ # (any matched, no negative match)
263
+ # If there are only 0's: result is False
264
+ # (none matched)
265
+ matches = False
266
+ for task_filter in filters:
267
+ match_result = test_filter(self.headers, task_filter)
268
+ if match_result == -1:
269
+ # Any negative match results in False
270
+ return False
271
+ if match_result == 1:
272
+ # Any positive match but without negative matches results in True
273
+ matches = True
247
274
  return matches
248
275
 
249
276
  def set_task_parent(self, parent: "Task"):
karton/system/system.py CHANGED
@@ -103,7 +103,7 @@ class SystemService(KartonServiceBase):
103
103
  and current_time > task.last_update + self.task_dispatched_timeout
104
104
  ):
105
105
  to_delete.append(task)
106
- self.log.warning(
106
+ self.log.error(
107
107
  "Task %s is in Dispatched state more than %d seconds. "
108
108
  "Killed. (origin: %s)",
109
109
  task.uid,
@@ -116,7 +116,7 @@ class SystemService(KartonServiceBase):
116
116
  and current_time > task.last_update + self.task_started_timeout
117
117
  ):
118
118
  to_delete.append(task)
119
- self.log.warning(
119
+ self.log.error(
120
120
  "Task %s is in Started state more than %d seconds. "
121
121
  "Killed. (receiver: %s)",
122
122
  task.uid,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: karton-core
3
- Version: 5.3.3
3
+ Version: 5.3.4
4
4
  Summary: Distributed malware analysis orchestration framework
5
5
  Home-page: https://github.com/CERT-Polska/karton
6
6
  License: UNKNOWN
@@ -1,26 +1,26 @@
1
- karton_core-5.3.3-nspkg.pth,sha256=vHa-jm6pBTeInFrmnsHMg9AOeD88czzQy-6QCFbpRcM,539
1
+ karton_core-5.3.4-nspkg.pth,sha256=vHa-jm6pBTeInFrmnsHMg9AOeD88czzQy-6QCFbpRcM,539
2
2
  karton/core/__init__.py,sha256=QuT0BWZyp799eY90tK3H1OD2hwuusqMJq8vQwpB3kG4,337
3
- karton/core/__version__.py,sha256=1nSgbQKO6KlKoDYLTNXC8iJUIO_SuORsK-CISssv5l0,22
3
+ karton/core/__version__.py,sha256=dAiy67tSM_yYFR8Us_fQT-TDbfV34VpASYNKXfGmEnQ,22
4
4
  karton/core/backend.py,sha256=evOzlz1v1sxWusc8VojGAYyeyi9fcbVoEPm6WoNT1Xs,34696
5
5
  karton/core/base.py,sha256=C6Lco3E0XCsxvEjeVOLR9fxh_IWJ1vjC9BqUYsQyewE,8083
6
6
  karton/core/config.py,sha256=7oKchitq6pWzPuXRfjBXqVT_BgGIz2p-CDo1RGaNJQg,8118
7
7
  karton/core/exceptions.py,sha256=8i9WVzi4PinNlX10Cb-lQQC35Hl-JB5R_UKXa9AUKoQ,153
8
8
  karton/core/inspect.py,sha256=rIa0u4u12vG_RudPfc9UAS4RZD56W8qbUa8n1dDIkX0,4868
9
- karton/core/karton.py,sha256=-BWsNvbL_yFFlSPjEOXlBqkENEWLTfIB0ETjowh7Mjo,14863
9
+ karton/core/karton.py,sha256=9SOAviG42kSsPqc3EuaHzWtA_KywMtc01hmU6FaJpHo,15007
10
10
  karton/core/logger.py,sha256=J3XAyG88U0cwYC9zR6E3QD1uJenrQh7zS9-HgxhqeAs,2040
11
11
  karton/core/main.py,sha256=ir1-dhn3vbwfh2YHiM6ZYfRBbjwLvJSz0d8tuK1mb_4,8310
12
12
  karton/core/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  karton/core/resource.py,sha256=tA3y_38H9HVKIrCeAU70zHUkQUv0BuCQWMC470JLxxc,20321
14
- karton/core/task.py,sha256=1yyCH6A6MBJ7yuKECmsLrZDRECbKQ-48dJ31ZL7FR5Y,19644
14
+ karton/core/task.py,sha256=WYXzVopg8VlWOc7ncEscHVKivsXHfZc5zWLHW_mxBwY,21000
15
15
  karton/core/test.py,sha256=tms-YM7sUKQDHN0vm2_W7DIvHnO_ld_VPsWHnsbKSfk,9102
16
16
  karton/core/utils.py,sha256=sEVqGdVPyYswWuVn8wYXBQmln8Az826N_2HgC__pmW8,4090
17
17
  karton/system/__init__.py,sha256=JF51OqRU_Y4c0unOulvmv1KzSHSq4ZpXU8ZsH4nefRM,63
18
18
  karton/system/__main__.py,sha256=QJkwIlSwaPRdzwKlNmCAL41HtDAa73db9MZKWmOfxGM,56
19
- karton/system/system.py,sha256=AsQLGF_8YI-o4dCOe2hyQefYlhGEguFSoPg1EcQtJyU,13791
20
- karton_core-5.3.3.dist-info/LICENSE,sha256=o8h7hYhn7BJC_-DmrfqWwLjaR_Gbe0TZOOQJuN2ca3I,1519
21
- karton_core-5.3.3.dist-info/METADATA,sha256=sumt5njKhDPynjbmFZvPxdPPSCCXR4wr3xchvowJPC8,6847
22
- karton_core-5.3.3.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
23
- karton_core-5.3.3.dist-info/entry_points.txt,sha256=FJj5EZuvFP0LkagjX_dLbRGBUnuLjgBiSyiFfq4c86U,99
24
- karton_core-5.3.3.dist-info/namespace_packages.txt,sha256=X8SslCPsqXDCnGZqrYYolzT3xPzJMq1r-ZQSc0jfAEA,7
25
- karton_core-5.3.3.dist-info/top_level.txt,sha256=X8SslCPsqXDCnGZqrYYolzT3xPzJMq1r-ZQSc0jfAEA,7
26
- karton_core-5.3.3.dist-info/RECORD,,
19
+ karton/system/system.py,sha256=65c8j1Ayra_CrXA1AQPBm00bTnpQiW91iZlTTRfJJI8,13787
20
+ karton_core-5.3.4.dist-info/LICENSE,sha256=o8h7hYhn7BJC_-DmrfqWwLjaR_Gbe0TZOOQJuN2ca3I,1519
21
+ karton_core-5.3.4.dist-info/METADATA,sha256=w15YiCEMDZrAF_429FAx98NH3tif38vyDxI9g9heY7E,6847
22
+ karton_core-5.3.4.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
23
+ karton_core-5.3.4.dist-info/entry_points.txt,sha256=FJj5EZuvFP0LkagjX_dLbRGBUnuLjgBiSyiFfq4c86U,99
24
+ karton_core-5.3.4.dist-info/namespace_packages.txt,sha256=X8SslCPsqXDCnGZqrYYolzT3xPzJMq1r-ZQSc0jfAEA,7
25
+ karton_core-5.3.4.dist-info/top_level.txt,sha256=X8SslCPsqXDCnGZqrYYolzT3xPzJMq1r-ZQSc0jfAEA,7
26
+ karton_core-5.3.4.dist-info/RECORD,,