agent capabilities live in a swarm KV record, set from swarmctl
An agent's capabilities move from the hive's meta repo
(`meta/capabilities.json`, injected as `HIVE_CAPABILITIES`) into the
`capabilities` field of its key in a new `agent-permissions` KV bucket,
which swarm-controller alone writes.
- swarm-queue-client: `agent_permissions` (bucket, key, `AgentPermissions`,
direct-get read, the import subject and its wire types).
- swarm-controller: creates the bucket at start; `GET|PUT|DELETE
/api/agents/{name}/permissions` (deny_unknown_fields and unknown
capability ⇒ 422, duplicate ⇒ 400, agent must be declared by a hive);
answers each hive's one-shot import, writing a key only where there is
none and only for agents that hive's wanted state declares.
- swarmctl: `agent permissions get|set|clear`.
- swarm-nats-auth: a hive reads every key of the bucket and sends its
import on its own subject; the controller subscribes to the imports and
may answer them (`responses`).
- hive-c0re: reads each of its agents' keys every 30s into
/var/lib/hyperhive/swarm-agent-permissions.json and restarts an agent,
gracefully, when its capabilities change. Unset is the compiled-in
default (ruth: manage_root_agent; everyone else: none). A failed read
keeps the stored value. On first boot it seeds that file from
meta/capabilities.json, sends the grants to the controller, and deletes
the file once the controller answers.
Deleted: the capabilities.json reader/writer, `HIVE_CAPABILITIES` in the
rendered meta flake, ruth's capability seed, the capabilities half of the
permissions rebuild job (`PermPayload::Capabilities`/`Combined`), the
dashboard's capabilities table and `capabilities_changed` event, and the
now-unused `Capability::description`.
Part of #5170.
This commit is contained in:
parent
fcda1f4a04
commit
f862354e43
47 changed files with 1943 additions and 1146 deletions
|
|
@ -17,9 +17,7 @@ import { bindAsyncForms } from "@hive/shared/forms.js";
|
|||
import { createTabStrip } from "@hive/shared/tabs.js";
|
||||
import { containersState, syncContainersFromSnapshot } from "./state.js";
|
||||
import {
|
||||
applyCapabilitiesChanged,
|
||||
applyToolGroupsChanged,
|
||||
fetchAndRenderCapabilities,
|
||||
fetchAndRenderToolGroups,
|
||||
initPermissions,
|
||||
} from "./permissions.js";
|
||||
|
|
@ -64,7 +62,6 @@ window.marked = marked;
|
|||
const MANAGED_SECTION_IDS = [
|
||||
"containers-section",
|
||||
"inbox-section",
|
||||
"capabilities-section",
|
||||
"tool-groups-section",
|
||||
];
|
||||
// <details> sections that should survive a refresh need a stable
|
||||
|
|
@ -210,7 +207,6 @@ window.marked = marked;
|
|||
},
|
||||
meta_inputs_changed: onMetaInputsChanged,
|
||||
meta_update_running: onMetaUpdateRunning,
|
||||
capabilities_changed: applyCapabilitiesChanged,
|
||||
tool_groups_changed: applyToolGroupsChanged,
|
||||
};
|
||||
(function bindDashboardStream() {
|
||||
|
|
@ -228,7 +224,7 @@ window.marked = marked;
|
|||
"transient_set,transient_cleared," +
|
||||
"container_state_changed,container_removed,rebuild_queue_changed," +
|
||||
"meta_inputs_changed,meta_update_running," +
|
||||
"capabilities_changed,tool_groups_changed",
|
||||
"tool_groups_changed",
|
||||
);
|
||||
es.onmessage = (e) => {
|
||||
let ev;
|
||||
|
|
@ -278,13 +274,12 @@ window.marked = marked;
|
|||
// visibility (bar only belongs on 4G3NTS where agent cards live).
|
||||
document.body.dataset.activeTab = target;
|
||||
renderSelectionBar(Array.from(containersState.values()));
|
||||
// Permissions tables: SSE covers worker-applied changes
|
||||
// (capabilities_changed / tool_groups_changed); re-fetch on
|
||||
// Permissions table: SSE covers worker-applied changes
|
||||
// (tool_groups_changed); re-fetch on
|
||||
// activation as a safety net for any gap between SSE events and
|
||||
// the cold-load snapshot.
|
||||
if (target === "permissions") {
|
||||
initPermissions();
|
||||
fetchAndRenderCapabilities();
|
||||
fetchAndRenderToolGroups();
|
||||
}
|
||||
onBuildsTabShown(target);
|
||||
|
|
|
|||
Loading…
Reference in a new issue