00001 /* 00002 * ################################################################ 00003 * 00004 * ProActive: The Java(TM) library for Parallel, Distributed, 00005 * Concurrent computing with Security and Mobility 00006 * 00007 * Copyright (C) 1997-2007 INRIA/University of Nice-Sophia Antipolis 00008 * Contact: proactive@objectweb.org 00009 * 00010 * This library is free software; you can redistribute it and/or 00011 * modify it under the terms of the GNU Lesser General Public 00012 * License as published by the Free Software Foundation; either 00013 * version 2.1 of the License, or any later version. 00014 * 00015 * This library is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 * Lesser General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU Lesser General Public 00021 * License along with this library; if not, write to the Free Software 00022 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 * USA 00024 * 00025 * Initial developer(s): The ProActive Team 00026 * http://www.inria.fr/oasis/ProActive/contacts.html 00027 * Contributor(s): 00028 * 00029 * ################################################################ 00030 */ 00031 package org.objectweb.proactive.core.process.gridengine; 00032 00033 import org.objectweb.proactive.core.process.AbstractExternalProcessDecorator; 00034 import org.objectweb.proactive.core.process.ExternalProcess; 00035 import org.objectweb.proactive.core.process.MessageSink; 00036 import org.objectweb.proactive.core.process.UniversalProcess; 00037 00038 00061 public class GridEngineSubProcess extends AbstractExternalProcessDecorator { 00062 private static final String FILE_SEPARATOR = System.getProperty( 00063 "file.separator"); 00064 public final static String DEFAULT_QSUBPATH = "/opt/gridengine/bin/glinux/qsub"; 00065 private static final String DEFAULT_SCRIPT_LOCATION = System.getProperty( 00066 "user.home") + FILE_SEPARATOR + "ProActive" + FILE_SEPARATOR + 00067 "scripts" + FILE_SEPARATOR + "unix" + FILE_SEPARATOR + "cluster" + 00068 FILE_SEPARATOR + "gridEngineStartRuntime.sh "; 00069 protected static final String DEFAULT_HOSTS_NUMBER = "1"; 00070 protected static final String DEFAULT_PARALLEL_ENVIRONMENT = null; 00071 protected String hostNumber = DEFAULT_HOSTS_NUMBER; 00072 protected String parallelEnvironment = DEFAULT_PARALLEL_ENVIRONMENT; 00073 protected String bookingDuration = null; 00074 protected String scriptLocation = DEFAULT_SCRIPT_LOCATION; 00075 00076 //Following options are not yet included in the command 00077 protected String interactive = "false"; 00078 protected String outputFile; 00079 protected String errorFile; 00080 protected int jobID; 00081 protected String queueName; 00082 protected String hostList; 00083 00084 public GridEngineSubProcess() { 00085 super(); 00086 setCompositionType(GIVE_COMMAND_AS_PARAMETER); 00087 this.hostname = null; 00088 this.command_path = DEFAULT_QSUBPATH; 00089 } 00090 00091 public GridEngineSubProcess(ExternalProcess targetProcess) { 00092 super(targetProcess); 00093 this.hostname = null; 00094 this.command_path = DEFAULT_QSUBPATH; 00095 } 00096 00097 //---------------------------------------------------------------------------------------- 00098 //-----------------------Extends AbstractExternalProcessDecorator------------------------- 00099 // ---------------------------------------------------------------------------------------- 00100 public void setOutputMessageSink(MessageSink outputMessageSink) { 00101 if (outputMessageSink == null) { 00102 super.setOutputMessageSink(new SimpleMessageSink()); 00103 } else { 00104 super.setOutputMessageSink(outputMessageSink); 00105 } 00106 } 00107 00112 public void setBookingDuration(String d) { 00113 this.bookingDuration = d; 00114 } 00115 00120 public String getHostsNumber() { 00121 return this.hostNumber; 00122 } 00123 00128 public void setHostsNumber(String hostNumber) { 00129 checkStarted(); 00130 if (hostNumber != null) { 00131 this.hostNumber = hostNumber; 00132 } 00133 } 00134 00138 public String getProcessId() { 00139 return "gridengine_" + targetProcess.getProcessId(); 00140 } 00141 00145 public int getNodeNumber() { 00146 return (new Integer(getHostsNumber()).intValue()); 00147 } 00148 00152 public UniversalProcess getFinalProcess() { 00153 checkStarted(); 00154 ; 00155 return targetProcess.getFinalProcess(); 00156 } 00157 00162 public void setScriptLocation(String location) { 00163 checkStarted(); 00164 // if (location != null) { 00165 this.scriptLocation = location; 00166 // } 00167 } 00168 00173 public void setParallelEnvironment(String p) { 00174 this.parallelEnvironment = p; 00175 } 00176 00181 public String getParallelEnvironment() { 00182 return this.parallelEnvironment; 00183 } 00184 00190 public void setHostList(String hostList) { 00191 checkStarted(); 00192 this.hostList = hostList; 00193 } 00194 00200 public String getHostList() { 00201 return hostList; 00202 } 00203 00209 public void setInteractive(String interactive) { 00210 this.interactive = interactive; 00211 } 00212 00216 public void setOutputFile(String string) { 00217 outputFile = string; 00218 } 00219 00223 public void setErrorFile(String string) { 00224 errorFile = string; 00225 } 00226 00231 public void setQueueName(String queueName) { 00232 checkStarted(); 00233 if (queueName == null) { 00234 throw new NullPointerException(); 00235 } 00236 this.queueName = queueName; 00237 } 00238 00239 protected String parseHostname(String message) { 00240 //To be modified for SGE, does not work with the present code 00241 String result = new String(); 00242 if (logger.isDebugEnabled()) { 00243 logger.debug("parseHostname() analyzing " + message); 00244 } 00245 java.util.StringTokenizer st = new java.util.StringTokenizer(message); 00246 if (st.countTokens() < 2) { 00247 return null; //at least two tokens 00248 } 00249 if (!":".equals(st.nextToken())) { 00250 return null; //should start with : 00251 } 00252 00253 while (st.hasMoreTokens()) { 00254 result += (st.nextToken()); 00255 result += " "; 00256 } 00257 return result; 00258 } 00259 00260 protected String internalBuildCommand() { 00261 return buildEnvironmentCommand(); // + buildPSubCommand(); 00262 } 00263 00264 protected String buildCommand() { 00265 StringBuilder qsubCommand = new StringBuilder(); 00266 00267 qsubCommand.append(command_path).append(" -S /bin/bash "); 00268 00269 if ((this.queueName != null) && (this.queueName.length() > 0)) { 00270 qsubCommand.append("-q ").append(queueName).append(" "); 00271 } 00272 00273 if ((this.outputFile != null) && (this.outputFile.length() > 0)) { 00274 qsubCommand.append("-o ").append(outputFile).append(" "); 00275 } 00276 00277 if ((this.errorFile != null) && (this.errorFile.length() > 0)) { 00278 qsubCommand.append("-e ").append(errorFile).append(" "); 00279 } 00280 00281 if ((this.parallelEnvironment != null) && 00282 (this.parallelEnvironment.length() > 0)) { 00283 qsubCommand.append("-pe ").append(parallelEnvironment).append(" "); 00284 00285 if ((this.hostNumber != null) && (this.hostNumber.length() > 0)) { 00286 qsubCommand.append(hostNumber).append(" "); 00287 } else { 00288 qsubCommand.append("1").append(" "); 00289 } 00290 } else { 00291 if ((this.hostNumber != null) && (this.hostNumber.length() > 0)) { 00292 logger.warn( 00293 "You specified hostNumber without a parallelEnvironment. Your job will fail. Please update your schema"); 00294 } 00295 } 00296 00297 if (this.bookingDuration != null) { 00298 qsubCommand.append(" -l s_rt=" + bookingDuration + " ") ; 00299 } 00300 00301 qsubCommand.append(scriptLocation).append(" "); 00302 qsubCommand.append(targetProcess.getCommand()); 00303 00304 if (logger.isDebugEnabled()) { 00305 logger.debug("qsub command is " + qsubCommand.toString()); 00306 } 00307 00308 //System.out.println("GridEngineSubProcess.buildCommand() " + qsubCommand); 00309 return qsubCommand.toString(); 00310 } 00311 00312 protected String buildResourceString() { 00313 StringBuilder rs = new StringBuilder(); 00314 rs.append(" -l walltime=").append(bookingDuration).append(","); 00315 //to specify nodes and processor per nodes, the syntax is different from 00316 //other resources 00317 rs.append("nodes=").append(hostNumber).append(":"); 00318 00319 return rs.toString(); 00320 } 00321 }