# -*- coding: utf-8 -*- # # Copyright (C) 2020 GNS3 Technologies Inc. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from pydantic import BaseModel, Field from pathlib import Path from typing import Optional, List from enum import Enum from uuid import UUID from .nodes import CustomAdapter, NodeStatus class QemuPlatform(str, Enum): aarch64 = "aarch64" alpha = "alpha" arm = "arm" cris = "cris" i386 = "i386" lm32 = "lm32" m68k = "m68k" microblaze = "microblaze" microblazeel = "microblazeel" mips = "mips" mips64 = "mips64" mips64el = "mips64el" mipsel = "mipsel" moxie = "moxie" or32 = "or32" ppc = "ppc" ppc64 = "ppc64" ppcemb = "ppcemb" s390x = "s390x" sh4 = "sh4" sh4eb = "sh4eb" sparc = "sparc" sparc64 = "sparc64" tricore = "tricore" unicore32 = "unicore32" x86_64 = "x86_64" xtensa = "xtensa" xtensaeb = "xtensaeb" class QemuConsoleType(str, Enum): """ Supported console types. """ vnc = "vnc" telnet = "telnet" spice = "spice" spice_agent = "spice+agent" none = "none" class QemuBootPriority(str, Enum): """ Supported boot priority types. """ c = "c" d = "d" n = "n" cn = "cn" cd = "cd" dn = "dn" dc = "dc" nc = "nc" nd = "nd" class QemuOnCloseAction(str, Enum): """ Supported actions when closing Qemu VM. """ power_off = "power_off" shutdown_signal = "shutdown_signal" save_vm_state = "save_vm_state" class QemuProcessPriority(str, Enum): realtime = "realtime" very_high = "very high" high = "high" normal = "normal" low = "low" very_low = "very low" class QemuBase(BaseModel): """ Common Qemu node properties. """ name: str node_id: Optional[UUID] usage: Optional[str] = Field(None, description="How to use the node") linked_clone: Optional[bool] = Field(None, description="Whether the VM is a linked clone or not") qemu_path: Optional[Path] = Field(None, description="Qemu executable path") platform: Optional[QemuPlatform] = Field(None, description="Platform to emulate") console: Optional[int] = Field(None, gt=0, le=65535, description="Console TCP port") console_type: Optional[QemuConsoleType] = Field(None, description="Console type") aux: Optional[int] = Field(None, gt=0, le=65535, description="Auxiliary console TCP port") aux_type: Optional[QemuConsoleType] = Field(None, description="Auxiliary console type") hda_disk_image: Optional[Path] = Field(None, description="QEMU hda disk image path") hda_disk_image_md5sum: Optional[str] = Field(None, description="QEMU hda disk image checksum") hda_disk_image_interface: Optional[str] = Field(None, description="QEMU hda interface") hdb_disk_image: Optional[Path] = Field(None, description="QEMU hdb disk image path") hdb_disk_image_md5sum: Optional[str] = Field(None, description="QEMU hdb disk image checksum") hdb_disk_image_interface: Optional[str] = Field(None, description="QEMU hdb interface") hdc_disk_image: Optional[Path] = Field(None, description="QEMU hdc disk image path") hdc_disk_image_md5sum: Optional[str] = Field(None, description="QEMU hdc disk image checksum") hdc_disk_image_interface: Optional[str] = Field(None, description="QEMU hdc interface") hdd_disk_image: Optional[Path] = Field(None, description="QEMU hdd disk image path") hdd_disk_image_md5sum: Optional[str] = Field(None, description="QEMU hdd disk image checksum") hdd_disk_image_interface: Optional[str] = Field(None, description="QEMU hdd interface") cdrom_image: Optional[Path] = Field(None, description="QEMU cdrom image path") cdrom_image_md5sum: Optional[str] = Field(None, description="QEMU cdrom image checksum") bios_image: Optional[Path] = Field(None, description="QEMU bios image path") bios_image_md5sum: Optional[str] = Field(None, description="QEMU bios image checksum") initrd: Optional[Path] = Field(None, description="QEMU initrd path") initrd_md5sum: Optional[str] = Field(None, description="QEMU initrd checksum") kernel_image: Optional[Path] = Field(None, description="QEMU kernel image path") kernel_image_md5sum: Optional[str] = Field(None, description="QEMU kernel image checksum") kernel_command_line: Optional[str] = Field(None, description="QEMU kernel command line") boot_priotiry: Optional[QemuBootPriority] = Field(None, description="QEMU boot priority") ram: Optional[int] = Field(None, description="Amount of RAM in MB") cpus: Optional[int] = Field(None, ge=1, le=255, description="Number of vCPUs") maxcpus: Optional[int] = Field(None, ge=1, le=255, description="Maximum number of hotpluggable vCPUs") adapters: Optional[int] = Field(None, ge=0, le=275, description="Number of adapters") adapter_type: Optional[str] = Field(None, description="QEMU adapter type") mac_address: Optional[str] = Field(None, description="QEMU MAC address", regex="^([0-9a-fA-F]{2}[:]){5}([0-9a-fA-F]{2})$") legacy_networking: Optional[bool] = Field(None, description="Use QEMU legagy networking commands (-net syntax)") replicate_network_connection_state: Optional[bool] = Field(None, description="Replicate the network connection state for links in Qemu") create_config_disk: Optional[bool] = Field(None, description="Automatically create a config disk on HDD disk interface (secondary slave)") on_close: Optional[QemuOnCloseAction] = Field(None, description="Action to execute on the VM is closed") cpu_throttling: Optional[int] = Field(None, ge=0, le=800, description="Percentage of CPU allowed for QEMU") process_priority: Optional[QemuProcessPriority] = Field(None, description="Process priority for QEMU") options: Optional[str] = Field(None, description="Additional QEMU options") custom_adapters: Optional[List[CustomAdapter]] = Field(None, description="Custom adapters") class QemuCreate(QemuBase): """ Properties to create a Qemu node. """ pass class QemuUpdate(QemuBase): """ Properties to update a Qemu node. """ name: Optional[str] class Qemu(QemuBase): project_id: UUID = Field(..., description="Project ID") node_directory: str = Field(..., description="Path to the node working directory (read only)") command_line: str = Field(..., description="Last command line used to start IOU (read only)") status: NodeStatus = Field(..., description="Container status (read only)") class QemuDriveName(str, Enum): """ Supported Qemu drive names. """ hda = "hda" hdb = "hdb" hdc = "hdc" hdd = "hdd" class QemuDiskResize(BaseModel): """ Properties to resize a Qemu disk. """ drive_name: QemuDriveName = Field(..., description="Qemu drive name") extend: int = Field(..., description="Number of Megabytes to extend the image") class QemuBinaryPath(BaseModel): path: Path version: str class QemuImageFormat(str, Enum): """ Supported Qemu image formats. """ qcow2 = "qcow2" qcow = "qcow" vpc = "vpc" vdi = "vdi" vdmk = "vdmk" raw = "raw" class QemuImagePreallocation(str, Enum): """ Supported Qemu image preallocation options. """ off = "off" metadata = "metadata" falloc = "falloc" full = "full" class QemuImageOnOff(str, Enum): """ Supported Qemu image on/off options. """ on = "off" off = "off" class QemuImageSubformat(str, Enum): """ Supported Qemu image preallocation options. """ dynamic = "dynamic" fixed = "fixed" stream_optimized = "streamOptimized" two_gb_max_extent_sparse = "twoGbMaxExtentSparse" two_gb_max_extent_flat = "twoGbMaxExtentFlat" monolithic_sparse = "monolithicSparse" monolithic_flat = "monolithicFlat" class QemuImageAdapterType(str, Enum): """ Supported Qemu image on/off options. """ ide = "ide" lsilogic = "lsilogic" buslogic = "buslogic" legacy_esx = "legacyESX" class QemuImageBase(BaseModel): qemu_img: Path = Field(..., description="Path to the qemu-img binary") path: Path = Field(..., description="Absolute or relative path of the image") format: QemuImageFormat = Field(..., description="Image format type") size: int = Field(..., description="Image size in Megabytes") preallocation: Optional[QemuImagePreallocation] cluster_size: Optional[int] refcount_bits: Optional[int] lazy_refcounts: Optional[QemuImageOnOff] subformat: Optional[QemuImageSubformat] static: Optional[QemuImageOnOff] zeroed_grain: Optional[QemuImageOnOff] adapter_type: Optional[QemuImageAdapterType] class QemuImageCreate(QemuImageBase): pass class QemuImageUpdate(QemuImageBase): format: Optional[QemuImageFormat] = Field(None, description="Image format type") size: Optional[int] = Field(None, description="Image size in Megabytes") extend: Optional[int] = Field(None, description="Number of Megabytes to extend the image")