Skip to content

[TS API] Add plugin API for the config reload framework.#13146

Draft
brbzull0 wants to merge 5 commits intoapache:masterfrom
brbzull0:plugin-config-registry-api-v2
Draft

[TS API] Add plugin API for the config reload framework.#13146
brbzull0 wants to merge 5 commits intoapache:masterfrom
brbzull0:plugin-config-registry-api-v2

Conversation

@brbzull0
Copy link
Copy Markdown
Contributor

@brbzull0 brbzull0 commented May 8, 2026

Adds a small TSCfg* plugin-facing API that lets plugins register
configuration files with the same reload framework core configs
already use (ConfigRegistry / ConfigContext). Plugin reloads then
surface in traffic_ctl config status with full state tracking,
can receive RPC payloads, and follow the deferred-completion
contract - none of which were available via TSMgmtUpdateRegister.

Motivation

Today, plugins react to traffic_ctl config reload only via
TSMgmtUpdateRegister. That gives them a notification but nothing
else: no per-key targeting, no payload, no _reload directives,
no companion files, no way to surface reload outcome in config status. Every plugin that wants config-reload behaviour ends up
re-implementing pieces of the framework - regex_revalidate, for
example, ships its own file-mtime watcher.

This PR exposes the framework directly so plugins integrate with
it instead of re-implementing it.

New API surface

Types & enums (in include/ts/apidefs.h.in)

Registration (called from TSPluginInit)

Function Declaration Implementation
TSCfgRegister ts.h:1285 InkAPI.cc:3335
TSCfgAttachReloadTrigger ts.h:1330 InkAPI.cc:3409
TSCfgAddFileDependency ts.h:1347 InkAPI.cc:3435

Per-reload context (used inside the plugin's TSCfgLoadCb)

Function Declaration Implementation
TSCfgLoadCtxInProgress ts.h:1371 InkAPI.cc:3519
TSCfgLoadCtxComplete ts.h:1384 InkAPI.cc:3535
TSCfgLoadCtxFail ts.h:1397 InkAPI.cc:3541
TSCfgLoadCtxAddLog ts.h:1412 InkAPI.cc:3547
TSCfgLoadCtxAddSubtask ts.h:1427 InkAPI.cc:3572
TSCfgLoadCtxGetFilename ts.h:1460 InkAPI.cc:3596
TSCfgLoadCtxGetReloadToken ts.h:1476 InkAPI.cc:3608
TSCfgLoadCtxGetSuppliedYaml ts.h:1490 InkAPI.cc:3620
TSCfgLoadCtxGetReloadDirectives ts.h:1503 InkAPI.cc:3636

What this gives plugins, on top of TSMgmtUpdateRegister

  • Per-key targeting - handler runs only when this plugin's
    registered file or trigger record actually changes.
  • RPC payload - configs registered with TS_CFG_SOURCE_FILE_AND_RPC
    receive YAML content via JSONRPC and react to _reload directives.
  • Status surface - success / fail / in-progress / timeout plus
    log entries appear in traffic_ctl config status for config reload, file changes, and record changes during a reload cycle.
  • Subtasks - handlers can split work into named subtasks that
    aggregate into the parent's status.
  • Companion files - TSCfgAddFileDependency declares an extra
    file whose changes invoke the same handler, optionally routing
    inline RPC content via dep_key.
  • Deferred completion - handlers may stash the context, return,
    and finish on another thread later. Same contract core handlers
    already have.

Limitations

  • Not supported in remap plugins (TSRemapInit /
    TSRemapNewInstance); the reload framework is centred on global
    plugins.
  • is_required is propagated to FileManager but not enforced at
    reload time today (catalog/inspection only).
  • TSCfgAttachReloadTrigger is not a free-form record-change
    subscription; it triggers a reload of the registered config and
    nothing else.

Documentation

Fixes: #12967

Damian Meden added 5 commits May 7, 2026 11:47
Expose the centralized config reload framework to plugins via a new
TSCfg* C API so they can register configuration files alongside core
ATS configs and participate in the reload status, RPC inline-YAML, and
diagnostics machinery on equal footing.

Public API (include/ts/ts.h, include/ts/apidefs.h.in):
- TSCfgRegister(const TSCfgRegistrationInfo *) registers a plugin
  config with a TSCfgLoadCb handler. The plugin's canonical name is
  captured automatically from TSPluginRegister and surfaced in logs
  and traffic_ctl output.
- TSCfgRegistrationInfo and TSCfgFileDependencyInfo option structs
  keep the API extensible without breaking source compatibility.
- TSCfgAttachTrigger, TSCfgAddFileDependency, TSCfgSetEnabled cover
  reload triggers, file dependencies, and runtime enable/disable.
  TSCfgAddFileDependency supports operator-tunable filename via
  filename_record and inline-YAML routing via dep_key.
- TSCfgLoadCtx handler-context API: InProgress / Complete / Fail for
  deferred completion, AddLog for severity-aware messages, AddSubtask
  for nested handlers, and getters for filename, reload token, the
  RPC-supplied YAML, and reload directives.
- TSCfgLoadCb callback type and TSCfgSourceType enum.

Core integration:
- ConfigRegistry::register_plugin_config attributes plugin name to
  the entry; ConfigContext / ConfigReloadTrace propagate it through
  tasks and logs.
- traffic_ctl config status renders plugin attribution and task
  trees with severity-prefixed log lines.
- regex_revalidate migrated to the new API as the reference example.

Tests:
- cfg_plugin_test exercises every public API entrypoint.
- cfg_plugin_deferred_test demonstrates two-stage deferred completion
  via scheduled continuations on ET_TASK.
- cfg_plugin_directives_test covers _reload directive routing.
- New autests: config_reload_plugin_api, config_reload_deferred,
  config_reload_directives_plugin, config_reload_ssl_bulk,
  config_reload_ssl_state.

Documentation:
- doc/developer-guide/api/functions/TSCfgRegister.en.rst consolidates
  the reference for TSCfgRegister and TSCfgLoadCtx.
- doc/developer-guide/config-reload-framework.en.rst gains a Plugin
  Configuration Reload section with example, lifecycle, and
  traffic_ctl status output.

Ref: apache#12967
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR exposes the existing config-reload framework (ConfigRegistry/ConfigContext/ReloadCoordinator) to global plugins via a new TSCfg* API, allowing plugin-owned config reloads to participate in the same reload lifecycle, status tracking, and JSONRPC/YAML payload flow as core configs.

Changes:

  • Introduces a plugin-facing registration + per-reload context API (TSCfgRegister, triggers/deps, and TSCfgLoadCtx* functions).
  • Propagates plugin ownership into reload task metadata and traffic_ctl config status output ([plugin: <name>] and meta.plugin_name).
  • Adds gold tests and unit tests covering plugin reload behavior, directives separation, deferred completion, and SSL reload status propagation.

Reviewed changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/gold_tests/jsonrpc/plugins/CMakeLists.txt Adds new autest plugins for exercising TSCfg*.
tests/gold_tests/jsonrpc/plugins/cfg_plugin_test.cc Test plugin covering core TSCfg* APIs and subtask logging.
tests/gold_tests/jsonrpc/plugins/cfg_plugin_deferred_test.cc Test plugin demonstrating deferred completion contract.
tests/gold_tests/jsonrpc/plugins/cfg_plugin_directives_test.cc Test plugin validating _reload directive extraction vs content.
tests/gold_tests/jsonrpc/config_reload_ssl_state.test.py New gold test validating SSL reload status propagation and severity tags.
tests/gold_tests/jsonrpc/config_reload_ssl_bulk.test.py New gold test exercising bulk SSL reload status detail and partial failure.
tests/gold_tests/jsonrpc/config_reload_plugin_api.test.py End-to-end gold test for the new plugin API and status output.
tests/gold_tests/jsonrpc/config_reload_directives_plugin.test.py Gold test validating directive delivery via plugin API.
tests/gold_tests/jsonrpc/config_reload_deferred.test.py Gold test validating deferred plugin completion within a full reload.
src/traffic_ctl/jsonrpc/CtrlRPCRequests.h Adds plugin_name to reload task metadata in the client model.
src/traffic_ctl/jsonrpc/ctrl_yaml_codecs.h Decodes meta.plugin_name from YAML into the traffic_ctl model.
src/traffic_ctl/CtrlPrinters.cc Prints plugin ownership tag in task tree output.
src/records/unit_tests/test_ConfigRegistry.cc Adds unit coverage for plugin registration plumbing + dependency collision behavior.
src/mgmt/config/FileManager.cc Routes file mtime updates for plugin registry keys directly into ConfigRegistry reload scheduling.
src/mgmt/config/ConfigRegistry.cc Adds plugin registration entrypoint, directive extraction helper, and plugin name propagation into contexts/tasks.
src/mgmt/config/ConfigContext.cc Adds get_reload_token() and plugin name setter forwarding into task info.
src/api/InkAPI.cc Implements the TSCfg* plugin API layer and TSCfgLoadCtx wrapper semantics.
plugins/regex_revalidate/regex_revalidate.cc Migrates plugin reload integration from TSMgmtUpdateRegister to TSCfgRegister.
include/ts/ts.h Public API declarations and detailed doxygen for TSCfg*.
include/ts/apidefs.h.in Adds new plugin API types/enums and option structs for ABI-stable registration.
include/records/YAMLConfigReloadTaskEncoder.h Encodes plugin_name into JSONRPC YAML task metadata.
include/mgmt/config/ConfigReloadTrace.h Adds plugin_name to reload task info and setter.
include/mgmt/config/ConfigRegistry.h Adds plugin registration API and _reload extraction helper declaration.
include/mgmt/config/ConfigContext.h Adds reload-token getter and plugin-name propagation hook.
doc/developer-guide/config-reload-framework.en.rst Documents plugin participation and traffic_ctl ownership tagging.
doc/developer-guide/api/functions/TSCfgRegister.en.rst New reference page for TSCfgRegister and the TSCfgLoadCtx* family.

Comment on lines +489 to +497
if (passed_config.IsMap() && passed_config["_reload"]) {
auto directives = passed_config["_reload"];
if (!directives.IsMap()) {
Warning("Config '%.*s': _reload must be a YAML map, ignoring directives", static_cast<int>(key.size()), key.data());
} else {
Dbg(dbg_ctl, "Config '%.*s' has reload directives", static_cast<int>(key.size()), key.data());
ctx.set_reload_directives(directives);
}
passed_config.remove("_reload");
Comment on lines +230 to +232
``TSPluginInit``, before ``TSPluginRegister``, with a null or
incomplete ``info`` struct, or if another plugin (or core) has
already registered the same key.
Comment on lines +129 to +134
tr.Processes.Default.Streams.stdout = All(
Testers.IncludesExpression('[plugin]', 'Plugin task should have [plugin] tag'),
Testers.IncludesExpression('greet=world', 'Should show greeting in status'),
Testers.IncludesExpression('success', 'Should show success'),
Testers.IncludesExpression('handler entered', 'TSCfgLoadCtxAddLog message should appear'),
)
tr.Processes.Default.Env = ts.Env
tr.Processes.Default.ReturnCode = 0
tr.Processes.Default.Streams.stdout = All(
Testers.IncludesExpression('[plugin]', 'Failed task should have [plugin] tag'),
Testers.IncludesExpression('directive_version=2.0', 'Plugin should see version directive'),
Testers.IncludesExpression('content_greeting=hello_directives', 'Plugin should see greeting in content'),
Testers.IncludesExpression('success', 'Should complete successfully'),
Testers.IncludesExpression('[plugin]', 'Should have plugin tag'),
Comment on lines +592 to +599
config_reload(TSCfgLoadCtx ctx, void *data)
{
auto *pstate = static_cast<plugin_state_t *>(data);

Dbg(dbg_ctl, "Config reload via ConfigRegistry");
bool const updated = do_config_reload(pstate);
TSCfgLoadCtxComplete(ctx, updated ? "regex_revalidate config reloaded" : "regex_revalidate config unchanged");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ATS Reload migration task. Expose ConfigRegistry to plugins

2 participants