feat: LXC container creation from CT templates

- Add LXC deploy API endpoints: GET /proxmox/api/lxc-templates/{id},
  GET /proxmox/api/lxc-storages/{id}, POST /proxmox/api/lxc/deploy
- Add ProxmoxClient.get_lxc_storage_templates() and get_node_storages()
- Fix duplicate create_lxc_container() — removed dead copy, updated
  canonical with nameserver/searchdomain params
- Fix wait_for_task(): accept WARNINGS:N exitstatus as success
- Add IPAM IP release on deploy failure
- Add frontend hooks: useLXCTemplates, useLXCStorages, useDeployLXC
  with 5-min staleTime caching
- Add LXC wizard steps to CreateInstanceWizard (type, template, config)
- Add LXC i18n keys to en.json and ru.json
- Add LXCTemplate and LXCDeployRequest TypeScript interfaces
This commit is contained in:
markmorado
2026-05-06 19:17:04 +02:00
parent adcc86f30a
commit 1cf099ba1d
8 changed files with 1000 additions and 39 deletions

View File

@@ -0,0 +1,44 @@
import { useQuery, useMutation } from '@tanstack/react-query';
import { apiClient } from '@/lib/api-client';
import type { LXCTemplate, LXCDeployRequest } from '@/types';
export const lxcKeys = {
templates: (serverId: number) => ['lxc-templates', serverId] as const,
storages: (serverId: number, node?: string) => ['lxc-storages', serverId, node] as const,
};
// CT templates change rarely — cache for 5 minutes
export function useLXCTemplates(serverId?: number) {
return useQuery({
queryKey: lxcKeys.templates(serverId!),
queryFn: () =>
apiClient
.get<{ server_id: number; templates: LXCTemplate[] }>(`/proxmox/api/lxc-templates/${serverId}`)
.then((r) => r.templates),
enabled: !!serverId,
staleTime: 5 * 60 * 1000,
});
}
// Storage list changes rarely — cache for 5 minutes
export function useLXCStorages(serverId?: number, node?: string) {
const params = node ? `?node=${encodeURIComponent(node)}` : '';
return useQuery({
queryKey: lxcKeys.storages(serverId!, node),
queryFn: () =>
apiClient
.get<{ storages: { storage: string; type: string; avail: number; total: number }[] }>(
`/proxmox/api/lxc-storages/${serverId}${params}`,
)
.then((r) => r.storages),
enabled: !!serverId,
staleTime: 5 * 60 * 1000,
});
}
export function useDeployLXC() {
return useMutation({
mutationFn: (data: LXCDeployRequest) =>
apiClient.post<{ task_id: number; status: string; name: string }>('/proxmox/api/lxc/deploy', data),
});
}