fix(api): показать частичные отказы каталога контейнеров
This commit is contained in:
1 parent
1e0fc4cd2d
commit
644ddb64b3
10 files changed
+191
-5
No files matched your search
@@ -57,6 +57,10 @@
|
||||
"./statistics": {
|
||||
"types": "./dist/statistics.d.ts",
|
||||
"default": "./dist/statistics.js"
|
||||
},
|
||||
"./containers": {
|
||||
"types": "./dist/containers.d.ts",
|
||||
"default": "./dist/containers.js"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { z } from "zod"
|
||||
|
||||
const serverId = z.number().int().positive().safe()
|
||||
const time = z.string().datetime({ offset: true })
|
||||
export const containerStateRowSchema = z.object({
|
||||
id: z.string().min(1), rosId: z.string().min(1), name: z.string().min(1),
|
||||
serverId: z.string().regex(/^[1-9]\d*$/),
|
||||
image: z.string(), tag: z.string(), status: z.enum(["running", "stopped", "error", "unknown"]),
|
||||
envs: z.array(z.object({ key: z.string().min(1), value: z.string() })),
|
||||
mounts: z.array(z.object({ dst: z.string().min(1), src: z.string().optional() })),
|
||||
interfaces: z.array(z.string().min(1)), cmd: z.string().optional(),
|
||||
startOnBoot: z.boolean().nullable(), comment: z.string(), uptime: z.string().optional(),
|
||||
cpu: z.number().finite().min(0).max(100).optional(), memMb: z.number().finite().nonnegative().optional(),
|
||||
})
|
||||
export const containerServerStateSchema = z.object({
|
||||
serverId, collectedAt: time, availability: z.enum(["available", "unsupported", "error"]),
|
||||
containers: z.array(containerStateRowSchema),
|
||||
failures: z.array(z.object({ resource: z.enum(["containers", "envs", "mounts"]), error: z.string().min(1) })),
|
||||
}).superRefine((value, ctx) => {
|
||||
const ids = new Set<string>()
|
||||
for (const row of value.containers) {
|
||||
if (row.serverId !== String(value.serverId) || row.id !== value.serverId + "-" + row.rosId || ids.has(row.rosId)) ctx.addIssue({ code: "custom", message: "Контейнеры не соответствуют устройству или содержат дубли" })
|
||||
ids.add(row.rosId)
|
||||
}
|
||||
const resources = value.failures.map(f => f.resource)
|
||||
if (new Set(resources).size !== resources.length) ctx.addIssue({ code: "custom", message: "Дубли ошибок ресурсов" })
|
||||
if (value.availability !== "available" && value.containers.length) ctx.addIssue({ code: "custom", message: "Неуспешная загрузка содержит контейнеры" })
|
||||
if (value.availability === "error" && !resources.includes("containers") || value.availability === "available" && resources.includes("containers") || value.availability === "unsupported" && resources.length) ctx.addIssue({ code: "custom", message: "Состояние не соответствует ошибкам" })
|
||||
})
|
||||
export const containersStateSchema = z.object({
|
||||
collectedAt: time, servers: z.array(containerServerStateSchema),
|
||||
}).superRefine((value, ctx) => {
|
||||
if (new Set(value.servers.map(s => s.serverId)).size !== value.servers.length) ctx.addIssue({ code: "custom", message: "Дубли устройств" })
|
||||
})
|
||||
export type ContainerStateRow = z.infer<typeof containerStateRowSchema>
|
||||
export type ContainerServerState = z.infer<typeof containerServerStateSchema>
|
||||
export type ContainersState = z.infer<typeof containersStateSchema>
|
||||
Reference in new issue
Block a user