362 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			362 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`;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
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)
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 |