Metadata-Version: 2.4
Name: sonata-tasks
Version: 0.6.6
Summary: Reusable task catalogue for the Sonata workflow engine
Author-email: miciav <5889596+miciav@users.noreply.github.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/Nanofaas/sonata
Project-URL: Repository, https://github.com/Nanofaas/sonata
Project-URL: Issues, https://github.com/Nanofaas/sonata/issues
Keywords: workflow,tasks,catalogue,orchestration,devops
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Distributed Computing
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: sonata-engine==0.6.6
Provides-Extra: shell
Requires-Dist: subprocess-toolkit==0.6.0; extra == "shell"
Provides-Extra: prometheus
Requires-Dist: httpx>=0.27; extra == "prometheus"
Provides-Extra: multipass
Requires-Dist: multipass-vm-sdk==0.6.0; extra == "multipass"
Requires-Dist: pydantic>=2.9.2; extra == "multipass"
Requires-Dist: subprocess-toolkit==0.6.0; extra == "multipass"
Provides-Extra: azure
Requires-Dist: azure-vm-sdk==0.6.0; extra == "azure"
Requires-Dist: pydantic>=2.9.2; extra == "azure"
Requires-Dist: subprocess-toolkit==0.6.0; extra == "azure"
Provides-Extra: proxmox
Requires-Dist: proxmox-vm-sdk==0.6.0; extra == "proxmox"
Requires-Dist: pydantic>=2.9.2; extra == "proxmox"
Requires-Dist: subprocess-toolkit==0.6.0; extra == "proxmox"
Dynamic: license-file

# sonata-tasks

Reusable, product-independent tasks for `sonata-engine`. The base installation
contains command execution contracts and common command-line tool tasks.
Provider and transport integrations are installed through optional extras.

The base catalogue includes Kubernetes namespace ownership, port forwarding,
Pod and OCI image inspection, and Minikube profile preflight in
`sonata_tasks.kubectl`, `sonata_tasks.imagetools`, and `sonata_tasks.minikube`.
`sonata_tasks.vm.logged` provides bounded VM command output with a complete
log copied to the host. Callers supply their own executor, VM provider, and
product-specific image checks.

`sonata_tasks.containerd` inspects a caller-owned container and its image using
caller-supplied commands, then checks the runtime image reference and published
manifest digest. The caller controls namespace, rootless session, and evidence
storage; the task has no NanoLab or recipe dependency.

With the `shell` extra, `sonata_tasks.shell.SubprocessShell` streams stdout and
stderr to the active workflow sink, including when no output listener is
provided. An explicit listener receives each line as well; command results
still contain the complete output and exit code.

`sonata_tasks.process` also exports `OwnedCommandRunner`, `OwnedCommandResult`
and `run_owned_command` for bounded local Linux commands. They require procfs,
pidfds and subreaper support. An isolated supervisor owns and reaps descendants,
including children that create their own sessions, without changing the caller's
subreaper state or signaling unrelated processes. Output goes to an exclusive
log file; optional framed summaries share the same byte budget.

```python
import os
import sys
from pathlib import Path
from threading import Event

from sonata_tasks.process import run_owned_command

result = run_owned_command(
    [sys.executable, "-c", "print('ordinary application command')"],
    cwd=Path.cwd(),
    env=os.environ,
    log_path=Path("command.log"),
    timeout_s=30,
    cancelled=Event(),
    output_limit_bytes=1024 * 1024,
)
print(result)
```

The result records exit status, cancellation, timeout, quota exhaustion, forced
stops and confirmed reaping. A zero exit code alone is insufficient to declare
success. `OwnedCommandRunner.stop(timeout_s)` requires at least 0.1 seconds for
descendant cleanup; a runner executes only once. Linux restrictions apply to this
API, while the existing `managed_process_resource` remains portable.

The implementation in `sonata_tasks.owned_process` uses only the standard
library. A worker that cannot install the catalogue may copy that module from
its installed distribution, preserving the distribution version and verifying
the source digest. It does not need the workflow engine at worker runtime.
