$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
// add translations
if (substr($_SERVER['REQUEST_URI'],0,4) != '/VMs') {
$_SERVER['REQUEST_URI'] = 'vms';
require_once "$docroot/webGui/include/Translations.php";
}
require_once "$docroot/webGui/include/Helpers.php";
require_once "$docroot/webGui/include/Custom.php";
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
$arrValidMachineTypes = getValidMachineTypes();
$arrValidGPUDevices = getValidGPUDevices();
$arrValidAudioDevices = getValidAudioDevices();
$arrValidOtherDevices = getValidOtherDevices();
$arrValidUSBDevices = getValidUSBDevices();
$arrValidDiskDrivers = getValidDiskDrivers();
$arrValidDiskBuses = getValidDiskBuses();
$arrValidCdromBuses = getValidCdromBuses();
$arrValidVNCModels = getValidVNCModels();
$arrValidKeyMaps = getValidKeyMaps();
$arrValidBridges = getNetworkBridges();
$strCPUModel = getHostCPUModel();
$arrConfigDefaults = [
'template' => [
'name' => $strSelectedTemplate,
'icon' => $arrAllTemplates[$strSelectedTemplate]['icon'],
'os' => $arrAllTemplates[$strSelectedTemplate]['os']
],
'domain' => [
'name' => $strSelectedTemplate,
'persistent' => 1,
'uuid' => $lv->domain_generate_uuid(),
'clock' => 'localtime',
'arch' => 'x86_64',
'machine' => 'pc',
'mem' => 1024 * 1024,
'maxmem' => 1024 * 1024,
'password' => '',
'cpumode' => 'host-passthrough',
'vcpus' => 1,
'vcpu' => [0],
'hyperv' => 1,
'ovmf' => 1,
'usbmode' => 'usb2'
],
'media' => [
'cdrom' => '',
'cdrombus' => 'ide',
'drivers' => is_file($domain_cfg['VIRTIOISO']) ? $domain_cfg['VIRTIOISO'] : '',
'driversbus' => 'ide'
],
'disk' => [
[
'new' => '',
'size' => '',
'driver' => 'raw',
'dev' => 'hda',
'select' => $domain_cfg['VMSTORAGEMODE'],
'bus' => 'virtio'
]
],
'gpu' => [
[
'id' => 'vnc',
'model' => 'qxl',
'keymap' => 'en-us'
]
],
'audio' => [
[
'id' => ''
]
],
'pci' => [],
'nic' => [
[
'network' => $domain_bridge,
'mac' => $lv->generate_random_mac_addr()
]
],
'usb' => [],
'shares' => [
[
'source' => '',
'target' => ''
]
]
];
$hdrXML = "\n"; // XML encoding declaration
// Merge in any default values from the VM template
if ($arrAllTemplates[$strSelectedTemplate] && $arrAllTemplates[$strSelectedTemplate]['overrides']) {
$arrConfigDefaults = array_replace_recursive($arrConfigDefaults, $arrAllTemplates[$strSelectedTemplate]['overrides']);
}
// create new VM
if ($_POST['createvm']) {
if ($_POST['xmldesc']) {
// XML view
$new = $lv->domain_define($_POST['xmldesc'], $_POST['domain']['xmlstartnow']==1);
if ($new){
$lv->domain_set_autostart($new, $_POST['domain']['autostart']==1);
$reply = ['success' => true];
} else {
$reply = ['error' => $lv->get_last_error()];
}
} else {
// form view
if ($lv->domain_new($_POST)){
// Fire off the vnc popup if available
$dom = $lv->get_domain_by_name($_POST['domain']['name']);
$vncport = $lv->domain_get_vnc_port($dom);
$wsport = $lv->domain_get_ws_port($dom);
if ($vncport > 0) {
$vnc = '/plugins/dynamix.vm.manager/vnc.html?autoconnect=true&host='.$_SERVER['HTTP_HOST'].'&port='.$wsport.'&path=';
$reply['vncurl'] = $vnc;
}
$reply = ['success' => true];
} else {
$reply = ['error' => $lv->get_last_error()];
}
}
echo json_encode($reply);
exit;
}
// update existing VM
if ($_POST['updatevm']) {
$uuid = $_POST['domain']['uuid'];
$dom = $lv->domain_get_domain_by_uuid($uuid);
$oldAutoStart = $lv->domain_get_autostart($dom)==1;
$newAutoStart = $_POST['domain']['autostart']==1;
$strXML = $lv->domain_get_xml($dom);
if ($lv->domain_get_state($dom)=='running') {
$arrErrors = [];
$arrExistingConfig = domain_to_config($uuid);
$arrNewUSBIDs = $_POST['usb'];
// hot-attach any new usb devices
foreach ($arrNewUSBIDs as $strNewUSBID) {
foreach ($arrExistingConfig['usb'] as $arrExistingUSB) {
if ($strNewUSBID == $arrExistingUSB['id']) continue 2;
}
list($strVendor,$strProduct) = explode(':', $strNewUSBID);
// hot-attach usb
file_put_contents('/tmp/hotattach.tmp', "
| _(Name)_: |
Give the VM a name (e.g. Work, Gaming, Media Player, Firewall, Bitcoin Miner)
| _(Description)_: |
Give the VM a brief description (optional field).
| _(CPU Mode)_: |
There are two CPU modes available to choose:
Host Passthrough
With this mode, the CPU visible to the guest should be exactly the same as the host CPU even in the aspects that libvirt does not understand. For the best possible performance, use this setting.Emulated
If you are having difficulties with Host Passthrough mode, you can try the emulated mode which doesn't expose the guest to host-based CPU features. This may impact the performance of your VM.
| _(Logical CPUs)_: |
$cpus = cpu_list();
foreach ($cpus as $pair) {
unset($cpu1,$cpu2);
list($cpu1, $cpu2) = preg_split('/[,-]/',$pair);
$extra = in_array($cpu1, $arrConfig['domain']['vcpu']) ? ($arrConfig['domain']['vcpus'] > 1 ? 'checked' : 'checked disabled') : '';
if (!$cpu2) {
echo "";
} else {
echo "";
$extra = in_array($cpu2, $arrConfig['domain']['vcpu']) ? ($arrConfig['domain']['vcpus'] > 1 ? 'checked' : 'checked disabled') : '';
echo "";
}
}
?>
|
The number of logical CPUs in your system is determined by multiplying the number of CPU cores on your processor(s) by the number of threads.
Select which logical CPUs you wish to allow your VM to use. (minimum 1).
| _(Initial)_ _(Memory)_: | _(Max)_ _(Memory)_: |
Select how much memory to allocate to the VM at boot.
For VMs where no PCI devices are being passed through (GPUs, sound, etc.), you can set different values to initial and max memory to allow for memory ballooning. If you are passing through a PCI device, only the initial memory value is used and the max memory value is ignored. For more information on KVM memory ballooning, see here.
| _(Machine)_: |
The machine type option primarily affects the success some users may have with various hardware and GPU pass through. For more information on the various QEMU machine types, see these links:
http://wiki.qemu.org/Documentation/Platforms/PC
http://wiki.qemu.org/Features/Q35
As a rule of thumb, try to get your configuration working with i440fx first and if that fails, try adjusting to Q35 to see if that changes anything.
| _(BIOS)_: |
SeaBIOS
is the default virtual BIOS used to create virtual machines and is compatible with all guest operating systems (Windows, Linux, etc.).OVMF
(Open Virtual Machine Firmware) adds support for booting VMs using UEFI, but virtual machine guests must also support UEFI. Assigning graphics devices to a OVMF-based virtual machine requires that the graphics device also support UEFI.Once a VM is created this setting cannot be adjusted.
| _(Hyper-V)_: |
Exposes the guest to hyper-v extensions for Microsoft operating systems.
| _(USB Controller)_: |
USB Controller
Select the USB Controller to emulate. Some OSes won't support USB3 (e.g. Windows 7). Qemu XHCI is the same code base as Nec XHCI but without several hacks applied over the years. Recommended to try qemu XHCI before resorting to nec XHCI.
| _(OS Install ISO)_: | |
| _(OS Install CDRom Bus)_: |
Select the virtual CD-ROM (ISO) that contains the installation media for your operating system. Clicking this field displays a list of ISOs found in the directory specified on the Settings page.
CDRom Bus
Specify what interface this virtual cdrom uses to connect inside the VM.
| _(VirtIO Drivers ISO)_: | |
| _(VirtIO Drivers CDRom Bus)_: |
Specify the virtual CD-ROM (ISO) that contains the VirtIO Windows drivers as provided by the Fedora Project. Download the latest ISO from here: https://docs.fedoraproject.org/en-US/quick-docs/creating-windows-virtual-machines-using-virtio-drivers/index.html#virtio-win-direct-downloads
When installing Windows, you will reach a step where no disk devices will be found. There is an option to browse for drivers on that screen. Click browse and locate the additional CD-ROM in the menu. Inside there will be various folders for the different versions of Windows. Open the folder for the version of Windows you are installing and then select the AMD64 subfolder inside (even if you are on an Intel system, select AMD64). Three drivers will be found. Select them all, click next, and the vDisks you have assigned will appear.
CDRom Bus
Specify what interface this virtual cdrom uses to connect inside the VM.
| _(vDisk Location)_: | |
| _(vDisk Size)_: | |
| _(vDisk Type)_: | |
| _(vDisk Bus)_: |
} ?> } ?> foreach ($arrConfig['shares'] as $i => $arrShare) { $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : ''; ?>vDisk Location
Specify a path to a user share in which you wish to store the VM or specify an existing vDisk. The primary vDisk will store the operating system for your VM.NOTE: Unraid will automatically "dereference" vdisk paths when starting a VM. That is, if a vdisk path is specified as being on a user share, we use the SYSTEM.LOCATION extended attribute to find out what physical disk the image exists on. We then pass this path when starting a VM via qemu. This ensures that VM I/O bypasses shfs (FUSE user share file system) for better performance. It also means that a vdisk image file can be moved from one physical device to another without changing the VM XML file.
Example: /mnt/user/domains/Windows/vdisk1.img will be dereferenced to /mnt/cache/domains/Windows/vdisk1.img (for vdisk1.img physically located in the "cache" volume).
vDisk Size
Specify a number followed by a letter. M for megabytes, G for gigabytes.vDisk Type
Select RAW for best performance. QCOW2 implementation is still in development.vDisk Bus
Select virtio for best performance.Additional devices can be added/removed by clicking the symbols to the left.
| _(Unraid Share)_: | |
| _(Unraid Mount tag)_: |
Unraid Share
Used to create a VirtFS mapping to a Linux-based guest. Specify the path on the host here.Unraid Mount tag
Specify the mount tag that you will use for mounting the VirtFS share inside the VM. See this page for how to do this on a Linux-based guest: http://wiki.qemu.org/Documentation/9psetupAdditional devices can be added/removed by clicking the symbols to the left.
| _(Graphics Card)_: | |
| _(VNC Video Driver)_: | |
| _(VNC Password)_: | |
| _(VNC Keyboard)_: | |
| _(Graphics ROM BIOS)_: |
} ?> } ?> foreach ($arrConfig['audio'] as $i => $arrAudio) { $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : ''; ?>Graphics Card
If you wish to assign a graphics card to the VM, select it from this list, otherwise leave it set to VNC.VNC Video Driver
If you wish to assign a different video driver to use for a VNC connection, specify one here.VNC Password
If you wish to require a password to connect to the VM over a VNC connection, specify one here.VNC Keyboard
If you wish to assign a different keyboard layout to use for a VNC connection, specify one here.Graphics ROM BIOS
If you wish to use a custom ROM BIOS for a Graphics card, specify one here.Additional devices can be added/removed by clicking the symbols to the left.
| _(Sound Card)_: |
} ?> } ?> foreach ($arrConfig['nic'] as $i => $arrNic) { $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : ''; ?>Select a sound device to assign to your VM. Most modern GPUs have a built-in audio device, but you can also select the on-board audio device(s) if present.
Additional devices can be added/removed by clicking the symbols to the left.
| _(Network MAC)_: | |
| _(Network Bridge)_: |
Network MAC
By default, a random MAC address will be assigned here that conforms to the standards for virtual network interface controllers. You can manually adjust this if desired.Network Bridge
The default libvirt managed network bridge (virbr0) will be used, otherwise you may specify an alternative name for a private network bridge to the host.Additional devices can be added/removed by clicking the symbols to the left.
| _(USB Devices)_: |
$arrDev) {
?>
"._('None available').""; } ?> |
If you wish to assign any USB devices to your guest, you can select them from this list.
| _(Other PCI Devices)_: |
$intAvailableOtherPCIDevices = 0;
if (!empty($arrValidOtherDevices)) {
foreach($arrValidOtherDevices as $i => $arrDev) {
$extra = '';
if (count(array_filter($arrConfig['pci'], function($arr) use ($arrDev) { return ($arr['id'] == $arrDev['id']); }))) {
$extra .= ' checked="checked"';
} elseif (!in_array($arrDev['driver'], ['pci-stub', 'vfio-pci'])) {
//$extra .= ' disabled="disabled"';
continue;
}
$intAvailableOtherPCIDevices++;
?>
} } if (empty($intAvailableOtherPCIDevices)) { echo ""._('None available').""; } ?> |
If you wish to assign any other PCI devices to your guest, you can select them from this list.
|
if (!$boolNew) { ?>
} else { ?>
} ?> |
} ?>Click Create to generate the vDisks and return to the Virtual Machines page where your new VM will be created.
|
if (!$boolRunning) { ?>
if ($strXML) { ?>
} else { ?>
} ?> } else { ?> } ?> |