" : "' style='display:none'>");
echo "";
echo "";
- echo "| ",_('Disk devices')," | ",_('Serial')," | ",_('Bus')," | ",_('Capacity')," | ",_('Allocation')," | Boot Order | ";
+ echo "| ",_('Disk devices/Volume')," | ",_('Serial')," | ",_('Bus')," | ",_('Capacity')," | ",_('Allocation')," | Boot Order | ";
echo "";
/* Display VM disks */
@@ -213,7 +213,9 @@ foreach ($vms as $vm) {
$boot= $arrDisk["boot order"];
$serial = $arrDisk["serial"];
if ($boot < 1) $boot = _('Not set');
- echo "| $disk | $serial | $bus | ";
+ $reallocation = trim(shell_exec("getfattr --absolute-names --only-values -n system.LOCATION ".escapeshellarg($disk)." 2>/dev/null"));
+ if (!empty($reallocation)) $reallocationstr = "($reallocation)"; else $reallocationstr = "";
+ echo " | $disk $reallocationstr | $serial | $bus | ";
if ($state == 'shutoff') {
echo "";
echo " | ";
From 97496beeb743189e4a0e710a26efcc8a5cba5864 Mon Sep 17 00:00:00 2001
From: SimonFair <39065407+SimonFair@users.noreply.github.com>
Date: Thu, 23 Nov 2023 19:41:02 +0000
Subject: [PATCH 4/8] Add override path support
Bug fix metadata on revert
---
.../include/libvirt_helpers.php | 35 +++++++++++++------
1 file changed, 25 insertions(+), 10 deletions(-)
diff --git a/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php b/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php
index e9dc13f1a..e4cb6011d 100644
--- a/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php
+++ b/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php
@@ -1611,6 +1611,8 @@ private static $encoding = 'UTF-8';
$state = $lv->domain_state_translate($dom['state']);
$vmxml = $lv->domain_get_xml($res) ;
file_put_contents("/tmp/cloningxml" ,$vmxml) ;
+ $storage = $lv->_get_single_xpath_result($vm, '//domain/metadata/*[local-name()=\'vmtemplate\']/@storage');
+ 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) ; }
# Wait for shutdown?
@@ -1666,7 +1668,7 @@ private static $encoding = 'UTF-8';
$file_clone[$diskid]["target"] = $config["disk"][$diskid]["new"] ;
}
- $clonedir = $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) ;
chown($clonedir, 'nobody');
@@ -1680,13 +1682,13 @@ private static $encoding = 'UTF-8';
$target = $disk['target'] ;
$source = $disk['source'] ;
if ($target == $source) { write("addLog\0".htmlspecialchars(_("New image file is same as old"))); return( false) ; }
- $sourcerealdisk = trim(shell_exec("getfattr --absolute-names --only-values -n system.LOCATION ".escapeshellarg($source)." 2>/dev/null"));
- $reptgt = str_replace('/mnt/user/', "/mnt/$sourcerealdisk/", $target);
- $repsrc = str_replace('/mnt/user/', "/mnt/$sourcerealdisk/", $source);
+ if ($storage == "default") $sourcerealdisk = trim(shell_exec("getfattr --absolute-names --only-values -n system.LOCATION ".escapeshellarg($source)." 2>/dev/null")); else $sourcerealdisk = $storage;
+ $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 '$source' '$target'" ;
+ $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) ; }
}
@@ -1841,6 +1843,8 @@ private static $encoding = 'UTF-8';
$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" ;
#Get disks for --diskspec
$disks =$lv->get_disk_stats($vm) ;
@@ -1852,16 +1856,23 @@ private static $encoding = 'UTF-8';
foreach($disks as $disk) {
$file = $disk["file"] ;
$pathinfo = pathinfo($file) ;
- $filenew = $pathinfo["dirname"].'/'.$pathinfo["filename"].'.'.$name.'qcow2' ;
+ $dirpath = $pathinfo["dirname"];
+ if ($storage == "default") {
+ $dirpath = $pathinfo["dirname"];
+ } 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' ;
$diskspec .= " --diskspec '".$disk["device"]."',snapshot=external,file='".$filenew."'" ;
$capacity = $capacity + $disk["capacity"] ;
}
- $dirpath = $pathinfo["dirname"] ;
+
#get memory
$mem = $lv->domain_get_memory_stats($vm) ;
$memory = $mem[6] ;
- if ($memorysnap = "yes") $memspec = ' --memspec "'.$pathinfo["dirname"].'/memory'.$name.'.mem",snapshot=external' ; else $memspec = "" ;
+ if ($memorysnap = "yes") $memspec = ' --memspec "'.$dirpath.'/memory'.$name.'.mem",snapshot=external' ; else $memspec = "" ;
$cmdstr = "virsh snapshot-create-as '$vm' --name '$name' $snapshotdesc --atomic" ;
@@ -1874,7 +1885,7 @@ private static $encoding = 'UTF-8';
}
#Check free space.
- $dirfree = disk_free_space($pathinfo["dirname"]) ;
+ $dirfree = disk_free_space($dirpath) ;
$capacity *= 1 ;
@@ -1883,7 +1894,7 @@ private static $encoding = 'UTF-8';
#Copy nvram
if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_create_snapshot($lv->domain_get_uuid($vm),$name) ;
- $xmlfile = $pathinfo["dirname"]."/".$name.".running" ;
+ $xmlfile = $dirpath."/".$name.".running" ;
file_put_contents("/tmp/xmltst", "$xmlfile" ) ;
if ($state == "running") exec("virsh dumpxml '$vm' > ".escapeshellarg($xmlfile),$outxml,$rtnxml) ;
@@ -1943,7 +1954,9 @@ private static $encoding = 'UTF-8';
}
}
$xml = custom::createXML('domain',$xmlobj)->saveXML();
+ if (!strpos($xml,'domain_define($xml);
+ file_put_contents("/tmp/xmlrevert", "$xml" ) ;
if ($new)
$arrResponse = ['success' => true] ; else
$arrResponse = ['error' => $lv->get_last_error()] ;
@@ -1978,6 +1991,8 @@ private static $encoding = 'UTF-8';
$xml = file_get_contents($xmlfile) ;
$xmlobj = custom::createArray('domain',$xml) ;
$xml = custom::createXML('domain',$xmlobj)->saveXML();
+ if (!strpos($xml,'domain_define($xml) ;
# Restore Memory.
From ec3b1e1f2beaa52453cb3d313899ca43b0da112b Mon Sep 17 00:00:00 2001
From: SimonFair <39065407+SimonFair@users.noreply.github.com>
Date: Thu, 23 Nov 2023 19:44:33 +0000
Subject: [PATCH 5/8] Update VMMachines.php
---
emhttp/plugins/dynamix.vm.manager/include/VMMachines.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/emhttp/plugins/dynamix.vm.manager/include/VMMachines.php b/emhttp/plugins/dynamix.vm.manager/include/VMMachines.php
index e50f8eadd..b29cf1cd5 100644
--- a/emhttp/plugins/dynamix.vm.manager/include/VMMachines.php
+++ b/emhttp/plugins/dynamix.vm.manager/include/VMMachines.php
@@ -185,7 +185,7 @@ foreach ($vms as $vm) {
$changemedia = "getisoimageboth(\"{$uuid}\",\"hda\",\"{$cdbus}\",\"{$cdfile}\",\"hdb\",\"{$cdbus2}\",\"{$cdfile2}\")";
$title = _('Select ISO image');
- $cdstr = $cdromcount." / 2 ";
+ $cdstr = $cdromcount." / 2 ";
echo "";
echo "$image$vm "._($status)." $snapshotstcount | ";
echo "$desc | ";
@@ -250,7 +250,7 @@ foreach ($vms as $vm) {
$title = _('Insert CD');
$changemedia = "changemedia(\"{$uuid}\",\"{$dev}\",\"{$bus}\",\"--select\")";
$disk = _("No CD image inserted into drive");
- echo " | $disk | | $bus | $capacity | $allocation | $boot | ";
+ echo "| $disk | | $bus | $capacity | $allocation | $boot | ";
}
}
echo "";
From 9c85e6132fa25a35c061f721d9f8b51ccbab4c12 Mon Sep 17 00:00:00 2001
From: SimonFair <39065407+SimonFair@users.noreply.github.com>
Date: Fri, 24 Nov 2023 14:23:18 +0000
Subject: [PATCH 6/8] Fix UUID change in xml view
---
.../plugins/dynamix.vm.manager/include/libvirt.php | 14 ++++++++++++++
.../dynamix.vm.manager/templates/Custom.form.php | 7 ++++++-
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/emhttp/plugins/dynamix.vm.manager/include/libvirt.php b/emhttp/plugins/dynamix.vm.manager/include/libvirt.php
index 5b3256811..847077d9b 100644
--- a/emhttp/plugins/dynamix.vm.manager/include/libvirt.php
+++ b/emhttp/plugins/dynamix.vm.manager/include/libvirt.php
@@ -1966,6 +1966,20 @@
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')) {
diff --git a/emhttp/plugins/dynamix.vm.manager/templates/Custom.form.php b/emhttp/plugins/dynamix.vm.manager/templates/Custom.form.php
index add684fe4..5e08ccc44 100644
--- a/emhttp/plugins/dynamix.vm.manager/templates/Custom.form.php
+++ b/emhttp/plugins/dynamix.vm.manager/templates/Custom.form.php
@@ -217,11 +217,15 @@
}
}
}
-
+ $newuuid = $uuid;
+ $olduuid = $uuid;
// construct updated config
if (isset($_POST['xmldesc'])) {
// XML view
$xml = $_POST['xmldesc'];
+ $arrExistingConfig = custom::createArray('domain',$xml);
+ $newuuid = $arrExistingConfig['uuid'] ;
+ $xml = str_replace($olduuid,$newuuid,$xml);
} else {
// form view
if ($error = create_vdisk($_POST) === false) {
@@ -240,6 +244,7 @@
$lv->nvram_backup($uuid);
$lv->domain_undefine($dom);
$lv->nvram_restore($uuid);
+ if ($newuuid != $olduuid) $lv->nvram_rename($olduuid,$newuuid);
$new = $lv->domain_define($xml);
if ($new) {
$lv->domain_set_autostart($new, $newAutoStart);
From 5f06519bdcf23d2d5d8992fb576ba75d25988a3d Mon Sep 17 00:00:00 2001
From: SimonFair <39065407+SimonFair@users.noreply.github.com>
Date: Fri, 24 Nov 2023 20:54:35 +0000
Subject: [PATCH 7/8] Update helptext and codetidy.
---
.../include/libvirt_helpers.php | 15 ++++++---------
.../dynamix.vm.manager/templates/Custom.form.php | 5 ++++-
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php b/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php
index e4cb6011d..8282bf84c 100644
--- a/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php
+++ b/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php
@@ -1610,7 +1610,7 @@ private static $encoding = 'UTF-8';
$dom = $lv->domain_get_info($res);
$state = $lv->domain_state_translate($dom['state']);
$vmxml = $lv->domain_get_xml($res) ;
- file_put_contents("/tmp/cloningxml" ,$vmxml) ;
+ file_put_contents("/tmp/cloningxml" ,$vmxml) ; ## Remove before stable.
$storage = $lv->_get_single_xpath_result($vm, '//domain/metadata/*[local-name()=\'vmtemplate\']/@storage');
if (empty($storage)) $storage = "default" ;
# if VM running shutdown. Record was running.
@@ -1697,7 +1697,7 @@ private static $encoding = 'UTF-8';
write("addLog\0".htmlspecialchars("Creating new XML $clone"));
$xml = $lv->config_to_xml($config, true) ;
- file_put_contents("/tmp/clonexml" ,$xml) ;
+ file_put_contents("/tmp/clonexml" ,$xml) ; ## Remove before stable.
$rtn = $lv->domain_define($xml) ;
return($rtn) ;
@@ -1867,7 +1867,7 @@ private static $encoding = 'UTF-8';
$diskspec .= " --diskspec '".$disk["device"]."',snapshot=external,file='".$filenew."'" ;
$capacity = $capacity + $disk["capacity"] ;
}
-
+
#get memory
$mem = $lv->domain_get_memory_stats($vm) ;
$memory = $mem[6] ;
@@ -1895,7 +1895,7 @@ private static $encoding = 'UTF-8';
if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_create_snapshot($lv->domain_get_uuid($vm),$name) ;
$xmlfile = $dirpath."/".$name.".running" ;
- file_put_contents("/tmp/xmltst", "$xmlfile" ) ;
+ file_put_contents("/tmp/xmltst", "$xmlfile" ) ;## Remove before stable.
if ($state == "running") exec("virsh dumpxml '$vm' > ".escapeshellarg($xmlfile),$outxml,$rtnxml) ;
$output= [] ;
@@ -1956,7 +1956,7 @@ private static $encoding = 'UTF-8';
$xml = custom::createXML('domain',$xmlobj)->saveXML();
if (!strpos($xml,'domain_define($xml);
- file_put_contents("/tmp/xmlrevert", "$xml" ) ;
+ file_put_contents("/tmp/xmlrevert", "$xml" ) ;## Remove before stable.
if ($new)
$arrResponse = ['success' => true] ; else
$arrResponse = ['error' => $lv->get_last_error()] ;
@@ -1992,14 +1992,13 @@ private static $encoding = 'UTF-8';
$xmlobj = custom::createArray('domain',$xml) ;
$xml = custom::createXML('domain',$xmlobj)->saveXML();
if (!strpos($xml,'domain_define($xml) ;
# Restore Memory.
$makerun = true ;
if ($makerun == true) exec("virsh restore ".escapeshellarg($memoryfile)) ;
- #exec("virsh restore $memoryfile") ;
}
#Delete Metadata only.
if ($actionmeta == "yes") {
@@ -2042,8 +2041,6 @@ private static $encoding = 'UTF-8';
$reversed = array_reverse($output) ;
$snaps[$vm][$rev] = $reversed ;
$pathinfo = pathinfo($file) ;
- #$filenew = $pathinfo["dirname"].'/'.$pathinfo["filename"].'.'.$name.'qcow2' ;
- #$diskspec .= " --diskspec ".$disk["device"].",snapshot=external,file=".$filenew ;
$capacity = $capacity + $disk["capacity"] ;
}
diff --git a/emhttp/plugins/dynamix.vm.manager/templates/Custom.form.php b/emhttp/plugins/dynamix.vm.manager/templates/Custom.form.php
index 5e08ccc44..7f5be035b 100644
--- a/emhttp/plugins/dynamix.vm.manager/templates/Custom.form.php
+++ b/emhttp/plugins/dynamix.vm.manager/templates/Custom.form.php
@@ -379,7 +379,10 @@
- Specify the overide storage pool for VM.
+ Specify the overide storage pool for VM. This option allows you to specify the physical pool/disk used to store the disk images and snapshot data.
+ Default will follow standard processing and store images in the default location for the share defined in the settings.
+ A pool/disk(Volume) will be the location for images if the default is overridden.
+
From c636ab6029e18fd51ddd5106e5198c5c8f1d2479 Mon Sep 17 00:00:00 2001
From: SimonFair <39065407+SimonFair@users.noreply.github.com>
Date: Sat, 25 Nov 2023 12:27:37 +0000
Subject: [PATCH 8/8] Self test fix for NVMEs
---
emhttp/plugins/dynamix/include/SmartInfo.php | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/emhttp/plugins/dynamix/include/SmartInfo.php b/emhttp/plugins/dynamix/include/SmartInfo.php
index 995e27a38..280604bb8 100644
--- a/emhttp/plugins/dynamix/include/SmartInfo.php
+++ b/emhttp/plugins/dynamix/include/SmartInfo.php
@@ -229,10 +229,10 @@ case "stop":
exec("smartctl -X $type ".escapeshellarg("/dev/$port"));
break;
case "update":
- if ($disk["transport"] == "scsi") {
+ if ($disk["transport"] == "scsi" || $disk["transport"] == "nvme") {
$progress = exec("smartctl -n standby -l selftest $type ".escapeshellarg("/dev/$port")."|grep -Pom1 '\d+%'");
if ($progress) {
- echo " "._('self-test in progress').", ".(100-substr($progress,0,-1))."% "._('complete')."";
+ if ($disk["transport"] == "nvme") echo " "._('self-test in progress').", ".(substr($progress,0,-1))."% "._('complete').""; else echo " "._('self-test in progress').", ".(100-substr($progress,0,-1))."% "._('complete')."";
break;
}
} else {
@@ -243,7 +243,8 @@ case "update":
}
}
if ($disk["transport"] == "scsi") $result = trim(exec("smartctl -n standby -l selftest $type ".escapeshellarg("/dev/$port")."|grep -m1 '^# 1'|cut -c24-50"));
- else $result = trim(exec("smartctl -n standby -l selftest $type ".escapeshellarg("/dev/$port")."|grep -m1 '^# 1'|cut -c26-55"));
+ else if ($disk["transport"] == "nvme") $result = trim(exec("smartctl -n standby -l selftest $type ".escapeshellarg("/dev/$port")."|grep -m1 '^ 0'|cut -c24-50"));
+ else $result = trim(exec("smartctl -n standby -l selftest $type ".escapeshellarg("/dev/$port")."|grep -m1 '^# 1'|cut -c26-55"));
if (!$result) {
$spundown = $disk['spundown'] ? "Device spundown, spinup to get information" : "No self-tests logged on this disk" ;
echo ""._($spundown)."";
|