brbzull0 opened a new pull request, #13070:
URL: https://github.com/apache/trafficserver/pull/13070
## Summary
Introduce `plugin.yaml`, a YAML-based configuration file for global plugins
that replaces the legacy line-based `plugin.config` format. When both files
exist, `plugin.yaml` takes precedence; `plugin.config` is used as a fallback.
**New??? capabilities over `plugin.config`:**
- **`enabled: false`** — replaces the old practice of commenting out lines
in `plugin.config` to disable a plugin. In YAML, commenting out a multi-line
plugin entry (path, params, etc) is more cumbersome than commenting a single
line in the old format. With `enabled: false` the entire entry stays in the
file for visibility and easy re-enabling, but the plugin is completely skipped
at startup (no `dlopen`, no `TSPluginInit`).
- **`load_order`** — optional integer that controls plugin loading priority.
By default, plugins load top-to-bottom in YAML sequence order (same as
`plugin.config`). When `load_order` is set, those plugins load first sorted by
ascending value; plugins sharing the same value keep their relative file order
(stable sort). Plugins without `load_order` load after all ordered ones. Most
deployments won't need this — reordering a single line in `plugin.config` was
trivial, but moving a multi-line YAML block is more error-prone, so
`load_order` exists to let you change loading priority without rearranging
entries. Useful for quick testing and troubleshooting, or when automation tools
may reorder entries.
- **`params`** — YAML sequence of string arguments with `$record` variable
expansion
- **Startup logging** — each plugin produces a `NOTE`-level log line with
its index, path, and load/skip status:
```
[NOTE] plugin.yaml loading ...
[NOTE] plugin #1 loading: stats_over_http.so
[NOTE] plugin #2 loading: header_rewrite.so (load_order: 10)
[NOTE] plugin #3 skipped: experimental_plugin.so (enabled: false)
[NOTE] plugin.yaml: 2 plugins loaded, 1 disabled
[NOTE] #1 stats_over_http.so loaded
[NOTE] #2 header_rewrite.so load_order: 10 loaded
[NOTE] -- experimental_plugin.so disabled
```
- **`traffic_ctl plugin list`** — new JSONRPC-based CLI command for runtime
introspection of loaded plugins:
```
$ traffic_ctl plugin list
source: plugin.yaml
# plugin load_order status
1 stats_over_http.so -- loaded
2 header_rewrite.so 10 loaded
3 experimental_plugin.so -- disabled
```
- **`traffic_ctl config convert plugin_config`** — automated migration tool
that converts `plugin.config` to `plugin.yaml`; commented-out lines become
`enabled: false` entries (use `--skip-disabled` to omit them entirely)
### Example
```yaml
plugins:
- path: stats_over_http.so
- path: header_rewrite.so
params:
- etc/trafficserver/header_rewrite.config
- path: experimental_plugin.so
enabled: false # was commented out in plugin.config
params:
- --verbose
```
---
## Feedback requested: Inline `config` field
I take the liberty to add this feature to this PR, a `config` field that
allows embedding a plugin's configuration directly in `plugin.yaml` instead of
maintaining a separate file. This is intended for quick tests and simple
configs where a standalone file is overkill.
### How it works
The `config` field accepts a YAML block scalar (`|`). At startup the literal
text is written to a temporary file in the config directory (named
`.<plugin_name>_inline_<index>.conf`) and the path is passed to the plugin as
an argument. Existing plugins work without code changes — they receive a file
path in `argv` just as they do today.
The inline config file path is inserted as a **bare positional argument** at
`argv[1]`, before any `params` entries. This works for the common convention
where plugins take a config file as their first argument (e.g.,
`header_rewrite.so`, `txn_box.so`). Plugins that require a flag before the
filename (e.g., `--config <file>`) should use `params` with a separate file
instead.
### Why block scalar only
Only literal block scalars (`|`) are accepted. Structured YAML (mappings,
sequences) is rejected. The reason: re-serializing structured YAML through
`YAML::Emitter` loses quoting semantics. Plugins like `txn_box` assign meaning
to YAML quoting (e.g., `"literal"` vs `extractor-name`), and round-tripping
through an emitter strips those quotes. A block scalar preserves the exact text
the operator wrote.
### Example
```yaml
plugins:
- path: header_rewrite.so
config: |
cond %{SEND_RESPONSE_HDR_HOOK}
set-header X-Custom "hello"
- path: txn_box.so
config: |
txn_box:
when: proxy-rsp
do:
- proxy-rsp-field<X-TxnBox>: "inline-config-active"
```
### Future
I think we should introduce a new TS API to let plugins retrieve inline
config directly, but that belongs in a separate PR. This API could also be
useful during config reload when injecting configuration via the RPC(for
reloadable plugins) — but that's another story.
### Notes
- The block scalar restriction is intentional for now — re-serializing
structured YAML through `YAML::Emitter` strips quoting that plugins like
`txn_box` rely on. Supporting structured YAML can be revisited if needed.
- Temporary inline config files are cleaned up at startup before new ones
are created (matching the `PluginFactory::cleanup()` pattern). This handles
both graceful shutdowns and crashes.
Part of https://github.com/apache/trafficserver/issues/12753
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]