Repository: bridgecrewio/checkov

Issue:
image scanning does not cleanup the twistcli binary
```
~ checkov --bc-api-key REDACTED --dockerfile-path Dockerfile --docker-image checkov_scan_me --repo-id tkishel/example

<SNIP>

More details: https://www.bridgecrew.cloud/projects?repository=tkishel73_tkishel/example&branch=bc-bdfab20_master&runId=latest
```

```
~ git status
On branch main
Your branch is up to date with 'origin/main'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	twistcli

no changes added to commit (use "git add" and/or "git commit -a")
```

Some usage of `twistcli` includes a `cleanup_scan()` or (misspelled) `cleanup_twictcli()` method, but they do not appear to be called:

https://github.com/bridgecrewio/checkov/blob/master/checkov/sca_image/runner.py

https://github.com/bridgecrewio/checkov/blob/master/checkov/sca_package/scanner.py

https://github.com/bridgecrewio/checkov/blob/master/checkov/common/bridgecrew/vulnerability_scanning/image_scanner.py

So, it may be valuable to add something like this, after all possible uses of `twistcli` have executed ...

```
def __exit__(self, t, v, tr):
    self.cleanup_scan()
````

... especially to execute that cleanup after an exception exit.

An argument could also be made to instead download and cache the `twistcli` binary outside of the current directory.

And, it may be valuable to consolidate the various duplicate methods that interact with the `twistcli` binary in the above files.


Discussion:

Resolving patch:
diff --git a/checkov/sca_image/runner.py b/checkov/sca_image/runner.py
--- a/checkov/sca_image/runner.py
+++ b/checkov/sca_image/runner.py
@@ -40,9 +40,14 @@ def scan(
 
         logging.info(f"SCA image scanning is scanning the image {image_id}")
         image_scanner.setup_scan(image_id, dockerfile_path, skip_extract_image_name=False)
-        scan_result = asyncio.run(self.execute_scan(image_id, Path('results.json')))
-        logging.info(f"SCA image scanning successfully scanned the image {image_id}")
-        return scan_result
+        try:
+            scan_result = asyncio.run(self.execute_scan(image_id, Path('results.json')))
+            logging.info(f"SCA image scanning successfully scanned the image {image_id}")
+            image_scanner.cleanup_scan()
+            return scan_result
+        except Exception as err:
+            image_scanner.cleanup_scan()
+            raise err
 
     @staticmethod
     async def execute_scan(
diff --git a/checkov/sca_package/runner.py b/checkov/sca_package/runner.py
--- a/checkov/sca_package/runner.py
+++ b/checkov/sca_package/runner.py
@@ -38,7 +38,7 @@ def prepare_and_scan(
         files: Optional[List[str]] = None,
         runner_filter: RunnerFilter = RunnerFilter(),
         exclude_package_json: bool = True,
-        cleanup_twictcli: bool = True,
+        cleanup_twistcli: bool = True,
     ) -> "Optional[Sequence[Dict[str, Any]]]":
 
         if not strtobool(os.getenv("ENABLE_SCA_PACKAGE_SCAN", "False")):
@@ -74,7 +74,7 @@ def prepare_and_scan(
 
         scanner = Scanner()
         self._check_class = f"{scanner.__module__}.{scanner.__class__.__qualname__}"
-        scan_results = scanner.scan(input_output_paths, cleanup_twictcli)
+        scan_results = scanner.scan(input_output_paths, cleanup_twistcli)
 
         logging.info(f"SCA package scanning successfully scanned {len(scan_results)} files")
         return scan_results


Test patch: