mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 03:12:30 +00:00 
			
		
		
		
	Added clone option to self-service page.
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@10758 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
		| @@ -114,6 +114,10 @@ body { | ||||
| 	color: inherit; | ||||
| } | ||||
|  | ||||
| pre { | ||||
| 	font-size: 10px;	 | ||||
| } | ||||
|  | ||||
| /*--------------- Groups ---------------*/ | ||||
| #groups { | ||||
| 	width: 150px; | ||||
|   | ||||
| @@ -14,6 +14,17 @@ var bladePlugin = function() { | ||||
|  | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Clone node (service page) | ||||
|  *  | ||||
|  * @param node | ||||
|  * 			Node to clone | ||||
|  * @return Nothing | ||||
|  */ | ||||
| bladePlugin.prototype.serviceClone = function(node) { | ||||
|  | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Load provision page (service page) | ||||
|  *  | ||||
|   | ||||
| @@ -14,6 +14,17 @@ var hmcPlugin = function() { | ||||
|  | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Clone node (service page) | ||||
|  *  | ||||
|  * @param node | ||||
|  * 			Node to clone | ||||
|  * @return Nothing | ||||
|  */ | ||||
| hmcPlugin.prototype.serviceClone = function(node) { | ||||
|  | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Load provision page (service page) | ||||
|  *  | ||||
|   | ||||
| @@ -14,6 +14,17 @@ var ipmiPlugin = function() { | ||||
|  | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Clone node (service page) | ||||
|  *  | ||||
|  * @param node | ||||
|  * 			Node to clone | ||||
|  * @return Nothing | ||||
|  */ | ||||
| ipmiPlugin.prototype.serviceClone = function(node) { | ||||
|  | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Load provision page (service page) | ||||
|  *  | ||||
|   | ||||
| @@ -15,6 +15,44 @@ var zvmPlugin = function() { | ||||
| 	 | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Clone node (service page) | ||||
|  *  | ||||
|  * @param node | ||||
|  * 			Node to clone | ||||
|  * @return Nothing | ||||
|  */ | ||||
| zvmPlugin.prototype.serviceClone = function(node) { | ||||
| 	var statBar = createStatusBar(node + 'CloneStat'); | ||||
| 	var loader = createLoader(''); | ||||
| 	statBar.find('div').append(loader);	 | ||||
| 	statBar.prependTo($('#manageTab')); | ||||
| 	 | ||||
| 	var owner = $.cookie('srv_usrname'); | ||||
| 	var group = getUserNodeAttr(node, 'groups'); | ||||
| 	 | ||||
| 	// Submit request to clone VM | ||||
| 	// webportal clonezlinux [src node] [group] [owner] | ||||
| 	$.ajax({ | ||||
|         url : 'lib/srv_cmd.php', | ||||
|         dataType : 'json', | ||||
|         data : { | ||||
|             cmd : 'webportal', | ||||
|             tgt : '', | ||||
|             args : 'clonezlinux;' + node + ';' + group + ';' + owner, | ||||
|             msg : '' | ||||
|         }, | ||||
|         success:function(data) { | ||||
|         	// Remove loader | ||||
|         	statBar.find('img').remove(); | ||||
|         	// Append output to status bar | ||||
|         	for (var i in data.rsp) { | ||||
|         		statBar.find('div').append($('<pre></pre>').append(data.rsp[i])); | ||||
|         	} | ||||
|         } | ||||
|     }); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Load provision page (service page) | ||||
|  *  | ||||
| @@ -68,7 +106,7 @@ 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 owner = $.cookie('srv_usrname');; | ||||
| 		var owner = $.cookie('srv_usrname'); | ||||
| 		 | ||||
| 		// Begin by creating VM | ||||
| 		createzVM(tabId, group, hcp, img, owner); | ||||
| @@ -79,7 +117,7 @@ zvmPlugin.prototype.loadServiceProvisionPage = function(tabId) { | ||||
| 	loadSrvGroups(groupCol); | ||||
| 	loadOSImages(imageCol); | ||||
| 	 | ||||
| 	 // Get zVM host names | ||||
| 	// Get zVM host names | ||||
| 	if (!$.cookie('srv_zvm')){ | ||||
| 		$.ajax( { | ||||
| 			url : 'lib/srv_cmd.php', | ||||
|   | ||||
| @@ -517,6 +517,15 @@ function loadNodesTable(data) { | ||||
| 		} | ||||
| 	}); | ||||
| 	 | ||||
| 	// Clone | ||||
| 	var cloneLnk = $('<a>Clone</a>'); | ||||
| 	cloneLnk.click(function() { | ||||
| 		var tgtNodes = getNodesChecked(nodesDTId); | ||||
| 		if (tgtNodes) { | ||||
| 			cloneNode(tgtNodes); | ||||
| 		} | ||||
| 	}); | ||||
| 	 | ||||
| 	// Delete | ||||
| 	var deleteLnk = $('<a>Delete</a>'); | ||||
| 	deleteLnk.click(function() { | ||||
| @@ -540,7 +549,7 @@ function loadNodesTable(data) { | ||||
| 	 | ||||
| 	// Prepend menu to datatable | ||||
| 	var actionsLnk = '<a>Actions</a>'; | ||||
| 	var actionMenu = createMenu([deleteLnk, powerOnLnk, powerOffLnk, monitorOnLnk, monitorOffLnk, unlockLnk]); | ||||
| 	var actionMenu = createMenu([cloneLnk, deleteLnk, monitorOnLnk, monitorOffLnk, powerOnLnk, powerOffLnk, unlockLnk]); | ||||
| 	var menu = createMenu([[actionsLnk, actionMenu]]); | ||||
| 	menu.superfish(); | ||||
| 	actionBar.append(menu); | ||||
| @@ -1171,6 +1180,43 @@ function monitorNode(node, monitor) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Open a dialog to clone node | ||||
|  *  | ||||
|  * @param tgtNodes | ||||
|  *            Nodes to clone | ||||
|  * @return Nothing | ||||
|  */ | ||||
| function cloneNode(tgtNodes) {	 | ||||
| 	var nodes = tgtNodes.split(','); | ||||
| 	 | ||||
| 	for (var n in nodes) { | ||||
| 		// Get hardware that was selected | ||||
| 		var hw = getUserNodeAttr(nodes[n], 'mgt'); | ||||
| 		 | ||||
| 		// Create an instance of the plugin | ||||
|         var plugin; | ||||
|         switch (hw) { | ||||
|         case "blade": | ||||
|             plugin = new bladePlugin(); | ||||
|             break; | ||||
|         case "hmc": | ||||
|             plugin = new hmcPlugin(); | ||||
|             break; | ||||
|         case "ipmi": | ||||
|             plugin = new ipmiPlugin(); | ||||
|             break; | ||||
|         case "zvm": | ||||
|             plugin = new zvmPlugin();	        	 | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         // Clone node | ||||
|         plugin.serviceClone(nodes[n]);				 | ||||
| 	} | ||||
| } | ||||
| 	 | ||||
|  | ||||
| /** | ||||
|  * Open a dialog to delete node | ||||
|  *  | ||||
|   | ||||
| @@ -318,4 +318,43 @@ function showChdefOutput(data) { | ||||
| 	} | ||||
| 	 | ||||
| 	info.append(prg); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Get an attribute of a given node | ||||
|  *  | ||||
|  * @param node | ||||
|  *            The node | ||||
|  * @param attrName | ||||
|  *            The attribute | ||||
|  * @return The attribute of the node | ||||
|  */ | ||||
| function getUserNodeAttr(node, attrName) { | ||||
| 	// Get the row | ||||
| 	var row = $('[id=' + node + ']').parents('tr'); | ||||
|  | ||||
| 	// Search for the column containing the attribute | ||||
| 	var attrCol; | ||||
| 	 | ||||
| 	var cols = row.parents('.dataTables_scroll').find('.dataTables_scrollHead thead tr:eq(0) th'); | ||||
| 	// Loop through each column | ||||
| 	for (var i in cols) { | ||||
| 		// Find column that matches the attribute | ||||
| 		if (cols.eq(i).html() == attrName) { | ||||
| 			attrCol = cols.eq(i); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	// If the column containing the attribute is found | ||||
| 	if (attrCol) { | ||||
| 		// Get the attribute column index | ||||
| 		var attrIndex = attrCol.index(); | ||||
|  | ||||
| 		// Get the attribute for the given node | ||||
| 		var attr = row.find('td:eq(' + attrIndex + ')'); | ||||
| 		return attr.text(); | ||||
| 	} else { | ||||
| 		return ''; | ||||
| 	} | ||||
| } | ||||
| @@ -111,7 +111,7 @@ function submit_request($req, $skipVerify, $opts_array){ | ||||
| 							format_TBD($tmp); | ||||
| 						} else { | ||||
| 							// Print out output by default | ||||
| 							echo '<pre>' . $tmp . '</pre>'; | ||||
| 							echo '<pre style="font-size: 10px;">' . $tmp . '</pre>'; | ||||
| 							ob_flush(); | ||||
| 							flush(); | ||||
| 						} | ||||
|   | ||||
| @@ -111,7 +111,7 @@ function submit_request($req, $skipVerify, $opts_array){ | ||||
| 							format_TBD($tmp); | ||||
| 						} else { | ||||
| 							// Print out output by default | ||||
| 							echo '<pre>' . $tmp . '</pre>'; | ||||
| 							echo '<pre style="font-size: 10px;">' . $tmp . '</pre>'; | ||||
| 							ob_flush(); | ||||
| 							flush(); | ||||
| 						} | ||||
|   | ||||
| @@ -34,8 +34,9 @@ sub process_request { | ||||
| 	my $callback        = shift; | ||||
| 	my $sub_req         = shift; | ||||
| 	my %authorized_cmds = ( | ||||
| 		'lszvm'      => \&lszvm, | ||||
| 		'provzlinux' => \&provzlinux | ||||
| 		'lszvm'       => \&lszvm, | ||||
| 		'provzlinux'  => \&provzlinux, | ||||
| 		'clonezlinux' => \&clonezlinux | ||||
| 	); | ||||
|  | ||||
| 	# Check if the request is authorized | ||||
| @@ -370,4 +371,126 @@ sub gennodename { | ||||
| 	  | ||||
| 	return ($hostname, $base_digit); | ||||
| } | ||||
| 1; | ||||
|  | ||||
| sub clonezlinux { | ||||
| 	my ( $request, $callback, $sub_req ) = @_; | ||||
|  | ||||
| 	# webportal clonezlinux [src node] [group] [owner] | ||||
| 	my $src_node = $request->{arg}->[1]; | ||||
| 	my $group = $request->{arg}->[2]; | ||||
| 	my $owner = $request->{arg}->[3]; | ||||
| 	 | ||||
| 	# Get source node's HCP | ||||
| 	my $props = xCAT::zvmUtils->getNodeProps( 'zvm', $src_node, ('hcp') ); | ||||
| 	my $hcp = $props->{'hcp'}; | ||||
|  | ||||
| 	# Read in default disk pool and disk size /opt/zhcp/conf/default.conf on zHCP | ||||
| 	#	pool = POOL3 | ||||
| 	#	eckd_size = 10016 | ||||
| 	my $disk_pool; | ||||
| 	my $eckd_size; | ||||
| 	my $fba_size; | ||||
| 	my $default_conf   = '/opt/zhcp/conf/default.conf'; | ||||
| 	my $default_direct = '/opt/zhcp/conf/default.direct'; | ||||
|  | ||||
| 	# Exit if default.conf does not exist | ||||
| 	if ( !(`ssh $hcp "test -e $default_conf && echo Exists"`) ) { | ||||
| 		println( $callback, '(Error) $default_conf does not exists' ); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	# Exit if default.direct does not exist | ||||
| 	if ( !(`ssh $hcp "test -e $default_direct && echo Exists"`) ) { | ||||
| 		println( $callback, '(Error) $default_direct does not exists' ); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	my $out = `ssh $hcp "cat $default_conf"`; | ||||
| 	my @tmp = split( /\n/, $out ); | ||||
| 	foreach (@tmp) { | ||||
| 		# Get disk pool | ||||
| 		if ( $_ =~ m/pool =/i ) { | ||||
| 			$disk_pool = $_; | ||||
| 			$disk_pool =~ s/pool =//g; | ||||
| 		} | ||||
|  | ||||
| 		# Get disk size | ||||
| 		elsif ( $_ =~ m/eckd_size =/i ) { | ||||
| 			$eckd_size = $_; | ||||
| 			$eckd_size =~ s/eckd_size =//g; | ||||
| 		} | ||||
| 		elsif ( $_ =~ m/fba_size = /i ) { | ||||
| 			$fba_size = $_; | ||||
| 			$fba_size =~ s/fba_size = //g; | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	println( $callback, "Your virtual machine is ready. It may take a few minutes before you can logon." ); | ||||
| 	println( $callback, "Done!" ); | ||||
| 	 | ||||
| 	return; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #	# Create VM | ||||
| #	# e.g. webportal provzlinux [group] [hcp] [image] | ||||
| #	my ($node, $base_digit) = gennodename( $callback, $group ); | ||||
| #	my $userid = 'XCAT' . $base_digit; | ||||
| # | ||||
| #	# Set node definitions | ||||
| #	$out = `mkdef -t node -o $node userid=$userid hcp=$hcp mgt=zvm groups=$group`; | ||||
| #	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"`; | ||||
| # | ||||
| #	# Update hosts table and DNS | ||||
| #	`makehosts`; | ||||
| #	`makedns`; | ||||
| # | ||||
| #	# Create user directory entry replacing LXUSR with user ID | ||||
| #	# Use /opt/zhcp/conf/default.direct on zHCP as the template | ||||
| #	#	USER LXUSR PSWD 512M 1G G | ||||
| #	#	INCLUDE LNXDFLT | ||||
| #	#	COMMAND SET VSWITCH VSW2 GRANT LXUSR | ||||
| #	$out = `ssh $hcp "sed $default_direct -e s/LXUSR/$userid/g" > /tmp/$node-direct.txt`; | ||||
| #	$out = `mkvm $node /tmp/$node-direct.txt`; | ||||
| #	`rm -rf /tmp/$node-direct.txt`; | ||||
| #	println( $callback, "$out" ); | ||||
| #	if ( $out =~ m/Error/i ) { | ||||
| #		return; | ||||
| #	} | ||||
| # | ||||
| #	# Update DHCP | ||||
| #	`makedhcp -a`; | ||||
| # | ||||
| #	# Toggle node power so COMMAND SET will get executed | ||||
| #	`rpower $node on`; | ||||
| #	`rpower $node off`; | ||||
| # | ||||
| #	# Punch kernel, initrd, and ramdisk to node reader | ||||
| #	$out = `nodeset $node install`; | ||||
| #	println( $callback, "$out" ); | ||||
| #	if ( $out =~ m/Error/i ) { | ||||
| #		return; | ||||
| #	} | ||||
| # | ||||
| #	# IPL reader and begin installation | ||||
| #	$out = `rnetboot $node ipl=00C`; | ||||
| #	println( $callback, "$out" ); | ||||
| #	if ( $out =~ m/Error/i ) { | ||||
| #		return; | ||||
| #	} | ||||
| #	 | ||||
| #	# Configure Ganglia monitoring | ||||
| #	$out = `moncfg gangliamon $node -r`; | ||||
| #	 | ||||
| #	# Show node information, e.g. IP, hostname, and root password | ||||
| #	$out = `lsdef $node | egrep "ip=|hostnames="`; | ||||
| #	my $rootpw = getsysrootpw(); | ||||
| #	println( $callback, "Your virtual machine is ready. It may take a few minutes before you can logon using VNC ($node:1). Below is your VM attributes." ); | ||||
| #	println( $callback, "$out" ); | ||||
| #	println( $callback, "    rootpw = $rootpw" ); | ||||
| } | ||||
| 1; | ||||
		Reference in New Issue
	
	Block a user