Skip to content

Commit d6d9358

Browse files
committed
feat(processing): add unblob dedicated temporary directory handling
1 parent 1965107 commit d6d9358

File tree

4 files changed

+37
-0
lines changed

4 files changed

+37
-0
lines changed

python/unblob/processing.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
import atexit
12
import multiprocessing
3+
import os
24
import shutil
5+
import tempfile
36
from collections.abc import Iterable, Sequence
47
from operator import attrgetter
58
from pathlib import Path
@@ -100,6 +103,21 @@ class ExtractionConfig:
100103
dir_handlers: DirectoryHandlers = BUILTIN_DIR_HANDLERS
101104
verbose: int = 1
102105
progress_reporter: type[ProgressReporter] = NullProgressReporter
106+
tmp_dir: Path = attrs.field(
107+
factory=lambda: Path(tempfile.mkdtemp(prefix="unblob-tmp-"))
108+
)
109+
110+
def __attrs_post_init__(self):
111+
atexit.register(self._cleanup_tmp_dir)
112+
113+
def _cleanup_tmp_dir(self):
114+
if isinstance(self.tmp_dir, Path) and self.tmp_dir.exists():
115+
try:
116+
shutil.rmtree(self.tmp_dir)
117+
except Exception as e:
118+
logger.warning(
119+
"Failed to clean up tmp_dir", tmp_dir=self.tmp_dir, exc_info=e
120+
)
103121

104122
def _get_output_path(self, path: Path) -> Path:
105123
"""Return path under extract root."""
@@ -244,11 +262,17 @@ def __init__(self, config: ExtractionConfig):
244262
def process_task(self, task: Task) -> TaskResult:
245263
result = TaskResult(task)
246264
try:
265+
self._set_tmp_dir()
247266
self._process_task(result, task)
248267
except Exception as exc:
249268
self._process_error(result, exc)
250269
return result
251270

271+
def _set_tmp_dir(self):
272+
"""Set environment variables so all subprocesses and handlers use our temp dir."""
273+
for var in ("TMP", "TMPDIR", "TEMP", "TEMPDIR"):
274+
os.environ[var] = self._config.tmp_dir.as_posix()
275+
252276
def _process_error(self, result: TaskResult, exc: Exception):
253277
error_report = UnknownError(exception=exc)
254278
result.add_report(error_report)

python/unblob/sandbox.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ def __init__(
5555
AccessFS.remove_file(config.extract_root),
5656
AccessFS.make_dir(config.extract_root.parent),
5757
AccessFS.read_write(log_path),
58+
# Allow access to the managed temp directory for handlers
59+
AccessFS.read_write(config.tmp_dir),
60+
AccessFS.remove_dir(config.tmp_dir),
61+
AccessFS.remove_file(config.tmp_dir),
5862
*extra_passthrough,
5963
]
6064

tests/test_cli.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ def test_archive_success(
274274
verbose=expected_verbosity,
275275
progress_reporter=expected_progress_reporter,
276276
)
277+
config.tmp_dir = mock.ANY
277278
process_file_mock.assert_called_once_with(config, in_path, None)
278279
logger_config_mock.assert_called_once_with(expected_verbosity, tmp_path, log_path)
279280

tests/test_sandbox.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ def test_necessary_resources_can_be_created_in_sandbox(
3434
):
3535
directory_in_extract_root = extraction_config.extract_root / "path" / "to" / "dir"
3636
file_in_extract_root = directory_in_extract_root / "file"
37+
file_in_tmp_dir = extraction_config.tmp_dir / "tmp_file"
38+
directory_in_tmp_dir = extraction_config.tmp_dir / "tmp_dir"
3739

3840
sandbox.run(extraction_config.extract_root.mkdir, parents=True)
3941
sandbox.run(directory_in_extract_root.mkdir, parents=True)
@@ -45,6 +47,12 @@ def test_necessary_resources_can_be_created_in_sandbox(
4547
log_path.touch()
4648
sandbox.run(log_path.write_text, "log line")
4749

50+
sandbox.run(directory_in_tmp_dir.mkdir, parents=True)
51+
sandbox.run(file_in_tmp_dir.touch)
52+
sandbox.run(file_in_tmp_dir.write_text, "tmp file content")
53+
sandbox.run(file_in_tmp_dir.unlink)
54+
sandbox.run(directory_in_tmp_dir.rmdir)
55+
4856

4957
def test_access_outside_sandbox_is_not_possible(sandbox: Sandbox, tmp_path: Path):
5058
unrelated_dir = tmp_path / "unrelated" / "path"

0 commit comments

Comments
 (0)