fix(plugins): show load-failure reasons on the page the banner links to
The admin banner counts every plugin load failure, but settings/plugins.html only rendered failure reasons inside the plugin card macro -- which iterates discovered plugins. A plugin that failed BECAUSE it has no directory was therefore counted in the banner and shown nowhere on the page the banner links to. That dead end is what the operator hit: "1 plugin failed to load" on the dashboard, nothing wrong on the details page, and no way to clean it up. Folds the reason into the "Configured but not installed" rows rather than adding a competing section, and drives that list from the UNION of stored plugin.* settings and recorded load failures instead of stored settings alone. A failure with no stored row -- a plugin enabled by a DEFAULTS entry, which is exactly what plugin.http was -- would otherwise still be counted and still be invisible. Rows carry `removable`: only a plugin with a real stored row can be cleaned up, so a default-declared one shows the reason and an explanation instead of a Remove button that would delete nothing while the default reasserts it. Rows with a reason read as an error (red, "Failed to load"); rows that merely have leftover config stay a warning. A discovered plugin that failed is excluded -- its own card already shows the reason. Replaces find_orphaned_plugin_names outright rather than adding a second overlapping helper; it had one caller. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,7 @@ from steward.core.audit import log_audit
|
||||
from steward.models.users import UserRole
|
||||
from steward.core.settings import (
|
||||
get_all_settings, set_setting, delete_setting,
|
||||
get_stored_plugin_names, find_orphaned_plugin_names,
|
||||
get_stored_plugin_names, find_orphaned_plugins,
|
||||
to_smtp_cfg, to_webhook_cfg, to_ansible_cfg, to_plugins_cfg,
|
||||
to_oidc_cfg, to_ldap_cfg, to_thresholds_cfg,
|
||||
)
|
||||
@@ -607,8 +607,17 @@ async def plugins():
|
||||
# explicit operator decision rather than cleaned up automatically: an external
|
||||
# plugin can be missing because /data/plugins isn't mounted or an install
|
||||
# failed, and silently dropping its row would destroy stored credentials.
|
||||
orphans = find_orphaned_plugin_names(
|
||||
stored_plugin_names, [p["_dir"] for p in discovered])
|
||||
#
|
||||
# Load failures are folded in so every plugin counted by the admin banner has
|
||||
# a row here. A plugin that failed BECAUSE it has no directory is not in
|
||||
# `discovered`, so without this it would be counted in the banner and shown
|
||||
# nowhere on the page that banner links to.
|
||||
from steward.core.plugin_manager import get_plugin_failures
|
||||
orphans = find_orphaned_plugins(
|
||||
stored_plugin_names,
|
||||
[p["_dir"] for p in discovered],
|
||||
get_plugin_failures(),
|
||||
)
|
||||
return await render_template(
|
||||
"settings/plugins.html",
|
||||
capabilities=[p for p in discovered if p["_kind"] == "capability"],
|
||||
|
||||
Reference in New Issue
Block a user