-
Notifications
You must be signed in to change notification settings - Fork 2
Plugins
Strut ships a lightweight plugin system so operators can extend the CLI with
project-specific commands without forking the engine. Drop a cmd_<name>.sh
file in .strut/plugins/ under your project root and strut will discover it
at startup and dispatch strut <name> or strut <stack> <name> to it.
Strut's core commands are deliberately generic. Teams often have workflows
on top of them — a blessed deploy-and-announce pipeline, a custom metrics
pull, a bespoke bulk rotation — that shouldn't live in the engine. Plugins
give you the familiar strut … namespace for those workflows while keeping
strut itself upgradeable.
my-project/
├── strut.conf
├── stacks/
│ └── api/
└── .strut/
└── plugins/
├── cmd_ship.sh # strut <stack> ship
├── cmd_announce.sh # strut announce "..."
└── cmd_metrics.sh # strut <stack> metrics
Plugins live under ${PROJECT_ROOT}/.strut/plugins/. The filename must
match cmd_<name>.sh; everything else is ignored. The <name> portion is
the command name operators will type.
Every plugin file must define plugin_main. plugin_help is optional but
strongly recommended — it's what strut list plugins and strut help <name>
show.
#!/usr/bin/env bash
# .strut/plugins/cmd_ship.sh
set -euo pipefail
plugin_help() {
echo "Validate, deploy, then announce to #releases"
}
plugin_main() {
local stack="$1"; local env_name="$2"; shift 2
strut "$stack" validate --env "$env_name"
strut "$stack" deploy --env "$env_name"
strut notify test slack
}-
Top-level plugins —
strut <plugin> [args…].plugin_mainreceives the raw args. -
Stack-level plugins —
strut <stack> <plugin> [--env <name>] [args…]. Strut parses the universal flags (--env,--services,--json,--dry-run) before calling you, then invokesplugin_main "$stack" "$env_name" "<remaining-args>". The first two positional args are always stack name and env name.
Plugins are sourced in a subshell after all of strut's libraries are loaded, so you have direct access to strut's helpers:
| Helper | Purpose |
|---|---|
log, ok, warn, fail, error
|
logging primitives |
run_cmd, run_cmd_eval
|
dry-run aware command execution |
build_ssh_opts |
consistent SSH option builder |
resolve_compose_cmd |
stack-scoped docker-compose project naming |
out_table_header, out_table_row, out_table_render
|
table output |
out_json_object, out_json_field, … |
streamed JSON output |
Calling strut itself is fully supported — plugins are re-entrant.
- After strut loads its core libraries, it scans
${PROJECT_ROOT}/.strut/plugins/forcmd_*.shfiles. - The plugin registry records each name and file path — no sourcing yet.
- When a command name comes in:
-
Core commands always win.
strut deploy,strut list,strut doctoretc. never get routed to a plugin of the same name. -
Stacks always win. At the top level, if
$1is a stack directory, strut dispatches to the stack regardless of plugin names. You can't shadow a stack. - Otherwise, if a plugin matches, strut sources the file in a subshell
and invokes
plugin_main.
-
Core commands always win.
-
strut list pluginsrenders the registry;strut help <plugin>runs the plugin'splugin_help.
strut list plugins # table view
strut list plugins --json # machine-readable
strut help ship # runs plugin_help from cmd_ship.sh-
Subshell isolation. Plugin code runs in a
(...)subshell. A plugin that callsexit 1, hitsset -e, or gets killed does not crash strut. - Operator privileges. Plugins run with the same permissions as the shell invoking strut — no sandbox. Only ship plugins you trust.
-
Core precedence. A plugin named
cmd_deploy.shwill never run asstrut <stack> deploy. Plugin names must not collide with core commands (usecmd_ship.shetc.).
$ mkdir -p .strut/plugins
$ cat > .strut/plugins/cmd_ship.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
plugin_help() {
echo "Validate + deploy + post-deploy hook"
}
plugin_main() {
local stack="$1" env="$2"
log "shipping $stack to $env"
strut "$stack" validate --env "$env"
strut "$stack" deploy --env "$env"
ok "shipped $stack → $env"
}
EOF
$ strut list plugins
Plugins:
Name Description File
---- --------------------------------- --------------------------------
ship Validate + deploy + post-deploy … /path/.strut/plugins/cmd_ship.sh
$ strut api ship --env prodThe lib/plugins.sh module is itself covered by tests/test_plugins.bats,
which doubles as a working reference for plugin authors — it shows how to
structure a plugin and assert its behavior end-to-end through the strut
entrypoint.
strut · v0.28.0 · Report an Issue
Getting Started
Core Concepts
Operations
- Deployment
- Ship and Rebuild
- GitHub Action
- Webhook Automation
- Remote Host Setup
- Provisioning
- Blue-Green Deploy
- Deploy Rollback
- Database Backups
- Secrets Management
- Stack Groups
- Lifecycle Hooks
- Notifications
- Key Rotation
- Drift Detection
- Domain and SSL
- Certificate Management
- Gateway Management
- Monitoring
- Volume Management
Advanced
- Security Posture
- VPS Audit and Migration
- Stack Validation
- Data Anonymization
- Debugging
- Local Development
Extending
Contributing