From 40ed64c1c290adf8585cf8209abc7b9fa2d493ec Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp <19+brynary@users.noreply.github.com> Date: Wed, 20 May 2026 17:22:53 -0400 Subject: [PATCH] Add system resources settings page (#328) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Adds server-visible resource reporting and a compact Resources settings tab for CPU, memory, and the filesystem that contains Fabro storage. ## Changes - Adds `GET /api/v1/system/resources` backed by `sysinfo`, including CPU sampling, cgroup-aware memory reporting, storage filesystem matching, and Fabro-managed disk byte totals. - Extends the OpenAPI contract and regenerates the Rust and TypeScript API clients. - Adds a deterministic demo-mode resources route. - Adds `/settings/resources` with 5 second polling and panels for overview, CPU, memory, disk, and notes. - Adds server integration/unit coverage and web route/render coverage. ## Screenshot ![Resources settings page](https://raw.githubusercontent.com/fabro-sh/fabro/feature/system-resources-settings/docs/public/images/web/settings-resources.jpg) ## Verification - `cargo build -p fabro-api` - `cd lib/packages/fabro-api-client && bun run generate` - `cargo nextest run -p fabro-server --features test-support --test it api::system` - `cargo test -p fabro-server resource_sampler::tests` - `cd apps/fabro-web && bun test` - `cd apps/fabro-web && bun run typecheck` - `cd apps/fabro-web && bun run build` - `cargo +nightly-2026-04-14 fmt --check --all` - `cargo +nightly-2026-04-14 clippy --workspace --all-targets -- -D warnings` --- [![Compound Engineering](https://img.shields.io/badge/Compound%20Engineering-Codex-6f42c1)](https://github.com/compound-engineering) 🤖 Generated with GPT-5 via [Codex](https://openai.com/codex) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- Cargo.lock | 1 + apps/fabro-web/app/lib/format.ts | 5 +- apps/fabro-web/app/lib/queries.ts | 9 + apps/fabro-web/app/lib/query-keys.ts | 1 + apps/fabro-web/app/router.test.tsx | 6 + apps/fabro-web/app/router.tsx | 2 + .../fabro-web/app/routes/settings-general.tsx | 46 +- .../app/routes/settings-resources.test.tsx | 184 ++++++++ .../app/routes/settings-resources.tsx | 214 +++++++++ apps/fabro-web/app/routes/settings.tsx | 7 + docs/public/api-reference/fabro-api.yaml | 183 ++++++++ docs/public/images/web/settings-resources.jpg | Bin 0 -> 136110 bytes lib/crates/fabro-server/Cargo.toml | 1 + lib/crates/fabro-server/src/demo/mod.rs | 46 ++ lib/crates/fabro-server/src/server.rs | 11 +- .../fabro-server/src/server/handler/mod.rs | 1 + .../fabro-server/src/server/handler/system.rs | 14 +- .../src/server/resource_sampler.rs | 423 ++++++++++++++++++ .../fabro-server/tests/it/api/system.rs | 91 ++++ .../src/.openapi-generator/FILES | 7 + .../fabro-api-client/src/api/system-api.ts | 69 +++ .../fabro-api-client/src/models/index.ts | 7 + .../src/models/system-cpu-resource-scope.ts | 25 ++ .../src/models/system-cpu-resources.ts | 46 ++ .../src/models/system-disk-resource-scope.ts | 25 ++ .../src/models/system-disk-resources.ts | 70 +++ .../models/system-memory-resource-scope.ts | 26 ++ .../src/models/system-memory-resources.ts | 54 +++ .../src/models/system-resources-response.ts | 42 ++ 29 files changed, 1608 insertions(+), 8 deletions(-) create mode 100644 apps/fabro-web/app/routes/settings-resources.test.tsx create mode 100644 apps/fabro-web/app/routes/settings-resources.tsx create mode 100644 docs/public/images/web/settings-resources.jpg create mode 100644 lib/crates/fabro-server/src/server/resource_sampler.rs create mode 100644 lib/packages/fabro-api-client/src/models/system-cpu-resource-scope.ts create mode 100644 lib/packages/fabro-api-client/src/models/system-cpu-resources.ts create mode 100644 lib/packages/fabro-api-client/src/models/system-disk-resource-scope.ts create mode 100644 lib/packages/fabro-api-client/src/models/system-disk-resources.ts create mode 100644 lib/packages/fabro-api-client/src/models/system-memory-resource-scope.ts create mode 100644 lib/packages/fabro-api-client/src/models/system-memory-resources.ts create mode 100644 lib/packages/fabro-api-client/src/models/system-resources-response.ts diff --git a/Cargo.lock b/Cargo.lock index c93b8139e..4c5912079 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2304,6 +2304,7 @@ dependencies = [ "serde_yaml", "sha2", "strum", + "sysinfo", "tempfile", "thiserror 2.0.18", "tokio", diff --git a/apps/fabro-web/app/lib/format.ts b/apps/fabro-web/app/lib/format.ts index 460ec9165..8f699a8cc 100644 --- a/apps/fabro-web/app/lib/format.ts +++ b/apps/fabro-web/app/lib/format.ts @@ -82,7 +82,10 @@ export function formatDurationSecs(secs: number): string { export function formatDurationMs(ms: number): string { if (ms < 1000) return `${Math.round(ms)}ms`; - if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`; + if (ms < 60_000) { + const seconds = ms / 1000; + return `${Number.isInteger(seconds) ? seconds : seconds.toFixed(1)}s`; + } const minutes = Math.floor(ms / 60_000); const seconds = Math.round((ms % 60_000) / 1000); return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`; diff --git a/apps/fabro-web/app/lib/queries.ts b/apps/fabro-web/app/lib/queries.ts index eca7ae931..b6681caf1 100644 --- a/apps/fabro-web/app/lib/queries.ts +++ b/apps/fabro-web/app/lib/queries.ts @@ -22,6 +22,7 @@ import type { SandboxServiceListResponse, ServerSettings, SystemInfoResponse, + SystemResourcesResponse, VncPreviewResponse, WorkflowDetailResponse, WorkflowSettings, @@ -93,6 +94,14 @@ export function useSystemInfo() { ); } +export function useSystemResources() { + return useSWR( + queryKeys.system.resources(), + () => apiData(() => systemApi.getSystemResources()), + { refreshInterval: 5_000 }, + ); +} + export function useBoardsRuns(includeArchived: boolean = false) { return useSWR( queryKeys.boards.runs(includeArchived), diff --git a/apps/fabro-web/app/lib/query-keys.ts b/apps/fabro-web/app/lib/query-keys.ts index 5f36b5341..6be29bb52 100644 --- a/apps/fabro-web/app/lib/query-keys.ts +++ b/apps/fabro-web/app/lib/query-keys.ts @@ -35,6 +35,7 @@ export const queryKeys = { }, system: { info: () => ["system", "info"] as const, + resources: () => ["system", "resources"] as const, attachUrl: () => "/api/v1/attach", }, boards: { diff --git a/apps/fabro-web/app/router.test.tsx b/apps/fabro-web/app/router.test.tsx index 70007f8fd..2901413f5 100644 --- a/apps/fabro-web/app/router.test.tsx +++ b/apps/fabro-web/app/router.test.tsx @@ -32,4 +32,10 @@ describe("browser router", () => { expect(paths).toContain("/setup"); expect(paths).not.toContain("/setup/complete"); }); + + test("exposes the resources settings page", () => { + const paths = collectPaths(routes); + + expect(paths).toContain("/settings/resources"); + }); }); diff --git a/apps/fabro-web/app/router.tsx b/apps/fabro-web/app/router.tsx index 53f960b92..a59eaa426 100644 --- a/apps/fabro-web/app/router.tsx +++ b/apps/fabro-web/app/router.tsx @@ -35,6 +35,7 @@ import * as Settings from "./routes/settings"; import * as SettingsGeneral from "./routes/settings-general"; import * as SettingsIntegrations from "./routes/settings-integrations"; import * as SettingsModels from "./routes/settings-models"; +import * as SettingsResources from "./routes/settings-resources"; import * as SettingsSecurity from "./routes/settings-security"; import * as SettingsStorage from "./routes/settings-storage"; import * as SettingsLiveEvents from "./routes/settings-live-events"; @@ -139,6 +140,7 @@ export const routes: RouteObject[] = [ route("models", SettingsModels), route("security", SettingsSecurity), route("storage", SettingsStorage), + route("resources", SettingsResources), route("live-events", SettingsLiveEvents), ], }), diff --git a/apps/fabro-web/app/routes/settings-general.tsx b/apps/fabro-web/app/routes/settings-general.tsx index e76aec902..1d4838683 100644 --- a/apps/fabro-web/app/routes/settings-general.tsx +++ b/apps/fabro-web/app/routes/settings-general.tsx @@ -2,8 +2,10 @@ import { useState } from "react"; import type { ServerListenSettings, ServerSettings, + SystemInfoResponse, } from "@qltysh/fabro-api-client"; -import { useServerSettings } from "../lib/queries"; +import { formatDurationSecs } from "../lib/format"; +import { useServerSettings, useSystemInfo } from "../lib/queries"; import { CollapsibleFile } from "../components/collapsible-file"; import { Badge, @@ -48,7 +50,10 @@ export default function SettingsGeneral() {
{view === "settings" ? ( - + <> + + + ) : ( ; + } + return ( + + + {info.version ? info.version : Unknown} + + + + + + {info.uptime_secs != null ? ( + formatDurationSecs(info.uptime_secs) + ) : ( + Unknown + )} + + + ); +} + +function OperatingSystemValue({ info }: { info: SystemInfoResponse }) { + return ( + + {info.os ?? "unknown"} + {info.arch ?? "unknown"} + + ); +} + function ListenValue({ listen }: { listen: ServerListenSettings }) { if (listen.type === "tcp") { return ( diff --git a/apps/fabro-web/app/routes/settings-resources.test.tsx b/apps/fabro-web/app/routes/settings-resources.test.tsx new file mode 100644 index 000000000..7b3f5c2b2 --- /dev/null +++ b/apps/fabro-web/app/routes/settings-resources.test.tsx @@ -0,0 +1,184 @@ +import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; +import type { + SystemCpuResources, + SystemDiskResources, + SystemMemoryResources, + SystemResourcesResponse, +} from "@qltysh/fabro-api-client"; +import TestRenderer, { act } from "react-test-renderer"; +import { setupReactTestEnv } from "../lib/test-utils"; + +let systemResources: SystemResourcesResponse | undefined; +let teardownReactTestEnv: (() => void) | undefined; + +mock.module("../lib/queries", () => ({ + useSystemResources: () => ({ data: systemResources }), +})); + +const { default: SettingsResources } = await import("./settings-resources"); + +const mountedRenderers: TestRenderer.ReactTestRenderer[] = []; + +function renderSettingsResources() { + let renderer: TestRenderer.ReactTestRenderer | undefined; + act(() => { + renderer = TestRenderer.create(); + }); + mountedRenderers.push(renderer!); + return renderer!; +} + +function textContent(node: ReturnType): string { + if (node == null || typeof node === "boolean") return ""; + if (typeof node === "string" || typeof node === "number") return String(node); + if (Array.isArray(node)) return node.map(textContent).join(""); + return node.children?.map(textContent).join("") ?? ""; +} + +type ResourceOverrides = Partial< + Omit +> & { + cpu?: Partial; + memory?: Partial; + disk?: Partial; +}; + +function sampleResources(overrides: ResourceOverrides = {}): SystemResourcesResponse { + const resources: SystemResourcesResponse = { + sampled_at: "2026-05-20T15:42:10Z", + cpu: { + supported: true, + scope: "server_environment", + unavailable_reason: null, + logical_cpus: 10, + usage_percent: 18.4, + sample_window_ms: 5000, + }, + memory: { + supported: true, + scope: "cgroup", + unavailable_reason: null, + total_bytes: 8 * 1024 * 1024 * 1024, + used_bytes: 3 * 1024 * 1024 * 1024, + available_bytes: 5 * 1024 * 1024 * 1024, + used_percent: 37.5, + host_total_bytes: 32 * 1024 * 1024 * 1024, + }, + disk: { + supported: true, + scope: "storage_filesystem", + unavailable_reason: null, + storage_path: "/var/lib/fabro", + mount_point: "/", + filesystem: "apfs", + total_bytes: 500 * 1024 * 1024 * 1024, + used_bytes: 200 * 1024 * 1024 * 1024, + available_bytes: 300 * 1024 * 1024 * 1024, + used_percent: 40, + fabro_managed_bytes: 2 * 1024 * 1024 * 1024, + fabro_reclaimable_bytes: 512 * 1024 * 1024, + }, + notes: [], + }; + return { + sampled_at: overrides.sampled_at ?? resources.sampled_at, + cpu: { ...resources.cpu, ...overrides.cpu }, + memory: { ...resources.memory, ...overrides.memory }, + disk: { ...resources.disk, ...overrides.disk }, + notes: overrides.notes ?? resources.notes, + }; +} + +describe("SettingsResources route", () => { + beforeEach(() => { + teardownReactTestEnv = setupReactTestEnv(); + }); + + afterEach(() => { + act(() => { + for (const renderer of mountedRenderers.splice(0)) { + renderer.unmount(); + } + }); + systemResources = undefined; + teardownReactTestEnv?.(); + teardownReactTestEnv = undefined; + }); + + test("renders loaded resource data", () => { + systemResources = sampleResources(); + + const renderer = renderSettingsResources(); + const text = textContent(renderer.toJSON()); + + expect(text).toContain("18.4%"); + expect(text).toContain("5s"); + expect(text).toContain("3 GiB"); + expect(text).toContain("8 GiB"); + expect(text).toContain("2 GiB"); + expect(text).toContain("512 MiB"); + }); + + test("shows CPU warmup state while usage is null", () => { + systemResources = sampleResources({ + cpu: { + supported: true, + scope: "server_environment", + unavailable_reason: null, + logical_cpus: 10, + usage_percent: null, + sample_window_ms: null, + }, + }); + + const renderer = renderSettingsResources(); + + expect(textContent(renderer.toJSON())).toContain("Collecting sample"); + }); + + test("renders unsupported resource sections", () => { + systemResources = sampleResources({ + cpu: { + supported: false, + scope: "server_environment", + unavailable_reason: "CPU metrics unavailable", + logical_cpus: null, + usage_percent: null, + sample_window_ms: null, + }, + disk: { + supported: false, + scope: "storage_filesystem", + unavailable_reason: "No storage filesystem matched", + storage_path: "/var/lib/fabro", + mount_point: null, + filesystem: null, + total_bytes: null, + used_bytes: null, + available_bytes: null, + used_percent: null, + fabro_managed_bytes: 0, + fabro_reclaimable_bytes: 0, + }, + }); + + const renderer = renderSettingsResources(); + const text = textContent(renderer.toJSON()); + + expect(text).toContain("Unsupported"); + expect(text).toContain("CPU metrics unavailable"); + expect(text).toContain("No storage filesystem matched"); + }); + + test("renders notes only when present", () => { + systemResources = sampleResources({ + notes: ["Memory is scoped to the current container."], + }); + + const renderer = renderSettingsResources(); + + expect(textContent(renderer.toJSON())).toContain( + "Memory is scoped to the current container.", + ); + }); +}); diff --git a/apps/fabro-web/app/routes/settings-resources.tsx b/apps/fabro-web/app/routes/settings-resources.tsx new file mode 100644 index 000000000..2e0d1914c --- /dev/null +++ b/apps/fabro-web/app/routes/settings-resources.tsx @@ -0,0 +1,214 @@ +import type { + SystemCpuResources, + SystemDiskResources, + SystemMemoryResources, + SystemResourcesResponse, +} from "@qltysh/fabro-api-client"; +import { formatBytesAsMemory, formatDurationMs } from "../lib/format"; +import { useSystemResources } from "../lib/queries"; +import { + Badge, + Mono, + Muted, + Panel, + PanelSkeleton, + Row, + SettingsPageIntro, +} from "../components/settings-panel"; + +export function meta() { + return [{ title: "Resources — Fabro" }]; +} + +const DESCRIPTION = + "Server-visible CPU, memory, and storage filesystem usage for this Fabro process."; + +export default function SettingsResources() { + const resourcesQuery = useSystemResources(); + const resources = resourcesQuery.data; + + return ( +
+ + {resources ? ( + <> + + + + + + ) : ( + <> + + + + + )} +
+ ); +} + +function CpuPanel({ cpu }: { cpu: SystemCpuResources }) { + if (!cpu.supported) { + return ( + + + + ); + } + + return ( + + + {cpu.usage_percent == null ? ( + Collecting sample + ) : ( + + )} + + + {cpu.sample_window_ms != null ? ( + formatDurationMs(cpu.sample_window_ms) + ) : ( + Unknown + )} + + + ); +} + +function MemoryPanel({ memory }: { memory: SystemMemoryResources }) { + if (!memory.supported) { + return ( + + + + ); + } + + return ( + + + + + + ); +} + +function DiskPanel({ disk }: { disk: SystemDiskResources }) { + if (!disk.supported) { + return ( + + + + {disk.storage_path} + + + + ); + } + + return ( + + + + + + {disk.mount_point ? {disk.mount_point} : Unknown} + + + + ); +} + +function FabroStorageRows({ disk }: { disk: SystemDiskResources }) { + return ( + <> + + {formatBytesAsMemory(disk.fabro_managed_bytes)} + + + {formatBytesAsMemory(disk.fabro_reclaimable_bytes)} + + + ); +} + +function NotesPanel({ resources }: { resources: SystemResourcesResponse }) { + const notes = Array.from(new Set(resources.notes)); + if (notes.length === 0) return null; + + return ( + + {notes.map((note) => ( + + {note} + + ))} + + ); +} + +function UnsupportedRows({ reason }: { reason: string | null }) { + return ( + <> + + Unsupported + + + {reason ?? "Metric unavailable"} + + + ); +} + +function UsageMeter({ + percent, + label, +}: { + percent: number | null | undefined; + label?: string; +}) { + const safePercent = percent == null ? null : Math.min(100, Math.max(0, percent)); + const value = safePercent == null ? "Not available" : formatPercent(safePercent); + return ( +
+
+ {label ?? value} + {label ? ( + {value} + ) : null} +
+
+
+
+
+ ); +} + +function formatPercent(value: number) { + return `${Number.isInteger(value) ? value : value.toFixed(1)}%`; +} diff --git a/apps/fabro-web/app/routes/settings.tsx b/apps/fabro-web/app/routes/settings.tsx index 4313b328f..d5503242e 100644 --- a/apps/fabro-web/app/routes/settings.tsx +++ b/apps/fabro-web/app/routes/settings.tsx @@ -4,6 +4,7 @@ import { Cog6ToothIcon, CpuChipIcon, PuzzlePieceIcon, + ServerStackIcon, ShieldCheckIcon, } from "@heroicons/react/24/outline"; import { Link, Outlet, useLocation, useMatches } from "react-router"; @@ -57,6 +58,12 @@ const navItems: NavEntry[] = [ icon: CircleStackIcon, match: (p) => p.startsWith("/settings/storage"), }, + { + name: "Resources", + href: "/settings/resources", + icon: ServerStackIcon, + match: (p) => p.startsWith("/settings/resources"), + }, { type: "divider", key: "after-storage" }, { name: "Live Events", diff --git a/docs/public/api-reference/fabro-api.yaml b/docs/public/api-reference/fabro-api.yaml index 7e53a255c..2839ea9f5 100644 --- a/docs/public/api-reference/fabro-api.yaml +++ b/docs/public/api-reference/fabro-api.yaml @@ -3620,6 +3620,20 @@ paths: schema: $ref: "#/components/schemas/SystemInfoResponse" + /api/v1/system/resources: + get: + operationId: getSystemResources + tags: [System] + summary: Retrieve System Resources + description: Returns server-visible CPU, memory, and storage filesystem resource usage. + responses: + "200": + description: System resource usage + content: + application/json: + schema: + $ref: "#/components/schemas/SystemResourcesResponse" + /api/v1/system/df: get: operationId: getSystemDiskUsage @@ -10246,6 +10260,175 @@ components: format: int64 description: Runs currently queued or executing. + SystemResourcesResponse: + description: Server-visible runtime resource usage for the active Fabro process environment. + type: object + required: [sampled_at, cpu, memory, disk, notes] + properties: + sampled_at: + type: string + format: date-time + description: Timestamp when the sample was collected. + cpu: + $ref: "#/components/schemas/SystemCpuResources" + memory: + $ref: "#/components/schemas/SystemMemoryResources" + disk: + $ref: "#/components/schemas/SystemDiskResources" + notes: + type: array + description: Human-readable caveats about unavailable or scoped metrics. + items: + type: string + + SystemCpuResources: + description: CPU resources visible to the Fabro server process. + type: object + required: + - supported + - scope + - unavailable_reason + - logical_cpus + - usage_percent + - sample_window_ms + properties: + supported: + type: boolean + description: Whether CPU metrics are available on this platform. + scope: + $ref: "#/components/schemas/SystemCpuResourceScope" + unavailable_reason: + type: ["string", "null"] + description: Reason metrics are unavailable when unsupported. + logical_cpus: + type: ["integer", "null"] + format: int64 + description: Logical CPUs visible to the server process. + usage_percent: + type: ["number", "null"] + format: double + description: CPU usage percentage, null until a delta sample is available. + sample_window_ms: + type: ["integer", "null"] + format: int64 + description: Elapsed milliseconds since the previous CPU sample, null until a delta sample is available. + + SystemCpuResourceScope: + description: Scope for CPU resource metrics. + type: string + enum: [server_environment] + + SystemMemoryResources: + description: Memory resources visible to the Fabro server process. + type: object + required: + - supported + - scope + - unavailable_reason + - total_bytes + - used_bytes + - available_bytes + - used_percent + - host_total_bytes + properties: + supported: + type: boolean + description: Whether memory metrics are available on this platform. + scope: + $ref: "#/components/schemas/SystemMemoryResourceScope" + unavailable_reason: + type: ["string", "null"] + description: Reason metrics are unavailable when unsupported. + total_bytes: + type: ["integer", "null"] + format: int64 + description: Total memory for the reported scope. + used_bytes: + type: ["integer", "null"] + format: int64 + description: Used memory for the reported scope. + available_bytes: + type: ["integer", "null"] + format: int64 + description: Available memory for the reported scope. + used_percent: + type: ["number", "null"] + format: double + description: Used memory percentage for the reported scope. + host_total_bytes: + type: ["integer", "null"] + format: int64 + description: Host total memory, included even when reporting a cgroup scope. + + SystemMemoryResourceScope: + description: "`cgroup` when Linux cgroup limits are available, otherwise `host`." + type: string + enum: [host, cgroup] + + SystemDiskResources: + description: Filesystem resources for the configured Fabro storage root. + type: object + required: + - supported + - scope + - unavailable_reason + - storage_path + - mount_point + - filesystem + - total_bytes + - used_bytes + - available_bytes + - used_percent + - fabro_managed_bytes + - fabro_reclaimable_bytes + properties: + supported: + type: boolean + description: Whether storage filesystem metrics are available. + scope: + $ref: "#/components/schemas/SystemDiskResourceScope" + unavailable_reason: + type: ["string", "null"] + description: Reason metrics are unavailable when unsupported. + storage_path: + type: string + description: Configured Fabro storage directory. + mount_point: + type: ["string", "null"] + description: Mount point for the filesystem containing the storage directory. + filesystem: + type: ["string", "null"] + description: Filesystem name reported by the operating system. + total_bytes: + type: ["integer", "null"] + format: int64 + description: Total bytes on the storage filesystem. + used_bytes: + type: ["integer", "null"] + format: int64 + description: Used bytes on the storage filesystem. + available_bytes: + type: ["integer", "null"] + format: int64 + description: Available bytes on the storage filesystem. + used_percent: + type: ["number", "null"] + format: double + description: Used percentage on the storage filesystem. + fabro_managed_bytes: + type: integer + format: int64 + description: Bytes managed by Fabro under the storage root. + fabro_reclaimable_bytes: + type: integer + format: int64 + description: Bytes reclaimable through Fabro pruning. + + SystemDiskResourceScope: + description: Scope for disk resource metrics. + type: string + enum: [storage_filesystem] + SystemRepairRunsResponse: description: Runs that need manual repair or deletion because they cannot be loaded. type: object diff --git a/docs/public/images/web/settings-resources.jpg b/docs/public/images/web/settings-resources.jpg new file mode 100644 index 0000000000000000000000000000000000000000..43b213a2e6b47007e08a636f1744552c5619ce0b GIT binary patch literal 136110 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, +) -> Response { + ( + StatusCode::OK, + Json(json!({ + "sampled_at": "2026-05-20T15:42:10Z", + "cpu": { + "supported": true, + "scope": "server_environment", + "unavailable_reason": null, + "logical_cpus": 8, + "usage_percent": 18.4, + "sample_window_ms": 5000 + }, + "memory": { + "supported": true, + "scope": "host", + "unavailable_reason": null, + "total_bytes": 17179869184_i64, + "used_bytes": 6442450944_i64, + "available_bytes": 10737418240_i64, + "used_percent": 37.5, + "host_total_bytes": 17179869184_i64 + }, + "disk": { + "supported": true, + "scope": "storage_filesystem", + "unavailable_reason": null, + "storage_path": "/demo/fabro/storage", + "mount_point": "/", + "filesystem": "demo-fs", + "total_bytes": 536870912000_i64, + "used_bytes": 214748364800_i64, + "available_bytes": 322122547200_i64, + "used_percent": 40.0, + "fabro_managed_bytes": 1280, + "fabro_reclaimable_bytes": 1280 + }, + "notes": [] + })), + ) + .into_response() +} + pub(crate) async fn get_system_disk_usage( _auth: RequiredUser, State(_state): State>, diff --git a/lib/crates/fabro-server/src/server.rs b/lib/crates/fabro-server/src/server.rs index 4688d2bef..9da0576dd 100644 --- a/lib/crates/fabro-server/src/server.rs +++ b/lib/crates/fabro-server/src/server.rs @@ -36,9 +36,11 @@ pub use fabro_api::types::{ RunArtifactListResponse, RunBilling, RunBillingStage, RunBillingTotals, RunError, RunManifest, RunStage, SandboxDetails, SandboxFileEntry, SandboxFileListResponse, SandboxService, SandboxServiceListResponse, SshAccessRequest, SshAccessResponse, StageHandler, StageState, - StartRunRequest, SubmitAnswerRequest, SystemFeatures, SystemInfoResponse, SystemRepairRunIssue, - SystemRepairRunsResponse, SystemRunCounts, TimelineEntryResponse, VncPreviewResponse, - WriteBlobResponse, + StartRunRequest, SubmitAnswerRequest, SystemCpuResourceScope, SystemCpuResources, + SystemDiskResourceScope, SystemDiskResources, SystemFeatures, SystemInfoResponse, + SystemMemoryResourceScope, SystemMemoryResources, SystemRepairRunIssue, + SystemRepairRunsResponse, SystemResourcesResponse, SystemRunCounts, TimelineEntryResponse, + VncPreviewResponse, WriteBlobResponse, }; use fabro_auth::{CredentialSource, VaultCredentialSource, auth_issue_message}; #[cfg(test)] @@ -142,6 +144,7 @@ use crate::{ }; mod handler; +mod resource_sampler; mod session_runtime; pub(crate) use handler::events::EventListParams; @@ -519,6 +522,7 @@ pub struct AppState { artifact_store: ArtifactStore, worker_tokens: WorkerTokenKeys, started_at: Instant, + resource_sampler: resource_sampler::ResourceSampler, max_concurrent_runs: usize, scheduler_notify: Notify, global_event_tx: broadcast::Sender, @@ -1646,6 +1650,7 @@ pub(crate) fn build_app_state(config: AppStateConfig) -> anyhow::Result Router> { .route("/health/diagnostics", post(demo::run_diagnostics)) .route("/settings", get(demo::get_server_settings)) .route("/system/info", get(demo::get_system_info)) + .route("/system/resources", get(demo::get_system_resources)) .route("/system/df", get(demo::get_system_disk_usage)) .route("/system/repair/runs", get(demo::get_system_repair_runs)) .route("/system/prune/runs", post(demo::prune_runs)) diff --git a/lib/crates/fabro-server/src/server/handler/system.rs b/lib/crates/fabro-server/src/server/handler/system.rs index c7f18cd4a..fcc279119 100644 --- a/lib/crates/fabro-server/src/server/handler/system.rs +++ b/lib/crates/fabro-server/src/server/handler/system.rs @@ -6,8 +6,8 @@ use super::super::{ PruneRunsRequest, PruneRunsResponse, Query, RequiredUser, Response, Router, RunStatus, State, StatusCode, SystemInfoResponse, SystemRepairRunIssue, SystemRepairRunsResponse, SystemRunCounts, build_disk_usage_response, build_prune_plan, delete_run_internal, diagnostics, - get, post, resolve_interp_string, spawn_blocking, system_features, system_sandbox_provider, - to_i64, + get, post, resolve_interp_string, resource_sampler, spawn_blocking, system_features, + system_sandbox_provider, to_i64, }; pub(super) fn routes() -> Router> { @@ -17,6 +17,7 @@ pub(super) fn routes() -> Router> { .route("/health/diagnostics", post(run_diagnostics)) .route("/settings", get(get_server_settings)) .route("/system/info", get(get_system_info)) + .route("/system/resources", get(get_system_resources)) .route("/system/df", get(get_system_df)) .route("/system/repair/runs", get(get_system_repair_runs)) .route("/system/prune/runs", post(prune_runs)) @@ -83,6 +84,15 @@ async fn get_system_info(_auth: RequiredUser, State(state): State> (StatusCode::OK, Json(response)).into_response() } +async fn get_system_resources(_auth: RequiredUser, State(state): State>) -> Response { + match resource_sampler::sample_system_resources(&state).await { + Ok(response) => (StatusCode::OK, Json(response)).into_response(), + Err(err) => { + ApiError::new(StatusCode::INTERNAL_SERVER_ERROR, err.to_string()).into_response() + } + } +} + async fn get_system_df( _auth: RequiredUser, State(state): State>, diff --git a/lib/crates/fabro-server/src/server/resource_sampler.rs b/lib/crates/fabro-server/src/server/resource_sampler.rs new file mode 100644 index 000000000..bc083c2cb --- /dev/null +++ b/lib/crates/fabro-server/src/server/resource_sampler.rs @@ -0,0 +1,423 @@ +use std::path::{Path, PathBuf}; +use std::sync::Mutex; +use std::time::{Duration, Instant}; + +use anyhow::Context as _; +use sysinfo::{Disks, System}; +use tokio::sync::Mutex as AsyncMutex; +use tokio::task::spawn_blocking; + +use super::{ + AppState, SystemCpuResourceScope, SystemCpuResources, SystemDiskResourceScope, + SystemDiskResources, SystemMemoryResourceScope, SystemMemoryResources, SystemResourcesResponse, + build_disk_usage_response, to_i64, +}; + +const FABRO_STORAGE_USAGE_CACHE_TTL: Duration = Duration::from_mins(1); + +pub(in crate::server) struct ResourceSampler { + system: Mutex, + fabro_storage_usage: AsyncMutex>, +} + +struct SystemSamplerState { + system: System, + last_cpu_sample_at: Option, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +struct CachedFabroStorageUsage { + sampled_at: Instant, + usage: FabroStorageUsage, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +struct FabroStorageUsage { + managed_bytes: i64, + reclaimable_bytes: i64, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +struct CgroupMemory { + total_bytes: u64, + available_bytes: u64, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +struct MemorySelection { + scope: SystemMemoryResourceScope, + total_bytes: u64, + used_bytes: u64, + available_bytes: u64, + host_total_bytes: u64, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +struct DiskCandidate { + mount_point: PathBuf, + filesystem: String, + total_bytes: u64, + available_bytes: u64, +} + +impl ResourceSampler { + pub(in crate::server) fn new() -> Self { + Self { + system: Mutex::new(SystemSamplerState { + system: System::new(), + last_cpu_sample_at: None, + }), + fabro_storage_usage: AsyncMutex::new(None), + } + } + + fn sample_cpu_and_memory(&self) -> (SystemCpuResources, SystemMemoryResources) { + let mut state = self.system.lock().expect("resource sampler lock poisoned"); + let sampled_at = Instant::now(); + let sample_window_ms = state + .last_cpu_sample_at + .map(|last_sampled_at| to_i64(sampled_at.duration_since(last_sampled_at).as_millis())); + + state.system.refresh_cpu_usage(); + state.system.refresh_memory(); + + let logical_cpus = logical_cpu_count(&state.system); + let usage_percent = sample_window_ms + .is_some() + .then(|| round_one(f64::from(state.system.global_cpu_usage()))); + state.last_cpu_sample_at = Some(sampled_at); + + let cpu = if sysinfo::IS_SUPPORTED_SYSTEM { + SystemCpuResources { + supported: true, + scope: SystemCpuResourceScope::ServerEnvironment, + unavailable_reason: None, + logical_cpus: Some(to_i64(logical_cpus)), + usage_percent, + sample_window_ms, + } + } else { + SystemCpuResources { + supported: false, + scope: SystemCpuResourceScope::ServerEnvironment, + unavailable_reason: Some( + "system metrics are not supported on this platform".to_string(), + ), + logical_cpus: None, + usage_percent: None, + sample_window_ms: None, + } + }; + + let cgroup = state.system.cgroup_limits().map(|limits| CgroupMemory { + total_bytes: limits.total_memory, + available_bytes: limits.free_memory, + }); + let memory = memory_response(select_memory( + state.system.total_memory(), + state.system.used_memory(), + state.system.available_memory(), + cgroup, + )); + + (cpu, memory) + } + + async fn sample_fabro_storage_usage( + &self, + state: &AppState, + storage_path: &Path, + ) -> anyhow::Result { + let mut cached = self.fabro_storage_usage.lock().await; + if let Some(cached) = cached + .as_ref() + .filter(|cached| cached.sampled_at.elapsed() < FABRO_STORAGE_USAGE_CACHE_TTL) + { + return Ok(cached.usage); + } + + let summaries = state + .store + .list_runs(&fabro_store::ListRunsQuery::default()) + .await + .context("failed to list runs for resource sampling")?; + let storage_path = storage_path.to_path_buf(); + let usage = spawn_blocking(move || compute_fabro_storage_usage(&summaries, &storage_path)) + .await + .context("resource storage usage task failed")??; + + *cached = Some(CachedFabroStorageUsage { + sampled_at: Instant::now(), + usage, + }); + Ok(usage) + } +} + +pub(in crate::server) async fn sample_system_resources( + state: &AppState, +) -> anyhow::Result { + let sampled_at = chrono::Utc::now(); + let (cpu, memory) = state.resource_sampler.sample_cpu_and_memory(); + let storage_path = state.server_storage_dir(); + let fabro_usage = state + .resource_sampler + .sample_fabro_storage_usage(state, &storage_path) + .await + .context("failed to sample Fabro-managed storage usage")?; + + let disk = sample_disk_resources(&storage_path, fabro_usage); + + Ok(SystemResourcesResponse { + sampled_at, + cpu, + memory, + disk, + notes: Vec::new(), + }) +} + +fn logical_cpu_count(system: &System) -> usize { + let sysinfo_count = system.cpus().len(); + if sysinfo_count > 0 { + return sysinfo_count; + } + std::thread::available_parallelism().map_or(0, std::num::NonZeroUsize::get) +} + +fn memory_response(selection: Option) -> SystemMemoryResources { + let Some(selection) = selection else { + return SystemMemoryResources { + supported: false, + scope: SystemMemoryResourceScope::Host, + unavailable_reason: Some("memory metrics reported zero total bytes".to_string()), + total_bytes: None, + used_bytes: None, + available_bytes: None, + used_percent: None, + host_total_bytes: None, + }; + }; + + SystemMemoryResources { + supported: true, + scope: selection.scope, + unavailable_reason: None, + total_bytes: Some(to_i64(selection.total_bytes)), + used_bytes: Some(to_i64(selection.used_bytes)), + available_bytes: Some(to_i64(selection.available_bytes)), + used_percent: percent(selection.used_bytes, selection.total_bytes), + host_total_bytes: Some(to_i64(selection.host_total_bytes)), + } +} + +fn select_memory( + host_total_bytes: u64, + host_used_bytes: u64, + host_available_bytes: u64, + cgroup: Option, +) -> Option { + if let Some(cgroup) = cgroup.filter(|cgroup| cgroup.total_bytes > 0) { + let available_bytes = cgroup.available_bytes.min(cgroup.total_bytes); + let used_bytes = cgroup.total_bytes.saturating_sub(available_bytes); + return Some(MemorySelection { + scope: SystemMemoryResourceScope::Cgroup, + total_bytes: cgroup.total_bytes, + used_bytes, + available_bytes, + host_total_bytes, + }); + } + + if host_total_bytes == 0 { + return None; + } + + Some(MemorySelection { + scope: SystemMemoryResourceScope::Host, + total_bytes: host_total_bytes, + used_bytes: host_used_bytes.min(host_total_bytes), + available_bytes: host_available_bytes.min(host_total_bytes), + host_total_bytes, + }) +} + +fn compute_fabro_storage_usage( + summaries: &[fabro_types::Run], + storage_path: &Path, +) -> anyhow::Result { + let usage = build_disk_usage_response(summaries, storage_path, false)?; + Ok(FabroStorageUsage { + managed_bytes: usage.total_size_bytes.unwrap_or_default(), + reclaimable_bytes: usage.total_reclaimable_bytes.unwrap_or_default(), + }) +} + +fn sample_disk_resources( + storage_path: &Path, + fabro_usage: FabroStorageUsage, +) -> SystemDiskResources { + let disks = Disks::new_with_refreshed_list(); + let candidates = disks + .list() + .iter() + .map(|disk| DiskCandidate { + mount_point: disk.mount_point().to_path_buf(), + filesystem: disk.file_system().to_string_lossy().to_string(), + total_bytes: disk.total_space(), + available_bytes: disk.available_space(), + }) + .collect::>(); + + let Some(disk) = select_storage_disk(storage_path, &candidates) else { + return SystemDiskResources { + supported: false, + scope: SystemDiskResourceScope::StorageFilesystem, + unavailable_reason: Some(format!( + "no filesystem mount matched storage path {}", + storage_path.display() + )), + storage_path: storage_path.display().to_string(), + mount_point: None, + filesystem: None, + total_bytes: None, + used_bytes: None, + available_bytes: None, + used_percent: None, + fabro_managed_bytes: fabro_usage.managed_bytes, + fabro_reclaimable_bytes: fabro_usage.reclaimable_bytes, + }; + }; + + if disk.total_bytes == 0 { + return SystemDiskResources { + supported: false, + scope: SystemDiskResourceScope::StorageFilesystem, + unavailable_reason: Some(format!( + "filesystem {} reported zero total bytes", + disk.mount_point.display() + )), + storage_path: storage_path.display().to_string(), + mount_point: Some(disk.mount_point.display().to_string()), + filesystem: Some(disk.filesystem.clone()), + total_bytes: None, + used_bytes: None, + available_bytes: None, + used_percent: None, + fabro_managed_bytes: fabro_usage.managed_bytes, + fabro_reclaimable_bytes: fabro_usage.reclaimable_bytes, + }; + } + + let available_bytes = disk.available_bytes.min(disk.total_bytes); + let used_bytes = disk.total_bytes.saturating_sub(available_bytes); + + SystemDiskResources { + supported: true, + scope: SystemDiskResourceScope::StorageFilesystem, + unavailable_reason: None, + storage_path: storage_path.display().to_string(), + mount_point: Some(disk.mount_point.display().to_string()), + filesystem: Some(disk.filesystem.clone()), + total_bytes: Some(to_i64(disk.total_bytes)), + used_bytes: Some(to_i64(used_bytes)), + available_bytes: Some(to_i64(available_bytes)), + used_percent: percent(used_bytes, disk.total_bytes), + fabro_managed_bytes: fabro_usage.managed_bytes, + fabro_reclaimable_bytes: fabro_usage.reclaimable_bytes, + } +} + +fn select_storage_disk<'a>( + storage_path: &Path, + disks: &'a [DiskCandidate], +) -> Option<&'a DiskCandidate> { + disks + .iter() + .filter(|disk| storage_path.starts_with(&disk.mount_point)) + .max_by_key(|disk| disk.mount_point.components().count()) +} + +fn percent(used: u64, total: u64) -> Option { + if total == 0 { + return None; + } + Some(round_one((used as f64 / total as f64) * 100.0)) +} + +fn round_one(value: f64) -> f64 { + (value * 10.0).round() / 10.0 +} + +#[cfg(test)] +mod tests { + use std::path::Path; + + use super::{ + CgroupMemory, DiskCandidate, SystemMemoryResourceScope, percent, select_memory, + select_storage_disk, + }; + + #[test] + fn percent_returns_one_decimal_percentage() { + assert_eq!(percent(1, 3), Some(33.3)); + assert_eq!(percent(0, 10), Some(0.0)); + assert_eq!(percent(1, 0), None); + } + + #[test] + fn select_memory_uses_host_values_without_cgroup_limits() { + let selection = + select_memory(1_000, 400, 600, None).expect("host memory should be selected"); + + assert_eq!(selection.scope, SystemMemoryResourceScope::Host); + assert_eq!(selection.total_bytes, 1_000); + assert_eq!(selection.used_bytes, 400); + assert_eq!(selection.available_bytes, 600); + assert_eq!(selection.host_total_bytes, 1_000); + } + + #[test] + fn select_memory_prefers_cgroup_limits_when_available() { + let selection = select_memory( + 1_000, + 200, + 800, + Some(CgroupMemory { + total_bytes: 500, + available_bytes: 125, + }), + ) + .expect("cgroup memory should be selected"); + + assert_eq!(selection.scope, SystemMemoryResourceScope::Cgroup); + assert_eq!(selection.total_bytes, 500); + assert_eq!(selection.used_bytes, 375); + assert_eq!(selection.available_bytes, 125); + assert_eq!(selection.host_total_bytes, 1_000); + } + + #[test] + fn select_storage_disk_uses_longest_mount_point_prefix() { + let disks = vec![ + disk("/"), + disk("/var"), + disk("/var/lib"), + disk("/var/lib-other"), + ]; + + let selected = select_storage_disk(Path::new("/var/lib/fabro/runs"), &disks) + .expect("storage disk should match"); + + assert_eq!(selected.mount_point, Path::new("/var/lib")); + } + + fn disk(mount_point: &str) -> DiskCandidate { + DiskCandidate { + mount_point: Path::new(mount_point).to_path_buf(), + filesystem: "testfs".to_string(), + total_bytes: 1_000, + available_bytes: 500, + } + } +} diff --git a/lib/crates/fabro-server/tests/it/api/system.rs b/lib/crates/fabro-server/tests/it/api/system.rs index 5f11d5f20..923959db6 100644 --- a/lib/crates/fabro-server/tests/it/api/system.rs +++ b/lib/crates/fabro-server/tests/it/api/system.rs @@ -144,6 +144,97 @@ async fn get_system_info_returns_runtime_fields() { ); } +#[tokio::test] +async fn get_system_resources_returns_server_visible_metrics() { + let (_temp, settings, expected_storage_dir) = temp_storage_settings(); + let app = + fabro_server::test_support::build_test_router(test_app_state_with_options(settings, 5)); + + let request = Request::builder() + .method("GET") + .uri(api("/system/resources")) + .body(Body::empty()) + .unwrap(); + let response = app.oneshot(request).await.unwrap(); + + let body = response_json(response, StatusCode::OK, "GET /api/v1/system/resources").await; + let sampled_at = body["sampled_at"] + .as_str() + .expect("sampled_at should be an RFC3339 timestamp"); + chrono::DateTime::parse_from_rfc3339(sampled_at).expect("sampled_at should parse as RFC3339"); + + assert_eq!(body["cpu"]["supported"], true); + assert_eq!(body["cpu"]["scope"], "server_environment"); + assert!( + body["cpu"]["sample_window_ms"].is_null() + || body["cpu"]["sample_window_ms"] + .as_i64() + .is_some_and(|value| value >= 0), + "sample window should be null until a delta sample is available or nonnegative: {body}" + ); + assert!( + body["cpu"]["logical_cpus"].as_i64().unwrap_or_default() > 0, + "logical CPU count should be positive" + ); + assert_percent_if_present(&body["cpu"]["usage_percent"]); + + assert_eq!(body["memory"]["supported"], true); + assert!(matches!( + body["memory"]["scope"].as_str(), + Some("host" | "cgroup") + )); + assert_nonnegative_i64(&body["memory"]["total_bytes"], "memory.total_bytes"); + assert_nonnegative_i64(&body["memory"]["used_bytes"], "memory.used_bytes"); + assert_nonnegative_i64(&body["memory"]["available_bytes"], "memory.available_bytes"); + assert_percent_if_present(&body["memory"]["used_percent"]); + + assert_eq!(body["disk"]["supported"], true); + assert_eq!(body["disk"]["scope"], "storage_filesystem"); + assert_eq!( + body["disk"]["storage_path"], + expected_storage_dir.display().to_string() + ); + assert!(body["disk"]["mount_point"].as_str().is_some()); + assert_nonnegative_i64(&body["disk"]["total_bytes"], "disk.total_bytes"); + assert_nonnegative_i64(&body["disk"]["used_bytes"], "disk.used_bytes"); + assert_nonnegative_i64(&body["disk"]["available_bytes"], "disk.available_bytes"); + assert_percent_if_present(&body["disk"]["used_percent"]); + assert_nonnegative_i64( + &body["disk"]["fabro_managed_bytes"], + "disk.fabro_managed_bytes", + ); + assert_nonnegative_i64( + &body["disk"]["fabro_reclaimable_bytes"], + "disk.fabro_reclaimable_bytes", + ); + assert!( + body["notes"] + .as_array() + .is_some_and(std::vec::Vec::is_empty), + "initial test app resources should not need notes: {body}" + ); +} + +fn assert_nonnegative_i64(value: &serde_json::Value, name: &str) { + assert!( + value.as_i64().is_some_and(|value| value >= 0), + "{name} should be a nonnegative integer: {value:?}" + ); +} + +fn assert_percent_if_present(value: &serde_json::Value) { + if value.is_null() { + return; + } + let percent = value + .as_f64() + .expect("percent should be numeric when present"); + assert!( + (0.0..=100.0).contains(&percent), + "percent should be between 0 and 100: {percent}" + ); +} + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_app_state_with_options_respects_max_concurrent_runs() { let app = test_app_with_scheduler(test_app_state_with_options(test_settings(), 1)); diff --git a/lib/packages/fabro-api-client/src/.openapi-generator/FILES b/lib/packages/fabro-api-client/src/.openapi-generator/FILES index 46ad2dc83..bfc203488 100644 --- a/lib/packages/fabro-api-client/src/.openapi-generator/FILES +++ b/lib/packages/fabro-api-client/src/.openapi-generator/FILES @@ -378,10 +378,17 @@ models/submit-answer-yes-request.ts models/submit-turn-request.ts models/success-reason.ts models/system-actor-kind.ts +models/system-cpu-resource-scope.ts +models/system-cpu-resources.ts +models/system-disk-resource-scope.ts +models/system-disk-resources.ts models/system-features.ts models/system-info-response.ts +models/system-memory-resource-scope.ts +models/system-memory-resources.ts models/system-repair-run-issue.ts models/system-repair-runs-response.ts +models/system-resources-response.ts models/system-run-counts.ts models/timeline-entry-response.ts models/tls-mode.ts diff --git a/lib/packages/fabro-api-client/src/api/system-api.ts b/lib/packages/fabro-api-client/src/api/system-api.ts index a18e7b642..27856ebaa 100644 --- a/lib/packages/fabro-api-client/src/api/system-api.ts +++ b/lib/packages/fabro-api-client/src/api/system-api.ts @@ -33,6 +33,8 @@ import type { PruneRunsResponse } from '../models'; import type { SystemInfoResponse } from '../models'; // @ts-ignore import type { SystemRepairRunsResponse } from '../models'; +// @ts-ignore +import type { SystemResourcesResponse } from '../models'; /** * SystemApi - axios parameter creator */ @@ -192,6 +194,42 @@ export const SystemApiAxiosParamCreator = function (configuration?: Configuratio options: localVarRequestOptions, }; }, + /** + * Returns server-visible CPU, memory, and storage filesystem resource usage. + * @summary Retrieve System Resources + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getSystemResources: async (options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/v1/system/resources`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication SessionCookie required + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, /** * Deletes completed runs matching the provided filters, or previews the deletion set when dry-run is enabled. * @summary Prune Runs @@ -292,6 +330,18 @@ export const SystemApiFp = function(configuration?: Configuration) { const localVarOperationServerBasePath = operationServerMap['SystemApi.getSystemRepairRuns']?.[localVarOperationServerIndex]?.url; return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); }, + /** + * Returns server-visible CPU, memory, and storage filesystem resource usage. + * @summary Retrieve System Resources + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getSystemResources(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getSystemResources(options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['SystemApi.getSystemResources']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, /** * Deletes completed runs matching the provided filters, or previews the deletion set when dry-run is enabled. * @summary Prune Runs @@ -352,6 +402,15 @@ export const SystemApiFactory = function (configuration?: Configuration, basePat getSystemRepairRuns(options?: RawAxiosRequestConfig): AxiosPromise { return localVarFp.getSystemRepairRuns(options).then((request) => request(axios, basePath)); }, + /** + * Returns server-visible CPU, memory, and storage filesystem resource usage. + * @summary Retrieve System Resources + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getSystemResources(options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.getSystemResources(options).then((request) => request(axios, basePath)); + }, /** * Deletes completed runs matching the provided filters, or previews the deletion set when dry-run is enabled. * @summary Prune Runs @@ -411,6 +470,16 @@ export class SystemApi extends BaseAPI { return SystemApiFp(this.configuration).getSystemRepairRuns(options).then((request) => request(this.axios, this.basePath)); } + /** + * Returns server-visible CPU, memory, and storage filesystem resource usage. + * @summary Retrieve System Resources + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public getSystemResources(options?: RawAxiosRequestConfig) { + return SystemApiFp(this.configuration).getSystemResources(options).then((request) => request(this.axios, this.basePath)); + } + /** * Deletes completed runs matching the provided filters, or previews the deletion set when dry-run is enabled. * @summary Prune Runs diff --git a/lib/packages/fabro-api-client/src/models/index.ts b/lib/packages/fabro-api-client/src/models/index.ts index 178d33d36..e258475fe 100644 --- a/lib/packages/fabro-api-client/src/models/index.ts +++ b/lib/packages/fabro-api-client/src/models/index.ts @@ -354,10 +354,17 @@ export * from './submit-answer-yes-request'; export * from './submit-turn-request'; export * from './success-reason'; export * from './system-actor-kind'; +export * from './system-cpu-resource-scope'; +export * from './system-cpu-resources'; +export * from './system-disk-resource-scope'; +export * from './system-disk-resources'; export * from './system-features'; export * from './system-info-response'; +export * from './system-memory-resource-scope'; +export * from './system-memory-resources'; export * from './system-repair-run-issue'; export * from './system-repair-runs-response'; +export * from './system-resources-response'; export * from './system-run-counts'; export * from './timeline-entry-response'; export * from './tls-mode'; diff --git a/lib/packages/fabro-api-client/src/models/system-cpu-resource-scope.ts b/lib/packages/fabro-api-client/src/models/system-cpu-resource-scope.ts new file mode 100644 index 000000000..e4637a6e7 --- /dev/null +++ b/lib/packages/fabro-api-client/src/models/system-cpu-resource-scope.ts @@ -0,0 +1,25 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Fabro Run API + * HTTP API for managing Fabro workflow run executions. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * Scope for CPU resource metrics. + */ + +export const SystemCpuResourceScope = { + SERVER_ENVIRONMENT: 'server_environment' +} as const; + +export type SystemCpuResourceScope = typeof SystemCpuResourceScope[keyof typeof SystemCpuResourceScope]; diff --git a/lib/packages/fabro-api-client/src/models/system-cpu-resources.ts b/lib/packages/fabro-api-client/src/models/system-cpu-resources.ts new file mode 100644 index 000000000..216912783 --- /dev/null +++ b/lib/packages/fabro-api-client/src/models/system-cpu-resources.ts @@ -0,0 +1,46 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Fabro Run API + * HTTP API for managing Fabro workflow run executions. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { SystemCpuResourceScope } from './system-cpu-resource-scope'; + +/** + * CPU resources visible to the Fabro server process. + */ +export interface SystemCpuResources { + /** + * Whether CPU metrics are available on this platform. + */ + 'supported': boolean; + 'scope': SystemCpuResourceScope; + /** + * Reason metrics are unavailable when unsupported. + */ + 'unavailable_reason': string | null; + /** + * Logical CPUs visible to the server process. + */ + 'logical_cpus': number | null; + /** + * CPU usage percentage, null until a delta sample is available. + */ + 'usage_percent': number | null; + /** + * Elapsed milliseconds since the previous CPU sample, null until a delta sample is available. + */ + 'sample_window_ms': number | null; +} + diff --git a/lib/packages/fabro-api-client/src/models/system-disk-resource-scope.ts b/lib/packages/fabro-api-client/src/models/system-disk-resource-scope.ts new file mode 100644 index 000000000..79daf2b31 --- /dev/null +++ b/lib/packages/fabro-api-client/src/models/system-disk-resource-scope.ts @@ -0,0 +1,25 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Fabro Run API + * HTTP API for managing Fabro workflow run executions. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * Scope for disk resource metrics. + */ + +export const SystemDiskResourceScope = { + STORAGE_FILESYSTEM: 'storage_filesystem' +} as const; + +export type SystemDiskResourceScope = typeof SystemDiskResourceScope[keyof typeof SystemDiskResourceScope]; diff --git a/lib/packages/fabro-api-client/src/models/system-disk-resources.ts b/lib/packages/fabro-api-client/src/models/system-disk-resources.ts new file mode 100644 index 000000000..5ff66fb39 --- /dev/null +++ b/lib/packages/fabro-api-client/src/models/system-disk-resources.ts @@ -0,0 +1,70 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Fabro Run API + * HTTP API for managing Fabro workflow run executions. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { SystemDiskResourceScope } from './system-disk-resource-scope'; + +/** + * Filesystem resources for the configured Fabro storage root. + */ +export interface SystemDiskResources { + /** + * Whether storage filesystem metrics are available. + */ + 'supported': boolean; + 'scope': SystemDiskResourceScope; + /** + * Reason metrics are unavailable when unsupported. + */ + 'unavailable_reason': string | null; + /** + * Configured Fabro storage directory. + */ + 'storage_path': string; + /** + * Mount point for the filesystem containing the storage directory. + */ + 'mount_point': string | null; + /** + * Filesystem name reported by the operating system. + */ + 'filesystem': string | null; + /** + * Total bytes on the storage filesystem. + */ + 'total_bytes': number | null; + /** + * Used bytes on the storage filesystem. + */ + 'used_bytes': number | null; + /** + * Available bytes on the storage filesystem. + */ + 'available_bytes': number | null; + /** + * Used percentage on the storage filesystem. + */ + 'used_percent': number | null; + /** + * Bytes managed by Fabro under the storage root. + */ + 'fabro_managed_bytes': number; + /** + * Bytes reclaimable through Fabro pruning. + */ + 'fabro_reclaimable_bytes': number; +} + diff --git a/lib/packages/fabro-api-client/src/models/system-memory-resource-scope.ts b/lib/packages/fabro-api-client/src/models/system-memory-resource-scope.ts new file mode 100644 index 000000000..31340786e --- /dev/null +++ b/lib/packages/fabro-api-client/src/models/system-memory-resource-scope.ts @@ -0,0 +1,26 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Fabro Run API + * HTTP API for managing Fabro workflow run executions. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * `cgroup` when Linux cgroup limits are available, otherwise `host`. + */ + +export const SystemMemoryResourceScope = { + HOST: 'host', + CGROUP: 'cgroup' +} as const; + +export type SystemMemoryResourceScope = typeof SystemMemoryResourceScope[keyof typeof SystemMemoryResourceScope]; diff --git a/lib/packages/fabro-api-client/src/models/system-memory-resources.ts b/lib/packages/fabro-api-client/src/models/system-memory-resources.ts new file mode 100644 index 000000000..3f0d4a8bd --- /dev/null +++ b/lib/packages/fabro-api-client/src/models/system-memory-resources.ts @@ -0,0 +1,54 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Fabro Run API + * HTTP API for managing Fabro workflow run executions. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { SystemMemoryResourceScope } from './system-memory-resource-scope'; + +/** + * Memory resources visible to the Fabro server process. + */ +export interface SystemMemoryResources { + /** + * Whether memory metrics are available on this platform. + */ + 'supported': boolean; + 'scope': SystemMemoryResourceScope; + /** + * Reason metrics are unavailable when unsupported. + */ + 'unavailable_reason': string | null; + /** + * Total memory for the reported scope. + */ + 'total_bytes': number | null; + /** + * Used memory for the reported scope. + */ + 'used_bytes': number | null; + /** + * Available memory for the reported scope. + */ + 'available_bytes': number | null; + /** + * Used memory percentage for the reported scope. + */ + 'used_percent': number | null; + /** + * Host total memory, included even when reporting a cgroup scope. + */ + 'host_total_bytes': number | null; +} + diff --git a/lib/packages/fabro-api-client/src/models/system-resources-response.ts b/lib/packages/fabro-api-client/src/models/system-resources-response.ts new file mode 100644 index 000000000..c2fb6fbdc --- /dev/null +++ b/lib/packages/fabro-api-client/src/models/system-resources-response.ts @@ -0,0 +1,42 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Fabro Run API + * HTTP API for managing Fabro workflow run executions. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { SystemCpuResources } from './system-cpu-resources'; +// May contain unused imports in some cases +// @ts-ignore +import type { SystemDiskResources } from './system-disk-resources'; +// May contain unused imports in some cases +// @ts-ignore +import type { SystemMemoryResources } from './system-memory-resources'; + +/** + * Server-visible runtime resource usage for the active Fabro process environment. + */ +export interface SystemResourcesResponse { + /** + * Timestamp when the sample was collected. + */ + 'sampled_at': string; + 'cpu': SystemCpuResources; + 'memory': SystemMemoryResources; + 'disk': SystemDiskResources; + /** + * Human-readable caveats about unavailable or scoped metrics. + */ + 'notes': Array; +} +