mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-07 16:09:43 +02:00
feat(docker): resource templates, GPU, elastic disk, bridge-hooks listener
- One-click "Run in Docker" gains an expandable settings panel with a Template picker (Small 2G/1 · Medium 4G/2 default · Large 8G/4 · GPU 8G/4/all) plus memory/cpu/gpu/network/image/mount-creds overrides. Any tweak creates a dedicated per-case host; the plain checkbox keeps using the shared `default` host. - GPU passthrough: `gpus` on DockerHost/SessionDocker -> `--gpus <value>` in create args (needs the NVIDIA container toolkit). Elastic disk: no `--storage-opt` cap, so container storage grows as data flows in. - CODEMAN_DOCKER_BRIDGE_HOOKS=1: opt-in second listener on the docker bridge gateway (auto-detected 172.17.0.1, override CODEMAN_DOCKER_BRIDGE_HOST) that serves ONLY the hook endpoints and delegates into the secret-gated pipeline, so in-container hooks fire on a loopback-only server. Non-hook paths -> 403; host-internal, not LAN. Verified live: Large template applies real 8GB/4CPU limits; a secret-authenticated hook POST from inside a container now reaches the handler (was connection-refused); non-hook paths return 403; template UI + GPU field verified via Playwright. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -413,6 +413,11 @@ export const DockerHostSchema = z.object({
|
||||
.regex(/^[a-zA-Z0-9][a-zA-Z0-9_.-]+$/, 'Invalid network name')
|
||||
.optional(),
|
||||
resources: DockerResourceLimitsSchema.optional(),
|
||||
gpus: z
|
||||
.string()
|
||||
.max(128)
|
||||
.regex(/^(all|\d+|device=[a-zA-Z0-9,:._-]+)$/, 'GPUs must be all / a count / device=...')
|
||||
.optional(),
|
||||
mountCredentials: z.boolean().optional(),
|
||||
hooksEnabled: z.boolean().optional(),
|
||||
resumeOnStart: z.boolean().optional(),
|
||||
@@ -485,6 +490,41 @@ export const DockerImportSchema = z.object({
|
||||
.regex(NO_SHELL_META, 'Invalid characters in destination path'),
|
||||
});
|
||||
|
||||
// One-click "Run in Docker" case creation. name/description behave like a normal
|
||||
// case; the docker fields are OPTIONAL overrides of the predefined defaults (the
|
||||
// checkbox alone, with no overrides, uses the shared `default` host).
|
||||
export const DockerQuickCreateSchema = z.object({
|
||||
name: z.string().regex(/^[a-zA-Z0-9_-]+$/, 'Invalid case name format'),
|
||||
description: z.string().max(1000).optional(),
|
||||
image: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(512)
|
||||
.regex(/^[a-zA-Z0-9][\w./:@-]*$/, 'Invalid image reference')
|
||||
.regex(NO_SHELL_META, 'Invalid characters in image reference')
|
||||
.optional(),
|
||||
network: z.enum(['bridge', 'none', 'custom']).optional(),
|
||||
networkName: z
|
||||
.string()
|
||||
.max(128)
|
||||
.regex(/^[a-zA-Z0-9][a-zA-Z0-9_.-]+$/, 'Invalid network name')
|
||||
.optional(),
|
||||
memory: z
|
||||
.string()
|
||||
.regex(/^\d+[bkmg]?$/i, 'Memory must be like 512m / 4g')
|
||||
.optional(),
|
||||
cpus: z
|
||||
.string()
|
||||
.regex(/^\d+(\.\d+)?$/, 'CPUs must be a number')
|
||||
.optional(),
|
||||
gpus: z
|
||||
.string()
|
||||
.max(128)
|
||||
.regex(/^(all|\d+|device=[a-zA-Z0-9,:._-]+)$/, 'GPUs must be all / a count / device=...')
|
||||
.optional(),
|
||||
mountCredentials: z.boolean().optional(),
|
||||
});
|
||||
|
||||
// ========== Quick Start ==========
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user