Author: chatellier Date: 2009-05-20 13:43:44 +0000 (Wed, 20 May 2009) New Revision: 2259 Added: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/SSHException.java isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/SSHUserInfo.java isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/SSHUtils.java isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/package-info.java Removed: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/ssh/ Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/IsisConfig.java isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationControl.java isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/InProcessSimulatorLauncher.java isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/IsisFishServerSimulationLauncher.java isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SSHSimulatorLauncher.java isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationJob.java isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationMonitor.java isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationService.java isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationServiceTableModel.java isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulatorLauncher.java isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SubProcessSimulationLauncher.java isis-fish/trunk/src/main/java/fr/ifremer/isisfish/ui/simulator/QueueUI.jaxx isis-fish/trunk/src/main/java/fr/ifremer/isisfish/ui/simulator/SimulAction.java isis-fish/trunk/src/main/java/fr/ifremer/isisfish/ui/simulator/launcher/SSHLauncherConfigUI.jaxx isis-fish/trunk/src/main/resources/i18n/isis-fish-en_GB.properties isis-fish/trunk/src/main/resources/i18n/isis-fish-fr_FR.properties isis-fish/trunk/src/main/resources/log4j.properties Log: When a job is stopped, it's forced to stop on caparmor. Can restart stopped jobs. Improve caparmor configuration frame (config tester). Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/IsisConfig.java =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/IsisConfig.java 2009-05-19 21:54:07 UTC (rev 2258) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/IsisConfig.java 2009-05-20 13:43:44 UTC (rev 2259) @@ -55,7 +55,8 @@ import fr.ifremer.isisfish.vcs.VCS; /** - * + * Isis fish configuration. + * * @author poussin * @version $Revision: 1310 $ * @@ -358,7 +359,7 @@ * * @param username username */ - public void setSimulatorSshUsername(String username ) { + public void setSimulatorSshUsername(String username) { setOption(Option.SIMULATOR_SSH_USER_NAME.key, username); } @@ -396,7 +397,7 @@ * * @param isishome isis home */ - public void setSimuatorShhIsisHome(String isishome) { + public void setSimulatorSshIsisHome(String isishome) { setOption(Option.SIMULATOR_SSH_ISIS_HOME.key, isishome); } @@ -422,23 +423,22 @@ } /** - * Retourne la commande a utiliser pour ajouter - * le script à la queue des simulation. + * PBS bin path directory. * - * @return add to queue command + * @return path */ - public String getSimulatorSshAddToQueueCommand() { - String result = getOption(Option.SIMULATOR_SSH_ADDSCRIPTTOQUEUECOMMAND.key); + public String getSimulatorSshPbsBinPath() { + String result = getOption(Option.SIMULATOR_SSH_PBSBINPATH.key); return result; } /** - * Change qsub command. + * Change PBS bin path. * - * @param command new command + * @param path new path */ - public void setSimulatorSshAddToQueueCommand(String command) { - setOption(Option.SIMULATOR_SSH_ADDSCRIPTTOQUEUECOMMAND.key, command); + public void setSimulatorSshPbsBinPath(String path) { + setOption(Option.SIMULATOR_SSH_PBSBINPATH.key, path); } /** @@ -839,19 +839,21 @@ SIMULATOR_PASSWORD("simulator.password", _("isisfish.config.main.password.description"), "guest"), /** Serveur accessible par ssh : address */ - SIMULATOR_SSH_SERVER("simulation.ssh.server", _("isisfish.config.main.simulation.ssh.server.description"), "caparmor.ifremer.fr:22"), + SIMULATOR_SSH_SERVER("simulation.ssh.server", _("isisfish.config.main.simulation.ssh.server.description"), "caparmor.ifremer.fr"), /** Serveur accessible par ssh : login */ - SIMULATOR_SSH_USER_NAME("simulation.ssh.username", _("isisfish.config.main.simulation.ssh.login.description"), "isisfish"), + SIMULATOR_SSH_USER_NAME("simulation.ssh.username", _("isisfish.config.main.simulation.ssh.username.description"), ""), + /** Serveur accessible par ssh : user home directory */ + //SIMULATOR_SSH_USER_HOME("simulation.ssh.userhome", _("isisfish.config.main.simulation.ssh.userhome.description"), ""), /** Serveur accessible par ssh : remote data path */ - SIMULATOR_SSH_DATAPATH("simulation.ssh.datapath", _("isisfish.config.main.simulation.ssh.datapath.description"), "/home/" + SIMULATOR_SSH_USER_NAME.defaultValue + "/isis-database-3"), + SIMULATOR_SSH_DATAPATH("simulation.ssh.datapath", _("isisfish.config.main.simulation.ssh.datapath.description"), "isis-database-3"), /** Serveur accessible par ssh : remote isis home install */ - SIMULATOR_SSH_ISIS_HOME("simulation.ssh.isis.home", _("isisfish.config.main.simulation.ssh.isis.home.description"), "/home/" + SIMULATOR_SSH_USER_NAME.defaultValue + "/isis-fish"), + SIMULATOR_SSH_ISIS_HOME("simulation.ssh.isis.home", _("isisfish.config.main.simulation.ssh.isis.home.description"), "/home3/caparmor/poussin/isis-fish"), /** Serveur accessible par ssh : remote tmp path */ - SIMULATOR_SSH_TMPPATH("simulation.ssh.tmppath", _("isisfish.config.main.simulation.ssh.tmppath.description"), "/tmp"), - /** Serveur accessible par SSH : chemin pour executer le script d'ajout des script dans la queue */ - SIMULATOR_SSH_ADDSCRIPTTOQUEUECOMMAND("simulation.ssh.addscripttoqueuecommand", _("isisfish.config.main.simulation.ssh.addscripttoqueuecommand.description"), "/usr/pbs/bin/qsub"), + SIMULATOR_SSH_TMPPATH("simulation.ssh.tmppath", _("isisfish.config.main.simulation.ssh.tmppath.description"), "isis-tmp"), + /** Serveur accessible par SSH : emplacement des executables pbs */ + SIMULATOR_SSH_PBSBINPATH("simulation.ssh.pbsbinpath", _("isisfish.config.main.simulation.ssh.pbsbinpath.description"), "/usr/pbs/bin"), /** Serveur accessible par SSH : interval de check du fichier de control */ - SIMULATOR_SSH_CONTROLCHECKINTERVAL("simulation.ssh.control.check.interval", _("isisfish.config.main.simulation.ssh.control.check.interval.description"), "5"), + SIMULATOR_SSH_CONTROLCHECKINTERVAL("simulation.ssh.control.check.interval", _("isisfish.config.main.simulation.ssh.control.check.interval.description"), "30"), /** Serveur accessible par SSH : nombre de simulations simultanées sur caparmor */ SIMULATOR_SSH_MAX_SIMULTANEOUS_SIMULATION("simulation.ssh.max.simultaneous.simulation", _("isisfish.config.main.simulation.max.simultaneous.simulation.description"), "20"), Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationControl.java =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationControl.java 2009-05-19 21:54:07 UTC (rev 2258) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationControl.java 2009-05-20 13:43:44 UTC (rev 2259) @@ -75,6 +75,18 @@ } /** + * Reset control values for job restart. + */ + public void reset() { + started = false; + running = true; + stop = false; + date = new Date(); + progressMax = 0; + progress = 0; + } + + /** * * @deprecated todo remove, should be always auto saved * @param autoSaveState Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/InProcessSimulatorLauncher.java =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/InProcessSimulatorLauncher.java 2009-05-19 21:54:07 UTC (rev 2258) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/InProcessSimulatorLauncher.java 2009-05-20 13:43:44 UTC (rev 2259) @@ -38,6 +38,7 @@ import org.codelutin.topia.event.TopiaTransactionEvent; import org.codelutin.topia.event.TopiaTransactionListener; import org.codelutin.topia.persistence.TopiaEntity; +import org.codelutin.util.FileUtil; import org.codelutin.util.ObjectUtil; import org.codelutin.util.StringUtil; @@ -49,7 +50,6 @@ import fr.ifremer.isisfish.aspect.Trace; import fr.ifremer.isisfish.datastore.SimulationStorage; import fr.ifremer.isisfish.datastore.SimulatorStorage; -import fr.ifremer.isisfish.rule.Rule; import fr.ifremer.isisfish.simulator.SimulationContext; import fr.ifremer.isisfish.simulator.SimulationControl; import fr.ifremer.isisfish.simulator.SimulationException; @@ -89,6 +89,21 @@ log.info(_("simulate %s with file %s", id, simulationZip)); try { + + // remove simulation if already exists + if (SimulationStorage.exists(id)) { + if (log.isWarnEnabled()) { + log.warn("Warning , simulation " + id + " aleady exists"); + log.warn("Deleting it before doing simulation"); + + // storage can be opened (result UI) + SimulationStorage storage = SimulationStorage.getSimulation(id); + storage.closeStorage(); + + FileUtil.deleteRecursively(storage.getFile()); + } + } + simulation = SimulationStorage .importAndRenameZip(simulationZip, id); @@ -510,7 +525,7 @@ * Do nothing (no restriction on inprocess launcher). */ @Override - public void simulationStopRequest() { + public void simulationStopRequest(SimulationJob job) { } Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/IsisFishServerSimulationLauncher.java =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/IsisFishServerSimulationLauncher.java 2009-05-19 21:54:07 UTC (rev 2258) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/IsisFishServerSimulationLauncher.java 2009-05-20 13:43:44 UTC (rev 2259) @@ -251,7 +251,7 @@ * Do nothing (no restriction on xml rpc launcher). */ @Override - public void simulationStopRequest() { + public void simulationStopRequest(SimulationJob job) { } } Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SSHSimulatorLauncher.java =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SSHSimulatorLauncher.java 2009-05-19 21:54:07 UTC (rev 2258) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SSHSimulatorLauncher.java 2009-05-20 13:43:44 UTC (rev 2259) @@ -40,7 +40,6 @@ import org.codelutin.util.FileUtil; import org.codelutin.util.MD5; import org.codelutin.util.MD5InputStream; -import org.codelutin.util.Tbz2Util; import org.codelutin.util.ZipUtil; import com.jcraft.jsch.JSch; @@ -50,12 +49,12 @@ import fr.ifremer.isisfish.IsisFish; import fr.ifremer.isisfish.datastore.SimulationStorage; import fr.ifremer.isisfish.simulator.SimulationControl; -import fr.ifremer.isisfish.simulator.launcher.ssh.SSHException; -import fr.ifremer.isisfish.simulator.launcher.ssh.SSHUserInfo; -import fr.ifremer.isisfish.simulator.launcher.ssh.SSHUtils; import fr.ifremer.isisfish.util.ClasspathTemplateLoader; import fr.ifremer.isisfish.util.ssh.InvalidPassphraseException; import fr.ifremer.isisfish.util.ssh.SSHAgent; +import fr.ifremer.isisfish.util.ssh.SSHException; +import fr.ifremer.isisfish.util.ssh.SSHUserInfo; +import fr.ifremer.isisfish.util.ssh.SSHUtils; import freemarker.cache.TemplateLoader; import freemarker.template.Configuration; import freemarker.template.Template; @@ -130,10 +129,8 @@ /** * Display message both in commons-logging and control text progress. * - * @param control - * control - * @param message - * message to display + * @param control control + * @param message message to display */ protected void message(SimulationControl control, String message) { // log @@ -210,7 +207,23 @@ * {@inheritDoc} */ @Override - public void simulationStopRequest() { + public void simulationStopRequest(SimulationJob job) throws RemoteException { + + // make sure user is connected + try { + getSSHSession(); + } + catch(JSchException e) { + throw new RemoteException("Can't connect", e); + } + + try { + sendStopSimulationRequest(sshSession, job.getId()); + } catch (SSHException e) { + throw new RemoteException("Can't connect", e); + } + + simulationEnded(); } @@ -227,6 +240,11 @@ SimulationControl control, File simulationZip, String simulationPrescript) throws RemoteException { + // check username + if (StringUtils.isBlank(IsisFish.config.getSimulatorSshUsername())) { + throw new RemoteException("Username is empty"); + } + // ask for available resources on caparmor // blocking until available message(control, _("isisfish.simulation.remote.message.waitingavailable")); @@ -256,7 +274,7 @@ // prescrit uploaded, delete simulationScript.delete(); - addScriptToQsubQueue(sshSession, scriptRemotePath); + sendStartSimulationRequest(sshSession, scriptRemotePath, control.getId()); } catch (Exception e) { if (log.isErrorEnabled()) { @@ -544,8 +562,7 @@ /** * Close ssh session. * - * @param session - * session to close + * @param session session to close */ protected void closeSSHSession(Session session) { if (session != null) { @@ -621,10 +638,10 @@ String localPath = simulationFile.getAbsolutePath(); // first check that remote directory exists - String remotePath = IsisFish.config.getSimulatorSshTmpPath(); - + String remotePath = getRemoteTempDirectory(); + // following command work on bash and csh - String command = "test -d \"" + remotePath + "\"||mkdir \"" + String command = "test -d \"" + remotePath + "\"||mkdir -p \"" + remotePath + "\""; if (log.isInfoEnabled()) { @@ -782,15 +799,11 @@ String localPath = simulationScript.getAbsolutePath(); - String remotePath = IsisFish.config.getSimulatorSshTmpPath(); + String remotePath = getRemoteTempDirectory(); + // remote temp directory should have been created // by #uploadSimulation(Session, String) - // upload directory in that dir - if (!remotePath.endsWith("/")) { - remotePath += "/"; - } - if (localPath.lastIndexOf("/") > 0) { remotePath += localPath.substring(localPath.lastIndexOf("/") + 1); } else if (localPath.lastIndexOf("\\") > 0) { // windows @@ -807,23 +820,12 @@ /** * Get remote simulation zip path. * - * Return path if uploaded or null if no upload needed. - * * @param simulationId simulation id - * - * @throws SSHException if upload fail - * @throws IOException if upload fail */ - protected String getRemoteResultArchivePath(String simulationId) - throws SSHException, IOException { + protected String getRemoteResultArchivePath(String simulationId) { - String remotePath = IsisFish.config.getSimulatorSshTmpPath(); + String remotePath = getRemoteTempDirectory(); - // upload directory in that dir - if (!remotePath.endsWith("/")) { - remotePath += "/"; - } - remotePath += "simulation-" + simulationId + "-result.zip"; return remotePath; @@ -855,15 +857,11 @@ FileUtil.writeString(tempPreScriptFile, simulationPreScript); String localPath = tempPreScriptFile.getAbsolutePath(); - String remotePath = IsisFish.config.getSimulatorSshTmpPath(); + String remotePath = getRemoteTempDirectory(); + // remote temp directory should have been created // by #uploadSimulation(Session, String) - // upload directory in that dir - if (!remotePath.endsWith("/")) { - remotePath += "/"; - } - if (localPath.lastIndexOf("/") > 0) { remotePath += localPath.substring(localPath.lastIndexOf("/") + 1); } else if (localPath.lastIndexOf("\\") > 0) { // windows @@ -964,21 +962,78 @@ * * @param session valid opened session * @param scriptRemotePath remote script path + * @param simulationId simulation id * * @throws SSHException if call fail */ - protected void addScriptToQsubQueue(Session session, String scriptRemotePath) + protected void sendStartSimulationRequest(Session session, String scriptRemotePath, String simulationId) throws SSHException { // command to : // - add script in qsub queue - String command = IsisFish.config.getSimulatorSshAddToQueueCommand() - + " \"" + scriptRemotePath + "\""; + String command = IsisFish.config.getSimulatorSshPbsBinPath() + + "/qsub \"" + scriptRemotePath + "\"|tee \"" + getRemoteTempDirectory() + "/" + simulationId + ".id\""; - int exit = SSHUtils.exec(session, command); + Writer output = new StringWriter(); + int exit = SSHUtils.exec(session, command, output); if (exit != 0) { throw new SSHException(_("Command '%s' fail to execute", command)); } + + String out = output.toString(); + if (out.trim().matches("\\d+\\.\\w+")) { + log.info("Job submitted with job id : " + out); + } } + + /** + * Send qdel request on job. + * + * @param session valid opened session + * @param simulationId simulation id + * + * @throws SSHException if call fail + */ + protected void sendStopSimulationRequest(Session session, String simulationId) + throws SSHException { + + // command to : + String command = IsisFish.config.getSimulatorSshPbsBinPath() + + "/qdel `cat \"" + getRemoteTempDirectory() + "/" + simulationId + ".id\"`"; + + // and delete simulation + command += " && rm -rf \"" + IsisFish.config.getSimulatorSshDataPath() + "/simulations/" + simulationId + "\""; + + if (log.isDebugEnabled()) { + log.debug("Send stop request : " + command); + } + + SSHUtils.exec(session, command); + + // can fail, already stopped + /*if (exit != 0) { + throw new SSHException(_("Command '%s' fail to execute", command)); + }*/ + } + + /** + * Get remote directory absolute path. + * + * @return remote temp directory path + */ + protected String getRemoteTempDirectory() { + String remotePath = IsisFish.config.getSimulatorSshTmpPath(); + + /*if (!remotePath.startsWith("/")) { + remotePath = IsisFish.config.getSimulatorSshUserHome() + "/" + remotePath; + }*/ + + // upload directory in that dir + if (!remotePath.endsWith("/")) { + remotePath += "/"; + } + + return remotePath; + } } Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationJob.java =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationJob.java 2009-05-19 21:54:07 UTC (rev 2258) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationJob.java 2009-05-20 13:43:44 UTC (rev 2259) @@ -120,6 +120,13 @@ } item.getControl().setStopSimulationRequest(true); } + + /** + * Resoumet un job. + */ + public void restart() { + simulationService.restart(this); + } public SimulationJob getParentJob() { return parentJob; Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationMonitor.java =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationMonitor.java 2009-05-19 21:54:07 UTC (rev 2258) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationMonitor.java 2009-05-20 13:43:44 UTC (rev 2259) @@ -27,14 +27,16 @@ import java.rmi.RemoteException; import java.util.ArrayList; import java.util.Collection; +import java.util.Comparator; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; -import java.util.SortedMap; +import java.util.SortedSet; import java.util.Timer; -import java.util.TreeMap; +import java.util.TreeSet; +import java.util.AbstractMap.SimpleEntry; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -103,7 +105,7 @@ * * Sorted on date ASC. */ - protected SortedMap<Date, SimulationJob> checkMap; + protected SortedSet<SimpleEntry<Date, SimulationJob>> checkSet; /** * Check scheduler. @@ -120,7 +122,14 @@ monitorFile = new File(monitorSaveFile); // init monitor check map - checkMap = new TreeMap<Date, SimulationJob>(); + checkSet = new TreeSet<SimpleEntry<Date, SimulationJob>>(new Comparator<SimpleEntry<Date, SimulationJob>>(){ + @Override + public int compare(SimpleEntry<Date, SimulationJob> o1, + SimpleEntry<Date, SimulationJob> o2) { + return o1.getKey().compareTo(o2.getKey()); + } + + }); // init timer checkScheduler = new Timer(); @@ -295,7 +304,7 @@ //checkDate.setTime(checkDate.getTime() + intervalInSeconds); // add simulation to check queue - checkMap.put(checkDate, job); + checkSet.add(new SimpleEntry<Date, SimulationJob>(checkDate, job)); // start thread if not already started if (!this.isAlive()) { @@ -355,14 +364,15 @@ } // take first job in map - if (!checkMap.isEmpty()) { - Date date = checkMap.firstKey(); + if (!checkSet.isEmpty()) { + SimpleEntry<Date, SimulationJob> firstEntry = checkSet.first(); + Date date = firstEntry.getKey(); Date now = new Date(); if (date.before(now)) { // first key date in map is over... // check is needed - SimulationJob job = checkMap.get(date); + SimulationJob job = firstEntry.getValue(); SimulatorLauncher launcher = job.getLauncher(); // retourne true if : @@ -371,7 +381,7 @@ boolean jobIsFinished = checkProgression(job, launcher); // always remove this simulation from map - checkMap.remove(date); + checkSet.remove(firstEntry); // if not finished, re-add it at end if (jobIsFinished) { @@ -390,7 +400,7 @@ long nextJobTimeMs = date.getTime() + launcher.getCheckProgressionInterval() * 1000; Date nextJobDate = new Date(nextJobTimeMs); - checkMap.put(nextJobDate, job); + checkSet.add(new SimpleEntry<Date, SimulationJob>(nextJobDate, job)); } } else { @@ -441,7 +451,7 @@ } if (control.isStopSimulationRequest()) { - launcher.simulationStopRequest(); // to release one resource + launcher.simulationStopRequest(job); // to release one resource simulationEnded = true; } } catch (RemoteException e) { Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationService.java =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationService.java 2009-05-19 21:54:07 UTC (rev 2258) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationService.java 2009-05-20 13:43:44 UTC (rev 2259) @@ -604,6 +604,19 @@ } /** + * Restart a job. + * + * This method fire "start" event. + * + * @param job job to retstart + */ + public void restart(SimulationJob job) { + job.getItem().getControl().reset(); + fireStartEvent(job); + submit(job); + } + + /** * Supprime un job de la queue (annulation d'une simulation). Appele * depuis {@link SimulationJob#stop} * Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationServiceTableModel.java =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationServiceTableModel.java 2009-05-19 21:54:07 UTC (rev 2258) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationServiceTableModel.java 2009-05-20 13:43:44 UTC (rev 2259) @@ -104,10 +104,12 @@ } public void removeJob(SimulationJob job) { + String id = job.getItem().getControl().getId(); synchronized (jobs) { int index = jobs.indexOf(job); if (index >= 0) { jobs.remove(index); + jobIds.remove(id); fireTableRowsDeleted(index, index); } } @@ -279,7 +281,9 @@ public void simulationStart(SimulationService simService, SimulationJob job) { - // nothing to do + // this happens when job is restarted + // remove it from here + model.removeJob(job); } public void simulationStop(SimulationService simService, @@ -290,7 +294,6 @@ public void clearJobDone(SimulationService simService) { model.clearJob(); } - } class JobToDoListener implements AbstractJobListener, Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulatorLauncher.java =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulatorLauncher.java 2009-05-19 21:54:07 UTC (rev 2258) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulatorLauncher.java 2009-05-20 13:43:44 UTC (rev 2259) @@ -111,5 +111,5 @@ * * TODO review this mecanism (some resource could be not released) */ - public void simulationStopRequest(); + public void simulationStopRequest(SimulationJob job) throws RemoteException; } Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SubProcessSimulationLauncher.java =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SubProcessSimulationLauncher.java 2009-05-19 21:54:07 UTC (rev 2258) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SubProcessSimulationLauncher.java 2009-05-20 13:43:44 UTC (rev 2259) @@ -323,7 +323,7 @@ * Do nothing (no restriction on subprocess launcher). */ @Override - public void simulationStopRequest() { - + public void simulationStopRequest(SimulationJob job) { + // TODO kill -9 sub process } } Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/ui/simulator/QueueUI.jaxx =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/ui/simulator/QueueUI.jaxx 2009-05-19 21:54:07 UTC (rev 2258) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/ui/simulator/QueueUI.jaxx 2009-05-20 13:43:44 UTC (rev 2259) @@ -56,6 +56,8 @@ * Stop simulation associated with table selected rows. */ protected void stopSimulation() { + SimulAction simulAction = getContextValue(SimulAction.class); + int[] selectedRows = queueTable.getSelectedRows(); SimulationJob[] jobsToStop = new SimulationJob[selectedRows.length]; int index = 0; @@ -65,11 +67,28 @@ for (int selectedRow : selectedRows) { jobsToStop[index++] = getContextValue(SimulationServiceTableModel.class, "new").getJob(selectedRow); } - for (SimulationJob job : jobsToStop) { - getContextValue(SimulAction.class).stopSimulation(job); + for (SimulationJob jobToStop : jobsToStop) { + simulAction.stopSimulation(jobToStop); } } + protected void restartSimulation() { + SimulAction simulAction = getContextValue(SimulAction.class); + + int[] selectedRows = queueTableDone.getSelectedRows(); + SimulationJob[] jobsToRestart = new SimulationJob[selectedRows.length]; + int index = 0; + + // to do in two pass, because each simulation + // change selected rows + for (int selectedRow : selectedRows) { + jobsToRestart[index++] = getContextValue(SimulationServiceTableModel.class, "done").getJob(selectedRow); + } + for (SimulationJob jobToRestart : jobsToRestart) { + simulAction.restartSimulation(jobToRestart); + } + } + protected void viewLog() { if (queueTableDone.getSelectedRow() >= 0) { getContextValue(SimulAction.class).viewLog(getContextValue(SimulationServiceTableModel.class, "done").getJob(queueTableDone.getSelectedRow())); @@ -85,6 +104,7 @@ setCanShowLog(!selectionModelQueueTabDone.isSelectionEmpty()); // TODO value have to change on non valueChanged event setCanClear(queueTableDone.getModel().getRowCount()>0); + setCanRestart(!selectionModelQueueTabDone.isSelectionEmpty()); } ]]> </script> @@ -92,12 +112,13 @@ <Boolean id='canStop' javaBean='false'/> <Boolean id='canShowLog' javaBean='false'/> <Boolean id='canClear' javaBean='false'/> + <Boolean id='canRestart' javaBean='false'/> <DefaultListSelectionModel id="selectionModelQueueTab" onValueChanged='updateActions()'/> <DefaultListSelectionModel id="selectionModelQueueTabDone" onValueChanged='updateActions()'/> <row> - <cell columns="4" fill="both" weightx="1.0" weighty="0.5"> + <cell columns="5" fill="both" weightx="1.0" weighty="0.5"> <JScrollPane> <JTable id="queueTable" model='{getContextValue(SimulationServiceTableModel.class, "new")}' selectionMode="{ListSelectionModel.MULTIPLE_INTERVAL_SELECTION}" selectionModel="{selectionModelQueueTab}"/> @@ -105,7 +126,7 @@ </cell> </row> <row> - <cell columns="4" fill="both" weightx="1.0" weighty="0.5"> + <cell columns="5" fill="both" weightx="1.0" weighty="0.5"> <JScrollPane> <JTable id="queueTableDone" model='{getContextValue(SimulationServiceTableModel.class, "done")}' selectionMode="{ListSelectionModel.SINGLE_SELECTION}" selectionModel="{selectionModelQueueTabDone}" /> @@ -120,6 +141,9 @@ <JButton id="stopSimuButton" text="isisfish.queue.stopSimulation" onActionPerformed='stopSimulation()' enabled='{isCanStop()}' /> </cell> <cell fill="horizontal" weightx="0.3"> + <JButton id="restartSimulationButton" text="isisfish.queue.restartSimulation" onActionPerformed='restartSimulation()' enabled='{isCanRestart()}' /> + </cell> + <cell fill="horizontal" weightx="0.3"> <JButton id="showLogButton" text="isisfish.queue.showLog" onActionPerformed='viewLog()' enabled='{isCanShowLog()}' /> </cell> <cell fill="horizontal" weightx="0.3"> Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/ui/simulator/SimulAction.java =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/ui/simulator/SimulAction.java 2009-05-19 21:54:07 UTC (rev 2258) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/ui/simulator/SimulAction.java 2009-05-20 13:43:44 UTC (rev 2259) @@ -262,6 +262,20 @@ .getId())); } } + + /** + * Restart job. + * + * @param job job to restart + */ + public void restartSimulation(SimulationJob job) { + job.restart(); + job.getItem().getControl().setText(_("isisfish.simulation.restarting")); + if (log.isInfoEnabled()) { + log.info(_("User restart simulation %s", job.getItem().getControl() + .getId())); + } + } protected void viewLog(SimulationJob job) { String id = job.getItem().getControl().getId(); Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/ui/simulator/launcher/SSHLauncherConfigUI.jaxx =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/ui/simulator/launcher/SSHLauncherConfigUI.jaxx 2009-05-19 21:54:07 UTC (rev 2258) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/ui/simulator/launcher/SSHLauncherConfigUI.jaxx 2009-05-20 13:43:44 UTC (rev 2259) @@ -19,14 +19,23 @@ <script><![CDATA[ import fr.ifremer.isisfish.IsisFish; - + import com.jcraft.jsch.JSch; + import com.jcraft.jsch.JSchException; + import com.jcraft.jsch.Session; + import fr.ifremer.isisfish.util.ssh.InvalidPassphraseException; + import fr.ifremer.isisfish.util.ssh.SSHAgent; + import fr.ifremer.isisfish.util.ssh.SSHException; + import fr.ifremer.isisfish.util.ssh.SSHUserInfo; + import fr.ifremer.isisfish.util.ssh.SSHUtils; + protected String currentSSHserver; protected String currentSSHUsername; protected String currentSSHKey; + protected String currentSSHUserhome; protected String currentSSHDatapath; protected String currentSSHIsisHome; protected String currentSSHTempPath; - protected String currentSSHScriptCommand; + protected String currentSSHPbsBinPath; protected String currentSSHControlInterval; protected String currentSSHSimultaneousSimulation; @@ -43,10 +52,11 @@ sshKeyField.setText(IsisFish.config.getSSHPrivateKeyFilePath().getAbsolutePath()); // caparmor config + //sshUserhomeField.setText(IsisFish.config.getSimulatorSshUserHome()); sshDatapathField.setText(IsisFish.config.getSimulatorSshDataPath()); sshIsisHomeField.setText(IsisFish.config.getSimulatorSshIsisHome()); sshTemppathField.setText(IsisFish.config.getSimulatorSshTmpPath()); - sshScriptQueueCommandField.setText(IsisFish.config.getSimulatorSshAddToQueueCommand()); + sshPbsBinPathField.setText(IsisFish.config.getSimulatorSshPbsBinPath()); sshControlIntervalField.setText(String.valueOf(IsisFish.config.getSimulatorSshControlCheckInterval())); sshSimultaneousSimulationField.setText(String.valueOf(IsisFish.config.getSimulatorSshMaxSimultaneousSimulation())); @@ -54,13 +64,13 @@ } protected void doCheck() { - - boolean configurationValid = true; + validButton.setEnabled(false); + messageLabel.setText(""); + // copy values currentSSHserver = sshServerField.getText().trim(); if (currentSSHserver.isEmpty()) { - configurationValid = false; setColor(true, sshServerField); } else { @@ -69,7 +79,6 @@ currentSSHUsername = usernameField.getText().trim(); if (!currentSSHUsername.matches("\\w+")) { - configurationValid = false; setColor(true, usernameField); } else { @@ -80,7 +89,6 @@ currentSSHDatapath = sshDatapathField.getText().trim(); if (currentSSHDatapath.isEmpty()) { - configurationValid = false; setColor(true, sshDatapathField); } else { @@ -88,8 +96,7 @@ } currentSSHIsisHome = sshIsisHomeField.getText().trim(); - if (!currentSSHIsisHome.startsWith("/")) { - configurationValid = false; + if (currentSSHIsisHome.isEmpty()) { setColor(true, sshIsisHomeField); } else { @@ -97,26 +104,23 @@ } currentSSHTempPath = sshTemppathField.getText().trim(); - if (!currentSSHTempPath.startsWith("/")) { - configurationValid = false; + if (currentSSHTempPath.isEmpty()) { setColor(true, sshTemppathField); } else { setColor(false, sshTemppathField); } - currentSSHScriptCommand = sshScriptQueueCommandField.getText().trim(); - if (currentSSHScriptCommand.isEmpty()) { - configurationValid = false; - setColor(true, sshScriptQueueCommandField); + currentSSHPbsBinPath = sshPbsBinPathField.getText().trim(); + if (currentSSHPbsBinPath.isEmpty()) { + setColor(true, sshPbsBinPathField); } else { - setColor(false, sshScriptQueueCommandField); + setColor(false, sshPbsBinPathField); } currentSSHControlInterval = sshControlIntervalField.getText().trim(); if (!currentSSHControlInterval.matches("\\d+")) { - configurationValid = false; setColor(true, sshControlIntervalField); } else { @@ -125,14 +129,11 @@ currentSSHSimultaneousSimulation = sshSimultaneousSimulationField.getText().trim(); if (!currentSSHSimultaneousSimulation.matches("\\d+")) { - configurationValid = false; setColor(true, sshSimultaneousSimulationField); } else { setColor(false, sshSimultaneousSimulationField); } - - okButton.setEnabled(configurationValid); } /** @@ -142,10 +143,11 @@ IsisFish.config.setSimulatorSshServer(currentSSHserver); IsisFish.config.setSimulatorSshUsername(currentSSHUsername); + //IsisFish.config.setSimulatorSshUserHome(currentSSHUserhome); IsisFish.config.setSimulatorSshDataPath(currentSSHDatapath); - IsisFish.config.setSimuatorShhIsisHome(currentSSHIsisHome); + IsisFish.config.setSimulatorSshIsisHome(currentSSHIsisHome); IsisFish.config.setSimulatorSshTmpPath(currentSSHTempPath); - IsisFish.config.setSimulatorSshAddToQueueCommand(currentSSHScriptCommand); + IsisFish.config.setSimulatorSshPbsBinPath(currentSSHPbsBinPath); IsisFish.config.setSimulatorSshControlCheckInterval(Long.parseLong(currentSSHControlInterval)); IsisFish.config.setSimulatorSshMaxSimultaneousSimulation(Integer.parseInt(currentSSHSimultaneousSimulation)); @@ -160,9 +162,108 @@ dispose(); } + protected void testSSHConfiguration() { + // pour ne pas bloquer le bouton test + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + testSSHConfigurationRunnable(); + } + }); + } + + /** + * Realise une connexion ssh et teste les données. + */ + protected void testSSHConfigurationRunnable() { + JSch jsch = new JSch(); + + String host = currentSSHserver; + int port = 22; // by default, 22 + String sPort = null; + + try { + if (host.indexOf(':') > 0) { + sPort = host.substring(host.indexOf(':') + 1); + port = Integer.parseInt(sPort); + host = host.substring(0, host.indexOf(':')); + } + + // add ssh key + boolean sshKeyUsed = false; + File sshKey = IsisFish.config.getSSHPrivateKeyFilePath(); + if (sshKey.canRead()) { + if (log.isInfoEnabled()) { + log.info(_("Ssh key found '%s' will be used to connect to", + sshKey.getAbsoluteFile(), host)); + } + jsch.addIdentity(sshKey.getAbsolutePath()); + sshKeyUsed = true; + } + else { + if (log.isInfoEnabled()) { + log.info(_("Can't read ssh key : %s", sshKey)); + } + } + + Session session = jsch.getSession(currentSSHUsername, host, port); + + // username and password will be given via UserInfo interface. + SSHUserInfo ui = new SSHUserInfo(); + if (sshKeyUsed) { + String passphrase = null; + passphrase = SSHAgent.getAgent().getPassphrase(sshKey); + ui.setPassphrase(passphrase); + setTestMessage(_("isisfish.simulator.ssh.configuration.connectingpk"), false); + } + else { + setTestMessage(_("isisfish.simulator.ssh.configuration.connecting"), false); + } + session.setUserInfo(ui); + session.connect(10000); // timeout + + setTestMessage(_("isisfish.simulator.ssh.configuration.connectionok"), false); + + // get user home + //currentSSHUserhome = getUserHomeDirectory(session); + //sshUserhomeField.setText(currentSSHUserhome); + session.disconnect(); + + validButton.setEnabled(true); + } catch (NumberFormatException e) { + setTestMessage(_("isisfish.error.simulation.remote.wrongportvalue", sPort), true); + } catch (JSchException e) { + setTestMessage(_("isisfish.simulator.ssh.configuration.connectionerror", e.getMessage()), true); + } catch (InvalidPassphraseException e) { + setTestMessage(_("isisfish.simulator.ssh.configuration.invalidpassphrase"), true); + } + } + + /** + * Get user home directory with an opened session. + */ + protected String getUserHomeDirectory(Session session) throws SSHException { + + String command ="pwd"; + + Writer output = new StringWriter(); + int exit = SSHUtils.exec(session, command, output); + + if (exit != 0) { + throw new SSHException(_("Command '%s' fail to execute", command)); + } + + String out = output.toString(); + return out; + } + protected void setColor(boolean invalid, JComponent component) { component.setForeground(invalid ? Color.RED: Color.BLACK); } + protected void setTestMessage(String message, boolean error) { + messageLabel.setForeground(error ? Color.RED: Color.GREEN.darker()); + messageLabel.setText(message); + } ]]></script> <Table border='{BorderFactory.createTitledBorder(_("isisfish.simulator.ssh.configuration.connection"))}' @@ -179,11 +280,11 @@ </row> <row fill='horizontal'> <cell> - <JLabel id='usernameLabel' text='isisfish.config.main.simulation.ssh.login' - toolTipText='isisfish.config.main.simulation.ssh.login.description' /> + <JLabel id='usernameLabel' text='isisfish.config.main.simulation.ssh.username' + toolTipText='isisfish.config.main.simulation.ssh.username.description' /> </cell> <cell> - <JTextField id='usernameField' toolTipText='isisfish.config.main.simulation.ssh.login.description' + <JTextField id='usernameField' toolTipText='isisfish.config.main.simulation.ssh.username.description' onKeyReleased="doCheck()" /> </cell> </row> @@ -198,8 +299,19 @@ </row> </Table> <Table border='{BorderFactory.createTitledBorder(_("isisfish.simulator.ssh.configuration.environment"))}'> + <!-- home is not necessary <row fill='horizontal'> <cell> + <JLabel id='sshUserhomeLabel' text='isisfish.config.main.simulation.ssh.userhome' + toolTipText='isisfish.config.main.simulation.ssh.userhome.description' /> + </cell> + <cell weightx="1.0"> + <JTextField id='sshUserhomeField' enabled='false' toolTipText='isisfish.config.main.simulation.ssh.userhome.description' + onKeyReleased="doCheck()" /> + </cell> + </row> --> + <row fill='horizontal'> + <cell> <JLabel id='sshDatapathLabel' text='isisfish.config.main.simulation.ssh.datapath' toolTipText='isisfish.config.main.simulation.ssh.datapath.description' /> </cell> @@ -230,12 +342,12 @@ </row> <row fill='horizontal'> <cell> - <JLabel id='sshScriptQueueCommandLabel' text='isisfish.config.main.simulation.ssh.addscripttoqueuecommand' - toolTipText='isisfish.config.main.simulation.ssh.addscripttoqueuecommand.description' /> + <JLabel id='sshPbsBinPathLabel' text='isisfish.config.main.simulation.ssh.pbsbinpath' + toolTipText='isisfish.config.main.simulation.ssh.pbsbinpath.description' /> </cell> <cell> - <JTextField id='sshScriptQueueCommandField' - toolTipText='isisfish.config.main.simulation.ssh.addscripttoqueuecommand.description' + <JTextField id='sshPbsBinPathField' + toolTipText='isisfish.config.main.simulation.ssh.pbsbinpath.description' onKeyReleased="doCheck()" /> </cell> </row> @@ -264,10 +376,18 @@ </Table> <Table> <row fill='horizontal'> + <cell columns="4" fill='horizontal'> + <JLabel id='messageLabel' text=' ' font-weight='bold' opaque='true' horizontalAlignment='center' minimumSize='{new Dimension(0, 25)}' preferredSize='{new Dimension(0, 25)}'/> + </cell> + </row> + <row fill='horizontal'> <cell fill='horizontal'> - <JButton id='okButton' text='isisfish.common.ok' onActionPerformed="saveSSHConfiguration()" /> + <JButton id='testButton' text='isisfish.simulator.ssh.configuration.test' onActionPerformed="testSSHConfiguration()" /> </cell> <cell fill='horizontal'> + <JButton id='validButton' text='isisfish.common.valid' onActionPerformed="saveSSHConfiguration()" /> + </cell> + <cell fill='horizontal'> <JButton id='resetButton' text='isisfish.common.reset' onActionPerformed="resetSSHConfiguration()" /> </cell> <cell fill='horizontal'> Copied: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/SSHException.java (from rev 2233, isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/ssh/SSHException.java) =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/SSHException.java (rev 0) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/SSHException.java 2009-05-20 13:43:44 UTC (rev 2259) @@ -0,0 +1,72 @@ +/* *##% + * Copyright (C) 2008, 2009 Code Lutin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *##%*/ + +package fr.ifremer.isisfish.util.ssh; + +/** + * SSHException. + * + * @author chatellier + * @version $Revision: 1.0 $ + * + * Last update : $Date: 14 janv. 2009 $ + * By : $Author: chatellier $ + */ +public class SSHException extends Exception { + + /** serialVersionUID. */ + private static final long serialVersionUID = -198651402309210758L; + + /** + * Constructs a new exception with null as its detail message. + */ + public SSHException() { + super(); + } + + /** + * Constructs a new exception with the specified detail message. + * + * @param message message + * @param cause cause + */ + public SSHException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new exception with the specified detail message and cause. + * + * @param message message + */ + public SSHException(String message) { + super(message); + } + + /** + * Constructs a new exception with the specified cause and a detail message + * of (cause==null ? null : cause.toString()) (which typically contains the + * class and detail message of cause). + * + * @param cause cause + */ + public SSHException(Throwable cause) { + super(cause); + } + +} Copied: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/SSHUserInfo.java (from rev 2233, isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/ssh/SSHUserInfo.java) =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/SSHUserInfo.java (rev 0) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/SSHUserInfo.java 2009-05-20 13:43:44 UTC (rev 2259) @@ -0,0 +1,118 @@ +/* *##% + * Copyright (C) 2008, 2009 Code Lutin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *##%*/ + +package fr.ifremer.isisfish.util.ssh; + +import javax.swing.JOptionPane; +import javax.swing.JPasswordField; + +import com.jcraft.jsch.UserInfo; + +/** + * Class used to ask used for connection info. + * + * Password, passphrase... + * + * @author chatellier + * @version $Revision: 1.0 $ + * + * Last update : $Date: 1 déc. 2008 $ + * By : $Author: chatellier $ + */ +public class SSHUserInfo implements UserInfo { + + /** + * Passphrase. + * + * Static to be stored on multiple connexion. + */ + protected String passphrase; + + /** + * Password text field. + */ + protected String passwd; + + /** + * Password text field. + */ + protected JPasswordField passwordField = new JPasswordField(20); + + /** + * Call to ask user in remote server key + * can be trusted. Here, auto accept. + */ + @Override + public boolean promptYesNo(String str) { + return true; + } + + @Override + public String getPassphrase() { + return passphrase; + } + + @Override + public String getPassword() { + return passwd; + } + + /** + * @return the passwd + */ + public String getPasswd() { + return passwd; + } + + /** + * @param passwd the passwd to set + */ + public void setPasswd(String passwd) { + this.passwd = passwd; + } + + /** + * @param passphrase the passphrase to set + */ + public void setPassphrase(String passphrase) { + this.passphrase = passphrase; + } + + @Override + public boolean promptPassphrase(String arg0) { + return true; + } + + @Override + public boolean promptPassword(String message) { + Object[] ob = { passwordField }; + int result = JOptionPane.showConfirmDialog(null, ob, message, + JOptionPane.OK_CANCEL_OPTION); + boolean bResult = false; + if (result == JOptionPane.OK_OPTION) { + passwd = String.valueOf(passwordField.getPassword()); + bResult = true; + } + return bResult; + } + + @Override + public void showMessage(String message) { + JOptionPane.showMessageDialog(null, message); + } +} Copied: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/SSHUtils.java (from rev 2245, isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/ssh/SSHUtils.java) =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/SSHUtils.java (rev 0) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/SSHUtils.java 2009-05-20 13:43:44 UTC (rev 2259) @@ -0,0 +1,466 @@ +/* *##% + * Copyright (C) 2008, 2009 Code Lutin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *##%*/ + +package fr.ifremer.isisfish.util.ssh; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.EOFException; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.Writer; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.jcraft.jsch.Channel; +import com.jcraft.jsch.ChannelExec; +import com.jcraft.jsch.JSchException; +import com.jcraft.jsch.Session; + +/** + * SSH utils class. + * + * All this code has be taken from ant optionnal ssh task. + * + * Use full for: + * - scpTo command + * - scpFrom command + * - exec command + * + * @author chatellier + * @version $Revision: 1.0 $ + * + * Last update : $Date: 13 janv. 2009 $ + * By : $Author: chatellier $ + */ +public class SSHUtils { + + /** log. */ + private static Log log = LogFactory.getLog(SSHUtils.class); + + protected static final byte LINE_FEED = 0x0a; + protected static final int BUFFER_SIZE = 1024; + private static final int HUNDRED_KILOBYTES = 102400; + + /** Utility class */ + protected SSHUtils() { + + } + + /** + * Exec command on remote server. + * + * @param session opened valid session + * @param command command to exec + * + * @return channel exit status (0 = no problem) + * @throws SSHException + */ + public static int exec(Session session, String command) throws SSHException { + return exec(session, command, null); + } + + /** + * Exec command on remote server. + * + * @param session opened valid session + * @param command command to exec + * @param out exec output (can be null) + * + * @return channel exit status (0 = no problem) + * @throws SSHException + */ + public static int exec(Session session, String command, Writer out) + throws SSHException { + + int exitStatus = 0; + + try { + // exec previous command + Channel channel = session.openChannel("exec"); + ((ChannelExec) channel).setCommand(command); + + BufferedReader br = new BufferedReader(new InputStreamReader( + channel.getInputStream())); + channel.connect(); + String line = null; + while (true) { + while ((line = br.readLine()) != null) { + if (out != null) { + out.write(line); + } + else if (log.isInfoEnabled()) { + log.info("Remote output : " + line); + } + } + if (channel.isClosed()) { + exitStatus = channel.getExitStatus(); + if (log.isInfoEnabled()) { + log.info("JSch channel exit-status: " + + exitStatus); + } + break; + } + try { + Thread.sleep(500); + } catch (Exception ee) { + } + } + channel.disconnect(); + // end read buffer + } catch (JSchException e) { + throw new SSHException("I/O error while executing command", e); + } catch (IOException e) { + throw new SSHException("I/O error while executing command", e); + } + + return exitStatus; + } + + /** + * Download a local file from remote server and check md5sum. + * + * @param session opened valid jsch session + * @param remoteFileName remote file name to download + * @param localFile local file name to download into + * + * @throws SSHException if transfer fail (include md5 control failed) + */ + public static void scpFrom(Session session, String remoteFileName, + File localFile) throws SSHException { + + String command = "scp -f -r \"" + remoteFileName + "\""; + + ChannelExec channel = null; + try { + channel = (ChannelExec) session.openChannel("exec"); + channel.setCommand(command); + + // get I/O streams for remote scp + OutputStream out = channel.getOutputStream(); + InputStream in = channel.getInputStream(); + + channel.connect(); + + sendAck(out); + startRemoteCpProtocol(in, out, localFile); + } catch (IOException e) { + throw new SSHException(e); + } catch (JSchException e) { + throw new SSHException(e); + } finally { + if (channel != null) { + channel.disconnect(); + } + } + } + + /** + * Upload file on remote server. + * + * @param session opened valid session + * @param localFile file to upload + * @param remoteFilePath remote file path + * + * @throws SSHException + */ + public static void scpTo(Session session, File localFile, + String remoteFilePath) throws SSHException { + + try { + doSingleTransfer(session, localFile, remoteFilePath); + } catch (IOException e) { + throw new SSHException(e); + } catch (JSchException e) { + throw new SSHException(e); + } + } + + /** + * Send an ack. + * @param out the output stream to use + * @throws IOException on error + */ + protected static void sendAck(OutputStream out) throws IOException { + byte[] buf = new byte[1]; + buf[0] = 0; + out.write(buf); + out.flush(); + } + + /** + * Reads the response, throws a BuildException if the response + * indicates an error. + * @param in the input stream to use + * @throws IOException on I/O error + */ + protected static void waitForAck(InputStream in) throws IOException, + SSHException { + int b = in.read(); + + // b may be 0 for success, + // 1 for error, + // 2 for fatal error, + + if (b == -1) { + // didn't receive any response + throw new SSHException("No response from server"); + } else if (b != 0) { + StringBuffer sb = new StringBuffer(); + + int c = in.read(); + while (c > 0 && c != '\n') { + sb.append((char) c); + c = in.read(); + } + + if (b == 1) { + throw new SSHException("server indicated an error: " + + sb.toString()); + } else if (b == 2) { + throw new SSHException("server indicated a fatal error: " + + sb.toString()); + } else { + throw new SSHException("unknown response, code " + b + + " message: " + sb.toString()); + } + } + } + + /** + * Track progress every 10% if 100kb < filesize < 1mb. For larger + * files track progress for every percent transmitted. + * @param filesize the size of the file been transmitted + * @param totalLength the total transmission size + * @param percentTransmitted the current percent transmitted + * @return the percent that the file is of the total + */ + protected static int trackProgress(long filesize, long totalLength, + int percentTransmitted) { + + // CheckStyle:MagicNumber OFF + int percent = (int) Math.round(Math + .floor((totalLength / (double) filesize) * 100)); + + if (percent > percentTransmitted) { + if (filesize < 1048576) { + if (percent % 5 == 0) { + if (percent == 100) { + System.out.println(" 100%"); + } else { + System.out.print("*"); + } + } + } else { + if (percent == 50) { + System.out.println(" 50%"); + } else if (percent == 100) { + System.out.println(" 100%"); + } else { + System.out.print("."); + } + } + } + // CheckStyle:MagicNumber ON + + return percent; + } + + protected static void startRemoteCpProtocol(InputStream in, + OutputStream out, File localFile) throws IOException, SSHException { + File startFile = localFile; + while (true) { + // C0644 filesize filename - header for a regular file + // T time 0 time 0\n - present if perserve time. + // D directory - this is the header for a directory. + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + while (true) { + int read = in.read(); + if (read < 0) { + return; + } + if ((byte) read == LINE_FEED) { + break; + } + stream.write(read); + } + String serverResponse = stream.toString("UTF-8"); + if (serverResponse.charAt(0) == 'C') { + parseAndFetchFile(serverResponse, startFile, out, in); + } else if (serverResponse.charAt(0) == 'D') { + startFile = parseAndCreateDirectory(serverResponse, startFile); + sendAck(out); + } else if (serverResponse.charAt(0) == 'E') { + startFile = startFile.getParentFile(); + sendAck(out); + } else if (serverResponse.charAt(0) == '\01' + || serverResponse.charAt(0) == '\02') { + // this indicates an error. + throw new IOException(serverResponse.substring(1)); + } + } + } + + protected static File parseAndCreateDirectory(String serverResponse, + File localFile) { + int start = serverResponse.indexOf(" "); + // appears that the next token is not used and it's zero. + start = serverResponse.indexOf(" ", start + 1); + String directoryName = serverResponse.substring(start + 1); + if (localFile.isDirectory()) { + File dir = new File(localFile, directoryName); + dir.mkdir(); + log.debug("Creating: " + dir); + return dir; + } + return null; + } + + protected static void parseAndFetchFile(String serverResponse, + File localFile, OutputStream out, InputStream in) + throws IOException, SSHException { + int start = 0; + int end = serverResponse.indexOf(" ", start + 1); + start = end + 1; + end = serverResponse.indexOf(" ", start + 1); + long filesize = Long.parseLong(serverResponse.substring(start, end)); + String filename = serverResponse.substring(end + 1); + log.debug("Receiving: " + filename + " : " + filesize); + File transferFile = (localFile.isDirectory()) ? new File(localFile, + filename) : localFile; + fetchFile(transferFile, filesize, out, in); + waitForAck(in); + sendAck(out); + } + + protected static void fetchFile(File localFile, long filesize, + OutputStream out, InputStream in) throws IOException { + byte[] buf = new byte[BUFFER_SIZE]; + sendAck(out); + + // read a content of lfile + FileOutputStream fos = new FileOutputStream(localFile); + int length; + long totalLength = 0; + + // only track progress for files larger than 100kb in verbose mode + boolean trackProgress = filesize > HUNDRED_KILOBYTES; + // since filesize keeps on decreasing we have to store the + // initial filesize + long initFilesize = filesize; + int percentTransmitted = 0; + + try { + while (true) { + length = in.read(buf, 0, (BUFFER_SIZE < filesize) ? BUFFER_SIZE + : (int) filesize); + if (length < 0) { + throw new EOFException("Unexpected end of stream."); + } + fos.write(buf, 0, length); + filesize -= length; + totalLength += length; + if (filesize == 0) { + break; + } + + if (trackProgress) { + percentTransmitted = trackProgress(initFilesize, + totalLength, percentTransmitted); + } + } + } finally { + fos.flush(); + fos.close(); + } + } + + protected static void doSingleTransfer(Session session, File localFile, + String remoteFilePath) throws IOException, JSchException, + SSHException { + + String command = "scp -t \"" + remoteFilePath + "\""; + ChannelExec channel = (ChannelExec) session.openChannel("exec"); + channel.setCommand(command); + try { + + OutputStream out = channel.getOutputStream(); + InputStream in = channel.getInputStream(); + + channel.connect(); + + waitForAck(in); + sendFileToRemote(localFile, in, out); + } finally { + channel.disconnect(); + } + } + + protected static void sendFileToRemote(File localFile, InputStream in, + OutputStream out) throws IOException, SSHException { + // send "C0644 filesize filename", where filename should not include '/' + long filesize = localFile.length(); + String command = "C0644 " + filesize + " "; + command += localFile.getName(); + command += "\n"; + + out.write(command.getBytes()); + out.flush(); + + waitForAck(in); + + // send a content of lfile + FileInputStream fis = new FileInputStream(localFile); + byte[] buf = new byte[BUFFER_SIZE]; + long totalLength = 0; + + // only track progress for files larger than 100kb in verbose mode + boolean trackProgress = filesize > HUNDRED_KILOBYTES; + // since filesize keeps on decreasing we have to store the + // initial filesize + long initFilesize = filesize; + int percentTransmitted = 0; + + try { + while (true) { + int len = fis.read(buf, 0, buf.length); + if (len <= 0) { + break; + } + out.write(buf, 0, len); + totalLength += len; + + if (trackProgress) { + percentTransmitted = trackProgress(initFilesize, + totalLength, percentTransmitted); + } + } + out.flush(); + sendAck(out); + waitForAck(in); + } finally { + fis.close(); + } + } +} Copied: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/package-info.java (from rev 2233, isis-fish/trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/ssh/package-info.java) =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/package-info.java (rev 0) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/package-info.java 2009-05-20 13:43:44 UTC (rev 2259) @@ -0,0 +1,11 @@ +/** + * Utility classes for {@link SSHSimulatorLauncher}. + * + * Contains : + * - SSH utility code + * + * Part of SSH code has been taken from + * Ant optional tasks. + */ +package fr.ifremer.isisfish.util.ssh; + Modified: isis-fish/trunk/src/main/resources/i18n/isis-fish-en_GB.properties =================================================================== --- isis-fish/trunk/src/main/resources/i18n/isis-fish-en_GB.properties 2009-05-19 21:54:07 UTC (rev 2258) +++ isis-fish/trunk/src/main/resources/i18n/isis-fish-en_GB.properties 2009-05-20 13:43:44 UTC (rev 2259) @@ -64,6 +64,7 @@ Try\ to\ eval\ current\ script\ (must\ be\ have\ main\ method)= Try\ to\ log\ on\ %s@%s\:%d= Use\ branches,\ switch\ not\ needed= +User\ restart\ simulation\ %s= User\ stop\ simulation\ %s= cant\ start\ nimbus= could\ not\ close\ reader\ %1$s=could not close reader %1$s @@ -143,6 +144,7 @@ isisfish.common.sum=somme isisfish.common.tag=tag isisfish.common.tripType=tripType +isisfish.common.valid=Valid isisfish.common.value=Value isisfish.common.warn=warn isisfish.common.year=annee @@ -171,20 +173,21 @@ isisfish.config.main.resultExport.description= isisfish.config.main.simulation.max.simultaneous.simulation=Simultaneous simulation isisfish.config.main.simulation.max.simultaneous.simulation.description=Simultaneous simulation to do on Caparmor -isisfish.config.main.simulation.ssh.addscripttoqueuecommand=Qsub command -isisfish.config.main.simulation.ssh.addscripttoqueuecommand.description=Qsub command path isisfish.config.main.simulation.ssh.control.check.interval=Control check interval (seconds) isisfish.config.main.simulation.ssh.control.check.interval.description=Control check interval (seconds) isisfish.config.main.simulation.ssh.datapath=Isis-Fish database isisfish.config.main.simulation.ssh.datapath.description=Isis-Fish database path isisfish.config.main.simulation.ssh.isis.home=Isis-Fish home isisfish.config.main.simulation.ssh.isis.home.description=Isis-Fish installation directory -isisfish.config.main.simulation.ssh.login=SSH identifier -isisfish.config.main.simulation.ssh.login.description=SSH identifier +isisfish.config.main.simulation.ssh.pbsbinpath=PBS executables directory +isisfish.config.main.simulation.ssh.pbsbinpath.description=PBS executables (qsub, qdel...) directory isisfish.config.main.simulation.ssh.server=Server address isisfish.config.main.simulation.ssh.server.description=Server adress isisfish.config.main.simulation.ssh.tmppath=Server temp directory -isisfish.config.main.simulation.ssh.tmppath.description=Server temp directory (must start with /) +isisfish.config.main.simulation.ssh.tmppath.description=Server temp directory +isisfish.config.main.simulation.ssh.userhome.description=User home directory +isisfish.config.main.simulation.ssh.username=SSH identifier +isisfish.config.main.simulation.ssh.username.description=SSH identifier isisfish.config.main.simulationServer.description= isisfish.config.main.simulationShowOnlyError.description= isisfish.config.main.simulationShowOnlyQueue.description= @@ -516,7 +519,6 @@ isisfish.input.tree.vesseltypes=Vessel types isisfish.input.tree.zones=Zones isisfish.launch.anonymous=read only -isisfish.launch.debugMode=debug mode isisfish.launch.email=email isisfish.launch.firstname=firstname isisfish.launch.init.done=init done in %1$s. @@ -531,7 +533,6 @@ isisfish.launch.server.ssh.privateKeyFile=private ssh key isisfish.launch.server.ssh.publicKeyFile=public ssh key isisfish.launch.ssh=read-write (ssh) -isisfish.launch.start=Launching Isis-fish ... %1$s isisfish.launch.stop=Stopping simulation... isisfish.launching=after init done in %1$s. isisfish.log.addAppender=add appender [%1$s] @@ -767,6 +768,7 @@ isisfish.queue.launcher=Simulation launcher isisfish.queue.plan=Plan isisfish.queue.progression=Progression +isisfish.queue.restartSimulation=Restart isisfish.queue.showLog=Show simulation log isisfish.queue.simulationLaunch=Simulation queue launch isisfish.queue.status=Status @@ -913,13 +915,20 @@ isisfish.simulation.remote.message.upload=Uploading simulation isisfish.simulation.remote.message.waitingavailable=Waiting for available resource. isisfish.simulation.remote.message.waitingstart=Waiting for simulation start +isisfish.simulation.restarting=Restarting... isisfish.simulation.title=Simulation launcher isisfish.simulator.launcher.inprocess=in current process isisfish.simulator.launcher.remote=on Caparmor server isisfish.simulator.launcher.subprocess=in subprocess isisfish.simulator.simulaction.badid=Can't start simulation, bad id\: %s +isisfish.simulator.ssh.configuration.connecting=Connection... +isisfish.simulator.ssh.configuration.connectingpk=Connection with public key... isisfish.simulator.ssh.configuration.connection=Connection information +isisfish.simulator.ssh.configuration.connectionerror=Can't connect +isisfish.simulator.ssh.configuration.connectionok=Connection successfull isisfish.simulator.ssh.configuration.environment=Caparmor configuration +isisfish.simulator.ssh.configuration.invalidpassphrase=Invalid passphrase +isisfish.simulator.ssh.configuration.test=Test configuration isisfish.simulator.ssh.configuration.title=Caparmor launcher configuration isisfish.simulator.subprocess.readoutput.error= isisfish.species.age=Age Modified: isis-fish/trunk/src/main/resources/i18n/isis-fish-fr_FR.properties =================================================================== --- isis-fish/trunk/src/main/resources/i18n/isis-fish-fr_FR.properties 2009-05-19 21:54:07 UTC (rev 2258) +++ isis-fish/trunk/src/main/resources/i18n/isis-fish-fr_FR.properties 2009-05-20 13:43:44 UTC (rev 2259) @@ -64,6 +64,7 @@ Try\ to\ eval\ current\ script\ (must\ be\ have\ main\ method)= Try\ to\ log\ on\ %s@%s\:%d= Use\ branches,\ switch\ not\ needed= +User\ restart\ simulation\ %s= User\ stop\ simulation\ %s= cant\ start\ nimbus= could\ not\ close\ reader\ %1$s=could not close reader %1$s @@ -143,6 +144,7 @@ isisfish.common.sum=somme isisfish.common.tag=Tag isisfish.common.tripType=Type de trajet +isisfish.common.valid=Valider isisfish.common.value=Valeur isisfish.common.warn=Warning isisfish.common.year=ann\u00E9e @@ -171,20 +173,21 @@ isisfish.config.main.resultExport.description=TODO isisfish.config.main.simulation.max.simultaneous.simulation=Nombre de simulations simultan\u00E9es isisfish.config.main.simulation.max.simultaneous.simulation.description=Nombre maximum de simulations pouvant \u00EAtre envoy\u00E9es au serveur -isisfish.config.main.simulation.ssh.addscripttoqueuecommand=Commande 'qsub' -isisfish.config.main.simulation.ssh.addscripttoqueuecommand.description=Emplacemement de la commande 'qsub' isisfish.config.main.simulation.ssh.control.check.interval=V\u00E9rification de la progression (secondes) isisfish.config.main.simulation.ssh.control.check.interval.description=Temps d'attente en secondes entre deux v\u00E9rifications de progression isisfish.config.main.simulation.ssh.datapath=Base de donn\u00E9es isisfish.config.main.simulation.ssh.datapath.description=Emplacement de la base de donn\u00E9es (isis-database) isisfish.config.main.simulation.ssh.isis.home=Installation d'Isis-Fish isisfish.config.main.simulation.ssh.isis.home.description=Emplacement d'installation d'Isis-Fish sur le serveur -isisfish.config.main.simulation.ssh.login=Identifiant -isisfish.config.main.simulation.ssh.login.description=Identifiant SSH pour se connecter au serveur +isisfish.config.main.simulation.ssh.pbsbinpath=Emplacement des executables PBS +isisfish.config.main.simulation.ssh.pbsbinpath.description=Emplacement des commandes PBS (qsub, qdel...) sur le serveur isisfish.config.main.simulation.ssh.server=Adresse du serveur isisfish.config.main.simulation.ssh.server.description=Adresse du serveur isisfish.config.main.simulation.ssh.tmppath=Dossier temporaire -isisfish.config.main.simulation.ssh.tmppath.description=Emplacement du dossier temporaire (le chemin doit commencer par /) +isisfish.config.main.simulation.ssh.tmppath.description=Emplacement du dossier temporaire +isisfish.config.main.simulation.ssh.userhome.description=R\u00E9pertoire d'accueil de l'utilsateur +isisfish.config.main.simulation.ssh.username=Identifiant +isisfish.config.main.simulation.ssh.username.description=Identifiant SSH pour se connecter au serveur isisfish.config.main.simulationServer.description=l'url du serveur de simulations distant isisfish.config.main.simulationShowOnlyError.description=pour indiquer si l'on doit conserver dans l'UI des simulations termin\u00E9es uniquement celles avec erreur isisfish.config.main.simulationShowOnlyQueue.description=pour indiquer si l'on doit conserver dans l'UI des simulations termin\u00E9es uniquement celles effectu\u00E9es localement @@ -516,7 +519,6 @@ isisfish.input.tree.vesseltypes=Types de navire isisfish.input.tree.zones=Zones isisfish.launch.anonymous=lecture seule -isisfish.launch.debugMode=debug mode isisfish.launch.email=courriel isisfish.launch.firstname=nom isisfish.launch.init.done=init done in %1$s. @@ -531,7 +533,6 @@ isisfish.launch.server.ssh.privateKeyFile=clef priv\u00E9e ssh isisfish.launch.server.ssh.publicKeyFile=clef publique ssh isisfish.launch.ssh=lecture-\u00E9criture (ssh) -isisfish.launch.start=Lancement Isis-fish... %1$s isisfish.launch.stop=Arr\u00EAt de la simulation... isisfish.launching=after init done in %1$s. isisfish.log.addAppender=ajoute un appender [%1$s] @@ -638,7 +639,7 @@ isisfish.metierSeasonInfoZone.season=Saison isisfish.metierSeasonInfoZone.selectSeason=S\u00E9lectionnez une saison isisfish.metierSeasonInfoZone.title=Saison / Zones -isisfish.monitor.title=Application Monitor +isisfish.monitor.title=Moniteur de l'application isisfish.month.april=avril isisfish.month.august=ao\u00FBt isisfish.month.december=d\u00E9cembre @@ -767,6 +768,7 @@ isisfish.queue.launcher=Lanceur de simulation isisfish.queue.plan=Plan isisfish.queue.progression=Progression +isisfish.queue.restartSimulation=Red\u00E9marrer isisfish.queue.showLog=Voir les logs de la simulation isisfish.queue.simulationLaunch=Lanceur de la queue des simulations isisfish.queue.status=\u00C9tat @@ -913,13 +915,20 @@ isisfish.simulation.remote.message.upload=Upload de la simulation isisfish.simulation.remote.message.waitingavailable=Attente d'une place de simulation isisfish.simulation.remote.message.waitingstart=Attente du d\u00E9marrage de la simulation +isisfish.simulation.restarting=Red\u00E9marrage... isisfish.simulation.title=Lanceur de simulation isisfish.simulator.launcher.inprocess=dans le m\u00EAme processus isisfish.simulator.launcher.remote=sur le serveur Caparmor isisfish.simulator.launcher.subprocess=dans un sous processus isisfish.simulator.simulaction.badid=Impossible de lancer la simulation '%s' \: l'identifiant existe d\u00E9j\u00E0 \! +isisfish.simulator.ssh.configuration.connecting=Connexion en cours +isisfish.simulator.ssh.configuration.connectingpk=Connexion en cours (avec cl\u00E9 publique) isisfish.simulator.ssh.configuration.connection=Information de connexion +isisfish.simulator.ssh.configuration.connectionerror=Connexion impossible (%s) +isisfish.simulator.ssh.configuration.connectionok=Connect\u00E9 avec succ\u00E8s isisfish.simulator.ssh.configuration.environment=Configuration sur Caparmor +isisfish.simulator.ssh.configuration.invalidpassphrase=Passphrase invalide +isisfish.simulator.ssh.configuration.test=Tester la configuration isisfish.simulator.ssh.configuration.title=Configuration du lanceur Caparmor isisfish.simulator.subprocess.readoutput.error= isisfish.species.age=Age Modified: isis-fish/trunk/src/main/resources/log4j.properties =================================================================== --- isis-fish/trunk/src/main/resources/log4j.properties 2009-05-19 21:54:07 UTC (rev 2258) +++ isis-fish/trunk/src/main/resources/log4j.properties 2009-05-20 13:43:44 UTC (rev 2259) @@ -6,7 +6,7 @@ log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) %M - %m%n # package level -log4j.logger.fr.ifremer.isisfish=INFO +log4j.logger.fr.ifremer.isisfish=DEBUG log4j.logger.org.codelutin=INFO log4j.logger.analyseplans=INFO log4j.logger.exports=INFO