mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 19:32:31 +00:00 
			
		
		
		
	Backport z/VM code in trunk to 2.8 branch.
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/branches/2.8@15441 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
		| @@ -731,7 +731,7 @@ function configGroupPanel(data) { | ||||
|     // Create table | ||||
|     var tableId = panelId + 'Datatable'; | ||||
|     var table = new DataTable(tableId); | ||||
|     table.init(['<input type="checkbox" onclick="selectAllCheckbox(event, $(this))">', 'Name', 'Selectable', 'IP', 'Hostname', 'Network', 'Description']); | ||||
|     table.init(['<input type="checkbox" onclick="selectAllCheckbox(event, $(this))">', 'Name', 'Selectable', 'IP', 'Hostname', 'Description']); | ||||
|  | ||||
|     // Insert groups into table | ||||
|     var nodePos = 0; | ||||
| @@ -787,12 +787,6 @@ function configGroupPanel(data) { | ||||
|                     desc = jQuery.trim(desc); | ||||
|                 } | ||||
|                  | ||||
|                 // Save network | ||||
|                 if (tmp[j].indexOf('network:') > -1) { | ||||
|                     network = tmp[j].replace('network:', ''); | ||||
|                     network = jQuery.trim(network); | ||||
|                 } | ||||
|                  | ||||
|                 // Is the group selectable? | ||||
|                 if (tmp[j].indexOf('selectable:') > -1) { | ||||
|                     selectable = tmp[j].replace('selectable:', ''); | ||||
| @@ -802,7 +796,7 @@ function configGroupPanel(data) { | ||||
|         } | ||||
|          | ||||
|         // Columns are: name, selectable, network, and description | ||||
|         var cols = new Array(name, selectable, ip, hostname, network, desc); | ||||
|         var cols = new Array(name, selectable, ip, hostname, desc); | ||||
|  | ||||
|         // Add remove button where id = user name | ||||
|         cols.unshift('<input type="checkbox" name="' + name + '"/>'); | ||||
| @@ -851,10 +845,9 @@ function configGroupPanel(data) { | ||||
|                 var selectable = cols.eq(2).text();                 | ||||
|                 var ip = cols.eq(3).text(); | ||||
|                 var hostnames = cols.eq(4).text(); | ||||
|                 var network = cols.eq(5).text(); | ||||
|                 var description = cols.eq(6).text(); | ||||
|                 var description = cols.eq(5).text(); | ||||
|                  | ||||
|                 editGroupDialog(group, selectable, ip, hostnames, network, description); | ||||
|                 editGroupDialog(group, selectable, ip, hostnames, description); | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
| @@ -913,9 +906,10 @@ function groupDialog() { | ||||
|     var selectable = $('<div><label>Selectable:</label><input type="checkbox" name="selectable" title="Select if you want this group to appear on the self service portal"/></div>'); | ||||
|     var ip = $('<div><label>IP:</label><input type="text" name="ip" title="The IP address of the nodes, usually given as a regular expression, e.g. |ihost(\d+)|10.1.1.($1+0)|"/></div>'); | ||||
|     var hostnames = $('<div><label>Hostnames:</label><input type="text" name="hostnames" title="The hostname of the nodes, usually given as a regular expression, e.g. |(.*)|($1).sourceforge.net|"/></div>'); | ||||
|     var network = $('<div><label>Network:</label><input type="text" name="network" title="The groups network and its subnet mask, e.g. 10.1.1.0/24"/></div>'); | ||||
|     var comments = $('<div><label>Description:</label><input type="text" name="comments" title="A description of the group"/></div>'); | ||||
|     groupForm.append(group, selectable, ip, hostnames, network, comments); | ||||
|     var ipPool = $('<div><label style="vertical-align: top;">IP pool:</label><textarea name="ip_pool" title="A pool of node names, IP addresses, and hostnames that can be chosen from for a newly provisioned virtual machine. An entry in the pool could be: ihost12,10.1.2.12,ihost12.endicott.ibm.com. A newline separates each entry."/></div>'); | ||||
|      | ||||
|     groupForm.append(group, selectable, ip, hostnames, comments, ipPool); | ||||
|      | ||||
| 	// Generate tooltips | ||||
|     groupForm.find('div input[title],textarea[title],select[title]').tooltip({ | ||||
| @@ -945,7 +939,7 @@ function groupDialog() { | ||||
|         close: function(){ | ||||
|             $(this).remove(); | ||||
|         }, | ||||
|         width: 400, | ||||
|         width: 600, | ||||
|         buttons: { | ||||
|             "Ok": function() { | ||||
|                 // Remove any warning messages | ||||
| @@ -956,12 +950,12 @@ function groupDialog() { | ||||
|                 var selectable = $(this).find('input[name="selectable"]'); | ||||
|                 var ip = $(this).find('input[name="ip"]'); | ||||
|                 var hostnames = $(this).find('input[name="hostnames"]'); | ||||
|                 var network = $(this).find('input[name="network"]'); | ||||
|                 var comments = $(this).find('input[name="comments"]'); | ||||
|                 var ipPool = $(this).find('textarea[name=ip_pool]').val(); | ||||
|                                  | ||||
|                 // Check that group attributes are provided before continuing | ||||
|                 var ready = 1; | ||||
|                 var inputs = new Array(group, ip, hostnames, network); | ||||
|                 var inputs = new Array(group, ip, hostnames); | ||||
|                 for (var i in inputs) { | ||||
|                     if (!inputs[i].val()) { | ||||
|                         inputs[i].css('border-color', 'red'); | ||||
| @@ -980,6 +974,10 @@ function groupDialog() { | ||||
|                         'Close': function() {$(this).dialog("close");} | ||||
|                     }); | ||||
|                      | ||||
|                     // A newline at the end of IP pool is needed | ||||
|                     ipPool = ipPool.replace(/^\s+|\s+$/g, ''); | ||||
|                     ipPool += '\n'; | ||||
|                      | ||||
|                     // Set default description | ||||
|                     if (!comments.val()) | ||||
|                         comments.val('No description'); | ||||
| @@ -988,12 +986,12 @@ function groupDialog() { | ||||
|                     var args = "updategroup;" + group.val() + ";'" + ip.val() + "';'" + hostnames.val() + "';"; | ||||
|                          | ||||
|                     if (selectable.attr("checked")) | ||||
|                         args += "'description:" + comments.val() + "|network:" + network.val() + "|selectable:yes"; | ||||
|                         args += "'description:" + comments.val() + "|selectable:yes"; | ||||
|                     else | ||||
|                         args += "'description:" + comments.val() + "|network:" + network.val() + "|selectable:no"; | ||||
|                         args += "'description:" + comments.val() + "|selectable:no"; | ||||
|                                                              | ||||
|                     // Add image to xCAT | ||||
|                     $.ajax( { | ||||
|                     $.ajax({ | ||||
|                         url : 'lib/cmd.php', | ||||
|                         dataType : 'json', | ||||
|                         data : { | ||||
| @@ -1005,6 +1003,37 @@ function groupDialog() { | ||||
|      | ||||
|                         success : updatePanel | ||||
|                     }); | ||||
|                      | ||||
|                     // Write IP pool file to /var/tmp | ||||
|                     $.ajax({ | ||||
|                         url : 'lib/cmd.php', | ||||
|                         dataType : 'json', | ||||
|                         data : { | ||||
|                             cmd : 'write', | ||||
|                             tgt : '/var/tmp/' + group.val() + '.pool', | ||||
|                             args : '', | ||||
|                             cont : ipPool, | ||||
|                             msg : dialogId + ';' + group.val() | ||||
|                         }, | ||||
|  | ||||
|                         success : function(data) { | ||||
|                             var args = data.msg.split(';'); | ||||
|                                                          | ||||
|                             // Create profile in xCAT | ||||
|                             $.ajax({ | ||||
|                                 url : 'lib/cmd.php', | ||||
|                                 dataType : 'json', | ||||
|                                 data : { | ||||
|                                     cmd : 'webrun', | ||||
|                                     tgt : '', | ||||
|                                     args : 'mkippool;' + args[1], | ||||
|                                     msg : args[0] | ||||
|                                 }, | ||||
|                                  | ||||
|                                 success: updatePanel | ||||
|                             }); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             }, | ||||
|             "Cancel": function() { | ||||
| @@ -1021,10 +1050,9 @@ function groupDialog() { | ||||
|  * @param iSelectable Is group selectable from the service page | ||||
|  * @param iIp Group IP regex | ||||
|  * @param iHostnames Group hostnames regex | ||||
|  * @param iNetwork Group network, e.g. 10.1.2.0/24 | ||||
|  * @param iComments Group description | ||||
|  */ | ||||
| function editGroupDialog(iGroup, iSelectable, iIp, iHostnames, iNetwork, iComments) { | ||||
| function editGroupDialog(iGroup, iSelectable, iIp, iHostnames, iComments) { | ||||
|     // Create form to add profile | ||||
|     var dialogId = 'createGroup-' + iGroup; | ||||
|     var groupForm = $('<div id="' + dialogId + '" class="form"></div>'); | ||||
| @@ -1037,15 +1065,32 @@ function editGroupDialog(iGroup, iSelectable, iIp, iHostnames, iNetwork, iCommen | ||||
|     var selectable = $('<div><label>Selectable:</label><input type="checkbox" name="selectable" title="Select if you want this group to appear on the self service portal"/></div>'); | ||||
|     var ip = $('<div><label>IP:</label><input type="text" name="ip" title="The IP address for the group, usually given as a regular expression, e.g. |ihost(\d+)|10.1.1.($1+0)|"/></div>'); | ||||
|     var hostnames = $('<div><label>Hostnames:</label><input type="text" name="hostnames" title="The hostname for the group, usually given as a regular expression, e.g. |(.*)|($1).sourceforge.net|"/></div>'); | ||||
|     var network = $('<div><label>Network:</label><input type="text" name="network" title="The groups network and its subnet mask, e.g. 10.1.1.0/24"/></div>'); | ||||
|     var comments = $('<div><label>Description:</label><input type="text" name="comments" title="A description of the group"/></div>'); | ||||
|     groupForm.append(group, selectable, ip, hostnames, network, comments); | ||||
|     var ipPool = $('<div><label style="vertical-align: top;">IP pool:</label><textarea name="ip_pool" title="A pool of node names, IP addresses, and hostnames that can be chosen from for a newly provisioned virtual machine."/></div>'); | ||||
|      | ||||
|     groupForm.append(group, selectable, ip, hostnames, comments, ipPool); | ||||
|      | ||||
| 	// Query IP pool based on group name | ||||
|     $.ajax({ | ||||
|         url : 'lib/cmd.php', | ||||
|         dataType : 'json', | ||||
|         data : { | ||||
|             cmd : 'webrun', | ||||
|             tgt : '', | ||||
|             args : 'lsippool;' + iGroup, | ||||
|             msg : dialogId | ||||
|         }, | ||||
|  | ||||
|         success : function(data) { | ||||
|         	// Populate textarea with IP pool entries | ||||
|         	$('#' + data.msg).find('textarea[name="ip_pool"]').val(data.rsp[0]); | ||||
|         } | ||||
|     }); | ||||
|      | ||||
|     // Fill in group attributes | ||||
|     groupForm.find('input[name="group"]').val(iGroup); | ||||
|     groupForm.find('input[name="ip"]').val(iIp); | ||||
|     groupForm.find('input[name="hostnames"]').val(iHostnames); | ||||
|     groupForm.find('input[name="network"]').val(iNetwork); | ||||
|     groupForm.find('input[name="comments"]').val(iComments); | ||||
|     if (iSelectable == "yes") | ||||
|         groupForm.find('input[name="selectable"]').attr('checked', 'checked'); | ||||
| @@ -1078,7 +1123,7 @@ function editGroupDialog(iGroup, iSelectable, iIp, iHostnames, iNetwork, iCommen | ||||
|         close: function(){ | ||||
|             $(this).remove(); | ||||
|         }, | ||||
|         width: 400, | ||||
|         width: 600, | ||||
|         buttons: { | ||||
|             "Ok": function() { | ||||
|                 // Remove any warning messages | ||||
| @@ -1089,12 +1134,12 @@ function editGroupDialog(iGroup, iSelectable, iIp, iHostnames, iNetwork, iCommen | ||||
|                 var selectable = $(this).find('input[name="selectable"]'); | ||||
|                 var ip = $(this).find('input[name="ip"]'); | ||||
|                 var hostnames = $(this).find('input[name="hostnames"]'); | ||||
|                 var network = $(this).find('input[name="network"]'); | ||||
|                 var comments = $(this).find('input[name="comments"]'); | ||||
|                 var ipPool = $(this).find('textarea[name=ip_pool]').val(); | ||||
|                                  | ||||
|                 // Check that group attributes are provided before continuing | ||||
|                 var ready = 1; | ||||
|                 var inputs = new Array(group, ip, hostnames, network); | ||||
|                 var inputs = new Array(group, ip, hostnames); | ||||
|                 for (var i in inputs) { | ||||
|                     if (!inputs[i].val()) { | ||||
|                         inputs[i].css('border-color', 'red'); | ||||
| @@ -1113,6 +1158,10 @@ function editGroupDialog(iGroup, iSelectable, iIp, iHostnames, iNetwork, iCommen | ||||
|                         'Close': function() {$(this).dialog("close");} | ||||
|                     }); | ||||
|                      | ||||
|                     // A newline at the end of IP pool is needed | ||||
|                     ipPool = ipPool.replace(/^\s+|\s+$/g, ''); | ||||
|                     ipPool += '\n'; | ||||
|                      | ||||
|                     // Set default description | ||||
|                     if (!comments.val()) | ||||
|                         comments.val('No description'); | ||||
| @@ -1121,9 +1170,9 @@ function editGroupDialog(iGroup, iSelectable, iIp, iHostnames, iNetwork, iCommen | ||||
|                     var args = "updategroup;" + group.val() + ";'" + ip.val() + "';'" + hostnames.val() + "';"; | ||||
|                          | ||||
|                     if (selectable.attr("checked")) | ||||
|                         args += "'description:" + comments.val() + "|network:" + network.val() + "|selectable:yes"; | ||||
|                         args += "'description:" + comments.val() + "|selectable:yes"; | ||||
|                     else | ||||
|                         args += "'description:" + comments.val() + "|network:" + network.val() + "|selectable:no"; | ||||
|                         args += "'description:" + comments.val() + "|selectable:no"; | ||||
|                                                              | ||||
|                     // Add image to xCAT | ||||
|                     $.ajax( { | ||||
| @@ -1138,6 +1187,37 @@ function editGroupDialog(iGroup, iSelectable, iIp, iHostnames, iNetwork, iCommen | ||||
|      | ||||
|                         success : updatePanel | ||||
|                     }); | ||||
|                      | ||||
|                     // Write IP pool file to /var/tmp | ||||
|                     $.ajax({ | ||||
|                         url : 'lib/cmd.php', | ||||
|                         dataType : 'json', | ||||
|                         data : { | ||||
|                             cmd : 'write', | ||||
|                             tgt : '/var/tmp/' + group.val() + '.pool', | ||||
|                             args : '', | ||||
|                             cont : ipPool, | ||||
|                             msg : dialogId + ';' + group.val() | ||||
|                         }, | ||||
|  | ||||
|                         success : function(data) { | ||||
|                             var args = data.msg.split(';'); | ||||
|                                                          | ||||
|                             // Create profile in xCAT | ||||
|                             $.ajax({ | ||||
|                                 url : 'lib/cmd.php', | ||||
|                                 dataType : 'json', | ||||
|                                 data : { | ||||
|                                     cmd : 'webrun', | ||||
|                                     tgt : '', | ||||
|                                     args : 'mkippool;' + args[1], | ||||
|                                     msg : args[0] | ||||
|                                 }, | ||||
|                                  | ||||
|                                 success: updatePanel | ||||
|                             }); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             }, | ||||
|             "Cancel": function() { | ||||
|   | ||||
| @@ -33,7 +33,7 @@ zvmPlugin.prototype.loadConfigPage = function(tabId) { | ||||
|      | ||||
|     // Create accordion panel for images | ||||
|     var imgSection = $('<div id="zvmConfigImages"></div>'); | ||||
|     var imgLnk = $('<h3><a href="#">Images</a></h3>').click(function () { | ||||
|     var imgLnk = $('<h3><a href="#">Templates</a></h3>').click(function () { | ||||
|         // Do not load panel again if it is already loaded | ||||
|         if ($('#zvmConfigImages').find('.dataTables_wrapper').length) | ||||
|             return; | ||||
| @@ -67,7 +67,7 @@ zvmPlugin.prototype.loadConfigPage = function(tabId) { | ||||
|  *  | ||||
|  * @param node Node to clone | ||||
|  */ | ||||
| zvmPlugin.prototype.serviceClone = function(node) {     | ||||
| zvmPlugin.prototype.serviceClone = function(node) { | ||||
|     var owner = $.cookie('xcat_username'); | ||||
|     var group = getUserNodeAttr(node, 'groups'); | ||||
|      | ||||
| @@ -95,7 +95,7 @@ zvmPlugin.prototype.loadServiceProvisionPage = function(tabId) { | ||||
|      | ||||
|     // Create provision table | ||||
|     var provTable = $('<table id="select-table" style="margin: 10px;"></table'); | ||||
|     var provHeader = $('<thead class="ui-widget-header"> <th>zVM</th> <th>Group</th> <th>Image</th></thead>'); | ||||
|     var provHeader = $('<thead class="ui-widget-header"> <th>zVM</th> <th>Group</th> <th>Template</th> <th>Image</th></thead>'); | ||||
|     var provBody = $('<tbody></tbody>'); | ||||
|     var provFooter = $('<tfoot></tfoot>'); | ||||
|     provTable.append(provHeader, provBody, provFooter); | ||||
| @@ -108,16 +108,18 @@ zvmPlugin.prototype.loadServiceProvisionPage = function(tabId) { | ||||
|     // Create row to contain selections | ||||
|     var provRow = $('<tr></tr>'); | ||||
|     provBody.append(provRow); | ||||
|     // Create columns for zVM, group, and image | ||||
|     // Create columns for zVM, group, template, and image | ||||
|     var zvmCol = $('<td style="vertical-align: top;"></td>'); | ||||
|     provRow.append(zvmCol); | ||||
|     var groupCol = $('<td style="vertical-align: top;"></td>'); | ||||
|     provRow.append(groupCol); | ||||
|     var imageCol = $('<td style="vertical-align: top;"></td>'); | ||||
|     provRow.append(imageCol); | ||||
|     var tmplCol = $('<td style="vertical-align: top;"></td>'); | ||||
|     provRow.append(tmplCol); | ||||
|     var imgCol = $('<td style="vertical-align: top;"></td>'); | ||||
|     provRow.append(imgCol); | ||||
|          | ||||
|     provRow.children('td').css({ | ||||
|         'min-width': '250px' | ||||
|         'min-width': '200px' | ||||
|     }); | ||||
|      | ||||
|     /** | ||||
| @@ -130,23 +132,38 @@ zvmPlugin.prototype.loadServiceProvisionPage = function(tabId) { | ||||
|          | ||||
|         var hcp = $('#select-table tbody tr:eq(0) td:eq(0) input[name="hcp"]:checked').val(); | ||||
|         var group = $('#select-table tbody tr:eq(0) td:eq(1) input[name="group"]:checked').val(); | ||||
|         var img = $('#select-table tbody tr:eq(0) td:eq(2) input[name="image"]:checked').val(); | ||||
|         var tmpl = $('#select-table tbody tr:eq(0) td:eq(2) input[name="image"]:checked').val(); | ||||
|         var img = $('#select-table tbody tr:eq(0) td:eq(3) input[name="master"]:checked').val(); | ||||
|         var owner = $.cookie('xcat_username'); | ||||
|          | ||||
|         if (!hcp || !group || !img) { | ||||
|         if (img && !group) { | ||||
|         	// Show warning message | ||||
|             var warn = createWarnBar('You need to select a group'); | ||||
|             warn.prependTo($(this).parent()); | ||||
|         } else if (!img && (!hcp || !group || !tmpl)) { | ||||
|             // Show warning message | ||||
|             var warn = createWarnBar('You need to select an option for each column'); | ||||
|             var warn = createWarnBar('You need to select a zHCP, group, and image'); | ||||
|             warn.prependTo($(this).parent()); | ||||
|         } else { | ||||
|             // Begin by creating VM | ||||
|             createzVM(tabId, group, hcp, img, owner); | ||||
|         	if (img) { | ||||
|         		// Begin by clonning VM | ||||
|         		 | ||||
|         	    // Submit request to clone VM | ||||
|         	    // webportal clonezlinux [src node] [group] [owner] | ||||
|         	    var iframe = createIFrame('lib/srv_cmd.php?cmd=webportal&tgt=&args=clonezlinux;' + img + ';' + group + ';' + owner + '&msg=&opts=flush'); | ||||
|         	    iframe.prependTo($('#zvmProvisionTab')); | ||||
|         	} else { | ||||
|         		// Begin by creating VM | ||||
|         		createzVM(tabId, group, hcp, tmpl, owner); | ||||
|         	} | ||||
|         } | ||||
|     }); | ||||
|     provForm.append(provisionBtn); | ||||
|      | ||||
|     // Load zVMs, groups, and images into their respective columns | ||||
|     // Load zVMs, groups, template, and image into their respective columns | ||||
|     loadSrvGroups(groupCol); | ||||
|     loadOSImages(imageCol); | ||||
|     loadOSImages(tmplCol); | ||||
|     loadGoldenImages(imgCol); | ||||
|      | ||||
|     // Get zVM host names | ||||
|     if (!$.cookie('zvms')){ | ||||
|   | ||||
| @@ -5569,6 +5569,9 @@ function loadOSImages(col) { | ||||
|             $(this).children('input:radio').attr('checked', 'checked'); | ||||
|             $(this).parents('td').find('div').attr('class', 'ui-state-default'); | ||||
|             $(this).attr('class', 'ui-state-active'); | ||||
|              | ||||
|             $('#select-table tbody tr:eq(0) td:eq(3) input[name="master"]').attr('checked', ''); | ||||
|             $('#select-table tbody tr:eq(0) td:eq(3) input[name="master"]').parents('td').find('div').attr('class', 'ui-state-default'); | ||||
|         }); | ||||
|         radio = $('<input type="radio" name="image" value="' + name + '"/>').css('display', 'none'); | ||||
|         imgBlock.append(radio, $('<span style="font-weight: normal;"><b>' + name + '</b>: ' + desc + '</span>')); | ||||
| @@ -5581,6 +5584,60 @@ function loadOSImages(col) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Load golden images into column | ||||
|  *  | ||||
|  * @param col Table column where master copies will be placed | ||||
|  */ | ||||
| function loadGoldenImages(col) { | ||||
|     // Get group names and description and append to group column     | ||||
|     if (!$.cookie('srv_goldenimages')) { | ||||
|         var infoBar = createInfoBar('No selectable master copies available'); | ||||
|         col.append(infoBar); | ||||
|         return; | ||||
|     } | ||||
|      | ||||
|     var imgNames = $.cookie('srv_goldenimages').split(','); | ||||
|      | ||||
|     var imgBlock, radio, args, name, desc; | ||||
|     for (var i in imgNames) { | ||||
|         args = imgNames[i].split(':'); | ||||
|         name = args[0]; | ||||
|         desc = args[1]; | ||||
|          | ||||
|         // Create block for each image | ||||
|         imgBlock = $('<div class="ui-state-default"></div>').css({ | ||||
|             'border': '1px solid', | ||||
|             'max-width': '200px', | ||||
|             'margin': '5px auto', | ||||
|             'padding': '5px', | ||||
|             'display': 'block',  | ||||
|             'vertical-align': 'middle', | ||||
|             'cursor': 'pointer', | ||||
|             'white-space': 'normal' | ||||
|         }).click(function(){ | ||||
|             $(this).children('input:radio').attr('checked', 'checked'); | ||||
|             $(this).parents('td').find('div').attr('class', 'ui-state-default'); | ||||
|             $(this).attr('class', 'ui-state-active'); | ||||
|              | ||||
|             // Un-select zVM and image | ||||
|             $('#select-table tbody tr:eq(0) td:eq(2) input[name="image"]').attr('checked', ''); | ||||
|             $('#select-table tbody tr:eq(0) td:eq(2) input[name="image"]').parents('td').find('div').attr('class', 'ui-state-default'); | ||||
|              | ||||
|             $('#select-table tbody tr:eq(0) td:eq(0) input[name="hcp"]').attr('checked', ''); | ||||
|             $('#select-table tbody tr:eq(0) td:eq(0) input[name="hcp"]').parents('td').find('div').attr('class', 'ui-state-default'); | ||||
|         }); | ||||
|         radio = $('<input type="radio" name="master" value="' + name + '"/>').css('display', 'none'); | ||||
|         imgBlock.append(radio, $('<span style="font-weight: normal;"><b>' + name + '</b>: ' + desc + '</span>')); | ||||
|         imgBlock.children('span').css({ | ||||
|             'display': 'block', | ||||
|             'margin': '5px', | ||||
|             'text-align': 'left' | ||||
|         }); | ||||
|         col.append(imgBlock); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Set a cookie for zVM host names (service page) | ||||
|  *  | ||||
| @@ -5603,6 +5660,28 @@ function setzVMCookies(data) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Set a cookie for master copies (service page) | ||||
|  *  | ||||
|  * @param data Data from HTTP request | ||||
|  */ | ||||
| function setGoldenImagesCookies(data) { | ||||
|     if (data.rsp[0].length) { | ||||
|         var copies = new Array(); | ||||
|         var tmp = data.rsp[0].split(","); | ||||
|         for ( var i = 0; i < tmp.length; i++) { | ||||
|             if (tmp[i] != null && tmp[i] != "") { | ||||
|             	copies.push(tmp[i]); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         // Set cookie to expire in 60 minutes | ||||
|         var exDate = new Date(); | ||||
|         exDate.setTime(exDate.getTime() + (240 * 60 * 1000)); | ||||
|         $.cookie('srv_goldenimages', copies, { expires: exDate }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Set a cookie for disk pool names of a given node | ||||
|  *  | ||||
|   | ||||
| @@ -239,22 +239,38 @@ function loadServiceProvisionPage(tabId) { | ||||
|                 title = 'z/VM'; | ||||
|                  | ||||
|                 // Get zVM host names | ||||
|                 if (!$.cookie('zvms')){ | ||||
|                     $.ajax( { | ||||
|                         url : 'lib/srv_cmd.php', | ||||
|                         dataType : 'json', | ||||
|                         data : { | ||||
|                             cmd : 'webportal', | ||||
|                             tgt : '', | ||||
|                             args : 'lszvm', | ||||
|                             msg : '' | ||||
|                         }, | ||||
|                 $.ajax({ | ||||
|                     url : 'lib/srv_cmd.php', | ||||
|                     dataType : 'json', | ||||
|                     async : false, | ||||
|                     data : { | ||||
|                         cmd : 'webportal', | ||||
|                         tgt : '', | ||||
|                         args : 'lszvm', | ||||
|                         msg : '' | ||||
|                     }, | ||||
|  | ||||
|                         success : function(data) { | ||||
|                             setzVMCookies(data); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|                     success : function(data) { | ||||
|                         setzVMCookies(data); | ||||
|                     } | ||||
|                 }); | ||||
|                  | ||||
|                 // Get master copies for clone | ||||
|                 $.ajax({ | ||||
|                     url : 'lib/srv_cmd.php', | ||||
|                     dataType : 'json', | ||||
|                     async : false, | ||||
|                     data : { | ||||
|                         cmd : 'webportal', | ||||
|                         tgt : '', | ||||
|                         args : 'lsgoldenimages', | ||||
|                         msg : '' | ||||
|                     }, | ||||
|  | ||||
|                     success : function(data) { | ||||
|                         setGoldenImagesCookies(data); | ||||
|                     } | ||||
|                 }); | ||||
|                  | ||||
|                 break; | ||||
|             } | ||||
| @@ -1077,11 +1093,27 @@ function setUserNodes(data) { | ||||
|             // where column names are: node, os, arch, profile, provmethod, supportedarchs, nodetype, comments, disable | ||||
|             var cols = data.rsp[i].split(','); | ||||
|             var node = cols[0].replace(new RegExp('"', 'g'), ''); | ||||
|             var owner = cols[7].replace(new RegExp('"', 'g'), ''); | ||||
|             owner = owner.replace('owner:', ''); | ||||
|              | ||||
|             if (owner == userName) { | ||||
|                 usrNodes.push(node); | ||||
|             // Comments can contain the owner and description | ||||
|             var comments = new Array(); | ||||
|             if (cols[7].indexOf(';') > -1) { | ||||
|             	comments = cols[7].replace(new RegExp('"', 'g'), '').split(';'); | ||||
|             } else { | ||||
|             	comments.push(cols[7].replace(new RegExp('"', 'g'), '')); | ||||
|             } | ||||
|              | ||||
|             // Extract the owner | ||||
|             var owner; | ||||
|             for (var j in comments) { | ||||
|             	if (comments[j].indexOf('owner:') > -1) { | ||||
|             		owner = comments[j].replace('owner:', ''); | ||||
|             		 | ||||
|             		if (owner == userName) { | ||||
|                         usrNodes.push(node); | ||||
|                     } | ||||
|             		 | ||||
|             		break; | ||||
|             	} | ||||
|             } | ||||
|         } // End of for | ||||
|          | ||||
|   | ||||
| @@ -93,7 +93,7 @@ function submit_request($req, $skipVerify, $opts_array){ | ||||
|         syslog(LOG_INFO, "Sending request: $cmd $nr"); | ||||
|         stream_set_blocking($fp, 0);    // Set as non-blocking | ||||
|         fwrite($fp,$req->asXML());      // Send XML to xcatd | ||||
|         set_time_limit(900);            // Set 15 minutes timeout (for long running requests) | ||||
|         set_time_limit(3600);            // Set 15 minutes timeout (for long running requests) | ||||
|         // The default is 30 seconds which is too short for some requests | ||||
|  | ||||
|         // Turn on output buffering | ||||
|   | ||||
| @@ -91,7 +91,7 @@ function submit_request($req, $skipVerify, $opts_array){ | ||||
|         syslog(LOG_INFO, "Sending request: $cmd $nr"); | ||||
|         stream_set_blocking($fp, 0);    // Set as non-blocking | ||||
|         fwrite($fp,$req->asXML());        // Send XML to xcatd | ||||
|         set_time_limit(900);            // Set 15 minutes timeout (for long running requests)  | ||||
|         set_time_limit(3600);            // Set 15 minutes timeout (for long running requests)  | ||||
|                                         // The default is 30 seconds which is too short for some requests | ||||
|          | ||||
|         // Turn on output buffering | ||||
|   | ||||
| @@ -70,6 +70,9 @@ sub process_request { | ||||
|         'deleteuser'          => \&web_deleteuser, | ||||
|         'mkzprofile'          => \&web_mkzprofile, | ||||
|         'rmzprofile'          => \&web_rmzprofile, | ||||
|         'mkippool'            => \&web_mkippool, | ||||
|         'rmippool'            => \&web_rmippool, | ||||
|         'lsippool'            => \&web_lsippool, | ||||
|         'updateosimage'       => \&web_updateosimage, | ||||
|         'rmosimage'           => \&web_rmosimage, | ||||
|         'updategroup'         => \&web_updategroup, | ||||
| @@ -2369,6 +2372,7 @@ sub web_mkzprofile() { | ||||
|     `echo "$var=$size" >> /var/opt/xcat/profiles/$profile.conf`; | ||||
|  | ||||
|     # Move directory entry into /var/opt/xcat/profiles from /var/tmp | ||||
|     `mkdir -p /var/opt/xcat/profiles`; | ||||
|     `mv /var/tmp/$profile.direct /var/opt/xcat/profiles`; | ||||
|  | ||||
|     my $info = "Profile successfully created/updated"; | ||||
| @@ -2394,6 +2398,60 @@ sub web_rmzprofile() { | ||||
|     $callback->( { info => $info } ); | ||||
| } | ||||
|  | ||||
| sub web_mkippool() { | ||||
|  | ||||
|     # Create group IP pool | ||||
|     my ( $request, $callback, $sub_req ) = @_; | ||||
|  | ||||
|     # Get profile | ||||
|     my $group = $request->{arg}->[1]; | ||||
|  | ||||
|     # Move directory entry into /var/opt/xcat/ippool from /var/tmp | ||||
|     `mkdir -p /var/opt/xcat/ippool`; | ||||
|     `mv /var/tmp/$group.pool /var/opt/xcat/ippool`; | ||||
|  | ||||
|     my $info = "IP pool successfully created/updated"; | ||||
|     $callback->( { info => $info } ); | ||||
| } | ||||
|  | ||||
| sub web_rmippool() { | ||||
|  | ||||
|     # Delete group IP pool | ||||
|     my ( $request, $callback, $sub_req ) = @_; | ||||
|  | ||||
|     # Get profile | ||||
|     my $group  = $request->{arg}->[1]; | ||||
|     my @groups = split( ',', $group ); | ||||
|  | ||||
|     # Delete IP pool under /var/opt/xcat/ippool | ||||
|     foreach (@groups) { | ||||
|         `rm -rf /var/opt/xcat/ippool/$_.pool`; | ||||
|     } | ||||
|  | ||||
|     my $info = "IP pool successfully deleted"; | ||||
|     $callback->( { info => $info } ); | ||||
| } | ||||
|  | ||||
| sub web_lsippool() { | ||||
|  | ||||
|     # List IP pool | ||||
|     my ( $request, $callback, $sub_req ) = @_; | ||||
|  | ||||
|     # Get profile | ||||
|     my $group  = $request->{arg}->[1]; | ||||
|      | ||||
|     # IP pool contained in /var/opt/xcat/ippool where a file exists per group | ||||
|     my $entries; | ||||
|     if ( !(`test -e /var/opt/xcat/ippool/$group.pool && echo Exists`) ) { | ||||
|         $entries = "No IP pool found!"; | ||||
|     } else { | ||||
|     	# List IP pool under /var/opt/xcat/ippool    | ||||
|         $entries = `cat /var/opt/xcat/ippool/$group.pool`; | ||||
|     } | ||||
|      | ||||
|     $callback->( { info => $entries } ); | ||||
| } | ||||
|  | ||||
| sub web_updateosimage() { | ||||
|  | ||||
|     # Add OS image to xCAT table | ||||
| @@ -2464,6 +2522,7 @@ sub web_rmgroup() { | ||||
|     # Delete user from xCAT passwd and policy tables | ||||
|     foreach (@names) { | ||||
|         `chtab -d node=$_ hosts`; | ||||
|         `rm -rf /var/opt/xcat/ippool/$_.pool`; | ||||
|     } | ||||
|  | ||||
|     my $info = "Group successfully deleted"; | ||||
|   | ||||
| @@ -40,7 +40,8 @@ sub process_request { | ||||
|         'clonezlinux' => \&clonezlinux, | ||||
|         'genhostip'   => \&genhostip, | ||||
|         'getmaxvm'    => \&getmaxvm, | ||||
|         'getuserprivilege' => \&getuserprivilege | ||||
|         'getuserprivilege' => \&getuserprivilege, | ||||
|         'lsgoldenimages' => \&lsgoldenimages | ||||
|     ); | ||||
|  | ||||
|     # Check if the request is authorized | ||||
| @@ -214,12 +215,13 @@ sub provzlinux { | ||||
|  | ||||
|     # Create VM | ||||
|     # e.g. webportal provzlinux [group] [hcp] [image] | ||||
|     my ($node, $ip, $base_digit) = gennodename( $callback, $group ); | ||||
|     if (!$base_digit) { | ||||
|         println( $callback, "(Error) Failed to generate node name" ); | ||||
|     # my ($node, $ip, $base_digit) = gennodename( $callback, $group ); | ||||
|     my ($node, $ip, $hostname) = findfreenode( $callback, $group ); | ||||
|     if (!$node) { | ||||
|         println( $callback, "Unable to find a free node, IP, and hostname for $group from the IP pool" ); | ||||
|         return; | ||||
|     } | ||||
|      | ||||
|          | ||||
|     my $userid = $node; | ||||
|  | ||||
|     # Set node definitions | ||||
| @@ -231,9 +233,9 @@ sub provzlinux { | ||||
|         $out = `mkdef -t node -o $node userid=$userid hcp=$hcp mgt=zvm groups=$group,all`; | ||||
|     }     | ||||
|     println( $callback, "$out" ); | ||||
|  | ||||
|      | ||||
|     # Set nodetype definitions | ||||
|     $out = `chtab node=$node noderes.netboot=zvm nodetype.nodetype=osi nodetype.provmethod=install nodetype.os=$os nodetype.arch=$arch nodetype.profile=$profile nodetype.comments="owner:$owner"`; | ||||
|     $out = `chtab node=$node hosts.ip=$ip hosts.hostnames=$hostname noderes.netboot=zvm nodetype.nodetype=osi nodetype.provmethod=install nodetype.os=$os nodetype.arch=$arch nodetype.profile=$profile nodetype.comments="owner:$owner"`; | ||||
|  | ||||
|     # Create user directory entry replacing LXUSR with user ID | ||||
|     # Use /opt/zhcp/conf/default.direct on zHCP as the template | ||||
| @@ -673,7 +675,13 @@ sub clonezlinux { | ||||
|          | ||||
|     # Create VM | ||||
|     # e.g. webportal provzlinux [group] [hcp] [image] | ||||
|     my ($node, $ip, $base_digit) = gennodename( $callback, $group ); | ||||
|     # my ($node, $ip, $base_digit) = gennodename( $callback, $group ); | ||||
|     my ($node, $ip, $hostname) = findfreenode( $callback, $group ); | ||||
|     if (!$node) { | ||||
|     	println( $callback, "Unable to find a free node, IP, and hostname for $group from the IP pool" ); | ||||
|         return;	 | ||||
|     } | ||||
|      | ||||
|     my $userid = $node; | ||||
|          | ||||
|     # Set node definitions | ||||
| @@ -681,7 +689,7 @@ sub clonezlinux { | ||||
|     println( $callback, "$out" ); | ||||
|  | ||||
|     # Set nodetype definitions | ||||
|     $out = `chtab node=$node noderes.netboot=zvm nodetype.nodetype=osi nodetype.provmethod=install nodetype.os=$os nodetype.arch=$arch nodetype.profile=$profile nodetype.comments="owner:$owner"`; | ||||
|     $out = `chtab node=$node hosts.ip=$ip hosts.hostnames=$hostname noderes.netboot=zvm nodetype.nodetype=osi nodetype.provmethod=install nodetype.os=$os nodetype.arch=$arch nodetype.profile=$profile nodetype.comments="owner:$owner"`; | ||||
|  | ||||
|     # Update hosts table and DNS | ||||
|     sleep(5); # Time needed to update /etc/hosts | ||||
| @@ -715,8 +723,9 @@ sub genhostip { | ||||
|     my ( $request, $callback, $sub_req ) = @_; | ||||
|     my $group = $request->{arg}->[1]; | ||||
|      | ||||
|     my ($node, $ip, $base_digit) = gennodename( $callback, $group ); | ||||
|     println( $callback, "$node: $ip" ); | ||||
|     # my ($node, $ip, $base_digit) = gennodename( $callback, $group ); | ||||
|     my ($node, $ip, $hostname) = findfreenode( $callback, $group ); | ||||
|     println( $callback, "$node: $ip, $hostname" ); | ||||
| } | ||||
|  | ||||
| sub getmaxvm { | ||||
| @@ -781,4 +790,86 @@ sub getuserprivilege { | ||||
|      | ||||
|     $callback->( { data => "Privilege: $privilege" } ); | ||||
| } | ||||
|  | ||||
| sub lsgoldenimages { | ||||
|     my ( $request, $callback, $sub_req ) = @_; | ||||
|      | ||||
|     # Find the golden image that can be cloned by searching nodetype table for nodetype.provmethod=clone | ||||
|     my $clones = ""; | ||||
|     my $comments = ""; | ||||
|     my $description = ""; | ||||
|     my @args; | ||||
|      | ||||
|     # Look in 'policy' table | ||||
|     my $tab = xCAT::Table->new( 'nodetype', -create => 1, -autocommit => 0 ); | ||||
|     my @results = $tab->getAllAttribsWhere( "provmethod='clone'", 'node', 'comments' ); | ||||
|     foreach (@results) { | ||||
|         if ($_->{'node'}) { | ||||
|         	$clones .= $_->{'node'} . ": "; | ||||
|         	 | ||||
|         	$comments = $_->{'comments'}; | ||||
|         	@args = split(';', $comments); | ||||
|         	foreach (@args) { | ||||
|         		if ($_ =~ m/description:/i) { | ||||
|         			$description = $_; | ||||
|         			$description =~ s/description://g; | ||||
|         			$description =~ s/\s*$//;    # Trim right | ||||
|                     $description =~ s/^\s*//;    # Trim left | ||||
|         		} else { | ||||
|         			$description = "No comments"; | ||||
|         		} | ||||
|         	} | ||||
|         	 | ||||
|         	$clones .= $description . ","; | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     # Delete last comma | ||||
|     $clones = substr($clones, 0, -1); | ||||
|          | ||||
|     $callback->( { data => $clones } ); | ||||
| } | ||||
|  | ||||
| sub findfreenode { | ||||
| 	# Generate node name based on given group | ||||
| 	my ( $callback, $group ) = @_; | ||||
|      | ||||
|     # IP pool contained in /var/opt/xcat/ippool where a file exists per group | ||||
|     if ( !(`test -e /var/opt/xcat/ippool/$group.pool && echo Exists`) ) { | ||||
|         return; | ||||
|     } | ||||
|      | ||||
|     # IP pool group format: node, IP, hostname | ||||
|     # It would look similar to: | ||||
|     #   ihost10,10.1.136.10,ihost10.endicott.ibm.com | ||||
|     #   ihost11,10.1.136.11,ihost11.endicott.ibm.com | ||||
|     #   ihost12,10.1.136.12,ihost12.endicott.ibm.com | ||||
|     my $node; | ||||
|     my $ipaddr; | ||||
|     my $hostname; | ||||
|      | ||||
|     my $out = `cat /var/opt/xcat/ippool/$group.pool | grep -v "#"`; | ||||
|     my @entries = split( /\n/, $out ); | ||||
|     if (@entries < 1) { | ||||
|     	return; | ||||
|     } | ||||
|      | ||||
|     my $found = 0; | ||||
|     foreach(@entries) { | ||||
|     	# Grab the 1st free entry found | ||||
|     	($node, $ipaddr, $hostname) = split(/,/, $_); | ||||
|     	if ($node && $ipaddr && $hostname) { | ||||
|     		 | ||||
|     		# Check against xCAT tables, /etc/hosts, and ping to see if hostname is already used | ||||
| 		    if (`nodels $node` || `cat /etc/hosts | grep "$ipaddr "` || !(`ping -c 4 $ipaddr` =~ m/100% packet loss/)) {         | ||||
| 		        next; | ||||
| 		    } else { | ||||
| 		    	$found = 1; | ||||
| 		    	return ($node, $ipaddr, $hostname); | ||||
| 		    } | ||||
|     	} | ||||
|     } | ||||
|  | ||||
|     return; | ||||
| } | ||||
| 1; | ||||
| @@ -3202,6 +3202,35 @@ sub cloneVM { | ||||
|     my $sourceId = $propVals->{'userid'}; | ||||
|     # Capitalize user ID | ||||
|     $sourceId =~ tr/a-z/A-Z/; | ||||
|      | ||||
|     # Get operating system, e.g. sles11sp2 or rhel6.2 | ||||
|     @propNames = ( 'os' ); | ||||
|     $propVals = xCAT::zvmUtils->getNodeProps( 'nodetype', $sourceNode, @propNames ); | ||||
|     my $srcOs = $propVals->{'os'}; | ||||
|      | ||||
|     # Set IP address | ||||
|     my $sourceIp = xCAT::zvmUtils->getIp($sourceNode); | ||||
|      | ||||
|     # Get networks in 'networks' table | ||||
|     my $netEntries = xCAT::zvmUtils->getAllTabEntries('networks'); | ||||
|     my $srcNetwork = ""; | ||||
|     my $srcMask; | ||||
|     foreach (@$netEntries) { | ||||
|         # Get source network and mask | ||||
|         $srcNetwork = $_->{'net'}; | ||||
|         $srcMask = $_->{'mask'}; | ||||
|                  | ||||
|         # If the host IP address is in this subnet, return | ||||
|         if (xCAT::NetworkUtils->ishostinsubnet($sourceIp, $srcMask, $srcNetwork)) { | ||||
|      | ||||
|             # Exit loop | ||||
|             last; | ||||
|         } else { | ||||
|             $srcNetwork = ""; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     xCAT::zvmUtils->printSyslog("cloneVM() srcHcp:$srcHcp sourceId:$sourceId srcOs:$srcOs srcNetwork:$srcNetwork srcMask:$srcMask"); | ||||
|  | ||||
|     foreach (@nodes) { | ||||
|         xCAT::zvmUtils->printLn( $callback, "$_: Cloning $sourceNode" ); | ||||
| @@ -3223,6 +3252,18 @@ sub cloneVM { | ||||
|             xCAT::zvmUtils->printLn( $callback, "$_: (Error) Missing source user ID" ); | ||||
|             return; | ||||
|         } | ||||
|          | ||||
|         # Exit if missing source operating system | ||||
|         if ( !$srcOs ) { | ||||
|             xCAT::zvmUtils->printLn( $callback, "$_: (Error) Missing source operating system" ); | ||||
|             return; | ||||
|         } | ||||
|          | ||||
|         # Exit if missing source operating system | ||||
|         if ( !$sourceIp || !$srcNetwork || !$srcMask ) { | ||||
|             xCAT::zvmUtils->printLn( $callback, "$_: (Error) Missing source IP, network, or mask" ); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         # Get target node | ||||
|         @propNames = ( 'hcp', 'userid' ); | ||||
| @@ -3279,6 +3320,8 @@ sub cloneVM { | ||||
|             # Generate new MACID | ||||
|             $out = xCAT::zvmUtils->generateMacId($::SUDOER, $tgtHcp); | ||||
|         } | ||||
|          | ||||
|         xCAT::zvmUtils->printSyslog("cloneVM() tgtHcp:$tgtHcp tgtId:$tgtId targetMac:$targetMac macId:$macId"); | ||||
|     } | ||||
|  | ||||
|     #*** Link source disks *** | ||||
| @@ -3286,11 +3329,8 @@ sub cloneVM { | ||||
|     my @words; | ||||
|     my $addr; | ||||
|     my $type; | ||||
|     my $srcMultiPw; | ||||
|     my $linkAddr; | ||||
|  | ||||
|     # Load vmcp module | ||||
|     xCAT::zvmCPUtils->loadVmcp($::SUDOER, $sourceNode); | ||||
|     my $i; | ||||
|  | ||||
|     # Hash table of source disk addresses | ||||
|     # $srcLinkAddr[$addr] = $linkAddr | ||||
| @@ -3300,15 +3340,21 @@ sub cloneVM { | ||||
|     # Hash table of source disk type | ||||
|     # $srcLinkAddr[$addr] = $type | ||||
|     my %srcDiskType; | ||||
|  | ||||
|     my @srcDisks = xCAT::zvmUtils->getMdisks( $callback, $::SUDOER, $sourceNode ); | ||||
|          | ||||
|     # Get details about source disks | ||||
|     # Output is similar to: | ||||
|     #   MDISK=VDEV=0100 DEVTYPE=3390 START=0001 COUNT=10016 VOLID=EMC2C4 MODE=MR         | ||||
|     $out = `ssh $::SUDOER\@$srcHcp "$::SUDO $::DIR/smcli Image_Definition_Query_DM -T $sourceId -k MDISK"`; | ||||
|     xCAT::zvmUtils->printSyslog("cloneVM() smcli Image_Definition_Query_DM -T $sourceId -k MDISK"); | ||||
|     xCAT::zvmUtils->printSyslog("cloneVM() $out"); | ||||
|     my $srcDiskDet = xCAT::zvmUtils->trimStr($out); | ||||
|     foreach (@srcDisks) { | ||||
|  | ||||
|         # Get disk address | ||||
|         @words      = split( ' ', $_ ); | ||||
|         $addr       = $words[1]; | ||||
|         $type       = $words[2]; | ||||
|         $srcMultiPw = $words[9]; | ||||
|  | ||||
|         # Add 0 in front if address length is less than 4 | ||||
|         while (length($addr) < 4) { | ||||
| @@ -3320,10 +3366,20 @@ sub cloneVM { | ||||
|  | ||||
|         # Get disk size (cylinders or blocks) | ||||
|         # ECKD or FBA disk | ||||
|         if ( $type eq '3390' || $type eq '9336' ) { | ||||
|             $out                = `ssh -o ConnectTimeout=5 $::SUDOER\@$sourceNode "/sbin/vmcp q v dasd" | grep "DASD $addr"`; | ||||
|             @words              = split( ' ', $out ); | ||||
|             $srcDiskSize{$addr} = xCAT::zvmUtils->trimStr( $words[5] ); | ||||
|         if ( $type eq '3390' || $type eq '9336' ) {                 | ||||
| 		    my @lines = split( '\n', $srcDiskDet ); | ||||
| 		     | ||||
| 		    # Loop through each line | ||||
| 		    for ( $i = 0 ; $i < @lines ; $i++ ) { | ||||
| 		        $lines[$i] =~ s/MDISK=//g; | ||||
| 		         | ||||
| 		        # Extract NIC address | ||||
| 		        @words = ($lines[$i] =~ m/=(\S+)/g); | ||||
| 		        my $srcDiskAddr = $words[0]; | ||||
|  | ||||
|                 $srcDiskSize{$srcDiskAddr} = $words[3]; | ||||
|                 xCAT::zvmUtils->printSyslog("cloneVM() addr:$addr type:$type srcDiskAddr:$srcDiskAddr srcDiskSize:$words[3]"); | ||||
| 		    } | ||||
|         } | ||||
|  | ||||
|         # If source disk is not linked | ||||
| @@ -3352,7 +3408,7 @@ sub cloneVM { | ||||
|             foreach (@nodes) { | ||||
|                 xCAT::zvmUtils->printLn( $callback, "$_: Linking source disk ($addr) as ($linkAddr)" ); | ||||
|             } | ||||
|             $out = `ssh -o ConnectTimeout=5 $::SUDOER\@$srcHcp "$::SUDO /sbin/vmcp link $sourceId $addr $linkAddr RR $srcMultiPw"`; | ||||
|             $out = `ssh -o ConnectTimeout=5 $::SUDOER\@$srcHcp "$::SUDO /sbin/vmcp link $sourceId $addr $linkAddr RR"`; | ||||
|  | ||||
|             if ( $out =~ m/not linked/i ) { | ||||
|                 # Do nothing | ||||
| @@ -3385,13 +3441,19 @@ sub cloneVM { | ||||
|      | ||||
|     # Get the NICDEF address of the network on the source node | ||||
|     my @tmp; | ||||
|     my $i; | ||||
|     my $hcpNicAddr = ''; | ||||
|     my $srcNicAddr = ''; | ||||
|     my $hcpNetName = ''; | ||||
|  | ||||
|     # Find the NIC address | ||||
|     xCAT::zvmCPUtils->loadVmcp($::SUDOER, $sourceNode); | ||||
|     $out = `ssh $::SUDOER\@$sourceNode "/sbin/vmcp q v nic"`; | ||||
|     $out = `ssh $::SUDOER\@$srcHcp "$::SUDO $::DIR/smcli Image_Definition_Query_DM -T $sourceId -k NICDEF"`; | ||||
|     xCAT::zvmUtils->printSyslog("cloneVM() smcli Image_Definition_Query_DM -T $sourceId -k NICDEF"); | ||||
|     xCAT::zvmUtils->printSyslog("cloneVM() $out"); | ||||
|     # Output is similar to: | ||||
|     #   NICDEF_PROFILE=VDEV=0800 TYPE=QDIO LAN=SYSTEM SWITCHNAME=VSW2 | ||||
|     #   NICDEF=VDEV=0900 TYPE=QDIO DEVICES=3 LAN=SYSTEM SWITCHNAME=GLAN1 | ||||
|     #   NICDEF=VDEV=0A00 TYPE=QDIO DEVICES=3 LAN=SYSTEM SWITCHNAME=VSW2 | ||||
|      | ||||
|     my @lines = split( '\n', $out ); | ||||
|      | ||||
|     # Loop through each line | ||||
| @@ -3400,48 +3462,48 @@ sub cloneVM { | ||||
|         # Loop through each network name | ||||
|         foreach (@hcpNets) { | ||||
|             # If the network is found | ||||
|             if ( $lines[$i] =~ m/ $_/i ) { | ||||
|             if ( $lines[$i] =~ m/SWITCHNAME=$_/i ) { | ||||
|                 # Save network name | ||||
|                 $hcpNetName = $_; | ||||
|                  | ||||
|                 # Get NIC address | ||||
|                 $line       = xCAT::zvmUtils->trimStr( $lines[ $i - 1 ] ); | ||||
|                 @words      = split( ' ', $line ); | ||||
|                 @tmp        = split( /\./, $words[1] ); | ||||
|                 $hcpNicAddr = $tmp[0]; | ||||
|                 $lines[$i] =~ s/NICDEF_PROFILE=//g; | ||||
|                 $lines[$i] =~ s/NICDEF=//g; | ||||
|                  | ||||
|                 # Extract NIC address | ||||
|                 @words = ($lines[$i] =~ m/=(\S+)/g); | ||||
|                 $srcNicAddr = $words[0]; | ||||
|                 xCAT::zvmUtils->printSyslog("cloneVM() hcpNetName:$hcpNetName srcNicAddr:$srcNicAddr"); | ||||
|                  | ||||
|                 # Grab only the 1st match     | ||||
|                 last; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|          | ||||
|      | ||||
|     # If no network name is found, exit | ||||
|     if (!$hcpNetName || !$hcpNicAddr) { | ||||
|     if (!$hcpNetName || !$srcNicAddr) { | ||||
|         #*** Detatch source disks *** | ||||
|         for $addr ( keys %srcLinkAddr ) { | ||||
|             $linkAddr = $srcLinkAddr{$addr}; | ||||
|      | ||||
|             # Disable and detatch source disk | ||||
|             $out = xCAT::zvmUtils->disableEnableDisk( $::SUDOER, $srcHcp, "-d", $linkAddr ); | ||||
|             $out = `ssh -o ConnectTimeout=5 $::SUDOER\@$srcHcp "$::SUDO /sbin/vmcp det $linkAddr"`; | ||||
|             $out = `ssh -o ConnectTimeout=5 $::SUDOER\@$srcHcp "$::SUDO /sbin/vmcp det $linkAddr"`;             | ||||
|             foreach (@nodes) { | ||||
|                 xCAT::zvmUtils->printLn( $callback, "$_: Detatching source disk ($addr) at ($linkAddr)" ); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         foreach (@nodes) { | ||||
|             xCAT::zvmUtils->printLn( $callback, "$_: (Error) No suitable network device found in user directory entry" ); | ||||
|             xCAT::zvmUtils->printLn( $callback, "$_: (Solution) Verify that the node has one of the following network devices: @hcpNets" ); | ||||
|             xCAT::zvmUtils->printLn( $callback, "$_: Detatching source disk ($addr) at ($linkAddr)" ); | ||||
|         } | ||||
|          | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     # Get VSwitch of source node (if any) | ||||
|     my @srcVswitch = xCAT::zvmCPUtils->getVswitchId($::SUDOER, $sourceNode); | ||||
|  | ||||
|     # Get device address that is the root partition (/) | ||||
|     my $srcRootPartAddr = xCAT::zvmUtils->getRootDeviceAddr($::SUDOER, $sourceNode); | ||||
|  | ||||
|     # Get source node OS | ||||
|     my $srcOs = xCAT::zvmUtils->getOs($::SUDOER, $sourceNode); | ||||
|     # Get vSwitch of source node (if any) | ||||
|     my @srcVswitch = xCAT::zvmCPUtils->getVswitchId($::SUDOER, $srcHcp); | ||||
|  | ||||
|     # Get source MAC address in 'mac' table | ||||
|     my $srcMac; | ||||
| @@ -3452,35 +3514,7 @@ sub cloneVM { | ||||
|         # Get MAC address | ||||
|         $srcMac = $propVals->{'mac'}; | ||||
|     } | ||||
|  | ||||
|     # Get network configuration file | ||||
|     # Location of this file depends on the OS | ||||
|     my $srcIfcfg = xCAT::zvmUtils->getIfcfgByNic( $::SUDOER, $sourceNode, "0.0." . $hcpNicAddr ); | ||||
|     if (!$srcIfcfg) { | ||||
|          | ||||
|         #*** Detatch source disks *** | ||||
|         for $addr ( keys %srcLinkAddr ) { | ||||
|             $linkAddr = $srcLinkAddr{$addr}; | ||||
|      | ||||
|             # Disable and detatch source disk | ||||
|             $out = xCAT::zvmUtils->disableEnableDisk( $::SUDOER, $srcHcp, "-d", $linkAddr ); | ||||
|             $out = `ssh -o ConnectTimeout=5 $::SUDOER\@$srcHcp "$::SUDO /sbin/vmcp det $linkAddr"`; | ||||
|         } | ||||
|          | ||||
|         foreach (@nodes) { | ||||
|             xCAT::zvmUtils->printLn( $callback, "$_: (Error) No suitable network configuration file found in Linux directory" ); | ||||
|             xCAT::zvmUtils->printLn( $callback, "$_: Detatching source disk ($addr) at ($linkAddr)" ); | ||||
|         } | ||||
|          | ||||
|         return; | ||||
|     } | ||||
|      | ||||
|     # Get source hardware configuration (SUSE only) | ||||
|     my $srcHwcfg = ''; | ||||
|     if ( $srcOs =~ m/SUSE/i ) { | ||||
|         $srcHwcfg = xCAT::zvmUtils->getHwcfg($::SUDOER, $sourceNode); | ||||
|     } | ||||
|  | ||||
|     # Get user entry of source node | ||||
|     my $srcUserEntry = "/tmp/$sourceNode.txt"; | ||||
|     $out = `rm $srcUserEntry`; | ||||
| @@ -3493,13 +3527,18 @@ sub cloneVM { | ||||
|     if ( $out =~ m/USER $sourceId/i ) { | ||||
|  | ||||
|         # Turn off source node | ||||
|         $out = `ssh -o ConnectTimeout=10 $sourceNode "shutdown -h now"`; | ||||
|         sleep(90);    # Wait 1.5 minutes before logging user off | ||||
|         if (`pping $sourceNode` =~ m/ ping/i) { | ||||
|             $out = `ssh -o ConnectTimeout=10 $sourceNode "shutdown -h now"`; | ||||
|             sleep(90);    # Wait 1.5 minutes before logging user off | ||||
|                          | ||||
| 	        foreach (@nodes) { | ||||
| 	            xCAT::zvmUtils->printLn( $callback, "$_: Shutting down $sourceNode" ); | ||||
| 	        } | ||||
|         } | ||||
|          | ||||
|         $out = `ssh $::SUDOER\@$srcHcp "$::SUDO $::DIR/smcli Image_Deactivate -T $sourceId -f IMMED"`; | ||||
|         foreach (@nodes) { | ||||
|             xCAT::zvmUtils->printLn( $callback, "$_: $out" ); | ||||
|         } | ||||
|         xCAT::zvmUtils->printSyslog("cloneVM() smcli Image_Deactivate -T $sourceId -f IMMED"); | ||||
|         xCAT::zvmUtils->printSyslog("cloneVM() $out"); | ||||
|  | ||||
|         #*** Clone source node *** | ||||
|         # Remove flashcopy lock (if any) | ||||
| @@ -3516,8 +3555,7 @@ sub cloneVM { | ||||
|             elsif ( $pid == 0 ) { | ||||
|                 clone( | ||||
|                     $callback, $_, $args, \@srcDisks, \%srcLinkAddr, \%srcDiskSize, \%srcDiskType,  | ||||
|                     $hcpNicAddr, $hcpNetName, \@srcVswitch, $srcOs, $srcMac, $srcRootPartAddr, $srcIfcfg,  | ||||
|                     $srcHwcfg | ||||
|                     $srcNicAddr, $hcpNetName, \@srcVswitch, $srcOs, $srcMac, $netEntries, $sourceIp, $srcNetwork, $srcMask | ||||
|                 ); | ||||
|  | ||||
|                 # Exit process | ||||
| @@ -3568,12 +3606,6 @@ sub cloneVM { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     # Turn back on source node | ||||
|     $out = `ssh $::SUDOER\@$srcHcp "$::SUDO $::DIR/smcli Image_Activate -T $sourceId"`; | ||||
|     foreach (@nodes) { | ||||
|         xCAT::zvmUtils->printLn( $callback, "$_: $out" ); | ||||
|     } | ||||
|  | ||||
|     #*** Done *** | ||||
|     foreach (@nodes) { | ||||
|         xCAT::zvmUtils->printLn( $callback, "$_: Done" ); | ||||
| @@ -3603,8 +3635,8 @@ sub cloneVM { | ||||
|                     Path to hardware configuration file (SUSE only) | ||||
|     Returns     : Nothing | ||||
|     Example     : clone($callback, $_, $args, \@srcDisks, \%srcLinkAddr, \%srcDiskSize,  | ||||
|                     $hcpNicAddr, $hcpNetName, \@srcVswitch, $srcOs, $srcMac,  | ||||
|                     $srcRootPartAddr, $srcIfcfg, $srcHwcfg); | ||||
|                     $srcNicAddr, $hcpNetName, \@srcVswitch, $srcOs, $srcMac, $netEntries,  | ||||
|                     $sourceIp, $srcNetwork, $srcMask); | ||||
|      | ||||
| =cut | ||||
|  | ||||
| @@ -3614,7 +3646,7 @@ sub clone { | ||||
|     # Get inputs | ||||
|     my ( | ||||
|         $callback, $tgtNode, $args, $srcDisksRef, $srcLinkAddrRef, $srcDiskSizeRef, $srcDiskTypeRef,  | ||||
|         $hcpNicAddr, $hcpNetName, $srcVswitchRef, $srcOs, $srcMac, $srcRootPartAddr, $srcIfcfg, $srcHwcfg | ||||
|         $srcNicAddr, $hcpNetName, $srcVswitchRef, $srcOs, $srcMac, $netEntries, $sourceIp, $srcNetwork, $srcMask | ||||
|       ) | ||||
|       = @_; | ||||
|  | ||||
| @@ -3667,7 +3699,7 @@ sub clone { | ||||
|         xCAT::zvmUtils->printLn( $callback, "$tgtNode: (Solution) Set the source and target HCP appropriately in the zvm table" ); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|      | ||||
|     # Get target IP from /etc/hosts | ||||
|     `makehosts`; | ||||
|     sleep(5); | ||||
| @@ -3677,6 +3709,7 @@ sub clone { | ||||
|         xCAT::zvmUtils->printLn( $callback, "$tgtNode: (Solution) Verify that the node's IP address is specified in the hosts table and then run makehosts" ); | ||||
|         return; | ||||
|     } | ||||
|     xCAT::zvmUtils->printSyslog("clone() hcp:$hcp tgtUserId:$tgtUserId targetIp:$targetIp"); | ||||
|  | ||||
|     my $out; | ||||
|     my @lines; | ||||
| @@ -3702,6 +3735,7 @@ sub clone { | ||||
|         xCAT::zvmUtils->printLn( $callback, "$tgtNode: (Error) Missing disk pool. Please specify one." ); | ||||
|         return; | ||||
|     } | ||||
|     xCAT::zvmUtils->printSyslog("clone() pool:$pool"); | ||||
|  | ||||
|     # Get multi password | ||||
|     # It is Ok not have a password | ||||
| @@ -3710,9 +3744,6 @@ sub clone { | ||||
|         $tgtPw = $inputs{"pw"}; | ||||
|     } | ||||
|  | ||||
|     # Set IP address | ||||
|     my $sourceIp = xCAT::zvmUtils->getIp($sourceNode); | ||||
|  | ||||
|     # Save user directory entry as /tmp/hostname.txt, e.g. /tmp/gpok3.txt | ||||
|     # The source user entry is retrieved in cloneVM() | ||||
|     my $userEntry    = "/tmp/$tgtNode.txt"; | ||||
| @@ -3795,6 +3826,8 @@ sub clone { | ||||
|             xCAT::zvmUtils->printLn( $callback, "$tgtNode: Trying again ($try) to create user directory entry" ); | ||||
|         } | ||||
|         $out = `ssh $::SUDOER\@$hcp "$::SUDO $::DIR/smcli Image_Create_DM -T $tgtUserId -f $userEntry"`; | ||||
|         xCAT::zvmUtils->printSyslog("clone() smcli Image_Create_DM -T $tgtUserId -f $userEntry"); | ||||
|         xCAT::zvmUtils->printSyslog("clone() $out"); | ||||
|  | ||||
|         # Check if user entry is created | ||||
|         $out = `ssh $::SUDOER\@$hcp "$::SUDO $::DIR/smcli Image_Query_DM -T $tgtUserId" | sed '\$d'`; | ||||
| @@ -3847,7 +3880,6 @@ sub clone { | ||||
|     my $type; | ||||
|     my $mode; | ||||
|     my $cyl; | ||||
|     my $srcMultiPw; | ||||
|     foreach (@srcDisks) { | ||||
|  | ||||
|         # Get disk address | ||||
| @@ -3856,7 +3888,6 @@ sub clone { | ||||
|         push( @tgtDisks, $addr ); | ||||
|         $type       = $words[2]; | ||||
|         $mode       = $words[6]; | ||||
|         $srcMultiPw = $words[9]; | ||||
|          | ||||
|         # Add 0 in front if address length is less than 4 | ||||
|         while (length($addr) < 4) { | ||||
| @@ -3879,7 +3910,9 @@ sub clone { | ||||
|                     xCAT::zvmUtils->printLn( $callback, "$tgtNode: Trying again ($try) to add minidisk ($addr)" ); | ||||
|                 } | ||||
|                 $out = `ssh $::SUDOER\@$hcp "$::SUDO $::DIR/smcli Image_Disk_Create_DM -T $tgtUserId -v $addr -t 3390 -a AUTOG -r $pool -u 1 -z $cyl -m $mode -f 1 -R $tgtPw -W $tgtPw -M $tgtPw"`; | ||||
|  | ||||
|                 xCAT::zvmUtils->printSyslog("clone() smcli Image_Disk_Create_DM -T $tgtUserId -v $addr -t 3390 -a AUTOG -r $pool -u 1 -z $cyl -m $mode -f 1 -R $tgtPw -W $tgtPw -M $tgtPw"); | ||||
|                 xCAT::zvmUtils->printSyslog("clone() $out"); | ||||
|                  | ||||
|                 # Check output | ||||
|                 $rc = xCAT::zvmUtils->checkOutput( $callback, $out ); | ||||
|                 if ( $rc == -1 ) { | ||||
| @@ -3920,7 +3953,9 @@ sub clone { | ||||
|                     xCAT::zvmUtils->printLn( $callback, "$tgtNode: Trying again ($try) to add minidisk ($addr)" ); | ||||
|                 } | ||||
|                 $out = `ssh $::SUDOER\@$hcp "$::SUDO $::DIR/smcli Image_Disk_Create_DM -T $tgtUserId -v $addr -t 9336 -a AUTOG -r $pool -u 1 -z $blks -m $mode -f 1 -R $tgtPw -W $tgtPw -M $tgtPw"`; | ||||
|  | ||||
|                 xCAT::zvmUtils->printSyslog("clone() smcli Image_Disk_Create_DM -T $tgtUserId -v $addr -t 9336 -a AUTOG -r $pool -u 1 -z $blks -m $mode -f 1 -R $tgtPw -W $tgtPw -M $tgtPw"); | ||||
|                 xCAT::zvmUtils->printSyslog("clone() $out"); | ||||
|                  | ||||
|                 # Check output | ||||
|                 $rc = xCAT::zvmUtils->checkOutput( $callback, $out ); | ||||
|                 if ( $rc == -1 ) { | ||||
| @@ -3953,6 +3988,8 @@ sub clone { | ||||
|  | ||||
|         # Get disks within user entry | ||||
|         $out = `ssh $::SUDOER\@$hcp "$::SUDO $::DIR/smcli Image_Query_DM -T $tgtUserId" | sed '\$d' | grep "MDISK"`; | ||||
|         xCAT::zvmUtils->printSyslog("clone() smcli Image_Query_DM -T $tgtUserId | grep MDISK"); | ||||
|         xCAT::zvmUtils->printSyslog("clone() $out"); | ||||
|         @disks = split( '\n', $out ); | ||||
|         xCAT::zvmUtils->printLn( $callback, "$tgtNode: Disks added (" . @tgtDisks . "). Disks in user entry (" . @disks . ")" ); | ||||
|  | ||||
| @@ -4046,6 +4083,7 @@ sub clone { | ||||
|             xCAT::zvmUtils->printLn( $callback, "$tgtNode: Copying source disk ($srcAddr) to target disk ($tgtAddr) using FLASHCOPY" ); | ||||
|             if (xCAT::zvmUtils->smapi4xcat($::SUDOER, $hcp)) { | ||||
|                  $out = xCAT::zvmCPUtils->smapiFlashCopy($::SUDOER, $hcp, $sourceId, $srcAddr, $tgtUserId, $tgtAddr); | ||||
|                  xCAT::zvmUtils->printSyslog("clone() smapiFlashCopy:$out"); | ||||
|                   | ||||
|                  # Exit if flashcopy completed successfully | ||||
|                  # Otherwsie, try CP FLASHCOPY | ||||
| @@ -4081,6 +4119,7 @@ sub clone { | ||||
|          | ||||
|                     # Flashcopy source disk | ||||
|                     $out = xCAT::zvmCPUtils->flashCopy( $::SUDOER, $hcp, $srcAddr, $tgtAddr ); | ||||
|                     xCAT::zvmUtils->printSyslog("clone() flashCopy:$out"); | ||||
|                     $rc = xCAT::zvmUtils->checkOutput( $callback, $out ); | ||||
|                     if ( $rc == -1 ) { | ||||
|                         xCAT::zvmUtils->printLn( $callback, "$tgtNode: $out" ); | ||||
| @@ -4120,6 +4159,7 @@ sub clone { | ||||
|             if ($tgtDiskType eq '3390') { | ||||
|                 xCAT::zvmUtils->printLn( $callback, "$tgtNode: Formating target disk ($tgtAddr)" ); | ||||
|                 $out = `ssh $::SUDOER\@$hcp "$::SUDO /sbin/dasdfmt -b 4096 -y -f /dev/$tgtDevNode"`; | ||||
|                 xCAT::zvmUtils->printSyslog("clone() dasdfmt -b 4096 -y -f /dev/$tgtDevNode"); | ||||
|  | ||||
|                 # Check for errors | ||||
|                 $rc = xCAT::zvmUtils->checkOutput( $callback, $out ); | ||||
| @@ -4134,19 +4174,19 @@ sub clone { | ||||
|      | ||||
|                 # Sleep 2 seconds to let the system settle | ||||
|                 sleep(2); | ||||
|                  | ||||
|                 # Automatically create a partition using the entire disk | ||||
|                 xCAT::zvmUtils->printLn( $callback, "$tgtNode: Creating a partition using the entire disk ($tgtDevNode)" ); | ||||
|                 $out = `ssh $::SUDOER\@$hcp "$::SUDO /sbin/fdasd -a /dev/$tgtDevNode"`; | ||||
|                  | ||||
|                                  | ||||
|                 # Copy source disk to target disk | ||||
|                 xCAT::zvmUtils->printLn( $callback, "$tgtNode: Copying source disk ($srcAddr) to target disk ($tgtAddr)" ); | ||||
|                 $out = `ssh $::SUDOER\@$hcp "$::SUDO /bin/dd if=/dev/$srcDevNode of=/dev/$tgtDevNode bs=4096 oflag=sync"`; | ||||
|                 xCAT::zvmUtils->printSyslog("clone() dd if=/dev/$srcDevNode of=/dev/$tgtDevNode bs=4096 oflag=sync"); | ||||
|                 xCAT::zvmUtils->printSyslog("clone() $out"); | ||||
|             } else { | ||||
|                 # Copy source disk to target disk | ||||
|                 # Block size = 512 | ||||
|                 xCAT::zvmUtils->printLn( $callback, "$tgtNode: Copying source disk ($srcAddr) to target disk ($tgtAddr)" ); | ||||
|                 $out = `ssh $::SUDOER\@$hcp "$::SUDO /bin/dd if=/dev/$srcDevNode of=/dev/$tgtDevNode bs=512 oflag=sync"`; | ||||
|                 xCAT::zvmUtils->printSyslog("clone() dd if=/dev/$srcDevNode of=/dev/$tgtDevNode bs=512 oflag=sync"); | ||||
|                 xCAT::zvmUtils->printSyslog("clone() $out"); | ||||
|                  | ||||
|                 # Force Linux to re-read partition table | ||||
|                 xCAT::zvmUtils->printLn( $callback, "$tgtNode: Forcing Linux to re-read partition table" ); | ||||
| @@ -4174,6 +4214,14 @@ EOM"`; | ||||
|             # Sleep 2 seconds to let the system settle | ||||
|             sleep(2); | ||||
|         } | ||||
|          | ||||
|         # Re-scan partition table | ||||
|         $out = `ssh $::SUDOER\@$hcp "$::SUDO /usr/sbin/partprobe /dev/$tgtDevNode"`;  # SLES | ||||
|         xCAT::zvmUtils->printSyslog("clone() /usr/sbin/partprobe /dev/$tgtDevNode"); | ||||
|         xCAT::zvmUtils->printSyslog("clone() $out"); | ||||
|         $out = `ssh $::SUDOER\@$hcp "$::SUDO /sbin/partprobe /dev/$tgtDevNode"`;  # RHEL | ||||
|         xCAT::zvmUtils->printSyslog("clone() /sbin/partprobe /dev/$tgtDevNode"); | ||||
|         xCAT::zvmUtils->printSyslog("clone() $out"); | ||||
|  | ||||
|         # Disable and enable target disk | ||||
|         $out = xCAT::zvmUtils->disableEnableDisk( $::SUDOER, $hcp, "-d", $tgtAddr ); | ||||
| @@ -4182,87 +4230,142 @@ EOM"`; | ||||
|         # Determine target device node (it might have changed) | ||||
|         $tgtDevNode = xCAT::zvmUtils->getDeviceNode($::SUDOER, $hcp, $tgtAddr); | ||||
|  | ||||
|         # Get disk address that is the root partition (/) | ||||
|         if ( $_ eq $srcRootPartAddr ) { | ||||
|  | ||||
|             # Mount target disk | ||||
|             my $cloneMntPt = "/mnt/$tgtUserId"; | ||||
|         # Mount device and check if it is the root partition | ||||
|         # If it is, then modify the network configuration | ||||
|          | ||||
|         # Mount target disk | ||||
|         my $cloneMntPt = "/mnt/$tgtUserId"; | ||||
|              | ||||
|             # Disk can contain more than 1 partition. Find the right one (not swap) | ||||
|             $out = `ssh $::SUDOER\@$hcp "$::SUDO /usr/bin/file -s /dev/$tgtDevNode*" | grep -v swap | grep -o "$tgtDevNode\[0-9\]"`; | ||||
|             my @tgtDevNodes = split( "\n", $out ); | ||||
|             my $iTgtDevNode = 0; | ||||
|             $tgtDevNode = xCAT::zvmUtils->trimStr($tgtDevNodes[$iTgtDevNode]); | ||||
|         # Disk can contain more than 1 partition. Find the right one (not swap) | ||||
|         $out = `ssh $::SUDOER\@$hcp "$::SUDO /usr/bin/file -s /dev/$tgtDevNode*"`; | ||||
|         xCAT::zvmUtils->printSyslog("clone() file -s /dev/$tgtDevNode*"); | ||||
|         xCAT::zvmUtils->printSyslog("clone() $out"); | ||||
|          | ||||
|         $out = `ssh $::SUDOER\@$hcp "$::SUDO /usr/bin/file -s /dev/$tgtDevNode*" | grep -v swap | grep -o "$tgtDevNode\[0-9\]"`; | ||||
|         xCAT::zvmUtils->printSyslog("clone() file -s /dev/$tgtDevNode* | grep -v swap | grep -o $tgtDevNode\[0-9\]"); | ||||
|         xCAT::zvmUtils->printSyslog("clone() $out"); | ||||
|          | ||||
|         my @tgtDevNodes = split( "\n", $out ); | ||||
|         my $iTgtDevNode = 0; | ||||
|         $tgtDevNode = xCAT::zvmUtils->trimStr($tgtDevNodes[$iTgtDevNode]); | ||||
|              | ||||
|             xCAT::zvmUtils->printLn( $callback, "$tgtNode: Mounting /dev/$tgtDevNode to $cloneMntPt" ); | ||||
|         xCAT::zvmUtils->printLn( $callback, "$tgtNode: Mounting /dev/$tgtDevNode to $cloneMntPt" ); | ||||
|  | ||||
|             # Check the disk is mounted | ||||
|             $try = 5; | ||||
|             while ( !(`ssh $::SUDOER\@$hcp "$::SUDO ls $cloneMntPt/etc/"`) && $try > 0 ) { | ||||
|                 $out = `ssh $::SUDOER\@$hcp "$::SUDO mkdir -p $cloneMntPt"`; | ||||
|                 $out = `ssh $::SUDOER\@$hcp "$::SUDO mount /dev/$tgtDevNode $cloneMntPt"`; | ||||
|         # Check the disk is mounted | ||||
|         $try = 5; | ||||
|         while ( !(`ssh $::SUDOER\@$hcp "$::SUDO ls $cloneMntPt"`) && $try > 0 ) { | ||||
|             $out = `ssh $::SUDOER\@$hcp "$::SUDO mkdir -p $cloneMntPt"`; | ||||
|             $out = `ssh $::SUDOER\@$hcp "$::SUDO mount /dev/$tgtDevNode $cloneMntPt"`; | ||||
|             xCAT::zvmUtils->printSyslog("clone() mount /dev/$tgtDevNode $cloneMntPt"); | ||||
|  | ||||
|                 # If more than 1 partition, try other partitions | ||||
|                 if (@tgtDevNodes > 1 && $iTgtDevNode < @tgtDevNodes) { | ||||
|                     $iTgtDevNode++; | ||||
|                     $tgtDevNode = xCAT::zvmUtils->trimStr($tgtDevNodes[$iTgtDevNode]); | ||||
|                 } | ||||
|             # If more than 1 partition, try other partitions | ||||
|             if (@tgtDevNodes > 1 && $iTgtDevNode < @tgtDevNodes) { | ||||
|                 $iTgtDevNode++; | ||||
|                 $tgtDevNode = xCAT::zvmUtils->trimStr($tgtDevNodes[$iTgtDevNode]); | ||||
|             } | ||||
|                  | ||||
|                 # Wait before trying again | ||||
|                 sleep(10); | ||||
|                 $try = $try - 1; | ||||
|             } | ||||
|  | ||||
|             # If the disk is not mounted | ||||
|             if ( !(`ssh $::SUDOER\@$hcp "$::SUDO ls $cloneMntPt/etc/"`) ) { | ||||
|                 xCAT::zvmUtils->printLn( $callback, "$tgtNode: (Error) Could not mount /dev/$tgtDevNode" ); | ||||
|  | ||||
|                 # Flush disk | ||||
|                 $out = `ssh $::SUDOER\@$hcp "$::SUDO sync"`; | ||||
|  | ||||
|                 # Unmount disk | ||||
|                 $out = `ssh $::SUDOER\@$hcp "$::SUDO umount $cloneMntPt"`; | ||||
|  | ||||
|                 # Remove mount point | ||||
|                 $out = `ssh $::SUDOER\@$hcp "$::SUDO rm -rf $cloneMntPt"`; | ||||
|  | ||||
|                 # Disable disks | ||||
|                 $out = xCAT::zvmUtils->disableEnableDisk( $::SUDOER, $hcp, "-d", $tgtAddr ); | ||||
|  | ||||
|                 # Detatch disks from HCP | ||||
|                 $out = `ssh $::SUDOER\@$hcp "$::SUDO /sbin/vmcp det $tgtAddr"`; | ||||
|  | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             # Wait before trying again | ||||
|             sleep(10); | ||||
|             $try = $try - 1; | ||||
|         } | ||||
|          | ||||
|         if (!(`ssh $::SUDOER\@$hcp "$::SUDO ls $cloneMntPt"`)) { | ||||
|         	xCAT::zvmUtils->printLn( $callback, "$tgtNode: Failed to mount /dev/$tgtDevNode. Skipping device." ); | ||||
|         } | ||||
|          | ||||
|         # Is this the partition containing /etc? | ||||
|         if (`ssh $::SUDOER\@$hcp "$::SUDO test -d $cloneMntPt/etc && echo Exists"`) { | ||||
|             #*** Set network configuration *** | ||||
|             # Set hostname | ||||
|             xCAT::zvmUtils->printLn( $callback, "$tgtNode: Setting network configuration" ); | ||||
|             $out = `ssh $::SUDOER\@$hcp "$::SUDO sed --in-place -e "s/$sourceNode/$tgtNode/i" $cloneMntPt/etc/HOSTNAME"`; | ||||
|             $out = `ssh $::SUDOER\@$hcp "$::SUDO sed --in-place -e \"s/$sourceNode/$tgtNode/i\" $cloneMntPt/etc/HOSTNAME"`; | ||||
|             xCAT::zvmUtils->printSyslog("clone() sed --in-place -e s/$sourceNode/$tgtNode/i $cloneMntPt/etc/HOSTNAME"); | ||||
|  | ||||
|             # If Red Hat - Set hostname in /etc/sysconfig/network | ||||
|             if ( $srcOs =~ m/Red Hat/i ) { | ||||
|                 $out = `ssh $::SUDOER\@$hcp "$::SUDO sed --in-place -e "s/$sourceNode/$tgtNode/i" $cloneMntPt/etc/sysconfig/network"`; | ||||
|             if ( $srcOs =~ m/rhel/i ) { | ||||
|                 $out = `ssh $::SUDOER\@$hcp "$::SUDO sed --in-place -e \"s/$sourceNode/$tgtNode/i\" $cloneMntPt/etc/sysconfig/network"`; | ||||
|                 xCAT::zvmUtils->printSyslog("clone() sed --in-place -e s/$sourceNode/$tgtNode/i $cloneMntPt/etc/sysconfig/network"); | ||||
|             } | ||||
|  | ||||
|             # Get network configuration file | ||||
|             # Location of this file depends on the OS | ||||
|             my $ifcfgPath = $cloneMntPt; | ||||
|             $ifcfgPath .= $srcIfcfg; | ||||
|             $out = `ssh $::SUDOER\@$hcp "$::SUDO sed --in-place -e "s/$sourceNode/$tgtNode/i" \ -e "s/$sourceIp/$targetIp/i" $cloneMntPt/etc/hosts"`; | ||||
|             $out = `ssh $::SUDOER\@$hcp "$::SUDO sed --in-place -e "s/$sourceIp/$targetIp/i" \ -e "s/$sourceNode/$tgtNode/i" $ifcfgPath"`; | ||||
|  | ||||
|             # Get network layer | ||||
|             my $layer = xCAT::zvmCPUtils->getNetworkLayer( $::SUDOER, $hcp, $hcpNetName ); | ||||
|             xCAT::zvmUtils->printSyslog("clone() hcp:$hcp hcpNetName:$hcpNetName layer:$layer"); | ||||
|  | ||||
|             # Get network configuration file | ||||
|             # Location of this file depends on the OS | ||||
|             my $srcIfcfg = ''; | ||||
|                          | ||||
|             # If it is Red Hat - ifcfg-qeth file is in /etc/sysconfig/network-scripts | ||||
|             my @files; | ||||
| 		    if ( $srcOs =~ m/rhel/i ) { | ||||
| 		        $out   = `ssh $::SUDOER\@$hcp "$::SUDO grep -H -r $srcNicAddr $cloneMntPt/etc/sysconfig/network-scripts"`; | ||||
| 		        xCAT::zvmUtils->printSyslog("clone() grep -H -r $srcNicAddr $cloneMntPt/etc/sysconfig/network-scripts"); | ||||
| 		        xCAT::zvmUtils->printSyslog("clone() $out"); | ||||
| 		        @files = split('\n', $out); | ||||
| 		        @words = split( ':', $files[0] ); | ||||
|                 $srcIfcfg = $words[0]; | ||||
| 		    } | ||||
| 		 | ||||
| 		    # If it is SLES 10 - ifcfg-qeth file is in /etc/sysconfig/network | ||||
| 		    elsif ( $srcOs =~ m/sles10/i ) { | ||||
| 		        $out   = `ssh $::SUDOER\@$hcp "$::SUDO grep -H -r $srcNicAddr $cloneMntPt/etc/sysconfig/network/ifcfg-qeth*"`; | ||||
| 		        xCAT::zvmUtils->printSyslog("clone() grep -H -r $srcNicAddr $cloneMntPt/etc/sysconfig/network/ifcfg-qeth*"); | ||||
| 		        xCAT::zvmUtils->printSyslog("clone() $out"); | ||||
|                 @files = split('\n', $out); | ||||
|                 @words = split( ':', $files[0] ); | ||||
|                 $srcIfcfg = $words[0]; | ||||
| 		    } | ||||
| 		 | ||||
| 		    # If it is SLES 11 - ifcfg-qeth file is in /etc/sysconfig/network | ||||
| 		    elsif ( $srcOs =~ m/sles11/i ) {		 | ||||
| 		        $out   = `ssh $::SUDOER\@$hcp "$::SUDO grep -H -r $srcNicAddr $cloneMntPt/etc/sysconfig/network/ifcfg-eth*"`; | ||||
| 		        xCAT::zvmUtils->printSyslog("clone() grep -H -r $srcNicAddr $cloneMntPt/etc/sysconfig/network/ifcfg-eth*"); | ||||
| 		        xCAT::zvmUtils->printSyslog("clone() $out"); | ||||
|                 @files = split('\n', $out); | ||||
|                 @words = split( ':', $files[0] ); | ||||
|                 $srcIfcfg = $words[0]; | ||||
| 		    } | ||||
| 		     | ||||
|             my $ifcfgPath = $srcIfcfg; | ||||
|              | ||||
|             # Change IP, network, and mask	 | ||||
| 	        # Go through each network | ||||
| 	        my $tgtNetwork = ""; | ||||
| 	        my $tgtMask; | ||||
| 	        foreach (@$netEntries) { | ||||
| 	 | ||||
| 	            # Get network and mask | ||||
| 	            $tgtNetwork = $_->{'net'}; | ||||
| 	            $tgtMask = $_->{'mask'}; | ||||
| 	             | ||||
| 	            # If the host IP address is in this subnet, return | ||||
| 	            if (xCAT::NetworkUtils->ishostinsubnet($targetIp, $tgtMask, $tgtNetwork)) { | ||||
| 	 | ||||
| 	                # Exit loop | ||||
| 	                last; | ||||
| 	            } else { | ||||
| 	                $tgtNetwork = ""; | ||||
| 	            } | ||||
| 	        } | ||||
|                  | ||||
|             $out = `ssh $::SUDOER\@$hcp "$::SUDO sed --in-place -e \"s/$sourceNode/$tgtNode/i\" \ -e \"s/$sourceIp/$targetIp/i\" $cloneMntPt/etc/hosts"`; | ||||
|             $out = `ssh $::SUDOER\@$hcp "$::SUDO sed --in-place -e \"s/$sourceIp/$targetIp/i\" \ -e \"s/$sourceNode/$tgtNode/i\" $ifcfgPath"`; | ||||
|             xCAT::zvmUtils->printSyslog("clone() sed --in-place -e s/$sourceNode/$tgtNode/i \ -e s/$sourceIp/$targetIp/i $cloneMntPt/etc/hosts"); | ||||
|             xCAT::zvmUtils->printSyslog("clone() sed --in-place -e s/$sourceIp/$targetIp/i \ -e s/$sourceNode/$tgtNode/i $ifcfgPath"); | ||||
|              | ||||
|             if ($tgtNetwork && $tgtMask) { | ||||
|             	$out = `ssh $::SUDOER\@$hcp "$::SUDO sed --in-place -e \"s/$srcNetwork/$tgtNetwork/i\" \ -e \"s/$srcMask/$tgtMask/i\" $ifcfgPath"`; | ||||
|                 xCAT::zvmUtils->printSyslog("clone() sed --in-place -e s/$srcNetwork/$tgtNetwork/i \ -e s/$srcMask/$tgtMask/i $ifcfgPath"); | ||||
|             } | ||||
|              | ||||
|             # Set MAC address | ||||
|             my $networkFile = $tgtNode . "NetworkConfig"; | ||||
|             my $config; | ||||
|             if ( $srcOs =~ m/Red Hat/i ) { | ||||
|             if ( $srcOs =~ m/rhel/i ) { | ||||
|  | ||||
|                 # Red Hat only | ||||
|                 $config = `ssh $::SUDOER\@$hcp "$::SUDO cat $ifcfgPath" | grep -v "MACADDR"`; | ||||
|                 $config .= "MACADDR='$targetMac'\n"; | ||||
|                 $config .= "MACADDR='" . $targetMac . "'\n"; | ||||
|             } else { | ||||
|  | ||||
|                 # SUSE only | ||||
| @@ -4270,15 +4373,16 @@ EOM"`; | ||||
|                                  | ||||
|                 # Set to MAC address (only for layer 2) | ||||
|                 if ( $layer == 2 ) { | ||||
|                     $config .= "LLADDR='$targetMac'\n"; | ||||
|                     $config .= "LLADDR='" . $targetMac . "'\n"; | ||||
|                     $config .= "UNIQUE=''\n"; | ||||
|                 } | ||||
|             } | ||||
|             xCAT::zvmUtils->printSyslog("clone() $config"); | ||||
|  | ||||
|             # Write network configuration | ||||
|             # You cannot SCP file over to mount point as sudo, so you have to copy file to zHCP  | ||||
|             # and move it to mount point | ||||
|             $out = `echo -e \"$config\" > /tmp/$networkFile`; | ||||
|             $out = `echo -e "$config" > /tmp/$networkFile`; | ||||
|             $out = `ssh $::SUDOER\@$hcp "$::SUDO rm -rf $ifcfgPath"`; | ||||
|             $out = `cat /tmp/$networkFile | ssh $::SUDOER\@$hcp "$::SUDO cat > /tmp/$networkFile"`; | ||||
|             $out = `ssh $::SUDOER\@$hcp "$::SUDO mv /tmp/$networkFile $ifcfgPath"`; | ||||
| @@ -4286,46 +4390,19 @@ EOM"`; | ||||
|  | ||||
|             # Set to hardware configuration (only for layer 2) | ||||
|             if ( $layer == 2 ) { | ||||
|  | ||||
|                 #*** Red Hat *** | ||||
|                 if ( $srcOs =~ m/Red Hat/i ) { | ||||
|                     my $srcMac; | ||||
|  | ||||
|                     # Get source MAC address in 'mac' table | ||||
|                     @propNames = ('mac'); | ||||
|                     $propVals = xCAT::zvmUtils->getNodeProps( 'mac', $sourceNode, @propNames ); | ||||
|                     if ($propVals) { | ||||
|  | ||||
|                         # Get MAC address | ||||
|                         $srcMac = $propVals->{'mac'}; | ||||
|                     } | ||||
|                     else { | ||||
|                         xCAT::zvmUtils->printLn( $callback, "$tgtNode: (Error) Could not find MAC address of $sourceNode" ); | ||||
|  | ||||
|                         # Unmount disk | ||||
|                         $out = `ssh $::SUDOER\@$hcp "$::SUDO umount $cloneMntPt"`; | ||||
|  | ||||
|                         # Disable disks | ||||
|                         $out = xCAT::zvmUtils->disableEnableDisk( $::SUDOER, $hcp, "-d", $tgtAddr ); | ||||
|  | ||||
|                         # Detatch disks from HCP | ||||
|                         $out = `ssh $::SUDOER\@$hcp "$::SUDO /sbin/vmcp det $tgtAddr"`; | ||||
|  | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                 if ( $srcOs =~ m/rhel/i && $srcMac ) { | ||||
|                 	#*** Red Hat Linux *** | ||||
|                 	 | ||||
|                     # Set MAC address | ||||
|                     $out = `ssh $::SUDOER\@$hcp "$::SUDO sed --in-place -e "s/$srcMac/$targetMac/i" $ifcfgPath"`; | ||||
|                 } | ||||
|  | ||||
|                 #*** SUSE *** | ||||
|                 else { | ||||
|                     $out = `ssh $::SUDOER\@$hcp "$::SUDO sed --in-place -e \"s/$srcMac/$targetMac/i\" $ifcfgPath"`; | ||||
|                     xCAT::zvmUtils->printSyslog("clone() sed --in-place -e s/$srcMac/$targetMac/i $ifcfgPath");                    | ||||
|                 } else { | ||||
|                 	#*** SuSE Linux *** | ||||
|  | ||||
|                     # Get hardware configuration | ||||
|                     my $hwcfgPath = $cloneMntPt; | ||||
|  | ||||
|                     # Set layer 2 support | ||||
|                     $hwcfgPath .= $srcHwcfg; | ||||
|                     # hwcfg-qeth file is in /etc/sysconfig/hardware | ||||
|                     my $hwcfgPath = $cloneMntPt . "/etc/sysconfig/hardware/hwcfg-qeth-bus-ccw-0.0.$srcNicAddr"; | ||||
|                     xCAT::zvmUtils->printSyslog("clone() hwcfgPath=$hwcfgPath"); | ||||
|                     my $hardwareFile = $tgtNode . "HardwareConfig"; | ||||
|                     $out = `ssh $::SUDOER\@$hcp "$::SUDO cat $hwcfgPath" | grep -v "QETH_LAYER2_SUPPORT" > /tmp/$hardwareFile`; | ||||
|                     $out = `echo "QETH_LAYER2_SUPPORT='1'" >> /tmp/$hardwareFile`; | ||||
| @@ -4338,16 +4415,16 @@ EOM"`; | ||||
|  | ||||
|             # Remove old SSH keys | ||||
|             $out = `ssh $::SUDOER\@$hcp "$::SUDO rm -f $cloneMntPt/etc/ssh/ssh_host_*"`; | ||||
|  | ||||
|             # Flush disk | ||||
|             $out = `ssh $::SUDOER\@$hcp "$::SUDO /bin/sync"`; | ||||
|  | ||||
|             # Unmount disk | ||||
|             $out = `ssh $::SUDOER\@$hcp "$::SUDO /bin/umount $cloneMntPt"`; | ||||
|  | ||||
|             # Remove mount point | ||||
|             $out = `ssh $::SUDOER\@$hcp "$::SUDO rm -rf $cloneMntPt"`; | ||||
|         } | ||||
|          | ||||
|         # Flush disk | ||||
|         $out = `ssh $::SUDOER\@$hcp "$::SUDO /bin/sync"`; | ||||
|  | ||||
|         # Unmount disk | ||||
|         $out = `ssh $::SUDOER\@$hcp "$::SUDO /bin/umount $cloneMntPt"`; | ||||
|  | ||||
|         # Remove mount point | ||||
|         $out = `ssh $::SUDOER\@$hcp "$::SUDO rm -rf $cloneMntPt"`; | ||||
|  | ||||
|         # Disable disks | ||||
|         $out = xCAT::zvmUtils->disableEnableDisk( $::SUDOER, $hcp, "-d", $tgtAddr ); | ||||
| @@ -4358,8 +4435,11 @@ EOM"`; | ||||
|         sleep(5); | ||||
|     }    # End of foreach (@tgtDisks) | ||||
|  | ||||
|     # Update DHCP | ||||
|     $out = `makedhcp -a`; | ||||
|     # Update DHCP (only if it is running) | ||||
|     $out = `service dhcpd status`; | ||||
|     if (!($out =~ m/unused/i || $out =~ m/stopped/i)) { | ||||
|         $out = `makedhcp -a`; | ||||
|     } | ||||
|  | ||||
|     # Power on target virtual server | ||||
|     xCAT::zvmUtils->printLn( $callback, "$tgtNode: Powering on" ); | ||||
| @@ -4766,20 +4846,16 @@ sub nodeSet { | ||||
|  | ||||
|         @propNames = ( 'nfsserver', 'xcatmaster' ); | ||||
|         $propVals = xCAT::zvmUtils->getNodeProps( 'noderes', $node, @propNames ); | ||||
|         my $nfs = $propVals->{'nfsserver'}; | ||||
|         my $repo = $propVals->{'nfsserver'};  # Repository containing Linux ISO | ||||
|         my $xcatmaster = $propVals->{'xcatmaster'}; | ||||
|              | ||||
|         # Use noderes.xcatmaster instead of site.master if it is given | ||||
|         if ( $xcatmaster ) { | ||||
|             $master = $xcatmaster; | ||||
|         } | ||||
|      | ||||
|         if ( !$nfs ) { | ||||
|             $nfs = $master; | ||||
|         } | ||||
|          | ||||
|  | ||||
|         # Combine NFS server and installation directory, e.g. 10.0.0.1/install | ||||
|         $nfs .= $installDir; | ||||
|         my $nfs = $master . $installDir; | ||||
|  | ||||
|         # Get broadcast address of NIC | ||||
|         my $ifcfg = xCAT::zvmUtils->getIfcfgByNic( $::SUDOER, $hcp, $readChannel ); | ||||
| @@ -5008,6 +5084,10 @@ END | ||||
|             #   Install=ftp://10.0.0.1/sles10.2/s390x/1/ | ||||
|             #   UseVNC=1  VNCPassword=12345678 | ||||
|             #   InstNetDev=osa OsaInterface=qdio OsaMedium=eth Manual=0 | ||||
|             if (!$repo) { | ||||
| 	            $repo = "http://$nfs/$os/s390x/1/"; | ||||
| 	        } | ||||
|          | ||||
|             my $ay = "http://$nfs/custom/install/sles/" . $node . "." . $profile . ".tmpl"; | ||||
|  | ||||
|             $parms = $parmHeader . "\n"; | ||||
| @@ -5024,7 +5104,7 @@ END | ||||
|  | ||||
|             $parms = $parms . "ReadChannel=$readChannel WriteChannel=$writeChannel DataChannel=$dataChannel\n"; | ||||
|             $parms = $parms . "Nameserver=$nameserver Portname=$portName Portno=0\n"; | ||||
|             $parms = $parms . "Install=http://$nfs/$os/s390x/1/\n"; | ||||
|             $parms = $parms . "Install=$repo\n"; | ||||
|             $parms = $parms . "UseVNC=1 VNCPassword=12345678\n"; | ||||
|             $parms = $parms . "InstNetDev=$instNetDev OsaInterface=$osaInterface OsaMedium=$osaMedium Manual=0\n"; | ||||
|  | ||||
| @@ -5127,9 +5207,12 @@ END | ||||
|             $out = `sed --in-place -e "s,replace_xcatinstallpost,,g" $customTmpl`; | ||||
|  | ||||
|             # Edit template | ||||
|             my $url = "http://$nfs/$os/s390x/"; | ||||
|             if (!$repo) { | ||||
|                 $repo = "http://$nfs/$os/s390x/"; | ||||
|             } | ||||
|              | ||||
|             $out = | ||||
| `sed --in-place -e "s,replace_url,$url,g" \ -e "s,replace_ip,$hostIP,g" \ -e "s,replace_netmask,$mask,g" \ -e "s,replace_gateway,$gateway,g" \ -e "s,replace_nameserver,$nameserver,g" \ -e "s,replace_hostname,$hostname,g" \ -e "s,replace_rootpw,$passwd,g" \ -e "s,replace_master,$master,g" \ -e "s,replace_install_dir,$installDir,g" $customTmpl`; | ||||
| `sed --in-place -e "s,replace_url,$repo,g" \ -e "s,replace_ip,$hostIP,g" \ -e "s,replace_netmask,$mask,g" \ -e "s,replace_gateway,$gateway,g" \ -e "s,replace_nameserver,$nameserver,g" \ -e "s,replace_hostname,$hostname,g" \ -e "s,replace_rootpw,$passwd,g" \ -e "s,replace_master,$master,g" \ -e "s,replace_install_dir,$installDir,g" $customTmpl`; | ||||
|  | ||||
|             # Attach SCSI FCP devices (if any) | ||||
|             # Go through each pool | ||||
|   | ||||
		Reference in New Issue
	
	Block a user