Use ant to send file to remote automatically
最近一直在做测试, 需要把自己的程序扔到远程服务器上执行. 于是, 在起初的阶段, 我每次都非常痛苦地打一堆字”scp -P xx file user@host:/some/dir”, 让人接近崩溃.. -,-
痛定思痛, 决定来自动化这个过程. 所以直接把目光投向了Ant, 一个强大的构建工具. Ant是伟大的, :) 它提供了remote task, 支持通过ftp/scp/sshexec等任务来完成远程操作. 我下面将针对scp task.
Scp task是Ant的一个optional task, 所以要运行这个task, 首先需要解决dependencies — jsch(java对ssh2的实现). 注: jsch需要0.1.29以上版本. 可以去Jsch主页下载.
关于Scp task的每个parameters的用法, 我这里就不累赘了. 可以去Ant主页上查看. 我下面就给出几个简单的例子.
Copy a remote directory to a local directory
<scp file=”user:pass@host:/home/sishen/*” todir=”/home/sishen”/>
Copy a single local file to a remote machine with separate password attribute
<scp file=”file” todir=”user@host:/home/sishen” password=”pass”/>
Copy a single local file to a remote machine using key base authentication.
<scp file=”myfile.txt”
todir=”user@somehost:/home/chuck”
keyfile=”${user.home}/.ssh/id_dsa”
passphrase=”my extremely secret passphrase”/>
在这基础上, 你还可以用FileSet, DirSet, FileList来group要传送的文件. 比如
<scp todir=”xxx@xxx:~/xxx”
port=”22″
keyfile=”${user.home}/.ssh/id_rsa”
passphrase=”xxxx”>
<fileset dir=”lib”>
<include <exclude </fileset>
<fileset dir=”${build.dir}”>
<include </fileset>
</scp>
这里也引进了一个问题. 密码是以明文的形式直接显示的, 而这却是我们无法接受的. 针对这个, 我们有3种解决方法.
通过command argument来输入密码. 比如ant -Dpassphrase=xxxxx.
把passphrase=xxx存储在文件里, 设置权限为600. 然后ant -propertyfile 来获取密码.
通过input task. 由用户交互输入密码.
从 安全性考虑, 只有方法3才是让我满意. 然而, 使用方法3, 你又将面临一个问题, 密码输入过程是明文的. 这是则是InputHandler的决策. 当不指定InputHandler, ant将使用DefaultInputHandler, 而DefaultInputHandler则是读取用户输入, 然后显示在console上. 那么, 解决的方法也就明了了. 我们需要实现一个MaskPasword的InputHandler. 关于这个, 已经有实现了. 其中心思想是设置InputStream为System.err(即取消buffer), 然后读取用户输入,读到一个就用\b*(backspace+*)来代替.
下面是我的一个完整的应用. 我用了单独的target.
<target depends=”jars” description=”send file to remote server”>
<echo level=”warning” message=”send file through ssh ing”/>
<input message=”Enter passphrase for key ‘${user.home}/.ssh/id_rsa’” addproperty=”passphrase”/>
<scp file=”${build.dir}/${app.jar}”
todir=”user@host:~/dir/”
port=”22″
keyfile=”${user.home}/.ssh/id_rsa”
passphrase=”${passphrase}”
trust=”yes”/>
</target>
这里有一点要注意, 就是trust=”yes”. 这个是表示接受所有unknown的host. Jsch只支持SSHV2的known_host. 而Openssh在knows_host文件里, 对host进行了hash, 所以造成每次匹配不成功, 因而使用openssh的客户端, 必须得加上trust=”yes”.
自此以后, 轻松了. 只要运行ant remote -inputhandler org.apache.tools.ant.input.PasswordInputHandler, 输入密码, 所以要传送的文件就会乖乖的到远方去了… 如果嫌麻烦的话, 把remote设为default…
Resource:
extendinput.jar: PasswordInputHandler的jar包
最近一直在做测试, 需要把自己的程序扔到远程服务器上执行. 于是, 在起初的阶段, 我每次都非常痛苦地打一堆字”scp -P xx file user@host:/some/dir”, 让人接近崩溃.. -,-
痛定思痛, 决定来自动化这个过程. 所以直接把目光投向了Ant, 一个强大的构建工具. Ant是伟大的, :) 它提供了remote task, 支持通过ftp/scp/sshexec等任务来完成远程操作. 我下面将针对scp task.
Scp task是Ant的一个optional task, 所以要运行这个task, 首先需要解决dependencies — jsch(java对ssh2的实现). 注: jsch需要0.1.29以上版本. 可以去Jsch主页下载.
关于Scp task的每个parameters的用法, 我这里就不累赘了. 可以去Ant主页上查看. 我下面就给出几个简单的例子.
Copy a remote directory to a local directory
<scp file=”user:pass@host:/home/sishen/*” todir=”/home/sishen”/>
Copy a single local file to a remote machine with separate password attribute
<scp file=”file” todir=”user@host:/home/sishen” password=”pass”/>
Copy a single local file to a remote machine using key base authentication.
<scp file=”myfile.txt”
todir=”user@somehost:/home/chuck”
keyfile=”${user.home}/.ssh/id_dsa”
passphrase=”my extremely secret passphrase”/>
在这基础上, 你还可以用FileSet, DirSet, FileList来group要传送的文件. 比如
<scp todir=”xxx@xxx:~/xxx”
port=”22″
keyfile=”${user.home}/.ssh/id_rsa”
passphrase=”xxxx”>
<fileset dir=”lib”>
<include <exclude </fileset>
<fileset dir=”${build.dir}”>
<include </fileset>
</scp>
这里也引进了一个问题. 密码是以明文的形式直接显示的, 而这却是我们无法接受的. 针对这个, 我们有3种解决方法.
通过command argument来输入密码. 比如ant -Dpassphrase=xxxxx.
把passphrase=xxx存储在文件里, 设置权限为600. 然后ant -propertyfile 来获取密码.
通过input task. 由用户交互输入密码.
从 安全性考虑, 只有方法3才是让我满意. 然而, 使用方法3, 你又将面临一个问题, 密码输入过程是明文的. 这是则是InputHandler的决策. 当不指定InputHandler, ant将使用DefaultInputHandler, 而DefaultInputHandler则是读取用户输入, 然后显示在console上. 那么, 解决的方法也就明了了. 我们需要实现一个MaskPasword的InputHandler. 关于这个, 已经有实现了. 其中心思想是设置InputStream为System.err(即取消buffer), 然后读取用户输入,读到一个就用\b*(backspace+*)来代替.
下面是我的一个完整的应用. 我用了单独的target.
<target depends=”jars” description=”send file to remote server”>
<echo level=”warning” message=”send file through ssh ing”/>
<input message=”Enter passphrase for key ‘${user.home}/.ssh/id_rsa’” addproperty=”passphrase”/>
<scp file=”${build.dir}/${app.jar}”
todir=”user@host:~/dir/”
port=”22″
keyfile=”${user.home}/.ssh/id_rsa”
passphrase=”${passphrase}”
trust=”yes”/>
</target>
这里有一点要注意, 就是trust=”yes”. 这个是表示接受所有unknown的host. Jsch只支持SSHV2的known_host. 而Openssh在knows_host文件里, 对host进行了hash, 所以造成每次匹配不成功, 因而使用openssh的客户端, 必须得加上trust=”yes”.
自此以后, 轻松了. 只要运行ant remote -inputhandler org.apache.tools.ant.input.PasswordInputHandler, 输入密码, 所以要传送的文件就会乖乖的到远方去了… 如果嫌麻烦的话, 把remote设为default…
Resource:
extendinput.jar: PasswordInputHandler的jar包