Merge pull request #1750 from SimonFair/WebUI

Create WebUI option in VM Template.
This commit is contained in:
tom mortensen
2024-06-03 13:13:34 -07:00
committed by GitHub
9 changed files with 133 additions and 7 deletions
@@ -183,6 +183,14 @@ _(Console Options)_:
:vms_console_help:
_(Show RDP menu option)_:
: <select id="vmsrdpopt" name="RDPOPT">
<?=mk_option($domain_cfg['RDPOPT'], 'no', _('Dont show RDP option'))?>
<?=mk_option($domain_cfg['RDPOPT'], 'yes', _('Show RDP option'))?>
</select>
:vms_rdpopt_help:
_(Show VM Usage)_:
: <select id="vmusage" name="USAGE">
<?=mk_option($domain_cfg['USAGE'], 'N', _('Disabled'))?>
@@ -72,6 +72,7 @@ foreach ($vms as $vm) {
$diskdesc = 'Current physical size: '.$lv->get_disk_capacity($res, true)."\nDefault snapshot type: $fstype";
}
$arrValidDiskBuses = getValidDiskBuses();
$WebUI = html_entity_decode($arrConfig['template']['webui']);
$vmrcport = $lv->domain_get_vnc_port($res);
$autoport = $lv->domain_get_vmrc_autoport($res);
$vmrcurl = '';
@@ -109,7 +110,8 @@ foreach ($vms as $vm) {
}
unset($dom);
if (!isset($domain_cfg["CONSOLE"])) $vmrcconsole = "web" ; else $vmrcconsole = $domain_cfg["CONSOLE"] ;
$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,false);
if (!isset($domain_cfg["RDPOPT"])) $vmrcconsole .= ";no" ; else $vmrcconsole .= ";".$domain_cfg["RDPOPT"] ;
$menu = sprintf("onclick=\"addVMContext('%s','%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,false,addslashes(str_replace('"',"'",$WebUI)));
$kvm[] = "kvm.push({id:'$uuid',state:'$state'});";
switch ($state) {
case 'running':
@@ -128,6 +128,20 @@ case 'domain-start-consoleRV':
$arrResponse['vvfile'] = $vvfile;
break;
case 'domain-consoleRDP':
requireLibvirt();
$dom = $lv->get_domain_by_name($domName);
$rdpvarray = array() ;
$myIP=get_vm_ip($dom);
if ($myIP == NULL) {$arrResponse['error'] = "No IP, guest agent not installed?"; break; }
$rdparray[] = "full address:s: $myIP\n";
#$rdparray[] = "administrative session:1\n";
if (!is_dir("/mnt/user/system/remoteviewer")) mkdir("/mnt/user/system/remoteviewer") ;
$rdpfile = "/mnt/user/system/remoteviewer/rv"._var($_SERVER,'HTTP_HOST').".$port.rdp" ;
file_put_contents($rdpfile,$rdparray) ;
$arrResponse['vvfile'] = $rdpfile;
break;
case 'domain-consoleRV':
requireLibvirt();
$dom = $lv->get_domain_by_name($domName);
@@ -146,6 +160,23 @@ case 'domain-consoleRV':
file_put_contents($vvfile,$vvarray) ;
$arrResponse['vvfile'] = $vvfile;
break;
case 'domain-openWebUI':
requireLibvirt();
$dom = $lv->get_domain_by_name($domName);
$WebUI = unscript(_var($_REQUEST,'vmrcurl'));
$myIP = get_vm_ip($dom);
if (strpos($WebUI,"[IP]") && $myIP == NULL) $arrResponse['error'] = "No IP, guest agent not installed?";
$WebUI = preg_replace("%\[IP\]%", $myIP, $WebUI);
$vmnamehypen = str_replace(" ","-",$domName);
$WebUI = preg_replace("%\[VMNAME\]%", $vmnamehypen, $WebUI);
if (preg_match("%\[PORT:(\d+)\]%", $WebUI, $matches)) {
$ConfigPort = $matches[1] ?? '';
$WebUI = preg_replace("%\[PORT:\d+\]%", $ConfigPort, $WebUI);
}
$arrResponse['vmrcurl'] = $WebUI;
break;
case 'domain-pause':
requireLibvirt();
@@ -2765,4 +2765,30 @@ function qemu_log($vm,$m) {
file_put_contents("/var/log/libvirt/qemu/$vm.log",$m."\n",FILE_APPEND);
}
function get_vm_ip($dom) {
global $lv;
$myIP=null;
$gastate = getgastate($dom);
if ($gastate == "connected") {
$ip = $lv->domain_interface_addresses($dom, 1);
$gastate = getgastate($dom);
if ($gastate == "connected") {
$ip = $lv->domain_interface_addresses($dom, 1);
if ($ip != false) {
foreach ($ip as $arrIP) {
$ipname = $arrIP["name"];
if (preg_match('/^(lo|Loopback)/',$ipname)) continue; // omit loopback interface
$iplist = $arrIP["addrs"];
foreach ($iplist as $arraddr) {
$myIP= $arraddr["addr"];
if (preg_match('/^f[c-f]/',$myIP)) continue; // omit ipv6 private addresses
break 2;
}
}
}
}
}
return $myIP;
}
?>
@@ -2,6 +2,10 @@ function displayconsole(url) {
window.open(url, '_blank', 'scrollbars=yes,resizable=yes');
}
function displayWebUI(url) {
window.open(url, '', 'scrollbars=yes,resizable=yes');
}
function downloadFile(source) {
var a = document.createElement('a');
a.setAttribute('href',source);
@@ -62,10 +66,30 @@ function ajaxVMDispatchconsoleRV(params, spin){
}
},'json');
}
function addVMContext(name, uuid, template, state, vmrcurl, vmrcprotocol, log, fstype="QEMU",console="web",usage=false){
function ajaxVMDispatchWebUI(params, spin){
if (spin) $('#vm-'+params['uuid']).parent().find('i').removeClass('fa-play fa-square fa-pause').addClass('fa-refresh fa-spin');
$.post("/plugins/dynamix.vm.manager/include/VMajax.php", params, function(data) {
if (data.error) {
swal({
title:_("Execution error"), html:true,
text:data.error, type:"error",
confirmButtonText:_('Ok')
},function(){
if (spin) setTimeout(spin+'()',500); else location=window.location.href;
});
} else {
if (spin) setTimeout(spin+'()',500); else location=window.location.href;
setTimeout('displayWebUI("'+data.vmrcurl+'")',500) ;
}
},'json');
}
function addVMContext(name, uuid, template, state, vmrcurl, vmrcprotocol, log, fstype="QEMU",consolein="web;no",usage=false,webui=""){
var opts = [];
var path = location.pathname;
var x = path.indexOf("?");
var consolesplit = consolein.split(";");
var console = consolesplit[0];
var rdpopt = consolesplit[1];
if (x!=-1) path = path.substring(0,x);
if (vmrcurl !== "" && state == "running") {
if (console == "web" || console == "both") {
@@ -81,7 +105,18 @@ function addVMContext(name, uuid, template, state, vmrcurl, vmrcprotocol, log, f
ajaxVMDispatchconsoleRV({action:"domain-consoleRV", uuid:uuid, vmrcurl:vmrcurl}, "loadlist") ;
}});
}
if (webui != "") {
opts.push({text:_("Open WebUI") , icon:"fa-globe", action:function(e) {
e.preventDefault();
ajaxVMDispatchWebUI({action:"domain-openWebUI", uuid:uuid, vmrcurl:webui}, "loadlist") ;
}});
}
if (rdpopt == "yes") {
opts.push({text:_("VM Remote Desktop Protocol(RDP)"), icon:"fa-desktop", action:function(e) {
e.preventDefault();
ajaxVMDispatchconsoleRV({action:"domain-consoleRDP", uuid:uuid, vmrcurl:vmrcurl}, "loadlist") ;
}});
}
opts.push({divider:true});
}
context.settings({right:false,above:false});
@@ -357,6 +357,22 @@
</blockquote>
</div>
<table>
<tr class="advanced">
<td>_(WebUI)_:</td>
<td><input type="url" name="template[webui]" title="_(Web UI to start)_" placeholder="_(Web UI to start from menu)_ (_(optional)_)" value="<?=htmlspecialchars($arrConfig['template']['webui'])?>" /></td>
</tr>
</table>
<div class="advanced">
<blockquote class="inline_help">
<p>Specify a URL that for menu to start. Substution variables are
<br>[IP] IP address, this will take the first IP on the VM. Guest Agent must be installed for this to work.
<br>[PORT:XX] Port Number in XX.
<br>[VMNAME] VM Name will have spaces replaced with -
</p>
</blockquote>
</div>
<table>
<tr>
<?if (!$boolNew) $disablestorage = " disabled "; else $disablestorage = "";?>
@@ -119,7 +119,9 @@ 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','%s')\"", addslashes($vm), addslashes($uuid), addslashes($template), $state, addslashes($vmrcurl), strtoupper($vmrcprotocol), addslashes($log),addslashes($fstype), $vmrcconsole);
if (!isset($domain_cfg["RDPOPT"])) $vmrcconsole .= ";no" ; else $vmrcconsole .= ";".$domain_cfg["RDPOPT"] ;
$WebUI = html_entity_decode($arrConfig["template"]["webui"]);
$menu = sprintf("onclick=\"addVMContext('%s','%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,false,addslashes(str_replace('"',"'",$WebUI)));
$icon = $lv->domain_get_icon_url($res);
switch ($state) {
case 'running':
@@ -144,7 +146,7 @@ if ($_POST['vms']) {
echo "<span class='outer solid vms $status'><span id='vm-$uuid' $menu class='hand'>$image</span><span class='inner'>$vm<br><i class='fa fa-$shape $status $color'></i><span class='state'>"._($status)."</span></span></span>";
if ($state == "running") {
#Build VM Usage array.
$menuusage = 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,true);
$menuusage = sprintf("onclick=\"addVMContext('%s','%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,true,addslashes(str_replace('"',"'",$WebUI)));
$vmusagehtml[] = "<span class='outer solid vmsuse $status'><span id='vmusage-$uuid' $menuusage class='hand'>$image</span><span class='inner'>$vm<br><i class='fa fa-$shape $status $color'></i><span class='state'>"._($status)."</span></span>";
$vmusagehtml[] = "<br><br><span id='vmmetrics-gcpu-".$uuid."'>"._("Loading")."....</span>";
$vmusagehtml[] = "<br><span id='vmmetrics-hcpu-".$uuid."'>"._("Loading")."....</span>";
+4 -2
View File
@@ -285,12 +285,14 @@ function my_mkdir($dirname,$permissions = 0777,$recursive = false,$own = "nobody
$parent = str_replace('/mnt/user/', "/mnt/$realdisk/", $parent);
}
}
$fstype = trim(shell_exec(" stat -f -c '%T' $parent"));
$fstype = trim(shell_exec(" stat -f -c '%T' $parent"));
$rtncode = false;
switch ($fstype) {
case "zfs":
$zfsdataset = trim(shell_exec("zfs list -H -o name $parent")) ;
$zfsdataset .= str_replace($parent,"",$dirname);
if (strpos($zfsdataset,'/') !== false) $zfsdataset .= str_replace($parent,"",$dirname); else {
$zfsdataset .= str_replace("/mnt/$zfsdataset","",$dirname);
}
if ($recursive) $rtncode=exec("zfs create -p \"$zfsdataset\"");else $rtncode=exec("zfs create \"$zfsdataset\"");
if (!$rtncode) mkdir($dirname, $permissions, $recursive); else chmod($zfsdataset,$permissions);
break;