Skip to content

Commit a566e87

Browse files
committed
Add on_failure to handle cleanup during pipeline failure
- Resolves #1639 Signed-off-by: Keshav Priyadarshi <[email protected]>
1 parent 297ab51 commit a566e87

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed

vulnerabilities/pipelines/__init__.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010
import logging
1111
from datetime import datetime
1212
from datetime import timezone
13+
from timeit import default_timer as timer
1314
from traceback import format_exc as traceback_format_exc
1415
from typing import Iterable
1516

1617
from aboutcode.pipeline import BasePipeline
1718
from aboutcode.pipeline import LoopProgress
19+
from aboutcode.pipeline import humanize_time
1820

1921
from vulnerabilities.importer import AdvisoryData
2022
from vulnerabilities.improver import MAX_CONFIDENCE
@@ -29,6 +31,57 @@
2931
class VulnerableCodePipeline(BasePipeline):
3032
pipeline_id = None # Unique Pipeline ID
3133

34+
def on_failure(self):
35+
"""
36+
Tasks to run in the event that pipeline execution fails.
37+
38+
Implement cleanup or other tasks that need to be performed
39+
on pipeline failure, such as:
40+
- Removing cloned repositories.
41+
- Deleting downloaded archives.
42+
"""
43+
pass
44+
45+
def execute(self):
46+
"""Execute each steps in the order defined on this pipeline class."""
47+
self.log(f"Pipeline [{self.pipeline_name}] starting")
48+
49+
steps = self.pipeline_class.get_steps(groups=self.selected_groups)
50+
steps_count = len(steps)
51+
pipeline_start_time = timer()
52+
53+
for current_index, step in enumerate(steps, start=1):
54+
step_name = step.__name__
55+
56+
if self.selected_steps and step_name not in self.selected_steps:
57+
self.log(f"Step [{step_name}] skipped")
58+
continue
59+
60+
self.set_current_step(f"{current_index}/{steps_count} {step_name}")
61+
self.log(f"Step [{step_name}] starting")
62+
step_start_time = timer()
63+
64+
try:
65+
step(self)
66+
except Exception as exception:
67+
self.log("Pipeline failed")
68+
on_failure_start_time = timer()
69+
self.log(f"Running [on_failure] tasks")
70+
self.on_failure()
71+
on_failure_run_time = timer() - on_failure_start_time
72+
self.log(f"Completed [on_failure] tasks in {humanize_time(on_failure_run_time)}")
73+
74+
return 1, self.output_from_exception(exception)
75+
76+
step_run_time = timer() - step_start_time
77+
self.log(f"Step [{step_name}] completed in {humanize_time(step_run_time)}")
78+
79+
self.set_current_step("") # Reset the `current_step` field on completion
80+
pipeline_run_time = timer() - pipeline_start_time
81+
self.log(f"Pipeline completed in {humanize_time(pipeline_run_time)}")
82+
83+
return 0, ""
84+
3285
def log(self, message, level=logging.INFO):
3386
"""Log the given `message` to the current module logger and execution_log."""
3487
now_local = datetime.now(timezone.utc).astimezone()

vulnerabilities/pipelines/gitlab_importer.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ def clean_downloads(self):
106106
self.log(f"Removing cloned repository")
107107
self.vcs_response.delete()
108108

109+
def on_failure(self):
110+
self.clean_downloads()
111+
109112

110113
def parse_advisory_path(base_path: Path, file_path: Path) -> Tuple[str, str, str]:
111114
"""

vulnerabilities/pipelines/npm_importer.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,6 @@ def clean_downloads(self):
163163
if self.vcs_response:
164164
self.log(f"Removing cloned repository")
165165
self.vcs_response.delete()
166+
167+
def on_failure(self):
168+
self.clean_downloads()

vulnerabilities/pipelines/pypa_importer.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,6 @@ def clean_downloads(self):
6868
if self.vcs_response:
6969
self.log(f"Removing cloned repository")
7070
self.vcs_response.delete()
71+
72+
def on_failure(self):
73+
self.clean_downloads()

0 commit comments

Comments
 (0)