release: r019 idempotent batch container updates
This commit is contained in:
+11
@@ -93,6 +93,17 @@ export function parseConfig(content: string): MUAConfig {
|
||||
}
|
||||
}
|
||||
}
|
||||
// r019 replaces repeated single-container update calls with an idempotent
|
||||
// batch variant. If an administrator already enabled the older update
|
||||
// capability, expose the safer equivalent automatically; this does not
|
||||
// grant a new class of operation.
|
||||
if (
|
||||
!cfg.allToolsEnabled
|
||||
&& cfg.enabledTools.includes("unraid_docker_update")
|
||||
&& !cfg.enabledTools.includes("unraid_docker_update_verified_batch")
|
||||
) {
|
||||
cfg.enabledTools.push("unraid_docker_update_verified_batch");
|
||||
}
|
||||
return cfg;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import { createHash, randomUUID } from "node:crypto";
|
||||
|
||||
// ── Konstanten ──────────────────────────────────────────────────────────
|
||||
export const MUA_SERVER_NAME = "mua";
|
||||
export const MUA_VERSION = "2026.08.24.r018";
|
||||
export const MUA_VERSION = "2026.08.24.r019";
|
||||
export const MUA_PROTOCOL_VERSION = "2025-03-26";
|
||||
export const PHP_HELPER = "/usr/local/bin/unraid-docker-mcp-helper.php";
|
||||
export const STATUS_HELPER = "/usr/local/bin/unraid-mcp-status-helper.php";
|
||||
|
||||
@@ -22,6 +22,14 @@ describe("secure tool configuration", () => {
|
||||
expect(cfg.allToolsEnabled).toBe(true);
|
||||
expect(cfg.enabledTools).toEqual([]);
|
||||
});
|
||||
|
||||
test("an enabled legacy update also exposes the safer batch update", () => {
|
||||
const cfg = parseConfig(
|
||||
"MUA_API_KEY=test\nMUA_ENABLED_TOOLS=unraid_docker_update\n",
|
||||
);
|
||||
expect(cfg.enabledTools).toContain("unraid_docker_update");
|
||||
expect(cfg.enabledTools).toContain("unraid_docker_update_verified_batch");
|
||||
});
|
||||
});
|
||||
|
||||
describe("secret handling", () => {
|
||||
@@ -40,6 +48,7 @@ describe("risk classification", () => {
|
||||
test("classifies root shell and container changes as critical", () => {
|
||||
expect(getToolRisk("unraid_system_shell")).toBe("critical");
|
||||
expect(getToolRisk("unraid_docker_modify")).toBe("critical");
|
||||
expect(getToolRisk("unraid_docker_update_verified_batch")).toBe("critical");
|
||||
expect(getToolRisk("unraid_docker_restart")).toBe("write");
|
||||
expect(getToolRisk("unraid_network_lan_probe")).toBe("active");
|
||||
expect(getToolRisk("unraid_docker_list")).toBe("read");
|
||||
|
||||
+27
-1
@@ -40,6 +40,7 @@ const CRITICAL_TOOLS = new Set([
|
||||
"unraid_docker_create",
|
||||
"unraid_docker_modify",
|
||||
"unraid_docker_update",
|
||||
"unraid_docker_update_verified_batch",
|
||||
"unraid_docker_rebuild",
|
||||
"unraid_system_shell",
|
||||
"unraid_ca_install",
|
||||
@@ -281,7 +282,8 @@ export const TOOLS: ToolDef[] = [
|
||||
},
|
||||
{
|
||||
name: "unraid_docker_update",
|
||||
description: "Update a container (pull latest image, rebuild).",
|
||||
description:
|
||||
"Update one explicitly named container (pull latest image and rebuild). For two or more containers, or when update status may be stale, use unraid_docker_update_verified_batch instead.",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: { container: str("Container/template name") },
|
||||
@@ -289,6 +291,30 @@ export const TOOLS: ToolDef[] = [
|
||||
},
|
||||
handler: (a) => runPhpHelper("update", validateName(a["container"], "container")),
|
||||
},
|
||||
{
|
||||
name: "unraid_docker_update_verified_batch",
|
||||
description:
|
||||
"Authoritative one-call Docker image update workflow for 1-25 explicitly named Unraid containers. Pulls each configured image, compares immutable image IDs, skips already-current containers even if Unraid's cached status is stale, rebuilds only when the image actually changed, preserves every original running/stopped state, and returns compact post-verification (container ID change, state, restart count and health). Use this after read-only update discovery when the user explicitly requested the updates.",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
containers: str(
|
||||
"One to 25 exact container names separated by |, as returned by Unraid inventory/update status",
|
||||
),
|
||||
},
|
||||
required: ["containers"],
|
||||
additionalProperties: false,
|
||||
},
|
||||
handler: (a) => {
|
||||
const raw = String(a["containers"] ?? "");
|
||||
const containers = raw.split("|").map((name) => name.trim()).filter(Boolean);
|
||||
if (containers.length < 1 || containers.length > 25) {
|
||||
throw new Error("containers must contain 1-25 names separated by |");
|
||||
}
|
||||
const unique = [...new Set(containers.map((name) => validateName(name, "container")))];
|
||||
return runPhpHelper("update-verified-batch", unique.join("|"));
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "unraid_docker_rebuild",
|
||||
description:
|
||||
|
||||
Reference in New Issue
Block a user