366 lines
7.3 KiB
TypeScript
366 lines
7.3 KiB
TypeScript
/**
|
|
* Virtual Machines API
|
|
*
|
|
* @author Pierre HUBERT
|
|
*/
|
|
|
|
import { APIClient } from "./ApiClient";
|
|
|
|
export type VMState =
|
|
| "NoState"
|
|
| "Running"
|
|
| "Blocked"
|
|
| "Paused"
|
|
| "Shutdown"
|
|
| "Shutoff"
|
|
| "Crashed"
|
|
| "PowerManagementSuspended"
|
|
| "Other";
|
|
|
|
export type DiskAllocType = "Sparse" | "Fixed";
|
|
|
|
export interface VMDisk {
|
|
size: number;
|
|
name: string;
|
|
alloc_type: DiskAllocType;
|
|
delete: boolean;
|
|
|
|
// application attribute
|
|
new?: boolean;
|
|
deleteType?: "keepfile" | "deletefile";
|
|
}
|
|
|
|
export interface VMNetInterfaceFilterParams {
|
|
name: string;
|
|
value: string;
|
|
}
|
|
|
|
export interface VMNetInterfaceFilter {
|
|
name: string;
|
|
parameters: VMNetInterfaceFilterParams[];
|
|
}
|
|
|
|
export type VMNetInterface = (VMNetUserspaceSLIRPStack | VMNetDefinedNetwork) &
|
|
VMNetInterfaceBase;
|
|
|
|
export interface VMNetInterfaceBase {
|
|
mac: string;
|
|
nwfilterref?: VMNetInterfaceFilter;
|
|
}
|
|
|
|
export interface VMNetUserspaceSLIRPStack {
|
|
type: "UserspaceSLIRPStack";
|
|
}
|
|
|
|
export interface VMNetDefinedNetwork {
|
|
type: "DefinedNetwork";
|
|
network: string;
|
|
}
|
|
|
|
interface VMInfoInterface {
|
|
name: string;
|
|
uuid?: string;
|
|
genid?: string;
|
|
title?: string;
|
|
description?: string;
|
|
boot_type: "UEFI" | "UEFISecureBoot";
|
|
architecture: "i686" | "x86_64";
|
|
memory: number;
|
|
number_vcpu: number;
|
|
vnc_access: boolean;
|
|
iso_files: string[];
|
|
disks: VMDisk[];
|
|
networks: VMNetInterface[];
|
|
tpm_module: boolean;
|
|
}
|
|
|
|
export class VMInfo implements VMInfoInterface {
|
|
name: string;
|
|
uuid?: string;
|
|
genid?: string;
|
|
title?: string;
|
|
description?: string;
|
|
boot_type: "UEFI" | "UEFISecureBoot";
|
|
architecture: "i686" | "x86_64";
|
|
number_vcpu: number;
|
|
memory: number;
|
|
vnc_access: boolean;
|
|
iso_files: string[];
|
|
disks: VMDisk[];
|
|
networks: VMNetInterface[];
|
|
tpm_module: boolean;
|
|
|
|
constructor(int: VMInfoInterface) {
|
|
this.name = int.name;
|
|
this.uuid = int.uuid;
|
|
this.genid = int.genid;
|
|
this.title = int.title;
|
|
this.description = int.description;
|
|
this.boot_type = int.boot_type;
|
|
this.architecture = int.architecture;
|
|
this.number_vcpu = int.number_vcpu;
|
|
this.memory = int.memory;
|
|
this.vnc_access = int.vnc_access;
|
|
this.iso_files = int.iso_files;
|
|
this.disks = int.disks;
|
|
this.networks = int.networks;
|
|
this.tpm_module = int.tpm_module;
|
|
}
|
|
|
|
static NewEmpty(): VMInfo {
|
|
return new VMInfo({
|
|
name: "",
|
|
boot_type: "UEFI",
|
|
architecture: "x86_64",
|
|
memory: 1024,
|
|
number_vcpu: 1,
|
|
vnc_access: true,
|
|
iso_files: [],
|
|
disks: [],
|
|
networks: [],
|
|
tpm_module: true,
|
|
});
|
|
}
|
|
|
|
get ViewURL(): string {
|
|
return `/vm/${this.uuid}`;
|
|
}
|
|
|
|
get EditURL(): string {
|
|
return `/vm/${this.uuid}/edit`;
|
|
}
|
|
|
|
get VNCURL(): string {
|
|
return `/vm/${this.uuid}/vnc`;
|
|
}
|
|
|
|
get XMLURL(): string {
|
|
return `/vm/${this.uuid}/xml`;
|
|
}
|
|
}
|
|
|
|
export class VMApi {
|
|
/**
|
|
* Create a new virtual machine
|
|
*/
|
|
static async Create(v: VMInfo): Promise<{ uuid: string }> {
|
|
return (
|
|
await APIClient.exec({
|
|
uri: `/vm/create`,
|
|
method: "POST",
|
|
jsonData: v,
|
|
})
|
|
).data;
|
|
}
|
|
|
|
/**
|
|
* Get the list of defined virtual machines
|
|
*/
|
|
static async GetList(): Promise<VMInfo[]> {
|
|
return (
|
|
await APIClient.exec({
|
|
uri: "/vm/list",
|
|
method: "GET",
|
|
})
|
|
).data.map((i: VMInfoInterface) => new VMInfo(i));
|
|
}
|
|
|
|
/**
|
|
* Get the information about a single VM
|
|
*/
|
|
static async GetSingle(uuid: string): Promise<VMInfo> {
|
|
const data = (
|
|
await APIClient.exec({
|
|
uri: `/vm/${uuid}`,
|
|
method: "GET",
|
|
})
|
|
).data;
|
|
return new VMInfo(data);
|
|
}
|
|
|
|
/**
|
|
* Get the source XML configuration of a domain for debugging purposes
|
|
*/
|
|
static async GetSingleXML(uuid: string): Promise<string> {
|
|
return (
|
|
await APIClient.exec({
|
|
uri: `/vm/${uuid}/src`,
|
|
method: "GET",
|
|
})
|
|
).data;
|
|
}
|
|
|
|
/**
|
|
* Update the information about a single VM
|
|
*/
|
|
static async UpdateSingle(vm: VMInfo): Promise<VMInfo> {
|
|
// Process disks list, looking for removal
|
|
vm.disks = vm.disks.filter((d) => d.deleteType !== "keepfile");
|
|
vm.disks.forEach((d) => {
|
|
if (d.deleteType === "deletefile") d.delete = true;
|
|
});
|
|
|
|
const data = (
|
|
await APIClient.exec({
|
|
uri: `/vm/${vm.uuid!}`,
|
|
method: "PUT",
|
|
jsonData: vm,
|
|
})
|
|
).data;
|
|
return new VMInfo(data);
|
|
}
|
|
|
|
/**
|
|
* Check if autostart is enabled on a VM
|
|
*/
|
|
static async IsAutostart(vm: VMInfo): Promise<boolean> {
|
|
return (
|
|
await APIClient.exec({
|
|
uri: `/vm/${vm.uuid}/autostart`,
|
|
method: "GET",
|
|
})
|
|
).data.autostart;
|
|
}
|
|
|
|
/**
|
|
* Set autostart status of a VM
|
|
*/
|
|
static async SetAutostart(vm: VMInfo, enabled: boolean): Promise<void> {
|
|
await APIClient.exec({
|
|
uri: `/vm/${vm.uuid}/autostart`,
|
|
method: "PUT",
|
|
jsonData: { autostart: enabled },
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get the state of a VM
|
|
*/
|
|
static async GetState(vm: VMInfo): Promise<VMState> {
|
|
return (
|
|
await APIClient.exec({
|
|
uri: `/vm/${vm.uuid}/state`,
|
|
method: "GET",
|
|
})
|
|
).data.state;
|
|
}
|
|
|
|
/**
|
|
* Get a screenshot of a VM
|
|
*/
|
|
static async Screenshot(vm: VMInfo): Promise<Blob> {
|
|
return (
|
|
await APIClient.exec({
|
|
uri: `/vm/${vm.uuid}/screenshot`,
|
|
method: "GET",
|
|
})
|
|
).data;
|
|
}
|
|
|
|
/**
|
|
* Start the VM
|
|
*/
|
|
static async StartVM(vm: VMInfo): Promise<void> {
|
|
return (
|
|
await APIClient.exec({
|
|
uri: `/vm/${vm.uuid}/start`,
|
|
method: "GET",
|
|
})
|
|
).data.state;
|
|
}
|
|
|
|
/**
|
|
* Shutdown the VM
|
|
*/
|
|
static async ShutdownVM(vm: VMInfo): Promise<void> {
|
|
return (
|
|
await APIClient.exec({
|
|
uri: `/vm/${vm.uuid}/shutdown`,
|
|
method: "GET",
|
|
})
|
|
).data.state;
|
|
}
|
|
|
|
/**
|
|
* Restt the VM
|
|
*/
|
|
static async ResetVM(vm: VMInfo): Promise<void> {
|
|
return (
|
|
await APIClient.exec({
|
|
uri: `/vm/${vm.uuid}/reset`,
|
|
method: "GET",
|
|
})
|
|
).data.state;
|
|
}
|
|
|
|
/**
|
|
* Kill the VM
|
|
*/
|
|
static async KillVM(vm: VMInfo): Promise<void> {
|
|
return (
|
|
await APIClient.exec({
|
|
uri: `/vm/${vm.uuid}/kill`,
|
|
method: "GET",
|
|
})
|
|
).data.state;
|
|
}
|
|
|
|
/**
|
|
* Suspend the VM
|
|
*/
|
|
static async SuspendVM(vm: VMInfo): Promise<void> {
|
|
return (
|
|
await APIClient.exec({
|
|
uri: `/vm/${vm.uuid}/suspend`,
|
|
method: "GET",
|
|
})
|
|
).data.state;
|
|
}
|
|
|
|
/**
|
|
* Resume the VM
|
|
*/
|
|
static async ResumeVM(vm: VMInfo): Promise<void> {
|
|
return (
|
|
await APIClient.exec({
|
|
uri: `/vm/${vm.uuid}/resume`,
|
|
method: "GET",
|
|
})
|
|
).data.state;
|
|
}
|
|
|
|
/**
|
|
* Delete a virtual machine
|
|
*/
|
|
static async Delete(vm: VMInfo, keep_files: boolean): Promise<void> {
|
|
await APIClient.exec({
|
|
uri: `/vm/${vm.uuid}`,
|
|
method: "DELETE",
|
|
jsonData: { keep_files },
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get a oneshot VNC connect URL
|
|
*/
|
|
static async OneShotVNCURL(vm: VMInfo): Promise<string> {
|
|
const token = (
|
|
await APIClient.exec({
|
|
uri: `/vm/${vm.uuid}/vnc_token`,
|
|
method: "GET",
|
|
})
|
|
).data.token;
|
|
|
|
let baseWSURL = APIClient.backendURL();
|
|
if (!baseWSURL.includes("://"))
|
|
baseWSURL =
|
|
window.location.protocol + "//" + window.location.host + baseWSURL;
|
|
|
|
return (
|
|
baseWSURL.replace("http", "ws") +
|
|
"/vnc?token=" +
|
|
encodeURIComponent(token)
|
|
);
|
|
}
|
|
}
|