Phase 2: Volume Wizard, GPU & device passthrough (0.2.0)
Backend: - gpu_service: detect NVIDIA (nvidia-smi) + AMD/Intel (/dev/dri, sysfs); inject helpers (nvidia deploy.reservations, /dev/dri + groups + LIBVA) - volume_service: list/orphaned/prune volumes; NFS/SMB/named/bind/tmpfs YAML generation (generate-yaml) - device_service: USB/TTY/DRI detection + sandboxed host path browser - compose_edit_service: server-side merge of volume/gpu/device fragments - routers: volumes (+host paths), editor (services/add-volume/set-gpu/ add-device/remove-device/set-privileged), system gpus+devices - compose: bind-mount /dev:ro for detection Frontend: - split-pane StackEditor with helper panel (service picker + tabs) - VolumeWizard (bind/named/nfs/smb/tmpfs) + HostPathBrowser - GPUSelector, DevicePanel; api clients for volumes/editor/system Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
7775128c07
commit
b553c1b861
@@ -4,6 +4,7 @@ import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import Editor from "@monaco-editor/react";
|
||||
import { Rocket, Save, Wand2, FileCode } from "lucide-react";
|
||||
import { Button, Card, Input } from "@/components/ui";
|
||||
import { EditorHelperPanel } from "@/components/stacks/EditorHelperPanel";
|
||||
import { stacksApi } from "@/api/stacks";
|
||||
import { apiErrorMessage } from "@/api/client";
|
||||
import { useThemeStore } from "@/store/theme";
|
||||
@@ -131,25 +132,35 @@ export function StackEditor() {
|
||||
</TabBtn>
|
||||
</div>
|
||||
|
||||
<div className="min-h-0 flex-1 overflow-hidden rounded-lg border border-slate-200 dark:border-slate-700">
|
||||
{tab === "compose" ? (
|
||||
<Editor
|
||||
height="100%"
|
||||
language="yaml"
|
||||
theme={theme === "dark" ? "vs-dark" : "light"}
|
||||
value={yaml}
|
||||
onChange={(v) => setYaml(v ?? "")}
|
||||
options={{ minimap: { enabled: false }, fontSize: 13, tabSize: 2 }}
|
||||
/>
|
||||
) : (
|
||||
<Editor
|
||||
height="100%"
|
||||
language="ini"
|
||||
theme={theme === "dark" ? "vs-dark" : "light"}
|
||||
value={env}
|
||||
onChange={(v) => setEnv(v ?? "")}
|
||||
options={{ minimap: { enabled: false }, fontSize: 13 }}
|
||||
/>
|
||||
<div className="flex min-h-0 flex-1 gap-3">
|
||||
{/* Editor */}
|
||||
<div className="min-h-0 flex-1 overflow-hidden rounded-lg border border-slate-200 dark:border-slate-700">
|
||||
{tab === "compose" ? (
|
||||
<Editor
|
||||
height="100%"
|
||||
language="yaml"
|
||||
theme={theme === "dark" ? "vs-dark" : "light"}
|
||||
value={yaml}
|
||||
onChange={(v) => setYaml(v ?? "")}
|
||||
options={{ minimap: { enabled: false }, fontSize: 13, tabSize: 2 }}
|
||||
/>
|
||||
) : (
|
||||
<Editor
|
||||
height="100%"
|
||||
language="ini"
|
||||
theme={theme === "dark" ? "vs-dark" : "light"}
|
||||
value={env}
|
||||
onChange={(v) => setEnv(v ?? "")}
|
||||
options={{ minimap: { enabled: false }, fontSize: 13 }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Helper panel (Volumes / GPU / Devices) */}
|
||||
{tab === "compose" && (
|
||||
<div className="w-[38%] min-w-[320px] overflow-hidden rounded-lg border border-slate-200 dark:border-slate-700">
|
||||
<EditorHelperPanel yaml={yaml} onYaml={setYaml} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user