"use client"; import React, { useState, useEffect } from "react"; import { cn } from "@/lib/utils"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Separator } from "@/components/ui/separator"; import { Progress } from "@/components/ui/progress"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Cpu, CheckCircle2, XCircle, AlertTriangle, FileText, Terminal, Info, Settings, Download, ChevronDown, ChevronRight, ExternalLink, RefreshCw, } from "lucide-react"; import { fetchQCrowsImages, KATA_REQUIRED_KERNEL_OPTIONS, KATA_RECOMMENDED_KERNEL_OPTIONS, HYPERVISOR_KERNEL_FORMAT, VMM_MODULE_MATRIX, COMPRESS_PRIORITY, INITRD_REGEN_DEFAULTS, type QCrowsImage, type QCrowsKernelConfig, type QCrowsBootParams, type InitrdRegenConfig, type InitrdRegenResult, } from "@/lib/kata-mock"; import { regenInitrd } from "@/lib/backend/adapter"; export function KernelDetail() { const [images, setImages] = useState([]); const [loading, setLoading] = useState(true); const [selectedImage, setSelectedImage] = useState(null); useEffect(() => { fetchQCrowsImages().then((data) => { setImages(data); if (data.length > 0) setSelectedImage(data[0]); setLoading(false); }); }, []); if (loading) { return (
Loading kernel images...
); } return (
{/* Header */}

Kernel Management

Inspect guest kernels bundled in QCrows images — config options, boot parameters, and hypervisor compatibility

QCrows v0.2 — Kernel REQUIRED
{/* Image selector sidebar */}
QCrows Images
{images.map((img) => ( ))}
{/* Main kernel detail area */}
{selectedImage && ( )}
); } function KernelDetailView({ image }: { image: QCrowsImage }) { const meta = image.metadata; const kConfig = image.kernelConfig; const bootParams = image.bootParams; const [regenOpen, setRegenOpen] = useState(false); const [regenConfig, setRegenConfig] = useState>(INITRD_REGEN_DEFAULTS); const [regening, setRegening] = useState(false); const [regenResult, setRegenResult] = useState(null); const executeRegen = async () => { setRegening(true); setRegenResult(null); try { const result = await regenInitrd(image, regenConfig); setRegenResult(result); } catch { setRegenResult({ success: false, output: "", sizeMB: 0, vmm: regenConfig.vmm || "qemu", format: regenConfig.format || "cpio-gzip", initStyle: regenConfig.initStyle || "busybox", kernelVersion: meta.kernelVersion, moduleCount: 0, messages: [], errors: ["Initrd regeneration failed unexpectedly"], }); } finally { setRegening(false); } }; return ( <> {/* Kernel Overview Cards */}
} color="emerald" /> } color="blue" /> } color="amber" /> : } color={meta.kernelConfigValid ? "emerald" : "red"} />
{/* Hypervisor Compatibility */} Hypervisor Kernel Format Compatibility
{meta.hypervisors.map((hyp) => { const requirement = HYPERVISOR_KERNEL_FORMAT[hyp]; const matches = requirement && requirement.format === meta.kernelFormat; const archMatch = requirement && requirement.arches.includes(meta.arch); return (
{hyp}
Requires: {requirement?.format || "vmlinux"} ({requirement?.arches.join(", ") || "any"})
{matches && archMatch ? ( <> Compatible ) : ( <> Format mismatch )}
); })}
{/* Initrd Regen Action */}
Initrd Regeneration

Rebuild the initrd component with environment-aware module selection. Unlike dracut or{" "} mkinitramfs, this produces an initrd where kata-agent IS the final process (no pivot_root) and includes ONLY the modules required by the detected VMM.

Auto-detects: VMM, compression, init style, kata-agent | Module matrix: {Object.keys(VMM_MODULE_MATRIX).length} VMMs
{/* Regen Dialog */} {regenOpen && !regenResult && (
Configure Initrd Regeneration
{/* VMM Selection */}
{/* Compression */}
{/* Init Style */}
{/* In-place toggle */}
{/* Module preview for selected VMM */} {regenConfig.vmm && VMM_MODULE_MATRIX[regenConfig.vmm] && (
Modules for {regenConfig.vmm}:
{VMM_MODULE_MATRIX[regenConfig.vmm].required.map((m) => ( {m} ))} {VMM_MODULE_MATRIX[regenConfig.vmm].optional.map((m) => ( {m}? ))}
)}
)} {/* Regen Result */} {regenResult && (
{regenResult.success ? ( ) : ( )} {regenResult.success ? "Initrd regenerated successfully" : "Initrd regeneration failed"}
{regenResult.success && (
Output
{regenResult.output}
Size
{regenResult.sizeMB} MB
Modules
{regenResult.moduleCount} included
)} {regenResult.messages.length > 0 && (
Pipeline Log
{regenResult.messages.map((msg, i) => (
{msg}
))}
)} {regenResult.errors.length > 0 && (
Errors
{regenResult.errors.map((err, i) => (
{err}
))}
)}
)}
{/* Tabs: Config Options / Boot Params / Build Info */} Kernel Config Boot Parameters Build Info ); } function KernelStatCard({ label, value, icon, color, }: { label: string; value: string; icon: React.ReactNode; color: "emerald" | "blue" | "amber" | "red"; }) { const colorMap = { emerald: "text-emerald-400", blue: "text-blue-400", amber: "text-amber-400", red: "text-red-400", }; return (
{icon} {label}
{value}
); } function KernelConfigPanel({ config, kernelVersion, }: { config?: QCrowsKernelConfig; kernelVersion: string; }) { const [showRecommended, setShowRecommended] = useState(false); if (!config) { return ( No kernel config data available for this image. ); } const requiredPass = Object.values(config.requiredOptions).filter(Boolean).length; const requiredTotal = Object.keys(config.requiredOptions).length; const optionalPass = Object.values(config.optionalOptions).filter(Boolean).length; const optionalTotal = Object.keys(config.optionalOptions).length; const allRequiredPass = requiredPass === requiredTotal; return (
{/* Summary cards */}
Required Options
{requiredPass}/{requiredTotal} {allRequiredPass ? ( ) : ( )}
div]:bg-emerald-500" : "[&>div]:bg-red-500")} />
Recommended Options
{optionalPass}/{optionalTotal}
Config Statistics
Total options {config.totalOptions.toLocaleString()}
Built-in {config.builtInCount.toLocaleString()}
Modules {config.moduleCount.toLocaleString()}
{/* Required options detail */} Required Kata Kernel Options {Object.entries(config.requiredOptions).map(([opt, enabled]) => { const desc = KATA_REQUIRED_KERNEL_OPTIONS[opt] || ""; return (
{enabled ? ( ) : ( )} {opt}
{desc} {enabled ? "y" : "MISSING"}
); })}
{/* Recommended options (collapsible) */} setShowRecommended(!showRecommended)} > Recommended Kata Kernel Options {optionalPass}/{optionalTotal} {showRecommended ? ( ) : ( )} {showRecommended && ( {Object.entries(config.optionalOptions).map(([opt, enabled]) => { const desc = KATA_RECOMMENDED_KERNEL_OPTIONS[opt] || ""; return (
{enabled ? ( ) : ( )} {opt}
{desc} {enabled ? "y" : "n/m"}
); })}
)}
); } function BootParamsPanel({ bootParams, kernelVersion, }: { bootParams?: QCrowsBootParams; kernelVersion: string; }) { if (!bootParams) { return ( No boot parameters data available for this image. ); } const dangerousParams = [ "module.sig_enforce=0", "nokaslr", "nopti", "nosmap", "nosmep", ]; const warnings = bootParams.params.filter((p) => dangerousParams.some((d) => p.includes(d.replace("=", "").replace("=0", ""))) ); return (
Kernel Command Line
BOOT_IMAGE=/kernel/vmlinuz{" "} {bootParams.params.map((param, i) => ( {i > 0 && " "} param.includes(d.split("=")[0])) ? "text-amber-400 underline decoration-amber-600 decoration-wavy" : "text-emerald-300" )} > {param} ))}
Source: {bootParams.source} {bootParams.params.length} parameters
{/* Parameter breakdown */} Parameter Breakdown {bootParams.params.map((param, i) => { const isDangerous = dangerousParams.some((d) => param.includes(d.split("=")[0])); const [key, ...valParts] = param.split("="); const val = valParts.join("="); return (
{isDangerous ? ( ) : ( )} {key} {val && ( <> = {val} )} {isDangerous && ( Security concern )}
); })}
{warnings.length > 0 && (
Security Warnings
The following parameters may reduce security isolation in the guest VM:
    {warnings.map((w, i) => (
  • {w}
  • ))}
)}
); } function BuildInfoPanel({ image }: { image: QCrowsImage }) { const build = image.build; const meta = image.metadata; if (!build) { return ( No build information available for this image. ); } return (
Kernel Build Provenance
{/* Kernel file paths after import */} Import Paths (after registration) {meta.initrdIncluded && ( )} {meta.bootParamsIncluded && ( )}
); } function BuildInfoRow({ label, value, mono }: { label: string; value: string; mono?: boolean }) { return (
{label} {value}
); } function PathRow({ label, path, exists }: { label: string; path: string; exists: boolean }) { return (
{exists ? ( ) : ( )} {label} {path}
); }