diff --git a/xCAT-UI/js/custom/zvm.js b/xCAT-UI/js/custom/zvm.js index 7e1da9090..3242873a9 100644 --- a/xCAT-UI/js/custom/zvm.js +++ b/xCAT-UI/js/custom/zvm.js @@ -45,6 +45,18 @@ zvmPlugin.prototype.loadConfigPage = function(tabId) { queryProfiles('zvmConfigProfile'); }); + // Create accordion panel for images + var imgSection = $('
'); + var imgLnk = $('

Images

').click(function () { + // Do not load panel again if it is already loaded + if ($('#zvmConfigImages').find('.dataTables_wrapper').length) + return; + else + $('#zvmConfigImages').append(createLoader('')); + + queryImages('zvmConfigImages'); + }); + // Create accordion panel for groups var groupsSection = $('
'); var groupsLnk = $('

Groups

').click(function () { @@ -56,15 +68,8 @@ zvmPlugin.prototype.loadConfigPage = function(tabId) { // queryGroups('zvmConfigGroups'); }); - - // Create accordion panel for nodes - var nodeSection = $('
'); - nodeSection.append(createInfoBar('Modify node attributes')); - var nodeLnk = $('

Nodes

').click(function () { - }); - - configAccordion.append(userLnk, userSection, profileLnk, profileSection, groupsLnk, groupsSection, nodeLnk, nodeSection); + configAccordion.append(userLnk, userSection, profileLnk, profileSection, imgLnk, imgSection, groupsLnk, groupsSection); $('#' + tabId).append(configAccordion); configAccordion.accordion(); diff --git a/xCAT-UI/js/custom/zvmUtils.js b/xCAT-UI/js/custom/zvmUtils.js index 6fb81071f..6f189f8dc 100644 --- a/xCAT-UI/js/custom/zvmUtils.js +++ b/xCAT-UI/js/custom/zvmUtils.js @@ -3407,6 +3407,220 @@ function queryProfiles(panelId) { }); } +/** + * Query the images that exists + * + * @param panelId + * Panel ID + * @return Nothing + */ +function queryImages(panelId) { + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'tabdump', + tgt : '', + args : 'osimage', + msg : panelId + }, + + success : configImagePanel + }); +} + +/** + * Panel to configure OS images + * + * @param data + * Data from HTTP request + * @return Nothing + */ +function configImagePanel(data) { + var panelId = data.msg; + var rsp = data.rsp; + + // Wipe panel clean + $('#' + panelId).empty(); + + // Add info bar + $('#' + panelId).append(createInfoBar('Create, edit, and delete operating system images for the self-service portal.')); + + // Create table + var tableId = 'zvmImageTable'; + var table = new DataTable(tableId); + table.init(['', 'Name', 'Selectable', 'OS Version', 'Profile', 'Method', 'Description']); + + // Insert images into table + var imagePos = 0; + var profilePos = 0; + var osversPos = 0; + var osarchPos = 0; + var provMethodPos = 0; + var comments = 0; + var desc, selectable, tmp; + // Get column index for each attribute + var colNameArray = rsp[0].substr(1).split(','); + for (var i in colNameArray){ + switch (colNameArray[i]){ + case 'imagename': { + imagePos = i; + } + break; + + case 'profile':{ + profilePos = i; + } + break; + + case 'osvers':{ + osversPos = i; + } + break; + + case 'osarch':{ + osarchPos = i; + } + break; + + case 'comments':{ + comments = i; + } + break; + + case 'provmethod':{ + provMethodPos = i; + } + break; + + default : + break; + } + } + + // Go through each index + for (var i = 1; i < rsp.length; i++) { + // Get image name + var cols = rsp[i].split(','); + var name = cols[imagePos].replace(new RegExp('"', 'g'), ''); + var profile = cols[profilePos].replace(new RegExp('"', 'g'), ''); + var provMethod = cols[provMethodPos].replace(new RegExp('"', 'g'), ''); + var osVer = cols[osversPos].replace(new RegExp('"', 'g'), ''); + var osArch = cols[osarchPos].replace(new RegExp('"', 'g'), ''); + var osComments = cols[comments].replace(new RegExp('"', 'g'), ''); + + // Only save install boot and s390x architectures + if (osArch == "s390x") { + // Set default description and selectable + selectable = "no"; + desc = "No description"; + + if (osComments) { + tmp = osComments.split('|'); + for (var j = 0; j < tmp.length; j++) { + // Save description + if (tmp[j].indexOf('description:') > -1) { + desc = tmp[j].replace('description:', ''); + desc = jQuery.trim(desc); + } + + // Is the image selectable? + if (tmp[j].indexOf('selectable:') > -1) { + selectable = tmp[j].replace('selectable:', ''); + selectable = jQuery.trim(selectable); + } + } + } + + // Columns are: name, selectable, OS version, profile, method, and description + var cols = new Array(name, selectable, osVer, profile, provMethod, desc); + + // Add remove button where id = user name + cols.unshift(''); + + // Add row + table.add(cols); + } + } + + // Append datatable to tab + $('#' + panelId).append(table.object()); + + // Turn into datatable + var dTable = $('#' + tableId).dataTable({ + 'iDisplayLength': 50, + 'bLengthChange': false, + "sScrollX": "100%", + "bAutoWidth": true + }); + + // Create action bar + var actionBar = $('
'); + + // Create a profile + var createLnk = $('Create'); + createLnk.click(function() { + imageDialog(); + }); + + // Edit a profile + var editLnk = $('Edit'); + editLnk.click(function() { + var images = $('#' + tableId + ' input[type=checkbox]:checked'); + for (var i in images) { + var image = images.eq(i).attr('name'); + if (image) { + // Column order is: profile, selectable, disk pool, disk size, and directory entry + var cols = images.eq(i).parents('tr').find('td'); + var selectable = cols.eq(2).text(); + var osVersion = cols.eq(3).text(); + var profile = cols.eq(4).text(); + var method = cols.eq(5).text(); + var description = cols.eq(6).text(); + + editImageDialog(image, selectable, osVersion, profile, method, description); + } + } + }); + + // Delete a profile + var deleteLnk = $('Delete'); + deleteLnk.click(function() { + var images = getNodesChecked(tableId); + if (images) { + deleteImageDialog(images); + } + }); + + // Refresh profiles table + var refreshLnk = $('Refresh'); + refreshLnk.click(function() { + queryImages(panelId); + }); + + // Create an action menu + var actionsMenu = createMenu([createLnk, editLnk, deleteLnk, refreshLnk]); + actionsMenu.superfish(); + actionsMenu.css('display', 'inline-block'); + actionBar.append(actionsMenu); + + // Set correct theme for action menu + actionsMenu.find('li').hover(function() { + setMenu2Theme($(this)); + }, function() { + setMenu2Normal($(this)); + }); + + // Create a division to hold actions menu + var menuDiv = $(''); + $('#' + tableId + '_wrapper').prepend(menuDiv); + menuDiv.append(actionBar); + $('#' + tableId + '_filter').appendTo(menuDiv); + + // Resize accordion + $('#zvmConfigAccordion').accordion('resize'); +} + /** * Panel to configure directory entries and disks for a profile * @@ -3424,15 +3638,15 @@ function configProfilePanel(panelId) { // Create table var tableId = 'zvmProfileTable'; var table = new DataTable(tableId); - table.init(['', 'Profile', 'Selectable', 'Disk pool', 'Disk size', 'Directory entry']); + table.init(['', 'Profile', 'Disk pool', 'Disk size', 'Directory entry']); // Insert profiles into table var profiles = $.cookie('profiles').split(','); profiles.push('default'); // Add default profile for (var i in profiles) { if (profiles[i]) { - // Columns are: profile, selectable, disk pool, disk size, and directory entry - var cols = new Array(profiles[i], '', '', '', ''); + // Columns are: profile, selectable, description, disk pool, disk size, and directory entry + var cols = new Array(profiles[i], '', '', ''); // Add remove button where id = user name cols.unshift(''); @@ -3471,11 +3685,11 @@ function configProfilePanel(panelId) { if (profile) { // Column order is: profile, selectable, disk pool, disk size, and directory entry var cols = profiles.eq(i).parents('tr').find('td'); - var pool = cols.eq(3).text(); - var size = cols.eq(4).text(); - var entry = cols.eq(5).html().replace(new RegExp('
', 'g'), '\n'); + var pool = cols.eq(2).text(); + var size = cols.eq(3).text(); + var entry = cols.eq(4).html().replace(new RegExp('
', 'g'), '\n'); - openEditProfileDialog(profile, pool, size, entry); + editProfileDialog(profile, pool, size, entry); } } }); @@ -3574,10 +3788,10 @@ function insertDirectoryEntry(data) { // Update the directory entry column var dTable = $('#' + tableId).dataTable(); - dTable.fnUpdate(entry, rowPos, 5, false); + dTable.fnUpdate(entry, rowPos, 4, false); // Adjust table styling - $('#' + tableId + ' td:nth-child(6)').css({ + $('#' + tableId + ' td:nth-child(5)').css({ 'text-align': 'left' }); adjustColumnSize(tableId); @@ -3618,12 +3832,12 @@ function insertDiskInfo(data) { tmp = info[i].split('='); pool = jQuery.trim(tmp[1]); - dTable.fnUpdate(pool, rowPos, 3, false); + dTable.fnUpdate(pool, rowPos, 2, false); } if (info[i].indexOf('eckd_size') > -1) { tmp = info[i].split('='); eckdSize = jQuery.trim(tmp[1]); - dTable.fnUpdate(eckdSize, rowPos, 4, false); + dTable.fnUpdate(eckdSize, rowPos, 3, false); } } @@ -3631,6 +3845,124 @@ function insertDiskInfo(data) { adjustColumnSize(tableId); } +/** + * Open image dialog + */ +function imageDialog() { + // Create form to add profile + var dialogId = 'zvmCreateImage'; + var imageForm = $('
'); + + // Create info bar + var info = createInfoBar('Provide the following attributes for the image. The image name will be generated based on the attributes you will give.'); + imageForm.append(info); + + var imageName = $('
'); + var selectable = $('
'); + var imageType = $('
'); + var architecture = $('
'); + var osName = $('
'); + var osVersion = $('
'); + var profile = $('
'); + var provisionMethod = $('
'); + var provisionSelect = $(''); + provisionMethod.append(provisionSelect); + var comments = $('
'); + imageForm.append(imageName, selectable, imageType, architecture, osName, osVersion, profile, provisionMethod, comments); + + // Open dialog to add image + imageForm.dialog({ + title:'Create image', + modal: true, + close: function(){ + $(this).remove(); + }, + width: 400, + buttons: { + "Ok": function() { + // Remove any warning messages + $(this).find('.ui-state-error').remove(); + + // Get image attributes + var imageType = $(this).find('input[name="imagetype"]'); + var selectable = $(this).find('input[name="selectable"]'); + var architecture = $(this).find('input[name="osarch"]'); + var osName = $(this).find('input[name="osname"]'); + var osVersion = $(this).find('input[name="osvers"]'); + var profile = $(this).find('input[name="profile"]'); + var provisionMethod = $(this).find('select[name="provmethod"]'); + var comments = $(this).find('input[name="comments"]'); + + // Check that image attributes are provided before continuing + var ready = 1; + var inputs = new Array(imageType, architecture, osName, osVersion, profile, provisionMethod); + for (var i in inputs) { + if (!inputs[i].val()) { + inputs[i].css('border-color', 'red'); + ready = 0; + } else + inputs[i].css('border-color', ''); + } + + // If inputs are not complete, show warning message + if (!ready) { + var warn = createWarnBar('Please provide a value for each missing field.'); + warn.prependTo($(this)); + } else { + // Override image name + $(this).find('input[name="imagename"]').val(osVersion.val() + '-' + architecture.val() + '-' + provisionMethod.val() + '-' + profile.val()); + var imageName = $(this).find('input[name="imagename"]'); + + // Change dialog buttons + $(this).dialog('option', 'buttons', { + 'Close': function() {$(this).dialog("close");} + }); + + // Set default description + if (!comments.val()) + comments.val('No description'); + + // Create arguments to send via AJAX + var args = 'updateosimage;' + imageName.val() + ';' + + imageType.val() + ';' + + architecture.val() + ';' + + osName.val() + ';' + + osVersion.val() + ';' + + profile.val() + ';' + + provisionMethod.val() + ';'; + + if (selectable.attr('checked')) + args += '"description:' + comments.val() + '|selectable:yes"'; + else + args += '"description:' + comments.val() + '|selectable:no"'; + + // Add image to xCAT + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'webrun', + tgt : '', + args : args, + msg : dialogId + }, + + success : updatePanel + }); + } + }, + "Cancel": function() { + $(this).dialog( "close" ); + } + } + }); +} + /** * Open profile dialog */ @@ -3735,7 +4067,7 @@ function profileDialog() { * Profiles to delete * @return Nothing */ -function openDeleteProfileDialog(profiles) { +function deleteProfileDialog(profiles) { // Create form to delete disk to pool var dialogId = 'zvmDeleteProfile'; var deleteForm = $('
'); @@ -3746,7 +4078,7 @@ function openDeleteProfileDialog(profiles) { // Open dialog to delete user deleteForm.dialog({ - title:'Delete user', + title:'Delete profile', modal: true, width: 400, close: function(){ @@ -3795,7 +4127,7 @@ function openDeleteProfileDialog(profiles) { * Directory entry * @return Nothing */ -function openEditProfileDialog(profile, pool, size, entry) { +function editProfileDialog(profile, pool, size, entry) { // Create form to add profile var dialogId = 'zvmEditProfile_' + profile; var profileForm = $('
'); @@ -3893,4 +4225,201 @@ function openEditProfileDialog(profile, pool, size, entry) { } } }); +} + +/** + * Open dialog to confirm image delete + * + * @param images + * Images to delete + * @return Nothing + */ +function deleteImageDialog(images) { + // Create form to delete disk to pool + var dialogId = 'zvmDeleteImage'; + var deleteForm = $('
'); + + // Create info bar + var info = createInfoBar('Are you sure you want to delete ' + images.replace(new RegExp(',', 'g'), ', ') + '?'); + deleteForm.append(info); + + // Open dialog to delete user + deleteForm.dialog({ + title:'Delete image', + modal: true, + width: 400, + close: function(){ + $(this).remove(); + }, + buttons: { + "Ok": function(){ + // Remove any warning messages + $(this).find('.ui-state-error').remove(); + + // Change dialog buttons + $(this).dialog('option', 'buttons', { + 'Close': function() {$(this).dialog("close");} + }); + + // Delete user + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'webrun', + tgt : '', + args : 'rmosimage;' + images, + msg : dialogId + }, + success : updatePanel + }); + }, + "Cancel": function() { + $(this).dialog( "close" ); + } + } + }); +} + + +/** + * Edit image dialog + * + * @param iName + * Image name + * @param iSelectable + * Is image selectable from service page + * @param iOsVersion + * OS version + * @param iProfile + * Profile name + * @param iMethod + * Provisioning method + * @param iComments + * Image description + * + * @return Nothing + */ +function editImageDialog(iName, iSelectable, iOsVersion, iProfile, iMethod, iComments) { + // Create form to add profile + var dialogId = 'zvmCreateImage'; + var imageForm = $('
'); + + // Create info bar + var info = createInfoBar('Provide the following attributes for the image. The image name will be generated based on the attributes you will give.'); + imageForm.append(info); + + var imageName = $('
'); + var selectable = $('
'); + var imageType = $('
'); + var architecture = $('
'); + var osName = $('
'); + var osVersion = $('
'); + var profile = $('
'); + var provisionMethod = $('
'); + var provisionSelect = $(''); + provisionMethod.append(provisionSelect); + var comments = $('
'); + imageForm.append(imageName, selectable, imageType, architecture, osName, osVersion, profile, provisionMethod, comments); + + // Fill in image attributes + imageForm.find('input[name="imagename"]').val(iName); + imageForm.find('input[name="osvers"]').val(iOsVersion); + imageForm.find('input[name="profile"]').val(iProfile); + imageForm.find('select[name="provmethod"]').val(iMethod); + imageForm.find('input[name="comments"]').val(iComments); + if (iSelectable == "yes") + imageForm.find('input[name="selectable"]').attr('checked', 'checked'); + + // Open dialog to add image + imageForm.dialog({ + title:'Edit image', + modal: true, + close: function(){ + $(this).remove(); + }, + width: 400, + buttons: { + "Ok": function() { + // Remove any warning messages + $(this).find('.ui-state-error').remove(); + + // Get image attributes + var imageType = $(this).find('input[name="imagetype"]'); + var selectable = $(this).find('input[name="selectable"]'); + var architecture = $(this).find('input[name="osarch"]'); + var osName = $(this).find('input[name="osname"]'); + var osVersion = $(this).find('input[name="osvers"]'); + var profile = $(this).find('input[name="profile"]'); + var provisionMethod = $(this).find('select[name="provmethod"]'); + var comments = $(this).find('input[name="comments"]'); + + // Check that image attributes are provided before continuing + var ready = 1; + var inputs = new Array(imageType, architecture, osName, osVersion, profile, provisionMethod); + for (var i in inputs) { + if (!inputs[i].val()) { + inputs[i].css('border-color', 'red'); + ready = 0; + } else + inputs[i].css('border-color', ''); + } + + // If inputs are not complete, show warning message + if (!ready) { + var warn = createWarnBar('Please provide a value for each missing field.'); + warn.prependTo($(this)); + } else { + // Override image name + $(this).find('input[name="imagename"]').val(osVersion.val() + '-' + architecture.val() + '-' + provisionMethod.val() + '-' + profile.val()); + var imageName = $(this).find('input[name="imagename"]'); + + // Change dialog buttons + $(this).dialog('option', 'buttons', { + 'Close': function() {$(this).dialog("close");} + }); + + // Set default description + if (!comments.val()) + comments.val('No description'); + + // Create arguments to send via AJAX + var args = 'updateosimage;' + imageName.val() + ';' + + imageType.val() + ';' + + architecture.val() + ';' + + osName.val() + ';' + + osVersion.val() + ';' + + profile.val() + ';' + + provisionMethod.val() + ';'; + + if (selectable.attr('checked')) + args += '"description:' + comments.val() + '|selectable:yes"'; + else + args += '"description:' + comments.val() + '|selectable:no"'; + + // Add image to xCAT + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'webrun', + tgt : '', + args : args, + msg : dialogId + }, + + success : updatePanel + }); + } + }, + "Cancel": function() { + $(this).dialog( "close" ); + } + } + }); } \ No newline at end of file diff --git a/xCAT-UI/js/service/service.js b/xCAT-UI/js/service/service.js index b81a724d7..f9728572b 100644 --- a/xCAT-UI/js/service/service.js +++ b/xCAT-UI/js/service/service.js @@ -895,7 +895,7 @@ function loadNode(e) { } /** - * Set a cookie for disk pool names + * Set a cookie for group names * * @param data * Data from HTTP request @@ -906,8 +906,12 @@ function setGroupCookies(data) { var groups = new Array(); // Index 0 is the table header - var cols, name, ip, hostname, desc, comments, tmp; + var cols, name, ip, hostname, desc, selectable, comments, tmp; for (var i = 1; i < data.rsp.length; i++) { + // Set default description and selectable + selectable = "no"; + desc = "No description"; + // Split into columns: // node, ip, hostnames, otherinterfaces, comments, disable cols = data.rsp[i].split(','); @@ -917,15 +921,24 @@ function setGroupCookies(data) { // It should return: "description: All machines; network: 10.1.100.0/24;" comments = cols[4].replace(new RegExp('"', 'g'), ''); - tmp = comments.split(';'); + tmp = comments.split('|'); for (var j = 0; j < tmp.length; j++) { + // Save description if (tmp[j].indexOf('description:') > -1) { desc = tmp[j].replace('description:', ''); desc = jQuery.trim(desc); } + + // Is the group selectable? + if (tmp[j].indexOf('selectable:') > -1) { + selectable = tmp[j].replace('selectable:', ''); + selectable = jQuery.trim(selectable); + } } - groups.push(name + ':' + ip + ':' + hostname + ':' + desc); + // Save groups that are selectable + if (selectable == "yes") + groups.push(name + ':' + ip + ':' + hostname + ':' + desc); } // Set cookie to expire in 60 minutes @@ -946,7 +959,7 @@ function setOSImageCookies(data) { // Get response var rsp = data.rsp; - var imageNames = new Array; + var imageNames = new Array(); var profilesHash = new Object(); var osVersHash = new Object(); var osArchsHash = new Object(); @@ -956,7 +969,8 @@ function setOSImageCookies(data) { var osarchPos = 0; var provMethodPos = 0; var comments = 0; - // Get the column value + var desc, selectable, tmp; + // Get column index for each attribute var colNameArray = rsp[0].substr(1).split(','); for (var i in colNameArray){ switch (colNameArray[i]){ @@ -1008,15 +1022,38 @@ function setOSImageCookies(data) { // Only save install boot if (provMethod.indexOf('install') > -1) { - if (!osComments) - osComments = 'No descritption'; - imageNames.push(osImage + ':' + osComments); + if (!osComments) { + osComments = "No descritption"; + imageNames.push(osImage + ':' + osComments); + } else { + // Set default description and selectable + selectable = "no"; + desc = "No description"; + + tmp = osComments.split('|'); + for (var j = 0; j < tmp.length; j++) { + // Save description + if (tmp[j].indexOf('description:') > -1) { + desc = tmp[j].replace('description:', ''); + desc = jQuery.trim(desc); + } + + // Is the image selectable? + if (tmp[j].indexOf('selectable:') > -1) { + selectable = tmp[j].replace('selectable:', ''); + selectable = jQuery.trim(selectable); + } + } + + // Save images that are selectable + if (selectable == "yes") + imageNames.push(osImage + ':' + desc); + } + profilesHash[profile] = 1; osVersHash[osVer] = 1; osArchsHash[osArch] = 1; - } - - + } } // Save image names in a cookie diff --git a/xCAT-UI/xCAT-UI.spec b/xCAT-UI/xCAT-UI.spec index 600ecd730..c36a82a3d 100644 --- a/xCAT-UI/xCAT-UI.spec +++ b/xCAT-UI/xCAT-UI.spec @@ -151,10 +151,7 @@ ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/bin/webportal if [ "$1" = 1 ] || [ "$1" = 2 ] # Install or upgrade then - # Copy xCAT plugins to /opt/xcat/lib/perl/xCAT_plugin - # cp %{prefix}/ui/xcat/plugins/web.pm %{prefix}/lib/perl/xCAT_plugin/ - # cp %{prefix}/ui/xcat/plugins/webportal.pm %{prefix}/lib/perl/xCAT_plugin/ - # /bin/ln -s ../bin/xcatclientnnr ../bin/webportal + # Restart xCAT /etc/init.d/xcatd restart # Copy php.ini file into /opt/xcat/ui and turn off output_buffering @@ -164,7 +161,7 @@ ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/bin/webportal /bin/sed /etc/php5/apache2/php.ini -e 's/output_buffering = 4096/output_buffering = Off/g' > %{prefix}/ui/php.ini fi - # Restart Apache Web Server + # Restart Apache Server /etc/init.d/$apachedaemon restart true fi diff --git a/xCAT-UI/xcat/plugins/web.pm b/xCAT-UI/xcat/plugins/web.pm index ad3754b5c..9ebd950c8 100644 --- a/xCAT-UI/xcat/plugins/web.pm +++ b/xCAT-UI/xcat/plugins/web.pm @@ -67,7 +67,9 @@ sub process_request { 'updateuser' => \&web_updateuser, 'deleteuser' => \&web_deleteuser, 'mkzprofile' => \&web_mkzprofile, - 'rmzprofile' => \&web_rmzprofile + 'rmzprofile' => \&web_rmzprofile, + 'updateosimage' => \&web_updateosimage, + 'rmosimage' => \&web_rmosimage ); #check whether the request is authorized or not @@ -2350,4 +2352,39 @@ sub web_rmzprofile() { $callback->( { info => $info } ); } +sub web_updateosimage() { + # Add OS image to xCAT table + my ( $request, $callback, $sub_req ) = @_; + + my $name = $request->{arg}->[1]; + my $type = $request->{arg}->[2]; + my $arch = $request->{arg}->[3]; + my $osName = $request->{arg}->[4]; + my $osVersion = $request->{arg}->[5]; + my $profile = $request->{arg}->[6]; + my $provMethod = $request->{arg}->[7]; + my $comments = $request->{arg}->[8]; + + `chtab -d imagename=$name osimage`; + `chtab osimage.imagename=$name osimage.imagetype=$type osimage.osarch=$arch osimage.osname=$osName osimage.osvers=$osVersion osimage.profile=$profile osimage.provmethod=$provMethod osimage.comments=$comments`; + my $info = "Image successfully updated"; + $callback->( { info => $info } ); +} + +sub web_rmosimage() { + # Delete OS image from xCAT table + my ( $request, $callback, $sub_req ) = @_; + + my $name = $request->{arg}->[1]; + my @names = split( ',', $name ); + + # Delete user from xCAT passwd and policy tables + foreach(@names) { + `chtab -d imagename=$_ osimage`; + } + + my $info = "Image successfully deleted"; + $callback->( { info => $info } ); +} + 1; diff --git a/xCAT-UI/xcat/plugins/webportal.pm b/xCAT-UI/xcat/plugins/webportal.pm index 714cb71db..4f6fd2387 100644 --- a/xCAT-UI/xcat/plugins/webportal.pm +++ b/xCAT-UI/xcat/plugins/webportal.pm @@ -442,7 +442,7 @@ sub gennodename { # Get the network within comments # It should return: "description: All machines; network: 10.1.100.0/24;" # This will help determine the 1st node in the group if none exists - @comments = split( /;/, $_->{'comments'} ); + @comments = split( /|/, $_->{'comments'} ); foreach (@comments) { if ($_ =~ m/network:/i) { $network = $_;