feat: the host agent is always on; the MCP sees and starts host maintenance (#5834)
#5834 "The host agent is always on, and the MCP sees a host's maintenance", step 1 of milestone 520 "The MCP sees what Steward has grown". The host agent is a core system (operator, 2026-10-15: "it's very core to the functionality of Steward as a whole and shouldn't be considered something that can be toggled off"). ALWAYS_ON_PLUGINS in core settings makes to_plugins_cfg report it enabled whatever its stored row says, so it always loads and its MCP tools are always listed. Settings -> Plugins shows it as "Built in: always on" with no switch, and a save keeps it enabled. Its code and URLs stay under plugins/host_agent: every installed agent posts to /plugins/host_agent/ingest. Maintenance through the MCP: - list_maintenance_plans: each plan's group, weekly slot, reboot policy, next slot, and its latest run (hosts, how far it got, who it skipped and why, how it ended). - get_maintenance_job(host | job): a host's jobs, newest and running first, or one job: state, packages updated, reboot, drained by, why it failed, when its current state times out. - run_maintenance(host, reboot="if_required" | "never"): admin, as the host page's Update now; refuses a busy host or one with no helper; audited "<user> via MCP". - The overview names a host whose latest job in the last week failed or timed out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -41,3 +41,14 @@ def test_defaults_use_plugin_dot_namespace():
|
||||
# The keys must live under the plugin.<name> namespace to_plugins_cfg reads.
|
||||
for name in DEFAULT_ON:
|
||||
assert f"plugin.{name}" in settings_module.DEFAULTS
|
||||
|
||||
|
||||
def test_the_host_agent_is_always_on():
|
||||
"""Steward relies on it, so a stored disable, or no row at all, still
|
||||
loads it (operator, 2026-10-15); its other settings are kept."""
|
||||
stored_off = {**DEFAULTS, "plugin.host_agent": {"enabled": False, "stale_after_seconds": 300}}
|
||||
assert to_plugins_cfg(stored_off)["host_agent"] == {"enabled": True, "stale_after_seconds": 300}
|
||||
no_row = {k: v for k, v in DEFAULTS.items() if k != "plugin.host_agent"}
|
||||
assert to_plugins_cfg(no_row)["host_agent"]["enabled"] is True
|
||||
# Only the host agent: another plugin's stored disable still wins.
|
||||
assert to_plugins_cfg({**DEFAULTS, "plugin.snmp": {"enabled": False}})["snmp"]["enabled"] is False
|
||||
|
||||
Reference in New Issue
Block a user