terok-executor 0.2.1__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {terok_executor-0.2.1 → terok_executor-0.3.0}/PKG-INFO +26 -21
- {terok_executor-0.2.1 → terok_executor-0.3.0}/README.md +16 -11
- {terok_executor-0.2.1 → terok_executor-0.3.0}/pyproject.toml +18 -18
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/__init__.py +1 -1
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/cli.py +8 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/commands.py +182 -20
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/container/build.py +117 -37
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/container/env.py +21 -19
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/container/runner.py +135 -52
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/credentials/auth.py +27 -2
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/credentials/extractors.py +1 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/integrations/sandbox.py +2 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/paths.py +34 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/agents/claude.yaml +1 -1
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/agents/codex.yaml +1 -1
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/agents/copilot.yaml +1 -1
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/agents/glab.yaml +6 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/agents/opencode.yaml +1 -1
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/agents/pi.yaml +1 -1
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/agents/vibe.yaml +1 -1
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/hilfe +37 -17
- terok_executor-0.3.0/src/terok_executor/resources/scripts/terok-agents.py +392 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/templates/l1.agent-cli.Dockerfile.template +1 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/roster/loader.py +2 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/roster/schema.py +9 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/roster/types.py +12 -0
- terok_executor-0.2.1/src/terok_executor/resources/scripts/terok-agents.py +0 -227
- {terok_executor-0.2.1 → terok_executor-0.3.0}/LICENSE +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/LICENSES/Apache-2.0.txt +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/_tree.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/_util/__init__.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/_util/_timezone.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/acp/__init__.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/acp/cache.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/acp/daemon.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/acp/endpoint.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/acp/model_options.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/acp/probe.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/acp/proxy.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/acp/roster.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/config.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/config_schema.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/container/__init__.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/container/cache.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/container/inject.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/credentials/__init__.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/credentials/vault_commands.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/credentials/vault_config.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/credentials/vendor_files.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/doctor.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/integrations/__init__.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/krun.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/preflight.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/provider/__init__.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/provider/agents.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/provider/instructions.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/provider/providers.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/provider/wrappers.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/py.typed +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/__init__.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/agents/__init__.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/agents/caddy.yaml +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/agents/coderabbit.yaml +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/agents/gh.yaml +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/agents/sonar.yaml +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/agents/toad.yaml +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/instructions/__init__.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/instructions/default.md +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/providers/anthropic.yaml +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/providers/blablador.yaml +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/providers/coderabbit.yaml +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/providers/github.yaml +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/providers/gitlab.yaml +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/providers/kisski.yaml +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/providers/mistral.yaml +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/providers/openai.yaml +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/providers/openrouter.yaml +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/providers/sonarcloud.yaml +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/Caddyfile +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/__init__.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/allthethings.sh +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/init-ssh-and-repo.sh +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/mistral-model-sync.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/opencode-provider +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/opencode-provider-acp +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/opencode-session-plugin.mjs +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/opencode-toad +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/pi-env.sh +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/pi-git-identity.ts +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/pi-provider +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/pi-vault-routes.ts +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/providers +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/setup-codex-auth.sh +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/terok-acp-env.sh +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/terok-bash-banner.sh +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/terok-claude-acp +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/terok-codex-acp +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/terok-copilot-acp +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/terok-env-git-identity.sh +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/terok-env.sh +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/terok-native-provider +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/terok-opencode-acp +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/terok-toad-entry +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/terok-trust-workspace.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/terok-vibe-acp +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/toad +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/update-all-the-things +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/scripts/vibe-model-sync.sh +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/templates/__init__.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/templates/agent-wrappers.sh.j2 +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/templates/l0.dev.Dockerfile.template +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/templates/l1.sidecar.Dockerfile.template +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/tmux/__init__.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/tmux/container-tmux.conf +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/toad-agents/__init__.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/toad-agents/blablador.helmholtz.de.toml +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/resources/toad-agents/kisski.academiccloud.de.toml +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/roster/__init__.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/sandbox.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/storage.py +0 -0
- {terok_executor-0.2.1 → terok_executor-0.3.0}/src/terok_executor/vault_addr.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: terok-executor
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Single-agent task runner for hardened Podman containers
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
License-File: LICENSE
|
|
@@ -23,15 +23,15 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
23
23
|
Classifier: Programming Language :: Python :: 3.14
|
|
24
24
|
Classifier: Topic :: Software Development :: Quality Assurance
|
|
25
25
|
Classifier: Typing :: Typed
|
|
26
|
-
Requires-Dist: Jinja2 (>=3.1)
|
|
27
|
-
Requires-Dist: agent-client-protocol (
|
|
28
|
-
Requires-Dist: prompt-toolkit (>=3.0)
|
|
29
|
-
Requires-Dist: pydantic (>=2.
|
|
30
|
-
Requires-Dist: rich (>=
|
|
31
|
-
Requires-Dist: ruamel.yaml (
|
|
32
|
-
Requires-Dist: terok-sandbox (>=0.
|
|
33
|
-
Requires-Dist: terok-util (>=0.2.
|
|
34
|
-
Requires-Dist: tomli-w (>=1.0)
|
|
26
|
+
Requires-Dist: Jinja2 (>=3.1,<4.0)
|
|
27
|
+
Requires-Dist: agent-client-protocol (==0.10.1)
|
|
28
|
+
Requires-Dist: prompt-toolkit (>=3.0,<4.0)
|
|
29
|
+
Requires-Dist: pydantic (>=2.13,<3.0)
|
|
30
|
+
Requires-Dist: rich (>=15.0,<16.0)
|
|
31
|
+
Requires-Dist: ruamel.yaml (==0.19.1)
|
|
32
|
+
Requires-Dist: terok-sandbox (>=0.4.0,<0.5.0)
|
|
33
|
+
Requires-Dist: terok-util (>=0.2.1,<0.3.0)
|
|
34
|
+
Requires-Dist: tomli-w (>=1.2,<2.0)
|
|
35
35
|
Project-URL: Changelog, https://github.com/terok-ai/terok-executor/blob/master/CHANGELOG.md
|
|
36
36
|
Project-URL: Documentation, https://terok-ai.github.io/terok-executor/
|
|
37
37
|
Project-URL: Homepage, https://terok-ai.github.io/terok-executor/
|
|
@@ -70,7 +70,7 @@ Python when you want library-grade control.
|
|
|
70
70
|
|
|
71
71
|
```bash
|
|
72
72
|
pip install terok-executor
|
|
73
|
-
terok-executor run claude ~/my-workspace
|
|
73
|
+
terok-executor run claude ~/my-workspace -p "Fix the bug"
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
The first `run` interactively offers any missing prerequisites — sandbox
|
|
@@ -112,16 +112,18 @@ hardening guarantees.
|
|
|
112
112
|
| Claude Code | OAuth*, API key | Anthropic Claude Code |
|
|
113
113
|
| Codex | OAuth*, API key | OpenAI Codex CLI |
|
|
114
114
|
| Vibe | API key | Mistral Vibe |
|
|
115
|
-
|
|
|
115
|
+
| Copilot | — | GitHub Copilot (no vault route yet) |
|
|
116
|
+
| OpenCode | — (uses provider keys) | Harness that drives any OpenAI-compatible provider — curated configs for Helmholtz Blablador, KISSKI AcademicCloud, and OpenRouter (each authenticated with its own API key) |
|
|
117
|
+
| Pi | — (uses provider keys) | Multi-provider harness; routes through the phantom tokens of co-installed providers |
|
|
116
118
|
| gh | OAuth, API key | GitHub CLI |
|
|
117
119
|
| glab | API key | GitLab CLI |
|
|
120
|
+
| SonarCloud | API key | SonarCloud scanner |
|
|
118
121
|
| CodeRabbit | API key | CodeRabbit (sidecar tool) |
|
|
119
|
-
| SonarCloud | API key | SonarCloud scanner (sidecar tool) |
|
|
120
122
|
|
|
121
|
-
\* Claude and Codex OAuth are experimental
|
|
123
|
+
\* Claude and Codex OAuth are experimental.
|
|
122
124
|
|
|
123
|
-
`terok-executor agents` lists the live roster (add `--all` to
|
|
124
|
-
include
|
|
125
|
+
`terok-executor agents list` lists the live roster (add `--all` to
|
|
126
|
+
include tools and harness-driven providers).
|
|
125
127
|
|
|
126
128
|
## Where it sits in the stack
|
|
127
129
|
|
|
@@ -142,13 +144,16 @@ hooks).
|
|
|
142
144
|
| `setup` | Bootstrap sandbox services + container images |
|
|
143
145
|
| `uninstall` | Remove sandbox services + container images |
|
|
144
146
|
| `auth` | Authenticate a provider |
|
|
145
|
-
| `agents` |
|
|
147
|
+
| `agents` | Inspect the agent roster (`list`) and set the build-time default selection (`set`) |
|
|
146
148
|
| `build` | Build base + agent images explicitly |
|
|
147
|
-
| `run-tool` | Run a sidecar tool (CodeRabbit
|
|
148
|
-
| `list` | List
|
|
149
|
-
| `
|
|
149
|
+
| `run-tool` | Run a sidecar tool (CodeRabbit) |
|
|
150
|
+
| `list` | List containers |
|
|
151
|
+
| `start` | Start a stopped container |
|
|
152
|
+
| `stop` | Stop a container (kept for a later `start`) |
|
|
153
|
+
| `rm` | Remove a container and its host-side state |
|
|
150
154
|
| `show-config` | Print the effective `SandboxConfig` as YAML (diffable across orchestrators) |
|
|
151
|
-
| `vault` | Vault management (
|
|
155
|
+
| `vault` | Vault management (status, unlock, lock, list, passphrase, routes, clean) |
|
|
156
|
+
| `sandbox` | Full terok-sandbox command tree (shield, vault, ssh, doctor, …) |
|
|
152
157
|
|
|
153
158
|
### Config override
|
|
154
159
|
|
|
@@ -28,7 +28,7 @@ Python when you want library-grade control.
|
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
30
|
pip install terok-executor
|
|
31
|
-
terok-executor run claude ~/my-workspace
|
|
31
|
+
terok-executor run claude ~/my-workspace -p "Fix the bug"
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
The first `run` interactively offers any missing prerequisites — sandbox
|
|
@@ -70,16 +70,18 @@ hardening guarantees.
|
|
|
70
70
|
| Claude Code | OAuth*, API key | Anthropic Claude Code |
|
|
71
71
|
| Codex | OAuth*, API key | OpenAI Codex CLI |
|
|
72
72
|
| Vibe | API key | Mistral Vibe |
|
|
73
|
-
|
|
|
73
|
+
| Copilot | — | GitHub Copilot (no vault route yet) |
|
|
74
|
+
| OpenCode | — (uses provider keys) | Harness that drives any OpenAI-compatible provider — curated configs for Helmholtz Blablador, KISSKI AcademicCloud, and OpenRouter (each authenticated with its own API key) |
|
|
75
|
+
| Pi | — (uses provider keys) | Multi-provider harness; routes through the phantom tokens of co-installed providers |
|
|
74
76
|
| gh | OAuth, API key | GitHub CLI |
|
|
75
77
|
| glab | API key | GitLab CLI |
|
|
78
|
+
| SonarCloud | API key | SonarCloud scanner |
|
|
76
79
|
| CodeRabbit | API key | CodeRabbit (sidecar tool) |
|
|
77
|
-
| SonarCloud | API key | SonarCloud scanner (sidecar tool) |
|
|
78
80
|
|
|
79
|
-
\* Claude and Codex OAuth are experimental
|
|
81
|
+
\* Claude and Codex OAuth are experimental.
|
|
80
82
|
|
|
81
|
-
`terok-executor agents` lists the live roster (add `--all` to
|
|
82
|
-
include
|
|
83
|
+
`terok-executor agents list` lists the live roster (add `--all` to
|
|
84
|
+
include tools and harness-driven providers).
|
|
83
85
|
|
|
84
86
|
## Where it sits in the stack
|
|
85
87
|
|
|
@@ -100,13 +102,16 @@ hooks).
|
|
|
100
102
|
| `setup` | Bootstrap sandbox services + container images |
|
|
101
103
|
| `uninstall` | Remove sandbox services + container images |
|
|
102
104
|
| `auth` | Authenticate a provider |
|
|
103
|
-
| `agents` |
|
|
105
|
+
| `agents` | Inspect the agent roster (`list`) and set the build-time default selection (`set`) |
|
|
104
106
|
| `build` | Build base + agent images explicitly |
|
|
105
|
-
| `run-tool` | Run a sidecar tool (CodeRabbit
|
|
106
|
-
| `list` | List
|
|
107
|
-
| `
|
|
107
|
+
| `run-tool` | Run a sidecar tool (CodeRabbit) |
|
|
108
|
+
| `list` | List containers |
|
|
109
|
+
| `start` | Start a stopped container |
|
|
110
|
+
| `stop` | Stop a container (kept for a later `start`) |
|
|
111
|
+
| `rm` | Remove a container and its host-side state |
|
|
108
112
|
| `show-config` | Print the effective `SandboxConfig` as YAML (diffable across orchestrators) |
|
|
109
|
-
| `vault` | Vault management (
|
|
113
|
+
| `vault` | Vault management (status, unlock, lock, list, passphrase, routes, clean) |
|
|
114
|
+
| `sandbox` | Full terok-sandbox command tree (shield, vault, ssh, doctor, …) |
|
|
110
115
|
|
|
111
116
|
### Config override
|
|
112
117
|
|
|
@@ -16,20 +16,20 @@ maintainers = [
|
|
|
16
16
|
keywords = ["podman", "containers", "agent", "ai", "coding-agent"]
|
|
17
17
|
requires-python = ">=3.12,<3.15"
|
|
18
18
|
dynamic = ["classifiers"]
|
|
19
|
+
# Dependency pins follow the policy in AGENTS.md ("Dependency Pinning &
|
|
20
|
+
# pyproject.toml Hygiene"). Keep the dependency list comment-free.
|
|
19
21
|
dependencies = [
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"rich>=13.0",
|
|
30
|
-
"agent-client-protocol>=0.10.1",
|
|
22
|
+
"terok-sandbox>=0.4.0,<0.5.0",
|
|
23
|
+
"terok-util>=0.2.1,<0.3.0",
|
|
24
|
+
"ruamel.yaml==0.19.1",
|
|
25
|
+
"Jinja2~=3.1",
|
|
26
|
+
"tomli-w~=1.2",
|
|
27
|
+
"prompt-toolkit~=3.0",
|
|
28
|
+
"pydantic~=2.13",
|
|
29
|
+
"rich~=15.0",
|
|
30
|
+
"agent-client-protocol==0.10.1",
|
|
31
31
|
]
|
|
32
|
-
version = "0.
|
|
32
|
+
version = "0.3.0"
|
|
33
33
|
|
|
34
34
|
[project.urls]
|
|
35
35
|
Homepage = "https://terok-ai.github.io/terok-executor/"
|
|
@@ -60,18 +60,18 @@ packages = [
|
|
|
60
60
|
|
|
61
61
|
[tool.poetry.group.dev.dependencies]
|
|
62
62
|
pre-commit = ">=4.0"
|
|
63
|
-
ruff = ">=0.15.
|
|
63
|
+
ruff = ">=0.15.20"
|
|
64
64
|
bandit = ">=1.7"
|
|
65
65
|
docstr-coverage = "^2.3.2"
|
|
66
|
-
complexipy = ">=
|
|
66
|
+
complexipy = ">=6.0.0"
|
|
67
67
|
vulture = ">=2.12"
|
|
68
68
|
reuse = "^6.2.0"
|
|
69
69
|
tach = "^0.35.0"
|
|
70
70
|
mypy = ">=2.1.0,<3.0"
|
|
71
|
-
import-linter = ">=2.
|
|
71
|
+
import-linter = ">=2.12"
|
|
72
72
|
|
|
73
73
|
[tool.poetry.group.test.dependencies]
|
|
74
|
-
pytest = ">=9.
|
|
74
|
+
pytest = ">=9.1.1"
|
|
75
75
|
pytest-cov = ">=4.0"
|
|
76
76
|
pytest-timeout = ">=2.0"
|
|
77
77
|
|
|
@@ -131,7 +131,7 @@ quote-style = "double"
|
|
|
131
131
|
indent-style = "space"
|
|
132
132
|
docstring-code-format = true
|
|
133
133
|
|
|
134
|
-
# Static type checking
|
|
134
|
+
# Static type checking -- see `make typecheck`.
|
|
135
135
|
# ``resources/`` is excluded entirely: it holds container-side scripts and
|
|
136
136
|
# bundled agent assets that aren't part of the host-side import graph
|
|
137
137
|
# (``resources/toad-agents/`` isn't even a valid Python package name).
|
|
@@ -152,7 +152,7 @@ pretty = true
|
|
|
152
152
|
show_error_codes = true
|
|
153
153
|
|
|
154
154
|
# ``resources/`` holds container-side scripts (run inside task containers, not
|
|
155
|
-
# part of the host import graph
|
|
155
|
+
# part of the host import graph -- the same reason mypy excludes it). Tests
|
|
156
156
|
# exercise them by path-loading (``SourceFileLoader``), which coverage.py can't
|
|
157
157
|
# attribute, so they report 0%; omit them rather than chase phantom misses.
|
|
158
158
|
[tool.coverage.run]
|
|
@@ -20,7 +20,7 @@ in their submodules; reach into ``terok_executor.<sub>`` when you
|
|
|
20
20
|
need them.
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
|
-
__version__: str = "0.
|
|
23
|
+
__version__: str = "0.3.0" # placeholder; replaced at build time
|
|
24
24
|
|
|
25
25
|
from importlib.metadata import PackageNotFoundError, version as _meta_version
|
|
26
26
|
|
|
@@ -36,6 +36,13 @@ except PackageNotFoundError:
|
|
|
36
36
|
__version__ = "0.0.0"
|
|
37
37
|
|
|
38
38
|
|
|
39
|
+
#: Spelling under which sandbox setup is reachable in this front-end;
|
|
40
|
+
#: declared at CLI entry so sandbox-composed re-run hints name a verb
|
|
41
|
+
#: this CLI actually exposes (protocol: env var name, shared by string).
|
|
42
|
+
_SETUP_INVOCATION_ENV = "TEROK_SETUP_INVOCATION"
|
|
43
|
+
_SETUP_INVOCATION = "terok-executor setup"
|
|
44
|
+
|
|
45
|
+
|
|
39
46
|
def main() -> None:
|
|
40
47
|
"""Run the terok-executor CLI.
|
|
41
48
|
|
|
@@ -44,6 +51,7 @@ def main() -> None:
|
|
|
44
51
|
subparser convention, matching the placement used by ``docker`` and
|
|
45
52
|
``kubectl``.
|
|
46
53
|
"""
|
|
54
|
+
os.environ.setdefault(_SETUP_INVOCATION_ENV, _SETUP_INVOCATION)
|
|
47
55
|
parser = argparse.ArgumentParser(
|
|
48
56
|
prog="terok-executor",
|
|
49
57
|
description="Single-agent task runner for hardened Podman containers",
|
|
@@ -202,7 +202,7 @@ def _resolve_host_git_identity() -> tuple[str | None, str | None]:
|
|
|
202
202
|
def _handle_run(
|
|
203
203
|
*,
|
|
204
204
|
agent: str,
|
|
205
|
-
repo: str =
|
|
205
|
+
repo: str | None = None,
|
|
206
206
|
prompt: str | None = None,
|
|
207
207
|
model: str | None = None,
|
|
208
208
|
max_turns: int | None = None,
|
|
@@ -218,6 +218,8 @@ def _handle_run(
|
|
|
218
218
|
gpu: bool = False,
|
|
219
219
|
memory: str | None = None,
|
|
220
220
|
cpus: str | None = None,
|
|
221
|
+
workspace: str | None = None,
|
|
222
|
+
ephemeral: bool = False,
|
|
221
223
|
git_identity_from_host: bool = False,
|
|
222
224
|
shared_dir: str | None = None,
|
|
223
225
|
shared_mount: str = "/shared",
|
|
@@ -249,6 +251,11 @@ def _handle_run(
|
|
|
249
251
|
else:
|
|
250
252
|
print("Warning: --git-identity-from-host: git config user.name not set, skipping")
|
|
251
253
|
|
|
254
|
+
# Bare ``run <agent>`` works on an isolated clone of the current repo;
|
|
255
|
+
# with --workspace the mounted directory's own content is the default.
|
|
256
|
+
if repo is None and workspace is None:
|
|
257
|
+
repo = "."
|
|
258
|
+
|
|
252
259
|
effective_gate = gate and not no_gate
|
|
253
260
|
runner = AgentRunner(base_image=base, family=family, cfg=cfg)
|
|
254
261
|
resolved_shared_dir = Path(shared_dir) if shared_dir else None
|
|
@@ -260,6 +267,8 @@ def _handle_run(
|
|
|
260
267
|
"gpu": gpu,
|
|
261
268
|
"memory": memory,
|
|
262
269
|
"cpus": cpus,
|
|
270
|
+
"workspace": Path(workspace) if workspace else None,
|
|
271
|
+
"ephemeral": ephemeral,
|
|
263
272
|
"human_name": human_name,
|
|
264
273
|
"human_email": human_email,
|
|
265
274
|
"authorship": authorship,
|
|
@@ -295,12 +304,14 @@ def _handle_run(
|
|
|
295
304
|
def _handle_run_tool(
|
|
296
305
|
*,
|
|
297
306
|
tool: str,
|
|
298
|
-
repo: str =
|
|
307
|
+
repo: str | None = None,
|
|
299
308
|
branch: str | None = None,
|
|
300
309
|
gate: bool = True,
|
|
301
310
|
no_gate: bool = False,
|
|
302
311
|
name: str | None = None,
|
|
303
312
|
timeout: int = 600,
|
|
313
|
+
workspace: str | None = None,
|
|
314
|
+
ephemeral: bool = False,
|
|
304
315
|
tool_args: list[str] | None = None,
|
|
305
316
|
base: str = DEFAULT_BASE_IMAGE,
|
|
306
317
|
family: str | None = None,
|
|
@@ -318,6 +329,11 @@ def _handle_run_tool(
|
|
|
318
329
|
|
|
319
330
|
from .container.runner import AgentRunner
|
|
320
331
|
|
|
332
|
+
# Same default policy as ``run``: bare invocation works on an isolated
|
|
333
|
+
# clone of the current repo; --workspace brings its own content.
|
|
334
|
+
if repo is None and workspace is None:
|
|
335
|
+
repo = "."
|
|
336
|
+
|
|
321
337
|
effective_gate = gate and not no_gate
|
|
322
338
|
runner = AgentRunner(base_image=base, family=family, cfg=cfg)
|
|
323
339
|
cname = runner.run_tool(
|
|
@@ -328,6 +344,8 @@ def _handle_run_tool(
|
|
|
328
344
|
gate=effective_gate,
|
|
329
345
|
name=name,
|
|
330
346
|
timeout=timeout,
|
|
347
|
+
workspace=Path(workspace) if workspace else None,
|
|
348
|
+
ephemeral=ephemeral,
|
|
331
349
|
timezone=timezone,
|
|
332
350
|
)
|
|
333
351
|
print(f"Container: {cname}")
|
|
@@ -338,10 +356,27 @@ def _handle_auth(
|
|
|
338
356
|
agent: str,
|
|
339
357
|
api_key: str | None = None,
|
|
340
358
|
base_image: str | None = None,
|
|
359
|
+
device_auth: bool = False,
|
|
341
360
|
) -> None:
|
|
342
|
-
"""Run auth flow for an agent.
|
|
361
|
+
"""Run auth flow for an agent.
|
|
362
|
+
|
|
363
|
+
With *device_auth* the interactive method chooser is skipped and the
|
|
364
|
+
provider's headless device-code login runs directly — for remote or
|
|
365
|
+
headless hosts where the browser callback can't open. ``--api-key`` and
|
|
366
|
+
``--device-auth`` are mutually exclusive; passing both takes the API-key
|
|
367
|
+
route (no container) and warns that ``--device-auth`` was ignored.
|
|
368
|
+
"""
|
|
343
369
|
from .credentials.auth import AUTH_PROVIDERS, Authenticator, store_api_key
|
|
344
370
|
|
|
371
|
+
if api_key is not None and device_auth:
|
|
372
|
+
import sys
|
|
373
|
+
|
|
374
|
+
print(
|
|
375
|
+
"Warning: --device-auth is ignored when --api-key is given; "
|
|
376
|
+
"the API key takes precedence (no auth container is launched).",
|
|
377
|
+
file=sys.stderr,
|
|
378
|
+
)
|
|
379
|
+
|
|
345
380
|
if api_key is not None:
|
|
346
381
|
if not api_key.strip():
|
|
347
382
|
raise SystemExit("API key cannot be empty.")
|
|
@@ -361,6 +396,7 @@ def _handle_auth(
|
|
|
361
396
|
None,
|
|
362
397
|
mounts_dir=mounts_dir(),
|
|
363
398
|
image=lambda: ImageBuilder(base).ensure_default_l1(),
|
|
399
|
+
device_auth=device_auth,
|
|
364
400
|
)
|
|
365
401
|
|
|
366
402
|
# Write vault URLs to shared config files (e.g. Vibe config.toml, gh config.yml)
|
|
@@ -455,12 +491,27 @@ def _handle_build(
|
|
|
455
491
|
|
|
456
492
|
|
|
457
493
|
def _handle_list() -> None:
|
|
458
|
-
"""List
|
|
494
|
+
"""List executor-managed containers and their states.
|
|
495
|
+
|
|
496
|
+
Two name sources meet here: the ``terok-executor-`` default-name
|
|
497
|
+
prefix, and the per-container state dirs under
|
|
498
|
+
[`container_state_root`][terok_executor.paths.container_state_root]
|
|
499
|
+
— the latter makes ``--name`` overrides visible. Podman stays the
|
|
500
|
+
truth for liveness: the dirs only contribute names to ask about,
|
|
501
|
+
and a name whose container is gone is skipped.
|
|
502
|
+
"""
|
|
459
503
|
from terok_executor.integrations.sandbox import PodmanRuntime
|
|
504
|
+
from terok_executor.paths import container_state_root
|
|
460
505
|
|
|
461
|
-
|
|
506
|
+
runtime = PodmanRuntime()
|
|
507
|
+
states = runtime.container_states("terok-executor")
|
|
508
|
+
run_root = container_state_root()
|
|
509
|
+
named = (p.name for p in run_root.iterdir() if p.is_dir()) if run_root.is_dir() else ()
|
|
510
|
+
for name in named:
|
|
511
|
+
if name not in states and (state := runtime.container(name).state) is not None:
|
|
512
|
+
states[name] = state
|
|
462
513
|
if not states:
|
|
463
|
-
print("No
|
|
514
|
+
print("No containers.")
|
|
464
515
|
return
|
|
465
516
|
for name, state in sorted(states.items()):
|
|
466
517
|
print(f"{name} {state}")
|
|
@@ -510,19 +561,57 @@ def _handle_show_config(*, cfg: SandboxConfig | None = None) -> None:
|
|
|
510
561
|
yaml.dump(data, sys.stdout)
|
|
511
562
|
|
|
512
563
|
|
|
513
|
-
def
|
|
514
|
-
"""
|
|
515
|
-
from terok_executor.integrations.sandbox import PodmanRuntime
|
|
564
|
+
def _handle_start(*, name: str) -> None:
|
|
565
|
+
"""Start a stopped container, re-establishing its host scaffolding."""
|
|
566
|
+
from terok_executor.integrations.sandbox import PodmanRuntime, Sandbox
|
|
516
567
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
568
|
+
try:
|
|
569
|
+
Sandbox(runtime=PodmanRuntime()).start(name)
|
|
570
|
+
except RuntimeError as exc:
|
|
571
|
+
raise SystemExit(str(exc)) from exc
|
|
572
|
+
print(f"Started: {name}")
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
def _handle_stop(*, name: str, timeout: int = 10) -> None:
|
|
576
|
+
"""Stop a container, keeping it for a later ``start``.
|
|
577
|
+
|
|
578
|
+
A missing container is an error, exactly as ``podman stop`` treats
|
|
579
|
+
it — the facade's ``RuntimeError`` carries podman's own message.
|
|
580
|
+
"""
|
|
581
|
+
from terok_executor.integrations.sandbox import PodmanRuntime, Sandbox
|
|
582
|
+
|
|
583
|
+
try:
|
|
584
|
+
Sandbox(runtime=PodmanRuntime()).stop([name], timeout=timeout)
|
|
585
|
+
except RuntimeError as exc:
|
|
586
|
+
raise SystemExit(str(exc)) from exc
|
|
523
587
|
print(f"Stopped: {name}")
|
|
524
588
|
|
|
525
589
|
|
|
590
|
+
def _handle_rm(*, name: str) -> None:
|
|
591
|
+
"""Remove a container together with its host-side state.
|
|
592
|
+
|
|
593
|
+
Also sweeps the per-container state when the container is already
|
|
594
|
+
gone — the one situation (crash, out-of-band ``podman rm``) where
|
|
595
|
+
residue outlives its container.
|
|
596
|
+
"""
|
|
597
|
+
import shutil
|
|
598
|
+
|
|
599
|
+
from terok_executor.integrations.sandbox import (
|
|
600
|
+
PodmanRuntime,
|
|
601
|
+
Sandbox,
|
|
602
|
+
remove_container_state,
|
|
603
|
+
)
|
|
604
|
+
from terok_executor.paths import container_state_dir
|
|
605
|
+
|
|
606
|
+
sandbox = Sandbox(runtime=PodmanRuntime())
|
|
607
|
+
[result] = sandbox.rm([name])
|
|
608
|
+
if not result.removed:
|
|
609
|
+
raise SystemExit(f"Could not remove {name}: {result.error}")
|
|
610
|
+
remove_container_state(name, cfg=sandbox.config)
|
|
611
|
+
shutil.rmtree(container_state_dir(name), ignore_errors=True)
|
|
612
|
+
print(f"Removed: {name}")
|
|
613
|
+
|
|
614
|
+
|
|
526
615
|
def _handle_setup(
|
|
527
616
|
*,
|
|
528
617
|
check: bool = False,
|
|
@@ -530,6 +619,7 @@ def _handle_setup(
|
|
|
530
619
|
no_images: bool = False,
|
|
531
620
|
base: str = DEFAULT_BASE_IMAGE,
|
|
532
621
|
family: str | None = None,
|
|
622
|
+
passphrase_tier: str | None = None,
|
|
533
623
|
cfg: SandboxConfig | None = None,
|
|
534
624
|
) -> None:
|
|
535
625
|
"""Bootstrap the full terok-executor stack on a fresh host.
|
|
@@ -546,7 +636,7 @@ def _handle_setup(
|
|
|
546
636
|
if not no_sandbox:
|
|
547
637
|
from .sandbox import ensure_sandbox_ready
|
|
548
638
|
|
|
549
|
-
ensure_sandbox_ready(cfg=cfg)
|
|
639
|
+
ensure_sandbox_ready(cfg=cfg, passphrase_tier=passphrase_tier)
|
|
550
640
|
|
|
551
641
|
if not no_images:
|
|
552
642
|
_build_images_with_banner(base, family)
|
|
@@ -656,7 +746,13 @@ RUN_COMMAND = CommandDef(
|
|
|
656
746
|
handler=_handle_run,
|
|
657
747
|
args=(
|
|
658
748
|
ArgDef(name="agent", help="Agent name (claude, codex, vibe, ...)"),
|
|
659
|
-
ArgDef(
|
|
749
|
+
ArgDef(
|
|
750
|
+
name="repo",
|
|
751
|
+
nargs="?",
|
|
752
|
+
default=None,
|
|
753
|
+
help="Git URL or local dir cloned into the workspace via the gate "
|
|
754
|
+
"(default: . — unless --workspace brings its own content)",
|
|
755
|
+
),
|
|
660
756
|
ArgDef(name="-p", dest="prompt", help="Prompt for headless mode"),
|
|
661
757
|
ArgDef(name="-m", dest="model", help="Model override"),
|
|
662
758
|
ArgDef(name="--max-turns", type=int, help="Maximum agent turns"),
|
|
@@ -676,6 +772,17 @@ RUN_COMMAND = CommandDef(
|
|
|
676
772
|
ArgDef(name="--gpu", action="store_true", help="Enable GPU passthrough"),
|
|
677
773
|
ArgDef(name="--memory", help="Container memory limit (e.g. 4g, 512m)"),
|
|
678
774
|
ArgDef(name="--cpus", help="Container CPU limit (e.g. 2.0, 0.5)"),
|
|
775
|
+
ArgDef(
|
|
776
|
+
name="--workspace",
|
|
777
|
+
help="Host directory to mount at /workspace "
|
|
778
|
+
"(default: the workspace lives in the container)",
|
|
779
|
+
),
|
|
780
|
+
ArgDef(
|
|
781
|
+
name="--rm",
|
|
782
|
+
dest="ephemeral",
|
|
783
|
+
action="store_true",
|
|
784
|
+
help="Remove the container when it exits (podman --rm)",
|
|
785
|
+
),
|
|
679
786
|
ArgDef(
|
|
680
787
|
name="--git-identity-from-host",
|
|
681
788
|
action="store_true",
|
|
@@ -726,12 +833,29 @@ RUN_TOOL_COMMAND = CommandDef(
|
|
|
726
833
|
handler=_handle_run_tool,
|
|
727
834
|
args=(
|
|
728
835
|
ArgDef(name="tool", help="Tool name (coderabbit)"),
|
|
729
|
-
ArgDef(
|
|
836
|
+
ArgDef(
|
|
837
|
+
name="repo",
|
|
838
|
+
nargs="?",
|
|
839
|
+
default=None,
|
|
840
|
+
help="Git URL or local dir cloned into the workspace via the gate "
|
|
841
|
+
"(default: . — unless --workspace brings its own content)",
|
|
842
|
+
),
|
|
730
843
|
ArgDef(name="--branch", help="Git branch to check out"),
|
|
731
844
|
ArgDef(name="--gate", action="store_true", default=True, help="Use gate (default)"),
|
|
732
845
|
ArgDef(name="--no-gate", action="store_true", help="Disable gate"),
|
|
733
846
|
ArgDef(name="--name", help="Container name override"),
|
|
734
847
|
ArgDef(name="--timeout", type=int, default=600, help="Timeout in seconds (default: 600)"),
|
|
848
|
+
ArgDef(
|
|
849
|
+
name="--workspace",
|
|
850
|
+
help="Host directory to mount at /workspace "
|
|
851
|
+
"(default: the workspace lives in the container)",
|
|
852
|
+
),
|
|
853
|
+
ArgDef(
|
|
854
|
+
name="--rm",
|
|
855
|
+
dest="ephemeral",
|
|
856
|
+
action="store_true",
|
|
857
|
+
help="Remove the container when it exits (podman --rm)",
|
|
858
|
+
),
|
|
735
859
|
ArgDef(name="tool_args", nargs="*", help="Extra args passed to the tool (after --)"),
|
|
736
860
|
ArgDef(
|
|
737
861
|
name="--base",
|
|
@@ -773,6 +897,11 @@ AUTH_COMMAND = CommandDef(
|
|
|
773
897
|
args=(
|
|
774
898
|
ArgDef(name="agent", help="Agent or tool name (claude, codex, gh, ...)"),
|
|
775
899
|
ArgDef(name="--api-key", help="Store an API key directly (skip interactive auth)"),
|
|
900
|
+
ArgDef(
|
|
901
|
+
name="--device-auth",
|
|
902
|
+
action="store_true",
|
|
903
|
+
help="Force the headless device-code login (skip the method chooser)",
|
|
904
|
+
),
|
|
776
905
|
ArgDef(
|
|
777
906
|
name="--base-image",
|
|
778
907
|
help=(
|
|
@@ -871,7 +1000,7 @@ ACP_COMMAND = CommandDef(
|
|
|
871
1000
|
)
|
|
872
1001
|
|
|
873
1002
|
|
|
874
|
-
LIST_COMMAND = CommandDef(name="list", help="List
|
|
1003
|
+
LIST_COMMAND = CommandDef(name="list", help="List containers", handler=_handle_list)
|
|
875
1004
|
|
|
876
1005
|
SHOW_CONFIG_COMMAND = CommandDef(
|
|
877
1006
|
name="show-config",
|
|
@@ -879,10 +1008,32 @@ SHOW_CONFIG_COMMAND = CommandDef(
|
|
|
879
1008
|
handler=_handle_show_config,
|
|
880
1009
|
)
|
|
881
1010
|
|
|
1011
|
+
START_COMMAND = CommandDef(
|
|
1012
|
+
name="start",
|
|
1013
|
+
help="Start a stopped container",
|
|
1014
|
+
handler=_handle_start,
|
|
1015
|
+
args=(ArgDef(name="name", help="Container name"),),
|
|
1016
|
+
)
|
|
1017
|
+
|
|
882
1018
|
STOP_COMMAND = CommandDef(
|
|
883
1019
|
name="stop",
|
|
884
|
-
help="Stop a
|
|
1020
|
+
help="Stop a container (kept for a later start)",
|
|
885
1021
|
handler=_handle_stop,
|
|
1022
|
+
args=(
|
|
1023
|
+
ArgDef(name="name", help="Container name"),
|
|
1024
|
+
ArgDef(
|
|
1025
|
+
name="--timeout",
|
|
1026
|
+
type=int,
|
|
1027
|
+
default=10,
|
|
1028
|
+
help="Seconds before the stop escalates to SIGKILL (default: 10)",
|
|
1029
|
+
),
|
|
1030
|
+
),
|
|
1031
|
+
)
|
|
1032
|
+
|
|
1033
|
+
RM_COMMAND = CommandDef(
|
|
1034
|
+
name="rm",
|
|
1035
|
+
help="Remove a container and its host-side state",
|
|
1036
|
+
handler=_handle_rm,
|
|
886
1037
|
args=(ArgDef(name="name", help="Container name"),),
|
|
887
1038
|
)
|
|
888
1039
|
|
|
@@ -918,6 +1069,15 @@ SETUP_COMMAND = CommandDef(
|
|
|
918
1069
|
default=None,
|
|
919
1070
|
help="Override package family for unknown base images (deb or rpm)",
|
|
920
1071
|
),
|
|
1072
|
+
ArgDef(
|
|
1073
|
+
name="--passphrase-tier",
|
|
1074
|
+
default=None,
|
|
1075
|
+
help=(
|
|
1076
|
+
"Force credentials-DB passphrase storage to a specific tier"
|
|
1077
|
+
" (systemd-creds | keyring | session-file | config); required"
|
|
1078
|
+
" on a non-TTY host without systemd-creds"
|
|
1079
|
+
),
|
|
1080
|
+
),
|
|
921
1081
|
),
|
|
922
1082
|
)
|
|
923
1083
|
|
|
@@ -956,7 +1116,9 @@ COMMANDS: tuple[CommandDef, ...] = (
|
|
|
956
1116
|
SETUP_COMMAND,
|
|
957
1117
|
UNINSTALL_COMMAND,
|
|
958
1118
|
LIST_COMMAND,
|
|
1119
|
+
START_COMMAND,
|
|
959
1120
|
STOP_COMMAND,
|
|
1121
|
+
RM_COMMAND,
|
|
960
1122
|
SHOW_CONFIG_COMMAND,
|
|
961
1123
|
ACP_COMMAND,
|
|
962
1124
|
)
|