diff --git a/emhttp/plugins/dynamix.vm.manager/include/libvirt.php b/emhttp/plugins/dynamix.vm.manager/include/libvirt.php
index 288c1a75e..c28842002 100644
--- a/emhttp/plugins/dynamix.vm.manager/include/libvirt.php
+++ b/emhttp/plugins/dynamix.vm.manager/include/libvirt.php
@@ -1,5 +1,6 @@
- class Libvirt {
- private $conn;
- private $last_error;
- private $allow_cached = true;
- private $dominfos = [];
- private $enabled = false;
+class Libvirt {
+ private $conn;
+ private $last_error;
+ private $allow_cached = true;
+ private $dominfos = [];
+ private $enabled = false;
- function Libvirt($uri = false, $login = false, $pwd = false, $debug=false) {
- if ($debug)
- $this->set_logfile($debug);
- if ($uri != false) {
- $this->enabled = $this->connect($uri, $login, $pwd);
- }
+ function Libvirt($uri = false, $login = false, $pwd = false, $debug=false) {
+ if ($debug)
+ $this->set_logfile($debug);
+ if ($uri != false) {
+ $this->enabled = $this->connect($uri, $login, $pwd);
}
+ }
- function __construct($uri = false, $login = false, $pwd = false, $debug=false) {
- if ($debug)
- $this->set_logfile($debug);
- if ($uri != false) {
- $this->enabled = $this->connect($uri, $login, $pwd);
- }
+ function __construct($uri = false, $login = false, $pwd = false, $debug=false) {
+ if ($debug)
+ $this->set_logfile($debug);
+ if ($uri != false) {
+ $this->enabled = $this->connect($uri, $login, $pwd);
}
+ }
- function _set_last_error() {
- $this->last_error = libvirt_get_last_error();
+ function _set_last_error() {
+ $this->last_error = libvirt_get_last_error();
+ return false;
+ }
+
+ function enabled() {
+ return $this->enabled;
+ }
+
+ function set_logfile($filename) {
+ if (!libvirt_logfile_set($filename,10000))
+ return $this->_set_last_error();
+ return true;
+ }
+
+ function get_capabilities() {
+ $tmp = libvirt_connect_get_capabilities($this->conn);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function get_domain_capabilities($emulatorbin, $arch, $machine, $virttype, $xpath) {
+
+ #@conn [resource]: resource for connection
+ #@emulatorbin [string]: optional path to emulator
+ #@arch [string]: optional domain architecture
+ #@machine [string]: optional machine type
+ #@virttype [string]: optional virtualization type
+ #@flags [int] : extra flags; not used yet, so callers should always pass 0
+ #@xpath [string]: optional xPath query to be applied on the result
+ #Returns: : domain capabilities XML from the connection or FALSE for error
+
+ $tmp = libvirt_connect_get_domain_capabilities($this->conn, $emulatorbin, $arch, $machine, $virttype, 0, $xpath);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function get_machine_types($arch = 'x86_64' /* or 'i686' */) {
+ $tmp = libvirt_connect_get_machine_types($this->conn);
+ if (!$tmp)
+ return $this->_set_last_error();
+
+ if (empty($tmp[$arch])) {
+ return [];
+ }
+ return $tmp[$arch];
+ }
+
+ function get_default_emulator() {
+ $tmp = libvirt_connect_get_capabilities($this->conn, '//capabilities/guest/arch/domain/emulator');
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function set_folder_nodatacow($folder) {
+ if (!is_dir($folder)) {
return false;
}
- function enabled() {
- return $this->enabled;
+ $folder = transpose_user_path($folder);
+
+ #@shell_exec("chattr +C -R ".escapeshellarg($folder)." &>/dev/null");
+ return true;
+ }
+
+ function create_disk_image($disk, $vmname = '', $diskid = 1) {
+ $arrReturn = [];
+
+ if (!empty($disk['size'])) {
+ $disk['size'] = str_replace(["KB","MB","GB","TB","PB"], ["K","M","G","T","P"], strtoupper($disk['size']));
+ }
+ if (empty($disk['driver'])) {
+ $disk['driver'] = 'raw';
}
- function set_logfile($filename) {
- if (!libvirt_logfile_set($filename,10000))
- return $this->_set_last_error();
+ // if new is a folder then
+ // if existing then
+ // create folder 'new/vmname'
+ // create image file as new/vmname/vdisk[1-x].xxx
+ // if doesn't exist then
+ // create folder 'new'
+ // create image file as new/vdisk[1-x].xxx
- return true;
+ // if new is a file then
+ // if existing then
+ // nothing to do
+ // if doesn't exist then
+ // create folder dirname('new') if needed
+ // create image file as new --> if size is specified
+
+ if (!empty($disk['new'])) {
+ if (is_file($disk['new']) || is_block($disk['new'])) {
+ $disk['image'] = $disk['new'];
+ }
}
- function get_capabilities() {
- $tmp = libvirt_connect_get_capabilities($this->conn);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
+ if (!empty($disk['image'])) {
+ // Use existing disk image
- function get_domain_capabilities($emulatorbin, $arch, $machine, $virttype, $xpath) {
-
- #@conn [resource]: resource for connection
- #@emulatorbin [string]: optional path to emulator
- #@arch [string]: optional domain architecture
- #@machine [string]: optional machine type
- #@virttype [string]: optional virtualization type
- #@flags [int] : extra flags; not used yet, so callers should always pass 0
- #@xpath [string]: optional xPath query to be applied on the result
- #Returns: : domain capabilities XML from the connection or FALSE for error
-
- $tmp = libvirt_connect_get_domain_capabilities($this->conn, $emulatorbin, $arch, $machine, $virttype, 0, $xpath);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
-
- function get_machine_types($arch = 'x86_64' /* or 'i686' */) {
- $tmp = libvirt_connect_get_machine_types($this->conn);
-
- if (!$tmp)
- return $this->_set_last_error();
-
- if (empty($tmp[$arch]))
- return [];
-
- return $tmp[$arch];
- }
-
- function get_default_emulator() {
- $tmp = libvirt_connect_get_capabilities($this->conn, '//capabilities/guest/arch/domain/emulator');
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function set_folder_nodatacow($folder) {
- if (!is_dir($folder)) {
- return false;
+ if (is_block($disk['image'])) {
+ // Valid block device, return as-is
+ return $disk;
}
- $folder = transpose_user_path($folder);
+ if (is_file($disk['image'])) {
+ $json_info = getDiskImageInfo($disk['image']);
+ $disk['driver'] = $json_info['format'];
- #@shell_exec("chattr +C -R " . escapeshellarg($folder) . " &>/dev/null");
+ if (!empty($disk['size'])) {
+ //TODO: expand disk image if size param is larger
+ }
- return true;
+ return $disk;
+ }
+
+ $disk['new'] = $disk['image'];
}
- function create_disk_image($disk, $vmname = '', $diskid = 1) {
- $arrReturn = [];
+ if (!empty($disk['new'])) {
+ // Create new disk image
+ $strImgFolder = $disk['new'];
+ $strImgPath = '';
- if (!empty($disk['size'])) {
- $disk['size'] = str_replace(["KB","MB","GB","TB","PB"], ["K","M","G","T","P"], strtoupper($disk['size']));
- }
- if (empty($disk['driver'])) {
- $disk['driver'] = 'raw';
+ if (strpos($strImgFolder, '/dev/') === 0) {
+ // ERROR invalid block device
+ $arrReturn = [
+ 'error' => "Not a valid block device location '".$strImgFolder."'"
+ ];
+ return $arrReturn;
}
- // if new is a folder then
- // if existing then
- // create folder 'new/vmname'
- // create image file as new/vmname/vdisk[1-x].xxx
- // if doesn't exist then
- // create folder 'new'
- // create image file as new/vdisk[1-x].xxx
-
- // if new is a file then
- // if existing then
- // nothing to do
- // if doesn't exist then
- // create folder dirname('new') if needed
- // create image file as new --> if size is specified
-
- if (!empty($disk['new'])) {
- if (is_file($disk['new']) || is_block($disk['new'])) {
- $disk['image'] = $disk['new'];
- }
+ if (empty($disk['size'])) {
+ // ERROR invalid disk size
+ $arrReturn = [
+ 'error' => "Please specify a disk size for '".$strImgFolder."'"
+ ];
+ return $arrReturn;
}
- if (!empty($disk['image'])) {
- // Use existing disk image
+ $path_parts = pathinfo($strImgFolder);
+ if (empty($path_parts['extension'])) {
+ // 'new' is a folder
- if (is_block($disk['image'])) {
- // Valid block device, return as-is
- return $disk;
+ if (substr($strImgFolder, -1) != '/') {
+ $strImgFolder .= '/';
}
- if (is_file($disk['image'])) {
- $json_info = getDiskImageInfo($disk['image']);
- $disk['driver'] = $json_info['format'];
-
- if (!empty($disk['size'])) {
- //TODO: expand disk image if size param is larger
- }
-
- return $disk;
+ if (is_dir($strImgFolder)) {
+ // 'new' is a folder and already exists, append vmname folder
+ $strImgFolder .= preg_replace('((^\.)|\/|(\.$))', '_', $vmname).'/';
}
- $disk['new'] = $disk['image'];
+ // create folder if needed
+ if (!is_dir($strImgFolder)) {
+ #mkdir($strImgFolder, 0777, true);
+ my_mkdir($strImgFolder, 0777, true);
+ #chown($strImgFolder, 'nobody');
+ #chgrp($strImgFolder, 'users');
+ }
+
+ $this->set_folder_nodatacow($strImgFolder);
+
+ $strExt = ($disk['driver'] == 'raw') ? 'img' : $disk['driver'];
+
+ $strImgPath = $strImgFolder.'vdisk'.$diskid.'.'.$strExt;
+
+ } else {
+ // 'new' is a file
+
+ // create parent folder if needed
+ if (!is_dir($path_parts['dirname'])) {
+ #mkdir($path_parts['dirname'], 0777, true);
+ my_mkdir($path_parts['dirname'], 0777, true);
+ #chown($path_parts['dirname'], 'nobody');
+ #chgrp($path_parts['dirname'], 'users');
+ }
+
+ $this->set_folder_nodatacow($path_parts['dirname']);
+
+ $strExt = ($disk['driver'] == 'raw') ? 'img' : $disk['driver'];
+ $strImgPath = $path_parts['dirname'].'/vdisk'.$diskid.'.'.$strExt;
}
- if (!empty($disk['new'])) {
- // Create new disk image
- $strImgFolder = $disk['new'];
- $strImgPath = '';
-
- if (strpos($strImgFolder, '/dev/') === 0) {
- // ERROR invalid block device
- $arrReturn = [
- 'error' => "Not a valid block device location '" . $strImgFolder . "'"
- ];
-
- return $arrReturn;
- }
-
- if (empty($disk['size'])) {
- // ERROR invalid disk size
- $arrReturn = [
- 'error' => "Please specify a disk size for '" . $strImgFolder . "'"
- ];
-
- return $arrReturn;
- }
-
- $path_parts = pathinfo($strImgFolder);
- if (empty($path_parts['extension'])) {
- // 'new' is a folder
-
- if (substr($strImgFolder, -1) != '/') {
- $strImgFolder .= '/';
- }
-
- if (is_dir($strImgFolder)) {
- // 'new' is a folder and already exists, append vmname folder
- $strImgFolder .= preg_replace('((^\.)|\/|(\.$))', '_', $vmname) . '/';
- }
+ if (is_file($strImgPath)) {
+ $json_info = getDiskImageInfo($strImgPath);
+ $disk['driver'] = $json_info['format'];
+ $return_value = 0;
+ } else {
+ $strImgRawLocationPath = $strImgPath;
+ if (!empty($disk['storage']) && !empty($disk['select']) && $disk['select'] == 'auto' && $disk['storage'] != "default") $disk['select'] = $disk['storage'];
+ if (!empty($disk['select']) && (!in_array($disk['select'], ['auto', 'manual'])) && (is_dir('/mnt/'.$disk['select']))) {
+ // Force qemu disk creation to happen directly on either cache/disk1/disk2 ect based on dropdown selection
+ $strImgRawLocationPath = str_replace('/mnt/user/', '/mnt/'.$disk['select'].'/', $strImgPath);
// create folder if needed
- if (!is_dir($strImgFolder)) {
- #mkdir($strImgFolder, 0777, true);
- my_mkdir($strImgFolder, 0777, true);
- #chown($strImgFolder, 'nobody');
- #chgrp($strImgFolder, 'users');
+ $strImgRawLocationParent = dirname($strImgRawLocationPath);
+ if (!is_dir($strImgRawLocationParent)) {
+ #mkdir($strImgRawLocationParent, 0777, true);
+ my_mkdir($strImgRawLocationParent, 0777, true);
+ #chown($strImgRawLocationParent, 'nobody');
+ #chgrp($strImgRawLocationParent, 'users');
}
- $this->set_folder_nodatacow($strImgFolder);
-
- $strExt = ($disk['driver'] == 'raw') ? 'img' : $disk['driver'];
-
- $strImgPath = $strImgFolder . 'vdisk' . $diskid . '.' . $strExt;
-
- } else {
- // 'new' is a file
-
- // create parent folder if needed
- if (!is_dir($path_parts['dirname'])) {
- #mkdir($path_parts['dirname'], 0777, true);
- my_mkdir($path_parts['dirname'], 0777, true);
- #chown($path_parts['dirname'], 'nobody');
- #chgrp($path_parts['dirname'], 'users');
- }
-
- $this->set_folder_nodatacow($path_parts['dirname']);
-
- $strExt = ($disk['driver'] == 'raw') ? 'img' : $disk['driver'];
- $strImgPath = $path_parts['dirname'] . '/vdisk' . $diskid . '.' . $strExt;
+ $this->set_folder_nodatacow($strImgRawLocationParent);
}
+ $strLastLine = exec("qemu-img create -q -f ".escapeshellarg($disk['driver'])." ".escapeshellarg($strImgRawLocationPath)." ".escapeshellarg($disk['size'])." 2>&1", $output, $return_value);
if (is_file($strImgPath)) {
- $json_info = getDiskImageInfo($strImgPath);
- $disk['driver'] = $json_info['format'];
- $return_value = 0;
- } else {
- $strImgRawLocationPath = $strImgPath;
- if (!empty($disk['storage']) && !empty($disk['select']) && $disk['select'] == 'auto' && $disk['storage'] != "default") $disk['select'] = $disk['storage'];
- if (!empty($disk['select']) && (!in_array($disk['select'], ['auto', 'manual'])) && (is_dir('/mnt/'.$disk['select']))) {
- // Force qemu disk creation to happen directly on either cache/disk1/disk2 ect based on dropdown selection
- $strImgRawLocationPath = str_replace('/mnt/user/', '/mnt/'.$disk['select'].'/', $strImgPath);
-
- // create folder if needed
- $strImgRawLocationParent = dirname($strImgRawLocationPath);
- if (!is_dir($strImgRawLocationParent)) {
- #mkdir($strImgRawLocationParent, 0777, true);
- my_mkdir($strImgRawLocationParent, 0777, true);
- #chown($strImgRawLocationParent, 'nobody');
- #chgrp($strImgRawLocationParent, 'users');
- }
-
- $this->set_folder_nodatacow($strImgRawLocationParent);
- }
-
- $strLastLine = exec("qemu-img create -q -f ".escapeshellarg($disk['driver'])." ".escapeshellarg($strImgRawLocationPath)." ".escapeshellarg($disk['size'])." 2>&1", $output, $return_value);
-
- if (is_file($strImgPath)) {
- chmod($strImgPath, 0777);
- chown($strImgPath, 'nobody');
- chgrp($strImgPath, 'users');
- }
- }
-
- if ($return_value != 0) {
-
- // ERROR during image creation, return message to user
- $arrReturn = [
- 'error' => "Error creating disk image '" . $strImgPath . "': " . $strLastLine,
- 'error_output' => $output
- ];
-
- } else {
-
- // Success!
- $arrReturn = [
- 'image' => $strImgPath,
- 'driver' => $disk['driver']
- ];
- if (!empty($disk['dev'])) {
- $arrReturn['dev'] = $disk['dev'];
- }
- if (!empty($disk['bus'])) {
- $arrReturn['bus'] = $disk['bus'];
- }
- if (!empty($disk['boot'])) {
- $arrReturn['boot'] = $disk['boot'];
- }
- if (!empty($disk['rotation'])) {
- $arrReturn['rotation'] = $disk['rotation'];
- }
- if (!empty($disk['serial'])) {
- $arrReturn['serial'] = $disk['serial'];
- }
- if (!empty($disk['discard'])) {
- $arrReturn['discard'] = $disk['discard'];
- }
-
+ chmod($strImgPath, 0777);
+ chown($strImgPath, 'nobody');
+ chgrp($strImgPath, 'users');
}
}
- return $arrReturn;
+ if ($return_value != 0) {
+
+ // ERROR during image creation, return message to user
+ $arrReturn = [
+ 'error' => "Error creating disk image '".$strImgPath."': ".$strLastLine,
+ 'error_output' => $output
+ ];
+
+ } else {
+
+ // Success!
+ $arrReturn = [
+ 'image' => $strImgPath,
+ 'driver' => $disk['driver']
+ ];
+ if (!empty($disk['dev'])) {
+ $arrReturn['dev'] = $disk['dev'];
+ }
+ if (!empty($disk['bus'])) {
+ $arrReturn['bus'] = $disk['bus'];
+ }
+ if (!empty($disk['boot'])) {
+ $arrReturn['boot'] = $disk['boot'];
+ }
+ if (!empty($disk['rotation'])) {
+ $arrReturn['rotation'] = $disk['rotation'];
+ }
+ if (!empty($disk['serial'])) {
+ $arrReturn['serial'] = $disk['serial'];
+ }
+ if (!empty($disk['discard'])) {
+ $arrReturn['discard'] = $disk['discard'];
+ }
+
+ }
}
+ return $arrReturn;
+ }
+ function config_to_xml($config,$vmclone = false) {
+ $domain = $config['domain'];
+ $media = $config['media'];
+ $nics = $config['nic'];
+ $disks = $config['disk'];
+ $usb = $config['usb'];
+ $usbopt = $config['usbopt'];
+ $usbboot = $config['usbboot'];
+ $shares = $config['shares'];
+ $gpus = $config['gpu'];
+ $pcis = $config['pci'];
+ $pciboot = $config['pciboot'];
+ $audios = $config['audio'];
+ $template = $config['template'];
+ $clocks = $config['clock'];
+ $evdevs = $config['evdev'];
- function config_to_xml($config,$vmclone = false) {
- $domain = $config['domain'];
- $media = $config['media'];
- $nics = $config['nic'];
- $disks = $config['disk'];
- $usb = $config['usb'];
- $usbopt = $config['usbopt'];
- $usbboot = $config['usbboot'];
- $shares = $config['shares'];
- $gpus = $config['gpu'];
- $pcis = $config['pci'];
- $pciboot = $config['pciboot'];
- $audios = $config['audio'];
- $template = $config['template'];
- $clocks = $config['clock'];
- $evdevs = $config['evdev'];
+ $type = $domain['type'];
+ $name = $domain['name'];
+ $mem = $domain['mem'];
+ $maxmem = (!empty($domain['maxmem'])) ? $domain['maxmem'] : $mem;
+ $uuid = (!empty($domain['uuid']) ? $domain['uuid'] : $this->domain_generate_uuid());
+ $machine = $domain['machine'];
+ $machine_type = (stripos($machine, 'q35') !== false ? 'q35' : 'pc');
+ $os_type = ((empty($template['os']) || stripos($template['os'], 'windows') === false) ? 'other' : 'windows');
+ //$emulator = $this->get_default_emulator();
+ $emulator = '/usr/local/sbin/qemu';
+ $arch = $domain['arch'];
+ $pae = ($arch == 'i686') ? '' : '';
- $type = $domain['type'];
- $name = $domain['name'];
- $mem = $domain['mem'];
- $maxmem = (!empty($domain['maxmem'])) ? $domain['maxmem'] : $mem;
- $uuid = (!empty($domain['uuid']) ? $domain['uuid'] : $this->domain_generate_uuid());
- $machine = $domain['machine'];
- $machine_type = (stripos($machine, 'q35') !== false ? 'q35' : 'pc');
- $os_type = ((empty($template['os']) || stripos($template['os'], 'windows') === false) ? 'other' : 'windows');
- //$emulator = $this->get_default_emulator();
- $emulator = '/usr/local/sbin/qemu';
- $arch = $domain['arch'];
- $pae = ($arch == 'i686') ? '' : '';
-
- $loader = '';
- $swtpm = '';
- $osbootdev = '';
- if (!empty($domain['ovmf'])) {
- if ($domain['ovmf'] == 1) {
- if (!is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd')) {
- // Create a new copy of OVMF VARS for this VM
- mkdir('/etc/libvirt/qemu/nvram/', 0777, true);
- copy('/usr/share/qemu/ovmf-x64/OVMF_VARS-pure-efi.fd', '/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd');
- }
+ $loader = '';
+ $swtpm = '';
+ $osbootdev = '';
+ if (!empty($domain['ovmf'])) {
+ if ($domain['ovmf'] == 1) {
+ if (!is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd')) {
+ // Create a new copy of OVMF VARS for this VM
+ mkdir('/etc/libvirt/qemu/nvram/', 0777, true);
+ copy('/usr/share/qemu/ovmf-x64/OVMF_VARS-pure-efi.fd', '/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd');
+ }
if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd')) {
// Delete OVMF-TPM VARS for this VM if found
unlink('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd');
- }
+ }
- $loader = "/usr/share/qemu/ovmf-x64/OVMF_CODE-pure-efi.fd
- /etc/libvirt/qemu/nvram/".$uuid."_VARS-pure-efi.fd";
- if ($domain['usbboot'] == 'Yes') $osbootdev = "" ;
- }
- if ($domain['ovmf'] == 2) {
- if (!is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd')) {
- // Create a new copy of OVMF VARS for this VM
- mkdir('/etc/libvirt/qemu/nvram/', 0777, true);
- copy('/usr/share/qemu/ovmf-x64/OVMF_VARS-pure-efi-tpm.fd', '/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd');
- }
+ $loader = "/usr/share/qemu/ovmf-x64/OVMF_CODE-pure-efi.fd
+ /etc/libvirt/qemu/nvram/".$uuid."_VARS-pure-efi.fd";
+ if ($domain['usbboot'] == 'Yes') $osbootdev = "";
+ }
+ if ($domain['ovmf'] == 2) {
+ if (!is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd')) {
+ // Create a new copy of OVMF VARS for this VM
+ mkdir('/etc/libvirt/qemu/nvram/', 0777, true);
+ copy('/usr/share/qemu/ovmf-x64/OVMF_VARS-pure-efi-tpm.fd', '/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd');
+ }
if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd')) {
// Delete OVMF VARS for this VM if found
unlink('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd');
- }
+ }
- $loader = "/usr/share/qemu/ovmf-x64/OVMF_CODE-pure-efi-tpm.fd
- /etc/libvirt/qemu/nvram/".$uuid."_VARS-pure-efi-tpm.fd";
+ $loader = "/usr/share/qemu/ovmf-x64/OVMF_CODE-pure-efi-tpm.fd
+ /etc/libvirt/qemu/nvram/".$uuid."_VARS-pure-efi-tpm.fd";
$swtpm = "
-
- ";
- if ($domain['usbboot'] == 'Yes') $osbootdev = "" ;
- }
- }
+
+ ";
+ if ($domain['usbboot'] == 'Yes') $osbootdev = "";
+ }
+ }
+ $metadata = '';
+ if (!empty($template)) {
+ $metadata .= "";
+ $template_options = '';
+ foreach ($template as $key => $value) {
+ $template_options .= $key."='".htmlspecialchars($value, ENT_QUOTES | ENT_XML1)."' ";
+ }
+ $metadata .= "";
+ $metadata .= "";
+ }
- $metadata = '';
- if (!empty($template)) {
- $metadata .= "";
- $template_options = '';
- foreach ($template as $key => $value) {
- $template_options .= $key . "='" . htmlspecialchars($value, ENT_QUOTES | ENT_XML1) . "' ";
+ $vcpus = $domain['vcpus'];
+ $vcpupinstr = '';
+
+ if (!empty($domain['vcpu']) && is_array($domain['vcpu'])) {
+ $vcpus = count($domain['vcpu']);
+ foreach($domain['vcpu'] as $i => $vcpu) {
+ $vcpupinstr .= "";
+ }
+ }
+
+ $intCores = $vcpus;
+ $intThreads = 1;
+ $intCPUThreadsPerCore = 1;
+
+ $cpumode = '';
+ $cpucache = '';
+ $cpufeatures = '';
+ $cpumigrate = '';
+ $cpucheck = '';
+ $cpumatch = '';
+ $cpucustom = '';
+ $cpufallback = '';
+ if (!empty($domain['cpumode']) && $domain['cpumode'] == 'host-passthrough') {
+ $cpumode .= "mode='host-passthrough'";
+ $cpucache = "";
+
+ // detect if the processor is hyperthreaded:
+ $intCPUThreadsPerCore = max(intval(shell_exec('/usr/bin/lscpu | grep \'Thread(s) per core\' | awk \'{print $4}\'')), 1);
+
+ // detect if the processor is AMD + multithreaded, and if so, enable topoext cpu feature
+ if ($intCPUThreadsPerCore > 1) {
+ $strCPUInfo = file_get_contents('/proc/cpuinfo');
+ if (strpos($strCPUInfo, 'AuthenticAMD') !== false) {
+ $cpufeatures .= "";
}
- $metadata .= "";
- $metadata .= "";
}
- $vcpus = $domain['vcpus'];
- $vcpupinstr = '';
-
- if (!empty($domain['vcpu']) && is_array($domain['vcpu'])) {
- $vcpus = count($domain['vcpu']);
- foreach($domain['vcpu'] as $i => $vcpu) {
- $vcpupinstr .= "";
- }
- }
-
- $intCores = $vcpus;
- $intThreads = 1;
- $intCPUThreadsPerCore = 1;
-
- $cpumode = '';
- $cpucache = '';
- $cpufeatures = '';
- $cpumigrate = '';
- $cpucheck = '';
- $cpumatch = '' ;
- $cpucustom = '' ;
- $cpufallback = '' ;
- if (!empty($domain['cpumode']) && $domain['cpumode'] == 'host-passthrough') {
- $cpumode .= "mode='host-passthrough'";
- $cpucache = "";
-
- // detect if the processor is hyperthreaded:
- $intCPUThreadsPerCore = max(intval(shell_exec('/usr/bin/lscpu | grep \'Thread(s) per core\' | awk \'{print $4}\'')), 1);
-
- // detect if the processor is AMD + multithreaded, and if so, enable topoext cpu feature
- if ($intCPUThreadsPerCore > 1) {
- $strCPUInfo = file_get_contents('/proc/cpuinfo');
- if (strpos($strCPUInfo, 'AuthenticAMD') !== false) {
- $cpufeatures .= "";
- }
- }
-
- // even amount of cores assigned and cpu is hyperthreaded: pass that info along to the cpu section below
- if ($intCPUThreadsPerCore > 1 && ($vcpus % $intCPUThreadsPerCore == 0)) {
- $intCores = $vcpus / $intCPUThreadsPerCore;
- $intThreads = $intCPUThreadsPerCore;
- }
-
- if (!empty($domain['cpumigrate'])) $cpumigrate = " migratable='".$domain['cpumigrate']."'" ;
- }
- #
- #Skylake-Client-noTSX-IBRS
-
- $cpustr = "
-
- $cpucache
- $cpufeatures
-
- {$vcpus}
-
- $vcpupinstr
- ";
-
- $usbmode = 'usb3';
- if (!empty($domain['usbmode'])) {
- $usbmode = $domain['usbmode'];
+ // even amount of cores assigned and cpu is hyperthreaded: pass that info along to the cpu section below
+ if ($intCPUThreadsPerCore > 1 && ($vcpus % $intCPUThreadsPerCore == 0)) {
+ $intCores = $vcpus / $intCPUThreadsPerCore;
+ $intThreads = $intCPUThreadsPerCore;
}
- $ctrl = '';
- switch ($usbmode) {
- case 'usb3':
- $ctrl = "
-
- ";
- break;
+ if (!empty($domain['cpumigrate'])) $cpumigrate = " migratable='".$domain['cpumigrate']."'";
+ }
+ #
+ #Skylake-Client-noTSX-IBRS
- case 'usb3-qemu':
- $ctrl = "
-
- ";
- break;
+ $cpustr = "
+
+ $cpucache
+ $cpufeatures
+
+ {$vcpus}
+
+ $vcpupinstr
+ ";
- case 'usb2':
- $ctrl = "
-
-
-
-
-
-
-
-
-
-
-
-
-
- ";
- break;
- }
+ $usbmode = 'usb3';
+ if (!empty($domain['usbmode'])) {
+ $usbmode = $domain['usbmode'];
+ }
- /*
- if ($os_type == "windows") $hypervclock = "" ; else $hypervclock = "" ;
+ $ctrl = '';
+ switch ($usbmode) {
+ case 'usb3':
+ $ctrl = "
+
+ ";
+ break;
- $clock = "
-
-
+ case 'usb3-qemu':
+ $ctrl = "
+
+ ";
+ break;
+
+ case 'usb2':
+ $ctrl = "
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ";
+ break;
+ }
+
+ /*
+ if ($os_type == "windows") $hypervclock = ""; else $hypervclock = "";
+
+ $clock = "
+
+
+
+ $hypervclock
+ ";
+
+ $hyperv = '';
+ if ($domain['hyperv'] == 1 && $os_type == "windows") {
+ $hyperv = "
+
+
+
+
+ ";
+
+ $clock = "
+
- $hypervclock
";
+ }
+ */
- $hyperv = '';
- if ($domain['hyperv'] == 1 && $os_type == "windows") {
- $hyperv = "
-
-
-
-
- ";
-
- $clock = "
-
-
- ";
+ $clock = "";
+ foreach ($clocks as $clockname => $clockvalues) {
+ switch ($clockname){
+ case "rtc":
+ if ($clockvalues['present'] == "yes") $clock .= "";
+ break;
+ case "pit":
+ if ($clockvalues['present'] == "yes") $clock .= "";
+ break;
+ case "hpet":
+ $clock .= "";
+ break;
+ case "hypervclock":
+ $clock .= "";
+ break;
}
- */
+ }
+ $hyperv = "";
+ if ($domain['hyperv'] == 1 && $os_type == "windows") {
+ $hyperv = "
+
+
+
+ ";
- $clock = "" ;
- foreach ($clocks as $clockname => $clockvalues) {
- switch ($clockname){
- case "rtc":
- if ($clockvalues['present'] == "yes") $clock .= "";
- break ;
- case "pit":
- if ($clockvalues['present'] == "yes") $clock .= "";
- break ;
- case "hpet":
- $clock .= "" ;
- break ;
- case "hypervclock":
- $clock .= "" ;
- break ;
+ if ($clocks['hypervclock']['present'] == "yes") {
+ $hyperv .= "";
+ }
+ $hyperv .="";
+ # $clock = "
+ #
+ # ";
+ }
+ $clock .= "";
+
+ $usbstr = '';
+ if (!empty($usb)) {
+ foreach($usb as $i => $v){
+ if ($vmclone) $usbx = explode(':', $v['id']); else $usbx = explode(':', $v);
+ $startupPolicy = '';
+ if (isset($usbopt[$v]) && !$vmclone ) {
+ if (strpos($usbopt[$v], "#remove") == false) $startupPolicy = 'startupPolicy="optional"'; else $startupPolicy = '';
}
- }
- $hyperv = "" ;
- if ($domain['hyperv'] == 1 && $os_type == "windows") {
- $hyperv = "
-
-
-
-
- ";
-
- if ($clocks['hypervclock']['present'] == "yes")
- $hyperv .= "" ;
- $hyperv .="";
- #$clock = "
- #
- # ";
- }
- $clock .= "" ;
-
- $usbstr = '';
- if (!empty($usb)) {
- foreach($usb as $i => $v){
- if ($vmclone) $usbx = explode(':', $v['id']); else $usbx = explode(':', $v);
- $startupPolicy = '' ;
- if (isset($usbopt[$v]) && !$vmclone ) {
- if (strpos($usbopt[$v], "#remove") == false) $startupPolicy = 'startupPolicy="optional"' ; else $startupPolicy = '' ;
- }
- if (isset($v["startupPolicy"]) && $vmclone ) {
- if ($v["startupPolicy"] == "optional" ) $startupPolicy = 'startupPolicy="optional"' ; else $startupPolicy = '' ;
- }
-
- $usbstr .= "
-
-
-
- " ;
- if (!empty($usbboot[$v]) && !$vmclone ) {
- $usbstr .= "" ;
- }
- if (isset($v["usbboot"]) && $vmclone ) {
- if ($v["usbboot"] != NULL) $usbstr .= "" ;
- }
- $usbstr .= "";
+ if (isset($v["startupPolicy"]) && $vmclone ) {
+ if ($v["startupPolicy"] == "optional" ) $startupPolicy = 'startupPolicy="optional"'; else $startupPolicy = '';
}
- }
- $arrAvailableDevs = [];
- foreach (range('a', 'z') as $letter) {
- $arrAvailableDevs['hd' . $letter] = 'hd' . $letter;
- }
+ $usbstr .= "
+
+
+
+ ";
- $needSCSIController = false;
-
- //media settings
- $bus = "ide";
- if ($machine_type == 'q35'){
- $bus = "sata";
- }
-
- $mediastr = '';
- if (!empty($media['cdrom'])) {
- unset($arrAvailableDevs['hda']);
- $cdromboot = $media['cdromboot'] ;
- $media['cdrombus'] = $media['cdrombus'] ?: $bus;
- if ($media['cdrombus'] == 'scsi') {
- $needSCSIController = true;
+ if (!empty($usbboot[$v]) && !$vmclone ) {
+ $usbstr .= "";
}
- if ($cdromboot > 0) {
- $mediaboot = "" ;
+ if (isset($v["usbboot"]) && $vmclone ) {
+ if ($v["usbboot"] != NULL) $usbstr .= "";
}
- $mediastr = "
-
-
-
-
- $mediaboot
- ";
+ $usbstr .= "";
}
+ }
- $driverstr = '';
- if (!empty($media['drivers']) && $os_type == "windows") {
- unset($arrAvailableDevs['hdb']);
- $media['driversbus'] = $media['driversbus'] ?: $bus;
- if ($media['driversbus'] == 'scsi') {
- $needSCSIController = true;
- }
- $driverstr = "
-
-
-
-
- ";
+ $arrAvailableDevs = [];
+ foreach (range('a', 'z') as $letter) {
+ $arrAvailableDevs['hd'.$letter] = 'hd'.$letter;
+ }
+
+ $needSCSIController = false;
+
+ //media settings
+ $bus = "ide";
+ if ($machine_type == 'q35'){
+ $bus = "sata";
+ }
+
+ $mediastr = '';
+ if (!empty($media['cdrom'])) {
+ unset($arrAvailableDevs['hda']);
+ $cdromboot = $media['cdromboot'];
+ $media['cdrombus'] = $media['cdrombus'] ?: $bus;
+ if ($media['cdrombus'] == 'scsi') {
+ $needSCSIController = true;
}
+ if ($cdromboot > 0) {
+ $mediaboot = "";
+ }
+ $mediastr = "
+
+
+
+
+ $mediaboot
+ ";
+ }
- //disk settings
- $diskstr = '';
- $diskcount = 0;
- if (!empty($disks)) {
+ $driverstr = '';
+ if (!empty($media['drivers']) && $os_type == "windows") {
+ unset($arrAvailableDevs['hdb']);
+ $media['driversbus'] = $media['driversbus'] ?: $bus;
+ if ($media['driversbus'] == 'scsi') {
+ $needSCSIController = true;
+ }
+ $driverstr = "
+
+
+
+
+ ";
+ }
- // force any hard drives to start with hdc, hdd, hde, etc
- unset($arrAvailableDevs['hda']);
- unset($arrAvailableDevs['hdb']);
+ //disk settings
+ $diskstr = '';
+ $diskcount = 0;
+ if (!empty($disks)) {
- foreach ($disks as $i => $disk) {
- if (!empty($disk['image']) | !empty($disk['new']) ) {
- //TODO: check if image/new is a block device
- $diskcount++;
+ // force any hard drives to start with hdc, hdd, hde, etc
+ unset($arrAvailableDevs['hda']);
+ unset($arrAvailableDevs['hdb']);
- if (!empty($disk['new'])) {
- if (is_file($disk['new']) || is_block($disk['new'])) {
- $disk['image'] = $disk['new'];
- }
+ foreach ($disks as $i => $disk) {
+ if (!empty($disk['image']) | !empty($disk['new']) ) {
+ //TODO: check if image/new is a block device
+ $diskcount++;
+
+ if (!empty($disk['new'])) {
+ if (is_file($disk['new']) || is_block($disk['new'])) {
+ $disk['image'] = $disk['new'];
}
+ }
- if (!empty($disk['image'])) {
- if (empty($disk['driver'])) {
- $disk['driver'] = 'raw';
+ if (!empty($disk['image'])) {
+ if (empty($disk['driver'])) {
+ $disk['driver'] = 'raw';
- if (is_file($disk['image'])) {
- $json_info = getDiskImageInfo($disk['image']);
- $disk['driver'] = $json_info['format'];
- }
- }
- } else {
- if (empty($disk['driver'])) {
- $disk['driver'] = 'raw';
- }
-
- $strImgFolder = $disk['new'];
- $strImgPath = '';
-
- $path_parts = pathinfo($strImgFolder);
- if (empty($path_parts['extension'])) {
- // 'new' is a folder
-
- if (substr($strImgFolder, -1) != '/') {
- $strImgFolder .= '/';
- }
-
- if (is_dir($strImgFolder)) {
- // 'new' is a folder and already exists, append domain name as child folder
- $strImgFolder .= preg_replace('((^\.)|\/|(\.$))', '_', $domain['name']) . '/';
- }
-
- $strExt = ($disk['driver'] == 'raw') ? 'img' : $disk['driver'];
-
- $strImgPath = $strImgFolder . 'vdisk' . $diskcount . '.' . $strExt;
-
- } else {
- // 'new' is a file
- $strImgPath = $strImgFolder;
- }
-
- if (is_file($strImgPath)) {
- $json_info = getDiskImageInfo($strImgPath);
+ if (is_file($disk['image'])) {
+ $json_info = getDiskImageInfo($disk['image']);
$disk['driver'] = $json_info['format'];
}
+ }
+ } else {
+ if (empty($disk['driver'])) {
+ $disk['driver'] = 'raw';
+ }
- $arrReturn = [
- 'image' => $strImgPath,
- 'driver' => $disk['driver']
- ];
- if (!empty($disk['dev'])) {
- $arrReturn['dev'] = $disk['dev'];
- }
- if (!empty($disk['bus'])) {
- $arrReturn['bus'] = $disk['bus'];
+ $strImgFolder = $disk['new'];
+ $strImgPath = '';
+
+ $path_parts = pathinfo($strImgFolder);
+ if (empty($path_parts['extension'])) {
+ // 'new' is a folder
+
+ if (substr($strImgFolder, -1) != '/') {
+ $strImgFolder .= '/';
}
- $disk = $arrReturn;
- }
+ if (is_dir($strImgFolder)) {
+ // 'new' is a folder and already exists, append domain name as child folder
+ $strImgFolder .= preg_replace('((^\.)|\/|(\.$))', '_', $domain['name']).'/';
+ }
- $disk['bus'] = $disk['bus'] ?: 'virtio';
+ $strExt = ($disk['driver'] == 'raw') ? 'img' : $disk['driver'];
+ $strImgPath = $strImgFolder.'vdisk'.$diskcount.'.'.$strExt;
- if ($disk['bus'] == 'scsi') {
- $needSCSIController = true;
- }
-
- if (empty($disk['dev']) || !in_array($disk['dev'], $arrAvailableDevs)) {
- $disk['dev'] = array_shift($arrAvailableDevs);
- }
- unset($arrAvailableDevs[$disk['dev']]);
- $boot = $disk['boot'] ;
- $bootorder = '';
- if ($boot > 0) {
- $bootorder = "" ;
- }
-
- $readonly = '';
- if (!empty($disk['readonly'])) {
- $readonly = '';
- }
-
- $strDevType = @filetype(realpath($disk['image']));
-
- if ($disk["serial"] != "") $serial = "".$disk["serial"]."" ; else $serial = "" ;
-
- $rotation_rate = "";
- if ($disk['bus'] == "scsi" || $disk['bus'] == "sata" || $disk['bus'] == "ide" ) {
- if ($disk['rotation']) $rotation_rate = " rotation_rate='1' ";
- }
-
- if ($strDevType == 'file' || $strDevType == 'block') {
- $strSourceType = ($strDevType == 'file' ? 'file' : 'dev');
-
- if (isset($disk['discard'])) $strDevUnmap = " discard=\"{$disk['discard']}\" "; else $strDevUnmap = " discard=\"ignore\" ";
-
- $diskstr .= "
-
-
-
- $bootorder
- $readonly
- $serial
- ";
- }
- }
- }
- }
-
- $scsicontroller = '';
- if ($needSCSIController) {
- $scsicontroller = "";
- }
-
- $netstr = '';
- if (!empty($nics)) {
- foreach ($nics as $i => $nic) {
- if (empty($nic['mac']) || empty($nic['network'])) {
- continue;
- }
- $netmodel = $nic['model'] ?: 'virtio-net';
-
- $net_res =$this->libvirt_get_net_res($this->conn, $nic['network']);
- exec("ls --indicator-style=none /sys/class/net|grep -Po '^((vir)?br|vhost)[0-9]+(\.[0-9]+)?'",$br);
- if ($nic["boot"] != NULL) $nicboot = "" ; else $nicboot = "" ;
- if ($net_res) {
- $netstr .= "
-
-
-
- $nicboot
- ";
- } elseif (in_array($nic['network'], $br)) {
- if (preg_match('/^(vir)?br/',$nic['network'])) {
- $netstr .= "
-
-
-
- $nicboot
- ";
} else {
- $netstr .= "
-
-
-
- $nicboot
- ";
+ // 'new' is a file
+ $strImgPath = $strImgFolder;
}
- } else {
- continue;
+
+ if (is_file($strImgPath)) {
+ $json_info = getDiskImageInfo($strImgPath);
+ $disk['driver'] = $json_info['format'];
+ }
+
+ $arrReturn = [
+ 'image' => $strImgPath,
+ 'driver' => $disk['driver']
+ ];
+ if (!empty($disk['dev'])) {
+ $arrReturn['dev'] = $disk['dev'];
+ }
+ if (!empty($disk['bus'])) {
+ $arrReturn['bus'] = $disk['bus'];
+ }
+
+ $disk = $arrReturn;
+ }
+
+ $disk['bus'] = $disk['bus'] ?: 'virtio';
+
+ if ($disk['bus'] == 'scsi') {
+ $needSCSIController = true;
+ }
+
+ if (empty($disk['dev']) || !in_array($disk['dev'], $arrAvailableDevs)) {
+ $disk['dev'] = array_shift($arrAvailableDevs);
+ }
+ unset($arrAvailableDevs[$disk['dev']]);
+ $boot = $disk['boot'];
+ $bootorder = '';
+ if ($boot > 0) {
+ $bootorder = "";
+ }
+
+ $readonly = '';
+ if (!empty($disk['readonly'])) {
+ $readonly = '';
+ }
+
+ $strDevType = @filetype(realpath($disk['image']));
+
+ if ($disk["serial"] != "") $serial = "".$disk["serial"].""; else $serial = "";
+
+ $rotation_rate = "";
+ if ($disk['bus'] == "scsi" || $disk['bus'] == "sata" || $disk['bus'] == "ide" ) {
+ if ($disk['rotation']) $rotation_rate = " rotation_rate='1' ";
+ }
+
+ if ($strDevType == 'file' || $strDevType == 'block') {
+ $strSourceType = ($strDevType == 'file' ? 'file' : 'dev');
+
+ if (isset($disk['discard'])) $strDevUnmap = " discard=\"{$disk['discard']}\" "; else $strDevUnmap = " discard=\"ignore\" ";
+
+ $diskstr .= "
+
+
+
+ $bootorder
+ $readonly
+ $serial
+ ";
}
}
}
+ }
- $sharestr = '';
- $memorybacking = json_decode($domain['memoryBacking'],true);
+ $scsicontroller = '';
+ if ($needSCSIController) {
+ $scsicontroller = "";
+ }
- if (!empty($shares)) {
- foreach ($shares as $i => $share) {
- if (empty($share['source']) || empty($share['target']) || ($os_type == "windows" && $share["mode"] == "9p")) {
- continue;
- }
+ $netstr = '';
+ if (!empty($nics)) {
+ foreach ($nics as $i => $nic) {
+ if (empty($nic['mac']) || empty($nic['network'])) {
+ continue;
+ }
+ $netmodel = $nic['model'] ?: 'virtio-net';
- if ($share['mode'] == "virtiofs") {
- if (!isset($memorybacking['source'])) $memorybacking['source']["@attributes"]["type"] = "memfd" ;
- if (!isset($memorybacking['access'])) $memorybacking['access']["@attributes"]["mode"] = "shared" ;
-
- $sharestr .= "
-
-
-
-
-
-
-
- " ;
+ $net_res =$this->libvirt_get_net_res($this->conn, $nic['network']);
+ exec("ls --indicator-style=none /sys/class/net|grep -Po '^((vir)?br|vhost)[0-9]+(\.[0-9]+)?'",$br);
+ if ($nic["boot"] != NULL) $nicboot = ""; else $nicboot = "";
+ if ($net_res) {
+ $netstr .= "
+
+
+
+ $nicboot
+ ";
+ } elseif (in_array($nic['network'], $br)) {
+ if (preg_match('/^(vir)?br/',$nic['network'])) {
+ $netstr .= "
+
+
+
+ $nicboot
+ ";
} else {
- $sharestr .= "
-
-
- ";
+ $netstr .= "
+
+
+
+ $nicboot
+ ";
}
+ } else {
+ continue;
}
}
+ }
- $pcidevs='';
- $gpudevs_used=[];
- $multidevices = [] ; #Load?
- $vmrc='';
- $channelscopypaste = '';
- if (!empty($gpus)) {
- foreach ($gpus as $i => $gpu) {
- // Skip duplicate video devices
- if (empty($gpu['id']) || in_array($gpu['id'], $gpudevs_used)) {
- continue;
- }
- if ($gpu['id'] == 'nogpu') break;
- if ($gpu['id'] == 'virtual') {
- $strKeyMap = '';
- if (!empty($gpu['keymap'])) {
- if ($gpu['keymap'] != "none") $strKeyMap = "keymap='" . $gpu['keymap'] . "'";
- }
+ $sharestr = '';
+ $memorybacking = json_decode($domain['memoryBacking'],true);
- $passwdstr = '';
- if (!empty($domain['password'])){
- $passwdstr = "passwd='" . htmlspecialchars($domain['password'], ENT_QUOTES | ENT_XML1) . "'";
- }
+ if (!empty($shares)) {
+ foreach ($shares as $i => $share) {
+ if (empty($share['source']) || empty($share['target']) || ($os_type == "windows" && $share["mode"] == "9p")) {
+ continue;
+ }
- $strModelType = 'qxl';
- if (!empty($gpu['model'])) {
- $strModelType = $gpu['model'];
+ if ($share['mode'] == "virtiofs") {
+ if (!isset($memorybacking['source'])) $memorybacking['source']["@attributes"]["type"] = "memfd";
+ if (!isset($memorybacking['access'])) $memorybacking['access']["@attributes"]["mode"] = "shared";
- if (!empty($domain['ovmf']) && $strModelType == 'vmvga') {
- // OVMF doesn't work with vmvga
- $strModelType = 'qxl';
- }
- }
- if (!empty($gpu['autoport'])) {
- $strAutoport = $gpu['autoport'];
- } else $strAutoport = "yes" ;
+ $sharestr .= "
+
+
+
+
+
+
+
+ ";
+ } else {
+ $sharestr .= "
+
+
+ ";
+ }
+ }
+ }
-
-
- if (!empty($gpu['protocol'])) {
- $strProtocol = $gpu['protocol'];
- } else $strProtocol = "vnc" ;
-
- if (!empty($gpu['wsport'])) {
- $strWSport = $gpu['wsport'];
- } else $strWSport = "-1" ;
-
- if (!empty($gpu['port'])) {
- $strPort = $gpu['port'];
- } else $strPort = "-1" ;
-
- if ($strAutoport == "yes") $strPort = $strWSport = "-1" ;
- if (($gpu['copypaste'] == "yes") && ($strProtocol == "spice")) $vmrcmousemode = "" ; else $vmrcmousemode = "" ;
- if ($strProtocol == "spice") $virtualaudio = "spice" ; else $virtualaudio = "none" ;
-
- $strEGLHeadless = "";
- $strAccel3d ="";
- if ($strModelType == "virtio3d") {
- $strModelType = "virtio";
- if (!isset($gpu['render'])) $gpu['render'] = "auto";
- if ($gpu['render'] == "auto") {
- $strEGLHeadless = '';
- $strAccel3d = "";
- } else {
- $strEGLHeadless = '';
- $strAccel3d ="";
- }}
-
- $strDisplayOptions = "";
- if ($strModelType == "qxl") {
- if (empty($gpu['DisplayOptions'])) $gpu['DisplayOptions'] ="ram='65536' vram='16384' vgamem='16384' heads='1' primary='yes'";
- $strDisplayOptions = $gpu['DisplayOptions'];
- }
-
- $vmrc = "
-
-
-
-
- $vmrcmousemode
-
- $strEGLHeadless
-
- ";
-
-
- if ($gpu['copypaste'] == "yes") {
- if ($strProtocol == "spice") {
- $channelscopypaste = "
-
- " ;
- } else {
- $channelscopypaste = "
-
-
-
-
-
- " ;
- }
- } else $channelcopypaste = "";
-
- continue;
+ $pcidevs='';
+ $gpudevs_used=[];
+ $multidevices = []; #Load?
+ $vmrc='';
+ $channelscopypaste = '';
+ if (!empty($gpus)) {
+ foreach ($gpus as $i => $gpu) {
+ // Skip duplicate video devices
+ if (empty($gpu['id']) || in_array($gpu['id'], $gpudevs_used)) {
+ continue;
+ }
+ if ($gpu['id'] == 'nogpu') break;
+ if ($gpu['id'] == 'virtual') {
+ $strKeyMap = '';
+ if (!empty($gpu['keymap'])) {
+ if ($gpu['keymap'] != "none") $strKeyMap = "keymap='".$gpu['keymap']."'";
}
- [$gpu_bus, $gpu_slot, $gpu_function] = my_explode(":", str_replace('.', ':', $gpu['id']), 3);
+ $passwdstr = '';
+ if (!empty($domain['password'])){
+ $passwdstr = "passwd='".htmlspecialchars($domain['password'], ENT_QUOTES | ENT_XML1)."'";
+ }
+ $strModelType = 'qxl';
+ if (!empty($gpu['model'])) {
+ $strModelType = $gpu['model'];
+
+ if (!empty($domain['ovmf']) && $strModelType == 'vmvga') {
+ // OVMF doesn't work with vmvga
+ $strModelType = 'qxl';
+ }
+ }
+ if (!empty($gpu['autoport'])) {
+ $strAutoport = $gpu['autoport'];
+ } else $strAutoport = "yes";
+
+ if (!empty($gpu['protocol'])) {
+ $strProtocol = $gpu['protocol'];
+ } else $strProtocol = "vnc";
+
+ if (!empty($gpu['wsport'])) {
+ $strWSport = $gpu['wsport'];
+ } else $strWSport = "-1";
+
+ if (!empty($gpu['port'])) {
+ $strPort = $gpu['port'];
+ } else $strPort = "-1";
+
+ if ($strAutoport == "yes") $strPort = $strWSport = "-1";
+ if (($gpu['copypaste'] == "yes") && ($strProtocol == "spice")) $vmrcmousemode = ""; else $vmrcmousemode = "" ;
+ if ($strProtocol == "spice") $virtualaudio = "spice"; else $virtualaudio = "none";
+
+ $strEGLHeadless = "";
+ $strAccel3d ="";
+ if ($strModelType == "virtio3d") {
+ $strModelType = "virtio";
+ if (!isset($gpu['render'])) $gpu['render'] = "auto";
+ if ($gpu['render'] == "auto") {
+ $strEGLHeadless = '';
+ $strAccel3d = "";
+ } else {
+ $strEGLHeadless = '';
+ $strAccel3d ="";
+ }}
+
+ $strDisplayOptions = "";
+ if ($strModelType == "qxl") {
+ if (empty($gpu['DisplayOptions'])) $gpu['DisplayOptions'] ="ram='65536' vram='16384' vgamem='16384' heads='1' primary='yes'";
+ $strDisplayOptions = $gpu['DisplayOptions'];
+ }
+
+ $vmrc = "
+
+
+
+
+ $vmrcmousemode
+
+ $strEGLHeadless
+
+ ";
+
+ if ($gpu['copypaste'] == "yes") {
+ if ($strProtocol == "spice") {
+ $channelscopypaste = "
+
+ ";
+ } else {
+ $channelscopypaste = "
+
+
+
+
+
+ ";
+ }
+ } else $channelcopypaste = "";
+
+ continue;
+ }
+
+ [$gpu_bus, $gpu_slot, $gpu_function] = my_explode(":", str_replace('.', ':', $gpu['id']), 3);
+
+ $strXVGA = '';
+ if (empty($gpudevs_used) && empty($domain['ovmf'])) {
+ $strXVGA = " xvga='yes'";
+ }
+
+ //HACK: add special address for intel iGPU and remove x-vga attribute
+ $strSpecialAddress = '';
+ if ($gpu_bus == '00' && $gpu_slot == '02') {
$strXVGA = '';
- if (empty($gpudevs_used) && empty($domain['ovmf'])) {
- $strXVGA = " xvga='yes'";
- }
-
- //HACK: add special address for intel iGPU and remove x-vga attribute
- $strSpecialAddress = '';
- if ($gpu_bus == '00' && $gpu_slot == '02') {
- $strXVGA = '';
+ $strSpecialAddress = "";
+ if ($gpu_function == '00') {
$strSpecialAddress = "";
- if ($gpu_function == '00') {
- $strSpecialAddress = "";
- # Add support for SR-IOV
+ # Add support for SR-IOV
+ } else {
+ if ($machine_type == 'q35'){
+ $strSpecialAddress = "";
} else {
- if ($machine_type == 'q35'){
- $strSpecialAddress = "";
- } else {
- $strSpecialAddress = "";
- }
+ $strSpecialAddress = "";
}
}
-
- $strRomFile = '';
- if (!empty($gpu['rom'])) {
- $strRomFile = "";
- }
-
- if ($gpu['multi'] == "on"){
- $newgpu_bus= 0x07;
- if (!isset($multibus[$newgpu_bus])) {
- $multibus[$newgpu_bus] = 0x07;
- } else {
- #Get next bus
- $newgpu_bus = end($multibus) + 0x01;
- $multibus[$newgpu_bus] = $newgpu_bus;
- }
- if ($machine_type == "pc") $newgpu_slot = "0x01" ; else $newgpu_slot = "0x00" ;
- $strSpecialAddress = "" ;
- $multidevices[$gpu_bus] = $newgpu_bus ;
- }
-
-
-
- $pcidevs .= "
-
-
-
-
- $strSpecialAddress
- $strRomFile
- ";
-
- $gpudevs_used[] = $gpu['id'];
}
- }
- $audiodevs_used=[];
- if (!empty($audios)) {
- foreach ($audios as $i => $audio) {
- $strSpecialAddressAudio = "" ;
- // Skip duplicate audio devices
- if (empty($audio['id']) || in_array($audio['id'], $audiodevs_used)) {
- continue;
- }
- [$audio_bus, $audio_slot, $audio_function] = my_explode(":", str_replace('.', ':', $audio['id']), 3);
- if ($audio_function != 0) {
- if (isset($multidevices[$audio_bus])) {
- $newaudio_bus = $multidevices[$audio_bus] ;
- if ($machine_type == "pc") $newaudio_slot = "0x01" ; else $newaudio_slot = "0x00" ;
- $strSpecialAddressAudio = "" ;
- }
- }
-
- $pcidevs .= "
-
-
-
-
- $strSpecialAddressAudio
- ";
-
- $audiodevs_used[] = $audio['id'];
+ $strRomFile = '';
+ if (!empty($gpu['rom'])) {
+ $strRomFile = "";
}
- }
- $pcidevs_used=[];
- if (!empty($pcis)) {
- foreach ($pcis as $i => $pci_id) {
- $strSpecialAddressOther = "" ;
- // Skip duplicate other pci devices
- if (empty($pci_id) || in_array($pci_id, $pcidevs_used)) {
- continue;
+ if ($gpu['multi'] == "on"){
+ $newgpu_bus= 0x07;
+ if (!isset($multibus[$newgpu_bus])) {
+ $multibus[$newgpu_bus] = 0x07;
+ } else {
+ #Get next bus
+ $newgpu_bus = end($multibus) + 0x01;
+ $multibus[$newgpu_bus] = $newgpu_bus;
}
- if ($vmclone) [$pci_bus, $pci_slot, $pci_function] = my_explode(":", str_replace('.', ':', $pci_id['id']), 3);
- else [$pci_bus, $pci_slot, $pci_function] = my_explode(":", str_replace('.', ':', $pci_id), 3);
-
- if ($pci_function != 0) {
- if (isset($multidevices[$pci_bus])) {
- $newpci_bus = $multidevices[$pci_bus];
- if ($machine_type == "pc") $newpci_slot = "0x01" ; else $newpci_slot = "0x00" ;
- $strSpecialAddressOther = "" ;
- }
- }
-
- $pcidevs .= "
-
-
-
-
- $strSpecialAddressOther " ;
-
- if (!empty($pciboot[$pci_id]) && !$vmclone) {
- $pcidevs .= "" ;
- }
- if (!empty($pci_id["boot"]) && $vmclone) {
- $pcidevs .= "" ;
- }
- $pcidevs .= "";
-
- if ($vmclone) $pcidevs_used[] = $pci_id['d']; else $pcidevs_used[] = $pci_id ;
+ if ($machine_type == "pc") $newgpu_slot = "0x01"; else $newgpu_slot = "0x00";
+ $strSpecialAddress = "";
+ $multidevices[$gpu_bus] = $newgpu_bus;
}
- }
- $memballoon = "";
- if (empty( array_filter(array_merge($gpudevs_used, $audiodevs_used, $pcidevs_used), function($k){ return strpos($k,'#remove')===false && $k!='virtual' ; }) )) {
- $memballoon = "
-
- ";
- }
- #$osbootdev = "" ;
- $evdevstr = "";
- foreach($evdevs as $evdev) {
- if ($evdev['dev'] == "") continue;
- $evdevstr .= "\n
+
+
+
+
+ $strSpecialAddress
+ $strRomFile
+ ";
- $memorybackingXML = Array2XML::createXML('memoryBacking', $memorybacking);
- $memoryBackingXML = $memorybackingXML->saveXML($memorybackingXML->documentElement);
- return "
- $uuid
- $name
- " . htmlspecialchars($domain['desc'], ENT_QUOTES | ENT_XML1) . "
- $metadata
- $mem
- $maxmem
- $cpustr
- $memoryBackingXML
-
- $loader
- hvm
- $osbootdev
-
-
-
-
- $hyperv
- $pae
-
- $clock
- destroy
- restart
- restart
-
- $emulator
- $diskstr
- $mediastr
- $driverstr
- $ctrl
- $sharestr
- $netstr
- $vmrc
-
- $scsicontroller
- $pcidevs
- $usbstr
-
-
-
- $channelscopypaste
- $swtpm
- $memballoon
- $evdevstr
-
- ";
+ $gpudevs_used[] = $gpu['id'];
+ }
+ }
+ $audiodevs_used=[];
+ if (!empty($audios)) {
+ foreach ($audios as $i => $audio) {
+ $strSpecialAddressAudio = "";
+ // Skip duplicate audio devices
+ if (empty($audio['id']) || in_array($audio['id'], $audiodevs_used)) {
+ continue;
+ }
+ [$audio_bus, $audio_slot, $audio_function] = my_explode(":", str_replace('.', ':', $audio['id']), 3);
+ if ($audio_function != 0) {
+ if (isset($multidevices[$audio_bus])) {
+ $newaudio_bus = $multidevices[$audio_bus];
+ if ($machine_type == "pc") $newaudio_slot = "0x01"; else $newaudio_slot = "0x00";
+ $strSpecialAddressAudio = "";
+ }
+ }
+
+ $pcidevs .= "
+
+
+
+
+ $strSpecialAddressAudio
+ ";
+
+ $audiodevs_used[] = $audio['id'];
+ }
}
- function appendqemucmdline($xml,$cmdline) {
- $newxml = $xml ;
- if ($cmdline != null) $newxml = str_replace("",$cmdline."\n",$xml) ;
- return $newxml ;
- }
+ $pcidevs_used=[];
+ if (!empty($pcis)) {
+ foreach ($pcis as $i => $pci_id) {
+ $strSpecialAddressOther = "";
+ // Skip duplicate other pci devices
+ if (empty($pci_id) || in_array($pci_id, $pcidevs_used)) {
+ continue;
+ }
+ if ($vmclone) [$pci_bus, $pci_slot, $pci_function] = my_explode(":", str_replace('.', ':', $pci_id['id']), 3);
+ else [$pci_bus, $pci_slot, $pci_function] = my_explode(":", str_replace('.', ':', $pci_id), 3);
- function domain_new($config) {
-
- # Set storage for disks.
- foreach ($config['disk'] as $i => $disk) { $config['disk'][$i]['storage'] = $config['template']['storage'];}
- // attempt to create all disk images if needed
- $diskcount = 0;
- if (!empty($config['disk'])) {
- foreach ($config['disk'] as $i => $disk) {
- if (!empty($disk['image']) | !empty($disk['new']) ) {
- $diskcount++;
-
- $disk = $this->create_disk_image($disk, $config['domain']['name'], $diskcount);
-
- if (!empty($disk['error'])) {
- $this->last_error = $disk['error'];
- return false;
- }
-
- $config['disk'][$i] = $disk;
+ if ($pci_function != 0) {
+ if (isset($multidevices[$pci_bus])) {
+ $newpci_bus = $multidevices[$pci_bus];
+ if ($machine_type == "pc") $newpci_slot = "0x01"; else $newpci_slot = "0x00";
+ $strSpecialAddressOther = "";
}
}
+
+ $pcidevs .= "
+
+
+
+
+ $strSpecialAddressOther ";
+
+ if (!empty($pciboot[$pci_id]) && !$vmclone) {
+ $pcidevs .= "";
+ }
+ if (!empty($pci_id["boot"]) && $vmclone) {
+ $pcidevs .= "";
+ }
+ $pcidevs .= "";
+
+ if ($vmclone) $pcidevs_used[] = $pci_id['d']; else $pcidevs_used[] = $pci_id;
}
-
- // generate xml for this domain
- $strXML = $this->config_to_xml($config);
- $qemucmdline = $config['qemucmdline'];
- $strXML = $this->appendqemucmdline($strXML,$qemucmdline) ;
-
-
- // Start the VM now if requested
- if (!empty($config['domain']['startnow'])) {
- $tmp = libvirt_domain_create_xml($this->conn, $strXML);
- if (!$tmp)
- return $this->_set_last_error();
- }
-
- // Define the VM to persist
- if ($config['domain']['persistent']) {
- $tmp = libvirt_domain_define_xml($this->conn, $strXML);
- if (!$tmp)
- return $this->_set_last_error();
-
- $this->domain_set_autostart($tmp, $config['domain']['autostart'] == 1);
- return $tmp;
- }
- else
- return $tmp;
-
}
- function vfio_bind($strPassthruDevice) {
- // Ensure we have leading 0000:
- $strPassthruDeviceShort = str_replace('0000:', '', $strPassthruDevice);
- $strPassthruDeviceLong = '0000:' . $strPassthruDeviceShort;
-
- // Determine the driver currently assigned to the device
- $strDriverSymlink = @readlink('/sys/bus/pci/devices/' . $strPassthruDeviceLong . '/driver');
-
- if ($strDriverSymlink !== false) {
- // Device is bound to a Driver already
-
- if (strpos($strDriverSymlink, 'vfio-pci') !== false) {
- // Driver bound to vfio-pci already - nothing left to do for this device now regarding vfio
- return true;
- }
-
- // Driver bound to some other driver - attempt to unbind driver
- if (file_put_contents('/sys/bus/pci/devices/' . $strPassthruDeviceLong . '/driver/unbind', $strPassthruDeviceLong) === false) {
- $this->last_error = 'Failed to unbind device ' . $strPassthruDeviceShort . ' from current driver';
- return false;
- }
- }
-
- // Get Vendor and Device IDs for the passthru device
- $strVendor = file_get_contents('/sys/bus/pci/devices/' . $strPassthruDeviceLong . '/vendor');
- $strDevice = file_get_contents('/sys/bus/pci/devices/' . $strPassthruDeviceLong . '/device');
-
- // Attempt to bind driver to vfio-pci
- if (file_put_contents('/sys/bus/pci/drivers/vfio-pci/new_id', $strVendor . ' ' . $strDevice) === false) {
- $this->last_error = 'Failed to bind device ' . $strPassthruDeviceShort . ' to vfio-pci driver';
- return false;
- }
-
- return true;
+ $memballoon = "";
+ if (empty( array_filter(array_merge($gpudevs_used, $audiodevs_used, $pcidevs_used), function($k){ return strpos($k,'#remove')===false && $k!='virtual'; }) )) {
+ $memballoon = "
+
+ ";
+ }
+ #$osbootdev = "";
+ $evdevstr = "";
+ foreach($evdevs as $evdev) {
+ if ($evdev['dev'] == "") continue;
+ $evdevstr .= "\nconn=libvirt_connect($uri, false, [VIR_CRED_AUTHNAME => $login, VIR_CRED_PASSPHRASE => $password]);
- } else {
- $this->conn=libvirt_connect($uri, false);
+ $memorybackingXML = Array2XML::createXML('memoryBacking', $memorybacking);
+ $memoryBackingXML = $memorybackingXML->saveXML($memorybackingXML->documentElement);
+ return "
+ $uuid
+ $name
+ ".htmlspecialchars($domain['desc'], ENT_QUOTES | ENT_XML1)."
+ $metadata
+ $mem
+ $maxmem
+ $cpustr
+ $memoryBackingXML
+
+ $loader
+ hvm
+ $osbootdev
+
+
+
+
+ $hyperv
+ $pae
+
+ $clock
+ destroy
+ restart
+ restart
+
+ $emulator
+ $diskstr
+ $mediastr
+ $driverstr
+ $ctrl
+ $sharestr
+ $netstr
+ $vmrc
+
+ $scsicontroller
+ $pcidevs
+ $usbstr
+
+
+
+ $channelscopypaste
+ $swtpm
+ $memballoon
+ $evdevstr
+
+ ";
+ }
+
+ function appendqemucmdline($xml,$cmdline) {
+ $newxml = $xml;
+ if ($cmdline != null) $newxml = str_replace("",$cmdline."\n",$xml);
+ return $newxml;
+ }
+
+ function domain_new($config) {
+
+ # Set storage for disks.
+ foreach ($config['disk'] as $i => $disk) { $config['disk'][$i]['storage'] = $config['template']['storage'];}
+ // attempt to create all disk images if needed
+ $diskcount = 0;
+ if (!empty($config['disk'])) {
+ foreach ($config['disk'] as $i => $disk) {
+ if (!empty($disk['image']) | !empty($disk['new']) ) {
+ $diskcount++;
+
+ $disk = $this->create_disk_image($disk, $config['domain']['name'], $diskcount);
+
+ if (!empty($disk['error'])) {
+ $this->last_error = $disk['error'];
+ return false;
+ }
+
+ $config['disk'][$i] = $disk;
+ }
}
- if ($this->conn==false)
+ }
+
+ // generate xml for this domain
+ $strXML = $this->config_to_xml($config);
+ $qemucmdline = $config['qemucmdline'];
+ $strXML = $this->appendqemucmdline($strXML,$qemucmdline);
+
+ // Start the VM now if requested
+ if (!empty($config['domain']['startnow'])) {
+ $tmp = libvirt_domain_create_xml($this->conn, $strXML);
+ if (!$tmp)
return $this->_set_last_error();
-
- return true;
}
- function domain_change_boot_devices($domain, $first, $second) {
- $domain = $this->get_domain_object($domain);
-
- $tmp = libvirt_domain_change_boot_devices($domain, $first, $second);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function domain_get_screen_dimensions($domain) {
- $dom = $this->get_domain_object($domain);
-
- $tmp = libvirt_domain_get_screen_dimensions($dom, $this->get_hostname() );
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function domain_send_keys($domain, $keys) {
- $dom = $this->get_domain_object($domain);
-
- $tmp = libvirt_domain_send_keys($dom, $this->get_hostname(), $keys);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function domain_send_pointer_event($domain, $x, $y, $clicked = 1, $release = false) {
- $dom = $this->get_domain_object($domain);
-
- $tmp = libvirt_domain_send_pointer_event($dom, $this->get_hostname(), $x, $y, $clicked, $release);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function domain_disk_remove($domain, $dev) {
- $dom = $this->get_domain_object($domain);
-
- $tmp = libvirt_domain_disk_remove($dom, $dev);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function supports($name) {
- return libvirt_has_feature($name);
- }
-
- function macbyte($val) {
- if ($val < 16)
- return '0'.dechex($val);
-
- return dechex($val);
- }
-
- function generate_random_mac_addr($seed=false) {
- if (!$seed)
- $seed = 1;
-
- if ($this->get_hypervisor_name() == 'qemu')
- $prefix = '52:54:00';
- else
- $prefix = $this->macbyte(($seed * rand()) % 256).':'.
- $this->macbyte(($seed * rand()) % 256).':'.
- $this->macbyte(($seed * rand()) % 256);
-
- return $prefix.':'.
- $this->macbyte(($seed * rand()) % 256).':'.
- $this->macbyte(($seed * rand()) % 256).':'.
- $this->macbyte(($seed * rand()) % 256);
- }
-
- function get_connection() {
- return $this->conn;
- }
-
- function get_hostname() {
- return libvirt_connect_get_hostname($this->conn);
- }
-
- function get_domain_object($nameRes) {
- if (is_resource($nameRes))
- return $nameRes;
-
- $dom=libvirt_domain_lookup_by_name($this->conn, $nameRes);
- if (!$dom) {
- $dom=libvirt_domain_lookup_by_uuid_string($this->conn, $nameRes);
- if (!$dom)
- return $this->_set_last_error();
- }
-
- return $dom;
- }
-
- function get_xpath($domain, $xpath, $inactive = false) {
- $dom = $this->get_domain_object($domain);
- $flags = 0;
- if ($inactive)
- $flags = VIR_DOMAIN_XML_INACTIVE;
-
- $tmp = libvirt_domain_xml_xpath($dom, $xpath, $flags);
+ // Define the VM to persist
+ if ($config['domain']['persistent']) {
+ $tmp = libvirt_domain_define_xml($this->conn, $strXML);
if (!$tmp)
return $this->_set_last_error();
+ $this->domain_set_autostart($tmp, $config['domain']['autostart'] == 1);
return $tmp;
}
+ else
+ return $tmp;
- function get_cdrom_stats($domain, $sort=true,$spincheck = false) {
- $unraiddisks = array_merge_recursive(@parse_ini_file('state/disks.ini',true)?:[], @parse_ini_file('state/devs.ini',true)?:[]);
- $dom = $this->get_domain_object($domain);
- $tmp = false;
- $buses = $this->get_xpath($dom, '//domain/devices/disk[@device="cdrom"]/target/@bus', false);
- $cds = $this->get_xpath($dom, '//domain/devices/disk[@device="cdrom"]/target/@dev', false);
- $files = $this->get_xpath($dom, '//domain/devices/disk[@device="cdrom"]/source/@file', false);
- $boot = $this->get_xpath($dom, '//domain/devices/disk[@device="cdrom"]/boot/@*', false);
+ }
- $ret = [];
- for ($i = 0; $i < $cds['num']; $i++) {
- $spundown = 0;
- $reallocation = null;
- if (isset($files[$i])) $reallocation = trim(get_realvolume($files[$i]));
- if ($spincheck) {
- if (isset($unraiddisks[$reallocation]['spundown']) && $unraiddisks[$reallocation]['spundown'] == 1) $spundown = 1; else $tmp = libvirt_domain_get_block_info($dom, $cds[$i]);
- } else $tmp = libvirt_domain_get_block_info($dom, $cds[$i]);
+ function vfio_bind($strPassthruDevice) {
+ // Ensure we have leading 0000:
+ $strPassthruDeviceShort = str_replace('0000:', '', $strPassthruDevice);
+ $strPassthruDeviceLong = '0000:'.$strPassthruDeviceShort;
- if ($tmp) {
- $tmp['bus'] = $buses[$i];
- $tmp["boot order"] = $boot[$i] ?? "";
- $tmp['reallocation'] = $reallocation;
- $tmp['spundown'] = $spundown;
- $ret[] = $tmp;
- }
- else {
- $this->_set_last_error();
+ // Determine the driver currently assigned to the device
+ $strDriverSymlink = @readlink('/sys/bus/pci/devices/'.$strPassthruDeviceLong.'/driver');
- $ret[] = [
- 'device' => $cds[$i],
- 'file' => $files[$i],
- 'type' => '-',
- 'capacity' => '-',
- 'allocation' => '-',
- 'physical' => '-',
- 'bus' => $buses[$i],
- 'reallocation' => $reallocation,
- 'spundown' => $spundown
- ];
- }
+ if ($strDriverSymlink !== false) {
+ // Device is bound to a Driver already
+
+ if (strpos($strDriverSymlink, 'vfio-pci') !== false) {
+ // Driver bound to vfio-pci already - nothing left to do for this device now regarding vfio
+ return true;
}
- if ($sort) {
- for ($i = 0; $i < sizeof($ret); $i++) {
- for ($ii = 0; $ii < sizeof($ret); $ii++) {
- if (strcmp($ret[$i]['device'], $ret[$ii]['device']) < 0) {
- $tmp = $ret[$i];
- $ret[$i] = $ret[$ii];
- $ret[$ii] = $tmp;
- }
- }
- }
+ // Driver bound to some other driver - attempt to unbind driver
+ if (file_put_contents('/sys/bus/pci/devices/'.$strPassthruDeviceLong.'/driver/unbind', $strPassthruDeviceLong) === false) {
+ $this->last_error = 'Failed to unbind device '.$strPassthruDeviceShort.' from current driver';
+ return false;
}
-
- unset($buses);
- unset($cds);
- unset($files);
-
- return $ret;
}
- function get_disk_stats($domain, $sort=true) {
- $dom = $this->get_domain_object($domain);
+ // Get Vendor and Device IDs for the passthru device
+ $strVendor = file_get_contents('/sys/bus/pci/devices/'.$strPassthruDeviceLong.'/vendor');
+ $strDevice = file_get_contents('/sys/bus/pci/devices/'.$strPassthruDeviceLong.'/device');
- $domainXML = $this->domain_get_xml($dom) ;
- $arrDomain = new SimpleXMLElement($domainXML);
- $arrDomain = $arrDomain->devices->disk;
+ // Attempt to bind driver to vfio-pci
+ if (file_put_contents('/sys/bus/pci/drivers/vfio-pci/new_id', $strVendor.' '.$strDevice) === false) {
+ $this->last_error = 'Failed to bind device '.$strPassthruDeviceShort.' to vfio-pci driver';
+ return false;
+ }
+ return true;
+ }
- $ret = [];
- foreach ($arrDomain as $disk) {
- if ($disk->attributes()->device != "disk") continue ;
- $tmp = libvirt_domain_get_block_info($dom, $disk->target->attributes()->dev);
+ function connect($uri = 'null', $login = false, $password = false) {
+ if ($login !== false && $password !== false) {
+ $this->conn=libvirt_connect($uri, false, [VIR_CRED_AUTHNAME => $login, VIR_CRED_PASSPHRASE => $password]);
+ } else {
+ $this->conn=libvirt_connect($uri, false);
+ }
+ if ($this->conn==false)
+ return $this->_set_last_error();
+ return true;
+ }
- if ($tmp) {
- $tmp['bus'] = $disk->target->attributes()->bus->__toString();
- $tmp["boot order"] = $disk->boot->attributes()->order ?? "";
- $tmp["discard"] = $disk->driver->attributes()->discard ?? "ignore";
- $tmp["rotation"] = $disk->target->attributes()->rotation_rate ?? "0";
- $tmp['serial'] = $disk->serial ;
+ function domain_change_boot_devices($domain, $first, $second) {
+ $domain = $this->get_domain_object($domain);
+ $tmp = libvirt_domain_change_boot_devices($domain, $first, $second);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
- // Libvirt reports 0 bytes for raw disk images that haven't been
- // written to yet so we just report the raw disk size for now
- if ( !empty($tmp['file']) &&
- $tmp['type'] == 'raw' &&
- empty($tmp['physical']) &&
- is_file($tmp['file']) ) {
+ function domain_get_screen_dimensions($domain) {
+ $dom = $this->get_domain_object($domain);
+ $tmp = libvirt_domain_get_screen_dimensions($dom, $this->get_hostname() );
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
- $intSize = filesize($tmp['file']);
- $tmp['physical'] = $intSize;
- $tmp['capacity'] = $intSize;
- }
+ function domain_send_keys($domain, $keys) {
+ $dom = $this->get_domain_object($domain);
- $ret[] = $tmp;
- }
- else {
- $this->_set_last_error();
+ $tmp = libvirt_domain_send_keys($dom, $this->get_hostname(), $keys);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
- $ret[] = [
- 'device' => $disk->target->attributes()->dev->__toString(),
- 'file' => $disk->source->attributes()->file,
- 'type' => '-',
- 'capacity' => '-',
- 'allocation' => '-',
- 'physical' => '-',
- 'bus' => $disk->target->attributes()->bus->__toString(),
- 'boot order' => $disk->boot->attributes()->order ,
- 'rotation' => $disk->target->attributes()->rotation_rate ?? "0",
- 'serial' => $disk->serial,
- 'discard' => $disk->driver->attributes()->discard ?? "ignore"
- ];
- }
+ function domain_send_pointer_event($domain, $x, $y, $clicked = 1, $release = false) {
+ $dom = $this->get_domain_object($domain);
+
+ $tmp = libvirt_domain_send_pointer_event($dom, $this->get_hostname(), $x, $y, $clicked, $release);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function domain_disk_remove($domain, $dev) {
+ $dom = $this->get_domain_object($domain);
+
+ $tmp = libvirt_domain_disk_remove($dom, $dev);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function supports($name) {
+ return libvirt_has_feature($name);
+ }
+
+ function macbyte($val) {
+ if ($val < 16)
+ return '0'.dechex($val);
+ return dechex($val);
+ }
+
+ function generate_random_mac_addr($seed=false) {
+ if (!$seed)
+ $seed = 1;
+
+ if ($this->get_hypervisor_name() == 'qemu')
+ $prefix = '52:54:00';
+ else
+ $prefix = $this->macbyte(($seed * rand()) % 256).':'.
+ $this->macbyte(($seed * rand()) % 256).':'.
+ $this->macbyte(($seed * rand()) % 256);
+ return $prefix.':'.
+ $this->macbyte(($seed * rand()) % 256).':'.
+ $this->macbyte(($seed * rand()) % 256).':'.
+ $this->macbyte(($seed * rand()) % 256);
+ }
+
+ function get_connection() {
+ return $this->conn;
+ }
+
+ function get_hostname() {
+ return libvirt_connect_get_hostname($this->conn);
+ }
+
+ function get_domain_object($nameRes) {
+ if (is_resource($nameRes))
+ return $nameRes;
+
+ $dom=libvirt_domain_lookup_by_name($this->conn, $nameRes);
+ if (!$dom) {
+ $dom=libvirt_domain_lookup_by_uuid_string($this->conn, $nameRes);
+ if (!$dom)
+ return $this->_set_last_error();
+ }
+ return $dom;
+ }
+
+ function get_xpath($domain, $xpath, $inactive = false) {
+ $dom = $this->get_domain_object($domain);
+ $flags = 0;
+ if ($inactive)
+ $flags = VIR_DOMAIN_XML_INACTIVE;
+
+ $tmp = libvirt_domain_xml_xpath($dom, $xpath, $flags);
+ if (!$tmp)
+ return $this->_set_last_error();
+ return $tmp;
+ }
+
+ function get_cdrom_stats($domain, $sort=true,$spincheck = false) {
+ $unraiddisks = array_merge_recursive(@parse_ini_file('state/disks.ini',true)?:[], @parse_ini_file('state/devs.ini',true)?:[]);
+ $dom = $this->get_domain_object($domain);
+ $tmp = false;
+ $buses = $this->get_xpath($dom, '//domain/devices/disk[@device="cdrom"]/target/@bus', false);
+ $cds = $this->get_xpath($dom, '//domain/devices/disk[@device="cdrom"]/target/@dev', false);
+ $files = $this->get_xpath($dom, '//domain/devices/disk[@device="cdrom"]/source/@file', false);
+ $boot = $this->get_xpath($dom, '//domain/devices/disk[@device="cdrom"]/boot/@*', false);
+
+ $ret = [];
+ for ($i = 0; $i < $cds['num']; $i++) {
+ $spundown = 0;
+ $reallocation = null;
+ if (isset($files[$i])) $reallocation = trim(get_realvolume($files[$i]));
+ if ($spincheck) {
+ if (isset($unraiddisks[$reallocation]['spundown']) && $unraiddisks[$reallocation]['spundown'] == 1) $spundown = 1; else $tmp = libvirt_domain_get_block_info($dom, $cds[$i]);
+ } else $tmp = libvirt_domain_get_block_info($dom, $cds[$i]);
+
+ if ($tmp) {
+ $tmp['bus'] = $buses[$i];
+ $tmp["boot order"] = $boot[$i] ?? "";
+ $tmp['reallocation'] = $reallocation;
+ $tmp['spundown'] = $spundown;
+ $ret[] = $tmp;
}
+ else {
+ $this->_set_last_error();
- if ($sort) {
- for ($i = 0; $i < sizeof($ret); $i++) {
- for ($ii = 0; $ii < sizeof($ret); $ii++) {
- if (strcmp($ret[$i]['device'], $ret[$ii]['device']) < 0) {
- $tmp = $ret[$i];
- $ret[$i] = $ret[$ii];
- $ret[$ii] = $tmp;
- }
- }
- }
+ $ret[] = [
+ 'device' => $cds[$i],
+ 'file' => $files[$i],
+ 'type' => '-',
+ 'capacity' => '-',
+ 'allocation' => '-',
+ 'physical' => '-',
+ 'bus' => $buses[$i],
+ 'reallocation' => $reallocation,
+ 'spundown' => $spundown
+ ];
}
-
- unset($domainXML);
- unset($arrDomain) ;
- unset($disk) ;
- return $ret;
}
- function get_domain_type($domain) {
- $dom = $this->get_domain_object($domain);
+ if ($sort) {
+ for ($i = 0; $i < sizeof($ret); $i++) {
+ for ($ii = 0; $ii < sizeof($ret); $ii++) {
+ if (strcmp($ret[$i]['device'], $ret[$ii]['device']) < 0) {
+ $tmp = $ret[$i];
+ $ret[$i] = $ret[$ii];
+ $ret[$ii] = $tmp;
+ }
+ }
+ }
+ }
- $tmp = $this->get_xpath($dom, '//domain/@type', false);
+ unset($buses);
+ unset($cds);
+ unset($files);
+ return $ret;
+ }
+
+ function get_disk_stats($domain, $sort=true) {
+ $dom = $this->get_domain_object($domain);
+
+ $domainXML = $this->domain_get_xml($dom);
+ $arrDomain = new SimpleXMLElement($domainXML);
+ $arrDomain = $arrDomain->devices->disk;
+
+ $ret = [];
+ foreach ($arrDomain as $disk) {
+ if ($disk->attributes()->device != "disk") continue;
+ $tmp = libvirt_domain_get_block_info($dom, $disk->target->attributes()->dev);
+
+ if ($tmp) {
+ $tmp['bus'] = $disk->target->attributes()->bus->__toString();
+ $tmp["boot order"] = $disk->boot->attributes()->order ?? "";
+ $tmp["discard"] = $disk->driver->attributes()->discard ?? "ignore";
+ $tmp["rotation"] = $disk->target->attributes()->rotation_rate ?? "0";
+ $tmp['serial'] = $disk->serial;
+
+ // Libvirt reports 0 bytes for raw disk images that haven't been
+ // written to yet so we just report the raw disk size for now
+ if ( !empty($tmp['file']) &&
+ $tmp['type'] == 'raw' &&
+ empty($tmp['physical']) &&
+ is_file($tmp['file']) ) {
+
+ $intSize = filesize($tmp['file']);
+ $tmp['physical'] = $intSize;
+ $tmp['capacity'] = $intSize;
+ }
+
+ $ret[] = $tmp;
+ }
+ else {
+ $this->_set_last_error();
+
+ $ret[] = [
+ 'device' => $disk->target->attributes()->dev->__toString(),
+ 'file' => $disk->source->attributes()->file,
+ 'type' => '-',
+ 'capacity' => '-',
+ 'allocation' => '-',
+ 'physical' => '-',
+ 'bus' => $disk->target->attributes()->bus->__toString(),
+ 'boot order' => $disk->boot->attributes()->order ,
+ 'rotation' => $disk->target->attributes()->rotation_rate ?? "0",
+ 'serial' => $disk->serial,
+ 'discard' => $disk->driver->attributes()->discard ?? "ignore"
+ ];
+ }
+ }
+
+ if ($sort) {
+ for ($i = 0; $i < sizeof($ret); $i++) {
+ for ($ii = 0; $ii < sizeof($ret); $ii++) {
+ if (strcmp($ret[$i]['device'], $ret[$ii]['device']) < 0) {
+ $tmp = $ret[$i];
+ $ret[$i] = $ret[$ii];
+ $ret[$ii] = $tmp;
+ }
+ }
+ }
+ }
+
+ unset($domainXML);
+ unset($arrDomain);
+ unset($disk);
+ return $ret;
+ }
+
+ function get_domain_type($domain) {
+ $dom = $this->get_domain_object($domain);
+
+ $tmp = $this->get_xpath($dom, '//domain/@type', false);
+ if ($tmp['num'] == 0)
+ return $this->_set_last_error();
+
+ $ret = $tmp[0];
+ unset($tmp);
+ return $ret;
+ }
+
+ function get_domain_emulator($domain) {
+ $dom = $this->get_domain_object($domain);
+
+ $tmp = $this->get_xpath($dom, '//domain/devices/emulator', false);
if ($tmp['num'] == 0)
return $this->_set_last_error();
- $ret = $tmp[0];
- unset($tmp);
+ $ret = $tmp[0];
+ unset($tmp);
- return $ret;
+ return $ret;
+ }
+
+ function get_disk_capacity($domain, $physical=false, $disk='*', $unit='?') {
+ $dom = $this->get_domain_object($domain);
+ $tmp = $this->get_disk_stats($dom);
+
+ $ret = 0;
+ for ($i = 0; $i < sizeof($tmp); $i++) {
+ if (($disk == '*') || ($tmp[$i]['device'] == $disk))
+ if ($physical) {
+ if($tmp[$i]['physical'] == "-") $tmp[$i]['physical'] = "0";
+ $ret += $tmp[$i]['physical'];
+ } else {
+ if($tmp[$i]['capacity'] == "-") $tmp[$i]['capacity'] = "0";
+ $ret += $tmp[$i]['capacity'];
+ }
+ }
+ unset($tmp);
+ return $this->format_size($ret, 0, $unit);
+ }
+
+ function get_disk_count($domain) {
+ $dom = $this->get_domain_object($domain);
+ $tmp = $this->get_disk_stats($dom);
+ $ret = sizeof($tmp);
+ unset($tmp);
+ return $ret;
+ }
+
+ function get_disk_fstype($domain) {
+ $dom = $this->get_domain_object($domain);
+ $tmp = $this->get_disk_stats($dom);
+ $dirname = transpose_user_path($tmp[0]['file']);
+ $pathinfo = pathinfo($dirname);
+ $parent = $pathinfo["dirname"];
+ $fstype = strtoupper(trim(shell_exec(" stat -f -c '%T' $parent")));
+ if ($fstype != "ZFS") $fstype = "QEMU";
+ #if ($fstype != "ZFS" && $fstype != "BTRFS") $fstype = "QEMU";
+ unset($tmp);
+ return $fstype;
+ }
+
+ function format_size($value, $decimals, $unit='?') {
+ if ($value == '-')
+ return 'unknown';
+
+ /* Autodetect unit that's appropriate */
+ if ($unit == '?') {
+ /* (1 << 40) is not working correctly on i386 systems */
+ if ($value >= 1099511627776)
+ $unit = 'T';
+ else
+ if ($value >= (1 << 30))
+ $unit = 'G';
+ else
+ if ($value >= (1 << 20))
+ $unit = 'M';
+ else
+ if ($value >= (1 << 10))
+ $unit = 'K';
+ else
+ $unit = 'B';
}
- function get_domain_emulator($domain) {
- $dom = $this->get_domain_object($domain);
+ $unit = strtoupper($unit);
- $tmp = $this->get_xpath($dom, '//domain/devices/emulator', false);
- if ($tmp['num'] == 0)
- return $this->_set_last_error();
+ switch ($unit) {
+ case 'T': return number_format($value / (float)1099511627776, $decimals +2).'T';
+ case 'G': return number_format($value / (float)(1 << 30), $decimals).'G';
+ case 'M': return number_format($value / (float)(1 << 20), $decimals).'M';
+ case 'K': return number_format($value / (float)(1 << 10), $decimals).'K';
+ case 'B': return $value.'B';
+ }
+ return false;
+ }
- $ret = $tmp[0];
- unset($tmp);
+ function get_uri() {
+ $tmp = libvirt_connect_get_uri($this->conn);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
- return $ret;
+ function get_domain_count() {
+ $tmp = libvirt_domain_get_counts($this->conn);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function translate_volume_type($type) {
+ if ($type == 1)
+ return 'Block device';
+ return 'File image';
+ }
+
+ function translate_perms($mode) {
+ $mode = (string)((int)$mode);
+
+ $tmp = '---------';
+
+ for ($i = 0; $i < 3; $i++) {
+ $bits = (int)$mode[$i];
+ if ($bits & 4)
+ $tmp[ ($i * 3) ] = 'r';
+ if ($bits & 2)
+ $tmp[ ($i * 3) + 1 ] = 'w';
+ if ($bits & 1)
+ $tmp[ ($i * 3) + 2 ] = 'x';
}
- function get_disk_capacity($domain, $physical=false, $disk='*', $unit='?') {
- $dom = $this->get_domain_object($domain);
- $tmp = $this->get_disk_stats($dom);
+ return $tmp;
+ }
- $ret = 0;
- for ($i = 0; $i < sizeof($tmp); $i++) {
- if (($disk == '*') || ($tmp[$i]['device'] == $disk))
- if ($physical) {
- if($tmp[$i]['physical'] == "-") $tmp[$i]['physical'] = "0" ;
- $ret += $tmp[$i]['physical'];
- } else {
- if($tmp[$i]['capacity'] == "-") $tmp[$i]['capacity'] = "0" ;
- $ret += $tmp[$i]['capacity'];
- }
- }
- unset($tmp);
+ function parse_size($size) {
+ $unit = $size[ strlen($size) - 1 ];
- return $this->format_size($ret, 0, $unit);
+ $size = (int)$size;
+ switch (strtoupper($unit)) {
+ case 'T': $size *= 1099511627776;
+ break;
+ case 'G': $size *= 1073741824;
+ break;
+ case 'M': $size *= 1048576;
+ break;
+ case 'K': $size *= 1024;
+ break;
+ }
+ return $size;
+ }
+
+ //create a storage volume and add file extension
+ /*function volume_create($name, $capacity, $allocation, $format) {
+ $capacity = $this->parse_size($capacity);
+ $allocation = $this->parse_size($allocation);
+ ($format != 'raw' ) ? $ext = $format : $ext = 'img';
+ ($ext == pathinfo($name, PATHINFO_EXTENSION)) ? $ext = '': $name .= '.';
+
+ $xml = "\n".
+ " $name$ext\n".
+ " $capacity\n".
+ " $allocation\n".
+ " \n".
+ " \n".
+ " \n".
+ "";
+
+ $tmp = libvirt_storagevolume_create_xml($pool, $xml);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }*/
+
+ function get_hypervisor_name() {
+ $tmp = libvirt_connect_get_information($this->conn);
+ $hv = $tmp['hypervisor'];
+ unset($tmp);
+
+ switch (strtoupper($hv)) {
+ case 'QEMU': $type = 'qemu';
+ break;
+
+ default:
+ $type = $hv;
+ }
+ return $type;
+ }
+
+ function get_connect_information() {
+ $tmp = libvirt_connect_get_information($this->conn);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function domain_get_icon_url($domain) {
+ global $docroot;
+
+ $strIcon = $this->_get_single_xpath_result($domain, '//domain/metadata/*[local-name()=\'vmtemplate\']/@icon');
+ if (empty($strIcon)) {
+ $strIcon = ($this->domain_get_clock_offset($domain) == 'localtime' ? 'windows.png' : 'linux.png');
}
- function get_disk_count($domain) {
- $dom = $this->get_domain_object($domain);
- $tmp = $this->get_disk_stats($dom);
- $ret = sizeof($tmp);
- unset($tmp);
-
- return $ret;
+ if (is_file($strIcon)) {
+ return $strIcon;
+ } elseif (is_file("$docroot/plugins/dynamix.vm.manager/templates/images/".$strIcon)) {
+ return '/plugins/dynamix.vm.manager/templates/images/'.$strIcon;
+ } elseif (is_file("$docroot/boot/config/plugins/dynamix.vm.manager/templates/images/".$strIcon)) {
+ return '/boot/config/plugins/dynamix.vm.manager/templates/images/'.$strIcon;
}
+ return '/plugins/dynamix.vm.manager/templates/images/default.png';
+ }
- function get_disk_fstype($domain) {
- $dom = $this->get_domain_object($domain);
- $tmp = $this->get_disk_stats($dom);
- $dirname = transpose_user_path($tmp[0]['file']);
- $pathinfo = pathinfo($dirname);
- $parent = $pathinfo["dirname"];
- $fstype = strtoupper(trim(shell_exec(" stat -f -c '%T' $parent")));
- if ($fstype != "ZFS") $fstype = "QEMU";
- #if ($fstype != "ZFS" && $fstype != "BTRFS") $fstype = "QEMU";
- unset($tmp);
-
- return $fstype;
- }
-
- function format_size($value, $decimals, $unit='?') {
- if ($value == '-')
- return 'unknown';
-
- /* Autodetect unit that's appropriate */
- if ($unit == '?') {
- /* (1 << 40) is not working correctly on i386 systems */
- if ($value >= 1099511627776)
- $unit = 'T';
- else
- if ($value >= (1 << 30))
- $unit = 'G';
- else
- if ($value >= (1 << 20))
- $unit = 'M';
- else
- if ($value >= (1 << 10))
- $unit = 'K';
- else
- $unit = 'B';
- }
-
- $unit = strtoupper($unit);
-
- switch ($unit) {
- case 'T': return number_format($value / (float)1099511627776, $decimals +2).'T';
- case 'G': return number_format($value / (float)(1 << 30), $decimals).'G';
- case 'M': return number_format($value / (float)(1 << 20), $decimals).'M';
- case 'K': return number_format($value / (float)(1 << 10), $decimals).'K';
- case 'B': return $value.'B';
- }
+ function domain_change_xml($domain, $xml) {
+ $dom = $this->get_domain_object($domain);
+ if (!($old_xml = $this->domain_get_xml($dom)))
+ return $this->_set_last_error();
+ if (!libvirt_domain_undefine($dom))
+ return $this->_set_last_error();
+ if (!libvirt_domain_define_xml($this->conn, $xml)) {
+ $this->last_error = libvirt_get_last_error();
+ libvirt_domain_define_xml($this->conn, $old_xml);
return false;
}
+ return true;
+ }
- function get_uri() {
- $tmp = libvirt_connect_get_uri($this->conn);
- return ($tmp) ? $tmp : $this->_set_last_error();
+ function get_domains() {
+ $tmp = libvirt_list_domains($this->conn);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function get_active_domain_ids() {
+ $tmp = libvirt_list_active_domain_ids($this->conn);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function get_domain_by_name($name) {
+ $tmp = @libvirt_domain_lookup_by_name($this->conn, $name);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function get_node_devices($dev = false) {
+ $tmp = ($dev == false) ? libvirt_list_nodedevs($this->conn) : libvirt_list_nodedevs($this->conn, $dev);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function get_interface_addresses($domain,$flag) {
+ $tmp = libvirt_domain_interface_addresses($domain,$flag);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function get_node_device_res($res) {
+ if ($res == false)
+ return false;
+ if (is_resource($res))
+ return $res;
+
+ $tmp = libvirt_nodedev_get($this->conn, $res);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function get_node_device_caps($dev) {
+ $dev = $this->get_node_device_res($dev);
+
+ $tmp = libvirt_nodedev_capabilities($dev);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function get_node_device_cap_options() {
+ $all = $this->get_node_devices();
+
+ $ret = [];
+ for ($i = 0; $i < sizeof($all); $i++) {
+ $tmp = $this->get_node_device_caps($all[$i]);
+
+ for ($ii = 0; $ii < sizeof($tmp); $ii++)
+ if (!in_array($tmp[$ii], $ret))
+ $ret[] = $tmp[$ii];
}
+ return $ret;
+ }
- function get_domain_count() {
- $tmp = libvirt_domain_get_counts($this->conn);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
+ function get_node_device_xml($dev) {
+ $dev = $this->get_node_device_res($dev);
- function translate_volume_type($type) {
- if ($type == 1)
- return 'Block device';
+ $tmp = libvirt_nodedev_get_xml_desc($dev, NULL);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
- return 'File image';
- }
+ function get_node_device_information($dev) {
+ $dev = $this->get_node_device_res($dev);
- function translate_perms($mode) {
- $mode = (string)((int)$mode);
+ if ($dev) $tmp = libvirt_nodedev_get_information($dev); else $tmp = $dev;
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
- $tmp = '---------';
+ function domain_get_name($res) {
+ return libvirt_domain_get_name($res);
+ }
- for ($i = 0; $i < 3; $i++) {
- $bits = (int)$mode[$i];
- if ($bits & 4)
- $tmp[ ($i * 3) ] = 'r';
- if ($bits & 2)
- $tmp[ ($i * 3) + 1 ] = 'w';
- if ($bits & 1)
- $tmp[ ($i * 3) + 2 ] = 'x';
- }
+ function domain_get_info_call($name = false, $name_override = false) {
+ $ret = [];
-
- return $tmp;
- }
-
- function parse_size($size) {
- $unit = $size[ strlen($size) - 1 ];
-
- $size = (int)$size;
- switch (strtoupper($unit)) {
- case 'T': $size *= 1099511627776;
- break;
- case 'G': $size *= 1073741824;
- break;
- case 'M': $size *= 1048576;
- break;
- case 'K': $size *= 1024;
- break;
- }
-
- return $size;
- }
-
- //create a storage volume and add file extension
- /*function volume_create($name, $capacity, $allocation, $format) {
- $capacity = $this->parse_size($capacity);
- $allocation = $this->parse_size($allocation);
- ($format != 'raw' ) ? $ext = $format : $ext = 'img';
- ($ext == pathinfo($name, PATHINFO_EXTENSION)) ? $ext = '': $name .= '.';
-
- $xml = "\n".
- " $name$ext\n".
- " $capacity\n".
- " $allocation\n".
- " \n".
- " \n".
- " \n".
- "";
-
- $tmp = libvirt_storagevolume_create_xml($pool, $xml);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }*/
-
- function get_hypervisor_name() {
- $tmp = libvirt_connect_get_information($this->conn);
- $hv = $tmp['hypervisor'];
- unset($tmp);
-
- switch (strtoupper($hv)) {
- case 'QEMU': $type = 'qemu';
- break;
-
- default:
- $type = $hv;
- }
-
- return $type;
- }
-
- function get_connect_information() {
- $tmp = libvirt_connect_get_information($this->conn);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function domain_get_icon_url($domain) {
- global $docroot;
-
- $strIcon = $this->_get_single_xpath_result($domain, '//domain/metadata/*[local-name()=\'vmtemplate\']/@icon');
- if (empty($strIcon)) {
- $strIcon = ($this->domain_get_clock_offset($domain) == 'localtime' ? 'windows.png' : 'linux.png');
- }
-
- if (is_file($strIcon)) {
- return $strIcon;
- } elseif (is_file("$docroot/plugins/dynamix.vm.manager/templates/images/" . $strIcon)) {
- return '/plugins/dynamix.vm.manager/templates/images/' . $strIcon;
- } elseif (is_file("$docroot/boot/config/plugins/dynamix.vm.manager/templates/images/" . $strIcon)) {
- return '/boot/config/plugins/dynamix.vm.manager/templates/images/' . $strIcon;
- }
-
- return '/plugins/dynamix.vm.manager/templates/images/default.png';
- }
-
- function domain_change_xml($domain, $xml) {
- $dom = $this->get_domain_object($domain);
-
- if (!($old_xml = $this->domain_get_xml($dom)))
- return $this->_set_last_error();
- if (!libvirt_domain_undefine($dom))
- return $this->_set_last_error();
- if (!libvirt_domain_define_xml($this->conn, $xml)) {
- $this->last_error = libvirt_get_last_error();
- libvirt_domain_define_xml($this->conn, $old_xml);
+ if ($name != false) {
+ $dom = $this->get_domain_object($name);
+ if (!$dom)
return false;
- }
- return true;
- }
-
- function get_domains() {
- $tmp = libvirt_list_domains($this->conn);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function get_active_domain_ids() {
- $tmp = libvirt_list_active_domain_ids($this->conn);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function get_domain_by_name($name) {
- $tmp = @libvirt_domain_lookup_by_name($this->conn, $name);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function get_node_devices($dev = false) {
- $tmp = ($dev == false) ? libvirt_list_nodedevs($this->conn) : libvirt_list_nodedevs($this->conn, $dev);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function get_interface_addresses($domain,$flag) {
- $tmp = libvirt_domain_interface_addresses($domain,$flag);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function get_node_device_res($res) {
- if ($res == false)
- return false;
- if (is_resource($res))
- return $res;
-
- $tmp = libvirt_nodedev_get($this->conn, $res);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function get_node_device_caps($dev) {
- $dev = $this->get_node_device_res($dev);
-
- $tmp = libvirt_nodedev_capabilities($dev);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function get_node_device_cap_options() {
- $all = $this->get_node_devices();
-
- $ret = [];
- for ($i = 0; $i < sizeof($all); $i++) {
- $tmp = $this->get_node_device_caps($all[$i]);
-
- for ($ii = 0; $ii < sizeof($tmp); $ii++)
- if (!in_array($tmp[$ii], $ret))
- $ret[] = $tmp[$ii];
- }
+ if ($name_override)
+ $name = $name_override;
+ $ret[$name] = libvirt_domain_get_info($dom);
return $ret;
}
-
- function get_node_device_xml($dev) {
- $dev = $this->get_node_device_res($dev);
-
- $tmp = libvirt_nodedev_get_xml_desc($dev, NULL);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function get_node_device_information($dev) {
- $dev = $this->get_node_device_res($dev);
-
- if ($dev) $tmp = libvirt_nodedev_get_information($dev); else $tmp = $dev ;
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function domain_get_name($res) {
- return libvirt_domain_get_name($res);
- }
-
- function domain_get_info_call($name = false, $name_override = false) {
- $ret = [];
-
- if ($name != false) {
- $dom = $this->get_domain_object($name);
- if (!$dom)
- return false;
-
- if ($name_override)
- $name = $name_override;
-
- $ret[$name] = libvirt_domain_get_info($dom);
- return $ret;
+ else {
+ $doms = libvirt_list_domains($this->conn);
+ foreach ($doms as $dom) {
+ $tmp = $this->get_domain_object($dom);
+ $ret[$dom] = libvirt_domain_get_info($tmp);
}
- else {
- $doms = libvirt_list_domains($this->conn);
- foreach ($doms as $dom) {
- $tmp = $this->get_domain_object($dom);
- $ret[$dom] = libvirt_domain_get_info($tmp);
- }
- }
-
- ksort($ret);
- return $ret;
}
- function domain_get_info($name = false, $name_override = false) {
- if (!$name)
- return false;
+ ksort($ret);
+ return $ret;
+ }
- if (!$this->allow_cached)
- return $this->domain_get_info_call($name, $name_override);
+ function domain_get_info($name = false, $name_override = false) {
+ if (!$name)
+ return false;
- $domname = $name_override ? $name_override : $name;
- $dom = $this->get_domain_object($domname);
- $domkey = $name_override ? $name_override : $this->domain_get_name($dom);
- if (!array_key_exists($domkey, $this->dominfos)) {
- $tmp = $this->domain_get_info_call($name, $name_override);
- $this->dominfos[$domkey] = $tmp[$domname];
- }
+ if (!$this->allow_cached)
+ return $this->domain_get_info_call($name, $name_override);
- return $this->dominfos[$domkey];
+ $domname = $name_override ? $name_override : $name;
+ $dom = $this->get_domain_object($domname);
+ $domkey = $name_override ? $name_override : $this->domain_get_name($dom);
+ if (!array_key_exists($domkey, $this->dominfos)) {
+ $tmp = $this->domain_get_info_call($name, $name_override);
+ $this->dominfos[$domkey] = $tmp[$domname];
}
+ return $this->dominfos[$domkey];
+ }
- function get_last_error() {
- return $this->last_error;
- }
+ function get_last_error() {
+ return $this->last_error;
+ }
- function domain_get_xml($domain, $xpath = NULL) {
- $dom = $this->get_domain_object($domain);
- if (!$dom)
- return false;
+ function domain_get_xml($domain, $xpath = NULL) {
+ $dom = $this->get_domain_object($domain);
+ if (!$dom)
+ return false;
- $tmp = libvirt_domain_get_xml_desc($dom, 0);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
+ $tmp = libvirt_domain_get_xml_desc($dom, 0);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
- function domain_get_id($domain, $name = false) {
- $dom = $this->get_domain_object($domain);
- if ((!$dom) || (!$this->domain_is_running($dom, $name)))
- return false;
+ function domain_get_id($domain, $name = false) {
+ $dom = $this->get_domain_object($domain);
+ if ((!$dom) || (!$this->domain_is_running($dom, $name)))
+ return false;
- $tmp = libvirt_domain_get_id($dom);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
+ $tmp = libvirt_domain_get_id($dom);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
- function domain_get_interface_stats($domain, $iface) {
- $dom = $this->get_domain_object($domain);
- if (!$dom)
- return false;
+ function domain_get_interface_stats($domain, $iface) {
+ $dom = $this->get_domain_object($domain);
+ if (!$dom)
+ return false;
- $tmp = libvirt_domain_interface_stats($dom, $iface);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
+ $tmp = libvirt_domain_interface_stats($dom, $iface);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
- function domain_get_interface_devices($res) {
- $tmp = libvirt_domain_get_interface_devices($res);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
+ function domain_get_interface_devices($res) {
+ $tmp = libvirt_domain_get_interface_devices($res);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
- function domain_interface_addresses($domain,$flag) {
- $tmp = libvirt_domain_interface_addresses($domain,$flag);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
+ function domain_interface_addresses($domain,$flag) {
+ $tmp = libvirt_domain_interface_addresses($domain,$flag);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
- function domain_get_memory_stats($domain) {
- $dom = $this->get_domain_object($domain);
- if (!$dom)
- return false;
+ function domain_get_memory_stats($domain) {
+ $dom = $this->get_domain_object($domain);
+ if (!$dom)
+ return false;
- $tmp = libvirt_domain_memory_stats($dom);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
+ $tmp = libvirt_domain_memory_stats($dom);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
- function domain_get_all_domain_stats() {
- $tmp = libvirt_connect_get_all_domain_stats($this->conn);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
+ function domain_get_all_domain_stats() {
+ $tmp = libvirt_connect_get_all_domain_stats($this->conn);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
- function domain_start($dom) {
- $dom=$this->get_domain_object($dom);
- if ($dom) {
- $ret = libvirt_domain_create($dom);
- $this->last_error = libvirt_get_last_error();
- return $ret;
- }
-
- $ret = libvirt_domain_create_xml($this->conn, $dom);
+ function domain_start($dom) {
+ $dom=$this->get_domain_object($dom);
+ if ($dom) {
+ $ret = libvirt_domain_create($dom);
$this->last_error = libvirt_get_last_error();
return $ret;
}
- function domain_define($xml, $autostart=false) {
- if (strpos($xml,'') || strpos($xml,'')) {
- $tmp = explode("\n", $xml);
- for ($i = 0; $i < sizeof($tmp); $i++)
- if (strpos('.'.$tmp[$i], "";
- $xml = join("\n", $tmp);
- }
+ $ret = libvirt_domain_create_xml($this->conn, $dom);
+ $this->last_error = libvirt_get_last_error();
+ return $ret;
+ }
- if ($autostart) {
- $tmp = libvirt_domain_create_xml($this->conn, $xml);
- if (!$tmp)
- return $this->_set_last_error();
- }
-
- $tmp = libvirt_domain_define_xml($this->conn, $xml);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function domain_destroy($domain) {
- $dom = $this->get_domain_object($domain);
- if (!$dom)
- return false;
-
- $tmp = libvirt_domain_destroy($dom);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function domain_reboot($domain) {
- $dom = $this->get_domain_object($domain);
- if (!$dom)
- return false;
-
- $tmp = libvirt_domain_reboot($dom);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function domain_suspend($domain) {
- $dom = $this->get_domain_object($domain);
- if (!$dom)
- return false;
-
- $tmp = libvirt_domain_suspend($dom);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function domain_save($domain) {
- $dom = $this->get_domain_object($domain);
- if (!$dom)
- return false;
-
- $tmp = libvirt_domain_managedsave($dom);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function domain_resume($domain) {
- $dom = $this->get_domain_object($domain);
- if (!$dom)
- return false;
-
- $tmp = libvirt_domain_resume($dom);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function domain_get_uuid($domain) {
- $dom = $this->get_domain_object($domain);
- if (!$dom)
- return false;
-
- $tmp = libvirt_domain_get_uuid_string($dom);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function domain_get_domain_by_uuid($uuid) {
- $dom = libvirt_domain_lookup_by_uuid_string($this->conn, $uuid);
- return ($dom) ? $dom : $this->_set_last_error();
- }
-
- function domain_get_name_by_uuid($uuid) {
- $dom = $this->domain_get_domain_by_uuid($uuid);
- if (!$dom)
- return false;
- $tmp = libvirt_domain_get_name($dom);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function domain_is_active($domain) {
- $domain = $this->get_domain_object($domain);
- $tmp = libvirt_domain_is_active($domain);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function domain_qemu_agent_command($domain,$cmd,$timeout,$flags) {
- $domain = $this->get_domain_object($domain);
- $tmp = libvirt_domain_qemu_agent_command($domain,$cmd,$timeout,$flags);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function generate_uuid($seed=false) {
- if (!$seed)
- $seed = time();
- srand($seed);
-
- $ret = [];
- for ($i = 0; $i < 16; $i++)
- $ret[] = $this->macbyte(rand() % 256);
-
- $a = $ret[0].$ret[1].$ret[2].$ret[3];
- $b = $ret[4].$ret[5];
- $c = $ret[6].$ret[7];
- $d = $ret[8].$ret[9];
- $e = $ret[10].$ret[11].$ret[12].$ret[13].$ret[14].$ret[15];
-
- return $a.'-'.$b.'-'.$c.'-'.$d.'-'.$e;
- }
-
- function domain_generate_uuid() {
- $uuid = $this->generate_uuid();
-
- //while ($this->domain_get_name_by_uuid($uuid))
- //$uuid = $this->generate_uuid();
-
- return $uuid;
- }
-
- function domain_shutdown($domain) {
- $dom = $this->get_domain_object($domain);
- if (!$dom)
- return false;
-
- $tmp = libvirt_domain_shutdown($dom);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function domain_undefine($domain) {
- $dom = $this->get_domain_object($domain);
- if (!$dom)
- return false;
-
- $uuid = $this->domain_get_uuid($dom);
- // remove OVMF VARS if this domain had them
- if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd')) {
- unlink('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd');
- }
- if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd')) {
- unlink('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd');
- }
-
- $tmp = libvirt_domain_undefine($dom);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- function domain_delete($domain) {
- $dom = $this->get_domain_object($domain);
- if (!$dom)
- return false;
- $disks = $this->get_disk_stats($dom);
- $tmp = $this->domain_undefine($dom);
- if (!$tmp)
- return $this->_set_last_error();
-
- // remove the first disk only
- if (array_key_exists('file', $disks[0])) {
- $disk = $disks[0]['file'];
- $pathinfo = pathinfo($disk);
- $dir = $pathinfo['dirname'];
-
- // remove the vm config
- $cfg_vm = $dir.'/'.$domain.'.cfg';
- if (is_file($cfg_vm)) unlink($cfg_vm);
-
- $cfg = $dir.'/'.$pathinfo['filename'].'.cfg';
- $xml = $dir.'/'.$pathinfo['filename'].'.xml';
- if (is_file($disk)) unlink($disk);
- if (is_file($cfg)) unlink($cfg);
- if (is_file($xml)) unlink($xml);
- if (is_dir($dir) && $this->is_dir_empty($dir)) {
- $result= my_rmdir($dir);
- if ($result['type'] == "zfs") {
- qemu_log("$domain","delete empty zfs $dir {$result['rtncode']}");
- if (isset($result['dataset'])) qemu_log("$domain","dataset {$result['dataset']} ");
- if (isset($result['cmd'])) qemu_log("$domain","Command {$result['cmd']} ");
- if (isset($result['output'])) {
- $outputlogs = implode(" ",$result['output']);
- qemu_log("$domain","Output $outputlogs end");
- }
- }
- else qemu_log("$domain","delete empty $dir {$result['rtncode']}");
- }
- }
-
- return true;
- }
-
- function nvram_backup($uuid) {
- // move OVMF VARS to a backup file if this domain has them
- if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd')) {
- rename('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd', '/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd_backup');
- return true;
- }
- if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd')) {
- rename('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd', '/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd_backup');
- return true;
- }
-
- return false;
- }
-
- function nvram_restore($uuid) {
- // restore backup OVMF VARS if this domain had them
- if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd_backup')) {
- rename('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd_backup', '/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd');
- return true;
- }
- if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd_backup')) {
- rename('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd_backup', '/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd');
- return true;
- }
-
- return false;
- }
-
- function nvram_rename($uuid,$newuuid) {
- // rename backup OVMF VARS if this domain had them
- if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd')) {
- rename('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd_backup', '/etc/libvirt/qemu/nvram/'.$newuuid.'_VARS-pure-efi.fd');
- return true;
- }
- if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd')) {
- rename('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd_backup', '/etc/libvirt/qemu/nvram/'.$newuuid.'_VARS-pure-efi-tpm.fd');
- return true;
- }
-
- return false;
- }
-
- function nvram_create_snapshot($uuid,$snapshotname) {
- // snapshot backup OVMF VARS if this domain had them
- if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd')) {
- copy('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd', '/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi.fd');
- return true;
- }
- if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd')) {
- copy('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd', '/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi-tpm.fd');
- return true;
- }
- return false;
- }
-
- function nvram_revert_snapshot($uuid,$snapshotname) {
- // snapshot backup OVMF VARS if this domain had them
- if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi.fd')) {
- copy('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi.fd', '/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd');
- unlink('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi.fd') ;
- return true;
- }
- if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi-tpm.fd')) {
- copy('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi-tpm.fd', '/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd');
- unlink('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi-tpm.fd') ;
- return true;
- }
- return false;
- }
-
- function nvram_delete_snapshot($uuid,$snapshotname) {
- // snapshot backup OVMF VARS if this domain had them
- if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi.fd')) {
- unlink('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi.fd') ;
- return true;
- }
- if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi-tpm.fd')) {
- unlink('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi-tpm.fd') ;
- return true;
- }
- return false;
- }
-
-
- function is_dir_empty($dir) {
- if (!is_readable($dir)) return NULL;
- $handle = opendir($dir);
- while (false !== ($entry = readdir($handle))) {
- if ($entry != "." && $entry != "..") {
- return FALSE;
- }
- }
- return TRUE;
- }
-
- function domain_is_running($domain, $name = false) {
- $dom = $this->get_domain_object($domain);
- if (!$dom)
- return false;
-
- $tmp = $this->domain_get_info( $domain, $name );
- if (!$tmp)
- return $this->_set_last_error();
- $ret = ( ($tmp['state'] == VIR_DOMAIN_RUNNING) || ($tmp['state'] == VIR_DOMAIN_BLOCKED) || ($tmp['state'] == 7 /*VIR_DOMAIN_PMSUSPENDED*/) );
- unset($tmp);
- return $ret;
- }
-
- function domain_get_state($domain) {
- $dom = $this->get_domain_object($domain);
- if (!$dom)
- return false;
-
- $info = libvirt_domain_get_info($dom);
- if (!$info)
- return $this->_set_last_error();
-
- return $this->domain_state_translate($info['state']);
- }
-
- function domain_state_translate($state) {
- switch ($state) {
- case VIR_DOMAIN_RUNNING: return 'running';
- case VIR_DOMAIN_NOSTATE: return 'nostate';
- case VIR_DOMAIN_BLOCKED: return 'blocked';
- case VIR_DOMAIN_PAUSED: return 'paused';
- case VIR_DOMAIN_SHUTDOWN: return 'shutdown';
- case VIR_DOMAIN_SHUTOFF: return 'shutoff';
- case VIR_DOMAIN_CRASHED: return 'crashed';
- //VIR_DOMAIN_PMSUSPENDED is 7 (not defined in libvirt-php yet)
- case 7: return 'pmsuspended';
- }
-
- return 'unknown';
- }
-
- function domain_get_vnc_port($domain) {
- $tmp = $this->get_xpath($domain, '//domain/devices/graphics[@type="spice" or @type="vnc"]/@port', false);
- $var = (int)$tmp[0];
- unset($tmp);
-
- return $var;
- }
-
- function domain_get_vmrc_autoport($domain) {
- $tmp = $this->get_xpath($domain, '//domain/devices/graphics[@type="spice" or @type="vnc"]/@autoport', false);
- $var = $tmp[0];
- unset($tmp);
-
- return $var;
- }
-
- function domain_get_vmrc_protocol($domain) {
- $tmp = $this->get_xpath($domain, '//domain/devices/graphics/@type', false);
- $var = $tmp[0];
- unset($tmp);
-
- return $var;
- }
-
- function domain_get_vnc_model($domain) {
- $tmp = $this->get_xpath($domain, '//domain/devices/video/model/@type', false);
- if (!$tmp)
- return 'qxl';
-
- $var = $tmp[0];
- unset($tmp);
-
- if ($var=="virtio") {
- $tmp = $this->get_xpath($domain, '//domain/devices/video/model/acceleration/@accel3d', false);
- if ($tmp[0] == "yes") $var = "virtio3d";
- unset($tmp);
- }
-
- return $var;
- }
-
- function domain_get_vnc_render($domain) {
- $tmp = $this->get_xpath($domain, '//domain/devices/graphics[@type="egl-headless"]/gl/@rendernode', false);
- if (!$tmp)
- return 'auto';
-
- $var = $tmp[0];
- unset($tmp);
-
- if (!str_contains($var,"pci")) $var = trim(shell_exec("udevadm info -q symlink -r $var"));
- $var = str_replace(['/dev/dri/by-path/pci-0000:','-render'],['',''],$var);
- return $var;
- }
-
- function domain_get_vnc_display_options($domain) {
- $tmp = $this->get_xpath($domain, '//domain/devices/video/model/@heads', false);
- if (!$tmp)
- $heads=1;
-
- $heads = $tmp[0];
- unset($tmp);
-
- $tmp = $this->get_xpath($domain, '//domain/devices/video/model/@vram', false);
- if (!$tmp)
- $vram=16384/1024;
-
- $vram = $tmp[0]/1024;
- unset($tmp);
-
- $var = "H$heads.{$vram}M";
- return $var;
- }
-
- function domain_get_vnc_keymap($domain) {
- $tmp = $this->get_xpath($domain, '//domain/devices/graphics/@keymap', false);
- if (!$tmp)
- return 'none';
-
- $var = $tmp[0];
- unset($tmp);
-
- return $var;
- }
-
- function domain_get_vnc_password($domain) {
- $domain_name = $this->domain_get_name($domain) ;
- $password = shell_exec("cat /etc/libvirt/qemu/'{$domain_name}.xml' | grep 'passwd'") ;
-
- if (!$password)
- return '';
-
- $strpos = strpos($password, "passwd=") +8 ;
- $endpos = strpos($password, "'",$strpos) ;
- $password = substr($password,$strpos, $endpos-$strpos) ;
-
- return $password ;
- }
-
- function domain_get_ws_port($domain) {
- $tmp = $this->get_xpath($domain, '//domain/devices/graphics/@websocket', false);
- $var = (int)$tmp[0];
- unset($tmp);
-
- return $var;
- }
-
- function domain_get_arch($domain) {
- $tmp = $this->get_xpath($domain, '//domain/os/type/@arch', false);
- $var = $tmp[0];
- unset($tmp);
-
- return $var;
- }
-
- function domain_get_machine($domain) {
- $tmp = $this->get_xpath($domain, '//domain/os/type/@machine', false);
- $var = $tmp[0];
- unset($tmp);
-
- return $var;
- }
-
- function domain_get_description($domain) {
- $tmp = $this->get_xpath($domain, '//domain/description', false);
- $var = $tmp[0] ?? "";
- unset($tmp);
-
- return $var;
- }
-
- function domain_get_clock_offset($domain) {
- $tmp = $this->get_xpath($domain, '//domain/clock/@offset', false);
- $var = $tmp[0];
- unset($tmp);
-
- return $var;
- }
-
- function domain_get_cpu_type($domain) {
- $tmp = $this->get_xpath($domain, '//domain/cpu/@mode', false);
- if (!$tmp)
- return 'emulated';
-
- $var = $tmp[0];
- unset($tmp);
-
- return $var;
- }
- #
- # Skylake-Client-noTSX-IBRS
-
- function domain_get_cpu_custom($domain) {
- $tmp = $this->get_xpath($domain, '//domain/cpu/@match', false);
- if (!$tmp)
- $tmp[0] = '';
-
- $var['match'] = trim($tmp[0]);
- unset($tmp);
-
- $tmp = $this->get_xpath($domain, '//domain/cpu/@check', false);
- if (!$tmp)
- $tmp[0] = '';
-
- $var['check'] = trim($tmp[0]);
- unset($tmp);
-
- $tmp = $this->get_xpath($domain, '//domain/cpu/model/@fallback', false);
- if (!$tmp)
- $tmp[0] = '';
-
- $var['fallback'] = trim($tmp[0]);
- unset($tmp);
-
- $tmp = $this->get_xpath($domain, '//domain/cpu/model', false);
- if (!$tmp)
- $tmp[0] = '';
-
- $var['model'] = trim($tmp[0]);
- unset($tmp);
-
- return $var;
- }
-
- function domain_get_cpu_migrate($domain) {
- $tmp = $this->get_xpath($domain, '//domain/cpu/@migratable', false);
- if (!$tmp)
- return 'no';
-
- $var = $tmp[0];
- unset($tmp);
-
- return $var;
- }
-
- function domain_get_vcpu($domain) {
- $tmp = $this->get_xpath($domain, '//domain/vcpu', false);
- $var = $tmp[0];
- unset($tmp);
-
- return $var;
- }
-
- function domain_get_vcpu_pins($domain) {
- $tmp = $this->get_xpath($domain, '//domain/cputune/vcpupin/@cpuset', false);
- if (!$tmp)
- return false;
-
- $devs = [];
- for ($i = 0; $i < $tmp['num']; $i++)
- $devs[] = $tmp[$i];
-
- return $devs;
- }
-
- function domain_get_memory($domain) {
- $tmp = $this->get_xpath($domain, '//domain/memory', false);
- $var = $tmp[0];
- unset($tmp);
-
- return $var;
- }
-
- function domain_get_current_memory($domain) {
- $tmp = $this->get_xpath($domain, '//domain/currentMemory', false);
- $var = $tmp[0];
- unset($tmp);
-
- return $var;
- }
-
- function domain_get_feature($domain, $feature) {
- $tmp = $this->get_xpath($domain, '//domain/features/'.$feature.'/..', false);
- $ret = ($tmp != false);
- unset($tmp);
-
- return $ret;
- }
-
- function domain_get_boot_devices($domain) {
- $tmp = $this->get_xpath($domain, '//domain/os/boot/@dev', false);
- if (!$tmp)
- return false;
-
- $devs = [];
- for ($i = 0; $i < $tmp['num']; $i++)
- $devs[] = $tmp[$i];
-
- return $devs;
- }
-
- function domain_get_mount_filesystems($domain) {
- $ret = [];
- $strXML = $this->domain_get_xml($domain) ;
- $xml = new SimpleXMLElement($strXML);
- $FS=$xml->xpath('//domain/devices/filesystem[@type="mount"]') ;
- foreach($FS as $FSD){
- $target=$FSD->target->attributes()->dir ;
- $source=$FSD->source->attributes()->dir ;
- $mode=$FSD->driver->attributes()->type ;
- $ret[] = [
- 'source' => $source,
- 'target' => $target ,
- 'mode' => $mode
- ];
- }
- return $ret;
- }
-
- function _get_single_xpath_result($domain, $xpath) {
- $tmp = $this->get_xpath($domain, $xpath, false);
- if (!$tmp)
- return false;
-
- if ($tmp['num'] == 0)
- return false;
-
- return $tmp[0];
- }
-
- function domain_get_ovmf($domain) {
- return $this->_get_single_xpath_result($domain, '//domain/os/loader');
- }
-
- function domain_get_multimedia_device($domain, $type, $display=false) {
- $domain = $this->get_domain_object($domain);
-
- if ($type == 'console') {
- $type = $this->_get_single_xpath_result($domain, '//domain/devices/console/@type');
- $targetType = $this->_get_single_xpath_result($domain, '//domain/devices/console/target/@type');
- $targetPort = $this->_get_single_xpath_result($domain, '//domain/devices/console/target/@port');
-
- if ($display)
- return $type.' ('.$targetType.' on port '.$targetPort.')';
- else
- return ['type' => $type, 'targetType' => $targetType, 'targetPort' => $targetPort];
- }
- else
- if ($type == 'input') {
- $type = $this->_get_single_xpath_result($domain, '//domain/devices/input/@type');
- $bus = $this->_get_single_xpath_result($domain, '//domain/devices/input/@bus');
-
- if ($display)
- return $type.' on '.$bus;
- else
- return ['type' => $type, 'bus' => $bus];
- }
- else
- if ($type == 'graphics') {
- $type = $this->_get_single_xpath_result($domain, '//domain/devices/graphics/@type');
- $port = $this->_get_single_xpath_result($domain, '//domain/devices/graphics/@port');
- $autoport = $this->_get_single_xpath_result($domain, '//domain/devices/graphics/@autoport');
-
- if ($display)
- return $type.' on port '.$port.' with'.($autoport ? '' : 'out').' autoport enabled';
- else
- return ['type' => $type, 'port' => $port, 'autoport' => $autoport];
- }
- else
- if ($type == 'video') {
- $type = $this->_get_single_xpath_result($domain, '//domain/devices/video/model/@type');
- $vram = $this->_get_single_xpath_result($domain, '//domain/devices/video/model/@vram');
- $heads = $this->_get_single_xpath_result($domain, '//domain/devices/video/model/@heads');
-
- if ($display)
- return $type.' with '.($vram / 1024).' MB VRAM, '.$heads.' head(s)';
- else
- return ['type' => $type, 'vram' => $vram, 'heads' => $heads];
- }
- else
- return false;
- }
-
- function domain_get_host_devices_pci($domain) {
- $devs = [];
-
- $res = $this->get_domain_object($domain);
- $strDOMXML = $this->domain_get_xml($res);
- $xmldoc = new DOMDocument();
- $xmldoc->loadXML($strDOMXML);
- $xpath = new DOMXPath($xmldoc);
- $objNodes = $xpath->query('//domain/devices/hostdev[@type="pci"]');
- if ($objNodes->length > 0) {
- foreach ($objNodes as $objNode) {
- $dom = $xpath->query('source/address/@domain', $objNode)->Item(0)->nodeValue;
- $bus = $xpath->query('source/address/@bus', $objNode)->Item(0)->nodeValue;
- $rotation = $xpath->query('target/address/@rotation_rate', $objNode)->Item(0)->nodeValue;
- $slot = $xpath->query('source/address/@slot', $objNode)->Item(0)->nodeValue;
- $func = $xpath->query('source/address/@function', $objNode)->Item(0)->nodeValue;
- $rom = $xpath->query('rom/@file', $objNode);
- $rom = ($rom->length > 0 ? $rom->Item(0)->nodeValue : '');
- $boot =$xpath->query('boot/@order', $objNode)->Item(0)->nodeValue;
- $devid = str_replace('0x', '', 'pci_'.$dom.'_'.$bus.'_'.$slot.'_'.$func);
- $tmp2 = $this->get_node_device_information($devid);
- $guest["multi"] = $xpath->query('address/@multifunction', $objNode)->Item(0)->nodeValue ? "on" : "off" ;
- $guest["dom"] = $xpath->query('address/@domain', $objNode)->Item(0)->nodeValue;
- $guest["bus"] = $xpath->query('address/@bus', $objNode)->Item(0)->nodeValue;
- $guest["slot"] = $xpath->query('address/@slot', $objNode)->Item(0)->nodeValue;
- $guest["func"] = $xpath->query('address/@function', $objNode)->Item(0)->nodeValue;
- $devs[] = [
- 'domain' => $dom,
- 'bus' => $bus,
- 'slot' => $slot,
- 'func' => $func,
- 'id' => str_replace('0x', '', $bus.':'.$slot.'.'.$func),
- 'vendor' => $tmp2['vendor_name'],
- 'vendor_id' => $tmp2['vendor_id'],
- 'product' => $tmp2['product_name'],
- 'product_id' => $tmp2['product_id'],
- 'boot' => $boot,
- 'rotation' => $rotation,
- 'rom' => $rom,
- 'guest' => $guest
- ];
- }
- }
-
- // Get any pci devices contained in the qemu args
- $args = $this->get_xpath($domain, '//domain/*[name()=\'qemu:commandline\']/*[name()=\'qemu:arg\']/@value', false);
- if (isset($args['num'])) {
- for ($i = 0; $i < $args['num']; $i++) {
- if (strpos($args[$i], 'vfio-pci') !== 0) {
- continue;
- }
-
- $arg_list = explode(',', $args[$i]);
-
- foreach ($arg_list as $arg) {
- $keypair = explode('=', $arg);
-
- if ($keypair[0] == 'host' && !empty($keypair[1])) {
- $devid = 'pci_0000_' . str_replace([':', '.'], '_', $keypair[1]);
- $tmp2 = $this->get_node_device_information($devid);
- [$bus, $slot, $func] = my_explode(":", str_replace('.', ':', $keypair[1]), 3);
- $devs[] = [
- 'domain' => '0x0000',
- 'bus' => '0x' . $bus,
- 'slot' => '0x' . $slot,
- 'func' => '0x' . $func,
- 'id' => $keypair[1],
- 'vendor' => $tmp2['vendor_name'],
- 'vendor_id' => $tmp2['vendor_id'],
- 'product' => $tmp2['product_name'],
- 'product_id' => $tmp2['product_id']
- ];
- break;
- }
- }
- }
- }
-
- return $devs;
- }
-
- function _lookup_device_usb($vendor_id, $product_id) {
- $tmp = $this->get_node_devices(false);
- for ($i = 0; $i < sizeof($tmp); $i++) {
- $tmp2 = $this->get_node_device_information($tmp[$i]);
- if (array_key_exists('product_id', $tmp2)) {
- if (($tmp2['product_id'] == $product_id)
- && ($tmp2['vendor_id'] == $vendor_id))
- return $tmp2;
- }
- }
-
- return false;
- }
-
- function domain_get_host_devices_usb($domain) {
- $xpath = '//domain/devices/hostdev[@type="usb"]/source/';
-
- $vid = $this->get_xpath($domain, $xpath.'vendor/@id', false);
- $pid = $this->get_xpath($domain, $xpath.'product/@id', false);
-
- $devs = [];
- if (isset($vid['num'])) {
- for ($i = 0; $i < $vid['num']; $i++) {
- $dev = $this->_lookup_device_usb($vid[$i], $pid[$i]);
- $devs[] = [
- 'id' => str_replace('0x', '', $vid[$i] . ':' . $pid[$i]),
- 'vendor_id' => $vid[$i],
- 'product_id' => $pid[$i],
- 'product' => $dev['product_name'],
- 'vendor' => $dev['vendor_name']
- ];
- }
- }
-
- return $devs;
- }
-
- function domain_get_host_devices($domain) {
- $domain = $this->get_domain_object($domain);
-
- $devs_pci = $this->domain_get_host_devices_pci($domain);
- $devs_usb = $this->domain_get_host_devices_usb($domain);
-
- return ['pci' => $devs_pci, 'usb' => $devs_usb];
- }
-
- function get_nic_info($domain) {
- $macs = $this->get_xpath($domain, "//domain/devices/interface/mac/@address", false);
-
- if (!$macs)
- return $this->_set_last_error();
- $ret = [];
- for ($i = 0; $i < $macs['num']; $i++) {
- $net = $this->get_xpath($domain, "//domain/devices/interface/mac[@address='$macs[$i]']/../source/@*", false);
- $model = $this->get_xpath($domain, "//domain/devices/interface/mac[@address='$macs[$i]']/../model/@type", false);
- $boot = $this->get_xpath($domain, "//domain/devices/interface/mac[@address='$macs[$i]']/../boot/@order", false);
-
- if(empty($macs[$i]) && empty($net[0])) {
- $this->_set_last_error();
- continue;
- }
- $ret[] = [
- 'mac' => $macs[$i],
- 'network' => $net[0],
- 'model' => $model[0],
- 'boot' => $boot[0] ?? ""
- ];
- }
-
- return $ret;
- }
-
- function domain_set_feature($domain, $feature, $val) {
- $domain = $this->get_domain_object($domain);
-
- if ($this->domain_get_feature($domain, $feature) == $val)
- return true;
-
- $xml = $this->domain_get_xml($domain);
- if ($val) {
- if (strpos('features', $xml))
- $xml = str_replace('', "\n<$feature/>", $xml);
- else
- $xml = str_replace('', "\n<$feature/>", $xml);
- }
- else
- $xml = str_replace("<$feature/>\n", '', $xml);
-
- return $this->domain_define($xml);
- }
-
- function domain_set_clock_offset($domain, $offset) {
- $domain = $this->get_domain_object($domain);
-
- if (($old_offset = $this->domain_get_clock_offset($domain)) == $offset)
- return true;
-
- $xml = $this->domain_get_xml($domain);
- $xml = str_replace("", "", $xml);
-
- return $this->domain_define($xml);
- }
-
- //change vpus for domain
- function domain_set_vcpu($domain, $vcpu) {
- $domain = $this->get_domain_object($domain);
-
- if (($old_vcpu = $this->domain_get_vcpu($domain)) == $vcpu)
- return true;
-
- $xml = $this->domain_get_xml($domain);
- $xml = str_replace("$old_vcpu", "$vcpu", $xml);
-
- return $this->domain_define($xml);
- }
-
- //change memory for domain
- function domain_set_memory($domain, $memory) {
- $domain = $this->get_domain_object($domain);
- if (($old_memory = $this->domain_get_memory($domain)) == $memory)
- return true;
-
- $xml = $this->domain_get_xml($domain);
- $xml = str_replace("$old_memory", "$memory", $xml);
-
- return $this->domain_define($xml);
- }
-
- //change memory for domain
- function domain_set_current_memory($domain, $memory) {
- $domain = $this->get_domain_object($domain);
- if (($old_memory = $this->domain_get_current_memory($domain)) == $memory)
- return true;
-
- $xml = $this->domain_get_xml($domain);
- $xml = str_replace("$old_memory", "$memory", $xml);
-
- return $this->domain_define($xml);
- }
-
- //change domain disk dev name
- function domain_set_disk_dev($domain, $olddev, $dev) {
- $domain = $this->get_domain_object($domain);
-
- $xml = $this->domain_get_xml($domain);
+ function domain_define($xml, $autostart=false) {
+ if (strpos($xml,'') || strpos($xml,'')) {
$tmp = explode("\n", $xml);
for ($i = 0; $i < sizeof($tmp); $i++)
- if (strpos('.'.$tmp[$i], "";
+ $xml = join("\n", $tmp);
+ }
+
+ if ($autostart) {
+ $tmp = libvirt_domain_create_xml($this->conn, $xml);
+ if (!$tmp)
+ return $this->_set_last_error();
+ }
+
+ $tmp = libvirt_domain_define_xml($this->conn, $xml);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function domain_destroy($domain) {
+ $dom = $this->get_domain_object($domain);
+ if (!$dom)
+ return false;
+
+ $tmp = libvirt_domain_destroy($dom);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function domain_reboot($domain) {
+ $dom = $this->get_domain_object($domain);
+ if (!$dom)
+ return false;
+
+ $tmp = libvirt_domain_reboot($dom);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function domain_suspend($domain) {
+ $dom = $this->get_domain_object($domain);
+ if (!$dom)
+ return false;
+
+ $tmp = libvirt_domain_suspend($dom);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function domain_save($domain) {
+ $dom = $this->get_domain_object($domain);
+ if (!$dom)
+ return false;
+
+ $tmp = libvirt_domain_managedsave($dom);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function domain_resume($domain) {
+ $dom = $this->get_domain_object($domain);
+ if (!$dom)
+ return false;
+
+ $tmp = libvirt_domain_resume($dom);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function domain_get_uuid($domain) {
+ $dom = $this->get_domain_object($domain);
+ if (!$dom)
+ return false;
+
+ $tmp = libvirt_domain_get_uuid_string($dom);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function domain_get_domain_by_uuid($uuid) {
+ $dom = libvirt_domain_lookup_by_uuid_string($this->conn, $uuid);
+ return ($dom) ? $dom : $this->_set_last_error();
+ }
+
+ function domain_get_name_by_uuid($uuid) {
+ $dom = $this->domain_get_domain_by_uuid($uuid);
+ if (!$dom)
+ return false;
+ $tmp = libvirt_domain_get_name($dom);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function domain_is_active($domain) {
+ $domain = $this->get_domain_object($domain);
+ $tmp = libvirt_domain_is_active($domain);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function domain_qemu_agent_command($domain,$cmd,$timeout,$flags) {
+ $domain = $this->get_domain_object($domain);
+ $tmp = libvirt_domain_qemu_agent_command($domain,$cmd,$timeout,$flags);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function generate_uuid($seed=false) {
+ if (!$seed)
+ $seed = time();
+ srand($seed);
+
+ $ret = [];
+ for ($i = 0; $i < 16; $i++)
+ $ret[] = $this->macbyte(rand() % 256);
+
+ $a = $ret[0].$ret[1].$ret[2].$ret[3];
+ $b = $ret[4].$ret[5];
+ $c = $ret[6].$ret[7];
+ $d = $ret[8].$ret[9];
+ $e = $ret[10].$ret[11].$ret[12].$ret[13].$ret[14].$ret[15];
+ return $a.'-'.$b.'-'.$c.'-'.$d.'-'.$e;
+ }
+
+ function domain_generate_uuid() {
+ $uuid = $this->generate_uuid();
+
+ //while ($this->domain_get_name_by_uuid($uuid))
+ //$uuid = $this->generate_uuid();
+ return $uuid;
+ }
+
+ function domain_shutdown($domain) {
+ $dom = $this->get_domain_object($domain);
+ if (!$dom)
+ return false;
+
+ $tmp = libvirt_domain_shutdown($dom);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function domain_undefine($domain) {
+ $dom = $this->get_domain_object($domain);
+ if (!$dom)
+ return false;
+
+ $uuid = $this->domain_get_uuid($dom);
+ // remove OVMF VARS if this domain had them
+ if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd')) {
+ unlink('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd');
+ }
+ if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd')) {
+ unlink('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd');
+ }
+
+ $tmp = libvirt_domain_undefine($dom);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ function domain_delete($domain) {
+ $dom = $this->get_domain_object($domain);
+ if (!$dom)
+ return false;
+ $disks = $this->get_disk_stats($dom);
+ $tmp = $this->domain_undefine($dom);
+ if (!$tmp)
+ return $this->_set_last_error();
+
+ // remove the first disk only
+ if (array_key_exists('file', $disks[0])) {
+ $disk = $disks[0]['file'];
+ $pathinfo = pathinfo($disk);
+ $dir = $pathinfo['dirname'];
+
+ // remove the vm config
+ $cfg_vm = $dir.'/'.$domain.'.cfg';
+ if (is_file($cfg_vm)) unlink($cfg_vm);
+
+ $cfg = $dir.'/'.$pathinfo['filename'].'.cfg';
+ $xml = $dir.'/'.$pathinfo['filename'].'.xml';
+ if (is_file($disk)) unlink($disk);
+ if (is_file($cfg)) unlink($cfg);
+ if (is_file($xml)) unlink($xml);
+ if (is_dir($dir) && $this->is_dir_empty($dir)) {
+ $result= my_rmdir($dir);
+ if ($result['type'] == "zfs") {
+ qemu_log("$domain","delete empty zfs $dir {$result['rtncode']}");
+ if (isset($result['dataset'])) qemu_log("$domain","dataset {$result['dataset']} ");
+ if (isset($result['cmd'])) qemu_log("$domain","Command {$result['cmd']} ");
+ if (isset($result['output'])) {
+ $outputlogs = implode(" ",$result['output']);
+ qemu_log("$domain","Output $outputlogs end");
+ }
+ }
+ else qemu_log("$domain","delete empty $dir {$result['rtncode']}");
+ }
+ }
+ return true;
+ }
+
+ function nvram_backup($uuid) {
+ // move OVMF VARS to a backup file if this domain has them
+ if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd')) {
+ rename('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd', '/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd_backup');
+ return true;
+ }
+ if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd')) {
+ rename('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd', '/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd_backup');
+ return true;
+ }
+ return false;
+ }
+
+ function nvram_restore($uuid) {
+ // restore backup OVMF VARS if this domain had them
+ if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd_backup')) {
+ rename('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd_backup', '/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd');
+ return true;
+ }
+ if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd_backup')) {
+ rename('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd_backup', '/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd');
+ return true;
+ }
+ return false;
+ }
+
+ function nvram_rename($uuid,$newuuid) {
+ // rename backup OVMF VARS if this domain had them
+ if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd')) {
+ rename('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd_backup', '/etc/libvirt/qemu/nvram/'.$newuuid.'_VARS-pure-efi.fd');
+ return true;
+ }
+ if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd')) {
+ rename('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd_backup', '/etc/libvirt/qemu/nvram/'.$newuuid.'_VARS-pure-efi-tpm.fd');
+ return true;
+ }
+ return false;
+ }
+
+ function nvram_create_snapshot($uuid,$snapshotname) {
+ // snapshot backup OVMF VARS if this domain had them
+ if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd')) {
+ copy('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd', '/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi.fd');
+ return true;
+ }
+ if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd')) {
+ copy('/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd', '/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi-tpm.fd');
+ return true;
+ }
+ return false;
+ }
+
+ function nvram_revert_snapshot($uuid,$snapshotname) {
+ // snapshot backup OVMF VARS if this domain had them
+ if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi.fd')) {
+ copy('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi.fd', '/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi.fd');
+ unlink('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi.fd');
+ return true;
+ }
+ if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi-tpm.fd')) {
+ copy('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi-tpm.fd', '/etc/libvirt/qemu/nvram/'.$uuid.'_VARS-pure-efi-tpm.fd');
+ unlink('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi-tpm.fd');
+ return true;
+ }
+ return false;
+ }
+
+ function nvram_delete_snapshot($uuid,$snapshotname) {
+ // snapshot backup OVMF VARS if this domain had them
+ if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi.fd')) {
+ unlink('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi.fd');
+ return true;
+ }
+ if (is_file('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi-tpm.fd')) {
+ unlink('/etc/libvirt/qemu/nvram/'.$uuid.$snapshotname.'_VARS-pure-efi-tpm.fd');
+ return true;
+ }
+ return false;
+ }
+
+ function is_dir_empty($dir) {
+ if (!is_readable($dir)) return null;
+ $handle = opendir($dir);
+ while (false !== ($entry = readdir($handle))) {
+ if ($entry != "." && $entry != "..") {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ function domain_is_running($domain, $name = false) {
+ $dom = $this->get_domain_object($domain);
+ if (!$dom)
+ return false;
+
+ $tmp = $this->domain_get_info( $domain, $name );
+ if (!$tmp)
+ return $this->_set_last_error();
+ $ret = ( ($tmp['state'] == VIR_DOMAIN_RUNNING) || ($tmp['state'] == VIR_DOMAIN_BLOCKED) || ($tmp['state'] == 7 /*VIR_DOMAIN_PMSUSPENDED*/) );
+ unset($tmp);
+ return $ret;
+ }
+
+ function domain_get_state($domain) {
+ $dom = $this->get_domain_object($domain);
+ if (!$dom)
+ return false;
+
+ $info = libvirt_domain_get_info($dom);
+ if (!$info)
+ return $this->_set_last_error();
+ return $this->domain_state_translate($info['state']);
+ }
+
+ function domain_state_translate($state) {
+ switch ($state) {
+ case VIR_DOMAIN_RUNNING: return 'running';
+ case VIR_DOMAIN_NOSTATE: return 'nostate';
+ case VIR_DOMAIN_BLOCKED: return 'blocked';
+ case VIR_DOMAIN_PAUSED: return 'paused';
+ case VIR_DOMAIN_SHUTDOWN: return 'shutdown';
+ case VIR_DOMAIN_SHUTOFF: return 'shutoff';
+ case VIR_DOMAIN_CRASHED: return 'crashed';
+ //VIR_DOMAIN_PMSUSPENDED is 7 (not defined in libvirt-php yet)
+ case 7: return 'pmsuspended';
+ }
+ return 'unknown';
+ }
+
+ function domain_get_vnc_port($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/devices/graphics[@type="spice" or @type="vnc"]/@port', false);
+ $var = (int)$tmp[0];
+ unset($tmp);
+ return $var;
+ }
+
+ function domain_get_vmrc_autoport($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/devices/graphics[@type="spice" or @type="vnc"]/@autoport', false);
+ $var = $tmp[0];
+ unset($tmp);
+ return $var;
+ }
+
+ function domain_get_vmrc_protocol($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/devices/graphics/@type', false);
+ $var = $tmp[0];
+ unset($tmp);
+ return $var;
+ }
+
+ function domain_get_vnc_model($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/devices/video/model/@type', false);
+ if (!$tmp)
+ return 'qxl';
+
+ $var = $tmp[0];
+ unset($tmp);
+
+ if ($var=="virtio") {
+ $tmp = $this->get_xpath($domain, '//domain/devices/video/model/acceleration/@accel3d', false);
+ if ($tmp[0] == "yes") $var = "virtio3d";
+ unset($tmp);
+ }
+ return $var;
+ }
+
+ function domain_get_vnc_render($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/devices/graphics[@type="egl-headless"]/gl/@rendernode', false);
+ if (!$tmp)
+ return 'auto';
+
+ $var = $tmp[0];
+ unset($tmp);
+
+ if (!str_contains($var,"pci")) $var = trim(shell_exec("udevadm info -q symlink -r $var"));
+ $var = str_replace(['/dev/dri/by-path/pci-0000:','-render'],['',''],$var);
+ return $var;
+ }
+
+ function domain_get_vnc_display_options($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/devices/video/model/@heads', false);
+ if (!$tmp)
+ $heads=1;
+
+ $heads = $tmp[0];
+ unset($tmp);
+
+ $tmp = $this->get_xpath($domain, '//domain/devices/video/model/@vram', false);
+ if (!$tmp)
+ $vram=16384/1024;
+
+ $vram = $tmp[0]/1024;
+ unset($tmp);
+
+ $var = "H$heads.{$vram}M";
+ return $var;
+ }
+
+ function domain_get_vnc_keymap($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/devices/graphics/@keymap', false);
+ if (!$tmp)
+ return 'none';
+
+ $var = $tmp[0];
+ unset($tmp);
+ return $var;
+ }
+
+ function domain_get_vnc_password($domain) {
+ $domain_name = $this->domain_get_name($domain);
+ $password = shell_exec("cat /etc/libvirt/qemu/'{$domain_name}.xml' | grep 'passwd'");
+
+ if (!$password)
+ return '';
+
+ $strpos = strpos($password, "passwd=") +8;
+ $endpos = strpos($password, "'",$strpos);
+ $password = substr($password,$strpos, $endpos-$strpos);
+ return $password;
+ }
+
+ function domain_get_ws_port($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/devices/graphics/@websocket', false);
+ $var = (int)$tmp[0];
+ unset($tmp);
+ return $var;
+ }
+
+ function domain_get_arch($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/os/type/@arch', false);
+ $var = $tmp[0];
+ unset($tmp);
+ return $var;
+ }
+
+ function domain_get_machine($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/os/type/@machine', false);
+ $var = $tmp[0];
+ unset($tmp);
+ return $var;
+ }
+
+ function domain_get_description($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/description', false);
+ $var = $tmp[0] ?? "";
+ unset($tmp);
+ return $var;
+ }
+
+ function domain_get_clock_offset($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/clock/@offset', false);
+ $var = $tmp[0];
+ unset($tmp);
+ return $var;
+ }
+
+ function domain_get_cpu_type($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/cpu/@mode', false);
+ if (!$tmp)
+ return 'emulated';
+
+ $var = $tmp[0];
+ unset($tmp);
+ return $var;
+ }
+ #
+ # Skylake-Client-noTSX-IBRS
+
+ function domain_get_cpu_custom($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/cpu/@match', false);
+ if (!$tmp)
+ $tmp[0] = '';
+
+ $var['match'] = trim($tmp[0]);
+ unset($tmp);
+
+ $tmp = $this->get_xpath($domain, '//domain/cpu/@check', false);
+ if (!$tmp)
+ $tmp[0] = '';
+
+ $var['check'] = trim($tmp[0]);
+ unset($tmp);
+
+ $tmp = $this->get_xpath($domain, '//domain/cpu/model/@fallback', false);
+ if (!$tmp)
+ $tmp[0] = '';
+
+ $var['fallback'] = trim($tmp[0]);
+ unset($tmp);
+
+ $tmp = $this->get_xpath($domain, '//domain/cpu/model', false);
+ if (!$tmp)
+ $tmp[0] = '';
+
+ $var['model'] = trim($tmp[0]);
+ unset($tmp);
+ return $var;
+ }
+
+ function domain_get_cpu_migrate($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/cpu/@migratable', false);
+ if (!$tmp)
+ return 'no';
+
+ $var = $tmp[0];
+ unset($tmp);
+ return $var;
+ }
+
+ function domain_get_vcpu($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/vcpu', false);
+ $var = $tmp[0];
+ unset($tmp);
+ return $var;
+ }
+
+ function domain_get_vcpu_pins($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/cputune/vcpupin/@cpuset', false);
+ if (!$tmp)
+ return false;
+
+ $devs = [];
+ for ($i = 0; $i < $tmp['num']; $i++)
+ $devs[] = $tmp[$i];
+ return $devs;
+ }
+
+ function domain_get_memory($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/memory', false);
+ $var = $tmp[0];
+ unset($tmp);
+ return $var;
+ }
+
+ function domain_get_current_memory($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/currentMemory', false);
+ $var = $tmp[0];
+ unset($tmp);
+ return $var;
+ }
+
+ function domain_get_feature($domain, $feature) {
+ $tmp = $this->get_xpath($domain, '//domain/features/'.$feature.'/..', false);
+ $ret = ($tmp != false);
+ unset($tmp);
+ return $ret;
+ }
+
+ function domain_get_boot_devices($domain) {
+ $tmp = $this->get_xpath($domain, '//domain/os/boot/@dev', false);
+ if (!$tmp)
+ return false;
+
+ $devs = [];
+ for ($i = 0; $i < $tmp['num']; $i++)
+ $devs[] = $tmp[$i];
+ return $devs;
+ }
+
+ function domain_get_mount_filesystems($domain) {
+ $ret = [];
+ $strXML = $this->domain_get_xml($domain);
+ $xml = new SimpleXMLElement($strXML);
+ $FS=$xml->xpath('//domain/devices/filesystem[@type="mount"]');
+ foreach($FS as $FSD){
+ $target=$FSD->target->attributes()->dir;
+ $source=$FSD->source->attributes()->dir;
+ $mode=$FSD->driver->attributes()->type;
+ $ret[] = [
+ 'source' => $source,
+ 'target' => $target ,
+ 'mode' => $mode
+ ];
+ }
+ return $ret;
+ }
+
+ function _get_single_xpath_result($domain, $xpath) {
+ $tmp = $this->get_xpath($domain, $xpath, false);
+ if (!$tmp)
+ return false;
+
+ if ($tmp['num'] == 0)
+ return false;
+ return $tmp[0];
+ }
+
+ function domain_get_ovmf($domain) {
+ return $this->_get_single_xpath_result($domain, '//domain/os/loader');
+ }
+
+ function domain_get_multimedia_device($domain, $type, $display=false) {
+ $domain = $this->get_domain_object($domain);
+
+ if ($type == 'console') {
+ $type = $this->_get_single_xpath_result($domain, '//domain/devices/console/@type');
+ $targetType = $this->_get_single_xpath_result($domain, '//domain/devices/console/target/@type');
+ $targetPort = $this->_get_single_xpath_result($domain, '//domain/devices/console/target/@port');
+
+ if ($display)
+ return $type.' ('.$targetType.' on port '.$targetPort.')';
+ else
+ return ['type' => $type, 'targetType' => $targetType, 'targetPort' => $targetPort];
+ }
+ else
+ if ($type == 'input') {
+ $type = $this->_get_single_xpath_result($domain, '//domain/devices/input/@type');
+ $bus = $this->_get_single_xpath_result($domain, '//domain/devices/input/@bus');
+
+ if ($display)
+ return $type.' on '.$bus;
+ else
+ return ['type' => $type, 'bus' => $bus];
+ }
+ else
+ if ($type == 'graphics') {
+ $type = $this->_get_single_xpath_result($domain, '//domain/devices/graphics/@type');
+ $port = $this->_get_single_xpath_result($domain, '//domain/devices/graphics/@port');
+ $autoport = $this->_get_single_xpath_result($domain, '//domain/devices/graphics/@autoport');
+
+ if ($display)
+ return $type.' on port '.$port.' with'.($autoport ? '' : 'out').' autoport enabled';
+ else
+ return ['type' => $type, 'port' => $port, 'autoport' => $autoport];
+ }
+ else
+ if ($type == 'video') {
+ $type = $this->_get_single_xpath_result($domain, '//domain/devices/video/model/@type');
+ $vram = $this->_get_single_xpath_result($domain, '//domain/devices/video/model/@vram');
+ $heads = $this->_get_single_xpath_result($domain, '//domain/devices/video/model/@heads');
+
+ if ($display)
+ return $type.' with '.($vram / 1024).' MB VRAM, '.$heads.' head(s)';
+ else
+ return ['type' => $type, 'vram' => $vram, 'heads' => $heads];
+ }
+ else
+ return false;
+ }
+
+ function domain_get_host_devices_pci($domain) {
+ $devs = [];
+
+ $res = $this->get_domain_object($domain);
+ $strDOMXML = $this->domain_get_xml($res);
+ $xmldoc = new DOMDocument();
+ $xmldoc->loadXML($strDOMXML);
+ $xpath = new DOMXPath($xmldoc);
+ $objNodes = $xpath->query('//domain/devices/hostdev[@type="pci"]');
+ if ($objNodes->length > 0) {
+ foreach ($objNodes as $objNode) {
+ $dom = $xpath->query('source/address/@domain', $objNode)->Item(0)->nodeValue;
+ $bus = $xpath->query('source/address/@bus', $objNode)->Item(0)->nodeValue;
+ $rotation = $xpath->query('target/address/@rotation_rate', $objNode)->Item(0)->nodeValue;
+ $slot = $xpath->query('source/address/@slot', $objNode)->Item(0)->nodeValue;
+ $func = $xpath->query('source/address/@function', $objNode)->Item(0)->nodeValue;
+ $rom = $xpath->query('rom/@file', $objNode);
+ $rom = ($rom->length > 0 ? $rom->Item(0)->nodeValue : '');
+ $boot =$xpath->query('boot/@order', $objNode)->Item(0)->nodeValue;
+ $devid = str_replace('0x', '', 'pci_'.$dom.'_'.$bus.'_'.$slot.'_'.$func);
+ $tmp2 = $this->get_node_device_information($devid);
+ $guest["multi"] = $xpath->query('address/@multifunction', $objNode)->Item(0)->nodeValue ? "on" : "off";
+ $guest["dom"] = $xpath->query('address/@domain', $objNode)->Item(0)->nodeValue;
+ $guest["bus"] = $xpath->query('address/@bus', $objNode)->Item(0)->nodeValue;
+ $guest["slot"] = $xpath->query('address/@slot', $objNode)->Item(0)->nodeValue;
+ $guest["func"] = $xpath->query('address/@function', $objNode)->Item(0)->nodeValue;
+ $devs[] = [
+ 'domain' => $dom,
+ 'bus' => $bus,
+ 'slot' => $slot,
+ 'func' => $func,
+ 'id' => str_replace('0x', '', $bus.':'.$slot.'.'.$func),
+ 'vendor' => $tmp2['vendor_name'],
+ 'vendor_id' => $tmp2['vendor_id'],
+ 'product' => $tmp2['product_name'],
+ 'product_id' => $tmp2['product_id'],
+ 'boot' => $boot,
+ 'rotation' => $rotation,
+ 'rom' => $rom,
+ 'guest' => $guest
+ ];
+ }
+ }
+
+ // Get any pci devices contained in the qemu args
+ $args = $this->get_xpath($domain, '//domain/*[name()=\'qemu:commandline\']/*[name()=\'qemu:arg\']/@value', false);
+ if (isset($args['num'])) {
+ for ($i = 0; $i < $args['num']; $i++) {
+ if (strpos($args[$i], 'vfio-pci') !== 0) {
+ continue;
+ }
+
+ $arg_list = explode(',', $args[$i]);
+
+ foreach ($arg_list as $arg) {
+ $keypair = explode('=', $arg);
+
+ if ($keypair[0] == 'host' && !empty($keypair[1])) {
+ $devid = 'pci_0000_'.str_replace([':', '.'], '_', $keypair[1]);
+ $tmp2 = $this->get_node_device_information($devid);
+ [$bus, $slot, $func] = my_explode(":", str_replace('.', ':', $keypair[1]), 3);
+ $devs[] = [
+ 'domain' => '0x0000',
+ 'bus' => '0x'.$bus,
+ 'slot' => '0x'.$slot,
+ 'func' => '0x'.$func,
+ 'id' => $keypair[1],
+ 'vendor' => $tmp2['vendor_name'],
+ 'vendor_id' => $tmp2['vendor_id'],
+ 'product' => $tmp2['product_name'],
+ 'product_id' => $tmp2['product_id']
+ ];
+ break;
+ }
+ }
+ }
+ }
+ return $devs;
+ }
+
+ function _lookup_device_usb($vendor_id, $product_id) {
+ $tmp = $this->get_node_devices(false);
+ for ($i = 0; $i < sizeof($tmp); $i++) {
+ $tmp2 = $this->get_node_device_information($tmp[$i]);
+ if (array_key_exists('product_id', $tmp2)) {
+ if (($tmp2['product_id'] == $product_id) && ($tmp2['vendor_id'] == $vendor_id)) {
+ return $tmp2;
+ }
+ }
+ }
+ return false;
+ }
+
+ function domain_get_host_devices_usb($domain) {
+ $xpath = '//domain/devices/hostdev[@type="usb"]/source/';
+
+ $vid = $this->get_xpath($domain, $xpath.'vendor/@id', false);
+ $pid = $this->get_xpath($domain, $xpath.'product/@id', false);
+
+ $devs = [];
+ if (isset($vid['num'])) {
+ for ($i = 0; $i < $vid['num']; $i++) {
+ $dev = $this->_lookup_device_usb($vid[$i], $pid[$i]);
+ $devs[] = [
+ 'id' => str_replace('0x', '', $vid[$i].':'.$pid[$i]),
+ 'vendor_id' => $vid[$i],
+ 'product_id' => $pid[$i],
+ 'product' => $dev['product_name'],
+ 'vendor' => $dev['vendor_name']
+ ];
+ }
+ }
+ return $devs;
+ }
+
+ function domain_get_host_devices($domain) {
+ $domain = $this->get_domain_object($domain);
+
+ $devs_pci = $this->domain_get_host_devices_pci($domain);
+ $devs_usb = $this->domain_get_host_devices_usb($domain);
+ return ['pci' => $devs_pci, 'usb' => $devs_usb];
+ }
+
+ function get_nic_info($domain) {
+ $macs = $this->get_xpath($domain, "//domain/devices/interface/mac/@address", false);
+
+ if (!$macs)
+ return $this->_set_last_error();
+ $ret = [];
+ for ($i = 0; $i < $macs['num']; $i++) {
+ $net = $this->get_xpath($domain, "//domain/devices/interface/mac[@address='$macs[$i]']/../source/@*", false);
+ $model = $this->get_xpath($domain, "//domain/devices/interface/mac[@address='$macs[$i]']/../model/@type", false);
+ $boot = $this->get_xpath($domain, "//domain/devices/interface/mac[@address='$macs[$i]']/../boot/@order", false);
+
+ if(empty($macs[$i]) && empty($net[0])) {
+ $this->_set_last_error();
+ continue;
+ }
+ $ret[] = [
+ 'mac' => $macs[$i],
+ 'network' => $net[0],
+ 'model' => $model[0],
+ 'boot' => $boot[0] ?? ""
+ ];
+ }
+ return $ret;
+ }
+
+ function domain_set_feature($domain, $feature, $val) {
+ $domain = $this->get_domain_object($domain);
+
+ if ($this->domain_get_feature($domain, $feature) == $val)
+ return true;
+
+ $xml = $this->domain_get_xml($domain);
+ if ($val) {
+ if (strpos('features', $xml))
+ $xml = str_replace('', "\n<$feature/>", $xml);
+ else
+ $xml = str_replace('', "\n<$feature/>", $xml);
+ }
+ else
+ $xml = str_replace("<$feature/>\n", '', $xml);
+ return $this->domain_define($xml);
+ }
+
+ function domain_set_clock_offset($domain, $offset) {
+ $domain = $this->get_domain_object($domain);
+
+ if (($old_offset = $this->domain_get_clock_offset($domain)) == $offset)
+ return true;
+
+ $xml = $this->domain_get_xml($domain);
+ $xml = str_replace("", "", $xml);
+ return $this->domain_define($xml);
+ }
+
+ //change vpus for domain
+ function domain_set_vcpu($domain, $vcpu) {
+ $domain = $this->get_domain_object($domain);
+
+ if (($old_vcpu = $this->domain_get_vcpu($domain)) == $vcpu)
+ return true;
+
+ $xml = $this->domain_get_xml($domain);
+ $xml = str_replace("$old_vcpu", "$vcpu", $xml);
+ return $this->domain_define($xml);
+ }
+
+ //change memory for domain
+ function domain_set_memory($domain, $memory) {
+ $domain = $this->get_domain_object($domain);
+ if (($old_memory = $this->domain_get_memory($domain)) == $memory)
+ return true;
+
+ $xml = $this->domain_get_xml($domain);
+ $xml = str_replace("$old_memory", "$memory", $xml);
+ return $this->domain_define($xml);
+ }
+
+ //change memory for domain
+ function domain_set_current_memory($domain, $memory) {
+ $domain = $this->get_domain_object($domain);
+ if (($old_memory = $this->domain_get_current_memory($domain)) == $memory)
+ return true;
+
+ $xml = $this->domain_get_xml($domain);
+ $xml = str_replace("$old_memory", "$memory", $xml);
+ return $this->domain_define($xml);
+ }
+
+ //change domain disk dev name
+ function domain_set_disk_dev($domain, $olddev, $dev) {
+ $domain = $this->get_domain_object($domain);
+
+ $xml = $this->domain_get_xml($domain);
+ $tmp = explode("\n", $xml);
+ for ($i = 0; $i < sizeof($tmp); $i++)
+ if (strpos('.'.$tmp[$i], "$desc";
$xml = join("\n", $tmp);
-
- return $this->domain_define($xml);
}
+ return $this->domain_define($xml);
+ }
- //set domain description
- function domain_set_description($domain, $desc) {
- $domain = $this->get_domain_object($domain);
+ //create metadata node for domain
+ function domain_set_metadata($domain) {
+ $domain = $this->get_domain_object($domain);
+ $xml = $this->domain_get_xml($domain);
+ $metadata = $this->get_xpath($domain, '//domain/metadata', false);
+ if (empty($metadata)){
$description = $this->domain_get_description($domain);
- if ($description == $desc)
- return true;
-
- $xml = $this->domain_get_xml($domain);
- if (!$description)
- $xml = str_replace("", "$desc", $xml);
- else {
- $tmp = explode("\n", $xml);
- for ($i = 0; $i < sizeof($tmp); $i++)
- if (strpos('.'.$tmp[$i], '$desc";
-
- $xml = join("\n", $tmp);
- }
-
- return $this->domain_define($xml);
+ if(!$description)
+ $node = "";
+ else
+ $node = "";
+ $desc = "$node\n\n\n";
+ $xml = str_replace($node, $desc, $xml);
}
+ return $this->domain_define($xml);
+ }
- //create metadata node for domain
- function domain_set_metadata($domain) {
- $domain = $this->get_domain_object($domain);
+ //set description for snapshot
+ function snapshot_set_metadata($domain, $name, $desc) {
+ $this->domain_set_metadata($domain);
+ $domain = $this->get_domain_object($domain);
- $xml = $this->domain_get_xml($domain);
- $metadata = $this->get_xpath($domain, '//domain/metadata', false);
- if (empty($metadata)){
- $description = $this->domain_get_description($domain);
- if(!$description)
- $node = "";
- else
- $node = "";
- $desc = "$node\n\n\n";
- $xml = str_replace($node, $desc, $xml);
- }
- return $this->domain_define($xml);
- }
-
- //set description for snapshot
- function snapshot_set_metadata($domain, $name, $desc) {
- $this->domain_set_metadata($domain);
- $domain = $this->get_domain_object($domain);
-
- $xml = $this->domain_get_xml($domain);
- $metadata = $this->get_xpath($domain, '//domain/metadata/snapshot'.$name, false);
- if (empty($metadata)){
- $desc = "\n$desc\n";
- $xml = str_replace('', $desc, $xml);
- } else {
- $tmp = explode("\n", $xml);
- for ($i = 0; $i < sizeof($tmp); $i++)
- if (strpos('.'.$tmp[$i], '$desc";
-
- $xml = join("\n", $tmp);
- }
- return $this->domain_define($xml);
- }
-
- //get host node info
- function host_get_node_info() {
- $tmp = libvirt_node_get_info($this->conn);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- //get domain autostart status true or false
- function domain_get_autostart($domain) {
- $domain = $this->get_domain_object($domain);
- $tmp = libvirt_domain_get_autostart($domain);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- //set domain to start with libvirt
- function domain_set_autostart($domain,$flags) {
- $domain = $this->get_domain_object($domain);
- $tmp = libvirt_domain_set_autostart($domain,$flags);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- //list all snapshots for domain
- function domain_snapshots_list($domain) {
- $tmp = libvirt_list_domain_snapshots($domain);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- //list all snapshots for domain
- function domain_snapshot_get_xml($domain) {
- $tmp = libvirt_domain_snapshot_get_xml($domain);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- // create a snapshot and metadata node for description
- function domain_snapshot_create($domain) {
- $this->domain_set_metadata($domain);
- $domain = $this->get_domain_object($domain);
- $tmp = libvirt_domain_snapshot_create($domain);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- //delete snapshot and metadata
- function domain_snapshot_delete($domain, $name, $flags=0) {
- $name = $this->domain_snapshot_lookup_by_name($domain, $name);
- $tmp = libvirt_domain_snapshot_delete($name,$flags);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- //get resource number of snapshot
- function domain_snapshot_lookup_by_name($domain, $name) {
- $domain = $this->get_domain_object($domain);
- $tmp = libvirt_domain_snapshot_lookup_by_name($domain, $name);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- //revert domain to snapshot state
- function domain_snapshot_revert($domain, $name) {
- $name = $this->domain_snapshot_lookup_by_name($domain, $name);
- $tmp = libvirt_domain_snapshot_revert($name);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- //get snapshot description
- function domain_snapshot_get_info($domain, $name) {
- $domain = $this->get_domain_object($domain);
- $tmp = $this->get_xpath($domain, '//domain/metadata/snapshot'.$name, false);
- $var = $tmp[0];
- unset($tmp);
-
- return $var;
- }
-
- //remove snapshot metadata
- function snapshot_remove_metadata($domain, $name) {
- $domain = $this->get_domain_object($domain);
-
- $xml = $this->domain_get_xml($domain);
+ $xml = $this->domain_get_xml($domain);
+ $metadata = $this->get_xpath($domain, '//domain/metadata/snapshot'.$name, false);
+ if (empty($metadata)){
+ $desc = "\n$desc\n";
+ $xml = str_replace('', $desc, $xml);
+ } else {
$tmp = explode("\n", $xml);
for ($i = 0; $i < sizeof($tmp); $i++)
if (strpos('.'.$tmp[$i], '$desc";
$xml = join("\n", $tmp);
-
- return $this->domain_define($xml);
- }
-
- //change cdrom media
- function domain_change_cdrom($domain, $iso, $dev, $bus) {
- $domain = $this->get_domain_object($domain);
- $tmp = libvirt_domain_update_device($domain, "", VIR_DOMAIN_DEVICE_MODIFY_CONFIG);
- if ($this->domain_is_active($domain))
- libvirt_domain_update_device($domain, "", VIR_DOMAIN_DEVICE_MODIFY_LIVE);
- return ($tmp) ? $tmp : $this->_set_last_error();
- }
-
- //change disk capacity
- /*function disk_set_cap($disk, $cap) {
- $xml = $this->domain_get_xml($domain);
- $tmp = explode("\n", $xml);
- for ($i = 0; $i < sizeof($tmp); $i++)
- if (strpos('.'.$tmp[$i], "";
-
- $xml = join("\n", $tmp);
-
- return $this->domain_define($xml);
- }
-
- function libvirt_get_net_res($conn, $net) {
- return libvirt_network_get($conn, $net);
- }
-
- function libvirt_get_net_list($conn, $opt=VIR_NETWORKS_ALL) {
- // VIR_NETWORKS_{ACTIVE|INACTIVE|ALL}
- return libvirt_list_networks($conn, $opt);
- }
-
- function libvirt_get_net_xml($res, $xpath=NULL) {
- return libvirt_network_get_xml_desc($res, $xpath);
}
+ return $this->domain_define($xml);
}
+
+ //get host node info
+ function host_get_node_info() {
+ $tmp = libvirt_node_get_info($this->conn);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ //get domain autostart status true or false
+ function domain_get_autostart($domain) {
+ $domain = $this->get_domain_object($domain);
+ $tmp = libvirt_domain_get_autostart($domain);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ //set domain to start with libvirt
+ function domain_set_autostart($domain,$flags) {
+ $domain = $this->get_domain_object($domain);
+ $tmp = libvirt_domain_set_autostart($domain,$flags);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ //list all snapshots for domain
+ function domain_snapshots_list($domain) {
+ $tmp = libvirt_list_domain_snapshots($domain);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ //list all snapshots for domain
+ function domain_snapshot_get_xml($domain) {
+ $tmp = libvirt_domain_snapshot_get_xml($domain);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ // create a snapshot and metadata node for description
+ function domain_snapshot_create($domain) {
+ $this->domain_set_metadata($domain);
+ $domain = $this->get_domain_object($domain);
+ $tmp = libvirt_domain_snapshot_create($domain);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ //delete snapshot and metadata
+ function domain_snapshot_delete($domain, $name, $flags=0) {
+ $name = $this->domain_snapshot_lookup_by_name($domain, $name);
+ $tmp = libvirt_domain_snapshot_delete($name,$flags);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ //get resource number of snapshot
+ function domain_snapshot_lookup_by_name($domain, $name) {
+ $domain = $this->get_domain_object($domain);
+ $tmp = libvirt_domain_snapshot_lookup_by_name($domain, $name);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ //revert domain to snapshot state
+ function domain_snapshot_revert($domain, $name) {
+ $name = $this->domain_snapshot_lookup_by_name($domain, $name);
+ $tmp = libvirt_domain_snapshot_revert($name);
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ //get snapshot description
+ function domain_snapshot_get_info($domain, $name) {
+ $domain = $this->get_domain_object($domain);
+ $tmp = $this->get_xpath($domain, '//domain/metadata/snapshot'.$name, false);
+ $var = $tmp[0];
+ unset($tmp);
+ return $var;
+ }
+
+ //remove snapshot metadata
+ function snapshot_remove_metadata($domain, $name) {
+ $domain = $this->get_domain_object($domain);
+
+ $xml = $this->domain_get_xml($domain);
+ $tmp = explode("\n", $xml);
+ for ($i = 0; $i < sizeof($tmp); $i++) {
+ if (strpos('.'.$tmp[$i], 'domain_define($xml);
+ }
+
+ //change cdrom media
+ function domain_change_cdrom($domain, $iso, $dev, $bus) {
+ $domain = $this->get_domain_object($domain);
+ $tmp = libvirt_domain_update_device($domain, "", VIR_DOMAIN_DEVICE_MODIFY_CONFIG);
+ if ($this->domain_is_active($domain)) {
+ libvirt_domain_update_device($domain, "", VIR_DOMAIN_DEVICE_MODIFY_LIVE);
+ }
+ return ($tmp) ? $tmp : $this->_set_last_error();
+ }
+
+ //change disk capacity
+ /*function disk_set_cap($disk, $cap) {
+ $xml = $this->domain_get_xml($domain);
+ $tmp = explode("\n", $xml);
+ for ($i = 0; $i < sizeof($tmp); $i++)
+ if (strpos('.'.$tmp[$i], "";
+ }
+ }
+ $xml = join("\n", $tmp);
+ return $this->domain_define($xml);
+ }
+
+ function libvirt_get_net_res($conn, $net) {
+ return libvirt_network_get($conn, $net);
+ }
+
+ function libvirt_get_net_list($conn, $opt=VIR_NETWORKS_ALL) {
+ // VIR_NETWORKS_{ACTIVE|INACTIVE|ALL}
+ return libvirt_list_networks($conn, $opt);
+ }
+
+ function libvirt_get_net_xml($res, $xpath=NULL) {
+ return libvirt_network_get_xml_desc($res, $xpath);
+ }
+}
?>
diff --git a/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php b/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php
index 1614b4318..13204c88c 100644
--- a/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php
+++ b/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php
@@ -1,6 +1,6 @@
formatOutput = $format_output;
- self::$encoding = $encoding;
+ self::$xml = new DomDocument($version, $encoding);
+ self::$xml->formatOutput = $format_output;
+ self::$encoding = $encoding;
}
/**
* Convert an Array to XML
@@ -64,11 +65,12 @@ private static $encoding = 'UTF-8';
* @param array $arr - aray to be converterd
* @return DomDocument
*/
+
public static function &createXML($node_name, $arr=array()) {
- $xml = self::getXMLRoot();
- $xml->appendChild(self::convert($node_name, $arr));
- self::$xml = null; // clear the xml node in the class for 2nd time use.
- return $xml;
+ $xml = self::getXMLRoot();
+ $xml->appendChild(self::convert($node_name, $arr));
+ self::$xml = null; // clear the xml node in the class for 2nd time use.
+ return $xml;
}
/**
* Convert an Array to XML
@@ -76,88 +78,92 @@ private static $encoding = 'UTF-8';
* @param array $arr - aray to be converterd
* @return DOMNode
*/
+
private static function &convert($node_name, $arr=array()) {
- //print_arr($node_name);
- $xml = self::getXMLRoot();
- $node = $xml->createElement($node_name);
- if(is_array($arr)){
- // get the attributes first.;
- if(isset($arr['@attributes'])) {
- foreach($arr['@attributes'] as $key => $value) {
- if(!self::isValidTagName($key)) {
- throw new Exception('[Array2XML] Illegal character in attribute name. attribute: '.$key.' in node: '.$node_name);
- }
- $node->setAttribute($key, self::bool2str($value));
- }
- unset($arr['@attributes']); //remove the key from the array once done.
+ //print_arr($node_name);
+ $xml = self::getXMLRoot();
+ $node = $xml->createElement($node_name);
+ if(is_array($arr)){
+ // get the attributes first.;
+ if(isset($arr['@attributes'])) {
+ foreach($arr['@attributes'] as $key => $value) {
+ if(!self::isValidTagName($key)) {
+ throw new Exception('[Array2XML] Illegal character in attribute name. attribute: '.$key.' in node: '.$node_name);
}
- // check if it has a value stored in @value, if yes store the value and return
- // else check if its directly stored as string
- if(isset($arr['@value'])) {
- $node->appendChild($xml->createTextNode(self::bool2str($arr['@value'])));
- unset($arr['@value']); //remove the key from the array once done.
- //return from recursion, as a note with value cannot have child nodes.
- return $node;
- } else if(isset($arr['@cdata'])) {
- $node->appendChild($xml->createCDATASection(self::bool2str($arr['@cdata'])));
- unset($arr['@cdata']); //remove the key from the array once done.
- //return from recursion, as a note with cdata cannot have child nodes.
- return $node;
+ $node->setAttribute($key, self::bool2str($value));
+ }
+ unset($arr['@attributes']); //remove the key from the array once done.
+ }
+ // check if it has a value stored in @value, if yes store the value and return
+ // else check if its directly stored as string
+ if(isset($arr['@value'])) {
+ $node->appendChild($xml->createTextNode(self::bool2str($arr['@value'])));
+ unset($arr['@value']); //remove the key from the array once done.
+ //return from recursion, as a note with value cannot have child nodes.
+ return $node;
+ } else if(isset($arr['@cdata'])) {
+ $node->appendChild($xml->createCDATASection(self::bool2str($arr['@cdata'])));
+ unset($arr['@cdata']); //remove the key from the array once done.
+ //return from recursion, as a note with cdata cannot have child nodes.
+ return $node;
+ }
+ }
+ //create subnodes using recursion
+ if(is_array($arr)){
+ // recurse to get the node for that key
+ foreach($arr as $key=>$value){
+ if(!self::isValidTagName($key)) {
+ throw new Exception('[Array2XML] Illegal character in tag name. tag: '.$key.' in node: '.$node_name);
+ }
+ if(is_array($value) && is_numeric(key($value))) {
+ // MORE THAN ONE NODE OF ITS KIND;
+ // if the new array is numeric index, means it is array of nodes of the same kind
+ // it should follow the parent key name
+ foreach($value as $k=>$v){
+ $node->appendChild(self::convert($key, $v));
}
+ } else {
+ // ONLY ONE NODE OF ITS KIND
+ $node->appendChild(self::convert($key, $value));
+ }
+ unset($arr[$key]); //remove the key from the array once done.
}
- //create subnodes using recursion
- if(is_array($arr)){
- // recurse to get the node for that key
- foreach($arr as $key=>$value){
- if(!self::isValidTagName($key)) {
- throw new Exception('[Array2XML] Illegal character in tag name. tag: '.$key.' in node: '.$node_name);
- }
- if(is_array($value) && is_numeric(key($value))) {
- // MORE THAN ONE NODE OF ITS KIND;
- // if the new array is numeric index, means it is array of nodes of the same kind
- // it should follow the parent key name
- foreach($value as $k=>$v){
- $node->appendChild(self::convert($key, $v));
- }
- } else {
- // ONLY ONE NODE OF ITS KIND
- $node->appendChild(self::convert($key, $value));
- }
- unset($arr[$key]); //remove the key from the array once done.
- }
- }
- // after we are done with all the keys in the array (if it is one)
- // we check if it has any text value, if yes, append it.
- if(!is_array($arr)) {
- $node->appendChild($xml->createTextNode(self::bool2str($arr ?? "")));
- }
- return $node;
+ }
+ // after we are done with all the keys in the array (if it is one)
+ // we check if it has any text value, if yes, append it.
+ if(!is_array($arr)) {
+ $node->appendChild($xml->createTextNode(self::bool2str($arr ?? "")));
+ }
+ return $node;
}
/*
* Get the root XML node, if there isn't one, create it.
*/
+
private static function getXMLRoot(){
- if(empty(self::$xml)) {
- self::init();
- }
- return self::$xml;
+ if(empty(self::$xml)) {
+ self::init();
+ }
+ return self::$xml;
}
/*
* Get string representation of boolean value
*/
+
private static function bool2str($v){
- //convert boolean to text value.
- $v = $v === true ? 'true' : $v;
- $v = $v === false ? 'false' : $v;
- return $v;
+ //convert boolean to text value.
+ $v = $v === true ? 'true' : $v;
+ $v = $v === false ? 'false' : $v;
+ return $v;
}
/*
* Check if the tag name or attribute name contains illegal characters
* Ref: http://www.w3.org/TR/xml/#sec-common-syn
*/
+
private static function isValidTagName($tag){
- $pattern = '/^[a-z_]+[a-z0-9\:\-\.\_]*[^:]*$/i';
- return preg_match($pattern, $tag, $matches) && $matches[0] == $tag;
+ $pattern = '/^[a-z_]+[a-z0-9\:\-\.\_]*[^:]*$/i';
+ return preg_match($pattern, $tag, $matches) && $matches[0] == $tag;
}
}
@@ -651,7 +657,7 @@ private static $encoding = 'UTF-8';
];}
$arrDefaultClocks = [
- "windows" => [
+ "windows" => [
"hpet" => [
"present" => "no",
"tickpolicy" => "delay"
@@ -668,8 +674,8 @@ private static $encoding = 'UTF-8';
"present" => "yes",
"tickpolicy" => "catchup"
]
- ],
- "hyperv" => [
+ ],
+ "hyperv" => [
"hpet" => [
"present" => "no",
"tickpolicy" => "delay"
@@ -687,7 +693,7 @@ private static $encoding = 'UTF-8';
"tickpolicy" => "catchup"
]
] ,
- "other" => [
+ "other" => [
"hpet" => [
"present" => "no",
"tickpolicy" => "delay"
@@ -705,53 +711,52 @@ private static $encoding = 'UTF-8';
"tickpolicy" => "catchup"
]
]
- ] ;
-
+ ];
#
$arrDisplayOptions = [
- "H1.16M" => [
+ "H1.16M" => [
"text" => "1 Display 16Mb Memory",
"qxlxml" => "ram='65536' vram='16384' vgamem='16384' heads='1' primary='yes'",
],
- "H1.32M" => [
+ "H1.32M" => [
"text" => "1 Display 32Mb Memory",
"qxlxml" => "ram='65536' vram='32768' vgamem='32768' heads='1' primary='yes'",
],
- "H1.64M" => [
+ "H1.64M" => [
"text" => "1 Display 64Mb Memory",
"qxlxml" => "ram='65536' vram='65536' vram64='65535' vgamem='65536' heads='1' primary='yes'",
],
- "H1.128M" => [
+ "H1.128M" => [
"text" => "1 Display 128Mb Memory",
"qxlxml"=> "ram='65536' vram='131072' vram64='131072' vgamem='65536' heads='1' primary='yes'",
],
- "H1.256M" => [
+ "H1.256M" => [
"text" => "1 Display 256Mb Memory",
"qxlxml" => "ram='65536' vram='262144' vram64='262144' vgamem='65536' heads='1' primary='yes'",
],
- "H2.64M" => [
+ "H2.64M" => [
"text" => "2 Displays 64Mb Memory",
"qxlxml" => "ram='65536' vram='65536' vram64='65535' vgamem='65536' heads='2' primary='yes'",
],
- "H2.128M" => [
+ "H2.128M" => [
"text" => "2 Displays 128Mb Memory",
"qxlxml" => "ram='65536' vram='131072'vram64='131072' vgamem='65536' heads='2' primary='yes'",
],
- "H2.256M" => [
+ "H2.256M" => [
"text" => "2 Displays 256Mb Memory",
"qxlxml" => "ram='65536' vram='262144'vram64='262144' vgamem='65536' heads='2' primary='yes'",
],
- "H4.64M" => [
+ "H4.64M" => [
"text" => "4 Displays 64Mb Memory",
"qxlxml" => "ram='65536' vram='65536' vram64='65535' vgamem='65536' heads='4' primary='yes'",
],
- "H4.128M" => [
+ "H4.128M" => [
"text" => "4 Displays 128Mb Memory",
"qxlxml" => "ram='65536' vram='131072'vram64='131072' vgamem='65536' heads='4' primary='yes'",
],
- "H4.256M" => [
+ "H4.256M" => [
"text" => "4 Displays 256Mb Memory",
"qxlxml"=> "ram='65536' vram='262144' vram64='262144' vgamem='65536' heads='4' primary='yes'",
],
@@ -769,10 +774,10 @@ private static $encoding = 'UTF-8';
$domain_cfg['VMSTORAGEMODE'] = "auto";
}
if (!empty($domain_cfg['DOMAINDIR'])) {
- $domain_cfg['DOMAINDIR'] = rtrim($domain_cfg['DOMAINDIR'], '/') . '/';
+ $domain_cfg['DOMAINDIR'] = rtrim($domain_cfg['DOMAINDIR'], '/').'/';
}
if (!empty($domain_cfg['MEDIADIR'])) {
- $domain_cfg['MEDIADIR'] = rtrim($domain_cfg['MEDIADIR'], '/') . '/';
+ $domain_cfg['MEDIADIR'] = rtrim($domain_cfg['MEDIADIR'], '/').'/';
}
if (empty($domain_cfg['TIMEOUT'])) {
$domain_cfg['TIMEOUT'] = 60;
@@ -799,11 +804,10 @@ private static $encoding = 'UTF-8';
$ends = ['th','st','nd','rd','th','th','th','th','th','th'];
if (($number % 100) >= 11 && ($number % 100) <= 13) {
- $abbreviation = $number . 'th';
+ $abbreviation = $number.'th';
} else {
- $abbreviation = $number . $ends[$number % 10];
+ $abbreviation = $number.$ends[$number % 10];
}
-
return $abbreviation;
}
@@ -828,7 +832,7 @@ private static $encoding = 'UTF-8';
}
function getDiskImageInfo($strImgPath) {
- $arrJSON = json_decode(shell_exec("qemu-img info --output json " . escapeshellarg($strImgPath) . " 2>/dev/null"), true);
+ $arrJSON = json_decode(shell_exec("qemu-img info --output json ".escapeshellarg($strImgPath)." 2>/dev/null"), true);
return $arrJSON;
}
@@ -868,9 +872,9 @@ private static $encoding = 'UTF-8';
# file is csv typeid:productid
#
if (is_file("/boot/config/VMPCIOverride.cfg")) {
- $arrWhiteListOverride = str_getcsv(file_get_contents("/boot/config/VMPCIOverride.cfg")) ;
+ $arrWhiteListOverride = str_getcsv(file_get_contents("/boot/config/VMPCIOverride.cfg"));
}
- $arrWhiteListOverride[] = "0880:089a" ;
+ $arrWhiteListOverride[] = "0880:089a";
$arrValidPCIDevices = [];
@@ -886,7 +890,7 @@ private static $encoding = 'UTF-8';
$boolBlacklisted = true;
}
- $overrideCheck = "{$arrMatch['typeid']}:{$arrMatch['productid']}" ;
+ $overrideCheck = "{$arrMatch['typeid']}:{$arrMatch['productid']}";
if (in_array($overrideCheck,$arrWhiteListOverride) ) $boolBlacklisted = false;
$strClass = 'other';
@@ -901,15 +905,15 @@ private static $encoding = 'UTF-8';
$strClass = 'audio';
}
- if (!file_exists('/sys/bus/pci/devices/0000:' . $arrMatch['id'] . '/iommu_group/')) {
+ if (!file_exists('/sys/bus/pci/devices/0000:'.$arrMatch['id'].'/iommu_group/')) {
// No IOMMU support for device, skip device
continue;
}
// Attempt to get the current kernel-bound driver for this pci device
$strDriver = '';
- if (is_link('/sys/bus/pci/devices/0000:' . $arrMatch['id'] . '/driver')) {
- $strLink = @readlink('/sys/bus/pci/devices/0000:' . $arrMatch['id'] . '/driver');
+ if (is_link('/sys/bus/pci/devices/0000:'.$arrMatch['id'].'/driver')) {
+ $strLink = @readlink('/sys/bus/pci/devices/0000:'.$arrMatch['id'].'/driver');
if (!empty($strLink)) {
$strDriver = basename($strLink);
}
@@ -917,8 +921,8 @@ private static $encoding = 'UTF-8';
// Attempt to get the boot_vga driver for this pci device
$strBootVGA = '';
- if (is_file('/sys/bus/pci/devices/0000:' . $arrMatch['id'] . '/boot_vga') && $strClass == 'vga') {
- $strFileVal = file_get_contents('/sys/bus/pci/devices/0000:' . $arrMatch['id'] . '/boot_vga');
+ if (is_file('/sys/bus/pci/devices/0000:'.$arrMatch['id'].'/boot_vga') && $strClass == 'vga') {
+ $strFileVal = file_get_contents('/sys/bus/pci/devices/0000:'.$arrMatch['id'].'/boot_vga');
if (!empty($strFileVal)) {
$strBootVGA = trim($strFileVal);
}
@@ -939,14 +943,13 @@ private static $encoding = 'UTF-8';
'class' => $strClass,
'driver' => $strDriver,
'bootvga' => $strBootVGA,
- 'name' => $arrMatch['vendorname'] . ' ' . $arrMatch['productname'],
+ 'name' => $arrMatch['vendorname'].' '.$arrMatch['productname'],
'blacklisted' => $boolBlacklisted
];
}
}
$cacheValidPCIDevices = $arrValidPCIDevices;
-
return $arrValidPCIDevices;
}
@@ -956,7 +959,6 @@ private static $encoding = 'UTF-8';
$arrValidGPUDevices = array_filter($arrValidPCIDevices, function($arrDev) {
return ($arrDev['class'] == 'vga' && !$arrDev['blacklisted']);
});
-
return $arrValidGPUDevices;
}
@@ -966,7 +968,6 @@ private static $encoding = 'UTF-8';
$arrValidAudioDevices = array_filter($arrValidPCIDevices, function($arrDev) {
return ($arrDev['class'] == 'audio' && !$arrDev['blacklisted']);
});
-
return $arrValidAudioDevices;
}
@@ -976,7 +977,6 @@ private static $encoding = 'UTF-8';
$arrValidOtherDevices = array_filter($arrValidPCIDevices, function($arrDev) {
return ($arrDev['class'] == 'other' && !$arrDev['blacklisted']);
});
-
return $arrValidOtherDevices;
}
@@ -986,7 +986,6 @@ private static $encoding = 'UTF-8';
$arrValidOtherStubbedDevices = array_filter($arrValidPCIDevices, function($arrDev) {
return ($arrDev['class'] == 'other' && !$arrDev['blacklisted'] && in_array($arrDev['driver'], ['pci-stub', 'vfio-pci']));
});
-
return $arrValidOtherStubbedDevices;
}
@@ -996,8 +995,8 @@ private static $encoding = 'UTF-8';
}
function getevDev($res) {
- global $lv ;
- $xml = $lv->domain_get_xml($res) ;
+ global $lv;
+ $xml = $lv->domain_get_xml($res);
$xmldoc = new SimpleXMLElement($xml);
$xmlpath = $xmldoc->xpath('//devices/input[@type="evdev"] ');
$evdevs = [];
@@ -1010,7 +1009,7 @@ private static $encoding = 'UTF-8';
];
}
if (empty($evdevs)) $evdevs[0] = ['dev'=>"",'grab'=>"",'repeat'=>"",'grabToggle'=>""];
- return $evdevs;
+ return $evdevs;
}
$cacheValidUSBDevices = null;
@@ -1068,7 +1067,6 @@ private static $encoding = 'UTF-8';
});
$cacheValidUSBDevices = $arrValidUSBDevices;
-
return $arrValidUSBDevices;
}
@@ -1080,12 +1078,12 @@ private static $encoding = 'UTF-8';
$arrQEMUInfo = $lv->get_connect_information();
$arrMachineTypes = $lv->get_machine_types('x86_64');
- $strQEMUVersion = $arrQEMUInfo['hypervisor_major'] . '.' . $arrQEMUInfo['hypervisor_minor'];
+ $strQEMUVersion = $arrQEMUInfo['hypervisor_major'].'.'.$arrQEMUInfo['hypervisor_minor'];
foreach ($arrMachineTypes as $arrMachine) {
if ($arrMachine['name'] == 'q35') {
// Latest Q35
- $arrValidMachineTypes['pc-q35-' . $strQEMUVersion] = 'Q35-' . $strQEMUVersion;
+ $arrValidMachineTypes['pc-q35-'.$strQEMUVersion] = 'Q35-'.$strQEMUVersion;
}
if (strpos($arrMachine['name'], 'q35-') !== false) {
// Prior releases of Q35
@@ -1093,7 +1091,7 @@ private static $encoding = 'UTF-8';
}
if ($arrMachine['name'] == 'pc') {
// Latest i440fx
- $arrValidMachineTypes['pc-i440fx-' . $strQEMUVersion] = 'i440fx-' . $strQEMUVersion;
+ $arrValidMachineTypes['pc-i440fx-'.$strQEMUVersion] = 'i440fx-'.$strQEMUVersion;
}
if (strpos($arrMachine['name'], 'i440fx-') !== false) {
// Prior releases of i440fx
@@ -1103,20 +1101,19 @@ private static $encoding = 'UTF-8';
uksort($arrValidMachineTypes, 'version_compare');
$arrValidMachineTypes = array_reverse($arrValidMachineTypes);
-
return $arrValidMachineTypes;
}
function ValidateMachineType($machinetype) {
$machinetypes=getValidMachineTypes();
$type = substr($machinetype,0,strpos($machinetype,'-',3));
- foreach($machinetypes as $machinetypekey => $machinedetails){
+ foreach($machinetypes as $machinetypekey => $machinedetails) {
$check_type = substr($machinetypekey,0,strlen($type));
if ($check_type == $type) break;
}
- return($machinetypekey) ;
+ return($machinetypekey);
}
-
+
function getLatestMachineType($strType = 'i440fx') {
$arrMachineTypes = getValidMachineTypes();
@@ -1125,7 +1122,6 @@ private static $encoding = 'UTF-8';
return $key;
}
}
-
return array_shift(array_keys($arrMachineTypes));
}
@@ -1134,7 +1130,6 @@ private static $encoding = 'UTF-8';
'raw' => 'raw',
'qcow2' => 'qcow2'
];
-
return $arrValidDiskDrivers;
}
@@ -1146,7 +1141,6 @@ private static $encoding = 'UTF-8';
'ide' => 'IDE',
'usb' => 'USB'
];
-
return $arrValidDiskBuses;
}
@@ -1155,7 +1149,6 @@ private static $encoding = 'UTF-8';
'ignore' => 'Ignore(No Trim)',
'unmap' => 'Unmap(Trim)',
];
-
return $arrValidDiskDiscard;
}
@@ -1166,7 +1159,6 @@ private static $encoding = 'UTF-8';
'ide' => 'IDE',
'usb' => 'USB'
];
-
return $arrValidCdromBuses;
}
@@ -1178,7 +1170,6 @@ private static $encoding = 'UTF-8';
'virtio3d' => 'Virtio(3d)',
'vmvga' => 'vmvga'
];
-
return $arrValidVNCModels;
}
function getValidVMRCProtocols() {
@@ -1186,7 +1177,6 @@ private static $encoding = 'UTF-8';
'vnc' => 'VNC',
'spice' => 'SPICE'
];
-
return $arrValidProtocols;
}
@@ -1228,13 +1218,12 @@ private static $encoding = 'UTF-8';
'th' => 'Thailand (th)',
'tr' => 'Turkish (tr)'
];
-
return $arrValidKeyMaps;
}
function getHostCPUModel() {
$cpu = explode('#', exec("dmidecode -q -t 4|awk -F: '{if(/Version:/) v=$2; else if(/Current Speed:/) s=$2} END{print v\"#\"s}'"));
- [$strCPUModel] = my_explode('@', str_replace(["Processor","CPU","(C)","(R)","(TM)"], ["","","©","®","™"], $cpu[0]) . '@', 1);
+ [$strCPUModel] = my_explode('@', str_replace(["Processor","CPU","(C)","(R)","(TM)"], ["","","©","®","™"], $cpu[0]).'@', 1);
return trim($strCPUModel);
}
@@ -1267,7 +1256,6 @@ private static $encoding = 'UTF-8';
$arrValidNetworks['libvirt'] = array_values($arrVirtual);
}*/
-
return $arrValidNetworks;
}
@@ -1288,7 +1276,7 @@ private static $encoding = 'UTF-8';
$arrNICs = $lv->get_nic_info($res);
$arrHostDevs = $lv->domain_get_host_devices_pci($res);
$arrUSBDevs = $lv->domain_get_host_devices_usb($res);
- $getcopypaste=getcopypaste($res) ;
+ $getcopypaste=getcopypaste($res);
// Metadata Parsing
// libvirt xpath parser sucks, use php's xpath parser instead
@@ -1316,7 +1304,7 @@ private static $encoding = 'UTF-8';
// check for vnc/spice; add to arrGPUDevices
$vmrcport = $lv->domain_get_vnc_port($res);
$autoport = $lv->domain_get_vmrc_autoport($res);
- if (empty($vmrcport) && $autoport == "yes") $vmrcport = -1 ;
+ if (empty($vmrcport) && $autoport == "yes") $vmrcport = -1;
if (!empty($vmrcport)) {
$arrGPUDevices[] = [
'id' => 'virtual',
@@ -1424,14 +1412,14 @@ private static $encoding = 'UTF-8';
$strOVMF = '0';
if (!empty($lv->domain_get_ovmf($res))) {
$ovmfloader = $lv->domain_get_ovmf($res);
- if (strpos($ovmfloader, '_CODE-pure-efi.fd') !== false) {
- $strOVMF = '1';
- } else if (strpos($ovmfloader, '_CODE-pure-efi-tpm.fd') !== false) {
- $strOVMF = '2';
- }
- }
+ if (strpos($ovmfloader, '_CODE-pure-efi.fd') !== false) {
+ $strOVMF = '1';
+ } else if (strpos($ovmfloader, '_CODE-pure-efi-tpm.fd') !== false) {
+ $strOVMF = '2';
+ }
+ }
- if ($lv->domain_get_boot_devices($res)[0] == "fd") $osbootdev = "Yes" ; else $osbootdev = "No" ;
+ if ($lv->domain_get_boot_devices($res)[0] == "fd") $osbootdev = "Yes"; else $osbootdev = "No";
$vmname = $lv->domain_get_name($res);
$cmdline = null;
$QEMUCmdline = getQEMUCmdLine($strDOMXML);
@@ -1532,8 +1520,8 @@ private static $encoding = 'UTF-8';
foreach ($new['devices']['disk'] as $key => $disk) {
$source = $disk['source']['@attributes']['file'];
if (isset($disk['driver']['@attributes']['discard'])) $discard = $disk['driver']['@attributes']['discard']; else $discard = null;
- foreach ($old['devices']['disk'] as $k => $d)
- if ($source==$d['source']['@attributes']['file']) {
+ foreach ($old['devices']['disk'] as $k => $d)
+ if ($source==$d['source']['@attributes']['file']) {
if (isset($discard)) $d['driver']['@attributes']['discard'] = $discard;
$new['devices']['disk'][$key]['driver']['@attributes'] = $d['driver']['@attributes'];
}
@@ -1544,7 +1532,7 @@ private static $encoding = 'UTF-8';
// preserve vnc/spice port settings
// unset($new['devices']['graphics']['@attributes']['port'],$new['devices']['graphics']['@attributes']['autoport']);
unset($old['devices']['graphics']);
- if (!isset($new['devices']['graphics']['@attributes']['keymap']) && isset($old['devices']['graphics']['@attributes']['keymap'])) unset($old['devices']['graphics']['@attributes']['keymap']) ;
+ if (!isset($new['devices']['graphics']['@attributes']['keymap']) && isset($old['devices']['graphics']['@attributes']['keymap'])) unset($old['devices']['graphics']['@attributes']['keymap']);
// update parent arrays
if (!$old['devices']['hostdev']) unset($old['devices']['hostdev']);
if (!$new['devices']['hostdev']) unset($new['devices']['hostdev']);
@@ -1553,16 +1541,15 @@ private static $encoding = 'UTF-8';
// remove existing auto-generated settings
unset($old['cputune']['vcpupin'],$old['devices']['video'],$old['devices']['disk'],$old['devices']['interface'],$old['devices']['filesystem'],$old['cpu']['@attributes'],$old['os']['boot'],$old['os']['loader'],$old['os']['nvram']);
// Remove old CPU cache and features
- unset($old['cpu']['cache'], $old['cpu']['feature']) ;
- unset($old['features']['hyperv'],$old['devices']['channel']) ;
+ unset($old['cpu']['cache'], $old['cpu']['feature']);
+ unset($old['features']['hyperv'],$old['devices']['channel']);
// set namespace
$new['metadata']['vmtemplate']['@attributes']['xmlns'] = 'unraid';
}
function getVMUSBs($strXML){
- $arrValidUSBDevices = getValidUSBDevices() ;
+ $arrValidUSBDevices = getValidUSBDevices();
foreach($arrValidUSBDevices as $key => $data) {
-
$array[$key] = [
'id' => $data['id'],
'name' => $data["name"],
@@ -1573,21 +1560,21 @@ private static $encoding = 'UTF-8';
}
if ($strXML !="") {
$VMxml = new SimpleXMLElement($strXML);
- $VMUSB=$VMxml->xpath('//devices/hostdev[@type="usb"]') ;
+ $VMUSB=$VMxml->xpath('//devices/hostdev[@type="usb"]');
foreach($VMUSB as $USB){
- $vendor=$USB->source->vendor->attributes()->id ;
- $product=$USB->source->product->attributes()->id ;
- $startupPolicy=$USB->source->attributes()->startupPolicy ;
- $usbboot= $USB->boot->attributes()->order ?? "" ;
- $id = str_replace('0x', '', $vendor . ':' . $product) ;
- $found = false ;
+ $vendor=$USB->source->vendor->attributes()->id;
+ $product=$USB->source->product->attributes()->id;
+ $startupPolicy=$USB->source->attributes()->startupPolicy;
+ $usbboot= $USB->boot->attributes()->order ?? "";
+ $id = str_replace('0x', '', $vendor.':'.$product);
+ $found = false;
foreach($arrValidUSBDevices as $key => $data) {
if ($data['id'] == $id) {
- $array[$key]['checked'] = "checked" ;
- $array[$key]['startupPolicy'] = $startupPolicy ;
- $array[$key]['usbboot'] = $usbboot ;
- $found = true ;
- break ;
+ $array[$key]['checked'] = "checked";
+ $array[$key]['startupPolicy'] = $startupPolicy;
+ $array[$key]['usbboot'] = $usbboot;
+ $found = true;
+ break;
}
}
if (!$found) {
@@ -1601,48 +1588,48 @@ private static $encoding = 'UTF-8';
}
}
}
- return $array ;
+ return $array;
}
function sharesOnly($disk) {
return strpos('Data,Cache',$disk['type'])!==false && $disk['exportable']=='yes';
- }
+ }
function getUnraidShares(){
$shares = parse_ini_file('state/shares.ini',true);
uksort($shares,'strnatcasecmp');
- $arrreturn[] = "Manual" ;
+ $arrreturn[] = "Manual";
foreach ($shares as $share) {
- $arrreturn[] = "User:".$share["name"] ;
+ $arrreturn[] = "User:".$share["name"];
}
$disks = parse_ini_file('state/disks.ini',true);
$disks = array_filter($disks,'sharesOnly');
foreach ($disks as $name => $disk) {
- $arrreturn[] = "Disk:".$name ;
+ $arrreturn[] = "Disk:".$name;
}
- return $arrreturn ;
+ return $arrreturn;
}
function getgastate($res) {
- global $lv ;
- $xml = new SimpleXMLElement($lv->domain_get_xml($res)) ;
- $data = $xml->xpath('//channel/target[@name="org.qemu.guest_agent.0"]/@state') ;
- $data = $data[0]->state ?? null ;
- return $data ;
+ global $lv;
+ $xml = new SimpleXMLElement($lv->domain_get_xml($res));
+ $data = $xml->xpath('//channel/target[@name="org.qemu.guest_agent.0"]/@state');
+ $data = $data[0]->state ?? null;
+ return $data;
}
function getmemoryBacking($res) {
- global $lv ;
- $xml = $lv->domain_get_xml($res) ;
+ global $lv;
+ $xml = $lv->domain_get_xml($res);
$memoryBacking = new SimpleXMLElement($xml);
- $memorybacking = $memoryBacking->memoryBacking ;
- return json_encode($memorybacking); ;
+ $memorybacking = $memoryBacking->memoryBacking;
+ return json_encode($memorybacking);;
}
function getClocks($xml) {
$clocks = new SimpleXMLElement($xml);
- $clocks = json_decode(json_encode($clocks->clock),true) ;
+ $clocks = json_decode(json_encode($clocks->clock),true);
$arrClocks = [
"hpet" => [
"present" => "no",
@@ -1660,66 +1647,66 @@ private static $encoding = 'UTF-8';
"present" => "no",
"tickpolicy" => "delay"
]
- ] ;
+ ];
foreach ($clocks['timer'] as $timer) {
- $name = $timer["@attributes"]["name"] ;
- $tickpolicy = $timer["@attributes"]["tickpolicy"] ;
- $present = $timer["@attributes"]["present"] ;
- if (isset($present)) $arrClocks[$name]['present'] = $present ;
- if (isset($tickpolicy)) { $arrClocks[$name]['tickpolicy'] = $tickpolicy ; $arrClocks[$name]['present'] = 'yes' ; }
+ $name = $timer["@attributes"]["name"];
+ $tickpolicy = $timer["@attributes"]["tickpolicy"];
+ $present = $timer["@attributes"]["present"];
+ if (isset($present)) $arrClocks[$name]['present'] = $present;
+ if (isset($tickpolicy)) { $arrClocks[$name]['tickpolicy'] = $tickpolicy; $arrClocks[$name]['present'] = 'yes'; }
}
- return json_encode($arrClocks) ;
+ return json_encode($arrClocks);
}
function getQEMUCmdLine($xml) {
- $x = strpos($xml,"", 0) ;
- if ($x === false) return null ;
- $y = strpos($xml,"", 0) ;
- $z=$y ;
+ $x = strpos($xml,"", 0);
+ if ($x === false) return null;
+ $y = strpos($xml,"", 0) ;
+ $z=$y;
while ($y!=false) {
- $y = strpos($xml,"", $z +19) ;
- if ($y != false) $z =$y ;
+ $y = strpos($xml,"", $z +19) ;
+ if ($y != false) $z =$y ;
}
return substr($xml,$x, ($z + 19) -$x);
}
function getQEMUOverride($xml) {
- $x = strpos($xml,"", 0) ;
- if ($x === false) return null ;
- $y = strpos($xml,"", 0) ;
- $z=$y ;
+ $x = strpos($xml,"", 0);
+ if ($x === false) return null;
+ $y = strpos($xml,"", 0) ;
+ $z=$y;
while ($y!=false) {
- $y = strpos($xml,"", $z +16) ;
- if ($y != false) $z =$y ;
+ $y = strpos($xml,"", $z +16) ;
+ if ($y != false) $z =$y ;
}
- return substr($xml,$x, ($z + 16) -$x) ;
+ return substr($xml,$x, ($z + 16) -$x);
}
function getchannels($res) {
- global $lv ;
- $xml = $lv->domain_get_xml($res) ;
- $x = strpos($xml,"", 0) ;
- $z=$y ;
+ global $lv;
+ $xml = $lv->domain_get_xml($res);
+ $x = strpos($xml,"", 0) ;
+ $z=$y;
while ($y!=false) {
- $y = strpos($xml,"", $z +10) ;
- if ($y != false) $z =$y ;
+ $y = strpos($xml,"", $z +10) ;
+ if ($y != false) $z =$y ;
}
- $channels = substr($xml,$x, ($z + 10) -$x) ;
- return $channels ;
+ $channels = substr($xml,$x, ($z + 10) -$x);
+ return $channels;
}
function getcopypaste($res) {
- $channels = getchannels($res) ;
- $spicevmc = $qemuvdaagent = $copypaste = false ;
- if (strpos($channels,"spicevmc",0)) $spicevmc = true ;
- if (strpos($channels,"qemu-vdagent",0)) $qemuvdaagent = true ;
- if ($spicevmc || $qemuvdaagent) $copypaste = true ; else $copypaste = false ;
- return $copypaste ;
+ $channels = getchannels($res);
+ $spicevmc = $qemuvdaagent = $copypaste = false;
+ if (strpos($channels,"spicevmc",0)) $spicevmc = true;
+ if (strpos($channels,"qemu-vdagent",0)) $qemuvdaagent = true;
+ if ($spicevmc || $qemuvdaagent) $copypaste = true; else $copypaste = false;
+ return $copypaste;
}
function vm_clone($vm, $clone ,$overwrite,$start,$edit, $free, $waitID) {
- global $lv,$domain_cfg ;
+ global $lv,$domain_cfg;
/*
Clone.
@@ -1747,78 +1734,78 @@ private static $encoding = 'UTF-8';
*/
$snaps = getvmsnapshots($vm);
if (is_array($snaps)) {
- if (count($snaps) ) {write("addLog\0".htmlspecialchars(_("Clone of VM not currently supported if it has snapshots"))); $arrResponse = ['error' => _("Clone of VM not currently supported if it has snapshots")]; return false ;}
+ if (count($snaps) ) {write("addLog\0".htmlspecialchars(_("Clone of VM not currently supported if it has snapshots"))); $arrResponse = ['error' => _("Clone of VM not currently supported if it has snapshots")]; return false;}
}
- $uuid = $lv->domain_get_uuid($clone) ;
+ $uuid = $lv->domain_get_uuid($clone);
write("addLog\0".htmlspecialchars(_("Checking if clone exists")));
- if ($uuid) { $arrResponse = ['error' => _("Clone VM name already inuse")]; return false ;}
+ if ($uuid) { $arrResponse = ['error' => _("Clone VM name already inuse")]; return false;}
#VM must be shutdown.
$res = $lv->get_domain_by_name($vm);
$dom = $lv->domain_get_info($res);
$state = $lv->domain_state_translate($dom['state']);
- $vmxml = $lv->domain_get_xml($res) ;
+ $vmxml = $lv->domain_get_xml($res);
$storage = $lv->_get_single_xpath_result($vm, '//domain/metadata/*[local-name()=\'vmtemplate\']/@storage');
- if (empty($storage)) $storage = "default" ;
+ if (empty($storage)) $storage = "default";
# if VM running shutdown. Record was running.
- if ($state != 'shutoff') {write("addLog\0".htmlspecialchars(_("Shuting down $vm current $state"))); $arrResponse = $lv->domain_destroy($vm) ; }
+ if ($state != 'shutoff') {write("addLog\0".htmlspecialchars(_("Shuting down $vm current $state"))); $arrResponse = $lv->domain_destroy($vm); }
# Wait for shutdown?
- $disks =$lv->get_disk_stats($vm) ;
+ $disks =$lv->get_disk_stats($vm);
- $capacity = 0 ;
+ $capacity = 0;
foreach($disks as $disk) {
- $file = $disk["file"] ;
- $pathinfo = pathinfo($file) ;
- $capacity = $capacity + $disk["capacity"] ;
+ $file = $disk["file"];
+ $pathinfo = pathinfo($file);
+ $capacity = $capacity + $disk["capacity"];
}
#Check free space.
write("addLog\0".htmlspecialchars("Checking for free space"));
- $dirfree = disk_free_space($pathinfo["dirname"]) ;
+ $dirfree = disk_free_space($pathinfo["dirname"]);
$sourcedir = trim(shell_exec("getfattr --absolute-names --only-values -n system.LOCATION ".escapeshellarg($pathinfo["dirname"])." 2>/dev/null"));
if (!empty($sourcedir)) $repdir = str_replace('/mnt/user/', "/mnt/$sourcedir/", $pathinfo["dirname"]); else $repdir = $pathinfo["dirname"];
- $repdirfree = disk_free_space($repdir) ;
- $reflink = true ;
- $capacity *= 1 ;
+ $repdirfree = disk_free_space($repdir);
+ $reflink = true;
+ $capacity *= 1;
- if ($free == "yes" && $repdirfree < $capacity) { $reflink = false ;}
- if ($free == "yes" && $dirfree < $capacity) { write("addLog\0".htmlspecialchars(_("Insufficent storage for clone"))); return false ;}
+ if ($free == "yes" && $repdirfree < $capacity) { $reflink = false;}
+ if ($free == "yes" && $dirfree < $capacity) { write("addLog\0".htmlspecialchars(_("Insufficent storage for clone"))); return false;}
#Clone XML
- $uuid = $lv->domain_get_uuid($vm) ;
- $config=domain_to_config($uuid) ;
+ $uuid = $lv->domain_get_uuid($vm);
+ $config=domain_to_config($uuid);
- $config["domain"]["name"] = $clone ;
- $config["domain"]["uuid"] = $lv->domain_generate_uuid() ;
+ $config["domain"]["name"] = $clone;
+ $config["domain"]["uuid"] = $lv->domain_generate_uuid();
foreach($config["nic"] as $index => $detail) {
- $config["nic"][$index]["mac"] = $lv->generate_random_mac_addr() ;
+ $config["nic"][$index]["mac"] = $lv->generate_random_mac_addr();
}
$config["domain"]["type"] = "kvm";
- $usbs = getVMUSBs($vmxml) ;
+ $usbs = getVMUSBs($vmxml);
foreach($usbs as $i => $usb) {
- if ($usb["checked"] == "checked") continue ;
- unset($usbs[$i]) ;
+ if ($usb["checked"] == "checked") continue;
+ unset($usbs[$i]);
}
- $config["usb"] = $usbs ;
+ $config["usb"] = $usbs;
- $files_exist = false ;
- $files_clone = array() ;
+ $files_exist = false;
+ $files_clone = array();
if ($config['disk'][0]['new'] != "") {
foreach ($config["disk"] as $diskid => $disk) {
- $file_clone[$diskid]["source"] = $config["disk"][$diskid]["new"] ;
- $config["disk"][$diskid]["new"] = str_replace($vm,$clone,$config["disk"][$diskid]["new"]) ;
- $pi = pathinfo($config["disk"][$diskid]["new"]) ;
- $isdir = is_dir($pi['dirname']) ;
- if (is_file($config["disk"][$diskid]["new"])) $file_exists = true ;
+ $file_clone[$diskid]["source"] = $config["disk"][$diskid]["new"];
+ $config["disk"][$diskid]["new"] = str_replace($vm,$clone,$config["disk"][$diskid]["new"]);
+ $pi = pathinfo($config["disk"][$diskid]["new"]);
+ $isdir = is_dir($pi['dirname']);
+ if (is_file($config["disk"][$diskid]["new"])) $file_exists = true;
write("addLog\0".htmlspecialchars("Checking from file:".$file_clone[$diskid]["source"]));
write("addLog\0".htmlspecialchars("Checking to file:".$config["disk"][$diskid]["new"]));
write("addLog\0".htmlspecialchars("File exists value:". ($file_exists ? "True" : "False")));
- $file_clone[$diskid]["target"] = $config["disk"][$diskid]["new"] ;
+ $file_clone[$diskid]["target"] = $config["disk"][$diskid]["new"];
}
- if ($storage == "default") $clonedir = $domain_cfg['DOMAINDIR'].$clone ; else $clonedir = str_replace('/mnt/user/', "/mnt/$storage/", $domain_cfg['DOMAINDIR']).$clone;
+ if ($storage == "default") $clonedir = $domain_cfg['DOMAINDIR'].$clone; else $clonedir = str_replace('/mnt/user/', "/mnt/$storage/", $domain_cfg['DOMAINDIR']).$clone;
if (!is_dir($clonedir)) {
#mkdir($clonedir,0777,true);
my_mkdir($clonedir,0777,true);
@@ -1826,68 +1813,67 @@ private static $encoding = 'UTF-8';
#chgrp($clonedir, 'users');
}
write("addLog\0".htmlspecialchars("Checking for image files"));
- if ($file_exists && $overwrite != "yes") { write("addLog\0".htmlspecialchars(_("New image file names exist and Overwrite is not allowed"))); return( false) ; }
+ if ($file_exists && $overwrite != "yes") { write("addLog\0".htmlspecialchars(_("New image file names exist and Overwrite is not allowed"))); return( false); }
#Create duplicate files.
foreach($file_clone as $diskid => $disk) {
- $reptgt = $target = $disk['target'] ;
- $repsrc = $source = $disk['source'] ;
- if ($target == $source) { write("addLog\0".htmlspecialchars(_("New image file is same as old"))); return( false) ; }
+ $reptgt = $target = $disk['target'];
+ $repsrc = $source = $disk['source'];
+ if ($target == $source) { write("addLog\0".htmlspecialchars(_("New image file is same as old"))); return( false); }
if ($storage == "default") $sourcerealdisk = trim(shell_exec("getfattr --absolute-names --only-values -n system.LOCATION ".escapeshellarg($source)." 2>/dev/null")); else $sourcerealdisk = $storage;
if (!empty($sourcerealdisk)) {
$reptgt = str_replace('/mnt/user/', "/mnt/$sourcerealdisk/", $target);
$repsrc = str_replace('/mnt/user/', "/mnt/$sourcerealdisk/", $source);
}
- $cmdstr = "cp --reflink=always '$repsrc' '$reptgt'" ;
- if ($reflink == true) { $refcmd = $cmdstr ; } else {$refcmd = false; }
- $cmdstr = "rsync -ahPIXS --out-format=%f --info=flist0,misc0,stats0,name1,progress2 '$repsrc' '$reptgt'" ;
- $error = execCommand_nchan_clone($cmdstr,$target,$refcmd) ;
- if (!$error) { write("addLog\0".htmlspecialchars("Image copied failed.")); return( false) ; }
+ $cmdstr = "cp --reflink=always '$repsrc' '$reptgt'";
+ if ($reflink == true) { $refcmd = $cmdstr; } else {$refcmd = false; }
+ $cmdstr = "rsync -ahPIXS --out-format=%f --info=flist0,misc0,stats0,name1,progress2 '$repsrc' '$reptgt'";
+ $error = execCommand_nchan_clone($cmdstr,$target,$refcmd);
+ if (!$error) { write("addLog\0".htmlspecialchars("Image copied failed.")); return( false); }
}
}
write("","addLog\0");
write("addLog\0".htmlspecialchars("Creating new XML $clone"));
- $xml = $lv->config_to_xml($config, true) ;
- $rtn = $lv->domain_define($xml) ;
- return($rtn) ;
+ $xml = $lv->config_to_xml($config, true);
+ $rtn = $lv->domain_define($xml);
+ return($rtn);
}
-
function compare_creationtime($a, $b) {
return strnatcmp($a['creationtime'], $b['creationtime']);
- }
-
- function compare_creationtimelt($a, $b) {
- return $a['creationtime'] < $b['creationtime'];
}
- function getvmsnapshots($vm) {
- $snaps=array() ;
- $dbpath = "/etc/libvirt/qemu/snapshotdb/$vm" ;
- $snaps_json = file_get_contents($dbpath."/snapshots.db") ;
- $snaps = json_decode($snaps_json,true) ;
- if (is_array($snaps)) uasort($snaps,'compare_creationtime') ;
- return $snaps ;
- }
+ function compare_creationtimelt($a, $b) {
+ return $a['creationtime'] < $b['creationtime'];
+ }
- function write_snapshots_database($vm,$name,$state,$desc,$method="QEMU") {
- global $lv ;
- $dbpath = "/etc/libvirt/qemu/snapshotdb/$vm" ;
- if (!is_dir($dbpath)) mkdir($dbpath) ;
- $noxml = "";
- $snaps_json = file_get_contents($dbpath."/snapshots.db") ;
- $snaps = json_decode($snaps_json,true) ;
- $snapshot_res=$lv->domain_snapshot_lookup_by_name($vm,$name) ;
- if (!$snapshot_res) {
- # Manual Snap no XML
+ function getvmsnapshots($vm) {
+ $snaps=array();
+ $dbpath = "/etc/libvirt/qemu/snapshotdb/$vm";
+ $snaps_json = file_get_contents($dbpath."/snapshots.db");
+ $snaps = json_decode($snaps_json,true);
+ if (is_array($snaps)) uasort($snaps,'compare_creationtime');
+ return $snaps;
+ }
+
+ function write_snapshots_database($vm,$name,$state,$desc,$method="QEMU") {
+ global $lv;
+ $dbpath = "/etc/libvirt/qemu/snapshotdb/$vm";
+ if (!is_dir($dbpath)) mkdir($dbpath);
+ $noxml = "";
+ $snaps_json = file_get_contents($dbpath."/snapshots.db");
+ $snaps = json_decode($snaps_json,true);
+ $snapshot_res=$lv->domain_snapshot_lookup_by_name($vm,$name);
+ if (!$snapshot_res) {
+ # Manual Snap no XML
if ($state == "shutoff" && ($method == "ZFS" || $method == "BTRFS")) {
# Create Snapshot info
$vmsnap = $name;
$snaps[$vmsnap]["name"]= $name;
- $snaps[$vmsnap]["parent"]= "None" ;
+ $snaps[$vmsnap]["parent"]= "None";
$snaps[$vmsnap]["state"]= "shutoff";
$snaps[$vmsnap]["desc"]= $desc;
$snaps[$vmsnap]["memory"]= ['@attributes' => ['snapshot' => 'no']];
@@ -1896,197 +1882,193 @@ private static $encoding = 'UTF-8';
$snaps[$vmsnap]['xml'] = $lv->domain_get_xml($vm);
$noxml = "noxml";
}
- } else {
- $snapshot_xml=$lv->domain_snapshot_get_xml($snapshot_res) ;
- $a = simplexml_load_string($snapshot_xml) ;
- $a = json_encode($a) ;
- $b = json_decode($a, TRUE);
- $vmsnap = $b["name"] ;
- $snaps[$vmsnap]["name"]= $b["name"];
- $snaps[$vmsnap]["parent"]= $b["parent"] ;
- $snaps[$vmsnap]["state"]= $b["state"];
- $snaps[$vmsnap]["desc"]= $b["description"];
- $snaps[$vmsnap]["memory"]= $b["memory"];
- $snaps[$vmsnap]["creationtime"]= $b["creationTime"];
- $snaps[$vmsnap]["method"]= $method;
+ } else {
+ $snapshot_xml=$lv->domain_snapshot_get_xml($snapshot_res);
+ $a = simplexml_load_string($snapshot_xml);
+ $a = json_encode($a);
+ $b = json_decode($a, TRUE);
+ $vmsnap = $b["name"];
+ $snaps[$vmsnap]["name"]= $b["name"];
+ $snaps[$vmsnap]["parent"]= $b["parent"];
+ $snaps[$vmsnap]["state"]= $b["state"];
+ $snaps[$vmsnap]["desc"]= $b["description"];
+ $snaps[$vmsnap]["memory"]= $b["memory"];
+ $snaps[$vmsnap]["creationtime"]= $b["creationTime"];
+ $snaps[$vmsnap]["method"]= $method;
}
- $disks =$lv->get_disk_stats($vm) ;
- foreach($disks as $disk) {
- $file = $disk["file"] ;
- if ($disk['device'] == "hdc" ) $primarypath = dirname(transpose_user_path($file));
- $output = array() ;
- exec("qemu-img info --backing-chain -U '$file' | grep image:",$output) ;
- foreach($output as $key => $line) {
- $line=str_replace("image: ","",$line) ;
- $output[$key] = $line ;
- }
+ $disks =$lv->get_disk_stats($vm);
+ foreach($disks as $disk) {
+ $file = $disk["file"];
+ if ($disk['device'] == "hdc" ) $primarypath = dirname(transpose_user_path($file));
+ $output = array();
+ exec("qemu-img info --backing-chain -U '$file' | grep image:",$output);
+ foreach($output as $key => $line) {
+ $line=str_replace("image: ","",$line);
+ $output[$key] = $line;
+ }
- $snaps[$vmsnap]['backing'][$disk["device"]] = $output ;
- $rev = "r".$disk["device"] ;
- $reversed = array_reverse($output) ;
- $snaps[$vmsnap]['backing'][$rev] = $reversed ;
- }
- $snaps[$vmsnap]["primarypath"]= $primarypath;
- $parentfind = $snaps[$vmsnap]['backing'][$disk["device"]] ;
- $parendfileinfo = pathinfo($parentfind[1]) ;
- $snaps[$vmsnap]["parent"]= $parendfileinfo["extension"];
- $snaps[$vmsnap]["parent"] = str_replace("qcow2",'',$snaps[$vmsnap]["parent"]) ;
- if (isset($parentfind[1]) && !isset($parentfind[2])) $snaps[$vmsnap]["parent"]="Base" ;
+ $snaps[$vmsnap]['backing'][$disk["device"]] = $output;
+ $rev = "r".$disk["device"];
+ $reversed = array_reverse($output);
+ $snaps[$vmsnap]['backing'][$rev] = $reversed;
+ }
+ $snaps[$vmsnap]["primarypath"]= $primarypath;
+ $parentfind = $snaps[$vmsnap]['backing'][$disk["device"]];
+ $parendfileinfo = pathinfo($parentfind[1]);
+ $snaps[$vmsnap]["parent"]= $parendfileinfo["extension"];
+ $snaps[$vmsnap]["parent"] = str_replace("qcow2",'',$snaps[$vmsnap]["parent"]);
+ if (isset($parentfind[1]) && !isset($parentfind[2])) $snaps[$vmsnap]["parent"]="Base";
- if (isset($b)) if (array_key_exists(0 , $b["disks"]["disk"])) $snaps[$vmsnap]["disks"]= $b["disks"]["disk"]; else $snaps[$vmsnap]["disks"][0]= $b["disks"]["disk"];
+ if (isset($b)) if (array_key_exists(0 , $b["disks"]["disk"])) $snaps[$vmsnap]["disks"]= $b["disks"]["disk"]; else $snaps[$vmsnap]["disks"][0]= $b["disks"]["disk"];
+ $value = json_encode($snaps,JSON_PRETTY_PRINT);
+ file_put_contents($dbpath."/snapshots.db",$value);
+ return $noxml;
+ }
- $value = json_encode($snaps,JSON_PRETTY_PRINT) ;
- file_put_contents($dbpath."/snapshots.db",$value) ;
- return $noxml;
- }
+ function refresh_snapshots_database($vm) {
+ global $lv;
+ $dbpath = "/etc/libvirt/qemu/snapshotdb/$vm";
+ if (!is_dir($dbpath)) mkdir($dbpath);
+ $snaps_json = file_get_contents($dbpath."/snapshots.db");
+ $snaps = json_decode($snaps_json,true);
+ foreach($snaps as $vmsnap=>$snap)
- function refresh_snapshots_database($vm) {
- global $lv ;
- $dbpath = "/etc/libvirt/qemu/snapshotdb/$vm" ;
- if (!is_dir($dbpath)) mkdir($dbpath) ;
- $snaps_json = file_get_contents($dbpath."/snapshots.db") ;
- $snaps = json_decode($snaps_json,true) ;
- foreach($snaps as $vmsnap=>$snap)
+ $disks =$lv->get_disk_stats($vm);
+ foreach($disks as $disk) {
+ $file = $disk["file"];
+ $output = array();
+ exec("qemu-img info --backing-chain -U '$file' | grep image:",$output);
+ foreach($output as $key => $line) {
+ $line=str_replace("image: ","",$line);
+ $output[$key] = $line;
+ }
- $disks =$lv->get_disk_stats($vm) ;
- foreach($disks as $disk) {
- $file = $disk["file"] ;
- $output = array() ;
- exec("qemu-img info --backing-chain -U '$file' | grep image:",$output) ;
- foreach($output as $key => $line) {
- $line=str_replace("image: ","",$line) ;
- $output[$key] = $line ;
- }
+ $snaps[$vmsnap]['backing'][$disk["device"]] = $output;
+ $rev = "r".$disk["device"];
+ $reversed = array_reverse($output);
+ $snaps[$vmsnap]['backing'][$rev] = $reversed;
+ }
+ $parentfind = $snaps[$vmsnap]['backing'][$disk["device"]];
+ $parendfileinfo = pathinfo($parentfind[1]);
+ $snaps[$vmsnap]["parent"]= $parendfileinfo["extension"];
+ $snaps[$vmsnap]["parent"] = str_replace("qcow2",'',$snaps[$vmsnap]["parent"]);
+ if (isset($parentfind[1]) && !isset($parentfind[2])) $snaps[$vmsnap]["parent"]="Base";
- $snaps[$vmsnap]['backing'][$disk["device"]] = $output ;
- $rev = "r".$disk["device"] ;
- $reversed = array_reverse($output) ;
- $snaps[$vmsnap]['backing'][$rev] = $reversed ;
- }
- $parentfind = $snaps[$vmsnap]['backing'][$disk["device"]] ;
- $parendfileinfo = pathinfo($parentfind[1]) ;
- $snaps[$vmsnap]["parent"]= $parendfileinfo["extension"];
- $snaps[$vmsnap]["parent"] = str_replace("qcow2",'',$snaps[$vmsnap]["parent"]) ;
- if (isset($parentfind[1]) && !isset($parentfind[2])) $snaps[$vmsnap]["parent"]="Base" ;
+ $value = json_encode($snaps,JSON_PRETTY_PRINT);
+ $res = $lv->get_domain_by_name($vm);
+ #if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_create_snapshot($lv->domain_get_uuid($vm),$name);
- $value = json_encode($snaps,JSON_PRETTY_PRINT) ;
- $res = $lv->get_domain_by_name($vm);
- #if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_create_snapshot($lv->domain_get_uuid($vm),$name) ;
+ #Remove any NVRAMs that are no longer valid.
+ # Get uuid
+ $vmuuid = $lv->domain_get_uuid($vm);
+ #Get list of files
+ $filepath = "/etc/libvirt/qemu/nvram/$vmuuid*"; #$snapshotname"
+ $nvram_files=glob($filepath);
+ foreach($nvram_files as $key => $nvram_file) {
+ if ($nvram_file == "/etc/libvirt/qemu/nvram/$vmuuid"."_VARS-pure-efi.fd" || $nvram_file == "/etc/libvirt/qemu/nvram/$vmuuid"."_VARS-pure-efi-tpm.fd" ) unset($nvram_files[$key]);
+ foreach ($snaps as $snapshotname => $snap) {
+ $tpmfilename = "/etc/libvirt/qemu/nvram/".$vmuuid.$snapshotname."_VARS-pure-efi-tpm.fd";
+ $nontpmfilename = "/etc/libvirt/qemu/nvram/".$vmuuid.$snapshotname."_VARS-pure-efi.fd";
+ if ($nvram_file == $tpmfilename || $nvram_file == $nontpmfilename ) {
+ unset($nvram_files[$key]);}
+ }
+ }
+ foreach ($nvram_files as $nvram_file) unlink($nvram_file);
+ file_put_contents($dbpath."/snapshots.db",$value);
+ }
- #Remove any NVRAMs that are no longer valid.
- # Get uuid
- $vmuuid = $lv->domain_get_uuid($vm) ;
- #Get list of files
- $filepath = "/etc/libvirt/qemu/nvram/$vmuuid*" ; #$snapshotname"
- $nvram_files=glob($filepath) ;
- foreach($nvram_files as $key => $nvram_file) {
- if ($nvram_file == "/etc/libvirt/qemu/nvram/$vmuuid"."_VARS-pure-efi.fd" || $nvram_file == "/etc/libvirt/qemu/nvram/$vmuuid"."_VARS-pure-efi-tpm.fd" ) unset($nvram_files[$key]) ;
- foreach ($snaps as $snapshotname => $snap) {
- $tpmfilename = "/etc/libvirt/qemu/nvram/".$vmuuid.$snapshotname."_VARS-pure-efi-tpm.fd" ;
- $nontpmfilename = "/etc/libvirt/qemu/nvram/".$vmuuid.$snapshotname."_VARS-pure-efi.fd" ;
- if ($nvram_file == $tpmfilename || $nvram_file == $nontpmfilename ) {
- unset($nvram_files[$key]) ;}
- }
- }
- foreach ($nvram_files as $nvram_file) unlink($nvram_file) ;
+ function delete_snapshots_database($vm,$name) {
+ global $lv;
+ $dbpath = "/etc/libvirt/qemu/snapshotdb/$vm";
+ $snaps_json = file_get_contents($dbpath."/snapshots.db");
+ $snaps = json_decode($snaps_json,true);
+ unset($snaps[$name]);
+ $value = json_encode($snaps,JSON_PRETTY_PRINT);
+ file_put_contents($dbpath."/snapshots.db",$value);
+ return true;
+ }
+ function vm_snapshot($vm,$snapshotname, $snapshotdescinput, $free = "yes", $method = "QEMU", $memorysnap = "yes") {
+ global $lv;
+ $logging = true;
+ #Get State
+ $res = $lv->get_domain_by_name($vm);
+ $dom = $lv->domain_get_info($res);
+ $state = $lv->domain_state_translate($dom['state']);
+ $storage = $lv->_get_single_xpath_result($vm, '//domain/metadata/*[local-name()=\'vmtemplate\']/@storage');
+ if (empty($storage)) $storage = "default";
- file_put_contents($dbpath."/snapshots.db",$value) ;
- }
+ if ($method == "ZFS" && $state == "running" && $memorysnap == "no") {$arrResponse = ['error' => _("ZFS snapshot without memory dump not supported at this time.") ];return $arrResponse;}
- function delete_snapshots_database($vm,$name) {
- global $lv ;
- $dbpath = "/etc/libvirt/qemu/snapshotdb/$vm" ;
- $snaps_json = file_get_contents($dbpath."/snapshots.db") ;
- $snaps = json_decode($snaps_json,true) ;
- unset($snaps[$name]) ;
- $value = json_encode($snaps,JSON_PRETTY_PRINT) ;
- file_put_contents($dbpath."/snapshots.db",$value) ;
- return true ;
- }
+ #Get disks for --diskspec
+ $disks =$lv->get_disk_stats($vm);
+ $diskspec = "";
+ $capacity = 0;
+ if ($snapshotname == "--generate") $name= "S".date("YmdHis"); else $name=$snapshotname;
+ if ($snapshotdescinput != "") $snapshotdesc = " --description '$snapshotdescinput'";
- function vm_snapshot($vm,$snapshotname, $snapshotdescinput, $free = "yes", $method = "QEMU", $memorysnap = "yes") {
- global $lv ;
- $logging = true;
- #Get State
- $res = $lv->get_domain_by_name($vm);
- $dom = $lv->domain_get_info($res);
- $state = $lv->domain_state_translate($dom['state']);
- $storage = $lv->_get_single_xpath_result($vm, '//domain/metadata/*[local-name()=\'vmtemplate\']/@storage');
- if (empty($storage)) $storage = "default" ;
-
- if ($method == "ZFS" && $state == "running" && $memorysnap == "no") {$arrResponse = ['error' => _("ZFS snapshot without memory dump not supported at this time.") ] ;return $arrResponse ;}
-
- #Get disks for --diskspec
- $disks =$lv->get_disk_stats($vm) ;
- $diskspec = "" ;
- $capacity = 0 ;
- if ($snapshotname == "--generate") $name= "S" . date("YmdHis") ; else $name=$snapshotname ;
- if ($snapshotdescinput != "") $snapshotdesc = " --description '$snapshotdescinput'" ;
-
- foreach($disks as $disk) {
- $file = $disk["file"] ;
- $pathinfo = pathinfo($file) ;
- $dirpath = $pathinfo["dirname"];
- if ($storage == "default") {
+ foreach($disks as $disk) {
+ $file = $disk["file"];
+ $pathinfo = pathinfo($file);
+ $dirpath = $pathinfo["dirname"];
+ if ($storage == "default") {
$dirpath = $pathinfo["dirname"];
- } else {
+ } else {
$storagelocation = trim(shell_exec("getfattr --absolute-names --only-values -n system.LOCATION ".escapeshellarg($file)." 2>/dev/null"));
$dirpath= str_replace('/mnt/user/', "/mnt/$storagelocation/", $dirpath);
- }
- $filenew = $dirpath.'/'.$pathinfo["filename"].'.'.$name.'qcow2' ;
- switch ($method) {
+ }
+ $filenew = $dirpath.'/'.$pathinfo["filename"].'.'.$name.'qcow2';
+ switch ($method) {
case "QEMU" :
- $diskspec .= " --diskspec '".$disk["device"]."',snapshot=external,file='".$filenew."'" ;
+ $diskspec .= " --diskspec '".$disk["device"]."',snapshot=external,file='".$filenew."'";
break;
case "ZFS":
case "BTRFS":
- $diskspec .= " --diskspec '".$disk["device"]."',snapshot=manual " ;
- }
- $capacity = $capacity + $disk["capacity"] ;
- }
+ $diskspec .= " --diskspec '".$disk["device"]."',snapshot=manual ";
+ }
+ $capacity = $capacity + $disk["capacity"];
+ }
- #get memory
- $mem = $lv->domain_get_memory_stats($vm) ;
- $memory = $mem[6] ;
+ #get memory
+ $mem = $lv->domain_get_memory_stats($vm);
+ $memory = $mem[6];
- if ($memorysnap == "yes") $memspec = ' --memspec "'.$dirpath.'/memory'.$name.'.mem",snapshot=external' ; else $memspec = "" ;
- $cmdstr = "virsh snapshot-create-as '$vm' --name '$name' $snapshotdesc --atomic" ;
+ if ($memorysnap == "yes") $memspec = ' --memspec "'.$dirpath.'/memory'.$name.'.mem",snapshot=external'; else $memspec = "";
+ $cmdstr = "virsh snapshot-create-as '$vm' --name '$name' $snapshotdesc --atomic";
+ if ($state == "running" & $memorysnap == "yes") {
+ $cmdstr .= " --live ".$memspec.$diskspec;
+ $capacity = $capacity + $memory;
- if ($state == "running" & $memorysnap == "yes") {
- $cmdstr .= " --live ".$memspec.$diskspec ;
- $capacity = $capacity + $memory ;
+ } else {
+ $cmdstr .= " --disk-only ".$diskspec;
+ }
- } else {
- $cmdstr .= " --disk-only ".$diskspec ;
- }
+ #Check free space.
+ $dirfree = disk_free_space($dirpath);
- #Check free space.
- $dirfree = disk_free_space($dirpath) ;
+ $capacity *= 1;
- $capacity *= 1 ;
+ if ($free == "yes" && $dirfree < $capacity) { $arrResponse = ['error' => _("Insufficent Storage for Snapshot")]; return $arrResponse;}
- if ($free == "yes" && $dirfree < $capacity) { $arrResponse = ['error' => _("Insufficent Storage for Snapshot")]; return $arrResponse ;}
+ #Copy nvram
+ if ($logging) qemu_log($vm,"Copy NVRAM");
+ if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_create_snapshot($lv->domain_get_uuid($vm),$name);
- #Copy nvram
- if ($logging) qemu_log($vm,"Copy NVRAM");
- if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_create_snapshot($lv->domain_get_uuid($vm),$name) ;
+ $xmlfile = $dirpath."/".$name.".running";
+ if ($logging) qemu_log($vm,"Save XML if state is running current $state");
+ if ($state == "running") exec("virsh dumpxml '$vm' > ".escapeshellarg($xmlfile),$outxml,$rtnxml);
- $xmlfile = $dirpath."/".$name.".running" ;
- if ($logging) qemu_log($vm,"Save XML if state is running current $state");
- if ($state == "running") exec("virsh dumpxml '$vm' > ".escapeshellarg($xmlfile),$outxml,$rtnxml) ;
-
- $output= [] ;
- if ($logging) qemu_log($vm,"snap method $method");
- switch ($method) {
+ $output= [];
+ if ($logging) qemu_log($vm,"snap method $method");
+ switch ($method) {
case "ZFS":
# Create ZFS Snapshot
if ($state == "running") exec($cmdstr." 2>&1",$output,$return);
- $zfsdataset = trim(shell_exec("zfs list -H -o name -r $dirpath")) ;
+ $zfsdataset = trim(shell_exec("zfs list -H -o name -r $dirpath"));
$fssnapcmd = " zfs snapshot $zfsdataset@$name";
if ($logging) qemu_log($vm,"zfs snap: $fssnapcmd");
shell_exec($fssnapcmd);
@@ -2100,60 +2082,60 @@ private static $encoding = 'UTF-8';
# No Action
if ($logging) qemu_log($vm,"Cmd: $cmdstr");
exec($cmdstr." 2>&1",$output,$return);
- }
+ }
- if (strpos(" ".$output[0],"error") ) {
- $arrResponse = ['error' => substr($output[0],6) ] ;
- if ($logging) qemu_log($vm,"Error");
- } else {
- $arrResponse = ['success' => true] ;
+ if (strpos(" ".$output[0],"error") ) {
+ $arrResponse = ['error' => substr($output[0],6) ];
+ if ($logging) qemu_log($vm,"Error");
+ } else {
+ $arrResponse = ['success' => true];
if ($logging) qemu_log($vm,"Success write snap db");
- $ret = write_snapshots_database("$vm","$name",$state,$snapshotdescinput,$method) ;
+ $ret = write_snapshots_database("$vm","$name",$state,$snapshotdescinput,$method);
#remove meta data
- if ($ret != "noxml") $ret = $lv->domain_snapshot_delete($vm, "$name" ,2) ;
- }
- return $arrResponse ;
+ if ($ret != "noxml") $ret = $lv->domain_snapshot_delete($vm, "$name" ,2);
+ }
+ return $arrResponse;
- }
+ }
- function vm_revert($vm, $snap="--current",$action="no",$actionmeta = 'yes',$dryrun = false) {
- global $lv ;
+ function vm_revert($vm, $snap="--current",$action="no",$actionmeta = 'yes',$dryrun = false) {
+ global $lv;
$logging = true;
- $snapslist= getvmsnapshots($vm) ;
- #$disks =$lv->get_disk_stats($vm) ;
+ $snapslist= getvmsnapshots($vm);
+ #$disks =$lv->get_disk_stats($vm);
$snapstate = $snapslist[$snap]['state'];
$method = $snapslist[$snap]['method'];
-
+
#VM must be shutdown.
$res = $lv->get_domain_by_name($vm);
$dom = $lv->domain_get_info($res);
$state = $lv->domain_state_translate($dom['state']);
# if VM running shutdown. Record was running.
- if ($state != 'shutdown') $arrResponse = $lv->domain_destroy($vm) ;
+ if ($state != 'shutdown') $arrResponse = $lv->domain_destroy($vm);
# Wait for shutdown?
# GetXML
- $strXML= $lv->domain_get_xml($res) ;
- $xmlobj = custom::createArray('domain',$strXML) ;
-
+ $strXML= $lv->domain_get_xml($res);
+ $xmlobj = custom::createArray('domain',$strXML);
+
# Process disks and update path for method QEMU.
if ($method == "QEMU") {
- $disks=($snapslist[$snap]['disks']) ;
+ $disks=($snapslist[$snap]['disks']);
foreach ($disks as $disk) {
- $diskname = $disk["@attributes"]["name"] ;
- if ($diskname == "hda" || $diskname == "hdb") continue ;
- $path = $disk["source"]["@attributes"]["file"] ;
+ $diskname = $disk["@attributes"]["name"];
+ if ($diskname == "hda" || $diskname == "hdb") continue;
+ $path = $disk["source"]["@attributes"]["file"];
if ($diskname == "hdc") {
- $primarypathinfo = pathinfo($path) ;
- $primarypath = $primarypathinfo['dirname'] ;
+ $primarypathinfo = pathinfo($path);
+ $primarypath = $primarypathinfo['dirname'];
}
if ($snapstate != "running") {
- $item = array_search($path,$snapslist[$snap]['backing'][$diskname]) ;
+ $item = array_search($path,$snapslist[$snap]['backing'][$diskname]);
$newpath = $snapslist[$snap]['backing'][$diskname][$item + 1];
- $json_info = getDiskImageInfo($newpath) ;
+ $json_info = getDiskImageInfo($newpath);
foreach($xmlobj['devices']['disk'] as $ddk => $dd){
if ($dd['target']["@attributes"]['dev'] == $diskname) {
- $xmlobj['devices']['disk'][$ddk]['source']["@attributes"]['file'] = "$newpath" ;
- $xmlobj['devices']['disk'][$ddk]['driver']["@attributes"]['type'] = $json_info["format"] ;
+ $xmlobj['devices']['disk'][$ddk]['source']["@attributes"]['file'] = "$newpath";
+ $xmlobj['devices']['disk'][$ddk]['driver']["@attributes"]['type'] = $json_info["format"];
}
}
}
@@ -2161,73 +2143,73 @@ private static $encoding = 'UTF-8';
}
# If Snapstate not running create new XML.
- if ($snapstate != "running") {
+ if ($snapstate != "running") {
if ($method == "ZFS") $xml = $snapslist[$snap]['xml']; else $xml = custom::createXML('domain',$xmlobj)->saveXML();
if (!strpos($xml,'domain_define($xml);
- if ($new) $arrResponse = ['success' => true] ; else $arrResponse = ['error' => $lv->get_last_error()] ;
+ if ($new) $arrResponse = ['success' => true]; else $arrResponse = ['error' => $lv->get_last_error()];
if ($logging) qemu_log($vm,"Create XML $new");
}
# remove snapshot meta data, images, memory, runxml and NVRAM. for all snapshots.
foreach ($disks as $disk) {
- $diskname = $disk["@attributes"]["name"] ;
- if ($diskname == "hda" || $diskname == "hdb") continue ;
- $path = $disk["source"]["@attributes"]["file"] ;
- if (is_file($path) && $action == "yes") if (!$dryrun) unlink("$path") ;else echo "unlink $path\n";
+ $diskname = $disk["@attributes"]["name"];
+ if ($diskname == "hda" || $diskname == "hdb") continue;
+ $path = $disk["source"]["@attributes"]["file"];
+ if (is_file($path) && $action == "yes") if (!$dryrun) unlink("$path");else echo "unlink $path\n";
if ($logging) qemu_log($vm,"unlink $path");
- $item = array_search($path,$snapslist[$snap]['backing']["r".$diskname]) ;
- $item++ ;
+ $item = array_search($path,$snapslist[$snap]['backing']["r".$diskname]);
+ $item++;
while($item > 0)
{
- if (!isset($snapslist[$snap]['backing']["r".$diskname][$item])) break ;
- $newpath = $snapslist[$snap]['backing']["r".$diskname][$item] ;
+ if (!isset($snapslist[$snap]['backing']["r".$diskname][$item])) break;
+ $newpath = $snapslist[$snap]['backing']["r".$diskname][$item];
if (is_file($newpath) && $action == "yes") if (!$dryrun) unlink("$newpath"); else echo "unlink $newpath\n";
if ($logging) qemu_log($vm,"unlink $newpath");
- $item++ ;
+ $item++;
}
}
-
- # Remove later snapshots
- if (!is_null($snapslist)) uasort($snapslist,'compare_creationtimelt') ;
+
+ # Remove later snapshots
+ if (!is_null($snapslist)) uasort($snapslist,'compare_creationtimelt');
foreach($snapslist as $s) {
- if ($s['name'] == $snap) break ;
- $name = $s['name'] ;
+ if ($s['name'] == $snap) break;
+ $name = $s['name'];
$oldmethod = $s['method'];
if ($dryrun) echo "$name $oldmethod\n";
if ($logging) qemu_log($vm,"$name $oldmethod");
if (!isset($primarypath)) $primarypath = $s['primarypath'];
- $xmlfile = $primarypath."/$name.running" ;
- $memoryfile = $primarypath."/memory$name.mem" ;
- $olddisks = $snapslist[$name]['disks'] ;
+ $xmlfile = $primarypath."/$name.running";
+ $memoryfile = $primarypath."/memory$name.mem";
+ $olddisks = $snapslist[$name]['disks'];
if ($oldmethod == "QEMU") {
foreach ($olddisks as $olddisk) {
- $olddiskname = $olddisk["@attributes"]["name"] ;
- if ($olddiskname == "hda" || $olddiskname == "hdb") continue ;
- $oldpath = $olddisk["source"]["@attributes"]["file"] ;
+ $olddiskname = $olddisk["@attributes"]["name"];
+ if ($olddiskname == "hda" || $olddiskname == "hdb") continue;
+ $oldpath = $olddisk["source"]["@attributes"]["file"];
if (is_file($oldpath) && $action == "yes") if (!$dryrun) unlink("$oldpath"); else echo "$oldpath\n";
if ($logging) qemu_log($vm,"unlink $oldpath");
}
}
if ($oldmethod == "ZFS") {
# Rollback ZFS Snapshot
- $zfsdataset = trim(shell_exec("zfs list -H -o name -r ".transpose_user_path($primarypath))) ;
+ $zfsdataset = trim(shell_exec("zfs list -H -o name -r ".transpose_user_path($primarypath)));
$fssnapcmd = " zfs destroy $zfsdataset@$name";
if (!$dryrun) shell_exec($fssnapcmd); else echo "old $fssnapcmd\n";
if ($logging) qemu_log($vm,"old $fssnapcmd");
}
#Delete Metadata
- #if ($actionmeta == "yes") if (!$dryrun) $ret = delete_snapshots_database("$vm","$name") ;
-
- if (is_file($memoryfile) && $action == "yes") if (!$dryrun) unlink($memoryfile); else echo ("$memoryfile \n") ;
- if (is_file($xmlfile) && $action == "yes") if (!$dryrun) unlink($xmlfile); else echo ("$xmlfile \n") ;
+ #if ($actionmeta == "yes") if (!$dryrun) $ret = delete_snapshots_database("$vm","$name");
+
+ if (is_file($memoryfile) && $action == "yes") if (!$dryrun) unlink($memoryfile); else echo ("$memoryfile \n");
+ if (is_file($xmlfile) && $action == "yes") if (!$dryrun) unlink($xmlfile); else echo ("$xmlfile \n");
if ($logging) qemu_log($vm,"mem $memoryfile xml $xmlfile");
# Delete NVRAM
- if (!empty($lv->domain_get_ovmf($res)) && $action == "yes") if (!$dryrun) if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_revert_snapshot($lv->domain_get_uuid($vm),$name) ; else echo "Remove old NV\n";
+ if (!empty($lv->domain_get_ovmf($res)) && $action == "yes") if (!$dryrun) if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_revert_snapshot($lv->domain_get_uuid($vm),$name); else echo "Remove old NV\n";
if ($actionmeta == "yes") {
if (!$dryrun) $ret = delete_snapshots_database("$vm","$name"); else echo "Old Delete snapshot meta\n";
if ($logging) qemu_log($vm,"Old Delete snapshot meta");
@@ -2237,7 +2219,7 @@ private static $encoding = 'UTF-8';
if ($method == "ZFS") {
if (!isset($primarypath)) $primarypath = $snapslist[$snap]['primarypath'];
- $zfsdataset = trim(shell_exec("zfs list -H -o name -r ".transpose_user_path($primarypath))) ;
+ $zfsdataset = trim(shell_exec("zfs list -H -o name -r ".transpose_user_path($primarypath)));
if ($dryrun) {
var_dump(transpose_user_path($primarypath));
}
@@ -2250,20 +2232,19 @@ private static $encoding = 'UTF-8';
}
if ($snapslist[$snap]['state'] == "running" || $snapslist[$snap]['state'] == "disk-snapshot") {
- $xmlfile = $primarypath."/$snap.running" ;
- $memoryfile = $primarypath."/memory$snap.mem" ;
+ $xmlfile = $primarypath."/$snap.running";
+ $memoryfile = $primarypath."/memory$snap.mem";
# Set XML to saved XML
- $xml = file_get_contents($xmlfile) ;
- $xmlobj = custom::createArray('domain',$xml) ;
+ $xml = file_get_contents($xmlfile);
+ $xmlobj = custom::createArray('domain',$xml);
$xml = custom::createXML('domain',$xmlobj)->saveXML();
if (!strpos($xml,'domain_define($xml) ;
+ if (!$dryrun) $rtn = $lv->domain_define($xml);
if ($logging) qemu_log($vm,"Define XML");
-
# Restore Memory.
if ($snapslist[$snap]['state'] == "running") {
- if (!$dryrun) $cmdrtn = exec("virsh restore --running ".escapeshellarg($memoryfile)) ;
+ if (!$dryrun) $cmdrtn = exec("virsh restore --running ".escapeshellarg($memoryfile));
if ($logging) qemu_log($vm,"Restore");
if (!$dryrun && !$cmdrtn) unlink($xmlfile);
if ($logging) qemu_log($vm,"Unlink XML");
@@ -2273,180 +2254,177 @@ private static $encoding = 'UTF-8';
if ($snapslist[$snap]['state'] == "disk-snapshot") if (!$dryrun) unlink($xmlfile);
}
-
#if VM was started restart.
if ($state == 'running' && $snapslist[$snap]['state'] != "running") {
- if (!$dryrun) $arrResponse = $lv->domain_start($vm) ;
+ if (!$dryrun) $arrResponse = $lv->domain_start($vm);
}
if ($actionmeta == "yes") {
if (!$dryrun) $ret = delete_snapshots_database("$vm","$snap"); else echo "Delete snapshot meta\n";
if ($logging) qemu_log($vm,"Delete Snapshot DB entry");
}
-
- if (!$dryrun) if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_revert_snapshot($lv->domain_get_uuid($vm),$snap) ; else echo "Delete NV $vm,$snap\n";
- $arrResponse = ['success' => true] ;
+ if (!$dryrun) if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_revert_snapshot($lv->domain_get_uuid($vm),$snap); else echo "Delete NV $vm,$snap\n";
+
+ $arrResponse = ['success' => true];
if ($dryrun) var_dump($arrResponse);
if ($logging) qemu_log($vm, "Success");
- return($arrResponse) ;
+ return($arrResponse);
}
-
- function vm_snapimages($vm, $snap, $only) {
- global $lv ;
- $snapslist= getvmsnapshots($vm) ;
- $data = "
Images and metadata to remove if tickbox checked.
" ;
- $capacity = 0 ;
- $diskspec = "" ;
- $disks =$lv->get_disk_stats($vm) ;
- foreach($disks as $disk) {
- $file = $disk["file"] ;
- $output = array() ;
- exec("qemu-img info --backing-chain -U '$file' | grep image:",$output) ;
- foreach($output as $key => $line) {
- $line=str_replace("image: ","",$line) ;
- $output[$key] = $line ;
- }
- $snaps[$vm][$disk["device"]] = $output ;
- $rev = "r".$disk["device"] ;
- $reversed = array_reverse($output) ;
- $snaps[$vm][$rev] = $reversed ;
- $pathinfo = pathinfo($file) ;
- $capacity = $capacity + $disk["capacity"] ;
- }
- $snapdisks= $snapslist[$snap]['disks'] ;
+ function vm_snapimages($vm, $snap, $only) {
+ global $lv;
+ $snapslist= getvmsnapshots($vm);
+ $data = "
Images and metadata to remove if tickbox checked.
";
+ $capacity = 0;
+ $diskspec = "";
+ $disks =$lv->get_disk_stats($vm);
+ foreach($disks as $disk) {
+ $file = $disk["file"];
+ $output = array();
+ exec("qemu-img info --backing-chain -U '$file' | grep image:",$output);
+ foreach($output as $key => $line) {
+ $line=str_replace("image: ","",$line);
+ $output[$key] = $line;
+ }
+ $snaps[$vm][$disk["device"]] = $output ;
+ $rev = "r".$disk["device"];
+ $reversed = array_reverse($output);
+ $snaps[$vm][$rev] = $reversed;
+ $pathinfo = pathinfo($file);
+ $capacity = $capacity + $disk["capacity"];
+ }
- foreach ($snapdisks as $diskkey => $snapdisk) {
- $diskname = $snapdisk["@attributes"]["name"] ;
- if ($diskname == "hda" || $diskname == "hdb") continue ;
- $path = $snapdisk["source"]["@attributes"]["file"] ;
- if (is_file($path)) $data .= "$path
" ;
- $item = array_search($path,$snaps[$vm]["r".$diskname]) ;
- $item++ ;
- if ($only == 0) $item = 0 ;
- while($item > 0)
- {
- if (!isset($snaps[$vm]["r".$diskname][$item])) break ;
- $newpath = $snaps[$vm]["r".$diskname][$item] ;
- if (is_file($path)) $data .= "$newpath
" ;
- $item++ ;
+ $snapdisks= $snapslist[$snap]['disks'];
- }
- }
- $data .= "
Snapshots metadata to remove." ;
- if ($only == 0) {
- $data .= "
$snap";
- } else {
- uasort($snapslist,'compare_creationtimelt') ;
- foreach($snapslist as $s) {
- $name = $s['name'] ;
- $data .= "
$name";
- if ($s['name'] == $snap) break ;
- }
- }
- return($data) ;
- }
+ foreach ($snapdisks as $diskkey => $snapdisk) {
+ $diskname = $snapdisk["@attributes"]["name"];
+ if ($diskname == "hda" || $diskname == "hdb") continue;
+ $path = $snapdisk["source"]["@attributes"]["file"];
+ if (is_file($path)) $data .= "$path
";
+ $item = array_search($path,$snaps[$vm]["r".$diskname]);
+ $item++;
+ if ($only == 0) $item = 0;
+ while($item > 0)
+ {
+ if (!isset($snaps[$vm]["r".$diskname][$item])) break;
+ $newpath = $snaps[$vm]["r".$diskname][$item];
+ if (is_file($path)) $data .= "$newpath
";
+ $item++;
+ }
+ }
+ $data .= "
Snapshots metadata to remove.";
+ if ($only == 0) {
+ $data .= "
$snap";
+ } else {
+ uasort($snapslist,'compare_creationtimelt');
+ foreach($snapslist as $s) {
+ $name = $s['name'];
+ $data .= "
$name";
+ if ($s['name'] == $snap) break;
+ }
+ }
+ return($data);
+ }
- function vm_snapremove($vm, $snap) {
- global $lv ;
- $snapslist= getvmsnapshots($vm) ;
- $res = $lv->get_domain_by_name($vm);
- $dom = $lv->domain_get_info($res);
+ function vm_snapremove($vm, $snap) {
+ global $lv;
+ $snapslist= getvmsnapshots($vm);
+ $res = $lv->get_domain_by_name($vm);
+ $dom = $lv->domain_get_info($res);
- $disks =$lv->get_disk_stats($vm) ;
- foreach($disks as $disk) {
- $file = $disk["file"] ;
- $output = array() ;
- exec("qemu-img info --backing-chain -U \"$file\" | grep image:",$output) ;
- foreach($output as $key => $line) {
- $line=str_replace("image: ","",$line) ;
- $output[$key] = $line ;
- }
+ $disks =$lv->get_disk_stats($vm);
+ foreach($disks as $disk) {
+ $file = $disk["file"];
+ $output = array();
+ exec("qemu-img info --backing-chain -U \"$file\" | grep image:",$output);
+ foreach($output as $key => $line) {
+ $line=str_replace("image: ","",$line);
+ $output[$key] = $line;
+ }
- $snaps[$vm][$disk["device"]] = $output ;
- $rev = "r".$disk["device"] ;
- $reversed = array_reverse($output) ;
- $snaps[$vm][$rev] = $reversed ;
- $pathinfo = pathinfo($file) ;
- }
+ $snaps[$vm][$disk["device"]] = $output;
+ $rev = "r".$disk["device"];
+ $reversed = array_reverse($output);
+ $snaps[$vm][$rev] = $reversed;
+ $pathinfo = pathinfo($file);
+ }
- # GetXML
- $strXML= $lv->domain_get_xml($res) ;
- $xmlobj = custom::createArray('domain',$strXML) ;
+ # GetXML
+ $strXML= $lv->domain_get_xml($res);
+ $xmlobj = custom::createArray('domain',$strXML);
- # Process disks.
- $disks=($snapslist[$snap]['disks']) ;
- foreach ($disks as $disk) {
- $diskname = $disk["@attributes"]["name"] ;
- if ($diskname == "hda" || $diskname == "hdb") continue ;
- $path = $disk["source"]["@attributes"]["file"] ;
- $item = array_search($path,$snaps[$vm][$diskname]) ;
- if ($item!==false) {
- $data = ["error" => "Image currently active for this domain."] ;
- return ($data) ;
- }
- }
+ # Process disks.
+ $disks=($snapslist[$snap]['disks']);
+ foreach ($disks as $disk) {
+ $diskname = $disk["@attributes"]["name"];
+ if ($diskname == "hda" || $diskname == "hdb") continue;
+ $path = $disk["source"]["@attributes"]["file"];
+ $item = array_search($path,$snaps[$vm][$diskname]);
+ if ($item!==false) {
+ $data = ["error" => "Image currently active for this domain."];
+ return ($data);
+ }
+ }
- $disks=($snapslist[$snap]['disks']) ;
- foreach ($disks as $disk) {
- $diskname = $disk["@attributes"]["name"] ;
- if ($diskname == "hda" || $diskname == "hdb") continue ;
- $path = $disk["source"]["@attributes"]["file"] ;
- if (is_file($path)) {
- if(!unlink("$path")) {
- $data = ["error" => "Unable to remove image file $path"] ;
- return ($data) ;
- }
- }
- }
+ $disks=($snapslist[$snap]['disks']);
+ foreach ($disks as $disk) {
+ $diskname = $disk["@attributes"]["name"];
+ if ($diskname == "hda" || $diskname == "hdb") continue;
+ $path = $disk["source"]["@attributes"]["file"];
+ if (is_file($path)) {
+ if(!unlink("$path")) {
+ $data = ["error" => "Unable to remove image file $path"];
+ return ($data);
+ }
+ }
+ }
- # Delete NVRAM
- if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_delete_snapshot($lv->domain_get_uuid($vm),$snap) ;
+ # Delete NVRAM
+ if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_delete_snapshot($lv->domain_get_uuid($vm),$snap);
- $ret = delete_snapshots_database("$vm","$snap") ;
+ $ret = delete_snapshots_database("$vm","$snap") ;
- if(!$ret)
- $data = ["error" => "Unable to remove snap metadata $snap"] ;
- else
- $data = ["success => 'true"] ;
-
- return($data) ;
- }
+ if(!$ret)
+ $data = ["error" => "Unable to remove snap metadata $snap"];
+ else
+ $data = ["success => 'true"];
+ return($data);
+ }
function vm_blockcommit($vm, $snap ,$path,$base,$top,$pivot,$action) {
- global $lv ;
- /*
+ global $lv;
+ /*
NAME
- blockcommit - Start a block commit operation.
+ blockcommit - Start a block commit operation.
SYNOPSIS
- blockcommit [--bandwidth ] [--base ] [--shallow] [--top ] [--active] [--delete] [--wait] [--verbose] [--timeout ] [--pivot] [--keep-overlay] [--async] [--keep-relative] [--bytes]
+ blockcommit [--bandwidth ] [--base ] [--shallow] [--top ] [--active] [--delete] [--wait] [--verbose] [--timeout ] [--pivot] [--keep-overlay] [--async] [--keep-relative] [--bytes]
DESCRIPTION
- Commit changes from a snapshot down to its backing image.
+ Commit changes from a snapshot down to its backing image.
OPTIONS
- [--domain] domain name, id or uuid
- [--path] fully-qualified path of disk
- --bandwidth bandwidth limit in MiB/s
- --base path of base file to commit into (default bottom of chain)
- --shallow use backing file of top as base
- --top path of top file to commit from (default top of chain)
- --active trigger two-stage active commit of top file
- --delete delete files that were successfully committed
- --wait wait for job to complete (with --active, wait for job to sync)
- --verbose with --wait, display the progress
- --timeout implies --wait, abort if copy exceeds timeout (in seconds)
- --pivot implies --active --wait, pivot when commit is synced
- --keep-overlay implies --active --wait, quit when commit is synced
- --async with --wait, don't wait for cancel to finish
- --keep-relative keep the backing chain relatively referenced
- --bytes the bandwidth limit is in bytes/s rather than MiB/s
+ [--domain] domain name, id or uuid
+ [--path] fully-qualified path of disk
+ --bandwidth bandwidth limit in MiB/s
+ --base path of base file to commit into (default bottom of chain)
+ --shallow use backing file of top as base
+ --top path of top file to commit from (default top of chain)
+ --active trigger two-stage active commit of top file
+ --delete delete files that were successfully committed
+ --wait wait for job to complete (with --active, wait for job to sync)
+ --verbose with --wait, display the progress
+ --timeout implies --wait, abort if copy exceeds timeout (in seconds)
+ --pivot implies --active --wait, pivot when commit is synced
+ --keep-overlay implies --active --wait, quit when commit is synced
+ --async with --wait, don't wait for cancel to finish
+ --keep-relative keep the backing chain relatively referenced
+ --bytes the bandwidth limit is in bytes/s rather than MiB/s
- blockcommit Debian --path /mnt/user/domains/Debian/vdisk1.S20230513120410qcow2 --verbose --pivot --delete
- */
+ blockcommit Debian --path /mnt/user/domains/Debian/vdisk1.S20230513120410qcow2 --verbose --pivot --delete
+ */
#Get VM State. If shutdown start as paused.
$res = $lv->get_domain_by_name($vm);
$dom = $lv->domain_get_info($res);
@@ -2456,201 +2434,199 @@ OPTIONS
$lv->domain_suspend($res);
}
- $snapslist= getvmsnapshots($vm) ;
- $disks =$lv->get_disk_stats($vm) ;
+ $snapslist= getvmsnapshots($vm);
+ $disks =$lv->get_disk_stats($vm);
- foreach($disks as $disk) {
- $path = $disk['file'] ;
- $cmdstr = "virsh blockcommit '$vm' --path '$path' --verbose " ;
- if ($pivot == "yes") $cmdstr .= " --pivot " ;
- if ($action == "yes") $cmdstr .= " --delete " ;
- # Process disks and update path.
- $snapdisks=($snapslist[$snap]['disks']) ;
- if ($base != "--base" && $base != "") {
- #get file name from snapshot.
- $snapdisks=($snapslist[$base]['disks']) ;
- $basepath = "" ;
- foreach ($snapdisks as $snapdisk) {
- $diskname = $snapdisk["@attributes"]["name"] ;
- if ($diskname != $disk['device']) continue ;
- $basepath = $snapdisk["source"]["@attributes"]["file"] ;
- }
- if ($basepath != "") $cmdstr .= " --base '$basepath' ";
- }
- if ($top != "--top" && $top !="") {
- #get file name from snapshot.
- $snapdisks=($snapslist[$top]['disks']) ;
- $toppath = "" ;
- foreach ($snapdisks as $snapdisk) {
- $diskname = $snapdisk["@attributes"]["name"] ;
- if ($diskname != $disk['device']) continue ;
- $toppath = $snapdisk["source"]["@attributes"]["file"] ;
- }
- if ($toppath != "") $cmdstr .= " --top '$toppath' ";
- }
+ foreach($disks as $disk) {
+ $path = $disk['file'];
+ $cmdstr = "virsh blockcommit '$vm' --path '$path' --verbose ";
+ if ($pivot == "yes") $cmdstr .= " --pivot ";
+ if ($action == "yes") $cmdstr .= " --delete ";
+ # Process disks and update path.
+ $snapdisks=($snapslist[$snap]['disks']);
+ if ($base != "--base" && $base != "") {
+ #get file name from snapshot.
+ $snapdisks=($snapslist[$base]['disks']);
+ $basepath = "";
+ foreach ($snapdisks as $snapdisk) {
+ $diskname = $snapdisk["@attributes"]["name"];
+ if ($diskname != $disk['device']) continue;
+ $basepath = $snapdisk["source"]["@attributes"]["file"];
+ }
+ if ($basepath != "") $cmdstr .= " --base '$basepath' ";
+ }
+ if ($top != "--top" && $top !="") {
+ #get file name from snapshot.
+ $snapdisks=($snapslist[$top]['disks']);
+ $toppath = "";
+ foreach ($snapdisks as $snapdisk) {
+ $diskname = $snapdisk["@attributes"]["name"];
+ if ($diskname != $disk['device']) continue;
+ $toppath = $snapdisk["source"]["@attributes"]["file"];
+ }
+ if ($toppath != "") $cmdstr .= " --top '$toppath' ";
+ }
- $error = execCommand_nchan($cmdstr,$path) ;
- if (!$error) {
- $arrResponse = ['error' => "Process Failed"] ;
- return($arrResponse) ;
- } else {
- $arrResponse = ['success' => true] ;
- }
+ $error = execCommand_nchan($cmdstr,$path);
+ if (!$error) {
+ $arrResponse = ['error' => "Process Failed"];
+ return($arrResponse);
+ } else {
+ $arrResponse = ['success' => true];
+ }
- }
- # Delete NVRAM
- #if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_delete_snapshot($lv->domain_get_uuid($vm),$snap) ;
- if ($state == "shutoff") {
+ }
+ # Delete NVRAM
+ #if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_delete_snapshot($lv->domain_get_uuid($vm),$snap);
+ if ($state == "shutoff") {
$lv->domain_destroy($res);
- }
+ }
- refresh_snapshots_database($vm) ;
- $ret = $ret = delete_snapshots_database("$vm","$snap") ; ;
- if($ret)
- $data = ["error" => "Unable to remove snap metadata $snap"] ;
- else
- $data = ["success => 'true"] ;
- return $data ;
+ refresh_snapshots_database($vm);
+ $ret = $ret = delete_snapshots_database("$vm","$snap");;
+ if($ret)
+ $data = ["error" => "Unable to remove snap metadata $snap"];
+ else
+ $data = ["success => 'true"];
+ return $data;
}
function vm_blockpull($vm, $snap ,$path,$base,$top,$pivot,$action) {
- global $lv ;
- /*
+ global $lv;
+ /*
NAME
- blockpull - Populate a disk from its backing image.
+ blockpull - Populate a disk from its backing image.
SYNOPSIS
- blockpull [--bandwidth ] [--base ] [--wait] [--verbose] [--timeout ] [--async] [--keep-relative] [--bytes]
+ blockpull [--bandwidth ] [--base ] [--wait] [--verbose] [--timeout ] [--async] [--keep-relative] [--bytes]
DESCRIPTION
- Populate a disk from its backing image.
+ Populate a disk from its backing image.
OPTIONS
- [--domain] domain name, id or uuid
- [--path] fully-qualified path of disk
- --bandwidth bandwidth limit in MiB/s
- --base path of backing file in chain for a partial pull
- --wait wait for job to finish
- --verbose with --wait, display the progress
- --timeout with --wait, abort if pull exceeds timeout (in seconds)
- --async with --wait, don't wait for cancel to finish
- --keep-relative keep the backing chain relatively referenced
- --bytes the bandwidth limit is in bytes/s rather than MiB/s
+ [--domain] domain name, id or uuid
+ [--path] fully-qualified path of disk
+ --bandwidth bandwidth limit in MiB/s
+ --base path of backing file in chain for a partial pull
+ --wait wait for job to finish
+ --verbose with --wait, display the progress
+ --timeout with --wait, abort if pull exceeds timeout (in seconds)
+ --async with --wait, don't wait for cancel to finish
+ --keep-relative keep the backing chain relatively referenced
+ --bytes the bandwidth limit is in bytes/s rather than MiB/s
-
- */
- #Get VM State. If shutdown start as paused.
- $res = $lv->get_domain_by_name($vm);
- $dom = $lv->domain_get_info($res);
- $state = $lv->domain_state_translate($dom['state']);
- if ($state == "shutoff") {
+ */
+ #Get VM State. If shutdown start as paused.
+ $res = $lv->get_domain_by_name($vm);
+ $dom = $lv->domain_get_info($res);
+ $state = $lv->domain_state_translate($dom['state']);
+ if ($state == "shutoff") {
$lv->domain_start($res);
- $lv->domain_suspend($res);
- }
+ $lv->domain_suspend($res);
+ }
- $snapslist= getvmsnapshots($vm) ;
- $disks =$lv->get_disk_stats($vm) ;
- foreach($disks as $disk) {
- $file = $disk["file"] ;
- $output = array() ;
- exec("qemu-img info --backing-chain -U '$file' | grep image:",$output) ;
- foreach($output as $key => $line) {
- $line=str_replace("image: ","",$line) ;
- $output[$key] = $line ;
- }
- $snaps[$vm][$disk["device"]] = $output ;
- $rev = "r".$disk["device"] ;
- $reversed = array_reverse($output) ;
- $snaps[$vm][$rev] = $reversed ;
- }
- $snaps_json=json_encode($snaps,JSON_PRETTY_PRINT) ;
- $pathinfo = pathinfo($file) ;
- $dirpath = $pathinfo["dirname"] ;
- #file_put_contents("$dirpath/image.tracker",$snaps_json) ;
+ $snapslist= getvmsnapshots($vm);
+ $disks =$lv->get_disk_stats($vm);
+ foreach($disks as $disk) {
+ $file = $disk["file"];
+ $output = array();
+ exec("qemu-img info --backing-chain -U '$file' | grep image:",$output);
+ foreach($output as $key => $line) {
+ $line=str_replace("image: ","",$line);
+ $output[$key] = $line;
+ }
+ $snaps[$vm][$disk["device"]] = $output ;
+ $rev = "r".$disk["device"];
+ $reversed = array_reverse($output);
+ $snaps[$vm][$rev] = $reversed;
+ }
+ $snaps_json=json_encode($snaps,JSON_PRETTY_PRINT);
+ $pathinfo = pathinfo($file);
+ $dirpath = $pathinfo["dirname"];
+ #file_put_contents("$dirpath/image.tracker",$snaps_json);
- foreach($disks as $disk) {
- $path = $disk['file'] ;
- $cmdstr = "virsh blockpull '$vm' --path '$path' --verbose --pivot --delete" ;
- $cmdstr = "virsh blockpull '$vm' --path '$path' --verbose --wait " ;
+ foreach($disks as $disk) {
+ $path = $disk['file'];
+ $cmdstr = "virsh blockpull '$vm' --path '$path' --verbose --pivot --delete";
+ $cmdstr = "virsh blockpull '$vm' --path '$path' --verbose --wait ";
# Process disks and update path.
- $snapdisks=($snapslist[$snap]['disks']) ;
+ $snapdisks=($snapslist[$snap]['disks']);
if ($base != "--base" && $base != "") {
#get file name from snapshot.
- $snapdisks=($snapslist[$base]['disks']) ;
- $basepath = "" ;
+ $snapdisks=($snapslist[$base]['disks']);
+ $basepath = "";
foreach ($snapdisks as $snapdisk) {
- $diskname = $snapdisk["@attributes"]["name"] ;
- if ($diskname != $disk['device']) continue ;
- $basepath = $snapdisk["source"]["@attributes"]["file"] ;
+ $diskname = $snapdisk["@attributes"]["name"];
+ if ($diskname != $disk['device']) continue;
+ $basepath = $snapdisk["source"]["@attributes"]["file"];
}
if ($basepath != "") $cmdstr .= " --base '$basepath' ";
}
if ($action) $cmdstr .= " $action ";
-
- $error = execCommand_nchan($cmdstr,$path) ;
+ $error = execCommand_nchan($cmdstr,$path);
if (!$error) {
- $arrResponse = ['error' => "Process Failed" ] ;
- return($arrResponse) ;
+ $arrResponse = ['error' => "Process Failed" ];
+ return($arrResponse);
} else {
# Remove nvram snapshot
- $arrResponse = ['success' => true] ;
+ $arrResponse = ['success' => true];
}
}
- if ($state == "shutoff") {
+ if ($state == "shutoff") {
$lv->domain_destroy($res);
- }
+ }
- refresh_snapshots_database($vm) ;
- $ret = $ret = delete_snapshots_database("$vm","$snap") ;
- if($ret)
- $data = ["error" => "Unable to remove snap metadata $snap"] ;
- else
- $data = ["success => 'true"] ;
+ refresh_snapshots_database($vm);
+ $ret = $ret = delete_snapshots_database("$vm","$snap");
+ if($ret)
+ $data = ["error" => "Unable to remove snap metadata $snap"];
+ else
+ $data = ["success => 'true"];
- return $data ;
+ return $data;
}
function vm_blockcopy($vm,$path,$base,$top,$pivot,$action) {
- /*
+ /*
NAME
- blockcopy - Start a block copy operation.
+ blockcopy - Start a block copy operation.
SYNOPSIS
- blockcopy [--dest ] [--bandwidth ] [--shallow] [--reuse-external] [--blockdev] [--wait] [--verbose] [--timeout ] [--pivot] [--finish] [--async] [--xml ] [--format ] [--granularity ] [--buf-size ] [--bytes] [--transient-job] [--synchronous-writes] [--print-xml]
+ blockcopy [--dest ] [--bandwidth ] [--shallow] [--reuse-external] [--blockdev] [--wait] [--verbose] [--timeout ] [--pivot] [--finish] [--async] [--xml ] [--format ] [--granularity ] [--buf-size ] [--bytes] [--transient-job] [--synchronous-writes] [--print-xml]
DESCRIPTION
- Copy a disk backing image chain to dest.
+ Copy a disk backing image chain to dest.
OPTIONS
- [--domain] domain name, id or uuid
- [--path] fully-qualified path of source disk
- --dest path of the copy to create
- --bandwidth bandwidth limit in MiB/s
- --shallow make the copy share a backing chain
- --reuse-external reuse existing destination
- --blockdev copy destination is block device instead of regular file
- --wait wait for job to reach mirroring phase
- --verbose with --wait, display the progress
- --timeout implies --wait, abort if copy exceeds timeout (in seconds)
- --pivot implies --wait, pivot when mirroring starts
- --finish implies --wait, quit when mirroring starts
- --async with --wait, don't wait for cancel to finish
- --xml filename containing XML description of the copy destination
- --format format of the destination file
- --granularity power-of-two granularity to use during the copy
- --buf-size maximum amount of in-flight data during the copy
- --bytes the bandwidth limit is in bytes/s rather than MiB/s
- --transient-job the copy job is not persisted if VM is turned off
- --synchronous-writes the copy job forces guest writes to be synchronously written to the destination
- --print-xml print the XML used to start the copy job instead of starting the job
- */
+ [--domain] domain name, id or uuid
+ [--path] fully-qualified path of source disk
+ --dest path of the copy to create
+ --bandwidth bandwidth limit in MiB/s
+ --shallow make the copy share a backing chain
+ --reuse-external reuse existing destination
+ --blockdev copy destination is block device instead of regular file
+ --wait wait for job to reach mirroring phase
+ --verbose with --wait, display the progress
+ --timeout implies --wait, abort if copy exceeds timeout (in seconds)
+ --pivot implies --wait, pivot when mirroring starts
+ --finish implies --wait, quit when mirroring starts
+ --async with --wait, don't wait for cancel to finish
+ --xml filename containing XML description of the copy destination
+ --format format of the destination file
+ --granularity power-of-two granularity to use during the copy
+ --buf-size maximum amount of in-flight data during the copy
+ --bytes the bandwidth limit is in bytes/s rather than MiB/s
+ --transient-job the copy job is not persisted if VM is turned off
+ --synchronous-writes the copy job forces guest writes to be synchronously written to the destination
+ --print-xml print the XML used to start the copy job instead of starting the job
+ */
}
function addtemplatexml($post) {
@@ -2658,17 +2634,16 @@ function addtemplatexml($post) {
$savedtemplates = json_decode(file_get_contents($templateslocation),true);
if (isset($post['xmldesc'])) {
$data = explode("\n",$post['xmldesc']);
- foreach ($data as $k => $line)
- {
- if (strpos($line,"uuid")) unset($data[$k]);
- if (strpos($line,"")) unset($data[$k]);
- if (strpos($line,"")) $data[$k] = "#template123456";
+ foreach ($data as $k => $line) {
+ if (strpos($line,"uuid")) unset($data[$k]);
+ if (strpos($line,"")) unset($data[$k]);
+ if (strpos($line,"")) $data[$k] = "#template123456";
}
-
+
$data = implode("\n",$data);
$new = $lv->domain_define($data);
- $dom = $lv->get_domain_by_name("#template123456") ;
- $uuid = $lv->domain_get_uuid("#template123456") ;
+ $dom = $lv->get_domain_by_name("#template123456");
+ $uuid = $lv->domain_get_uuid("#template123456");
$usertemplate = domain_to_config($uuid);
$lv->domain_undefine($dom);
$usertemplate['templatename'] = $post['templatename'];
@@ -2676,48 +2651,46 @@ function addtemplatexml($post) {
unset($usertemplate['domain']['uuid']);
unset($usertemplate['domain']['name']);
-
} else {
// form view
- $usertemplate = $post;
+ $usertemplate = $post;
// generate xml for this domain
$strXML = $lv->config_to_xml($usertemplate);
$qemucmdline = $config['qemucmdline'];
- $strXML = $lv->appendqemucmdline($strXML,$qemucmdline) ;
+ $strXML = $lv->appendqemucmdline($strXML,$qemucmdline);
}
- foreach($usertemplate['disk'] as $diskid => $diskdata) { unset($usertemplate['disk'][$diskid]['new']);}
- foreach($usertemplate['gpu'] as $gpuid => $gpudata) { $usertemplate['gpu'][$gpuid]['guest']['multi'] = $usertemplate['gpu'][$gpuid]['multi']; unset($usertemplate['gpu'][$gpuid]['multi']);}
- unset($usertemplate['createvmtemplate']);
- unset($usertemplate['domain']['xmlstart']);
- unset($usertemplate['pci']) ;
- unset($usertemplate['usb']) ;
- unset($usertemplate['usbboot']) ;
- unset($usertemplate['nic']['mac']) ;
+ foreach($usertemplate['disk'] as $diskid => $diskdata) { unset($usertemplate['disk'][$diskid]['new']);}
+ foreach($usertemplate['gpu'] as $gpuid => $gpudata) { $usertemplate['gpu'][$gpuid]['guest']['multi'] = $usertemplate['gpu'][$gpuid]['multi']; unset($usertemplate['gpu'][$gpuid]['multi']);}
+ unset($usertemplate['createvmtemplate']);
+ unset($usertemplate['domain']['xmlstart']);
+ unset($usertemplate['pci']);
+ unset($usertemplate['usb']);
+ unset($usertemplate['usbboot']);
+ unset($usertemplate['nic']['mac']);
- $templatename=$usertemplate['templatename'];
- if ($templatename == "") $templatename=$usertemplate['template']['os'];
- unset($usertemplate['templatename']) ;
- if (strpos($templatename,"User-") === false) $templatename = "User-".$templatename ;
- if (is_array($usertemplate['clock'])) $usertemplate['clocks'] = json_encode($usertemplate['clock']);
- unset($usertemplate['clock']);
- $savedtemplates[$templatename] = [
- 'icon' => $usertemplate['template']['icon'],
- 'form' => 'Custom.form.php',
- 'os' => $usertemplate['template']['os'],
- 'overrides' => $usertemplate
- ];
- if (!is_dir(dirname($templateslocation))) mkdir(dirname($templateslocation));
- file_put_contents($templateslocation,json_encode($savedtemplates,JSON_PRETTY_PRINT));
- $reply = ['success' => true];
-
+ $templatename=$usertemplate['templatename'];
+ if ($templatename == "") $templatename=$usertemplate['template']['os'];
+ unset($usertemplate['templatename']);
+ if (strpos($templatename,"User-") === false) $templatename = "User-".$templatename;
+ if (is_array($usertemplate['clock'])) $usertemplate['clocks'] = json_encode($usertemplate['clock']);
+ unset($usertemplate['clock']);
+ $savedtemplates[$templatename] = [
+ 'icon' => $usertemplate['template']['icon'],
+ 'form' => 'Custom.form.php',
+ 'os' => $usertemplate['template']['os'],
+ 'overrides' => $usertemplate
+ ];
+ if (!is_dir(dirname($templateslocation))) mkdir(dirname($templateslocation));
+ file_put_contents($templateslocation,json_encode($savedtemplates,JSON_PRETTY_PRINT));
+ $reply = ['success' => true];
return $reply;
}
function get_vm_usage_stats($collectcpustats = true,$collectdiskstats = true,$collectnicstats = true, $collectmemstats = true) {
global $lv, $vmusagestats;
-
+
$hostcpus = $lv->host_get_node_info();
$timestamp = time();
$allstats=$lv->domain_get_all_domain_stats();
@@ -2735,7 +2708,7 @@ function get_vm_usage_stats($collectcpustats = true,$collectdiskstats = true,$co
$cpuTime = $cpuTimeAbs - $vmusagestats[$vm]["cpuTimeAbs"];
$pcentbase = ((($cpuTime) * 100.0) / ((($timestamp) - $vmusagestats[$vm]["timestamp"] ) * 1000.0 * 1000.0 * 1000.0));
$cpuHostPercent = round($pcentbase / $hostcpus['cpus'],1);
- $cpuGuestPercent = round($pcentbase / $guestcpus, 1) ;
+ $cpuGuestPercent = round($pcentbase / $guestcpus, 1);
$cpuHostPercent = max(0.0, min(100.0, $cpuHostPercent));
$cpuGuestPercent = max(0.0, min(100.0, $cpuGuestPercent));
}
@@ -2753,8 +2726,8 @@ function get_vm_usage_stats($collectcpustats = true,$collectdiskstats = true,$co
$rd=$wr=$i=0;
for ($i = 0; $i < $disknum; $i++) {
if ($data["block.$i.name"] == "hda" || $data["block.$i.name"] == "hdb") continue;
- $rd += $data["block.$i.rd.bytes"] ;
- $wr += $data["block.$i.wr.bytes"] ;
+ $rd += $data["block.$i.rd.bytes"];
+ $wr += $data["block.$i.wr.bytes"];
}
$rdrate = ($rd - $vmusagestats[$vm]['rdp']);
$wrrate = ($wr - $vmusagestats[$vm]['wrp']);
@@ -2765,32 +2738,33 @@ function get_vm_usage_stats($collectcpustats = true,$collectdiskstats = true,$co
$nicnum = $data["net.count"];
$rx=$tx=$i=0;
for ($i = 0; $i < $nicnum; $i++) {
- $rx += $data["net.$i.rx.bytes"] ;
- $tx += $data["net.$i.tx.bytes"] ;
+ $rx += $data["net.$i.rx.bytes"];
+ $tx += $data["net.$i.tx.bytes"];
}
$rxrate = round(($rx - $vmusagestats[$vm]['rxp']),0);
$txrate = round(($tx - $vmusagestats[$vm]['txp']),0);
- } else $rxrate=$txrate=0;
-
- $vmusagestats[$vm] = [
- "cpuTime" => $cpuTime,
- "cpuTimeAbs" => $cpuTimeAbs,
- "cpuhost" => $cpuHostPercent,
- "cpuguest" => $cpuGuestPercent,
- "timestamp" => $timestamp,
- "mem" => $meminuse,
- "curmem" => $currentmem,
- "maxmem" => $maximummem,
- "rxrate" => $rxrate,
- "rxp" => $rx,
- "txrate" => $txrate,
- "txp" => $tx,
- "rdp" => $rd,
- "rdrate" => $rdrate,
- "wrp" => $wr,
- "wrrate" => $wrrate,
- "state" => $state,
- ];
+ } else {
+ $rxrate=$txrate=0;
+ }
+ $vmusagestats[$vm] = [
+ "cpuTime" => $cpuTime,
+ "cpuTimeAbs" => $cpuTimeAbs,
+ "cpuhost" => $cpuHostPercent,
+ "cpuguest" => $cpuGuestPercent,
+ "timestamp" => $timestamp,
+ "mem" => $meminuse,
+ "curmem" => $currentmem,
+ "maxmem" => $maximummem,
+ "rxrate" => $rxrate,
+ "rxp" => $rx,
+ "txrate" => $txrate,
+ "txp" => $tx,
+ "rdp" => $rd,
+ "rdrate" => $rdrate,
+ "wrp" => $wr,
+ "wrrate" => $wrrate,
+ "state" => $state,
+ ];
}
}
@@ -2798,35 +2772,34 @@ function build_xml_templates($strXML) {
global $arrValidPCIDevices,$arrValidUSBDevices;
$xmldevsections = $xmlsections = [];
- $xml = new SimpleXMLElement($strXML) ;
+ $xml = new SimpleXMLElement($strXML);
$x = $xml->children();
foreach($x as $key=>$y) {
$xmlsections[] = $key;
}
-
+
$ns= $xml->getNamespaces(true);
foreach($ns as $namekey=>$namespace) foreach($xml->children($namespace) as $key=>$y) $xmlsections[] = "$namekey:$key";
-
+
$v = $xml->devices->children();
$keys = [];
foreach($v as $key=>$y) $keys[] = $key;
foreach(array_count_values($keys) as $key=>$number) $xmldevsections[]= $key;
-
+
$endpos = 0;
foreach($xmlsections as $xmlsection) {
$strpos = strpos($strXML,"<$xmlsection",$endpos);
- if ($strpos === false) continue ;
+ if ($strpos === false) continue ;
$endcheck = "$xmlsection>";
$endpos = strpos($strXML,$endcheck,$strpos);
- $xml2[$xmlsection] = trim(substr($strXML,$strpos,$endpos-$strpos+strlen($endcheck)),'/0') ;
+ $xml2[$xmlsection] = trim(substr($strXML,$strpos,$endpos-$strpos+strlen($endcheck)),'/0');
}
-
+
$xml = $xml2['devices'];
$endpos = 0;
foreach($xmldevsections as $xmlsection ) {
$strpos = $count = 0;
while (true) {
-
$strpos = strpos($xml,"<$xmlsection",$endpos);
if ($strpos === false) continue 2;
$endcheck = "$xmlsection>";
@@ -2836,14 +2809,13 @@ function build_xml_templates($strXML) {
$endcheck = "/>";
$endpos = strpos($xml,$endcheck,$strpos);
}
- # echo substr($xml,$strpos,$endpos-$strpos+strlen($endcheck)) ;
+ # echo substr($xml,$strpos,$endpos-$strpos+strlen($endcheck));
if ($xmlsection == "disk") {
$disk = substr($xml,$strpos,$endpos-$strpos+strlen($endcheck));
$xmldiskdoc = new SimpleXMLElement($disk);
$devxml[$xmlsection][$xmldiskdoc->target->attributes()->dev->__toString()] = $disk;
-
} else {
- $devxml[$xmlsection][$count] = substr($xml,$strpos,$endpos-$strpos+strlen($endcheck)) ;
+ $devxml[$xmlsection][$count] = substr($xml,$strpos,$endpos-$strpos+strlen($endcheck));
}
$count++;
}
@@ -2853,29 +2825,28 @@ function build_xml_templates($strXML) {
foreach ($xml2['devices']["hostdev"] as $xmlhostdev) {
$xmlhostdevdoc = new SimpleXMLElement($xmlhostdev);
switch ($xmlhostdevdoc->attributes()->type) {
- case 'pci' :
- $pciaddr = $xmlhostdevdoc->source->address->attributes()->bus.":".$xmlhostdevdoc->source->address->attributes()->slot.".".$xmlhostdevdoc->source->address->attributes()->function;
- $pciaddr = str_replace("0x","",$pciaddr);
- $xml2["devices"][$arrValidPCIDevices[$pciaddr]["class"]][$pciaddr] = $xmlhostdev;
- break;
- case "usb":
- $usbaddr = $xmlhostdevdoc->source->vendor->attributes()->id.":".$xmlhostdevdoc->source->product->attributes()->id;
- $usbaddr = str_replace("0x","",$usbaddr);
- $xml2["devices"]["usb"][$usbaddr] = $xmlhostdev;
- $xml2["devices"]["allusb"] .= $xmlhostdev;
- break;
- }
+ case 'pci' :
+ $pciaddr = $xmlhostdevdoc->source->address->attributes()->bus.":".$xmlhostdevdoc->source->address->attributes()->slot.".".$xmlhostdevdoc->source->address->attributes()->function;
+ $pciaddr = str_replace("0x","",$pciaddr);
+ $xml2["devices"][$arrValidPCIDevices[$pciaddr]["class"]][$pciaddr] = $xmlhostdev;
+ break;
+ case "usb":
+ $usbaddr = $xmlhostdevdoc->source->vendor->attributes()->id.":".$xmlhostdevdoc->source->product->attributes()->id;
+ $usbaddr = str_replace("0x","",$usbaddr);
+ $xml2["devices"]["usb"][$usbaddr] = $xmlhostdev;
+ $xml2["devices"]["allusb"] .= $xmlhostdev;
+ break;
+ }
}
- foreach($xml2["devices"]["input"] as $input) $xml2["devices"]["allinput"] .= "$input\n";
-
+ foreach($xml2["devices"]["input"] as $input) $xml2["devices"]["allinput"] .= "$input\n";
return $xml2;
}
function qemu_log($vm,$m) {
- $m = print_r($m,true);
- $m = date("YmdHis")." ".$m;
- $m = str_replace("\n", " ", $m);
- $m = str_replace('"', "'", $m);
+ $m = print_r($m,true);
+ $m = date("YmdHis")." ".$m;
+ $m = str_replace("\n", " ", $m);
+ $m = str_replace('"', "'", $m);
file_put_contents("/var/log/libvirt/qemu/$vm.log",$m."\n",FILE_APPEND);
}
@@ -2897,7 +2868,7 @@ function get_vm_ip($dom) {
$myIP= $arraddr["addr"];
if (preg_match('/^f[c-f]/',$myIP)) continue; // omit ipv6 private addresses
break 2;
- }
+ }
}
}
}
@@ -2926,5 +2897,4 @@ function get_storage_fstype($storage="default") {
$fstype = trim(shell_exec(" stat -f -c '%T' $storage"));
return $fstype;
}
-
?>