mirror of
https://github.com/unraid/webgui.git
synced 2026-01-06 09:39:58 -06:00
Updates to ZFS Snaps and fix for Libvirt 9.8.0+ issue
This commit is contained in:
@@ -243,9 +243,9 @@ function selectsnapshot(uuid, name ,snaps, opt, getlist,state ,fstype){
|
||||
box.html($("#templatesnapshot"+opt).html());
|
||||
const capopt = opt.charAt(0).toUpperCase() + opt.slice(1);
|
||||
var optiontext = capopt + " _(Snapshot)_";
|
||||
//var fstype = "ZFS";
|
||||
box.find('#VMName').html(name);
|
||||
box.find('#fstype').html(fstype);
|
||||
if (fstype == "QEMU") box.find('#fstypeline').prop('hidden',true);
|
||||
box.find('#targetsnap').val(snaps);
|
||||
box.find('#targetsnapl').html(snaps);
|
||||
if (getlist) {
|
||||
@@ -496,7 +496,7 @@ $(function() {
|
||||
<tr><td>_(VM Name)_:</td><td><label id="VMName"></label></td></tr>
|
||||
<tr><td>_(Snapshot Name)_:</td><td><input type="text" id="targetsnap" autocomplete="off" spellcheck="false" value="--generate" onclick="this.select()">_(Check free space)_: <input type="checkbox" id="targetsnapfspc" checked></td></tr>
|
||||
<tr><td>_(Description )_:</td><td><input type="text" id="targetsnapdesc" autocomplete="off" spellcheck="false" value="" onclick="this.select()"></td></tr>
|
||||
<tr><td>_(FS Native Snapshot )_:</td><td><label id="fstype"></label><input type="checkbox" id="targetsnapfstype" checked>_(Unchecked will use QEMU External Snapshot)_</td></tr>
|
||||
<tr id="fstypeline"><td>_(FS Native Snapshot )_:</td><td><label id="fstype"></label><input type="checkbox" id="targetsnapfstype" checked>_(Unchecked will use QEMU External Snapshot)_</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -66,8 +66,10 @@ foreach ($vms as $vm) {
|
||||
$log = (is_file("/var/log/libvirt/qemu/$vm.log") ? "libvirt/qemu/$vm.log" : '');
|
||||
$disks = '-';
|
||||
$diskdesc = '';
|
||||
$fstype ="QEMU";
|
||||
if (($diskcnt = $lv->get_disk_count($res)) > 0) {
|
||||
$disks = $diskcnt.' / '.$lv->get_disk_capacity($res);
|
||||
$fstype = $lv->get_disk_fstype($res);
|
||||
$diskdesc = 'Current physical size: '.$lv->get_disk_capacity($res, true)."\nDefault snapshot type:$fstype";
|
||||
}
|
||||
$arrValidDiskBuses = getValidDiskBuses();
|
||||
@@ -108,8 +110,6 @@ foreach ($vms as $vm) {
|
||||
}
|
||||
unset($dom);
|
||||
if (!isset($domain_cfg["CONSOLE"])) $vmrcconsole = "web" ; else $vmrcconsole = $domain_cfg["CONSOLE"] ;
|
||||
if ($diskcnt > 0) $fstype = $lv->get_disk_fstype($res); else $fstype="QEMU";
|
||||
#$fstype = "ZFS";
|
||||
$menu = sprintf("onclick=\"addVMContext('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')\"", addslashes($vm),addslashes($uuid),addslashes($template),$state,addslashes($vmrcurl),strtoupper($vmrcprotocol),addslashes($log),addslashes($fstype), $vmrcconsole,$vmpreview);
|
||||
$kvm[] = "kvm.push({id:'$uuid',state:'$state'});";
|
||||
switch ($state) {
|
||||
|
||||
@@ -1726,7 +1726,7 @@ private static $encoding = 'UTF-8';
|
||||
|
||||
function getvmsnapshots($vm) {
|
||||
$snaps=array() ;
|
||||
$dbpath = "/etc/libvirt/qemu/snapshot/$vm" ;
|
||||
$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') ;
|
||||
@@ -1735,7 +1735,7 @@ private static $encoding = 'UTF-8';
|
||||
|
||||
function write_snapshots_database($vm,$name,$state,$desc,$method="QEMU") {
|
||||
global $lv ;
|
||||
$dbpath = "/etc/libvirt/qemu/snapshot/$vm" ;
|
||||
$dbpath = "/etc/libvirt/qemu/snapshotdb/$vm" ;
|
||||
if (!is_dir($dbpath)) mkdir($dbpath) ;
|
||||
$noxml = "";
|
||||
$snaps_json = file_get_contents($dbpath."/snapshots.db") ;
|
||||
@@ -1747,12 +1747,13 @@ private static $encoding = 'UTF-8';
|
||||
# Create Snapshot info
|
||||
$vmsnap = $name;
|
||||
$snaps[$vmsnap]["name"]= $name;
|
||||
$snaps[$vmsnap]["parent"]= "Base" ;
|
||||
$snaps[$vmsnap]["parent"]= "None" ;
|
||||
$snaps[$vmsnap]["state"]= "shutoff";
|
||||
$snaps[$vmsnap]["desc"]= $desc;
|
||||
$snaps[$vmsnap]["memory"]= ['@attributes' => ['snapshot' => 'no']];
|
||||
$snaps[$vmsnap]["creationtime"]= date("U");
|
||||
$snaps[$vmsnap]["method"]= $method;
|
||||
$snaps[$vmsnap]['xml'] = $lv->domain_get_xml($vm);
|
||||
$noxml = "noxml";
|
||||
}
|
||||
} else {
|
||||
@@ -1773,7 +1774,7 @@ private static $encoding = 'UTF-8';
|
||||
$disks =$lv->get_disk_stats($vm) ;
|
||||
foreach($disks as $disk) {
|
||||
$file = $disk["file"] ;
|
||||
if ($disk['device'] == "hdc" ) $primarypath = dirname($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) {
|
||||
@@ -1803,7 +1804,7 @@ private static $encoding = 'UTF-8';
|
||||
|
||||
function refresh_snapshots_database($vm) {
|
||||
global $lv ;
|
||||
$dbpath = "/etc/libvirt/qemu/snapshot/$vm" ;
|
||||
$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) ;
|
||||
@@ -1839,7 +1840,6 @@ private static $encoding = 'UTF-8';
|
||||
# Get uuid
|
||||
$vmuuid = $lv->domain_get_uuid($vm) ;
|
||||
#Get list of files
|
||||
#$filepath = "/etc/libvirt/qemu/nvram/'.$uuid*" ; #$snapshotname"
|
||||
$filepath = "/etc/libvirt/qemu/nvram/$vmuuid*" ; #$snapshotname"
|
||||
$nvram_files=glob($filepath) ;
|
||||
foreach($nvram_files as $key => $nvram_file) {
|
||||
@@ -1859,7 +1859,7 @@ private static $encoding = 'UTF-8';
|
||||
|
||||
function delete_snapshots_database($vm,$name) {
|
||||
global $lv ;
|
||||
$dbpath = "/etc/libvirt/qemu/snapshot/$vm" ;
|
||||
$dbpath = "/etc/libvirt/qemu/snapshotdb/$vm" ;
|
||||
$snaps_json = file_get_contents($dbpath."/snapshots.db") ;
|
||||
$snaps = json_decode($snaps_json,true) ;
|
||||
unset($snaps[$name]) ;
|
||||
@@ -1938,14 +1938,10 @@ private static $encoding = 'UTF-8';
|
||||
if ($state == "running") exec("virsh dumpxml '$vm' > ".escapeshellarg($xmlfile),$outxml,$rtnxml) ;
|
||||
|
||||
$output= [] ;
|
||||
#$test = false ;
|
||||
#if ($test) exec($cmdstr." --print-xml 2>&1",$output,$return) ; else exec($cmdstr." 2>&1",$output,$return) ;
|
||||
|
||||
switch ($method) {
|
||||
case "ZFS":
|
||||
# Create ZFS Snapshot
|
||||
#$zfsdataset = "vmpoolzfs/domains3/Arch3";
|
||||
#stat -f -c '%T' /mnt/vmpoolzfs/domains2/Arch3
|
||||
if ($state == "running") exec($cmdstr." 2>&1",$output,$return);
|
||||
$zfsdataset = trim(shell_exec("zfs list -H -o name -r $dirpath")) ;
|
||||
$fssnapcmd = " zfs snapshot $zfsdataset@$name";
|
||||
@@ -1973,115 +1969,6 @@ private static $encoding = 'UTF-8';
|
||||
|
||||
}
|
||||
|
||||
function vm_revert_old($vm, $snap="--current",$action="no",$actionmeta = 'yes') {
|
||||
global $lv ;
|
||||
$snapslist= getvmsnapshots($vm) ;
|
||||
$disks =$lv->get_disk_stats($vm) ;
|
||||
|
||||
switch ($snapslist[$snap]['state']) {
|
||||
case "shutoff":
|
||||
case "running":
|
||||
#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) ;
|
||||
# Wait for shutdown?
|
||||
# GetXML
|
||||
$strXML= $lv->domain_get_xml($res) ;
|
||||
$xmlobj = custom::createArray('domain',$strXML) ;
|
||||
|
||||
# Process disks and update path.
|
||||
$disks=($snapslist[$snap]['disks']) ;
|
||||
foreach ($disks as $disk) {
|
||||
$diskname = $disk["@attributes"]["name"] ;
|
||||
if ($diskname == "hda" || $diskname == "hdb") continue ;
|
||||
$path = $disk["source"]["@attributes"]["file"] ;
|
||||
if ($diskname == "hdc") {
|
||||
$primarypathinfo = pathinfo($path) ;
|
||||
$primarypath = $primarypathinfo['dirname'] ;
|
||||
}
|
||||
$item = array_search($path,$snapslist[$snap]['backing'][$diskname]) ;
|
||||
$newpath = $snapslist[$snap]['backing'][$diskname][$item + 1];
|
||||
$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"] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
$xml = custom::createXML('domain',$xmlobj)->saveXML();
|
||||
if (!strpos($xml,'<vmtemplate xmlns="unraid"')) $xml=str_replace('<vmtemplate','<vmtemplate xmlns="unraid"',$xml);
|
||||
$new = $lv->domain_define($xml);
|
||||
file_put_contents("/tmp/xmlrevert", "$xml" ) ;## Remove before stable.
|
||||
if ($new)
|
||||
$arrResponse = ['success' => true] ; else
|
||||
$arrResponse = ['error' => $lv->get_last_error()] ;
|
||||
|
||||
# remove snapshot meta data and images for all snpahots.
|
||||
|
||||
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") unlink("$path") ;
|
||||
file_put_contents("/tmp/rmvsnaps",$path,FILE_APPEND);
|
||||
$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] ;
|
||||
file_put_contents("/tmp/rmvsnaps",$newpath,FILE_APPEND);
|
||||
if (is_file($newpath) && $action == "yes") unlink("$newpath") ;
|
||||
$item++ ;
|
||||
}
|
||||
}
|
||||
|
||||
uasort($snapslist,'compare_creationtimelt') ;
|
||||
foreach($snapslist as $s) {
|
||||
$name = $s['name'] ;
|
||||
|
||||
$xmlfile = $primarypath."/$name.running" ;
|
||||
$memoryfile = $primarypath."/memory$name.mem" ;
|
||||
|
||||
if ($snapslist[$snap]['state'] == "running") {
|
||||
# Set XML to saved XML
|
||||
$xml = file_get_contents($xmlfile) ;
|
||||
$xmlobj = custom::createArray('domain',$xml) ;
|
||||
$xml = custom::createXML('domain',$xmlobj)->saveXML();
|
||||
if (!strpos($xml,'<vmtemplate xmlns="unraid"')) $xml=str_replace('<vmtemplate','<vmtemplate xmlns="unraid"',$xml);
|
||||
file_put_contents("/tmp/xmlrevert2", "$xml" ) ;## Remove before stable.
|
||||
$rtn = $lv->domain_define($xml) ;
|
||||
|
||||
# Restore Memory.
|
||||
|
||||
$makerun = true ;
|
||||
if ($makerun == true) exec("virsh restore ".escapeshellarg($memoryfile)) ;
|
||||
}
|
||||
#Delete Metadata only.
|
||||
if ($actionmeta == "yes") {
|
||||
$ret = delete_snapshots_database("$vm","$name") ;
|
||||
}
|
||||
if (is_file($memoryfile) && $action == "yes") unlink($memoryfile) ;
|
||||
if (is_file($xmlfile) && $action == "yes") unlink($xmlfile) ;
|
||||
if ($s['name'] == $snap) break ;
|
||||
}
|
||||
#if VM was started restart.
|
||||
if ($state == 'running' && $snapslist[$snap]['state'] != "running") {
|
||||
$arrResponse = $lv->domain_start($vm) ;
|
||||
}
|
||||
|
||||
if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_revert_snapshot($lv->domain_get_uuid($vm),$name) ;
|
||||
break ;
|
||||
|
||||
}
|
||||
$arrResponse = ['success' => true] ;
|
||||
return($arrResponse) ;
|
||||
}
|
||||
|
||||
function vm_revert($vm, $snap="--current",$action="no",$actionmeta = 'yes',$dryrun = false) {
|
||||
global $lv ;
|
||||
$snapslist= getvmsnapshots($vm) ;
|
||||
@@ -2127,7 +2014,7 @@ private static $encoding = 'UTF-8';
|
||||
|
||||
# If Snapstate not running create new XML.
|
||||
if ($snapstate != "running") {
|
||||
$xml = custom::createXML('domain',$xmlobj)->saveXML();
|
||||
if ($method == "ZFS") $xml = $snapslist[$snap]['xml']; else $xml = custom::createXML('domain',$xmlobj)->saveXML();
|
||||
if (!strpos($xml,'<vmtemplate xmlns="unraid"')) $xml=str_replace('<vmtemplate','<vmtemplate xmlns="unraid"',$xml);
|
||||
if (!$dryrun) $new = $lv->domain_define($xml);
|
||||
file_put_contents("/tmp/xmlrevert", "$xml" ) ;## Remove before stable.
|
||||
@@ -2155,14 +2042,13 @@ private static $encoding = 'UTF-8';
|
||||
}
|
||||
|
||||
# Remove later snapshots
|
||||
uasort($snapslist,'compare_creationtimelt') ;
|
||||
#var_dump($snapslist);
|
||||
if (!is_null($snapslist)) uasort($snapslist,'compare_creationtimelt') ;
|
||||
|
||||
foreach($snapslist as $s) {
|
||||
if ($s['name'] == $snap) break ;
|
||||
$name = $s['name'] ;
|
||||
$oldmethod = $s['method'];
|
||||
if (!$dryrun) echo "$name $oldmethod\n";
|
||||
if ($dryrun) echo "$name $oldmethod\n";
|
||||
if (!isset($primarypath)) $primarypath = $s['primarypath'];
|
||||
$xmlfile = $primarypath."/$name.running" ;
|
||||
$memoryfile = $primarypath."/memory$name.mem" ;
|
||||
@@ -2177,10 +2063,7 @@ private static $encoding = 'UTF-8';
|
||||
}
|
||||
}
|
||||
if ($oldmethod == "ZFS") {
|
||||
# Create ZFS Snapshot
|
||||
#$zfsdataset = "vmpoolzfs/domains3/Arch3";
|
||||
#stat -f -c '%T' /mnt/vmpoolzfs/domains2/Arch3
|
||||
#if ($state == "running") exec($cmdstr." 2>&1",$output,$return);
|
||||
# Rollback ZFS Snapshot
|
||||
$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";
|
||||
@@ -2194,13 +2077,17 @@ private static $encoding = 'UTF-8';
|
||||
# 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 ($actionmeta == "yes") {
|
||||
if (!$dryrun) $ret = delete_snapshots_database("$vm","$name") ; echo "Old Delete snapshot meta\n";
|
||||
if (!$dryrun) $ret = delete_snapshots_database("$vm","$name"); else echo "Old Delete snapshot meta\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ($method == "ZFS") {
|
||||
if (!isset($primarypath)) $primarypath = $snapslist[$snap]['primarypath'];
|
||||
|
||||
$zfsdataset = trim(shell_exec("zfs list -H -o name -r ".transpose_user_path($primarypath))) ;
|
||||
if ($dryrun) {
|
||||
var_dump(transpose_user_path($primarypath));
|
||||
}
|
||||
$fssnapcmd = " zfs rollback $zfsdataset@$snap";
|
||||
if (!$dryrun) shell_exec($fssnapcmd); else echo "$fssnapcmd\n";
|
||||
$fssnapcmd = " zfs destroy $zfsdataset@$snap";
|
||||
@@ -2220,7 +2107,9 @@ private static $encoding = 'UTF-8';
|
||||
|
||||
|
||||
# Restore Memory.
|
||||
if (!$dryrun) exec("virsh restore ".escapeshellarg($memoryfile)) ;
|
||||
if (!$dryrun) $cmdrtn = exec("virsh restore --running ".escapeshellarg($memoryfile)) ;
|
||||
if (!$dryrun && !$cmdrtn) unlink($xmlfile);
|
||||
if (!$dryrun && !$cmdrtn) unlink($memoryfile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -685,6 +685,7 @@ function hideShow() {
|
||||
<tr><td>_(VM Name)_:</td><td><label id="VMName"></label></td></tr>
|
||||
<tr><td>_(Snapshot Name)_:</td><td><input type="text" id="targetsnap" autocomplete="off" spellcheck="false" value="--generate" onclick="this.select()">_(Check free space)_:<input type="checkbox" id="targetsnapfspc" checked></td></tr>
|
||||
<tr><td>_(Description)_:</td><td><input type="text" id="targetsnapdesc" autocomplete="off" spellcheck="false" value="" onclick="this.select()"></td></tr>
|
||||
<tr id="fstypeline"><td>_(FS Native Snapshot )_:</td><td><label id="fstype"></label><input type="checkbox" id="targetsnapfstype" checked>_(Unchecked will use QEMU External Snapshot)_</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -1379,12 +1380,14 @@ function VMClone(uuid, name){
|
||||
});
|
||||
dialogStyle();
|
||||
}
|
||||
function selectsnapshot(uuid, name ,snaps, opt, getlist){
|
||||
function selectsnapshot(uuid, name ,snaps, opt, getlist, status,fstype){
|
||||
box = $("#iframe-popup");
|
||||
box.html($("#templatesnapshot"+opt).html());
|
||||
const capopt = opt.charAt(0).toUpperCase() + opt.slice(1);
|
||||
var optiontext = capopt + " _(Snapshot)_";
|
||||
box.find('#VMName').html(name);
|
||||
box.find('#fstype').html(fstype);
|
||||
if (fstype == "QEMU") box.find('#fstypeline').prop('hidden',true);
|
||||
box.find('#targetsnap').val(snaps);
|
||||
box.find('#targetsnapl').html(snaps);
|
||||
if (getlist) {
|
||||
@@ -1419,8 +1422,10 @@ function selectsnapshot(uuid, name ,snaps, opt, getlist){
|
||||
if (opt == "create") {
|
||||
free = box.find('#targetsnapfspc').prop('checked') ? 'yes' : 'no';
|
||||
desc = box.find("#targetsnapdesc").prop('value');
|
||||
fstypeuse = box.find('#targetsnapfstype').prop('checked') ? 'yes' : 'no';
|
||||
if (fstypeuse == "no") fstype ="QEMU";
|
||||
}
|
||||
ajaxVMDispatch({action:"snap-" + opt +'-external', uuid:uuid, snapshotname:target, remove:remove, free:free, desc:desc}, "loadlist");
|
||||
ajaxVMDispatch({action:"snap-" + opt +'-external', uuid:uuid, snapshotname:target, remove:remove, free:free, desc:desc, fstype:fstype}, "loadlist");
|
||||
box.dialog('close');
|
||||
},
|
||||
"_(Cancel)_": function(){
|
||||
|
||||
@@ -83,6 +83,8 @@ if ($_POST['vms']) {
|
||||
$uuid = libvirt_domain_get_uuid_string($res);
|
||||
$dom = $lv->domain_get_info($res);
|
||||
$id = $lv->domain_get_id($res);
|
||||
$fstype ="QEMU";
|
||||
if (($diskcnt = $lv->get_disk_count($res)) > 0) $fstype = $lv->get_disk_fstype($res);
|
||||
$state = $lv->domain_state_translate($dom['state']);
|
||||
$vmrcport = $lv->domain_get_vnc_port($res);
|
||||
$autoport = $lv->domain_get_vmrc_autoport($res);
|
||||
@@ -114,7 +116,7 @@ if ($_POST['vms']) {
|
||||
if (empty($template)) $template = 'Custom';
|
||||
$log = (is_file("/var/log/libvirt/qemu/$vm.log") ? "libvirt/qemu/$vm.log" : '');
|
||||
if (!isset($domain_cfg["CONSOLE"])) $vmrcconsole = "web" ; else $vmrcconsole = $domain_cfg["CONSOLE"] ;
|
||||
$menu = sprintf("onclick=\"addVMContext('%s','%s','%s','%s','%s','%s','%s','%s')\"", addslashes($vm), addslashes($uuid), addslashes($template), $state, addslashes($vmrcurl), strtoupper($vmrcprotocol), addslashes($log), $vmrcconsole);
|
||||
$menu = sprintf("onclick=\"addVMContext('%s','%s','%s','%s','%s','%s','%s','%s','%s')\"", addslashes($vm), addslashes($uuid), addslashes($template), $state, addslashes($vmrcurl), strtoupper($vmrcprotocol), addslashes($log),addslashes($fstype), $vmrcconsole);
|
||||
$icon = $lv->domain_get_icon_url($res);
|
||||
switch ($state) {
|
||||
case 'running':
|
||||
|
||||
Reference in New Issue
Block a user