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.prun; 00032 00033 import java.util.StringTokenizer; 00034 00035 import org.objectweb.proactive.core.config.ProActiveConfiguration; 00036 import org.objectweb.proactive.core.process.AbstractExternalProcessDecorator; 00037 import org.objectweb.proactive.core.process.ExternalProcess; 00038 import org.objectweb.proactive.core.process.MessageSink; 00039 import org.objectweb.proactive.core.process.SimpleExternalProcess; 00040 import org.objectweb.proactive.core.process.UniversalProcess; 00041 00042 00064 public class PrunSubProcess extends AbstractExternalProcessDecorator { 00065 00066 // private static final String DEFAULT_SCRIPT_LOCATION = System.getProperty( 00067 // "user.home") + FILE_SEPARATOR + "ProActive" + FILE_SEPARATOR + 00068 // "scripts" + FILE_SEPARATOR + "unix" + FILE_SEPARATOR + "cluster" + 00069 // FILE_SEPARATOR + "startRuntime.sh "; 00070 // public final static String DEFAULT_PBSPATH = FILE_SEPARATOR + "usr" + 00071 // FILE_SEPARATOR + "local" + FILE_SEPARATOR + "pbs" + FILE_SEPARATOR + 00072 // "bin"; 00073 // public final static String DEFAULT_QSUBPATH = DEFAULT_PBSPATH + 00074 // FILE_SEPARATOR + "qsub"; 00075 public final static String DEFAULT_PRUNPATH = "/usr/local/bin/prun"; 00076 00077 // public final static String DEFAULT_QJOBPATH = DEFAULT_PBSPATH + 00078 // FILE_SEPARATOR + "qjobs"; 00079 // public static final String DEFAULT_QUEUE_NAME = "normal"; 00080 protected static final String DEFAULT_HOSTS_NUMBER = "1"; 00081 protected static final String DEFAULT_PROCESSOR_NUMBER = "1"; 00082 protected static final String DEFAULT_BOOKING_DURATION = "00:01:00"; 00083 private static final String FILE_TRANSFER_DEFAULT_PROTOCOL = null; 00084 protected int jobID; 00085 protected String queueName; 00086 protected String hostList; 00087 00088 // protected String scriptLocation = DEFAULT_SCRIPT_LOCATION; 00089 protected String hosts = DEFAULT_HOSTS_NUMBER; 00090 protected String processorPerNode = DEFAULT_PROCESSOR_NUMBER; 00091 protected String bookingDuration = DEFAULT_BOOKING_DURATION; 00092 protected String interactive = "false"; 00093 protected String outputFile; 00094 00095 // 00096 // -- CONSTRUCTORS ----------------------------------------------- 00097 // 00098 00103 public PrunSubProcess() { 00104 super(); 00105 setCompositionType(GIVE_COMMAND_AS_PARAMETER); 00106 this.hostname = null; 00107 this.command_path = DEFAULT_PRUNPATH; 00108 } 00109 00115 public PrunSubProcess(ExternalProcess targetProcess) { 00116 super(targetProcess); 00117 this.hostname = null; 00118 this.command_path = DEFAULT_PRUNPATH; 00119 } 00120 00121 // 00122 // -- PUBLIC METHODS ----------------------------------------------- 00123 // 00124 // public void setInputMessageLogger(RemoteProcessMessageLogger inputMessageLogger) { 00125 // super.setInputMessageLogger(new CompositeMessageLogger( 00126 // new ParserMessageLogger(), inputMessageLogger)); 00127 // } 00128 00129 public void setOutputMessageSink(MessageSink outputMessageSink) { 00130 if (outputMessageSink == null) { 00131 super.setOutputMessageSink(new SimpleMessageSink()); 00132 } else { 00133 super.setOutputMessageSink(outputMessageSink); 00134 } 00135 } 00136 00142 public static ExternalProcess buildBKillProcess(int jobID) { 00143 return new SimpleExternalProcess("qdel " + jobID); 00144 } 00145 00146 public static void main(String[] args) { 00147 ProActiveConfiguration.load(); 00148 try { 00149 PrunSubProcess p = new PrunSubProcess(new SimpleExternalProcess( 00150 "/bin/ls ")); 00151 p.setHostsNumber("2"); 00152 p.setQueueName("plugtest"); 00153 p.startProcess(); 00154 } catch (Exception e) { 00155 e.printStackTrace(); 00156 } 00157 } 00158 00162 public String getOutputFile() { 00163 return outputFile; 00164 } 00165 00170 public void setOutputFile(String string) { 00171 outputFile = string; 00172 } 00173 00178 public int getJobID() { 00179 return jobID; 00180 } 00181 00186 public String getQueueName() { 00187 return queueName; 00188 } 00189 00190 /* (non-Javadoc) 00191 * @see org.objectweb.proactive.core.process.UniversalProcess#stopProcess() 00192 */ 00193 public void stopProcess() { 00194 //System.out.println("PrunSubProcess.stopProcess()"); 00195 super.stopProcess(); 00196 } 00197 00202 public void setQueueName(String queueName) { 00203 checkStarted(); 00204 if (queueName == null) { 00205 throw new NullPointerException(); 00206 } 00207 this.queueName = queueName; 00208 } 00209 00214 public void setHostList(String hostList) { 00215 checkStarted(); 00216 this.hostList = hostList; 00217 } 00218 00223 public String getHostList() { 00224 return hostList; 00225 } 00226 00227 // /** 00228 // * Returns true if this BsubProcess is lauched with -I option false otherwise 00229 // * @return boolean 00230 // */ 00231 // public String isInteractive() { 00232 // return interactive; 00233 // } 00234 00239 public void setBookingDuration(String d) { 00240 this.bookingDuration = d; 00241 } 00242 00247 public String getBookingDuration() { 00248 return this.bookingDuration; 00249 } 00250 00257 protected String parseHostname(String message) { 00258 String result = new String(); 00259 if (logger.isDebugEnabled()) { 00260 logger.debug("parseHostname() analyzing " + message); 00261 } 00262 java.util.StringTokenizer st = new java.util.StringTokenizer(message); 00263 if (st.countTokens() < 2) { 00264 return null; //at least two tokens 00265 } 00266 if (!":".equals(st.nextToken())) { 00267 return null; //should start with : 00268 } 00269 00270 while (st.hasMoreTokens()) { 00271 result += (st.nextToken()); 00272 result += " "; 00273 } 00274 return result; 00275 } 00276 00281 public void setInteractive(String interactive) { 00282 this.interactive = interactive; 00283 } 00284 00289 public void setHostsNumber(String hosts) { 00290 checkStarted(); 00291 if (hosts != null) { 00292 this.hosts = hosts; 00293 } 00294 00295 // System.out.println("-------- setNodeNumber() " + nodes); 00296 } 00297 00302 public void setProcessorPerNodeNumber(String processorPerNode) { 00303 checkStarted(); 00304 if (processorPerNode != null) { 00305 this.processorPerNode = processorPerNode; 00306 } 00307 } 00308 00312 public String getProcessId() { 00313 return "prun_" + targetProcess.getProcessId(); 00314 } 00315 00319 public int getNodeNumber() { 00320 return (new Integer(getProcessorPerNodeNumber()).intValue() * (new Integer(getHostsNumber()).intValue())); 00321 } 00322 00326 public UniversalProcess getFinalProcess() { 00327 checkStarted(); 00328 return targetProcess.getFinalProcess(); 00329 } 00330 00335 public String getHostsNumber() { 00336 return this.hosts; 00337 } 00338 00339 public String getProcessorPerNodeNumber() { 00340 return this.processorPerNode; 00341 } 00342 00343 // public void setScriptLocation(String location) { 00344 // checkStarted(); 00345 // if (location != null) { 00346 // this.scriptLocation = location; 00347 // } 00348 // } 00349 // 00350 // public String getScriptLocation() { 00351 // return scriptLocation; 00352 // } 00353 // 00354 // -- PROTECTED METHODS ----------------------------------------------- 00355 // 00356 protected String internalBuildCommand() { 00357 return buildEnvironmentCommand(); // + buildPSubCommand(); 00358 } 00359 00360 protected void sendJobDetailsCommand() { 00361 // outputMessageSink.setMessage(buildBJobsCommand()); 00362 } 00363 00364 protected void internalStartProcess(String command) 00365 throws java.io.IOException { 00366 // System.out.println( 00367 // "---------------Internal start process of PBSSubProcess " + 00368 // command); 00369 if (logger.isDebugEnabled()) { 00370 logger.debug(command); 00371 } 00372 00373 super.internalStartProcess(command); 00374 } 00375 00376 protected String buildCommand() { 00377 StringBuilder prunCommand = new StringBuilder(); 00378 prunCommand.append(command_path); 00379 if (interactive.equals("true")) { 00380 prunCommand.append(" -I"); 00381 } 00382 00383 String[] commandAndOptions = separateCommandFromOptions(targetProcess.getCommand()); 00384 prunCommand.append(" -no-panda -v -" + processorPerNode + " -t " + 00385 bookingDuration + " "); 00386 00387 if (queueName != null) { 00388 //prunCommand.append("-native '-q " + queueName + "' "); 00389 prunCommand.append("-q " + queueName + " "); 00390 } 00391 00392 if (hostList != null) { 00393 prunCommand.append("-m " + hostList + " "); 00394 } 00395 00396 if (outputFile != null) { 00397 prunCommand.append("-o " + outputFile + " "); 00398 } 00399 00400 prunCommand.append(commandAndOptions[0] + " " + hosts + " " + 00401 commandAndOptions[1]); // " -q " + queueName + " "); 00402 00403 if (logger.isDebugEnabled()) { 00404 logger.debug("prun command is " + prunCommand.toString()); 00405 } 00406 return prunCommand.toString(); 00407 } 00408 00409 protected String[] separateCommandFromOptions(String s) { 00410 String[] result = { "", "" }; 00411 00412 //the problem is that the command we get should be splitted in command+option 00413 //since prun likes to have options for the command at the very end 00414 //of the line, after the requested number of nodes 00415 StringTokenizer st = new StringTokenizer(s); 00416 if (st.countTokens() > 1) { 00417 result[0] = st.nextToken(); 00418 while (st.hasMoreTokens()) { 00419 result[1] += st.nextToken(); 00420 result[1] += " "; 00421 } 00422 } 00423 return result; 00424 } 00425 00426 public String getFileTransferDefaultCopyProtocol() { 00427 return FILE_TRANSFER_DEFAULT_PROTOCOL; 00428 } 00429 00430 // end inner class CompositeMessageLogger 00431 }