Unverified Commit ebaf5ddf authored by Romain Reuillon's avatar Romain Reuillon
Browse files

[Application] enh: document arguments and add a password-file arg.

parent 6997d7b1
......@@ -13,7 +13,7 @@
@sect{Headless mode}
OpenMOLE proposes a headless mode for running scripts. You can enable it thanks to the -s option: @hl.highlight("./openmole -s /path/to/you/mole/script", "plain")
@p In that case OpenMOLE still asks for your preferences cyphering password. To provide it at launch time use the -pw option: @hl.highlight("./openmole -s /path/to/your/mole/script -pw password", "plain")
@p In that case OpenMOLE still asks for your preferences cyphering password. To provide it at launch time use the -pw option: @hl.highlight("./openmole -s /path/to/your/mole/script --password password", "plain"). A better practice is to write this password in a file readable by OpenMOLE only and use @hl.highlight("./openmole -s /path/to/your/mole/script --password-file password.txt", "plain").
@sect{Interactive console mode}
OpenMOLE also proposes an interactive console mode. To launch the console execute openmole -c in a console. The only difference between the script in the console mode and the ones from the editor concerns the way you launch the execution, you cancel it and you follow the execution progress. An console workflow is launched like this:
......
......@@ -4,7 +4,7 @@
@sect{Web Server}
Warning: The REST API of OpenMOLE is still experimental, it might be subject to some backward incompatible changes in the future.
@p OpenMOLE ships with a web server providing a REST API to @b{start} workflows, @b{manage} their execution and @b{retrieve} their output data. You should first configure your web server by running openmole --ws-configure. Then you may start the OpenMOLE web server, run the command: "openmole -ws --port 8843" from the console.
@p OpenMOLE ships with a web server providing a REST API to @b{start} workflows, @b{manage} their execution and @b{retrieve} their output data. To start the OpenMOLE REST API, run the command: "openmole --rest --port 8843" from the console. If you need to launch it automatically in a deamon for instance you should also you the --password-file argument to provide the password for encryption of the preferences.
@p The web server can be accessed at the URL https://localhost:8443. Replace @i{localhost} with the remote machine's hostname or IP address if the web server is not running on your local system.
......
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension
id="org.openmole.ui"
name="openmole"
point="org.eclipse.core.runtime.applications">
<application
cardinality="singleton-global"
thread="main"
visible="true">
<run class="org.openmole.ui.Application" />
</application>
</extension>
</plugin>
......@@ -58,8 +58,7 @@ object Application extends Logger {
object ConsoleMode extends LaunchMode
object GUIMode extends LaunchMode
object HelpMode extends LaunchMode
object ServerMode extends LaunchMode
object ServerConfigMode extends LaunchMode
object RESTMode extends LaunchMode
case class Config(
userPlugins: List[String] = Nil,
......@@ -68,6 +67,7 @@ object Application extends Logger {
scriptFile: Option[String] = None,
consoleWorkDirectory: Option[File] = None,
password: Option[String] = None,
passwordFile: Option[File] = None,
hostName: Option[String] = None,
launchMode: LaunchMode = GUIMode,
ignored: List[String] = Nil,
......@@ -97,34 +97,52 @@ object Application extends Logger {
def usage =
"""openmole [options]
[-p list of arg] plugins list of jar or category containing jars to be loaded
[-s path] a path of script to execute
[-pw password] openmole password
[-c] console mode
[-h] print help"""
@tailrec def parse(args: List[String], c: Config = Config()): Config =
|
|[-p | --plugin list of arg] plugins list of jar or category containing jars to be loaded
|[-c | --console] console mode
|[--port port] specify the port for the GUI or REST API
|[--script path] a path of on OpenMOLE script to execute
|[--password password] openmole password
|[--password-file file containing a password] read the OpenMOLE password (--password option) in a file
|[--rest] run the REST server
|[--remote] enable remote connection to the web interface
|[--no-browser] don't automatically launch the browser in GUI mode
|[--load-workspace-plugins] load the plugins of the OpenMOLE workspace (these plugins are always loaded in GUI mode)
|[--console-work-directory] specify the workDirectory variable in console mode (it is set to the current dirrectory by default)
|[--reset] reset all preferences and authentications
|[--] end of options the remaining arguments are provided to the console in the args array
|[-h | --help] print help"""
def parse(args: List[String], c: Config = Config()): Config = {
def plugins(tail: List[String]) = parse(dropArgs(tail), c.copy(userPlugins = takeArgs(tail)))
def help(tail: List[String]) = parse(tail, c.copy(launchMode = HelpMode))
def script(tail: List[String]) = parse(dropArg(tail), c.copy(scriptFile = Some(takeArg(tail)), launchMode = ConsoleMode))
def console(tail: List[String]) = parse(tail, c.copy(launchMode = ConsoleMode))
args match {
case "-p" :: tail parse(dropArgs(tail), c.copy(userPlugins = takeArgs(tail)))
case "-s" :: tail parse(dropArg(tail), c.copy(scriptFile = Some(takeArg(tail)), launchMode = ConsoleMode))
case "-pw" :: tail parse(dropArg(tail), c.copy(password = Some(takeArg(tail))))
case "-c" :: tail parse(tail, c.copy(launchMode = ConsoleMode))
case "-h" :: tail parse(tail, c.copy(launchMode = HelpMode))
case "-ws" :: tail parse(tail, c.copy(launchMode = ServerMode))
case "--load-homePlugins" :: tail parse(tail, c.copy(loadHomePlugins = Some(true)))
case "--console-workDirectory" :: tail parse(dropArg(tail), c.copy(consoleWorkDirectory = Some(new File(takeArg(tail)))))
case "--ws-configure" :: tail parse(tail, c.copy(launchMode = ServerConfigMode))
case "--port" :: tail parse(tail.tail, c.copy(port = Some(tail.head.toInt))) // Server port
case "--logger-level" :: tail parse(tail.tail, c.copy(loggerLevel = Some(tail.head)))
case "--remote" :: tail parse(tail, c.copy(remote = true))
case "--no-browser" :: tail parse(tail, c.copy(browse = false))
case "--reset" :: tail parse(tail, c.copy(reset = true))
case "--host-name" :: tail parse(tail.tail, c.copy(hostName = Some(tail.head)))
case "--" :: tail parse(Nil, c.copy(args = tail))
case s :: tail parse(tail, c.copy(ignored = s :: c.ignored))
case Nil c
case "-p" :: tail plugins(tail)
case "--plugins" :: tail plugins(tail)
case "-c" :: tail console(tail)
case "--console" :: tail console(tail)
case "-s" :: tail script(tail)
case "--script" :: tail script(tail)
case "--port" :: tail parse(tail.tail, c.copy(port = Some(tail.head.toInt)))
case "--password" :: tail parse(dropArg(tail), c.copy(password = Some(takeArg(tail))))
case "--password-file" :: tail parse(dropArg(tail), c.copy(passwordFile = Some(new File(takeArg(tail)))))
case "--rest" :: tail parse(tail, c.copy(launchMode = RESTMode))
case "--load-workspace-plugins" :: tail parse(tail, c.copy(loadHomePlugins = Some(true)))
case "--console-work-directory" :: tail parse(dropArg(tail), c.copy(consoleWorkDirectory = Some(new File(takeArg(tail)))))
case "--logger-level" :: tail parse(tail.tail, c.copy(loggerLevel = Some(tail.head)))
case "--remote" :: tail parse(tail, c.copy(remote = true))
case "--no-browser" :: tail parse(tail, c.copy(browse = false))
case "--reset" :: tail parse(tail, c.copy(reset = true))
case "--host-name" :: tail parse(tail.tail, c.copy(hostName = Some(tail.head)))
case "--" :: tail parse(Nil, c.copy(args = tail))
case "-h" :: tail help(tail)
case "--help" :: tail help(tail)
case s :: tail parse(tail, c.copy(ignored = s :: c.ignored))
case Nil c
}
}
val config = parse(args.map(_.trim).toList)
......@@ -141,7 +159,7 @@ object Application extends Logger {
val userPlugins =
existingUserPlugins.flatMap { p PluginManager.plugins(new File(p)) } ++
(if (config.loadHomePlugins.getOrElse(config.launchMode != ConsoleMode)) Workspace.pluginDir.listFilesSafe.flatMap(PluginManager.plugins) else Nil)
(if (config.loadHomePlugins.getOrElse(config.launchMode == GUIMode)) Workspace.pluginDir.listFilesSafe.flatMap(PluginManager.plugins) else Nil)
logger.fine(s"Loading user plugins " + userPlugins)
......@@ -150,7 +168,10 @@ object Application extends Logger {
PluginManager.startAll.foreach { case (b, e) logger.log(WARNING, s"Error staring bundle $b", e) }
PluginManager.tryLoad(plugins).foreach { case (b, e) logger.log(WARNING, s"Error loading bundle $b", e) }
try config.password foreach Workspace.setPassword
def password =
config.password orElse config.passwordFile.map(_.lines.head)
try password foreach Workspace.setPassword
catch {
case e: UserBadDataError
logger.severe("Wrong password!")
......@@ -164,18 +185,15 @@ object Application extends Logger {
case HelpMode
println(usage)
Console.ExitCodes.ok
case ServerConfigMode
configureRestServer()
Console.ExitCodes.ok
case ServerMode
if (!config.password.isDefined) Console.initPassword
case RESTMode
if (!password.isDefined) Console.initPassword
val server = new RESTServer(config.port, config.hostName)
server.start()
Console.ExitCodes.ok
case ConsoleMode
print(consoleSplash)
println(consoleUsage)
val console = new Console(config.password, config.scriptFile)
val console = new Console(password, config.scriptFile)
val variables = ConsoleVariables(args = config.args)
console.run(variables, config.consoleWorkDirectory)
case GUIMode
......@@ -187,7 +205,7 @@ object Application extends Logger {
val port = config.port.getOrElse(Workspace.preference(GUIServer.port))
val url = s"https://localhost:$port"
GUIServer.urlFile.content = url
if (config.remote) initGUIPassword()
if (config.remote && !password.isDefined) Console.initPassword
//The webapp location will then be somewhere in target
val webui = Workspace.file("webui")
webui.mkdirs()
......@@ -212,14 +230,4 @@ object Application extends Logger {
}
}
def initGUIPassword() = {
Console.initPassword
if (!Workspace.preferenceIsSet(GUIServer.passwordHash)) GUIServer.setPassword(Console.askPassword("Authentication password"))
}
def configureRestServer() = {
Console.initPassword
RESTServer.setPassword(Console.askPassword("Server password"))
}
}
......@@ -34,11 +34,8 @@ import org.openmole.tool.hash._
import org.openmole.tool.file._
object GUIServer {
val passwordHash = ConfigurationLocation[String]("GUIServer", "PasswordHash", None, true)
def isPasswordCorrect(p: String) = Workspace.preferenceOption(passwordHash).map(_ == p.hash.toString).getOrElse(false)
def isPasswordCorrect(p: String) = Workspace.passwordIsCorrect(p)
def resourcePath = (Workspace.openMOLELocation / "webapp").getAbsolutePath
def setPassword(p: String) = Workspace.setPreference(GUIServer.passwordHash, p.hash.toString)
val portValue = Network.freePort
val port = ConfigurationLocation("GUIServer", "Port", Some(portValue))
......
......@@ -16,9 +16,7 @@ import org.scalatra._
import org.openmole.tool.hash._
object RESTServer extends Logger {
def passwordHash = ConfigurationLocation[String]("REST", "PasswordHash", None, true)
def setPassword(p: String) = Workspace.setPreference(passwordHash, p.hash.toString)
def isPasswordCorrect(p: String) = Workspace.preferenceOption(passwordHash).map(_ == p.hash.toString).getOrElse(false)
def isPasswordCorrect(p: String) = Workspace.passwordIsCorrect(p)
}
import RESTServer.Log._
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment