mirror of
https://github.com/unraid/webgui.git
synced 2026-04-25 11:49:30 -05:00
VM edit corrections
- create image when new vdisk is added - keep sound card selection included - fix add/remove of network interfaces
This commit is contained in:
@@ -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';
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
<?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?>
|
||||
|
||||
@@ -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?>
|
||||
|
||||
@@ -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?>
|
||||
|
||||
Reference in New Issue
Block a user