All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ammonite.sshd.SshdRepl.scala Maven / Gradle / Ivy

The newest version!
package ammonite.sshd

import acyclic.file
import java.io.{InputStream, OutputStream, PrintStream}

import ammonite.ops.Path
import ammonite.sshd.util.Environment
import ammonite.util.{Bind, Ref}
import ammonite.runtime.Storage
import ammonite.repl.Repl

import scala.language.postfixOps

/**
 * An ssh server which serves ammonite repl as it's shell channel.
 * To start listening for incoming connections call
 * [[start()]] method. You can [[stop()]] the server at any moment.
 * It will also close all running sessions
 * @param sshConfig configuration of ssh server,
 *                  such as users credentials or port to be listening to
 * @param predef predef that will be installed on repl instances served by this server
 * @param replArgs arguments to pass to ammonite repl on initialization of the session
 * @param classloader classloader for ammonite to use
 */
class SshdRepl(sshConfig: SshServerConfig,
               predef: String = "",
               defaultPredef: Boolean = true,
               wd: Path = ammonite.ops.pwd,
               replArgs: Seq[Bind[_]] = Nil,
               classLoader: ClassLoader = SshdRepl.getClass.getClassLoader) {
  private lazy val sshd = SshServer(sshConfig, shellServer =
    SshdRepl.runRepl(sshConfig.ammoniteHome, predef, defaultPredef, wd, replArgs, classLoader))

  def port = sshd.getPort
  def start(): Unit = sshd.start()
  def stop(): Unit = sshd.stop()
  def stopImmediately(): Unit = sshd.stop(true)
}


object SshdRepl {
  // Actually runs a repl inside of session serving a remote user shell.
  private def runRepl(homePath: Path,
                      predef: String,
                      defaultPredef: Boolean,
                      wd: Path,
                      replArgs: Seq[Bind[_]],
                      replServerClassLoader: ClassLoader)
                     (in: InputStream, out: OutputStream): Unit = {
    // since sshd server has it's own customised environment,
    // where things like System.out will output to the
    // server's console, we need to prepare individual environment
    // to serve this particular user's session
    val replSessionEnv = Environment(replServerClassLoader, in, out)
    Environment.withEnvironment(replSessionEnv) {
      try {
        val augmentedPredef = ammonite.Main.maybeDefaultPredef(
          defaultPredef,
          ammonite.main.Defaults.predefString
        )
        new Repl(
          in, out, out,
          new Storage.Folder(homePath), augmentedPredef + "\n" + predef,
          wd, Some(ammonite.main.Defaults.welcomeBanner), replArgs
        ).run()
      } catch {
        case any: Throwable =>
          val sshClientOutput = new PrintStream(out)
          sshClientOutput.println("What a terrible failure, the REPL just blow up!")
          any.printStackTrace(sshClientOutput)
      }
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy