mirror of
https://github.com/unraid/webgui.git
synced 2026-01-15 14:09:54 -06:00
Merge pull request #1151 from SimonFair/Add-Boot-order-to-GUI
Add boot order to GUI and CD hot plug function
This commit is contained in:
@@ -20,6 +20,10 @@ Markdown="false"
|
||||
<?
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
$cpus = cpu_list();
|
||||
$hover = in_array($theme,['white','azure']) ? 'rgba(0,0,0,0.1)' : 'rgba(255,255,255,0.1)';
|
||||
$bgcolor = in_array($theme,['white','azure']) ? '#f2f2f2' : '#1c1c1c';
|
||||
$fgcolor = in_array($theme,['white','azure']) ? '#1c1c1c' : '#f2f2f2';
|
||||
$incolor = $theme!='gray' ? $bgcolor : '#121510';
|
||||
|
||||
function showCPUs($uuid) {
|
||||
global $cpus;
|
||||
@@ -105,6 +109,9 @@ if (empty($vms)) {
|
||||
}
|
||||
?>
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.switchbutton.css')?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/jquery.filetree.css")?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/jquery.ui.css")?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/plugins/dynamix.docker.manager/styles/style-$theme.css")?>">
|
||||
<style>
|
||||
th.th1{width:25%}
|
||||
th.th2{width:15%}
|
||||
@@ -117,10 +124,16 @@ div.four label.cpu2{width:26%}
|
||||
table.domdisk thead th:nth-child(1){width:76%;}
|
||||
table.domdisk thead th:nth-child(2){width:8%;}
|
||||
table.domdisk thead th:nth-child(3){width:8%;}
|
||||
table.domdisk thead th:nth-child(3){width:8%;}
|
||||
table.domdisk thead tr th:nth-child(1){padding-left:72px}
|
||||
table.domdisk tbody tr td:nth-child(1){padding-left:72px}
|
||||
table.domdisk tbody tr:nth-child(even){background-color:transparent!important}
|
||||
table.domdisk tbody tr:nth-child(4n-1){background-color:transparent!important}
|
||||
.fileTree{background:<?=$bgcolor?>;width:500px;max-height:320px;overflow-y:scroll;overflow-x:hidden;position:absolute;z-index:100;display:none}
|
||||
div.template,div#dialogWindow,input#upload{display:none}
|
||||
.fileTree{background:<?=$bgcolor?>;width:500px;max-height:320px;overflow-y:scroll;overflow-x:hidden;position:absolute;z-index:100;display:none}
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button[disabled]{cursor:default;color:#808080;background:-webkit-gradient(linear,left top,right top,from(#404040),to(#808080)) 0 0 no-repeat,-webkit-gradient(linear,left top,right top,from(#404040),to(#808080)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#404040),to(#404040)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#808080),to(#808080)) 100% 100% no-repeat;background:linear-gradient(90deg,#404040 0,#808080) 0 0 no-repeat,linear-gradient(90deg,#404040 0,#808080) 0 100% no-repeat,linear-gradient(0deg,#404040 0,#404040) 0 100% no-repeat,linear-gradient(0deg,#808080 0,#808080) 100% 100% no-repeat;background-size:100% 2px,100% 2px,2px 100%,2px 100%}
|
||||
.dropdown-menu{z-index:10001;
|
||||
</style>
|
||||
<table id="kvm_table" class="tablesorter four shift">
|
||||
<thead><tr><th class="th1"><a href="#" style="cursor:hand;margin-left:12px;display:inline-block;width:32px" onclick="resetSorting()" title="Reset sorting"><i class="fa fa-th-list"></i></a>_(Name)_</th><th class="th2">_(Description)_</th><th>_(CPUs)_</th><th>_(Memory)_</th><th>_(vDisks)_</th><th>_(Graphics)_</th><th class="th3">_(Autostart)_</th></tr></thead>
|
||||
@@ -133,6 +146,7 @@ table.domdisk tbody tr:nth-child(4n-1){background-color:transparent!important}
|
||||
<script src="<?autov('/webGui/javascript/jquery.switchbutton.js')?>"></script>
|
||||
<script src="<?autov('/plugins/dynamix.vm.manager/javascript/dynamix.vm.manager.js')?>"></script>
|
||||
<script src="<?autov('/plugins/dynamix.vm.manager/javascript/vmmanager.js')?>"></script>
|
||||
<script src="<?autov("/webGui/javascript/jquery.filetree.js")?>"></script>
|
||||
<script>
|
||||
<?if ($display['resize']):?>
|
||||
function resize(bind) {
|
||||
@@ -157,6 +171,56 @@ var sortableHelper = function(e,i){
|
||||
});
|
||||
return i;
|
||||
};
|
||||
function changemedia(uuid,dev,bus,file) {
|
||||
if (file === "--select") getisoimage(uuid,dev,bus,file) ;
|
||||
if (file === "--eject") ajaxVMDispatch({action:"change-media", uuid:uuid , cdrom:"" , dev:dev , bus:bus , file:file}, "loadlist");
|
||||
|
||||
}
|
||||
function getisoimage(uuid,dev,bus,file){
|
||||
var root = "/mnt/user/isos" ;
|
||||
var match= ".iso" ;
|
||||
var box = $("#dialogWindow");
|
||||
box.html($("#templateISO").html());
|
||||
|
||||
box.find('#target').attr('data-pickroot',root).attr('data-picktop',root).attr('data-pickmatch',match).fileTreeAttach(null,null,function(path){
|
||||
var bits = path.substr(1).split('/');
|
||||
var auto = bits.length>3 ? '' : share;
|
||||
box.find('#target').val(path+auto).change();
|
||||
});
|
||||
var height = 100;
|
||||
box.dialog({
|
||||
title: "Select ISO",
|
||||
resizable: false,
|
||||
width: 600,
|
||||
height: 300,
|
||||
modal: true,
|
||||
show: {effect:'fade', duration:250},
|
||||
hide: {effect:'fade', duration:250},
|
||||
buttons: {
|
||||
"_(Insert)_": function(){
|
||||
var target = box.find('#target');
|
||||
if (target.length) {
|
||||
target = target.val();
|
||||
if (!target ) {errorTarget(); return;}
|
||||
} else target = '';
|
||||
box.find('#target').prop('disabled',true);
|
||||
ajaxVMDispatch({action:"change-media", uuid:uuid , cdrom:"" , dev:dev , bus:bus , file:target}, "loadlist"); ;
|
||||
box.dialog('close');
|
||||
},
|
||||
"_(Cancel)_": function(){
|
||||
box.dialog('close');
|
||||
}
|
||||
}
|
||||
});
|
||||
dialogStyle();
|
||||
}
|
||||
function dialogStyle() {
|
||||
$('.ui-dialog-titlebar-close').css({'background':'transparent','border':'none','font-size':'1.8rem','margin-top':'-14px','margin-right':'-18px'}).html('<i class="fa fa-times"></i>').prop('title',"_(Close)_").prop('onclick',null).off('click').click(function(){box.dialog('close');});
|
||||
$('.ui-dialog-title').css({'text-align':'center','width':'100%','font-size':'1.8rem'});
|
||||
$('.ui-dialog-content').css({'padding-top':'15px','vertical-align':'bottom'});
|
||||
$('.ui-button-text').css({'padding':'0px 5px'});
|
||||
}
|
||||
|
||||
function loadlist() {
|
||||
timers.vm = setTimeout(function(){$('div.spinner.fixed').show('slow');},500);
|
||||
$.get('/plugins/dynamix.vm.manager/include/VMMachines.php',{show:$.cookie('vmshow')},function(d) {
|
||||
@@ -215,3 +279,23 @@ $(function() {
|
||||
loadlist();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="dialogWindow"></div>
|
||||
<div markdown="1" id="templateISO" class="template">
|
||||
<html <?=$display['rtl']?>lang="<?=strtok($locale,'_')?:'en'?>">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="viewport" content="width=1600">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<meta name="referrer" content="same-origin">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/default-fonts.css")?>">
|
||||
</head>
|
||||
<body>
|
||||
_(ISO Image)_:
|
||||
: <input type="text" id="target" autocomplete="off" spellcheck="false" value="" data-pickcloseonfile="true" data-pickfolders="true" data-pickfilter="" data-pickmatch="" data-pickroot="" data-picktop="">
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
||||
@@ -37,7 +37,8 @@ if (file_exists($user_prefs)) {
|
||||
$i = 0;
|
||||
$kvm = ['var kvm=[];'];
|
||||
$show = explode(',',unscript($_GET['show']??''));
|
||||
|
||||
$path = $domain_cfg['MEDIADIR'] ;
|
||||
|
||||
foreach ($vms as $vm) {
|
||||
$res = $lv->get_domain_by_name($vm);
|
||||
$desc = $lv->domain_get_description($res);
|
||||
@@ -127,7 +128,7 @@ foreach ($vms as $vm) {
|
||||
echo "<tr child-id='$i' id='name-$i".(in_array('name-'.$i++,$show) ? "'>" : "' style='display:none'>");
|
||||
echo "<td colspan='8' style='margin:0;padding:0'>";
|
||||
echo "<table class='tablesorter domdisk' id='domdisk_table'>";
|
||||
echo "<thead><tr><th><i class='fa fa-hdd-o'></i> <b>"._('Disk devices')."</b></th><th>"._('Bus')."</th><th>"._('Capacity')."</th><th>"._('Allocation')."</th></tr></thead>";
|
||||
echo "<thead><tr><th><i class='fa fa-hdd-o'></i> <b>"._('Disk devices')."</b></th><th>"._('Bus')."</th><th>"._('Capacity')."</th><th>"._('Allocation')."</th><th>Boot Order</th</tr></thead>";
|
||||
echo "<tbody id='domdisk_list'>";
|
||||
|
||||
/* Display VM disks */
|
||||
@@ -137,6 +138,8 @@ foreach ($vms as $vm) {
|
||||
$disk = $arrDisk['file'] ?? $arrDisk['partition'];
|
||||
$dev = $arrDisk['device'];
|
||||
$bus = $arrValidDiskBuses[$arrDisk['bus']] ?? 'VirtIO';
|
||||
$boot= $arrDisk["boot order"] ;
|
||||
if ($boot < 1) $boot="Not set" ;
|
||||
echo "<tr><td>$disk</td><td>$bus</td>";
|
||||
if ($state == 'shutoff') {
|
||||
echo "<td title='Click to increase Disk Size'>";
|
||||
@@ -152,7 +155,7 @@ foreach ($vms as $vm) {
|
||||
} else {
|
||||
echo "<td>$capacity</td>";
|
||||
}
|
||||
echo "<td>$allocation</td></tr>";
|
||||
echo "<td>$allocation</td><td>$boot</td></tr>";
|
||||
}
|
||||
|
||||
/* Display VM cdroms */
|
||||
@@ -162,11 +165,24 @@ foreach ($vms as $vm) {
|
||||
$disk = $arrCD['file'] ?? $arrCD['partition'];
|
||||
$dev = $arrCD['device'];
|
||||
$bus = $arrValidDiskBuses[$arrCD['bus']] ?? 'VirtIO';
|
||||
echo "<tr><td>$disk</td><td>$bus</td><td>$capacity</td><td>$allocation</td></tr>";
|
||||
$boot= $arrCD["boot order"] ;
|
||||
if ($boot < 1) $boot="Not set" ;
|
||||
if ($disk != "" ) {
|
||||
$title = _("Eject CD Drive").".";
|
||||
$changemedia = "changemedia(\"{$uuid}\",\"{$dev}\",\"{$bus}\", \"--eject\")" ;
|
||||
echo "<tr><td>$disk <a title='$title' href='#' onclick='$changemedia'> <i class='fa fa-eject' aria-hidden=true></i></a></td><td>$bus</td><td>$capacity</td><td>$allocation</td><td>$boot</td></tr>";
|
||||
} else {
|
||||
$title = _("Insert CD").".";
|
||||
$changemedia = "changemedia(\"{$uuid}\",\"{$dev}\",\"{$bus}\",\"--select\")" ;
|
||||
$disk = _("No CD image inserted in to drive") ;
|
||||
echo "<tr><td>$disk<a title='$title' href='#' onclick='$changemedia'> <i class='fa fa-bullseye' aria-hidden=true></i></a> </td><td>$bus</td><td>$capacity</td><td>$allocation</td><td>$boot</td></tr>";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Display VM IP Addresses "execute":"guest-network-get-interfaces" --pretty */
|
||||
echo "<thead><tr><th><i class='fa fa-sitemap'></i> <b>"._('Interfaces')."</b></th><th>"._('Type')."</th><th>"._('IP Address')."</th><th>"._('Prefix')."</th></tr></thead>";
|
||||
echo "<thead><tr><th><i class='fa fa-sitemap'></i> <b>"._('Interfaces')."</b></th><th></th><th>"._('Type')."</th><th>"._('IP Address')."</th><th>"._('Prefix')."</th></tr></thead>";
|
||||
$ip = $lv->domain_qemu_agent_command($res, '{"execute":"guest-network-get-interfaces"}', 10, 0) ;
|
||||
if ($ip != false) {
|
||||
$ip = json_decode($ip,true) ;
|
||||
@@ -184,7 +200,7 @@ foreach ($vms as $vm) {
|
||||
$ipprefix = $arraddr["prefix"] ;
|
||||
$ipnamemac = "$ipname ($iphdwadr)";
|
||||
if (!in_array($ipnamemac,$duplicates)) $duplicates[] = $ipnamemac; else $ipnamemac = "";
|
||||
echo "<tr><td>$ipnamemac</td><td>$iptype</td><td>$ipaddrval</td><td>$ipprefix</td></tr>";
|
||||
echo "<tr><td>$ipnamemac</td><td></td><td>$iptype</td><td>$ipaddrval</td><td>$ipprefix</td></tr>";
|
||||
}
|
||||
}
|
||||
} else echo "<tr><td>"._('Guest not running or guest agent not installed')."</td><td></td><td></td><td></td></tr>";
|
||||
|
||||
@@ -198,6 +198,16 @@ case 'cdrom-change':
|
||||
: ['error' => $lv->get_last_error()];
|
||||
break;
|
||||
|
||||
case 'change-media':
|
||||
requireLibvirt();
|
||||
$dev= $_REQUEST['dev'] ;
|
||||
$file= $_REQUEST['file'] ;
|
||||
$cmdstr = "virsh change-media $domName $dev $file" ;
|
||||
$rtn=shell_exec($cmdstr)
|
||||
? ['success' => true]
|
||||
: ['error' => "Change Media Failed"];
|
||||
break;
|
||||
|
||||
case 'memory-change':
|
||||
requireLibvirt();
|
||||
$arrResponse = $lv->domain_set_memory($domName, $_REQUEST['memory']*1024)
|
||||
|
||||
@@ -475,12 +475,14 @@
|
||||
if ($media['cdrombus'] == 'scsi') {
|
||||
$needSCSIController = true;
|
||||
}
|
||||
$cdromboot = 2 ;
|
||||
$mediaboot = "<boot order='$cdromboot'/>" ;
|
||||
$mediastr = "<disk type='file' device='cdrom'>
|
||||
<driver name='qemu'/>
|
||||
<source file='" . htmlspecialchars($media['cdrom'], ENT_QUOTES | ENT_XML1) . "'/>
|
||||
<target dev='hda' bus='" . $media['cdrombus'] . "'/>
|
||||
<readonly/>
|
||||
<boot order='2'/>
|
||||
$mediaboot
|
||||
</disk>";
|
||||
}
|
||||
|
||||
@@ -1037,12 +1039,14 @@
|
||||
$buses = $this->get_xpath($dom, '//domain/devices/disk[@device="cdrom"]/target/@bus', false);
|
||||
$disks = $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 < $disks['num']; $i++) {
|
||||
$tmp = libvirt_domain_get_block_info($dom, $disks[$i]);
|
||||
if ($tmp) {
|
||||
$tmp['bus'] = $buses[$i];
|
||||
$tmp["boot order"] = $boot[$i] ;
|
||||
$ret[] = $tmp;
|
||||
}
|
||||
else {
|
||||
@@ -1085,13 +1089,14 @@
|
||||
$buses = $this->get_xpath($dom, '//domain/devices/disk[@device="disk"]/target/@bus', false);
|
||||
$disks = $this->get_xpath($dom, '//domain/devices/disk[@device="disk"]/target/@dev', false);
|
||||
$files = $this->get_xpath($dom, '//domain/devices/disk[@device="disk"]/source/@*', false);
|
||||
$boot = $this->get_xpath($dom, '//domain/devices/disk[@device="disk"]/boot/@*', false);
|
||||
|
||||
$ret = [];
|
||||
for ($i = 0; $i < $disks['num']; $i++) {
|
||||
$tmp = libvirt_domain_get_block_info($dom, $disks[$i]);
|
||||
if ($tmp) {
|
||||
$tmp['bus'] = $buses[$i];
|
||||
|
||||
$tmp["boot order"] = $boot[$i] ;
|
||||
// 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']) &&
|
||||
|
||||
@@ -1043,6 +1043,7 @@
|
||||
'driver' => 'raw',
|
||||
'dev' => $disk['device'],
|
||||
'bus' => $disk['bus'],
|
||||
'boot' => $disk['boot order'],
|
||||
'select' => $default_option
|
||||
];
|
||||
}
|
||||
@@ -1104,6 +1105,7 @@
|
||||
],
|
||||
'media' => [
|
||||
'cdrom' => (!empty($medias) && !empty($medias[0]) && array_key_exists('file', $medias[0])) ? $medias[0]['file'] : '',
|
||||
'cdromboot' => (!empty($medias) && !empty($medias[0]) && array_key_exists('file', $medias[0])) ? $medias[0]['boot order'] : '',
|
||||
'cdrombus' => (!empty($medias) && !empty($medias[0]) && array_key_exists('bus', $medias[0])) ? $medias[0]['bus'] : (stripos($lv->domain_get_machine($res), 'q35')!==false ? 'sata': 'ide'),
|
||||
'drivers' => (!empty($medias) && !empty($medias[1]) && array_key_exists('file', $medias[1])) ? $medias[1]['file'] : '',
|
||||
'driversbus' => (!empty($medias) && !empty($medias[1]) && array_key_exists('bus', $medias[1])) ? $medias[1]['bus'] : (stripos($lv->domain_get_machine($res), 'q35')!==false ? 'sata': 'ide')
|
||||
|
||||
@@ -62,7 +62,8 @@
|
||||
'cdrom' => '',
|
||||
'cdrombus' => 'ide',
|
||||
'drivers' => is_file($domain_cfg['VIRTIOISO']) ? $domain_cfg['VIRTIOISO'] : '',
|
||||
'driversbus' => 'ide'
|
||||
'driversbus' => 'ide' ,
|
||||
'cdromboot' => 2
|
||||
],
|
||||
'disk' => [
|
||||
[
|
||||
@@ -71,7 +72,8 @@
|
||||
'driver' => 'raw',
|
||||
'dev' => 'hda',
|
||||
'select' => $domain_cfg['VMSTORAGEMODE'],
|
||||
'bus' => 'virtio'
|
||||
'bus' => 'virtio' ,
|
||||
'boot' => 1
|
||||
]
|
||||
],
|
||||
'gpu' => [
|
||||
@@ -506,6 +508,9 @@
|
||||
<select name="media[cdrombus]" class="cdrom_bus narrow">
|
||||
<?mk_dropdown_options($arrValidCdromBuses, $arrConfig['media']['cdrombus']);?>
|
||||
</select>
|
||||
_(Boot Order)_:
|
||||
<input type="number" size="5" maxlength="5" id="cdboot" class="narrow" style="width: 50px;" name="cdboot" title="_(Boot order)_" value="<?=$arrConfig['media']['cdromboot']?>" disabled>
|
||||
</td>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -653,6 +658,8 @@
|
||||
<select name="disk[<?=$i?>][bus]" class="disk_bus narrow">
|
||||
<?mk_dropdown_options($arrValidDiskBuses, $arrDisk['bus']);?>
|
||||
</select>
|
||||
_(Boot Order)_:
|
||||
<input type="number" size="5" maxlength="5" id="wboot" class="narrow" style="width: 50px;" name="disk[<?=$i?>][boot]" title="_(Boot order)_" value="<?=$arrDisk['boot']?>" disabled>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -780,6 +787,10 @@
|
||||
<?mk_dropdown_options($arrValidDiskBuses, '');?>
|
||||
</select>
|
||||
</td>
|
||||
|
||||
<td>_(Boot Order)_:</td><td>
|
||||
<input type="number" size="5" maxlength="5" id="wboot" class="narrow" style="width: 50px;" name="disk[<?=$i?>][boot]" title="_(Boot order)_" value="<?=$arrdisk['boot']?>" disabled>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user