Update version 1.2.3

This commit is contained in:
MacRimi
2026-07-14 19:22:33 +02:00
parent 1872a309ec
commit 8060f59d69
10 changed files with 230 additions and 17 deletions

View File

@@ -413,7 +413,7 @@ const formatRunAt = (iso: string | null) => {
// belong to matches "the key is a PBS thing" without dragging in
// the fuller management surface.
// ──────────────────────────────────────────────────────────────
function PbsKeyfileActions() {
function PbsKeyfileActions({ pbsRepository }: { pbsRepository?: string }) {
const { data: info, mutate: mutateInfo } = useSWR<{
installed: boolean
fingerprint?: string
@@ -428,6 +428,22 @@ function PbsKeyfileActions() {
const [busy, setBusy] = useState(false)
const [err, setErr] = useState<string | null>(null)
// Auto-discover a PVE-managed keyfile at /etc/pve/priv/storage/<NAME>.enc
// that matches this specific PBS repository. When present, the Upload
// modal surfaces a one-click "Use PVE-managed key" shortcut at the
// top so the operator doesn't have to hunt down the file path — the
// exact convenience the shell TUI already provides during its import
// wizard. Only fetched while the modal is open + a repository is known.
const { data: pveDiscover } = useSWR<{
entries: Array<{ name: string; server: string; datastore: string; path: string; matches_repository: boolean }>
}>(
uploadOpen && pbsRepository
? `/api/host-backups/pbs-encryption/discover-pve-keyfiles?repository=${encodeURIComponent(pbsRepository)}`
: null,
fetcher,
)
const pveMatch = pveDiscover?.entries?.find((e) => e.matches_repository) || null
const closeUpload = () => {
setUploadOpen(false)
setImportFile(null)
@@ -572,6 +588,34 @@ function PbsKeyfileActions() {
</DialogDescription>
</DialogHeader>
<div className="space-y-3">
{pveMatch && (
<div className="rounded-md border border-emerald-500/40 bg-emerald-500/10 p-3 space-y-2 text-xs">
<div className="flex items-start gap-2">
<Lock className="h-4 w-4 text-emerald-400 mt-0.5 shrink-0" />
<div className="flex-1 space-y-1">
<div className="font-semibold text-emerald-300">PVE-managed keyfile detected for this PBS</div>
<div className="text-muted-foreground">
Proxmox already stores an encryption key for storage <code className="font-mono text-[10.5px]">{pveMatch.name}</code> at{" "}
<code className="font-mono text-[10.5px] break-all">{pveMatch.path}</code>. Import it in one click.
</div>
</div>
</div>
<div className="flex justify-end">
<Button
size="sm"
onClick={() => {
setImportPath(pveMatch.path)
setImportFile(null)
}}
disabled={busy}
className="!bg-emerald-600 hover:!bg-emerald-700 !text-white h-7 text-[11px]"
>
Use this key
</Button>
</div>
</div>
)}
{pveMatch && <div className="text-[10px] text-center text-muted-foreground"> or upload your own </div>}
<div>
<Label htmlFor="pbsKfUploadFile" className="text-xs">Upload from your machine</Label>
<Input
@@ -592,7 +636,7 @@ function PbsKeyfileActions() {
value={importPath}
onChange={(e) => setImportPath(e.target.value)}
disabled={busy || !!importFile}
placeholder="/usr/local/share/proxmenux/pbs-key.conf"
placeholder="e.g. /etc/pve/priv/storage/<NAME>.enc or /root/my-pbs-key"
className="h-9 mt-1 font-mono text-xs"
/>
</div>
@@ -1578,6 +1622,21 @@ function InspectModal({
fetcher,
)
const needsKeyfile = !!(remoteArc?.encrypted && keyfileInfo && !keyfileInfo.installed)
// Same PVE-managed keyfile auto-discovery the setup wizards use: when
// the encrypted snapshot lives on a PBS whose PVE storage.cfg entry
// has an `encryption-key` file at /etc/pve/priv/storage/<NAME>.enc,
// surface a one-click "Use this key" shortcut in the amber panel so
// the operator doesn't have to type the full path. Only fetched when
// the amber gate is actually rendered (encrypted + no keyfile).
const { data: pveDiscoverInspect } = useSWR<{
entries: Array<{ name: string; server: string; datastore: string; path: string; matches_repository: boolean }>
}>(
needsKeyfile && remoteArc?.repo_repository
? `/api/host-backups/pbs-encryption/discover-pve-keyfiles?repository=${encodeURIComponent(remoteArc.repo_repository)}`
: null,
fetcher,
)
const pveMatchInspect = pveDiscoverInspect?.entries?.find((e) => e.matches_repository) || null
const [importFile, setImportFile] = useState<File | null>(null)
const [importPath, setImportPath] = useState<string>("")
const [importing, setImporting] = useState(false)
@@ -2041,8 +2100,37 @@ function InspectModal({
</div>
</div>
</div>
{pveMatchInspect && (
<div className="rounded-md border border-emerald-500/40 bg-emerald-500/10 p-2.5 space-y-1.5 text-[11px]">
<div className="flex items-start gap-2">
<Lock className="h-3.5 w-3.5 text-emerald-400 mt-0.5 shrink-0" />
<div className="flex-1 space-y-1">
<div className="font-semibold text-emerald-300">PVE-managed keyfile detected for this PBS</div>
<div className="text-muted-foreground">
Proxmox stores an encryption key for storage <code className="font-mono text-[10.5px]">{pveMatchInspect.name}</code> at{" "}
<code className="font-mono text-[10.5px] break-all">{pveMatchInspect.path}</code>. Import it in one click.
</div>
</div>
</div>
<div className="flex justify-end">
<Button
size="sm"
onClick={() => {
setImportPath(pveMatchInspect.path)
setImportFile(null)
}}
disabled={importing}
className="!bg-emerald-600 hover:!bg-emerald-700 !text-white h-6 text-[10.5px] px-2"
>
Use this key
</Button>
</div>
</div>
)}
<div className="space-y-1.5 pt-1 border-t border-amber-500/30">
<Label htmlFor="keyfileImport" className="text-[11px] font-medium">Upload from your machine</Label>
<Label htmlFor="keyfileImport" className="text-[11px] font-medium">
{pveMatchInspect ? "Or upload from your machine" : "Upload from your machine"}
</Label>
<Input
id="keyfileImport"
type="file"
@@ -2061,7 +2149,7 @@ function InspectModal({
value={importPath}
onChange={(e) => setImportPath(e.target.value)}
disabled={importing || !!importFile}
placeholder="/usr/local/share/proxmenux/pbs-key.conf"
placeholder="e.g. /etc/pve/priv/storage/<NAME>.enc or /root/my-pbs-key"
className="h-8 text-[11px] font-mono"
/>
</div>
@@ -3834,7 +3922,7 @@ function CreateJobDialog({
value={pbsImportPath}
onChange={(e) => setPbsImportPath(e.target.value)}
disabled={pbsImportBusy || !!pbsImportFile}
placeholder="/usr/local/share/proxmenux/pbs-key.conf"
placeholder="e.g. /etc/pve/priv/storage/<NAME>.enc or /root/my-pbs-key"
className="h-8 text-[11px] font-mono"
/>
<p className="text-[10px] text-muted-foreground">
@@ -4808,7 +4896,7 @@ function ManualBackupDialog({
value={pbsImportPath}
onChange={(e) => setPbsImportPath(e.target.value)}
disabled={pbsImportBusy || !!pbsImportFile}
placeholder="/usr/local/share/proxmenux/pbs-key.conf"
placeholder="e.g. /etc/pve/priv/storage/<NAME>.enc or /root/my-pbs-key"
className="h-8 text-[11px] font-mono"
/>
<p className="text-[10px] text-muted-foreground">
@@ -5843,7 +5931,7 @@ function DestinationRow({
is host-wide but conceptually belongs to PBS usage, so the
Download / Upload / Delete controls sit next to the
destination(s) they support. */}
{item.kind === "pbs" && <PbsKeyfileActions />}
{item.kind === "pbs" && <PbsKeyfileActions pbsRepository={item.repository} />}
</div>
)
}

View File

@@ -1,17 +1,18 @@
{
"_description": "Verified AI models for ProxMenux notifications. Only models listed here will be shown to users. Models are tested to work with the chat/completions API format.",
"_updated": "2026-07-13",
"_updated": "2026-07-14",
"_verifier": "Refreshed with tools/ai-models-verifier (private). Re-run before each ProxMenux release to keep the list current. The verifier and ProxMenux share the same reasoning/thinking-model handlers so their verdicts stay aligned with runtime behaviour.",
"groq": {
"models": [
"llama-3.3-70b-versatile",
"llama-3.1-8b-instant",
"meta-llama/llama-4-scout-17b-16e-instruct",
"openai/gpt-oss-120b",
"openai/gpt-oss-20b"
],
"recommended": "llama-3.3-70b-versatile",
"_note": "Verified 2026-07-13 against Groq's public production catalog. Legacy llama-3.1-70b-versatile / llama3-70b-8192 / llama3-8b-8192 / mixtral-8x7b-32768 / gemma2-9b-it removed (retired upstream). openai/gpt-oss-120b (500 T/s) and openai/gpt-oss-20b (1000 T/s) added — both listed as current production."
"_note": "Verified functionally 2026-07-14 with the Groq API (15 models discovered, 9 passed). Legacy llama-3.1-70b-versatile / llama3-70b-8192 / llama3-8b-8192 / mixtral-8x7b-32768 / gemma2-9b-it removed (retired upstream). llama-4-scout added (current-gen Llama 4, 0.47s). openai/gpt-oss-120b / gpt-oss-20b confirmed. Passing but excluded: allam-2-7b (Arabic-focused), qwen/qwen3-32b (Chinese-first, unreliable Spanish output), openai/gpt-oss-safeguard-20b (safety-classifier variant), groq/compound-mini (agentic system, wrong fit for notification translation)."
},
"gemini": {
@@ -69,7 +70,7 @@
"mistralai/mistral-small-3.2-24b-instruct"
],
"recommended": "meta-llama/llama-3.3-70b-instruct",
"_note": "Verified 2026-07-13 against OpenRouter's public /api/v1/models catalog (343 models advertised). anthropic/claude-3.5-haiku / anthropic/claude-3.5-sonnet / google/gemini-flash-1.5 / mistralai/mistral-7b-instruct / mistralai/mixtral-8x7b-instruct removed (GONE from catalog). Modern replacements added: llama-4-scout (Meta's current gen), claude-haiku-4.5 / claude-sonnet-4.6 (Anthropic current gen via OpenRouter proxy), gemini-2.5-flash / flash-lite (Google current gen), mistral-small-3.2-24b (Mistral current small)."
"_note": "Verified functionally 2026-07-14 with the OpenRouter API — all 10 curated candidates pass the Spanish-translation notification test. Fastest: llama-4-scout (0.51s), gemini-2.5-flash-lite (1.14s), gemini-2.5-flash (1.94s), llama-3.3-70b-instruct (2.29s), claude-haiku-4.5 (2.71s). Legacy anthropic/claude-3.5-* / google/gemini-flash-1.5 / mistralai/mistral-7b-instruct / mixtral-8x7b-instruct removed (GONE from catalog). Modern replacements added: llama-4-scout (Meta's current gen — dramatically fastest), claude-haiku-4.5 / claude-sonnet-4.6, gemini-2.5-flash / flash-lite, mistral-small-3.2-24b. recommended kept as llama-3.3-70b for capability/latency balance; llama-4-scout is a faster alternative worth considering as recommended after a broader release."
},
"ollama": {