177 lines
4.8 KiB
TypeScript
177 lines
4.8 KiB
TypeScript
import apiClient from './client'
|
|
|
|
export interface PhysicalDisk {
|
|
id: string
|
|
device_path: string
|
|
vendor?: string
|
|
model?: string
|
|
serial_number?: string
|
|
size_bytes: number
|
|
sector_size?: number
|
|
is_ssd: boolean
|
|
health_status: string
|
|
is_used: boolean
|
|
attached_to_pool?: string // Pool name if disk is used in a ZFS pool
|
|
created_at: string
|
|
updated_at: string
|
|
}
|
|
|
|
export interface VolumeGroup {
|
|
id: string
|
|
name: string
|
|
size_bytes: number
|
|
free_bytes: number
|
|
physical_volumes: string[]
|
|
created_at: string
|
|
updated_at: string
|
|
}
|
|
|
|
export interface Repository {
|
|
id: string
|
|
name: string
|
|
description?: string
|
|
volume_group: string
|
|
logical_volume: string
|
|
size_bytes: number
|
|
used_bytes: number
|
|
filesystem_type?: string
|
|
mount_point?: string
|
|
is_active: boolean
|
|
warning_threshold_percent: number
|
|
critical_threshold_percent: number
|
|
created_at: string
|
|
updated_at: string
|
|
}
|
|
|
|
export const storageApi = {
|
|
listDisks: async (): Promise<PhysicalDisk[]> => {
|
|
const response = await apiClient.get<{ disks: PhysicalDisk[] | null }>('/storage/disks')
|
|
return response.data.disks || []
|
|
},
|
|
|
|
syncDisks: async (): Promise<{ task_id: string }> => {
|
|
const response = await apiClient.post<{ task_id: string }>('/storage/disks/sync')
|
|
return response.data
|
|
},
|
|
|
|
listVolumeGroups: async (): Promise<VolumeGroup[]> => {
|
|
const response = await apiClient.get<{ volume_groups: VolumeGroup[] | null }>('/storage/volume-groups')
|
|
return response.data.volume_groups || []
|
|
},
|
|
|
|
listRepositories: async (): Promise<Repository[]> => {
|
|
const response = await apiClient.get<{ repositories: Repository[] | null }>('/storage/repositories')
|
|
return response.data.repositories || []
|
|
},
|
|
|
|
getRepository: async (id: string): Promise<Repository> => {
|
|
const response = await apiClient.get<Repository>(`/storage/repositories/${id}`)
|
|
return response.data
|
|
},
|
|
|
|
createRepository: async (data: {
|
|
name: string
|
|
description?: string
|
|
volume_group: string
|
|
size_gb: number
|
|
filesystem_type?: string
|
|
}): Promise<{ task_id: string }> => {
|
|
const response = await apiClient.post<{ task_id: string }>('/storage/repositories', data)
|
|
return response.data
|
|
},
|
|
|
|
deleteRepository: async (id: string): Promise<void> => {
|
|
await apiClient.delete(`/storage/repositories/${id}`)
|
|
},
|
|
}
|
|
|
|
export interface ZFSPool {
|
|
id: string
|
|
name: string
|
|
description?: string
|
|
raid_level: string // stripe, mirror, raidz, raidz2, raidz3
|
|
disks: string[] // device paths
|
|
spare_disks?: string[] // spare disk paths
|
|
size_bytes: number
|
|
used_bytes: number
|
|
compression: string // off, lz4, zstd, gzip
|
|
deduplication: boolean
|
|
auto_expand: boolean
|
|
scrub_interval: number // days
|
|
is_active: boolean
|
|
health_status: string // online, degraded, faulted, offline
|
|
created_at: string
|
|
updated_at: string
|
|
created_by: string
|
|
}
|
|
|
|
export const zfsApi = {
|
|
listPools: async (): Promise<ZFSPool[]> => {
|
|
const response = await apiClient.get<{ pools: ZFSPool[] | null }>('/storage/zfs/pools')
|
|
return response.data.pools || []
|
|
},
|
|
|
|
getPool: async (id: string): Promise<ZFSPool> => {
|
|
const response = await apiClient.get<ZFSPool>(`/storage/zfs/pools/${id}`)
|
|
return response.data
|
|
},
|
|
|
|
createPool: async (data: {
|
|
name: string
|
|
description?: string
|
|
raid_level: string
|
|
disks: string[]
|
|
compression?: string
|
|
deduplication?: boolean
|
|
auto_expand?: boolean
|
|
}): Promise<ZFSPool> => {
|
|
const response = await apiClient.post<ZFSPool>('/storage/zfs/pools', data)
|
|
return response.data
|
|
},
|
|
|
|
deletePool: async (id: string): Promise<void> => {
|
|
await apiClient.delete(`/storage/zfs/pools/${id}`)
|
|
},
|
|
|
|
addSpareDisk: async (id: string, disks: string[]): Promise<void> => {
|
|
await apiClient.post(`/storage/zfs/pools/${id}/spare`, { disks })
|
|
},
|
|
|
|
listDatasets: async (poolId: string): Promise<ZFSDataset[]> => {
|
|
const response = await apiClient.get<{ datasets: ZFSDataset[] | null }>(`/storage/zfs/pools/${poolId}/datasets`)
|
|
return response.data.datasets || []
|
|
},
|
|
|
|
createDataset: async (poolId: string, data: {
|
|
name: string
|
|
type: 'filesystem' | 'volume'
|
|
compression?: string
|
|
quota?: number
|
|
reservation?: number
|
|
mount_point?: string
|
|
}): Promise<ZFSDataset> => {
|
|
const response = await apiClient.post<ZFSDataset>(`/storage/zfs/pools/${poolId}/datasets`, data)
|
|
return response.data
|
|
},
|
|
|
|
deleteDataset: async (poolId: string, datasetName: string): Promise<void> => {
|
|
await apiClient.delete(`/storage/zfs/pools/${poolId}/datasets/${datasetName}`)
|
|
},
|
|
}
|
|
|
|
export interface ZFSDataset {
|
|
name: string
|
|
pool: string
|
|
type: string // filesystem, volume, snapshot
|
|
mount_point: string
|
|
used_bytes: number
|
|
available_bytes: number
|
|
referenced_bytes: number
|
|
compression: string
|
|
deduplication: string
|
|
quota: number // -1 for unlimited
|
|
reservation: number
|
|
created_at: string
|
|
}
|
|
|