mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-07-26 18:38:30 +00:00
Update version 1.2.3
This commit is contained in:
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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": {
|
||||
|
||||
Reference in New Issue
Block a user