mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 03:12:30 +00:00 
			
		
		
		
	Done cleaning out the js and lib/XCAT dir
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@126 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
		| @@ -1,64 +0,0 @@ | ||||
| ul.clickTree {  | ||||
| 	list-style: none; | ||||
| 	margin: 0; | ||||
| 	padding: 0; | ||||
| } | ||||
|  | ||||
| ul.clickTree li {  | ||||
| 	padding-left: 20px;  | ||||
| } | ||||
|  | ||||
| ul.clickTree ul { | ||||
|   	/*padding-left: 10px; */ | ||||
| 	list-style: none; | ||||
| } | ||||
|  | ||||
|  | ||||
| ul.clickTree li.firstItem  { | ||||
|     background: url(http://wopr.dfw.ibm.com/xcat/images/middle-line.gif) center left no-repeat; | ||||
| 	/*padding-left: 20px;*/ | ||||
| } | ||||
| ul.clickTree li.lastItem  { | ||||
|     background: url(http://wopr.dfw.ibm.com/xcat/images/line.gif) center left no-repeat; | ||||
| 	/* padding-left: 20px; */ | ||||
| } | ||||
| ul.clickTree li.middleItem  { | ||||
|     background: url(http://wopr.dfw.ibm.com/xcat/images/middle-line.gif) center left no-repeat; | ||||
| 	/* padding-left: 20px;*/ | ||||
| } | ||||
| ul.clickTree .unchecked { | ||||
|     background: url(http://wopr.dfw.ibm.com/xcat/images/chkbox-uncheck.gif) center left no-repeat; | ||||
| 	/* padding-left: 20px; */ | ||||
| } | ||||
| ul.clickTree .checked { | ||||
|     background: url(http://wopr.dfw.ibm.com/xcat/images/chkbox-check.gif) center left no-repeat; | ||||
| 	/* padding-left: 20px; */ | ||||
| } | ||||
|  | ||||
| .nodeIcon { | ||||
|     background: url(http://wopr.dfw.ibm.com/xcat/images/node.gif) center left no-repeat; | ||||
| 	 padding-left: 20px; | ||||
|  | ||||
| } | ||||
|  | ||||
| .nodeGroupIcon { | ||||
|     background: url(http://wopr.dfw.ibm.com/xcat/images/burst.gif) center left no-repeat; | ||||
| 	padding-left: 20px;  | ||||
|  | ||||
| } | ||||
| .plus { | ||||
|     background: url(http://wopr.dfw.ibm.com/xcat/images/plus.gif) center left no-repeat; | ||||
| 	padding-left: 20px; | ||||
| 	cursor: pointer; | ||||
| } | ||||
|  | ||||
| .minus { | ||||
|     background: url(http://wopr.dfw.ibm.com/xcat/images/minus.gif) center left no-repeat; | ||||
| 	padding-left: 20px; | ||||
| 	cursor: pointer; | ||||
| 	 | ||||
| } | ||||
|  | ||||
| /* Actually show and hide sublists */ | ||||
| ul.clickTree li.open ul { display: block; } | ||||
| ul.clickTree li.closed ul { display: none; } | ||||
| @@ -1,129 +0,0 @@ | ||||
|  | ||||
|  | ||||
|  | ||||
| processHeader = function(head,ul) { | ||||
|  | ||||
|  | ||||
| 	/* make the head icon different */ | ||||
| 	for (i=0; i < head.childNodes.length; i++ ) { | ||||
| 		if(head.childNodes[i].className = "nodeIcon"){ | ||||
| 			head.childNodes[i].className = "nodeGroupIcon"; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	/* add the plus and expandibility */	 | ||||
| 	myBox = document.createElement('span'); | ||||
| 	myBox.className = 'plus'; | ||||
| 	myBox.innerHTML = " "; | ||||
| 	myBox.onclick = function() { | ||||
| 			this.className = (this.className == 'plus') ? 'minus' : 'plus'; | ||||
| 			this.parentNode.parentNode.className = (this.parentNode.parentNode.className=='open') ? 'closed' : 'open'; | ||||
|         	return false; | ||||
| 	} | ||||
| 	head.insertBefore(myBox, head.childNodes[0]); | ||||
| 	head.parentNode.className = 'closed'; | ||||
| } | ||||
|  | ||||
| processItem = function(li, lili){ | ||||
| 	myN = document.createElement('span'); | ||||
| 	myIcon = document.createElement('span'); | ||||
| 	myIcon.innerHTML = " "; | ||||
| 	myCheck = document.createElement('span'); | ||||
| 	myIcon.className = "nodeIcon"; | ||||
| 	myCheck.className = "unchecked"; | ||||
| 	myCheck.onclick = function (){ | ||||
| 		this.className = (this.className=='checked') ? "unchecked" : "checked"; | ||||
| 		//this.parentNode. | ||||
|    		return false; | ||||
| 	} | ||||
|  | ||||
| 	/* create form element */ | ||||
| 	myInput = document.createElement('input'); | ||||
| 	myInput.type = 'checkbox'; | ||||
| 	myInput.id = 'input'; | ||||
| 	myInput.name = 'nodes[]'; | ||||
| 	myInput.value = lili.nodeValue; | ||||
| 	/* end create form element */ | ||||
| 	li.insertBefore(myN, lili); | ||||
| 	li.removeChild(lili); | ||||
| 	// myCheck.appendChild(lili); | ||||
| 	// myInput.appendChild(lili); | ||||
| 	myN.appendChild(myIcon); | ||||
| 	// myN.appendChild(myCheck); | ||||
| 	myN.appendChild(myInput); | ||||
| 	myN.appendChild(lili); | ||||
| 	return myN; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| processList = function(ul) { | ||||
| 	if (!ul.childNodes || ul.childNodes.length == 0) return; | ||||
| 	isFirst = ''; | ||||
| 	isLast = ''; | ||||
| 	tempNode = ''; | ||||
| 	for (var i=0; i < ul.childNodes.length; i++ ) { | ||||
| 		li = ul.childNodes[i]; | ||||
| 		if (li.nodeName == "LI") { | ||||
| 		var subUL = ''; | ||||
| 		var head = ''; | ||||
| 		for(j = 0; j < li.childNodes.length; j++) { | ||||
| 			lili = li.childNodes[j]; | ||||
| 				switch (lili.nodeName) { | ||||
| 					case "#text":  | ||||
| 						myN = processItem(li, lili); | ||||
| 						head = myN; | ||||
| 						break; | ||||
| 					case "UL":  | ||||
| 						subUL = lili; | ||||
| 						processList(lili); | ||||
| 						break; | ||||
| 		    		default:  | ||||
| 						// other items may be a span. | ||||
| 						// alert("exception:" + lili.nodeName); | ||||
| 						break; | ||||
| 				} | ||||
| 			} | ||||
| 			if (subUL) { | ||||
| 				processHeader(head,subUL); | ||||
| 			} else { | ||||
| 				//alert('cl: ' + (ul.childNodes.length - 1)); | ||||
| 				if(isFirst == ''){ | ||||
| 					li.className = 'firstItem'; | ||||
| 					isFirst = 1; | ||||
| 				} | ||||
| 				else { | ||||
| 					if(isLast == ''){ | ||||
| 						li.className = "lastItem"; | ||||
| 						tempNode = li; | ||||
| 						isLast = 1; | ||||
| 					}else{ | ||||
| 						tempNode.className = "middleItem"; | ||||
| 						li.className = "lastItem"; | ||||
| 						tempNode = li; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| makeTree = function(el) { | ||||
| 	// see if we can create an element | ||||
| 	if (!document.createElement) return; | ||||
| 	ul = document.getElementById(el); | ||||
| 	if(!ul){ | ||||
| 		return; | ||||
| 	} | ||||
| 	ul.className = "clickTree"; | ||||
| 	processList(ul); | ||||
| } | ||||
|  | ||||
| function closeTree(){ | ||||
| 	var el = document.getElementsByClassName('minus'); | ||||
| 	for(var i = 0; i< el.length; i++){ | ||||
| 		el[i].className = 'plus'; | ||||
| 		el[i].parentNode.parentNode.className = 'closed'; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -1,58 +0,0 @@ | ||||
| var winNum = 1; | ||||
| var zIndex = -100; | ||||
|  | ||||
| function winNewWin(title){ | ||||
| 	var dob; | ||||
| 	var d; | ||||
| 	dob = document.getElementById('content'); | ||||
| 	 | ||||
| 	d = document.createElement('div'); | ||||
| 	d.className = 'block'; | ||||
| 	var winid = 'window' + winNum; | ||||
| 	d.id = 'window' + winNum; | ||||
| 	d.style.zIndex = zIndex; | ||||
| 	zIndex++; | ||||
| 	d.appendChild(winNewTitleBar(title)); | ||||
| 	var cont = winNewContent(); | ||||
| 	d.appendChild(cont); | ||||
| 	dob.appendChild(d); | ||||
| 	new Draggable(winid, {handle: 'handle'}); | ||||
| 	winNum++; | ||||
| 	/* return s the place to start writing */ | ||||
| 	return cont; | ||||
| } | ||||
|  | ||||
| function winNewTitleBar(title){ | ||||
| 	var ti = document.createElement('h3'); | ||||
| 	ti.className = 'handle'; | ||||
| 	var winid = 'window' + winNum; | ||||
| 	var newHTML =  "<a class='block-close' "; | ||||
| 	newHTML += "alt='Close Window' "; | ||||
| 	newHTML += "onClick=\"winKill('" + winid + "')\">"; | ||||
| 	newHTML += "<span> </span></a>" | ||||
| 	newHTML += "<a class='block-toggle' "; | ||||
| 	newHTML += "alt='Toggle Window' "; | ||||
| 	newHTML += "onClick=\"Effect.toggle('winContent"; | ||||
| 	newHTML += winNum ; | ||||
| 	newHTML += "','slide')\">"; | ||||
| 	newHTML += "<span> </span></a>"; | ||||
| 	newHTML += title; | ||||
| 	ti.innerHTML = newHTML; | ||||
| 	return ti; | ||||
| } | ||||
|  | ||||
| function winNewContent(){ | ||||
| 	var doc = document.createElement('div'); | ||||
| 	doc.className = 'blockContent'; | ||||
| 	doc.id = 'winContent' + winNum ; | ||||
| 	return doc; | ||||
| } | ||||
|  | ||||
| function winKill(wid){ | ||||
|         // Todo: make this random effects | ||||
| 	var w = document.getElementById(wid); | ||||
|         Effect.Puff(w); | ||||
| 	w.parentNode.removeChild(w); | ||||
|         // var killU = w.parentNode; | ||||
|         // killU.removeChild(w); | ||||
| } | ||||
| @@ -1,57 +0,0 @@ | ||||
| /** | ||||
|  * This file registers event listeners using Prototype's | ||||
|  * Event API. | ||||
|  * | ||||
|  * See: | ||||
|  * * http://www.prototypejs.org/api/event/ | ||||
|  * * http://www.prototypejs.org/api/event/observe | ||||
|  */ | ||||
|  | ||||
| var XCATEvent = {}; | ||||
|  | ||||
| XCATEvent.doAll = function() { | ||||
| 	Event.observe(window, 'load', function() { | ||||
| 		// Add other functions here | ||||
| 		XCATEvent.doRunCmdButton();	// dsh.php: Run Cmd button is clicked | ||||
| 		//XCATEvent.doExpandNodes();	// index.php: plus sign is click to expand node group | ||||
| 	}); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Register JS function with events for the RunCmdButton | ||||
|  */ | ||||
| XCATEvent.doRunCmdButton = function() { | ||||
| 	Event.observe('runCmdButton_top', 'click', function(event) { | ||||
| 		XCATui.updateCommandResult(); | ||||
| 	}); | ||||
| 	Event.observe('runCmdButton_bottom', 'click', function(event) { | ||||
| 		XCATui.updateCommandResult(); | ||||
| 	}); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Register JS function with events to retrieve nodes of a group | ||||
|  */ | ||||
| XCATEvent.doExpandNodes = function() { | ||||
| 	/*var img_id; | ||||
| 	for (var i = 0; i<document.nodelist.elements.length; i++) { | ||||
|         if ((document.nodelist.elements[i].id.indexOf('img_gr_') > -1)) { | ||||
|         	img_id = document.nodelist.elements[i].id; | ||||
|         	group_name = img_id.substring(7,img_id.length-3); //the image id is of the form "img_gr_groupname-im" | ||||
|             Event.observe(img_id, 'click', function(event) { | ||||
| 			XCATui.updateNodeList(group_name); | ||||
| 			}); | ||||
|         } | ||||
|     }*/ | ||||
|  | ||||
|     for (var i = 0; i<document.nodelist.elements.length; i++) { | ||||
|     	//if (document.nodelist.elements[i].id == 'img_gr_all-im') | ||||
|     		//alert(document.nodelist.elements[i].id); | ||||
|     } | ||||
|  | ||||
|     //Event.observe('img_gr_all-im', 'click', function(event) { | ||||
| 			//XCATui.updateNodeList('img_gr_all-im'); | ||||
| 			//}); | ||||
|  | ||||
|  | ||||
| }; | ||||
							
								
								
									
										69
									
								
								xCAT-web/lib/CommandWindow.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								xCAT-web/lib/CommandWindow.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| var CommandWindow = {}; | ||||
|  | ||||
| CommandWindow.updateCommandResult = function() { | ||||
| 	var commandQueryId = "commandQuery"; | ||||
| 	var copyChkBoxId = "copyChkBox"; | ||||
| 	var nodenameHiddenTxtId = "nodename"; | ||||
| 	var nodegrpsCboBoxId = "nodegrpsCboBox"; | ||||
| 	var pshChkBoxId = "pshChkBox"; | ||||
|  | ||||
| 	var serialChkBoxId = "serialChkBox"; | ||||
| 	var verifyChkBoxId = "verifyChkBox"; | ||||
| 	var fanoutTxtBoxId = "fanoutTxtBox"; | ||||
| 	var userIDTxtBoxId = "userIDTxtBox"; | ||||
| 	var rshellTxtBoxId = "rshellTxtBox"; | ||||
| 	var rshellTxtBoxId = "rshellTxtBox"; | ||||
| 	var monitorChkBoxId = "monitorChkBox"; | ||||
| 	var ret_codeChkBoxId = "ret_codeChkBox"; | ||||
|  | ||||
| 	var copyChkBoxObj = $(copyChkBoxId); | ||||
| 	var commandQueryObj = $(commandQueryId); | ||||
| 	var nodenameHiddenTxtObj = $(nodenameHiddenTxtId); | ||||
| 	var nodegrpsCboBoxObj = $(nodegrpsCboBoxId); | ||||
| 	var pshChkBoxObj = $(pshChkBoxId); | ||||
|  | ||||
| 	var serialChkBoxObj = $(serialChkBoxId); | ||||
| 	var verifyChkBoxObj = $(verifyChkBoxId); | ||||
| 	var fanoutTxtBoxObj = $(fanoutTxtBoxId); | ||||
| 	var userIDTxtBoxObj = $(userIDTxtBoxId); | ||||
| 	var rshellTxtBoxObj = $(rshellTxtBoxId); | ||||
| 	var monitorChkBoxObj = $(monitorChkBoxId); | ||||
| 	var ret_codeChkBoxObj = $(ret_codeChkBoxId); | ||||
|  | ||||
| 	// Do AJAX call and get HTML here. | ||||
| 	var url = "dsh_action.php"; | ||||
| 	var postPara = "command=" + encodeURIComponent(commandQueryObj.value); | ||||
| 	postPara += "&node=" + encodeURIComponent(nodenameHiddenTxtObj.value); | ||||
| 	postPara += "&nodegrps=" + encodeURIComponent(nodegrpsCboBoxObj.options[nodegrpsCboBoxObj.selectedIndex].value); | ||||
| 	if (copyChkBoxObj.checked == true)	postPara += "©=on";	else postPara += "©=off"; | ||||
| 	if (pshChkBoxObj.checked == true)	postPara += "&psh=on";	else postPara += "&psh=off"; | ||||
| 	if (serialChkBoxObj.checked == true)	postPara += "&serial=on"; else postPara += "&serial=off"; | ||||
| 	if (verifyChkBoxObj.checked == true)	postPara += "&verify=on"; else postPara += "&verify=off"; | ||||
| 	postPara += "&fanout=" + encodeURIComponent(fanoutTxtBoxObj.value); | ||||
| 	postPara += "&userID=" + encodeURIComponent(userIDTxtBoxObj.value); | ||||
| 	postPara += "&rshell=" + encodeURIComponent(rshellTxtBoxObj.value); | ||||
| 	if (monitorChkBoxObj.checked == true)	postPara += "&monitor=on"; else postPara += "&monitor=off"; | ||||
| 	if (ret_codeChkBoxObj.checked == true)	postPara += "&ret_code=on"; else postPara += "&ret_code=off"; | ||||
|  | ||||
| 	new Ajax.Request(url, { | ||||
| 	  method: 'post', postBody: postPara, | ||||
| 	  onSuccess: function(transport) { | ||||
|     	var htmlContent = transport.responseText; | ||||
|  | ||||
| 		 var win = new Window({className: "dialog", | ||||
| 		 			width: 350, | ||||
| 		 			height: 400, | ||||
| 		 			zIndex: 100, | ||||
| 		 			resizable: true, | ||||
| 		 			title: "Running commands", | ||||
| 		 			showEffect: Effect.BlindDown, | ||||
| 		 			hideEffect: Effect.SwitchOff, | ||||
| 		 			draggable: true, | ||||
| 		 			wiredDrag: true}); | ||||
|  | ||||
| 		 win.getContent().innerHTML = htmlContent; | ||||
| 		 //win.setStatusBar("Status bar info"); | ||||
| 		 win.showCenter(); | ||||
| 	  } | ||||
| 	}); | ||||
| }; | ||||
| @@ -18,7 +18,7 @@ echo <<<EOS | ||||
| <table border="0" cellspacing="1" cellpadding=1> | ||||
| <tr class=TableHeader> | ||||
| 	<td width="88" align=left><input type="checkbox" name="chk_node_all" id="chk_node_all">Groups</td> | ||||
| 	<td>HW Type</td><td>OS</td><td>Mode</td><td>Status</td><td>HW Ctrl Pt</td><td>Comment</td> | ||||
| 	<td>Status</td><td>Comment</td> | ||||
| </tr> | ||||
|  | ||||
| EOS; | ||||
| @@ -60,19 +60,15 @@ function insertGroupTableRow($nodeGroupName, $status) { | ||||
| $img_string = getStatusImage(GroupNodeTable::determineStatus($status)); | ||||
|  | ||||
| //echo '<tr bgcolor="#FFCC00"><td align=left>'; | ||||
| echo '<tr class=TableRow><td align=left>'; | ||||
| echo '<tr class=TableRow><td align=left width=140>'; | ||||
| echo GroupNodeTable::getToggleString($nodeGroupName); | ||||
| echo <<<EOE | ||||
| 	<input type="checkbox" name="chk_node_group_$nodeGroupName"  id="chk_node_group_$nodeGroupName"><b>$nodeGroupName</b></span> | ||||
| 	</td> | ||||
| 	<td> </td> | ||||
| 	<td> </td> | ||||
| 	<td> </td> | ||||
| 	<td><img src="$img_string"></td> | ||||
| 	<td> </td> | ||||
| 	<td align=center><img src="$img_string"></td> | ||||
| 	<td> </td> | ||||
| 	</tr> | ||||
| 	<tr><td colspan=7><div id=div_$nodeGroupName style="display:none"></div></td></tr> | ||||
| 	<tr><td colspan=3><div id=div_$nodeGroupName style="display:none"></div></td></tr> | ||||
| EOE; | ||||
| return; | ||||
| } | ||||
| @@ -88,13 +84,14 @@ function getNodeGroupSection($group, $nodes) { | ||||
| 	$right_arrow_gif = $imagedir . "/grey_arrow_r.gif"; | ||||
| 	$left_arrow_gif = $imagedir . "/grey_arrow_l.gif"; | ||||
|  | ||||
| 	$html .= "<table id='$group' width='100%' cellpadding=0 cellspacing=1 border=0>\n"; | ||||
| 	$html .= "<table id='$group' class=GroupNodeTable width='100%' cellpadding=0 cellspacing=1 border=0>\n"; | ||||
| 	$html .= "<TR class=GroupNodeTableHeader><TD>Node Name</TD><TD>Arch</TD><TD>OS</TD><TD>Mode</TD><TD>Status</TD><TD>Power Method</TD><TD>Comment</TD></TR>\n"; | ||||
|  | ||||
| 	foreach($nodes as $nodeName => $attrs) { | ||||
| 		$html .= GroupNodeTable::getNodeTableRow($nodeName, $attrs); | ||||
| 	} | ||||
|  | ||||
| 	$html .= "<TR bgcolor='#FFFF66'><TD colspan=9 align=right><image src='$left_arrow_gif' alt='Previous page'>    <image src='$right_arrow_gif' alt='Next page'>  </TD></TR>\n"; | ||||
| 	$html .= "<TR class=GroupNodeTableRow><TD colspan=9 align=right><image src='$left_arrow_gif' alt='Previous page'>    <image src='$right_arrow_gif' alt='Next page'>  </TD></TR>\n"; | ||||
| 	$html .= "</table>\n"; | ||||
|  | ||||
| 	return $html; | ||||
| @@ -104,18 +101,18 @@ function getNodeGroupSection($group, $nodes) { | ||||
| 	 * @param The node for which we want to generate the html. | ||||
| 	 */ | ||||
| function getNodeTableRow($nodeName, $attrs) { | ||||
| 	$html = "<tr bgcolor='#FFFF66' class=indent>\n" . | ||||
| 			"<td width=89><input type=checkbox name='node_$nodeName' >$nodeName</td>\n" . | ||||
| 			"<td width=38><div align=center>" . $attrs['arch'] . "</div></td>\n" . | ||||
| 			"<td width=22><div align=center>" . $attrs['osversion'] . "</div></td>\n" . | ||||
| 			"<td width=43><div align=center>" . $attrs['mode'] . "</div></td>\n"; | ||||
| 	$html = "<tr class=GroupNodeTableRow>\n" . | ||||
| 			"<td align=left><input type=checkbox name='node_$nodeName' >$nodeName</td>\n" . | ||||
| 			"<td>" . $attrs['arch'] . "</td>\n" . | ||||
| 			"<td>" . $attrs['osversion'] . "</td>\n" . | ||||
| 			"<td>" . $attrs['mode'] . "</td>\n"; | ||||
|  | ||||
| 	$stat = 'unknown';   //todo: implement | ||||
| 	$img_string = '<img src="' . getStatusImage($stat) . '">'; | ||||
|  | ||||
| 	$html .= "<td width=43><div align=center>" . $img_string . "</div></td>". | ||||
| 			"<td width=85><div align=center>" . $attrs['power'] . "</div></td>". | ||||
| 			"<td width=71><div align=center>" . $attrs['comment'] . "</div></td></tr>"; | ||||
| 	$html .= "<td>" . $img_string . "</td>". | ||||
| 			"<td>" . $attrs['power'] . "</td>". | ||||
| 			"<td>" . $attrs['comment'] . "</td></tr>"; | ||||
|  | ||||
| 	return $html; | ||||
| 	} | ||||
|   | ||||
| @@ -1,73 +1,5 @@ | ||||
| var GroupNodeTableUpdater = {}; | ||||
|  | ||||
| GroupNodeTableUpdater.updateCommandResult = function() { | ||||
| 	var commandQueryId = "commandQuery"; | ||||
| 	var copyChkBoxId = "copyChkBox"; | ||||
| 	var nodenameHiddenTxtId = "nodename"; | ||||
| 	var nodegrpsCboBoxId = "nodegrpsCboBox"; | ||||
| 	var pshChkBoxId = "pshChkBox"; | ||||
|  | ||||
| 	var serialChkBoxId = "serialChkBox"; | ||||
| 	var verifyChkBoxId = "verifyChkBox"; | ||||
| 	var fanoutTxtBoxId = "fanoutTxtBox"; | ||||
| 	var userIDTxtBoxId = "userIDTxtBox"; | ||||
| 	var rshellTxtBoxId = "rshellTxtBox"; | ||||
| 	var rshellTxtBoxId = "rshellTxtBox"; | ||||
| 	var monitorChkBoxId = "monitorChkBox"; | ||||
| 	var ret_codeChkBoxId = "ret_codeChkBox"; | ||||
|  | ||||
| 	var copyChkBoxObj = $(copyChkBoxId); | ||||
| 	var commandQueryObj = $(commandQueryId); | ||||
| 	var nodenameHiddenTxtObj = $(nodenameHiddenTxtId); | ||||
| 	var nodegrpsCboBoxObj = $(nodegrpsCboBoxId); | ||||
| 	var pshChkBoxObj = $(pshChkBoxId); | ||||
|  | ||||
| 	var serialChkBoxObj = $(serialChkBoxId); | ||||
| 	var verifyChkBoxObj = $(verifyChkBoxId); | ||||
| 	var fanoutTxtBoxObj = $(fanoutTxtBoxId); | ||||
| 	var userIDTxtBoxObj = $(userIDTxtBoxId); | ||||
| 	var rshellTxtBoxObj = $(rshellTxtBoxId); | ||||
| 	var monitorChkBoxObj = $(monitorChkBoxId); | ||||
| 	var ret_codeChkBoxObj = $(ret_codeChkBoxId); | ||||
|  | ||||
| 	// Do AJAX call and get HTML here. | ||||
| 	var url = "dsh_action.php"; | ||||
| 	var postPara = "command=" + encodeURIComponent(commandQueryObj.value); | ||||
| 	postPara += "&node=" + encodeURIComponent(nodenameHiddenTxtObj.value); | ||||
| 	postPara += "&nodegrps=" + encodeURIComponent(nodegrpsCboBoxObj.options[nodegrpsCboBoxObj.selectedIndex].value); | ||||
| 	if (copyChkBoxObj.checked == true)	postPara += "©=on";	else postPara += "©=off"; | ||||
| 	if (pshChkBoxObj.checked == true)	postPara += "&psh=on";	else postPara += "&psh=off"; | ||||
| 	if (serialChkBoxObj.checked == true)	postPara += "&serial=on"; else postPara += "&serial=off"; | ||||
| 	if (verifyChkBoxObj.checked == true)	postPara += "&verify=on"; else postPara += "&verify=off"; | ||||
| 	postPara += "&fanout=" + encodeURIComponent(fanoutTxtBoxObj.value); | ||||
| 	postPara += "&userID=" + encodeURIComponent(userIDTxtBoxObj.value); | ||||
| 	postPara += "&rshell=" + encodeURIComponent(rshellTxtBoxObj.value); | ||||
| 	if (monitorChkBoxObj.checked == true)	postPara += "&monitor=on"; else postPara += "&monitor=off"; | ||||
| 	if (ret_codeChkBoxObj.checked == true)	postPara += "&ret_code=on"; else postPara += "&ret_code=off"; | ||||
|  | ||||
| 	new Ajax.Request(url, { | ||||
| 	  method: 'post', postBody: postPara, | ||||
| 	  onSuccess: function(transport) { | ||||
|     	var htmlContent = transport.responseText; | ||||
|  | ||||
| 		 var win = new Window({className: "dialog", | ||||
| 		 			width: 350, | ||||
| 		 			height: 400, | ||||
| 		 			zIndex: 100, | ||||
| 		 			resizable: true, | ||||
| 		 			title: "Running commands", | ||||
| 		 			showEffect: Effect.BlindDown, | ||||
| 		 			hideEffect: Effect.SwitchOff, | ||||
| 		 			draggable: true, | ||||
| 		 			wiredDrag: true}); | ||||
|  | ||||
| 		 win.getContent().innerHTML = htmlContent; | ||||
| 		 //win.setStatusBar("Status bar info"); | ||||
| 		 win.showCenter(); | ||||
| 	  } | ||||
| 	}); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Hides/shows the nodes in a node group table. | ||||
|  */ | ||||
| @@ -109,7 +41,7 @@ GroupNodeTableUpdater.getFailureSpanHTML = function(nodeGroupName) { | ||||
|  | ||||
| GroupNodeTableUpdater.getLoadingSpanHTML = function(nodeGroupName) { | ||||
| 	var spanId = "nodegroup_" + nodeGroupName + "_loading"; | ||||
| 	var html = '<span id="' + spanId + '" style="padding-left: 0.5em; display: none;"><img alt="Loading ..." src="../images/ajax-loader.gif" />Loading ...</span>'; | ||||
| 	var html = '<span id="' + spanId + '" style="padding-left: 0.5em; display: none;"><img alt="Loading ..." src="../images/ajax-loader.gif" /></span>'; | ||||
| 	return html; | ||||
| } | ||||
|  | ||||
| @@ -176,8 +108,6 @@ GroupNodeTableUpdater.updateNodeList = function(nodeGroupName) { | ||||
|  | ||||
| 		// Check whether the table already exists and has already been updated? | ||||
|  | ||||
| 		//var URL = "webservice.php?method=getXCATNodeRows&nodeGroupName=" + encodeURIComponent(nodeGroupName); | ||||
|  | ||||
| 		//alert('About to call Ajax.Updater'); | ||||
| 		new Ajax.Updater(target, URL, { | ||||
| 			method: 'post', parameters: pars, | ||||
|   | ||||
| @@ -1,132 +0,0 @@ | ||||
| <?php | ||||
| require_once("../lib/XCAT/XCATNode/XCATNode.class.php"); | ||||
| require_once("../lib/XCAT/XCATNode/XCATNodeManager.class.php"); | ||||
| require_once("../lib/XCAT/XCATNodeGroup/XCATNodeGroup.class.php"); | ||||
| require_once("../lib/XCAT/XCATNodeGroup/XCATNodeGroupManager.class.php"); | ||||
|  | ||||
| class XCATCommandRunner { | ||||
| 	var $XCATRoot; | ||||
|  | ||||
| 	var $XCATNodeManager; | ||||
|  | ||||
| 	var $XCATNodeGroupManager; | ||||
|  | ||||
| 	function XCATCommandRunner() { | ||||
| 		$this->XCATRoot = '';   //'/opt/xcat/bin';   //todo: get rid of these | ||||
| 		$this->CurrDir = '';    //'/opt/xcat/web'; | ||||
| 		$this->Sudo = '/bin/sudo '; | ||||
|  | ||||
| 		$this->XCATNodeManager = &XCATNodeManager::getInstance(); | ||||
| 		$this->XCATNodeGroupManager = &XCATNodeGroupManager::getInstance(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param String cmdString	The command to execute. | ||||
| 	 * @return An array containing the command output as the first element | ||||
| 	 * 			and the command return status as the second element. | ||||
| 	 */ | ||||
| 	function runCommand($cmdString) { | ||||
| 		$cmdOutput = NULL; | ||||
| 		$cmdReturnStat = NULL; | ||||
| 		exec($cmdString, $cmdOutput, $cmdReturnStat); | ||||
|  | ||||
| 		$outputStat = array(); | ||||
| 		$outputStat["output"] = $cmdOutput; | ||||
| 		$outputStat["returnStat"] = $cmdReturnStat; | ||||
|  | ||||
| 		return $outputStat; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Will always return an up to date list of node names belonging to the group. | ||||
| 	 * | ||||
| 	 * @param String groupName	The name of the XCATNodeGroup | ||||
| 	 * @return An array containing the name of all nodes in the group. | ||||
| 	 */ | ||||
| 	function getNodeNamesByGroupName($groupName) { | ||||
| 		$cmdString = $this->Sudo . "nodels $groupName"; | ||||
| 		$outputStat = $this->runCommand($cmdString); | ||||
|  | ||||
| 		return $outputStat["output"]; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param String nodeName	The name of the node. | ||||
| 	 */ | ||||
| 	function getXCATNodeByName($nodeName) { | ||||
|  | ||||
| 			$cmdString = $this->Sudo . "nodestat $nodeName"; | ||||
| 			$outputStat = $this->runCommand($cmdString); | ||||
|  | ||||
| 			$xcn = new XCATNode(); | ||||
| 			$xcn->setName($nodeName); | ||||
| 			$xcn->setStatus($this->determineNodeStatus($outputStat["output"][0])); | ||||
| 			$xcn->setHwType("HW Type"); | ||||
| 			$xcn->setOs("OS"); | ||||
| 			$xcn->setMode("Mode"); | ||||
| 			$xcn->setHwCtrlPt("HW Ctrl Pt"); | ||||
| 			$xcn->setComment("Comment"); | ||||
|  | ||||
| 			// Add the node to the manager, now that we've loaded it. | ||||
| 			$this->XCATNodeManager->addNode($xcn); | ||||
|  | ||||
|  | ||||
| 			return $xcn; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param String nodestatStr	The status of the node as output by the nodestat command | ||||
| 	 * @return "good", "bad", or "other" | ||||
| 	 */ | ||||
| 	function determineNodeStatus($nodestatStr) { | ||||
| 		$status = NULL; | ||||
|  | ||||
| 		if ((strpos($nodestatStr, "ready") != FALSE) || | ||||
| 			(strpos($nodestatStr, "pbs") != FALSE) || | ||||
| 			(strpos($nodestatStr, "sshd") != FALSE)) { | ||||
| 			$status = 'good'; | ||||
| 		} else if(strpos($nodestatStr, "noping") != FALSE) { | ||||
| 			$status = 'bad'; | ||||
| 		} else { | ||||
| 			$status = 'other'; | ||||
| 		} | ||||
|  | ||||
| 		return $status; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return An array containing the name of every node group. | ||||
| 	 */ | ||||
| 	function getAllGroupNames() { | ||||
| 		$cmdString = $this->Sudo . "listattr"; | ||||
| 		$outputStat = $this->runCommand($cmdString); | ||||
|  | ||||
| 		return $outputStat["output"]; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param String groupName	The name of the group we want to get. | ||||
| 	 * @return An XCATNodeGroup object representing | ||||
| 	 * 			the node group with the given name. This object will | ||||
| 	 * 			contain the XCATNodes belonging to this XCATNodeGroup. | ||||
| 	 */ | ||||
| 	function getXCATNodeByGroupName($groupName) { | ||||
| 			$nodeNames = $this->getNodeNamesByGroupName($groupName); | ||||
|  | ||||
| 			$xcatNodes = array(); | ||||
|  | ||||
| 			foreach($nodeNames as $nodeName) { | ||||
| 				$xcatNode = $this->getXCATNodeByName($nodeName); | ||||
| 				array_push($xcatNodes, $xcatNode); | ||||
| 			} | ||||
|  | ||||
| 			$xcatNodeGroup = new XCATNodeGroup(); | ||||
| 			$xcatNodeGroup->setName($groupName); | ||||
| 			$xcatNodeGroup->setNodes($xcatNodes); | ||||
|  | ||||
|  | ||||
| 		return $xcatNodeGroup; | ||||
| 	} | ||||
|  | ||||
| } | ||||
| ?> | ||||
| @@ -1,74 +0,0 @@ | ||||
| <?php | ||||
| /** | ||||
|  * XCATNode entity class. | ||||
|  */ | ||||
| class XCATNode { | ||||
| 	var $name; | ||||
| 	var $hwType; | ||||
| 	var $os; | ||||
| 	var $mode; | ||||
| 	var $status; | ||||
| 	var $hwCtrlPt; | ||||
| 	var $comment; | ||||
|  | ||||
| 	function XCATNode() { | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	function getName() { | ||||
| 		return $this->name; | ||||
| 	} | ||||
|  | ||||
| 	function getHwType() { | ||||
| 		return $this->hwType; | ||||
| 	} | ||||
|  | ||||
| 	function getOs() { | ||||
| 		return $this->os; | ||||
| 	} | ||||
|  | ||||
| 	function getMode() { | ||||
| 		return $this->mode; | ||||
| 	} | ||||
|  | ||||
| 	function getStatus() { | ||||
| 		return $this->status; | ||||
| 	} | ||||
|  | ||||
| 	function getHwCtrlPt() { | ||||
| 		return $this->hwCtrlPt; | ||||
| 	} | ||||
|  | ||||
| 	function getComment() { | ||||
| 		return $this->comment; | ||||
| 	} | ||||
|  | ||||
| 	function setName($pName) { | ||||
| 		$this->name = $pName; | ||||
| 	} | ||||
|  | ||||
| 	function setHwType($pHwType) { | ||||
| 		$this->hwType = $pHwType; | ||||
| 	} | ||||
|  | ||||
| 	function setOs($pOs) { | ||||
| 		$this->os = $pOs; | ||||
| 	} | ||||
|  | ||||
| 	function setMode($pMode) { | ||||
| 		$this->mode = $pMode; | ||||
| 	} | ||||
|  | ||||
| 	function setStatus($pStatus) { | ||||
| 		$this->status = $pStatus; | ||||
| 	} | ||||
|  | ||||
| 	function setHwCtrlPt($pHwCtrlPt) { | ||||
| 		$this->hwCtrlPt = $pHwCtrlPt; | ||||
| 	} | ||||
|  | ||||
| 	function setComment($pComment) { | ||||
| 		$this->comment = $pComment; | ||||
| 	} | ||||
| } | ||||
| ?> | ||||
| @@ -1,51 +0,0 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Manages a collection of XCATNode objects. | ||||
|  */ | ||||
| class XCATNodeManager { | ||||
| 	/** | ||||
| 	 * An array of nodes, keyed by name. | ||||
| 	 */ | ||||
| 	var $nodes = array(); | ||||
|  | ||||
| 	function XCATNodeManager() { | ||||
| 		$nodes = array(); | ||||
| 	} | ||||
|  | ||||
| 	function &getInstance() { | ||||
| 		static $instance; | ||||
|  | ||||
| 		if(is_null($instance)) { | ||||
| 			$instance = new XCATNodeManager(); | ||||
| 		} | ||||
|  | ||||
| 		return $instance; | ||||
| 	} | ||||
|  | ||||
| 	function getNodes() { | ||||
| 		return $this->nodes; | ||||
| 	} | ||||
|  | ||||
| 	function setNodes($pNodes) { | ||||
| 		$this->nodes = $pNodes; | ||||
| 	} | ||||
|  | ||||
| 	function addNode($node) { | ||||
| 		$this->nodes[$node->getName()] = $node; | ||||
| 	} | ||||
|  | ||||
| 	function removeNode($node) { | ||||
| 		$this->nodes[$node->getName()] = NULL; | ||||
| 	} | ||||
|  | ||||
| 	function getNodeByName($nodeName) { | ||||
| 		$node = NULL; | ||||
|  | ||||
| 		if(array_key_exists($nodeName, $this->nodes)) { | ||||
| 			$node = $this->nodes[$nodeName]; | ||||
| 		} | ||||
|  | ||||
| 		return $node; | ||||
| 	} | ||||
| } | ||||
| ?> | ||||
| @@ -1,45 +0,0 @@ | ||||
| <?php | ||||
| /** | ||||
|  * XCATNodeGroup entity class. | ||||
|  */ | ||||
| class XCATNodeGroup { | ||||
| 	var $name; | ||||
| 	var $nodes; | ||||
|  | ||||
| 	function XCATNodeGroup() { | ||||
| 		$this->nodes = array(); | ||||
| 	} | ||||
|  | ||||
| 	function getName() { | ||||
| 		return $this->name; | ||||
| 	} | ||||
|  | ||||
| 	function setName($pName) { | ||||
| 		$this->name = $pName; | ||||
| 	} | ||||
|  | ||||
| 	function getNodes() { | ||||
| 		return $this->nodes; | ||||
| 	} | ||||
|  | ||||
| 	function getStatus() { | ||||
| 		return $this->status; | ||||
| 	} | ||||
|  | ||||
| 	function setNodes($pNodes) { | ||||
| 		$this->nodes = $pNodes; | ||||
| 	} | ||||
|  | ||||
| 	function setStatus($pStatus) { | ||||
| 		$this->status = $pStatus; | ||||
| 	} | ||||
|  | ||||
| 	function addNode($node) { | ||||
| 		$this->nodes[$node->getName()] = $node; | ||||
| 	} | ||||
|  | ||||
| 	function removeNode($node) { | ||||
| 		$this->nodes[$node->getName()] = NULL; | ||||
| 	} | ||||
| } | ||||
| ?> | ||||
| @@ -1,51 +0,0 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Manages a collection of XCATNodeGroup objects. | ||||
|  */ | ||||
| class XCATNodeGroupManager { | ||||
| 	/** | ||||
| 	 * An array of node groups, keyed by name. | ||||
| 	 */ | ||||
| 	var $nodeGroups = array(); | ||||
|  | ||||
| 	function XCATNodeGroupManager() { | ||||
| 		$nodes = array(); | ||||
| 	} | ||||
|  | ||||
| 	function &getInstance() { | ||||
| 		static $instance; | ||||
|  | ||||
| 		if(is_null($instance)) { | ||||
| 			$instance = new XCATNodeGroupManager(); | ||||
| 		} | ||||
|  | ||||
| 		return $instance; | ||||
| 	} | ||||
|  | ||||
| 	function getNodeGroups() { | ||||
| 		return $this->nodeGroups; | ||||
| 	} | ||||
|  | ||||
| 	function setNodeGroups($pNodeGroups) { | ||||
| 		$this->nodeGroups = $pNodeGroups; | ||||
| 	} | ||||
|  | ||||
| 	function addNodeGroup($nodeGroup) { | ||||
| 		$this->nodeGroups[$nodeGroup->getName()] = $nodeGroup; | ||||
| 	} | ||||
|  | ||||
| 	function removeNodeGroup($nodeGroup) { | ||||
| 		$this->nodeGroups[$nodeGroup->getName()] = NULL; | ||||
| 	} | ||||
|  | ||||
| 	function getNodeGroupByName($nodeGroupName) { | ||||
| 		$nodeGroup = NULL; | ||||
|  | ||||
| 		if(array_key_exists($nodeGroupName, $this->nodeGroups)) { | ||||
| 			$nodeGroup = $this->nodeGroups[$nodeGroupName]; | ||||
| 		} | ||||
|  | ||||
| 		return $nodeGroup; | ||||
| 	} | ||||
| } | ||||
| ?> | ||||
| @@ -33,7 +33,6 @@ echo <<<EOS | ||||
| EOS; | ||||
|  | ||||
| // These are only needed for popup windows, so only need it for specific pages like groups & dsh | ||||
| //echo "<script src='$TOPDIR/js_xcat/event.js' type='text/javascript'> </script>\n"; | ||||
| //echo "<script src='$TOPDIR/lib/GroupNodeTableUpdater.js' type='text/javascript'> </script>\n"; | ||||
|  | ||||
| //echo "<script src='$TOPDIR/js/prototype.js' type='text/javascript'></script>\n"; | ||||
| @@ -46,10 +45,6 @@ EOS; | ||||
| //echo "<link href='$TOPDIR/css/xcattop.css' rel='stylesheet'>\n"; | ||||
| //echo "<link href='$TOPDIR/css/xcat.css' rel='stylesheet'>\n"; | ||||
|  | ||||
| //echo "<script src='$TOPDIR/js/windows.js' type='text/javascript'></script>\n"; | ||||
| //echo "<script src='$TOPDIR/js/clickTree.js' type='text/javascript'></script>\n"; | ||||
| //echo "<link href='$TOPDIR/css/clickTree.css' rel='stylesheet'>\n"; | ||||
|  | ||||
|  | ||||
| if ($stylesheets) { | ||||
| 	foreach ($stylesheets as $s) { | ||||
| @@ -186,8 +181,8 @@ function insertMenuRow($current, $isTop, $items) { | ||||
| function runcmd ($cmd, $mode, &$output, $options=NULL){ | ||||
|  | ||||
| 	//Set error output to the same source as standard output (on Linux) | ||||
| 	if (strstr($cmd,'2>&1') == FALSE && !$options["NoRedirectStdErr"]) | ||||
| 		$cmd .= ' 2>&1'; | ||||
| 	if (strstr($cmd,'2>&1') == FALSE && !$options["NoRedirectStdErr"]) { $cmd .= ' 2>&1'; } | ||||
| 	$cmd = "/bin/sudo $cmd";      //todo: change this when move to xcat 2 | ||||
|  | ||||
| 	$ret_stat = ""; | ||||
| 	$arr_output = NULL; | ||||
| @@ -235,9 +230,9 @@ function dumpGlobals() { //------------------------------------ | ||||
| # Returns true if the given rpm file is already installed at this version or higher. | ||||
| function isInstalled($rpmfile) { //------------------------------------ | ||||
| 	$aixrpmopt = isAIX() ? '--ignoreos' : ''; | ||||
| 	$lang = isWindows() ? '' : 'LANG=C'; | ||||
| 	$lang = isWindows() ? '' : 'LANG=C';    //todo: add this back in | ||||
| 	$out = array(); | ||||
| 	$rc = runcmd("$lang /bin/rpm -U $aixrpmopt --test $rpmfile", 2, $out); | ||||
| 	$rc = runcmd("rpm -U $aixrpmopt --test $rpmfile", 2, $out); | ||||
| 	# The rc is not reliable in this case because it will be 1 if it is already installed | ||||
| 	# of if there is some other problem like a dependency is not satisfied.  So we parse the | ||||
| 	# output instead. | ||||
| @@ -432,8 +427,8 @@ function getNodes($noderange, $attrs) { | ||||
| 	$nodes = array(); | ||||
| 	foreach ($attrs as $a) { | ||||
| 		$output = array(); | ||||
| 		//echo "<p>/bin/sudo nodels $noderange $a</p>\n"; | ||||
| 		runcmd("/bin/sudo nodels $noderange $a", 2, $output); | ||||
| 		//echo "<p>nodels $noderange $a</p>\n"; | ||||
| 		runcmd("nodels $noderange $a", 2, $output); | ||||
| 		foreach ($output as $line) { | ||||
| 			$vals = preg_split('/: */', $line);   // vals[0] will be the node name | ||||
| 			if (!$nodes[$vals[0]]) { $nodes[$vals[0]] = array(); } | ||||
| @@ -454,7 +449,7 @@ function getNodes($noderange, $attrs) { | ||||
| function getGroups() { | ||||
| 	$groups = array(); | ||||
| 	$output = array(); | ||||
| 	runcmd("/bin/sudo listattr", 2, $output); | ||||
| 	runcmd("listattr", 2, $output); | ||||
| 	foreach ($output as $grp) { $groups[] = $grp; } | ||||
| 	return $groups; | ||||
| } | ||||
| @@ -465,7 +460,7 @@ function getGroups() { | ||||
| function getGroupStatus() { | ||||
| 	$groups = array(); | ||||
| 	$output = array(); | ||||
| 	runcmd("/bin/sudo grpattr", 2, $output); | ||||
| 	runcmd("grpattr", 2, $output); | ||||
| 	foreach ($output as $line) { | ||||
| 		//echo "<p>line=$line</p>"; | ||||
| 		$vals = preg_split('/: */', $line); | ||||
|   | ||||
| @@ -146,6 +146,7 @@ TEXTAREA {vertical-align : middle; font-size : 8pt; font-family : sans-serif; fo | ||||
|  | ||||
| .TableHeader { color: black; background-color : #fffdb0; font-weight : bold; font-size : 9pt; white-space: nowrap; } | ||||
| .TableRow { color: black; background-color : #b3c2d9; font-size : 9pt; white-space: nowrap; } /* #d8dff1 */ | ||||
| .FormTable { color: black; background-color : #CCCCCC; } | ||||
| .Info {color : blue;} | ||||
| .Error {font-weight : bold; color : red;} | ||||
| .Trace {color: gray;  padding: 0px; margin: 0px;} | ||||
|   | ||||
| @@ -7,22 +7,21 @@ $expire_time = gmmktime(0, 0, 0, 1, 1, 2038); | ||||
| setcookie("history", "date;hello.sh", $expire_time); | ||||
|  | ||||
| require_once "$TOPDIR/lib/functions.php"; | ||||
| require_once("$TOPDIR/lib/XCAT/XCATCommand/XCATCommandRunner.class.php"); | ||||
|  | ||||
| insertHeader('Run Commands on Nodes', array('themes/default.css'), | ||||
| 			array('javascripts/prototype.js', 'javascripts/effect.js', 'javascripts/window.js'), | ||||
| insertHeader('Run Commands on Nodes', array("$TOPDIR/themes/default.css"), | ||||
| 			array("$TOPDIR/lib/CommandWindow.js", "$TOPDIR/js/prototype.js", "$TOPDIR/js/scriptaculous.js?load=effects", "$TOPDIR/js/window.js"), | ||||
| 			array('machines','dsh')); | ||||
|  | ||||
| ?> | ||||
| <div id=content> | ||||
| <FORM NAME="dsh_options" onsubmit="checkEmpty();"> | ||||
| <input type="hidden" id="nodename" value=<?php echo @$_REQUEST["node"] ?> > | ||||
| <input type="hidden" id="nodename" value=<?php echo @$_REQUEST["noderange"] ?> > | ||||
| <TABLE class="inner_table" cellspacing=0 cellpadding=5> | ||||
|   <TBODY> | ||||
|   	<TR> | ||||
|   	  <TD colspan="3"> | ||||
| 		<?php if (@$_REQUEST["node"] == ""){ ?> | ||||
|   	  	<font class="BlueBack">Run Command on Group</font> | ||||
| 		<?php if (@$_REQUEST["noderange"] == ""){ ?> | ||||
|   	  	<font class="BlueBack">Run Command on Group:</font> | ||||
|   	  	<SELECT name=nodegrps id=nodegrpsCboBox class=middle> | ||||
|   	  	<OPTION value="">Choose ...</OPTION> | ||||
|   	  	<?php | ||||
| @@ -35,30 +34,21 @@ insertHeader('Run Commands on Nodes', array('themes/default.css'), | ||||
|    		</SELECT> | ||||
|  | ||||
|    		<?php }else{ ?> | ||||
|    		<font class="BlueBack">Run Command on Node:</font> | ||||
|    		<SELECT name=nodegrps id=nodegrpsCboBox class=middle> | ||||
|   	  	<OPTION value="">Choose ...</OPTION> | ||||
|   	  	<?php | ||||
|   	  	$nodes = getNodes(NULL, NULL); | ||||
| 		foreach ($nodes as $n) { | ||||
| 				$nodename = $n['hostname']; | ||||
| 				//if($nodename == $currentGroup) { $selected = 'selected'; } else { $selected = ''; } | ||||
| 				echo "<OPTION value='$nodename' $selected>$nodename</OPTION>\n"; | ||||
| 		} | ||||
| 		?> | ||||
|    		</SELECT> | ||||
|    		<?php echo @$_REQUEST["node"];  } ?> | ||||
|    		<font class="BlueBack">Run Command on: </font><?php echo @$_REQUEST["noderange"];  } ?> | ||||
|   	  </TD> | ||||
|   	</TR> | ||||
| 	<TR> | ||||
| 	  <TD colspan="3"> | ||||
| 		<P>Select a previous command from the history, or enter the command and options | ||||
| 		below.  Then click on Run Cmd.</P> | ||||
|  | ||||
| 		<P>Select a previous command from the history, or enter the command and options below. Then click on Run Cmd.</P> | ||||
| 	  </TD> | ||||
| 	</TR> | ||||
|     <TR> | ||||
|       <TD colspan="3"><font class="BlueBack">Command History: </font> | ||||
|       <TD colspan="3"><p> | ||||
| 		<INPUT type="button" id="runCmdButton" name="runCmdButton" value="Run Cmd" class=middle onclick="CommandWindow.updateCommandResult()"></p> | ||||
|       </TD> | ||||
|     </TR> | ||||
|     <TR> | ||||
|       <TD colspan="3"><font class="BlueBack">Command History:</font> | ||||
|       <SELECT name="history" onChange="_setvars();" class="middle"> | ||||
|       <OPTION value="">Choose ...</OPTION> | ||||
|       <?php | ||||
| @@ -77,89 +67,98 @@ insertHeader('Run Commands on Nodes', array('themes/default.css'), | ||||
|     <TR> | ||||
|       <TD colspan="3"><div id="commandResult"></div></TD> | ||||
|     </TR> | ||||
|     <TR> | ||||
|       <TD colspan="3"><p> | ||||
| 		<INPUT type="button" id="runCmdButton_top" name="runCmdButton_top" value="Run Cmd" class=middle ></p> | ||||
|       </TD> | ||||
|     </TR> | ||||
|     <TR bgcolor="CCCCCC"> | ||||
|       <TD colspan="3"><font class="BlueBack">Command:</font>  | ||||
|     <TR class=FormTable> | ||||
|       <TD colspan="3">Command:  | ||||
|       <INPUT size="80" type="text" name="command" id="commandQuery" class="middle"></TD> | ||||
|     </TR> | ||||
|     <TR bgcolor="CCCCCC"> | ||||
|     <TR class=FormTable> | ||||
|       <TD colspan="3" nowrap><INPUT type="checkbox" name="copy_script" id="copyChkBox"> | ||||
| 		Copy command to nodes  (The command specified above will 1st be copied | ||||
|       	to /tmp on the nodes and executed from there.)</TD> | ||||
|     </TR> | ||||
|     <TR bgcolor="CCCCCC"> | ||||
|     <TR class=FormTable> | ||||
|       <TD colspan="3" nowrap><INPUT type="checkbox" name="run_psh" id="pshChkBox"> | ||||
| 		Use parallel shell (psh) command</TD> | ||||
| 		Use parallel shell (psh) command instead of xdsh.</TD> | ||||
|     </TR> | ||||
|     <TR bgcolor="CCCCCC"> | ||||
|       <TD colspan="3" class="BlueBack"><B>Options:</TD> | ||||
|     <TR class=FormTable> | ||||
|       <TD colspan="3"><B>Options:</TD> | ||||
|     </TR> | ||||
|     <TR bgcolor="CCCCCC"> | ||||
|     <TR class=FormTable> | ||||
|       <TD width="37"></TD> | ||||
|       <TD width="210" valign="top" nowrap><INPUT type="checkbox" name="serial" id="serialChkBox" checked>Streaming mode</TD> | ||||
|       <TD width="500">Specifies that output is returned as it becomes available from each target, instead of waiting for the command_list to be completed on a target before returning output.</TD> | ||||
|       <TD width="500">Specifies that output is returned as it becomes available from each target, instead of waiting for the command to be completed on a target before returning output from that target.</TD> | ||||
|     </TR> | ||||
|     <TR bgcolor="CCCCCC"> | ||||
|       <TD width="37"></TD> | ||||
|       <TD width="210" valign="top" nowrap><INPUT type="checkbox" name="verify" id="verifyChkBox">Verify</TD> | ||||
|       <TD width="500">Verifies that nodes are responding before sending the command to them.</TD> | ||||
|     <TR class=FormTable> | ||||
|       <TD></TD> | ||||
|       <TD valign="top" nowrap><INPUT type="checkbox" name="monitor" id="monitorChkBox">Monitor</TD> | ||||
|       <TD>Prints starting and completion messages for each node.  Useful with Streaming mode.</TD> | ||||
|     </TR> | ||||
|     <TR bgcolor="CCCCCC"> | ||||
|       <TD width="37"></TD> | ||||
|       <TD width="210" valign="top" nowrap><INPUT type="checkbox" name="collapse" id="collapseChkBox">Collaspe Identical Output</TD> | ||||
|       <TD width="500">Automatically pipe the dsh output into dshbak which will only display output once for all the nodes that display identical output.  See the dshbak man page for more info.</TD> | ||||
|     <TR class=FormTable> | ||||
|       <TD></TD> | ||||
|       <TD valign="top" nowrap><INPUT type="checkbox" name="verify" id="verifyChkBox">Verify</TD> | ||||
|       <TD>Verifies that nodes are responding before sending the command to them.</TD> | ||||
|     </TR> | ||||
|     <TR bgcolor="CCCCCC"> | ||||
|       <TD width="37"></TD> | ||||
|       <TD width="210" valign="top" nowrap>Fanout:<INPUT type="text" name="fanout" id="fanoutTxtBox"></TD> | ||||
|       <TD width="500">The maximum number of nodes the command should be run on concurrently. When the command finishes on 1 of the nodes, it will be started on an additional node (the default is 64).</TD> | ||||
|     <TR class=FormTable> | ||||
|       <TD></TD> | ||||
|       <TD valign="top" nowrap><INPUT type="checkbox" name="collapse" id="collapseChkBox">Collaspe Identical Output</TD> | ||||
|       <TD>Automatically pipe the xdsh output into xdshbak which will only display output once for all the nodes that display identical output.  See the xdshbak man page for more info.</TD> | ||||
|     </TR> | ||||
|     <TR bgcolor="CCCCCC"> | ||||
|       <TD width="37"></TD> | ||||
|       <TD width="210" valign="top" nowrap>UserID:<INPUT type="text" name="userID" id="userIDTxtBox"></TD> | ||||
|       <TD width="500">The user id to use to run the command on the nodes.</TD> | ||||
|     <TR class=FormTable> | ||||
|       <TD></TD> | ||||
|       <TD valign="top" nowrap>Fanout:<INPUT type="text" name="fanout" id="fanoutTxtBox"></TD> | ||||
|       <TD>The maximum number of nodes the command should be run on concurrently. When the command finishes on 1 of the nodes, it will be started on an additional node (the default is 64).</TD> | ||||
|     </TR> | ||||
|     <TR bgcolor="CCCCCC"> | ||||
|       <TD width="37"></TD> | ||||
|       <TD width="210" valign="top" nowrap>Remote Shell:<INPUT type="text" name="rshell" id="rshellTxtBox"></TD> | ||||
|       <TD width="500">The remote shell program to use to run the command on the nodes, for example /usr/bin/ssh. (The default is stored by the csmconfig command or DSH_REMOTE_CMD enviroment variable).</TD> | ||||
|     <TR class=FormTable> | ||||
|       <TD></TD> | ||||
|       <TD valign="top" nowrap>UserID:<INPUT type="text" name="userID" id="userIDTxtBox"></TD> | ||||
|       <TD>The user id to use to run the command on the nodes.</TD> | ||||
|     </TR> | ||||
|     <TR bgcolor="CCCCCC"> | ||||
|       <TD width="37"></TD> | ||||
|       <TD width="210" valign="top" nowrap>Shell Options:<INPUT type="txt" name="shell_opt" id="shell_optTxtBox"></TD> | ||||
|       <TD width="500">Options to pass to the remote shell being used.</TD> | ||||
|     <TR class=FormTable> | ||||
|       <TD></TD> | ||||
|       <TD valign="top" nowrap>Remote Shell:<INPUT type="text" name="rshell" id="rshellTxtBox"></TD> | ||||
|       <TD>The remote shell program to use to run the command on the nodes. The default is /usr/bin/ssh.</TD> | ||||
|     </TR> | ||||
|     <TR bgcolor="CCCCCC"> | ||||
|       <TD width="37"></TD> | ||||
|       <TD width="210" valign="top" nowrap><INPUT type="checkbox" name="monitor" id="monitorChkBox">Monitor</TD> | ||||
|       <TD width="500">Prints the results of monitoring for each node in the form of the starting and completion messages for each node.</TD> | ||||
|     <TR class=FormTable> | ||||
|       <TD></TD> | ||||
|       <TD valign="top" nowrap>Shell Options:<INPUT type="txt" name="shell_opt" id="shell_optTxtBox"></TD> | ||||
|       <TD>Options to pass to the remote shell being used.</TD> | ||||
|     </TR> | ||||
|     <TR bgcolor="CCCCCC"> | ||||
|       <TD width="37"></TD> | ||||
|       <TD width="210" valign="top" nowrap><INPUT type="checkbox" name="ret_code" id="ret_codeChkBox">Code Return</TD> | ||||
|       <TD width="500">Prints the return code of the last command that was run remotely. The return code is appended at the end of the output for each node.</TD> | ||||
|     </TR> | ||||
|     <TR> | ||||
|       <TD colspan="3"> | ||||
| 		<INPUT type="button" id="runCmdButton_bottom" name="runCmdButton_bottom" value="Run Cmd" class=middle > | ||||
|  | ||||
|       </TD> | ||||
|     <TR class=FormTable> | ||||
|       <TD></TD> | ||||
|       <TD valign="top" nowrap><INPUT type="checkbox" name="ret_code" id="ret_codeChkBox">Code Return</TD> | ||||
|       <TD>Prints the return code of the (last) command that was run remotely on each node. The return code is appended at the end of the output for each node.</TD> | ||||
|     </TR> | ||||
|     <TR><TD colspan="3"> | ||||
| 		<font class="BlueBack">Tips:</font> | ||||
| 		<UL> | ||||
| 		  <LI>See the <A href="$::CSMDIR/doc.cgi?book=cmdref§ion=dsh">psh man page</A> for more information about this command.</LI> | ||||
| 		  <LI>See the <A href="<?php echo $TOPDIR; ?>/support/doc.php?book=manpages&section=xdsh">xdsh man page</A> for more information about this command.</LI> | ||||
| 		</UL> | ||||
| 	</TD></TR> | ||||
|   </TBODY> | ||||
| </TABLE> | ||||
| </FORM> | ||||
| <div> | ||||
| <script type="text/javascript" src="js_xcat/event.js"> </script> | ||||
| <script type="text/javascript" src="js_xcat/ui.js"> </script> | ||||
| <SCRIPT language="JavaScript"> | ||||
| <!-- | ||||
| // in CSM perl script this portion used to be javascript to get | ||||
| // and set cookies, now php has handled it | ||||
|  | ||||
| window.onload = function(){window.document.dsh_options.runCmdButton.focus()}; | ||||
| function _setvars(){ | ||||
| 	var form = window.document.dsh_options; | ||||
| 	form.command.value = form.history.value; | ||||
| } | ||||
| function checkEmpty(){ | ||||
| 	var form = window.document.dsh_options; | ||||
| 	var cmd = form.command.value; | ||||
| 	if (cmd.length == 0) | ||||
| 	  { | ||||
| 	    alert('Enter a command before pressing the Run Cmd button.'); | ||||
| 	    return false; | ||||
| 	  } | ||||
| 	else { return true; } | ||||
| } | ||||
| --> | ||||
| </SCRIPT> | ||||
| </BODY> | ||||
| </HTML> | ||||
| @@ -1,29 +1,26 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Action file for running dsh/psh and output the results to the screen | ||||
|  * Action file for running xdsh/psh and output the results to the screen | ||||
|  */ | ||||
|  | ||||
| /*------------------------------------------------------------------------------ | ||||
|   HTTP Headers: headers, cookies, ... | ||||
| -------------------------------------------------------------------------------*/ | ||||
| $TOPDIR = '..'; | ||||
| require_once "$TOPDIR/lib/functions.php"; | ||||
|  | ||||
|  | ||||
| // HTTP Headers: headers, cookies, ... | ||||
| header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // date in the past | ||||
| header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // always modified | ||||
| header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1 | ||||
| header("Cache-Control: post-check=0, pre-check=0", false); | ||||
| header("Pragma: no-cache"); // HTTP/1.0 | ||||
|  | ||||
| /* | ||||
|  * Store commands into Cookie | ||||
|  */ | ||||
| // Store commands into Cookie | ||||
| //setcookie("history",""); | ||||
| $expire_time = gmmktime(0, 0, 0, 1, 1, 2038); | ||||
| ?> | ||||
|  | ||||
| <FORM> | ||||
| <?php | ||||
| require_once("lib/XCAT/XCATCommand/XCATCommandRunner.class.php"); | ||||
|  | ||||
| require_once "$TOPDIR/functions.php"; | ||||
|  | ||||
| //echo "history:" . $_COOKIE["history"]; | ||||
|  | ||||
| @@ -48,14 +45,14 @@ require_once "$TOPDIR/functions.php"; | ||||
| 		 if ($group == "")	$nodegrps = "blade7";	// For now, use blade7 as test node | ||||
|  | ||||
| 		 if ($psh == "off"){ //using dsh | ||||
| 			$command = $SYSTEMROOT . "/dsh "; | ||||
| 			$copy_cmd = $SYSTEMROOT . "/dcp "; | ||||
| 			$command = "xdsh "; | ||||
| 			$copy_cmd = "xdcp "; | ||||
| 			if ($group == "") $node_group = "-n " . $nodegrps; | ||||
| 			else $node_group = "-N " . $group; | ||||
|  | ||||
| 		 }else{ | ||||
| 		 	$command = $XCATROOT . "/psh "; | ||||
| 			$copy_cmd = $XCATROOT . "/prcp "; | ||||
| 		 	$command = "psh "; | ||||
| 			$copy_cmd = "prcp "; | ||||
| 			if ($group == "") $node_group = $nodegrps; | ||||
| 			else $node_group = $group; | ||||
| 		 } | ||||
| @@ -66,9 +63,9 @@ require_once "$TOPDIR/functions.php"; | ||||
| 		if ($verify == "on")  $options .= "-v "; | ||||
| 		if ($monitor == "on")  $options .= "-m "; | ||||
|  | ||||
| 		echo "<p>Command executed: ". $cmd ."</br></p>"; | ||||
| 		//echo "<p>Command: ". $cmd ."</p>"; | ||||
|  | ||||
| 		$exp_cmd = "export DSH_CONTEXT=XCAT XCATROOT=/opt/xcat; "; | ||||
| 		//$exp_cmd = "export DSH_CONTEXT=XCAT XCATROOT=/opt/xcat; "; | ||||
|  | ||||
| 		if ($copy == "on"){		//using dcp/prcp | ||||
|  | ||||
| @@ -79,38 +76,36 @@ require_once "$TOPDIR/functions.php"; | ||||
| 			$source = "/opt/xcat/bin/" . $script; //copy from | ||||
| 			$target = "/tmp";	//copy to | ||||
| 			if ($psh == "off"){ | ||||
| 				$copy_cmd = $exp_cmd . "sudo " . $copy_cmd . $node_group . " " . $source . " " . $target; | ||||
| 				$copy_cmd = $exp_cmd . $copy_cmd . $node_group . " " . $source . " " . $target; | ||||
| 			}else{ | ||||
| 				$copy_cmd = "sudo " . $copy_cmd . $source . " " . $node_group . ":" . $target; | ||||
| 				$copy_cmd = $copy_cmd . $source . " " . $node_group . ":" . $target; | ||||
| 			} | ||||
| 			runcmd($copy_cmd,1, $outp); | ||||
|  | ||||
| 			if ($psh != "on"){ | ||||
| 				$command_string = $exp_cmd . "sudo ". $command. $node_group . " /tmp/" . $cmd; | ||||
| 				$command_string = $exp_cmd . $command. $node_group . " /tmp/" . $cmd; | ||||
| 			}else{ | ||||
| 				$command_string = "sudo " . $command . $node_group . " /tmp/" . $cmd; | ||||
| 				$command_string = $command . $node_group . " /tmp/" . $cmd; | ||||
| 			} | ||||
|  | ||||
| 		} | ||||
| 		else{ | ||||
| 			if ($psh != "on"){ | ||||
| 				$command_string = $exp_cmd . "sudo ". $command. $node_group . " " . $cmd; | ||||
| 				$command_string = $exp_cmd . $command. $node_group . " " . $cmd; | ||||
| 			}else{ | ||||
| 				$command_string = "sudo " . $command . $node_group . " " . $cmd; | ||||
| 				$command_string = $command . $node_group . " " . $cmd; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		//using dshbak to format the output | ||||
| 		$command_string .= " | $SYSTEMROOT/dshbak "; | ||||
| 		if ($collapse == "on")  $command_string .= " | dshbak -c"; | ||||
|  | ||||
| 		if ($collapse == "on")  $command_string .= "-c "; | ||||
|  | ||||
| 		echo " Full command (for TEST purpose): " . $command_string . "</br>"; | ||||
| 		echo "<p><b>Command Ouput:</b></br></p>"; //output will be returned from the runcmd function call | ||||
| 		echo "<p><b>Command:  $command_string</b></p>"; | ||||
| 		//echo "<p><b>Command Ouput:</b></br></p>"; //output will be returned from the runcmd function call | ||||
|  | ||||
| 		//run the script | ||||
| 		$output = array(); | ||||
| 		if ($ret_code == "on"){ | ||||
| 			$rc = runcmd($command_string,0, $outp);	//mode 0 | ||||
| 			$rc = runcmd($command_string, 0, $output);	//mode 0 | ||||
| 			if ($rc == 0){ | ||||
| 				foreach ($outp as $key => $val){ | ||||
| 					echo $val. "</br>"; | ||||
| @@ -118,12 +113,10 @@ require_once "$TOPDIR/functions.php"; | ||||
| 			} | ||||
|  | ||||
| 		}else{ | ||||
| 			//$rc = runcmd($command_string,1, $outp);	//streaming mode  COMMENTED AS BY SOME WAY THIS DOESN'T WORK YET | ||||
| 			$rc = runcmd($command_string,0, $outp);	//mode 0 | ||||
| 			//$rc = runcmd($command_string,1, $outp);	//streaming mode - DOES NOT WORK YET | ||||
| 			$rc = runcmd($command_string, 0, $output);	//mode 0 | ||||
| 			if ($rc == 0){ | ||||
| 				foreach ($outp as $key => $val){ | ||||
| 					echo $val. "</br>"; | ||||
| 				} | ||||
| 				foreach ($output as $line){ echo "$line<br>"; } | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
|   | ||||
| @@ -7,3 +7,7 @@ | ||||
|  text-align: center; | ||||
|  margin: 5px; | ||||
| } | ||||
|  | ||||
| .GroupNodeTable { margin-left: 10px; } | ||||
| .GroupNodeTableHeader { color: black; background-color : #FFFF66; font-weight : bold; white-space: nowrap; } | ||||
| .GroupNodeTableRow { color: black; background-color : #FFFF66; white-space: nowrap; } | ||||
|   | ||||
| @@ -57,7 +57,7 @@ insertButtons(array( | ||||
|  | ||||
| echo '<form name="nodelist" class=ContentForm>'; | ||||
|  | ||||
| /* $output = array(); runcmd("/bin/sudo listattr", 2, $output); foreach ($output as $line) { echo "<p>line=$line</p>"; } */ | ||||
| /* $output = array(); runcmd("listattr", 2, $output); foreach ($output as $line) { echo "<p>line=$line</p>"; } */ | ||||
|  | ||||
| GroupNodeTable::insertGroupTableHeader(); | ||||
|  | ||||
|   | ||||
| @@ -22,12 +22,12 @@ See <a href="https://sourceforge.net/projects/xcat">xCAT on SourceForge</a>. Tha | ||||
| approximately priority order:</p> | ||||
|  | ||||
| <ul> | ||||
|   <li>Update the spec file for this web interface to have all the necessary post installation scripts.</li> | ||||
|   <li>One button update of this web interface from the internet.</li> | ||||
|   <li>Restructure the files in lib/XCAT and js_xcat to make them simpler.</li> | ||||
|   <li>Have the task pane save the current task in the cookie and have each page set the current task.</li> | ||||
|   <li>Do frame view and rack layout pages.</li> | ||||
|   <li>Do several of the buttons within the machines views: | ||||
|   <li>Update the spec file for this web interface to have all the necessary post installation scripts (Bruce)</li> | ||||
|   <li>One button update of this web interface from the internet (Bruce)</li> | ||||
|   <li>Improve the look of associating the top menu with the 2nd menu (Quyen)</li> | ||||
|   <li>Have the task pane save the current task in the cookie and have each page set the current task (Bruce)</li> | ||||
|   <li>Do frame view and rack layout pages (Bruce)</li> | ||||
|   <li>Do several of the buttons within the machines views (Bruce): | ||||
|   <ul> | ||||
|     <li>Attributes</li> | ||||
|     <li>Ping</li> | ||||
| @@ -37,9 +37,9 @@ approximately priority order:</p> | ||||
|     <li>Diagnose</li> | ||||
|   </ul> | ||||
|   </li> | ||||
|   <li>Do RMC configuration pages</li> | ||||
|   <li>Do Cluster Settings (site table) page</li> | ||||
|   <li>Start set up cluster wizard page.</li> | ||||
|   <li>Do RMC configuration pages (Bruce)</li> | ||||
|   <li>Do Cluster Settings (site table) page (Bruce)</li> | ||||
|   <li>Start cluster wizard page (Bruce)</li> | ||||
|   <li>Do a summary page that lists # of bad nodes, # of jobs, etc.</li> | ||||
| </ul> | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user