From c3fbd382aaffefeb2b46f8117acf56c590d062d0 Mon Sep 17 00:00:00 2001 From: SimonFair <39065407+SimonFair@users.noreply.github.com> Date: Thu, 3 Jul 2025 18:25:18 +0100 Subject: [PATCH] Remove OpenElec and LibreElec --- .../dynamix.vm.manager/include/VMedit.php | 6 +- .../include/libvirt_helpers.php | 56 - .../javascript/vmmanager.js | 30 +- .../templates/Custom.formold.php | 2556 ----------------- .../templates/LibreELEC.form.php | 1578 ---------- .../templates/OpenELEC.form.php | 1568 ---------- 6 files changed, 15 insertions(+), 5779 deletions(-) delete mode 100644 emhttp/plugins/dynamix.vm.manager/templates/Custom.formold.php delete mode 100644 emhttp/plugins/dynamix.vm.manager/templates/LibreELEC.form.php delete mode 100644 emhttp/plugins/dynamix.vm.manager/templates/OpenELEC.form.php diff --git a/emhttp/plugins/dynamix.vm.manager/include/VMedit.php b/emhttp/plugins/dynamix.vm.manager/include/VMedit.php index 813f881b8..822c9afa1 100644 --- a/emhttp/plugins/dynamix.vm.manager/include/VMedit.php +++ b/emhttp/plugins/dynamix.vm.manager/include/VMedit.php @@ -72,11 +72,7 @@ if (isset($_GET['uuid'])) { if (empty($_GET['template'])) { // read vm-template attribute $strTemplateOS = $lv->_get_single_xpath_result($res, '//domain/metadata/*[local-name()=\'vmtemplate\']/@os'); - $strLibreELEC = $lv->_get_single_xpath_result($res, '//domain/metadata/*[local-name()=\'vmtemplate\']/@libreelec'); - $strOpenELEC = $lv->_get_single_xpath_result($res, '//domain/metadata/*[local-name()=\'vmtemplate\']/@openelec'); - if ($strLibreELEC) $strSelectedTemplate = 'LibreELEC'; - elseif ($strOpenELEC) $strSelectedTemplate = 'OpenELEC'; - elseif ($strTemplateOS) { + if ($strTemplateOS) { $strSelectedTemplate = $lv->_get_single_xpath_result($res, '//domain/metadata/*[local-name()=\'vmtemplate\']/@name'); } else { // legacy VM support for <6.2 but need it going forward too diff --git a/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php b/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php index 8d3ae5854..8350c5fbe 100644 --- a/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php +++ b/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php @@ -343,17 +343,6 @@ class Array2XML { ] ], - ' Pre-packaged ' => '', /* Pre-built Header */ - - 'LibreELEC' => [ - 'form' => 'LibreELEC.form.php', - 'icon' => 'libreelec.png' - ], - - 'OpenELEC' => [ - 'form' => 'OpenELEC.form.php', - 'icon' => 'openelec.png' - ], ' Linux ' => '', /* Linux Header */ @@ -441,51 +430,6 @@ class Array2XML { ] ]; - $arrOpenELECVersions = [ - '6.0.3_1' => [ - 'name' => '6.0.3', - 'url' => 'https://s3.amazonaws.com/dnld.lime-technology.com/images/OpenELEC/OpenELEC-unRAID.x86_64-6.0.3_1.tar.xz', - 'size' => 178909136, - 'md5' => 'c584312831d7cd93a40e61ac9f186d32', - 'localpath' => '', - 'valid' => '0' - ], - '6.0.0_1' => [ - 'name' => '6.0.0', - 'url' => 'https://s3.amazonaws.com/dnld.lime-technology.com/images/OpenELEC/OpenELEC-unRAID.x86_64-6.0.0_1.tar.xz', - 'size' => 165658636, - 'md5' => '66fb6c3f1b6db49c291753fb3ec7c15c', - 'localpath' => '', - 'valid' => '0' - ], - '5.95.3_1' => [ - 'name' => '5.95.3 (6.0.0 Beta3)', - 'url' => 'https://s3.amazonaws.com/dnld.lime-technology.com/images/OpenELEC/OpenELEC-unRAID.x86_64-5.95.3_1.tar.xz', - 'size' => 153990180, - 'md5' => '8936cda74c28ddcaa165cc49ff2a477a', - 'localpath' => '', - 'valid' => '0' - ], - '5.95.2_1' => [ - 'name' => '5.95.2 (6.0.0 Beta2)', - 'url' => 'https://s3.amazonaws.com/dnld.lime-technology.com/images/OpenELEC/OpenELEC-unRAID.x86_64-5.95.2_1.tar.xz', - 'size' => 156250392, - 'md5' => 'ac70048eecbda4772e386c6f271cb5e9', - 'localpath' => '', - 'valid' => '0' - ] - ]; - - $arrLibreELECVersions = [ - '7.0.1_1' => [ - 'name' => '7.0.1', - 'url' => 'https://s3.amazonaws.com/dnld.lime-technology.com/images/LibreELEC/LibreELEC-unRAID.x86_64-7.0.1_1.tar.xz', - 'size' => 209748564, - 'md5' => 'c1e8def2ffb26a355e7cc598311697f6', - 'localpath' => '', - 'valid' => '0' - ] - ]; $fedora = '/var/tmp/fedora-virtio-isos'; // set variable to obtained information diff --git a/emhttp/plugins/dynamix.vm.manager/javascript/vmmanager.js b/emhttp/plugins/dynamix.vm.manager/javascript/vmmanager.js index 71431b8ff..21d7aa11e 100644 --- a/emhttp/plugins/dynamix.vm.manager/javascript/vmmanager.js +++ b/emhttp/plugins/dynamix.vm.manager/javascript/vmmanager.js @@ -228,22 +228,20 @@ function addVMContext(name, uuid, template, state, vmrcurl, vmrcprotocol, log, f ajaxVMDispatch({action:"domain-undefine",uuid:uuid}, "loadlist"); }); }}); - if (template != 'OpenELEC') { - opts.push({text:_("Remove VM")+" & "+_("Disks"), icon:"fa-trash", action:function(e) { - e.preventDefault(); - swal({ - title:_("Are you sure?"), - text:_("Completely REMOVE")+" "+name+" "+_("disk image and definition"), - type:"warning", - showCancelButton:true, - confirmButtonText:_('Proceed'), - cancelButtonText:_('Cancel') - },function(){ - $('#vm-'+uuid).find('i').removeClass('fa-play fa-square fa-pause').addClass('fa-refresh fa-spin'); - ajaxVMDispatch({action:"domain-delete",uuid:uuid}, "loadlist"); - }); - }}); - } + opts.push({text:_("Remove VM")+" & "+_("Disks"), icon:"fa-trash", action:function(e) { + e.preventDefault(); + swal({ + title:_("Are you sure?"), + text:_("Completely REMOVE")+" "+name+" "+_("disk image and definition"), + type:"warning", + showCancelButton:true, + confirmButtonText:_('Proceed'), + cancelButtonText:_('Cancel') + },function(){ + $('#vm-'+uuid).find('i').removeClass('fa-play fa-square fa-pause').addClass('fa-refresh fa-spin'); + ajaxVMDispatch({action:"domain-delete",uuid:uuid}, "loadlist"); + }); + }}); } if (usage) { context.destroy('#vmusage-'+uuid); context.attach('#vmusage-'+uuid, opts); } else { context.destroy('#vm-'+uuid); context.attach('#vm-'+uuid, opts); } } diff --git a/emhttp/plugins/dynamix.vm.manager/templates/Custom.formold.php b/emhttp/plugins/dynamix.vm.manager/templates/Custom.formold.php deleted file mode 100644 index 681b423ff..000000000 --- a/emhttp/plugins/dynamix.vm.manager/templates/Custom.formold.php +++ /dev/null @@ -1,2556 +0,0 @@ - - [ - 'name' => $strSelectedTemplate, - 'icon' => $arrAllTemplates[$strSelectedTemplate]['icon'], - 'os' => $arrAllTemplates[$strSelectedTemplate]['os'], - 'storage' => "default" - ], - 'domain' => [ - 'name' => $strSelectedTemplate, - 'persistent' => 1, - 'uuid' => $lv->domain_generate_uuid(), - 'clock' => 'localtime', - 'arch' => 'x86_64', - 'machine' => 'pc-i440fx', - 'mem' => 1024 * 1024, - 'maxmem' => 1024 * 1024, - 'password' => '', - 'cpumode' => 'host-passthrough', - 'cpumigrate' => 'on', - 'vcpus' => 1, - 'vcpu' => [0], - 'hyperv' => 1, - 'ovmf' => 1, - 'usbmode' => 'usb2', - 'memoryBacking' => '{"nosharepages":{}}' - ], - 'media' => [ - 'cdrom' => '', - 'cdrombus' => 'ide', - 'drivers' => is_file($domain_cfg['VIRTIOISO']) ? $domain_cfg['VIRTIOISO'] : '', - 'driversbus' => 'ide' , - 'cdromboot' => 2 - ], - 'disk' => [ - [ - 'new' => '', - 'size' => '', - 'driver' => 'raw', - 'dev' => 'hda', - 'select' => $domain_cfg['VMSTORAGEMODE'], - 'bus' => 'virtio' , - 'boot' => 1, - 'serial' => 'vdisk1' - ] - ], - 'gpu' => [ - [ - 'id' => 'virtual', - 'protocol' => 'vnc', - 'autoport' => 'yes', - 'model' => 'qxl', - 'keymap' => 'none', - 'port' => -1 , - 'wsport' => -1, - 'copypaste' => 'no' - ] - ], - 'audio' => [ - [ - 'id' => '' - ] - ], - 'pci' => [], - 'nic' => [ - [ - 'network' => $domain_bridge, - 'mac' => $lv->generate_random_mac_addr(), - 'model' => 'virtio-net' - ] - ], - 'usb' => [], - 'shares' => [ - [ - 'source' => '', - 'target' => '', - 'mode' => '' - ] - ] - ]; - $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 (isset($_POST['createvm'])) { - if (isset($_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/spice popup if available - $dom = $lv->get_domain_by_name($_POST['domain']['name']); - $vmrcport = $lv->domain_get_vnc_port($dom); - $wsport = $lv->domain_get_ws_port($dom); - $protocol = $lv->domain_get_vmrc_protocol($dom); - $reply = ['success' => true]; - if ($vmrcport > 0) { - $reply['vmrcurl'] = autov('/plugins/dynamix.vm.manager/'.$protocol.'.html',true).'&autoconnect=true&host=' . $_SERVER['HTTP_HOST']; - if ($protocol == "spice") $reply['vmrcurl'] .= '&port=/wsproxy/'.$vmrcport.'/'; else $reply['vmrcurl'] .= '&port=&path=/wsproxy/' . $wsport . '/'; - } - } else { - $reply = ['error' => $lv->get_last_error()]; - } - } - echo json_encode($reply); - exit; - } - - // create new VM template - if (isset($_POST['createvmtemplate'])) { - $reply = addtemplatexml($_POST); - echo json_encode($reply); - exit; - } - - // update existing VM - if (isset($_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) { - if (strpos($strNewUSBID,"#remove")) continue; - $remove = explode('#', $strNewUSBID); - $strNewUSBID2 = $remove[0]; - foreach ($arrExistingConfig['usb'] as $arrExistingUSB) { - if ($strNewUSBID2 == $arrExistingUSB['id']) continue 2; - } - [$strVendor,$strProduct] = my_explode(':', $strNewUSBID2); - // hot-attach usb - file_put_contents('/tmp/hotattach.tmp', ""); - exec("virsh attach-device ".escapeshellarg($uuid)." /tmp/hotattach.tmp --live 2>&1", $arrOutput, $intReturnCode); - unlink('/tmp/hotattach.tmp'); - if ($intReturnCode != 0) { - $arrErrors[] = implode(' ', $arrOutput); - } - } - - // hot-detach any old usb devices - foreach ($arrExistingConfig['usb'] as $arrExistingUSB) { - if (!in_array($arrExistingUSB['id'], $arrNewUSBIDs)) { - [$strVendor, $strProduct] = my_explode(':', $arrExistingUSB['id']); - file_put_contents('/tmp/hotdetach.tmp', ""); - exec("virsh detach-device ".escapeshellarg($uuid)." /tmp/hotdetach.tmp --live 2>&1", $arrOutput, $intReturnCode); - unlink('/tmp/hotdetach.tmp'); - if ($intReturnCode != 0) $arrErrors[] = implode(' ',$arrOutput); - } - } - $reply = !$arrErrors ? ['success' => true] : ['error' => implode(', ',$arrErrors)]; - echo json_encode($reply); - exit; - } - - // backup xml for existing domain in ram - if ($dom && empty($_POST['xmldesc'])) { - $oldName = $lv->domain_get_name($dom); - $newName = $_POST['domain']['name']; - $oldDir = $domain_cfg['DOMAINDIR'].$oldName; - $newDir = $domain_cfg['DOMAINDIR'].$newName; - if ($oldName && $newName && is_dir($oldDir) && !is_dir($newDir)) { - // mv domain/vmname folder - if (rename($oldDir, $newDir)) { - // replace all disk paths in xml - foreach ($_POST['disk'] as &$arrDisk) { - if ($arrDisk['new']) $arrDisk['new'] = str_replace($oldDir, $newDir, $arrDisk['new']); - if ($arrDisk['image']) $arrDisk['image'] = str_replace($oldDir, $newDir, $arrDisk['image']); - } - } - } - } - $newuuid = $uuid; - $olduuid = $uuid; - // construct updated config - if (isset($_POST['xmldesc'])) { - // XML view - $xml = $_POST['xmldesc']; - $arrExistingConfig = custom::createArray('domain',$xml); - $newuuid = $arrExistingConfig['uuid']; - $xml = str_replace($olduuid,$newuuid,$xml); - } else { - // form view - if ($error = create_vdisk($_POST) === false) { - $arrExistingConfig = custom::createArray('domain',$strXML); - $arrUpdatedConfig = custom::createArray('domain',$lv->config_to_xml($_POST)); - array_update_recursive($arrExistingConfig, $arrUpdatedConfig); - $arrConfig = array_replace_recursive($arrExistingConfig, $arrUpdatedConfig); - $xml = custom::createXML('domain',$arrConfig)->saveXML(); - $xml = $lv->appendqemucmdline($xml,$_POST["qemucmdline"]); - } else { - echo json_encode(['error' => $error]); - exit; - } - } - // delete and create the VM - $lv->nvram_backup($uuid); - $lv->domain_undefine($dom); - $lv->nvram_restore($uuid); - if ($newuuid != $olduuid) $lv->nvram_rename($olduuid,$newuuid); - $new = $lv->domain_define($xml); - if ($new) { - $lv->domain_set_autostart($new, $newAutoStart); - $reply = ['success' => true]; - } else { - // Failure -- try to restore existing VM - $reply = ['error' => $lv->get_last_error()]; - $old = $lv->domain_define($strXML); - if ($old) $lv->domain_set_autostart($old, $oldAutoStart); - } - echo json_encode($reply); - exit; - } - - if (isset($_GET['uuid'])) { - // edit an existing VM - $uuid = unscript($_GET['uuid']); - $dom = $lv->domain_get_domain_by_uuid($uuid); - $boolRunning = $lv->domain_get_state($dom)=='running'; - $strXML = $lv->domain_get_xml($dom); - $boolNew = false; - $arrConfig = array_replace_recursive($arrConfigDefaults, domain_to_config($uuid)); - $arrVMUSBs = getVMUSBs($strXML); - } else { - // edit new VM - $boolRunning = false; - $strXML = ''; - $boolNew = true; - $arrConfig = $arrConfigDefaults; - $arrVMUSBs = getVMUSBs($strXML); - } - // Add any custom metadata field defaults (e.g. os) - if (!$arrConfig['template']['os']) { - $arrConfig['template']['os'] = ($arrConfig['domain']['clock']=='localtime' ? 'windows' : 'linux'); - } - $os_type = ((empty($arrConfig['template']['os']) || stripos($arrConfig['template']['os'], 'windows') === false) ? 'other' : 'windows'); - if (isset($arrConfig['clocks'])) $arrClocks = json_decode($arrConfig['clocks'],true); else { - if ($os_type == "windows") { - if ($arrConfig['domain']['hyperv'] == 1) $arrClocks = $arrDefaultClocks['hyperv']; else $arrClocks = $arrDefaultClocks['windows']; - } else $arrClocks = $arrDefaultClocks['other']; - } - - if (strpos($arrConfig['template']['name'],"User-") !== false) { - $arrConfig['template']['name'] = str_replace("User-","",$arrConfig['template']['name']); - unset($arrConfig['domain']['uuid']); - } - if ($usertemplate == 1) unset($arrConfig['domain']['uuid']); -?> - - - - - -
- - - - - - - - - - - - - -
_(Name)_:
-
-

Give the VM a name (e.g. Work, Gaming, Media Player, Firewall, Bitcoin Miner)

-
- - - - - - -
_(Description)_:
-
-
-

Give the VM a brief description (optional field).

-
-
- - - - - -
_(Override Storage Location)_: -
-
-

Specify the overide storage pool for VM. This option allows you to specify the physical pool/disk used to store the disk images and snapshot data. - Default will follow standard processing and store images in the default location for the share defined in the settings. - A pool/disk(Volume) will be the location for images if the default is overridden. -

-
- - - - - - - - -
_(CPU)_ _(Mode)_: - - >_(Migratable)_: - - -
-
-
-

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. -

-

- Migratable
- Migratable attribute may be used to explicitly request such features to be removed from (on) or kept in (off) the virtual CPU. Off will not remove any host features when using Host Passthrough. Not support on emulated. -

-
-
- - - - - - -
_(Logical CPUs)_: -
- 1 ? 'checked' : 'checked disabled') : ''; - if (!$cpu2) { - echo ""; - } else { - echo ""; - $extra = ($arrConfig['domain']['vcpu'] && 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)_: - - - - >_(Enable USB boot)_: - - -
-
-
-

- 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. -

-

- OVMF TPM
- (Open Virtual Machine Firmware) adds support for booting VMs using UEFI with TPM and Secure Boot available, 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. -

-

- USB Boot
- Adds support for booting from USB devices using UEFI. No device boot orders can be specified at the same time as this option.
-

-
-
- - - - - - -
_(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)_: - - _(Boot Order)_: - -
-
-

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. -

-
-
-
- - $arrDisk) { - $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : _('Primary'); - - ?> - - - - - - - - - - - - - - - - - - - - - - - - - - -
_(vDisk Location)_: -
-
_(vDisk Size)_: - -
_(vDisk Type)_: - -
_(vDisk Bus)_: - - _(Boot Order)_: - - - >_(SSD)_: - title="_(Set SDD flag)_" value="" > -
_(Serial)_: - -
- -
-

- 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. -

- -

- vDisk Boot Order
- Specify the order the devices are used for booting. -

- -

- vDisk SSD Flag
- Specify the vdisk shows as SSD within the guest, only supported on SCSI, SATA and IDE bus types. -

- -

- vDisk Serial
- Set the device serial number presented to the VM. -

- -

Additional devices can be added/removed by clicking the symbols to the left.

-
- - - - - $arrShare) { - $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : ''; - - ?> - - - - - - - - - - - - - - - - -
_(Unraid Share Mode)_: - - _(Unraid Share)_: - -
- _(Unraid Source Path)_: - - id="shares[][source]" name="shares[][source]" autocomplete="off" data-pickfolders="true" data-pickfilter="NO_FILES_FILTER" data-pickroot="/mnt/" value="" placeholder="_(e.g.)_ /mnt/user/..." title="_(path of Unraid share)_" /> -
_(Unraid Mount Tag)_: - name="shares[][target]" id="shares[][target]" value="" placeholder="_(e.g.)_ _(shares)_ (_(name of mount tag inside vm)_)" title="_(mount tag inside vm)_" /> -
- -
-
-
-

- Unraid Share Mode
- Used to create a VirtFS mapping to a Linux-based guest. Specify the mode you want to use either 9p or Virtiofs. -

- - -

- Unraid Share
- Set tag and path to match the selected Unraid share. -

- -

- Unraid Source Path
- 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/9psetup -

-

- For Windows additional software needs to be installed: https://virtio-fs.gitlab.io/howto-windows.html -

- -

Additional devices can be added/removed by clicking the symbols to the left.

-
-
-
- - - - - $arrGPU) { - $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : ''; - - ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_(Graphics Card)_: - - - _(Multifunction)_: - - -
_(VM Console Protocol)_: - -
_(VM Console enable Copy/paste)_: - -
_(VM Console AutoPort)_: - - - >_(VM Console Port)_: - - > - - >_(VM Console WS Port)_: - - > -
_(VM Console Video Driver)_: - -
_(VM Console Password)_:
_(VM Console Keyboard)_: - -
_(Graphics ROM BIOS)_: - -
- -
-

- Graphics Card
- If you wish to assign a graphics card to the VM, select it from this list, otherwise leave it set to virtual. -

- -

- Virtual video protocol VNC/SPICE
- If you wish to assign a protocol type, specify one here. -

- -

- Virtual enable copy paste for VNC/SPICE
- If you enable copy paste you need to install additional software on the client in addition to the QEMU agent if that has been installed. https://www.spice-space.org/download.html is the location for spice-vdagent for both window and linux. Note copy paste function will not work with web spice viewer you need to use virt-viewer. -

- -

- Virtual auto port
- Set it you want to specify a manual port for VNC or Spice. VNC needs two ports where Spice only requires one. Leave as auto yes for the system to set. -

- -

- Virtual Video Driver
- If you wish to assign a different video driver to use for a VM Console connection, specify one here. -

- -

- Virtual Password
- If you wish to require a password to connect to the VM over a VM Console connection, specify one here. -

- -

- Virtual Keyboard
- If you wish to assign a different keyboard layout to use for a VM Console 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.

-
- - - - - $arrAudio) { - $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : ''; - - ?> - - - - - -
_(Sound Card)_: - -
- -
-

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.

-
- - - - - $domain_bridge, - 'mac' => "", - 'model' => 'virtio-net' - ]; - } - foreach ($arrConfig['nic'] as $i => $arrNic) { - $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : ''; - - ?> - - - - - - - - - - - - - - - - - -
_(Network MAC)_: - -
_(Network Source)_: - -
_(Network Model)_: - -
_(Boot Order)_: - style="width: 50px;" name="nic[][boot]" title="_(Boot order)_" value="" > -
- -
-
-

- 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 Source
- The default libvirt managed network bridge (virbr0) will be used, otherwise you may specify an alternative name for a private network to the host. -

- -

- Network Model
- Default and recommended is 'virtio-net', which gives improved stability. To improve performance 'virtio' can be selected, but this may lead to stability issues. -

- -

Use boot order to set device as bootable and boot sequence.

- -

Additional devices can be added/removed by clicking the symbols to the left.

-
-
- - - - - - - - - - - -
_(Select)_  _(Optional)_  _(Boot Order)_
_(USB Devices)_: -
- $arrDev) { - ?> -
- "._('None available').""; - } - ?> -
-
-
-

If you wish to assign any USB devices to your guest, you can select them from this list.

-

Use boot order to set device as bootable and boot sequence.

-

Select optional if you want device to be ignored when VM starts if not present.

-
- - - - - - - - - -
_(Select)_  _(Boot Order)_
_(Other PCI Devices)_: -
- $arrDev) { - $bootdisable = $extra = $pciboot = ''; - if ($arrDev["typeid"] != "0108" && substr($arrDev["typeid"],0,2) != "02") $bootdisable = ' disabled="disabled"'; - if (count($pcidevice=array_filter($arrConfig['pci'], function($arr) use ($arrDev) { return ($arr['id'] == $arrDev['id']); }))) { - $extra .= ' checked="checked"'; - foreach ($pcidevice as $pcikey => $pcidev) $pciboot = $pcidev["boot"]; - } elseif (!in_array($arrDev['driver'], ['pci-stub', 'vfio-pci'])) { - //$extra .= ' disabled="disabled"'; - continue; - } - $intAvailableOtherPCIDevices++; - ?> -
- "._('None available').""; - } - ?> -
-
-
-

If you wish to assign any other PCI devices to your guest, you can select them from this list.

-

Use boot order to set device as bootable and boot sequence. Only NVMe and Network devices (PCI types 0108 and 02xx) supported for boot order.

-
- - - - - - -
- - - - - -
- - - - -
- -
-

Click Create to generate the vDisks and return to the Virtual Machines page where your new VM will be created.

-
- - - - - - - - - - - -
_(Advanced tuning options)_
_(QEMU Command Line)_: -
-
-

If you need to add QEMU arguments to the XML

- Examples can be found on the Libvirt page => https://libvirt.org/kbase/qemu-passthrough-security.html -

-
- - - - - - - $arrTimer) { - if ($i =="offset") continue; - if ($clockcount == 0) $clocksourcetext = _("Timer Source").":"; else $clocksourcetext = ""; - ?> - - - - - - - -
_(Clocks)_
_(Clocks Offset)_: - - -
- : - _(Present)_: - - _(Tickpolicy)_: - -
-
-

Allows setting of timers and offset into the XML You should not need to modify these values.

-

Windows tuning details can be found here https://forums.unraid.net/topic/134041-guide-optimizing-windows-vms-in-unraid/

-

Details can be found on the Libvirt XML page => https://libvirt.org/formatdomain.html#time-keeping

-

Defaults are:

-

linux Hpet:no Hypervclock: no Pit yes rtc yes tickpolicy catchup.

-

Windows Hpet:no Hypervclock: yes Pit yes rtc yes tickpolicy catchup.

-

Windows and Hyperv Hpet:no Hypervclock: yes Pit no rtc no.

-

-
- "",'grab'=>"",'repeat'=>"",'grabToggle'=>""]; - foreach ($arrConfig['evdev'] as $i => $arrEvdev) { - $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : ''; - ?> - - - - - - - - - - - - - - - - - - - - -
_(Evdev Device)_: - -
_(Grab)_: - -
_(Repeat)_: - -
_(Grab Toggle)_: - -
- -
-
-

- Event Devices
- Evdev is an input interface built into the Linux kernel. QEMU’s evdev passthrough support allows a user to redirect evdev events to a guest. These events can include mouse movements and key presses. By hitting both Ctrl keys at the same time, QEMU can toggle the input recipient. QEMU’s evdev passthrough also features almost no latency, making it perfect for gaming. The main downside to evdev passthrough is the lack of button rebinding – and in some cases, macro keys won’t even work at all. - Optional items are normally only used for keyboards. -

-

- Device
- Host device to passthrough to guest. -

- -

- Grab
- All grabs all input devices instead of just one -

- -

- Repeat
- Repeat with value 'on'/'off' to enable/disable auto-repeat events -

- -

- GrabToggle
- GrabToggle with values ctrl-ctrl, alt-alt, shift-shift, meta-meta, scrolllock or ctrl-scrolllock to change the grab key combination

- -

Additional devices can be added/removed by clicking the symbols to the left.

-
-
- - - - - - - - - -
- - - - - - - - - -
- -
-

Click Create to generate the vDisks and return to the Virtual Machines page where your new VM will be created.

-
- -
- -
- - - - - - - -
- - - - - - -
- - - - - - - - -
-
- - - - - - - - - diff --git a/emhttp/plugins/dynamix.vm.manager/templates/LibreELEC.form.php b/emhttp/plugins/dynamix.vm.manager/templates/LibreELEC.form.php deleted file mode 100644 index 88556695d..000000000 --- a/emhttp/plugins/dynamix.vm.manager/templates/LibreELEC.form.php +++ /dev/null @@ -1,1578 +0,0 @@ - - $strLocalpath) { - if (array_key_exists($strID, $arrLibreELECVersions)) { - $arrLibreELECVersions[$strID]['localpath'] = $strLocalpath; - if (file_exists($strLocalpath)) { - $arrLibreELECVersions[$strID]['valid'] = '1'; - } - } - } - - if (isset($_POST['delete_version'])) { - $arrDeleteLibreELEC = []; - if (array_key_exists($_POST['delete_version'], $arrLibreELECVersions)) { - $arrDeleteLibreELEC = $arrLibreELECVersions[$_POST['delete_version']]; - } - $reply = []; - if (empty($arrDeleteLibreELEC)) { - $reply = ['error' => _('Unknown version').': ' . $_POST['delete_version']]; - } else { - // delete img file - @unlink($arrDeleteLibreELEC['localpath']); - - // Save to strLibreELECConfig - unset($arrLibreELECConfig[$_POST['delete_version']]); - $text = ''; - foreach ($arrLibreELECConfig as $key => $value) $text .= "$key=\"$value\"\n"; - file_put_contents($strLibreELECConfig, $text); - $reply = ['status' => 'ok']; - } - - echo json_encode($reply); - exit; - } - - if (isset($_POST['download_path'])) { - $arrDownloadLibreELEC = []; - if (array_key_exists($_POST['download_version'], $arrLibreELECVersions)) { - $arrDownloadLibreELEC = $arrLibreELECVersions[$_POST['download_version']]; - } - if (empty($arrDownloadLibreELEC)) { - $reply = ['error' => _('Unknown version').': ' . $_POST['download_version']]; - } elseif (empty($_POST['download_path'])) { - $reply = ['error' => _('Please choose a folder the LibreELEC image will download to')]; - } else { - @mkdir($_POST['download_path'], 0777, true); - $_POST['download_path'] = realpath($_POST['download_path']) . '/'; - - // Check free space - if (disk_free_space($_POST['download_path']) < $arrDownloadLibreELEC['size']+10000) { - $reply = ['error' => _('Not enough free space, need at least').' ' . ceil($arrDownloadLibreELEC['size']/1000000).'MB']; - echo json_encode($reply); - exit; - } - - $boolCheckOnly = !empty($_POST['checkonly']); - $strInstallScript = '/tmp/LibreELEC_' . $_POST['download_version'] . '_install.sh'; - $strInstallScriptPgrep = '-f "LibreELEC_' . $_POST['download_version'] . '_install.sh"'; - $strTempFile = $_POST['download_path'] . basename($arrDownloadLibreELEC['url']); - $strLogFile = $strTempFile . '.log'; - $strMD5File = $strTempFile . '.md5'; - $strMD5StatusFile = $strTempFile . '.md5status'; - $strExtractedFile = $_POST['download_path'] . basename($arrDownloadLibreELEC['url'], 'tar.xz') . 'img'; - - // Save to strLibreELECConfig - $arrLibreELECConfig[$_POST['download_version']] = $strExtractedFile; - $text = ''; - foreach ($arrLibreELECConfig as $key => $value) $text .= "$key=\"$value\"\n"; - file_put_contents($strLibreELECConfig, $text); - - $strDownloadCmd = 'wget -nv -c -O ' . escapeshellarg($strTempFile) . ' ' . escapeshellarg($arrDownloadLibreELEC['url']); - $strDownloadPgrep = '-f "wget.*' . $strTempFile . '.*' . $arrDownloadLibreELEC['url'] . '"'; - $strVerifyCmd = 'md5sum -c ' . escapeshellarg($strMD5File); - $strVerifyPgrep = '-f "md5sum.*' . $strMD5File . '"'; - $strExtractCmd = 'tar Jxf ' . escapeshellarg($strTempFile) . ' -C ' . escapeshellarg(dirname($strTempFile)); - $strExtractPgrep = '-f "tar.*' . $strTempFile . '.*' . dirname($strTempFile) . '"'; - $strCleanCmd = '(chmod 777 ' . escapeshellarg($_POST['download_path']) . ' ' . escapeshellarg($strExtractedFile) . '; chown nobody:users ' . escapeshellarg($_POST['download_path']) . ' ' . escapeshellarg($strExtractedFile) . '; rm ' . escapeshellarg($strTempFile) . ' ' . escapeshellarg($strMD5File) . ' ' . escapeshellarg($strMD5StatusFile) . ')'; - $strCleanPgrep = '-f "chmod.*chown.*rm.*' . $strMD5StatusFile . '"'; - $strAllCmd = "#!/bin/bash\n\n"; - $strAllCmd .= $strDownloadCmd . ' >>' . escapeshellarg($strLogFile) . ' 2>&1 && '; - $strAllCmd .= 'echo "' . $arrDownloadLibreELEC['md5'] . ' ' . $strTempFile . '" > ' . escapeshellarg($strMD5File) . ' && '; - $strAllCmd .= $strVerifyCmd . ' >' . escapeshellarg($strMD5StatusFile) . ' 2>/dev/null && '; - $strAllCmd .= $strExtractCmd . ' >>' . escapeshellarg($strLogFile) . ' 2>&1 && '; - $strAllCmd .= $strCleanCmd . ' >>' . escapeshellarg($strLogFile) . ' 2>&1 && '; - $strAllCmd .= 'rm ' . escapeshellarg($strLogFile) . ' && '; - $strAllCmd .= 'rm ' . escapeshellarg($strInstallScript); - - $reply = []; - if (file_exists($strExtractedFile)) { - if (!file_exists($strTempFile)) { - // Status = done - $reply['status'] = 'Done'; - $reply['localpath'] = $strExtractedFile; - $reply['localfolder'] = dirname($strExtractedFile); - } else { - if (pgrep($strExtractPgrep, false)) { - // Status = running extract - $reply['status'] = _('Extracting').' ... '; - } else { - // Status = cleanup - $reply['status'] = _('Cleanup').' ... '; - } - } - } elseif (file_exists($strTempFile)) { - if (pgrep($strDownloadPgrep, false)) { - // Get Download percent completed - $intSize = filesize($strTempFile); - $strPercent = 0; - if ($intSize > 0) { - $strPercent = round(($intSize / $arrDownloadLibreELEC['size']) * 100); - } - $reply['status'] = _('Downloading').' ... ' . $strPercent . '%'; - } elseif (pgrep($strVerifyPgrep, false)) { - // Status = running md5 check - $reply['status'] = _('Verifying').' ... '; - } elseif (file_exists($strMD5StatusFile)) { - // Status = running extract - $reply['status'] = _('Extracting').' ... '; - if (!pgrep($strExtractPgrep, false)) { - // Examine md5 status - $strMD5StatusContents = file_get_contents($strMD5StatusFile); - if (strpos($strMD5StatusContents, ': FAILED') !== false) { - // ERROR: MD5 check failed - unset($reply['status']); - $reply['error'] = _('MD5 verification failed, your download is incomplete or corrupted').'.'; - } - } - } elseif (!file_exists($strMD5File)) { - // Status = running md5 check - $reply['status'] = _('Downloading').' ... 100%'; - if (!pgrep($strInstallScriptPgrep, false) && !$boolCheckOnly) { - // Run all commands - file_put_contents($strInstallScript, $strAllCmd); - chmod($strInstallScript, 0777); - exec($strInstallScript . ' >/dev/null 2>&1 &'); - } - } - } elseif (!$boolCheckOnly) { - if (!pgrep($strInstallScriptPgrep, false)) { - // Run all commands - file_put_contents($strInstallScript, $strAllCmd); - chmod($strInstallScript, 0777); - exec($strInstallScript . ' >/dev/null 2>&1 &'); - } - $reply['status'] = _('Downloading').' ... '; - } - $reply['pid'] = pgrep($strInstallScriptPgrep, false); - } - echo json_encode($reply); - exit; - } - - $arrLibreELECVersion = reset($arrLibreELECVersions); - $strLibreELECVersionID = key($arrLibreELECVersions); - - $arrConfigDefaults = [ - 'template' => [ - 'name' => $strSelectedTemplate, - 'icon' => $arrAllTemplates[$strSelectedTemplate]['icon'], - 'libreelec' => $strLibreELECVersionID - ], - 'domain' => [ - 'name' => $strSelectedTemplate, - 'persistent' => 1, - 'uuid' => $lv->domain_generate_uuid(), - 'clock' => 'utc', - 'arch' => 'x86_64', - 'machine' => getLatestMachineType('q35'), - 'mem' => 512 * 1024, - 'maxmem' => 512 * 1024, - 'password' => '', - 'cpumode' => 'host-passthrough', - 'vcpus' => 1, - 'vcpu' => [0], - 'hyperv' => 0, - 'ovmf' => 1, - 'usbmode' => 'usb3' - ], - 'media' => [ - 'cdrom' => '', - 'cdrombus' => '', - 'drivers' => '', - 'driversbus' => '' - ], - 'disk' => [ - [ - 'image' => $arrLibreELECVersion['localpath'], - 'size' => '', - 'driver' => 'raw', - 'dev' => 'hda', - 'readonly' => 1, - 'boot' => 1 - ] - ], - 'gpu' => [ - [ - 'id' => 'virtual', - 'protocol' => 'vnc', - 'autoport' => 'yes', - 'model' => 'qxl', - 'keymap' => 'en-us', - 'port' => -1 , - 'wsport' => -1 - ] - ], - 'audio' => [ - [ - 'id' => '' - ] - ], - 'pci' => [], - 'nic' => [ - [ - 'network' => $domain_bridge, - 'mac' => $lv->generate_random_mac_addr(), - 'model' => 'virtio-net' - ] - ], - 'usb' => [], - 'shares' => [ - [ - 'source' => (is_dir('/mnt/user/appdata') ? '/mnt/user/appdata/LibreELEC/' : ''), - 'target' => 'appconfig' - ] - ] - ]; - -$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 (isset($_POST['createvm'])) { - if (isset($_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 (isset($_POST['shares'][0]['source'])) { - @mkdir($_POST['shares'][0]['source'], 0777, true); - } - $_POST['clock'] = $arrDefaultClocks["other"] ; - if ($lv->domain_new($_POST)){ - $reply = ['success' => true]; - } else { - $reply = ['error' => $lv->get_last_error()]; - } - } - echo json_encode($reply); - exit; - } - - // update existing VM - if (isset($_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) { - if (strpos($strNewUSBID,"#remove")) continue ; - $remove = explode('#', $strNewUSBID) ; - $strNewUSBID2 = $remove[0] ; - foreach ($arrExistingConfig['usb'] as $arrExistingUSB) { - if ($strNewUSBID2 == $arrExistingUSB['id']) continue 2; - } - [$strVendor,$strProduct] = my_explode(':', $strNewUSBID2); - // hot-attach usb - file_put_contents('/tmp/hotattach.tmp', ""); - exec("virsh attach-device ".escapeshellarg($uuid)." /tmp/hotattach.tmp --live 2>&1", $arrOutput, $intReturnCode); - unlink('/tmp/hotattach.tmp'); - if ($intReturnCode != 0) { - $arrErrors[] = implode(' ', $arrOutput); - } - } - - // hot-detach any old usb devices - foreach ($arrExistingConfig['usb'] as $arrExistingUSB) { - if (!in_array($arrExistingUSB['id'], $arrNewUSBIDs)) { - [$strVendor, $strProduct] = my_explode(':', $arrExistingUSB['id']); - file_put_contents('/tmp/hotdetach.tmp', ""); - exec("virsh detach-device ".escapeshellarg($uuid)." /tmp/hotdetach.tmp --live 2>&1", $arrOutput, $intReturnCode); - unlink('/tmp/hotdetach.tmp'); - if ($intReturnCode != 0) $arrErrors[] = implode(' ',$arrOutput); - } - } - $reply = !$arrErrors ? ['success' => true] : ['error' => implode(', ',$arrErrors)]; - echo json_encode($reply); - exit; - } - - // backup xml for existing domain in ram - if ($dom && empty($_POST['xmldesc'])) { - $oldName = $lv->domain_get_name($dom); - $newName = $_POST['domain']['name']; - $oldDir = $domain_cfg['DOMAINDIR'].$oldName; - $newDir = $domain_cfg['DOMAINDIR'].$newdName; - if ($oldName && $newName && is_dir($oldDir) && !is_dir($newDir)) { - // mv domain/vmname folder - if (rename($oldDir, $newDir)) { - // replace all disk paths in xml - foreach ($_POST['disk'] as &$arrDisk) { - if ($arrDisk['new']) $arrDisk['new'] = str_replace($oldDir, $newDir, $arrDisk['new']); - if ($arrDisk['image']) $arrDisk['image'] = str_replace($oldDir, $newDir, $arrDisk['image']); - } - } - } - } - - // construct updated config - if (isset($_POST['xmldesc'])) { - // XML view - $xml = $_POST['xmldesc']; - } else { - // form view - if (isset($_POST['shares'][0]['source'])) { - @mkdir($_POST['shares'][0]['source'], 0777, true); - } - $_POST['clock'] = $arrDefaultClocks["other"] ; - $arrExistingConfig = custom::createArray('domain',$strXML); - $arrUpdatedConfig = custom::createArray('domain',$lv->config_to_xml($_POST)); - array_update_recursive($arrExistingConfig, $arrUpdatedConfig); - $arrConfig = array_replace_recursive($arrExistingConfig, $arrUpdatedConfig); - $xml = custom::createXML('domain',$arrConfig)->saveXML(); - } - // delete and create the VM - $lv->nvram_backup($uuid); - $lv->domain_undefine($dom); - $lv->nvram_restore($uuid); - $new = $lv->domain_define($xml); - if ($new) { - $lv->domain_set_autostart($new, $newAutoStart); - $reply = ['success' => true]; - } else { - // Failure -- try to restore existing VM - $reply = ['error' => $lv->get_last_error()]; - $old = $lv->domain_define($strXML); - if ($old) $lv->domain_set_autostart($old, $oldAutoStart); - } - echo json_encode($reply); - exit; - } - - if (isset($_GET['uuid'])) { - // edit an existing VM - $uuid = unscript($_GET['uuid']); - $dom = $lv->domain_get_domain_by_uuid($uuid); - $boolRunning = $lv->domain_get_state($dom)=='running'; - $strXML = $lv->domain_get_xml($dom); - $boolNew = false; - $arrConfig = array_replace_recursive($arrConfigDefaults, domain_to_config($uuid)); - $arrVMUSBs = getVMUSBs($strXML) ; - } else { - // edit new VM - $boolRunning = false; - $strXML = ''; - $boolNew = true; - $arrConfig = $arrConfigDefaults; - $arrVMUSBs = getVMUSBs($strXML) ; - } - - if (array_key_exists($arrConfig['template']['libreelec'], $arrLibreELECVersions)) { - $arrConfigDefaults['disk'][0]['image'] = $arrLibreELECVersions[$arrConfig['template']['libreelec']]['localpath']; - } -?> - - - - - -
- - - - - - - - - - - -
- - - - - -
_(Name)_:
-
-

Give the VM a name (e.g. LibreELEC Family Room, LibreELEC Theatre, LibreELEC)

-
- - - - - - -
_(Description)_:
-
-
-

Give the VM a brief description (optional field).

-
-
-
- - - - - - -
_(LibreELEC Version)_: - -
-
-

Select which LibreELEC version to download or use for this VM

-
- -
- - - - - -
_(Download Folder)_: - -
-
-

Choose a folder where the LibreELEC image will downloaded to

-
- - - - - - -
- -
-
- -
- - - - - -
_(Config Folder)_: - - -
-
-

Choose a folder or type in a new name off of an existing folder to specify where LibreELEC will save configuration files. If you create multiple LibreELEC VMs, these Config Folders must be unique for each instance.

-
- - - - - - -
_(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)_: -
- 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)_: - - - >_(Enable USB boot)_: - - -
-
-
-

- 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. -

-

- USB Boot
- Adds support for booting from USB devices using UEFI. No device boot orders can be specified at the same time as this option.
-

-
-
- - - - - - -
_(USB Controller)_: - -
-
-
-

- USB Controller
- Select the USB Controller to emulate. 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. -

-
-
- - $arrGPU) { - $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : ''; - - ?> - - - - - - - - - - - - - - - - - - - -
_(Graphics Card)_: - -
_(VM Console Protocol)_: - -
_(VM Console AutoPort)_: - - - >_(VM Console Port)_: - - > - - >_(VM Console WS Port)_: - - > -
_(Graphics ROM BIOS)_: - -
- -
-

- Graphics Card
- If you wish to assign a graphics card to the VM, select it from this list, otherwise leave it set to virtual. -

-

- virtual video protocol VDA/SPICE
- If you wish to assign a protocol type, specify one here. -

- - Graphics Card
- If you wish to assign a graphics card to the VM, select it from this list, otherwise leave it set to virtual. -

- -

- virtual video protocol VDC/SPICE
- If you wish to assign a protocol type, specify one here. -

- -

- virtual auto port
- Set it you want to specify a manual port for VNC or Spice. VNC needs two ports where Spice only requires one. Leave as auto yes for the system to set. -

- - -

- Graphics ROM BIOS
- If you wish to use a custom ROM BIOS for a Graphics card, specify one here. -

- - 1) {?> -

Additional devices can be added/removed by clicking the symbols to the left.

- -
- - - - - $arrAudio) { - $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : ''; - - ?> - - - - - -
_(Sound Card)_: - -
- -
-

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.

- 1) {?> -

Additional devices can be added/removed by clicking the symbols to the left.

- -
- - - - - $domain_bridge, - 'mac' => "", - 'model' => 'virtio-net' - ] ; - } - foreach ($arrConfig['nic'] as $i => $arrNic) { - $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : ''; - - ?> - - - - - - - - - - - - - - - - - -
_(Network MAC)_: - -
_(Network Source)_: - -
_(Network Model)_: - -
_(Boot Order)_: - style="width: 50px;" name="nic[][boot]" title="_(Boot order)_" value="" > -
- -
-
-

- 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 Source
- The default libvirt managed network bridge (virbr0) will be used, otherwise you may specify an alternative name for a private network to the host. -

- -

- Network Model
- Default and recommended is 'virtio-net', which gives improved stability. To improve performance 'virtio' can be selected, but this may lead to stability issues. -

- -

Use boot order to set device as bootable and boot sequence.

- -

Additional devices can be added/removed by clicking the symbols to the left.

-
-
- - - - - - - - - - - - -
_(Select)_  _(Optional)_  _(Boot Order)_
_(USB Devices)_: -
- $arrDev) { - ?> -
- "._('None available').""; - } - ?> -
-
-
-

If you wish to assign any USB devices to your guest, you can select them from this list.

-

Use boot order to set device as bootable and boot sequence.

-

Select optional if you want device to be ignored when VM starts if not present.

-
- - - - - - - - - -
_(Select)_  _(Boot Order)_
_(Other PCI Devices)_: -
- $arrDev) { - $bootdisable = $extra = $pciboot = ''; - if ($arrDev["typeid"] != "0108") $bootdisable = ' disabled="disabled"' ; - if (count($pcidevice=array_filter($arrConfig['pci'], function($arr) use ($arrDev) { return ($arr['id'] == $arrDev['id']); }))) { - $extra .= ' checked="checked"'; - foreach ($pcidevice as $pcikey => $pcidev) $pciboot = $pcidev["boot"]; ; - - } elseif (!in_array($arrDev['driver'], ['pci-stub', 'vfio-pci'])) { - //$extra .= ' disabled="disabled"'; - continue; - } - $intAvailableOtherPCIDevices++; - ?> -
- "._('None available').""; - } - ?> -
-
-
-

If you wish to assign any other PCI devices to your guest, you can select them from this list.

-

Use boot order to set device as bootable and boot sequence. Only NVMe devices (PCI types 0108) supported for boot order.

-
- - - - - - -
- - - - - -
- - - - -
- -
-

Click Create to return to the Virtual Machines page where your new VM will be created.

-
- -
- - -
- - - - - - - -
- - - - - - -
- - - - - - - -
-
- - - - - - - - - diff --git a/emhttp/plugins/dynamix.vm.manager/templates/OpenELEC.form.php b/emhttp/plugins/dynamix.vm.manager/templates/OpenELEC.form.php deleted file mode 100644 index ce5bbddce..000000000 --- a/emhttp/plugins/dynamix.vm.manager/templates/OpenELEC.form.php +++ /dev/null @@ -1,1568 +0,0 @@ - - $strLocalpath) { - if (array_key_exists($strID, $arrOpenELECVersions)) { - $arrOpenELECVersions[$strID]['localpath'] = $strLocalpath; - if (file_exists($strLocalpath)) { - $arrOpenELECVersions[$strID]['valid'] = '1'; - } - } - } - - if (isset($_POST['delete_version'])) { - $arrDeleteOpenELEC = []; - if (array_key_exists($_POST['delete_version'], $arrOpenELECVersions)) { - $arrDeleteOpenELEC = $arrOpenELECVersions[$_POST['delete_version']]; - } - $reply = []; - if (empty($arrDeleteOpenELEC)) { - $reply = ['error' => 'Unknown version: ' . $_POST['delete_version']]; - } else { - // delete img file - @unlink($arrDeleteOpenELEC['localpath']); - - // Save to strOpenELECConfig - unset($arrOpenELECConfig[$_POST['delete_version']]); - $text = ''; - foreach ($arrOpenELECConfig as $key => $value) $text .= "$key=\"$value\"\n"; - file_put_contents($strOpenELECConfig, $text); - $reply = ['status' => 'ok']; - } - - echo json_encode($reply); - exit; - } - - if (isset($_POST['download_path'])) { - $arrDownloadOpenELEC = []; - if (array_key_exists($_POST['download_version'], $arrOpenELECVersions)) { - $arrDownloadOpenELEC = $arrOpenELECVersions[$_POST['download_version']]; - } - if (empty($arrDownloadOpenELEC)) { - $reply = ['error' => _('Unknown version').': ' . $_POST['download_version']]; - } elseif (empty($_POST['download_path'])) { - $reply = ['error' => _('Please choose a folder the OpenELEC image will download to')]; - } else { - @mkdir($_POST['download_path'], 0777, true); - $_POST['download_path'] = realpath($_POST['download_path']) . '/'; - - // Check free space - if (disk_free_space($_POST['download_path']) < $arrDownloadOpenELEC['size']+10000) { - $reply = ['error' => _('Not enough free space, need at least').' ' . ceil($arrDownloadOpenELEC['size']/1000000).'MB']; - echo json_encode($reply); - exit; - } - - $boolCheckOnly = !empty($_POST['checkonly']); - $strInstallScript = '/tmp/OpenELEC_' . $_POST['download_version'] . '_install.sh'; - $strInstallScriptPgrep = '-f "OpenELEC_' . $_POST['download_version'] . '_install.sh"'; - $strTempFile = $_POST['download_path'] . basename($arrDownloadOpenELEC['url']); - $strLogFile = $strTempFile . '.log'; - $strMD5File = $strTempFile . '.md5'; - $strMD5StatusFile = $strTempFile . '.md5status'; - $strExtractedFile = $_POST['download_path'] . basename($arrDownloadOpenELEC['url'], 'tar.xz') . 'img'; - - // Save to strOpenELECConfig - $arrOpenELECConfig[$_POST['download_version']] = $strExtractedFile; - $text = ''; - foreach ($arrOpenELECConfig as $key => $value) $text .= "$key=\"$value\"\n"; - file_put_contents($strOpenELECConfig, $text); - - $strDownloadCmd = 'wget -nv -c -O ' . escapeshellarg($strTempFile) . ' ' . escapeshellarg($arrDownloadOpenELEC['url']); - $strDownloadPgrep = '-f "wget.*' . $strTempFile . '.*' . $arrDownloadOpenELEC['url'] . '"'; - $strVerifyCmd = 'md5sum -c ' . escapeshellarg($strMD5File); - $strVerifyPgrep = '-f "md5sum.*' . $strMD5File . '"'; - $strExtractCmd = 'tar Jxf ' . escapeshellarg($strTempFile) . ' -C ' . escapeshellarg(dirname($strTempFile)); - $strExtractPgrep = '-f "tar.*' . $strTempFile . '.*' . dirname($strTempFile) . '"'; - $strCleanCmd = '(chmod 777 ' . escapeshellarg($_POST['download_path']) . ' ' . escapeshellarg($strExtractedFile) . '; chown nobody:users ' . escapeshellarg($_POST['download_path']) . ' ' . escapeshellarg($strExtractedFile) . '; rm ' . escapeshellarg($strTempFile) . ' ' . escapeshellarg($strMD5File) . ' ' . escapeshellarg($strMD5StatusFile) . ')'; - $strCleanPgrep = '-f "chmod.*chown.*rm.*' . $strMD5StatusFile . '"'; - $strAllCmd = "#!/bin/bash\n\n"; - $strAllCmd .= $strDownloadCmd . ' >>' . escapeshellarg($strLogFile) . ' 2>&1 && '; - $strAllCmd .= 'echo "' . $arrDownloadOpenELEC['md5'] . ' ' . $strTempFile . '" > ' . escapeshellarg($strMD5File) . ' && '; - $strAllCmd .= $strVerifyCmd . ' >' . escapeshellarg($strMD5StatusFile) . ' 2>/dev/null && '; - $strAllCmd .= $strExtractCmd . ' >>' . escapeshellarg($strLogFile) . ' 2>&1 && '; - $strAllCmd .= $strCleanCmd . ' >>' . escapeshellarg($strLogFile) . ' 2>&1 && '; - $strAllCmd .= 'rm ' . escapeshellarg($strLogFile) . ' && '; - $strAllCmd .= 'rm ' . escapeshellarg($strInstallScript); - - $reply = []; - if (file_exists($strExtractedFile)) { - if (!file_exists($strTempFile)) { - // Status = done - $reply['status'] = 'Done'; - $reply['localpath'] = $strExtractedFile; - $reply['localfolder'] = dirname($strExtractedFile); - } else { - if (pgrep($strExtractPgrep, false)) { - // Status = running extract - $reply['status'] = _('Extracting').' ... '; - } else { - // Status = cleanup - $reply['status'] = _('Cleanup').' ... '; - } - } - } elseif (file_exists($strTempFile)) { - if (pgrep($strDownloadPgrep, false)) { - // Get Download percent completed - $intSize = filesize($strTempFile); - $strPercent = 0; - if ($intSize > 0) { - $strPercent = round(($intSize / $arrDownloadOpenELEC['size']) * 100); - } - $reply['status'] = _('Downloading').' ... ' . $strPercent . '%'; - } elseif (pgrep($strVerifyPgrep, false)) { - // Status = running md5 check - $reply['status'] = _('Verifying').' ... '; - } elseif (file_exists($strMD5StatusFile)) { - // Status = running extract - $reply['status'] = _('Extracting').' ... '; - if (!pgrep($strExtractPgrep, false)) { - // Examine md5 status - $strMD5StatusContents = file_get_contents($strMD5StatusFile); - if (strpos($strMD5StatusContents, ': FAILED') !== false) { - // ERROR: MD5 check failed - unset($reply['status']); - $reply['error'] = _('MD5 verification failed, your download is incomplete or corrupted').'.'; - } - } - } elseif (!file_exists($strMD5File)) { - // Status = running md5 check - $reply['status'] = _('Downloading').' ... 100%'; - if (!pgrep($strInstallScriptPgrep, false) && !$boolCheckOnly) { - // Run all commands - file_put_contents($strInstallScript, $strAllCmd); - chmod($strInstallScript, 0777); - exec($strInstallScript . ' >/dev/null 2>&1 &'); - } - } - } elseif (!$boolCheckOnly) { - if (!pgrep($strInstallScriptPgrep, false)) { - // Run all commands - file_put_contents($strInstallScript, $strAllCmd); - chmod($strInstallScript, 0777); - exec($strInstallScript . ' >/dev/null 2>&1 &'); - } - $reply['status'] = _('Downloading').' ... '; - } - $reply['pid'] = pgrep($strInstallScriptPgrep, false); - } - echo json_encode($reply); - exit; - } - - $arrOpenELECVersion = reset($arrOpenELECVersions); - $strOpenELECVersionID = key($arrOpenELECVersions); - - $arrConfigDefaults = [ - 'template' => [ - 'name' => $strSelectedTemplate, - 'icon' => $arrAllTemplates[$strSelectedTemplate]['icon'], - 'openelec' => $strOpenELECVersionID - ], - 'domain' => [ - 'name' => $strSelectedTemplate, - 'persistent' => 1, - 'uuid' => $lv->domain_generate_uuid(), - 'clock' => 'utc', - 'arch' => 'x86_64', - 'machine' => getLatestMachineType('q35'), - 'mem' => 512 * 1024, - 'maxmem' => 512 * 1024, - 'password' => '', - 'cpumode' => 'host-passthrough', - 'vcpus' => 1, - 'vcpu' => [0], - 'hyperv' => 0, - 'ovmf' => 1, - 'usbmode' => 'usb3' - ], - 'media' => [ - 'cdrom' => '', - 'cdrombus' => '', - 'drivers' => '', - 'driversbus' => '' - ], - 'disk' => [ - [ - 'image' => $arrOpenELECVersion['localpath'], - 'size' => '', - 'driver' => 'raw', - 'dev' => 'hda', - 'readonly' => 1, - 'boot' => 1 - ] - ], - 'gpu' => [ - [ - 'id' => 'virtual', - 'protocol' => 'vnc', - 'autoport' => 'yes', - 'model' => 'qxl', - 'keymap' => 'en-us', - 'port' => -1 , - 'wsport' => -1 - ] - ], - 'audio' => [ - [ - 'id' => '' - ] - ], - 'pci' => [], - 'nic' => [ - [ - 'network' => $domain_bridge, - 'mac' => $lv->generate_random_mac_addr(), - 'model' => 'virtio-net' - ] - ], - 'usb' => [], - 'shares' => [ - [ - 'source' => (is_dir('/mnt/user/appdata') ? '/mnt/user/appdata/OpenELEC/' : ''), - 'target' => 'appconfig' - ] - ] - ]; - -$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 (isset($_POST['createvm'])) { - if (isset($_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 (isset($_POST['shares'][0]['source'])) { - @mkdir($_POST['shares'][0]['source'], 0777, true); - } - $_POST['clock'] = $arrDefaultClocks["other"] ; - if ($lv->domain_new($_POST)){ - $reply = ['success' => true]; - } else { - $reply = ['error' => $lv->get_last_error()]; - } - } - echo json_encode($reply); - exit; - } - - // update existing VM - if (isset($_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) { - if (strpos($strNewUSBID,"#remove")) continue ; - $remove = explode('#', $strNewUSBID) ; - $strNewUSBID2 = $remove[0] ; - foreach ($arrExistingConfig['usb'] as $arrExistingUSB) { - if ($strNewUSBID2 == $arrExistingUSB['id']) continue 2; - } - [$strVendor,$strProduct] = my_explode(':', $strNewUSBID2); - // hot-attach usb - file_put_contents('/tmp/hotattach.tmp', ""); - exec("virsh attach-device ".escapeshellarg($uuid)." /tmp/hotattach.tmp --live 2>&1", $arrOutput, $intReturnCode); - unlink('/tmp/hotattach.tmp'); - if ($intReturnCode != 0) { - $arrErrors[] = implode(' ', $arrOutput); - } - } - - // hot-detach any old usb devices - foreach ($arrExistingConfig['usb'] as $arrExistingUSB) { - if (!in_array($arrExistingUSB['id'], $arrNewUSBIDs)) { - [$strVendor, $strProduct] = my_explode(':', $arrExistingUSB['id']); - file_put_contents('/tmp/hotdetach.tmp', ""); - exec("virsh detach-device ".escapeshellarg($uuid)." /tmp/hotdetach.tmp --live 2>&1", $arrOutput, $intReturnCode); - unlink('/tmp/hotdetach.tmp'); - if ($intReturnCode != 0) $arrErrors[] = implode(' ',$arrOutput); - } - } - $reply = !$arrErrors ? ['success' => true] : ['error' => implode(', ',$arrErrors)]; - echo json_encode($reply); - exit; - } - - // backup xml for existing domain in ram - if ($dom && empty($_POST['xmldesc'])) { - $oldName = $lv->domain_get_name($dom); - $newName = $_POST['domain']['name']; - $oldDir = $domain_cfg['DOMAINDIR'].$oldName; - $newDir = $domain_cfg['DOMAINDIR'].$newdName; - if ($oldName && $newName && is_dir($oldDir) && !is_dir($newDir)) { - // mv domain/vmname folder - if (rename($oldDir, $newDir)) { - // replace all disk paths in xml - foreach ($_POST['disk'] as &$arrDisk) { - if ($arrDisk['new']) $arrDisk['new'] = str_replace($oldDir, $newDir, $arrDisk['new']); - if ($arrDisk['image']) $arrDisk['image'] = str_replace($oldDir, $newDir, $arrDisk['image']); - } - } - } - } - - // construct updated config - if (isset($_POST['xmldesc'])) { - // XML view - $xml = $_POST['xmldesc']; - } else { - // form view - if (isset($_POST['shares'][0]['source'])) { - @mkdir($_POST['shares'][0]['source'], 0777, true); - } - $_POST['clock'] = $arrDefaultClocks["other"] ; - $arrExistingConfig = custom::createArray('domain',$strXML); - $arrUpdatedConfig = custom::createArray('domain',$lv->config_to_xml($_POST)); - array_update_recursive($arrExistingConfig, $arrUpdatedConfig); - $arrConfig = array_replace_recursive($arrExistingConfig, $arrUpdatedConfig); - $xml = custom::createXML('domain',$arrConfig)->saveXML(); - } - // delete and create the VM - $lv->nvram_backup($uuid); - $lv->domain_undefine($dom); - $lv->nvram_restore($uuid); - $new = $lv->domain_define($xml); - if ($new) { - $lv->domain_set_autostart($new, $newAutoStart); - $reply = ['success' => true]; - } else { - // Failure -- try to restore existing VM - $reply = ['error' => $lv->get_last_error()]; - $old = $lv->domain_define($strXML); - if ($old) $lv->domain_set_autostart($old, $oldAutoStart); - } - echo json_encode($reply); - exit; - } - - if (isset($_GET['uuid'])) { - // edit an existing VM - $uuid = unscript($_GET['uuid']); - $dom = $lv->domain_get_domain_by_uuid($uuid); - $boolRunning = $lv->domain_get_state($dom)=='running'; - $strXML = $lv->domain_get_xml($dom); - $boolNew = false; - $arrConfig = array_replace_recursive($arrConfigDefaults, domain_to_config($uuid)); - $arrVMUSBs = getVMUSBs($strXML) ; - } else { - // edit new VM - $boolRunning = false; - $strXML = ''; - $boolNew = true; - $arrConfig = $arrConfigDefaults; - $arrVMUSBs = getVMUSBs($strXML) ; - } - - if (array_key_exists($arrConfig['template']['openelec'], $arrLibreELECVersions)) { - $arrConfigDefaults['disk'][0]['image'] = $arrLibreELECVersions[$arrConfig['template']['openelec']]['localpath']; - } -?> - - - - - -
- - - - - - - - - - - -
- - - - - -
_(Name)_:
-
-

Give the VM a name (e.g. OpenELEC Family Room, OpenELEC Theatre, OpenELEC)

-
- - - - - - -
_(Description)_:
-
-
-

Give the VM a brief description (optional field).

-
-
-
- - - - - - -
_(OpenELEC Version)_: - -
-
-

Select which OpenELEC version to download or use for this VM

-
- -
- - - - - -
_(Download Folder)_: - -
-
-

Choose a folder where the OpenELEC image will downloaded to

-
- - - - - - -
- -
-
- -
- - - - - -
_(Config Folder)_: - - -
-
-

Choose a folder or type in a new name off of an existing folder to specify where OpenELEC will save configuration files. If you create multiple OpenELEC VMs, these Config Folders must be unique for each instance.

-
- - - - - - -
_(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)_: -
- 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)_: - - - >_(Enable USB boot)_: - - -
-
-
-

- 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. -

-

- USB Boot
- Adds support for booting from USB devices using UEFI. No device boot orders can be specified at the same time as this option.
-

-
-
- - - - - - -
_(USB Controller)_: - -
-
-
-

- USB Controller
- Select the USB Controller to emulate. 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. -

-
-
- - $arrGPU) { - $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : ''; - - ?> - - - - - - - - - - - - - - - - - - - -
_(Graphics Card)_: - -
_(VM Console Protocol)_: - -
_(VM Console AutoPort)_: - - - >_(VM Console Port)_: - - > - - >_(VM Console WS Port)_: - - > -
_(Graphics ROM BIOS)_: - -
- -
-

- Graphics Card
- If you wish to assign a graphics card to the VM, select it from this list. -

- - Graphics Card
- If you wish to assign a graphics card to the VM, select it from this list, otherwise leave it set to virtual. -

- -

- virtual video protocol VDC/SPICE
- If you wish to assign a protocol type, specify one here. -

- -

- virtual auto port
- Set it you want to specify a manual port for VNC or Spice. VNC needs two ports where Spice only requires one. Leave as auto yes for the system to set. -

- -

- Graphics ROM BIOS
- If you wish to use a custom ROM BIOS for a Graphics card, specify one here. -

- - 1) {?> -

Additional devices can be added/removed by clicking the symbols to the left.

- -
- - - - - $arrAudio) { - $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : ''; - - ?> - - - - - -
_(Sound Card)_: - -
- -
-

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.

- 1) {?> -

Additional devices can be added/removed by clicking the symbols to the left.

- -
- - - - - $domain_bridge, - 'mac' => "", - 'model' => 'virtio-net' - ] ; - } - foreach ($arrConfig['nic'] as $i => $arrNic) { - $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : ''; - - ?> - - - - - - - - - - - - - - - - - -
_(Network MAC)_: - -
_(Network Source)_: - -
_(Network Model)_: - -
_(Boot Order)_: - style="width: 50px;" name="nic[][boot]" title="_(Boot order)_" value="" > -
- -
-
-

- 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 Source
- The default libvirt managed network bridge (virbr0) will be used, otherwise you may specify an alternative name for a private network to the host. -

- -

- Network Model
- Default and recommended is 'virtio-net', which gives improved stability. To improve performance 'virtio' can be selected, but this may lead to stability issues. -

- -

Use boot order to set device as bootable and boot sequence.

- -

Additional devices can be added/removed by clicking the symbols to the left.

-
-
- - - - - - - - - - - - -
_(Select)_  _(Optional)_  _(Boot Order)_
_(USB Devices)_: -
- $arrDev) { - ?> -
- "._('None available').""; - } - ?> -
-
-
-

If you wish to assign any USB devices to your guest, you can select them from this list.

-

Use boot order to set device as bootable and boot sequence.

-

Select optional if you want device to be ignored when VM starts if not present.

-
- - - - - - - - - -
_(Select)_  _(Boot Order)_
_(Other PCI Devices)_: -
- $arrDev) { - $bootdisable = $extra = $pciboot = ''; - if ($arrDev["typeid"] != "0108") $bootdisable = ' disabled="disabled"' ; - if (count($pcidevice=array_filter($arrConfig['pci'], function($arr) use ($arrDev) { return ($arr['id'] == $arrDev['id']); }))) { - $extra .= ' checked="checked"'; - foreach ($pcidevice as $pcikey => $pcidev) $pciboot = $pcidev["boot"]; ; - - } elseif (!in_array($arrDev['driver'], ['pci-stub', 'vfio-pci'])) { - //$extra .= ' disabled="disabled"'; - continue; - } - $intAvailableOtherPCIDevices++; - ?> -
- "._('None available').""; - } - ?> -
-
-
-

If you wish to assign any other PCI devices to your guest, you can select them from this list.

-

Use boot order to set device as bootable and boot sequence. Only NVMe devices (PCI types 0108) supported for boot order.

-
- - - - - - -
- - - - - -
- - - - -
- -
-

Click Create to return to the Virtual Machines page where your new VM will be created.

-
- -
-
- -
- - - - - - - -
- - - - - - -
- - - - - - - -
-
- - - - - - - - -