feat(command): isolated run directory (#1081)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added `cwd_isolated` toggle for Command runner tasks. When enabled
without a custom working directory, tasks execute in isolated, per-task
working directories within the reports output folder.

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/freelabz/secator/pull/1081)

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Olivier Cervello 2026-05-12 14:36:43 +02:00 committed by GitHub
parent df01409ebe
commit 3a87b099cc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -58,6 +58,7 @@ class Command(Runner):
# Current working directory
cwd = None
cwd_isolated = False
# Output encoding
encoding = 'utf-8'
@ -486,7 +487,7 @@ class Command(Runner):
task_part = f'[bold gold3]{self.unique_name}[/]'
yield Info(
message=f'Started task {task_part} (cmd=[dim white]{cmd_str}[/])',
_source=self.unique_name
_source=self.unique_name,
)
# Check for sudo requirements and prepare the password if needed
@ -519,6 +520,11 @@ class Command(Runner):
self.killed = False
self.memory_limit_mb = CONFIG.celery.task_memory_limit_mb
# Isolated CWD
if not self.cwd and self.cwd_isolated:
self.cwd = f'{self.reports_folder}/.outputs/{self.fqn}'
os.makedirs(self.cwd, exist_ok=True)
# Run the command using subprocess
env = os.environ
self.process = subprocess.Popen(
@ -876,9 +882,8 @@ class Command(Runner):
# Check if we have a tty
if not self.has_tty:
error = (
"Sudo password required but no TTY available (non-interactive mode). "
"Retry without sudo-requiring options (e.g. use nmap -sT instead of -sS), "
"or configure passwordless sudo."
'Sudo password required but no TTY available (non-interactive mode). '
'Retry without sudo-requiring options (e.g. use nmap -sT instead of -sS), or configure passwordless sudo.'
)
return -1, error