scalaでssh処理をしたい!ってなった時に、まず思いつくのは、sys.processだと思います。
sys.processを使えば、生のコマンドが実行できますので、自由にsshだったりなんだったりできます。
しかし、sprayやAkkaのコミッターである
sirthias (Mathias) · GitHub
が、ssh用のライブラリを作ってくれています。
sirthias/scala-ssh · GitHub
せっかくなので使ってみました。
ライブラリのインポート
まず、以下をインポートします。
libraryDependencies ++= Seq( "com.decodified" %% "scala-ssh" % "0.7.0" // メインのライブラリ "ch.qos.logback" % "logback-classic" % "1.1.2" //ログ用 "org.bouncycastle" % "bcprov-jdk16" % "1.46", // 暗号化用 "com.jcraft" % "jzlib" % "1.1.3" //圧縮用 )
実装
以下で実装している処理は、
- パスワードによるssh接続
- mkdirでリモート上でディレクトリを作成
- scpで作成したディレクトリにファイルを送信
となっております。
このライブラリを使ってあげることで、SSH接続に関しては委譲することができ、なんのコマンドを発行するかに集中できました。
また、sshのログイン方法をパスワードにしていますが、
公開鍵方式でもアクセス可能です。
その際は、
HostConfig(PublicKeyLogin(user, password, keyLocation))
で設定してあげるとできるかと思います。
sbt-assembly
これで万事解決かと思いきや、
ssh-assemblyでjarに固める際に、インポートしたライブラリの"org.bouncycastle"が悪さをします。
具体的に言うと、ライブラリ内で競合が発生します。
scala - assembly-merge-strategy issues using sbt-assembly - Stack Overflow
そこで、sbt-assembly 0.11.2での解決方法は、以下をassembly.sbtかbuild.sbtに追加します。
mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) => { // 競合した際に、先に出てきた方を使う case PathList("org", "bouncycastle", xs @ _*) => MergeStrategy.first case x => old(x) } }
sbt-assembly0.12では書き方が変わっていたので、ご注意ください。