Merge pull request #385 from bergware/master

System devices: fixed display of ACS override warning message
This commit is contained in:
tom mortensen
2018-09-16 09:49:03 -07:00
committed by GitHub
8 changed files with 99 additions and 41 deletions

View File

@@ -1085,6 +1085,20 @@
];
}
function create_vdisk(&$new) {
global $lv;
$index = 0;
foreach ($new['disk'] as $i => $disk) {
$index++;
if ($disk['new']) {
$disk = $lv->create_disk_image($disk, $new['domain']['name'], $index);
if ($disk['error']) return $disk['error'];
$new['disk'][$i] = $disk;
}
}
return false;
}
function array_update_recursive(&$old, &$new) {
$hostold = $old['devices']['hostdev']; // existing devices including custom settings
$hostnew = $new['devices']['hostdev']; // GUI generated devices
@@ -1115,7 +1129,8 @@
// update parent arrays
if (!$old['devices']['hostdev']) unset($old['devices']['hostdev']);
if (!$new['devices']['hostdev']) unset($new['devices']['hostdev']);
unset($old['cputune']['vcpupin'],$old['devices']['graphics'],$old['devices']['video'],$old['devices']['disk']);
// remove existing auto-generated settings
unset($old['cputune']['vcpupin'],$old['devices']['graphics'],$old['devices']['video'],$old['devices']['disk'],$old['devices']['interface']);
// set namespace
$new['metadata']['vmtemplate']['@attributes']['xmlns'] = 'unraid';
}

View File

@@ -201,11 +201,16 @@ $hdrXML = "<?xml version='1.0' encoding='UTF-8'?>\n"; // XML encoding declaratio
$xml = $_POST['xmldesc'];
} else {
// form view
$arrExistingConfig = custom::createArray('domain',$strXML);
$arrUpdatedConfig = custom::createArray('domain',$lv->config_to_xml($_POST));
array_update_recursive($arrExistingConfig, $arrUpdatedConfig);
$arrConfig = array_replace_recursive($arrExistingConfig, $arrUpdatedConfig);
$xml = custom::createXML('domain',$arrConfig)->saveXML();
if ($error = create_vdisk($_POST) === false) {
$arrExistingConfig = custom::createArray('domain',$strXML);
$arrUpdatedConfig = custom::createArray('domain',$lv->config_to_xml($_POST));
array_update_recursive($arrExistingConfig, $arrUpdatedConfig);
$arrConfig = array_replace_recursive($arrExistingConfig, $arrUpdatedConfig);
$xml = custom::createXML('domain',$arrConfig)->saveXML();
} else {
echo json_encode(['error' => $error]);
exit;
}
}
// delete and create the VM
$lv->nvram_backup($uuid);
@@ -232,7 +237,7 @@ $hdrXML = "<?xml version='1.0' encoding='UTF-8'?>\n"; // XML encoding declaratio
$boolRunning = $lv->domain_get_state($dom)=='running';
$strXML = $lv->domain_get_xml($dom);
$boolNew = false;
$arrConfig = domain_to_config($uuid);
$arrConfig = array_replace_recursive($arrConfigDefaults, domain_to_config($uuid));
} else {
// edit new VM
$boolRunning = false;
@@ -1418,6 +1423,7 @@ $(function() {
$("#vmform .formview #btnSubmit").click(function frmSubmit() {
var $button = $(this);
var $panel = $('.formview');
var form = $button.closest('form');
$("#vmform .disk_select option:selected").not("[value='manual']").closest('table').each(function () {
var v = $(this).find('.disk_preview').html();
@@ -1428,24 +1434,34 @@ $(function() {
<?if (!$boolNew):?>
// signal devices to be added or removed
$button.closest('form').find('input[name="usb[]"],input[name="pci[]"]').each(function(){
form.find('input[name="usb[]"],input[name="pci[]"]').each(function(){
if (!$(this).prop('checked')) $(this).prop('checked',true).val($(this).val()+'#remove');
});
// remove unused graphic cards
var gpus = [], i = 0;
do {
var gpu = $button.closest('form').find('select[name="gpu['+(i++)+'][id]"] option:selected').val();
var gpu = form.find('select[name="gpu['+(i++)+'][id]"] option:selected').val();
if (gpu) gpus.push(gpu);
} while (gpu);
$button.closest('form').find('select[name="gpu[0][id]"] option').each(function(){
form.find('select[name="gpu[0][id]"] option').each(function(){
var gpu = $(this).val();
if (gpu != 'vnc' && !gpus.includes(gpu)) $('form#vmform').append('<input type="hidden" name="pci[]" value="'+gpu+'#remove">');
if (gpu != 'vnc' && !gpus.includes(gpu)) form.append('<input type="hidden" name="pci[]" value="'+gpu+'#remove">');
});
// remove unused sound cards
var sound = [], i = 0;
do {
var audio = form.find('select[name="audio['+(i++)+'][id]"] option:selected').val();
if (audio) sound.push(audio);
} while (audio);
form.find('select[name="audio[0][id]"] option').each(function(){
var audio = $(this).val();
if (audio && !sound.includes(audio)) form.append('<input type="hidden" name="pci[]" value="'+audio+'#remove">');
});
<?endif?>
var postdata = $button.closest('form').find('input,select').serialize().replace(/'/g,"%27");
var postdata = form.find('input,select').serialize().replace(/'/g,"%27");
<?if (!$boolNew):?>
// keep checkbox visually unchecked
$button.closest('form').find('input[name="usb[]"],input[name="pci[]"]').each(function(){
form.find('input[name="usb[]"],input[name="pci[]"]').each(function(){
if ($(this).val().indexOf('#remove')>0) $(this).prop('checked',false);
});
<?endif?>

View File

@@ -392,7 +392,7 @@ $hdrXML = "<?xml version='1.0' encoding='UTF-8'?>\n"; // XML encoding declaratio
$boolRunning = $lv->domain_get_state($dom)=='running';
$strXML = $lv->domain_get_xml($dom);
$boolNew = false;
$arrConfig = domain_to_config($uuid);
$arrConfig = array_replace_recursive($arrConfigDefaults, domain_to_config($uuid));
} else {
// edit new VM
$boolRunning = false;
@@ -1116,29 +1116,40 @@ $(function() {
$("#vmform .formview #btnSubmit").click(function frmSubmit() {
var $button = $(this);
var $panel = $('.formview');
var form = $button.closest('form');
$panel.find('input').prop('disabled', false); // enable all inputs otherwise they wont post
<?if (!$boolNew):?>
// signal devices to be added or removed
$button.closest('form').find('input[name="usb[]"],input[name="pci[]"]').each(function(){
form.find('input[name="usb[]"],input[name="pci[]"]').each(function(){
if (!$(this).prop('checked')) $(this).prop('checked',true).val($(this).val()+'#remove');
});
// remove unused graphic cards
var gpus = [], i = 0;
do {
var gpu = $button.closest('form').find('select[name="gpu['+(i++)+'][id]"] option:selected').val();
var gpu = form.find('select[name="gpu['+(i++)+'][id]"] option:selected').val();
if (gpu) gpus.push(gpu);
} while (gpu);
$button.closest('form').find('select[name="gpu[0][id]"] option').each(function(){
form.find('select[name="gpu[0][id]"] option').each(function(){
var gpu = $(this).val();
if (gpu != 'vnc' && !gpus.includes(gpu)) $('form#vmform').append('<input type="hidden" name="pci[]" value="'+gpu+'#remove">');
if (gpu != 'vnc' && !gpus.includes(gpu)) form.append('<input type="hidden" name="pci[]" value="'+gpu+'#remove">');
});
// remove unused sound cards
var sound = [], i = 0;
do {
var audio = form.find('select[name="audio['+(i++)+'][id]"] option:selected').val();
if (audio) sound.push(audio);
} while (audio);
form.find('select[name="audio[0][id]"] option').each(function(){
var audio = $(this).val();
if (audio && !sound.includes(audio)) form.append('<input type="hidden" name="pci[]" value="'+audio+'#remove">');
});
<?endif?>
var postdata = $button.closest('form').find('input,select').serialize().replace(/'/g,"%27");
var postdata = form.find('input,select').serialize().replace(/'/g,"%27");
<?if (!$boolNew):?>
// keep checkbox visually unchecked
$button.closest('form').find('input[name="usb[]"],input[name="pci[]"]').each(function(){
form.find('input[name="usb[]"],input[name="pci[]"]').each(function(){
if ($(this).val().indexOf('#remove')>0) $(this).prop('checked',false);
});
<?endif?>

View File

@@ -394,7 +394,7 @@ $hdrXML = "<?xml version='1.0' encoding='UTF-8'?>\n"; // XML encoding declaratio
$boolRunning = $lv->domain_get_state($dom)=='running';
$strXML = $lv->domain_get_xml($dom);
$boolNew = false;
$arrConfig = domain_to_config($uuid);
$arrConfig = array_replace_recursive($arrConfigDefaults, domain_to_config($uuid));
} else {
// edit new VM
$boolRunning = false;
@@ -1118,29 +1118,40 @@ $(function() {
$("#vmform .formview #btnSubmit").click(function frmSubmit() {
var $button = $(this);
var $panel = $('.formview');
var form = $button.closest('form');
$panel.find('input').prop('disabled', false); // enable all inputs otherwise they wont post
<?if (!$boolNew):?>
// signal devices to be added or removed
$button.closest('form').find('input[name="usb[]"],input[name="pci[]"]').each(function(){
form.find('input[name="usb[]"],input[name="pci[]"]').each(function(){
if (!$(this).prop('checked')) $(this).prop('checked',true).val($(this).val()+'#remove');
});
// remove unused graphic cards
var gpus = [], i = 0;
do {
var gpu = $button.closest('form').find('select[name="gpu['+(i++)+'][id]"] option:selected').val();
var gpu = form.find('select[name="gpu['+(i++)+'][id]"] option:selected').val();
if (gpu) gpus.push(gpu);
} while (gpu);
$button.closest('form').find('select[name="gpu[0][id]"] option').each(function(){
form.find('select[name="gpu[0][id]"] option').each(function(){
var gpu = $(this).val();
if (gpu != 'vnc' && !gpus.includes(gpu)) $('form#vmform').append('<input type="hidden" name="pci[]" value="'+gpu+'#remove">');
if (gpu != 'vnc' && !gpus.includes(gpu)) form.append('<input type="hidden" name="pci[]" value="'+gpu+'#remove">');
});
// remove unused sound cards
var sound = [], i = 0;
do {
var audio = form.find('select[name="audio['+(i++)+'][id]"] option:selected').val();
if (audio) sound.push(audio);
} while (audio);
form.find('select[name="audio[0][id]"] option').each(function(){
var audio = $(this).val();
if (audio && !sound.includes(audio)) form.append('<input type="hidden" name="pci[]" value="'+audio+'#remove">');
});
<?endif?>
var postdata = $button.closest('form').find('input,select').serialize().replace(/'/g,"%27");
var postdata = form.find('input,select').serialize().replace(/'/g,"%27");
<?if (!$boolNew):?>
// keep checkbox visually unchecked
$button.closest('form').find('input[name="usb[]"],input[name="pci[]"]').each(function(){
form.find('input[name="usb[]"],input[name="pci[]"]').each(function(){
if ($(this).val().indexOf('#remove')>0) $(this).prop('checked',false);
});
<?endif?>

View File

@@ -34,7 +34,7 @@ $(function(){
> This displays a list of IOMMU groups available on your system along with the output of the `lspci` command for each IOMMU group. The numeric identifiers are used to configure PCI pass-through.
<?if (strpos(file_get_contents('/proc/cmdline'), 'pcie_acs_override=') !== false):?>
<p class="notice">Warning: Your system has booted with the PCIe ACS Override setting enabled. The below list doesn't not reflect the way IOMMU would naturally group devices. To see natural IOMMU groups for your hardware, go to the <b><a href="/Settings/VMSettings">VM Settings</a></b> page and set the <b>PCIe ACS Override</b> setting to <b>No</b>.</p>
<p class="notice" style="line-height:30px;height:auto">Warning: Your system has booted with the PCIe ACS Override setting enabled. The below list doesn't not reflect the way IOMMU would naturally group devices.<br>To see natural IOMMU groups for your hardware, go to the <b><a href="/Settings/VMSettings">VM Settings</a></b> page and set the <b>PCIe ACS Override</b> setting to <b>No</b>.</p>
<?endif;?>
<pre><table id='t1' class='pre'><tr><td><div class="spinner"></div></td></tr></table></pre><br>

View File

@@ -34,7 +34,7 @@ class custom {
* @param array $arr - array object to be converterd
* @return XML object
*/
public static function &createXML($root, $arr=array()) {
public static function &createXML($root, $arr) {
$xml = self::getXMLRoot();
$xml->appendChild(self::Array2XML($root, $arr));
self::$xml = null; // clear the xml node in the class for 2nd time use
@@ -55,7 +55,7 @@ class custom {
/*
* Recursive conversion Array to XML
*/
private static function &Array2XML($node_name, $arr=array()) {
private static function &Array2XML($node_name, $arr) {
$xml = self::getXMLRoot();
$node = $xml->createElement($node_name);
if (is_array($arr)) {
@@ -130,11 +130,11 @@ class custom {
// store as single or multi array
if (!isset($tags[$node])) {
// specific for Unraid
if (in_array($node,['hostdev','controller','disk'])) $tags[$node][] = $data; else $tags[$node] = $data;
if (in_array($node,['hostdev','controller','disk','interface'])) $tags[$node][] = $data; else $tags[$node] = $data;
} elseif (is_array($tags[$node]) && array_keys($tags[$node])===range(0, count($tags[$node])-1)) {
$tags[$node][] = $data;
} else {
$tags[$node] = array($tags[$node], $data);
$tags[$node] = [$tags[$node], $data];
}
}
$textContent = [];

View File

@@ -52,6 +52,7 @@ case 'vm':
$xml->cpu->topology['cores'] = $cores;
$xml->cpu->topology['threads'] = $threads;
$xml->vcpu = $vcpus;
$pin = []; foreach ($xml->cputune->emulatorpin->attributes() as $key => $value) $pin[$key] = (string)$value;
unset($xml->cputune);
$xml->addChild('cputune');
for ($i = 0; $i < $vcpus; $i++) {
@@ -59,6 +60,10 @@ case 'vm':
$vcpu['vcpu'] = $i;
$vcpu['cpuset'] = $cpuset[$i];
}
if ($pin) {
$attr = $xml->cputune->addChild('emulatorpin');
foreach ($pin as $key => $value) $attr[$key] = $value;
}
// stop running vm first?
$running = $lv->domain_get_state($dom)=='running';
if ($running) {

View File

@@ -18,21 +18,21 @@ $memory = '/tmp/memory.tmp';
if (isset($_POST['#apply'])) {
$cron = "";
if ($_POST['mode']>0) {
$time = $_POST['hour'] ?? '* *';
$dotm = $_POST['dotm'] ?? '*';
$term = $echo = '';
$time = $_POST['hour'] ?: '* *';
$dotm = $_POST['dotm'] ?: '*';
$month = $_POST['month'] ?: '*';
$day = $_POST['day'] ?: '*';
$write = $_POST['write'] ?: '';
$term = '';
switch ($dotm) {
case '28-31': $term = '[[ $(date +%e -d +1day) -eq 1 ]] && '; $echo = ' || :'; break;
case '28-31': $term = '[[ $(date +%e -d +1day) -eq 1 ]] && '; break;
case 'W1' : $dotm = '1-7'; break;
case 'W2' : $dotm = '8-14'; break;
case 'W3' : $dotm = '15-21'; break;
case 'W4' : $dotm = '22-28'; break;
case 'WL' : $dotm = '*'; $term = '[[ $(date +%e -d +7days) -le 7 ]] && '; $echo = ' || :'; break;
case 'WL' : $dotm = '22-31'; $term = '[[ $(date +%e -d +7days) -le 7 ]] && '; break;
}
$month = isset($_POST['month']) ? $_POST['month'] : '*';
$day = isset($_POST['day']) ? $_POST['day'] : '*';
$write = isset($_POST['write']) ? $_POST['write'] : '';
$cron = "# Generated parity check schedule:\n$time $dotm $month $day $term/usr/local/sbin/mdcmd check $write &> /dev/null{$echo}\n\n";
$cron = "# Generated parity check schedule:\n$time $dotm $month $day $term/usr/local/sbin/mdcmd check $write &> /dev/null || :\n\n";
}
parse_cron_cfg("dynamix", "parity-check", $cron);
@unlink($memory);