You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by bu...@apache.org on 2004/08/11 10:31:08 UTC
DO NOT REPLY [Bug 30582] New: -
New task to allow tunnelling nested tasks through ssh
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=30582>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND
INSERTED IN THE BUG DATABASE.
http://issues.apache.org/bugzilla/show_bug.cgi?id=30582
New task to allow tunnelling nested tasks through ssh
Summary: New task to allow tunnelling nested tasks through ssh
Product: Ant
Version: unspecified
Platform: All
OS/Version: All
Status: NEW
Severity: Enhancement
Priority: Other
Component: Optional Tasks
AssignedTo: dev@ant.apache.org
ReportedBy: mike.elmsly@ihug.co.nz
Example as in email excerpt below (I've pasted sample source below that)
Hi Rob, All,
heres my situation as an example
I have
[Reporting HOST]----[FW]----[BASTION HOST]----[FW]----[WEBSERVER]
I can ssh to the bastion host from my reporting host but not directly to
the webserver. What I wanted to do was retreive log files, without
storing them temporarily on the bastion host which involved some messy
workarounds to first retrieve the files and then clean up afterwards.
Hence the tunnel...Heres a sample from my demo build file....
<taskdef name="sshtunnel" classname="org.mike.Ant.SSHTunnel"
classpath="/home/elmslym/anttunnel.jar"/>
<!-- tunnel_retrieve - If bastion_host property is defined then first
bring files down from
remote host by tunneling through bastion host -->
<target name="tunnel_retrieve" if="env.bastion_host" >
<sshtunnel host="${env.bastion_host}"
username="${user.name}"
keyfile="${user.home}/.ssh/id_dsa"
knownhosts="${user.home}/.ssh/known_hosts"
passphrase="youre kidding me"
lport="2222"
rport="22"
rhost="${env.remote_host}">
<scp
file="${user.name}@localhost:${env.remote_dir}/${env.remote_file_pattern}"
todir="${env.local_dir}"
keyfile="${user.home}/.ssh/id_dsa"
knownhosts="${user.home}/.ssh/known_hosts"
trust="yes"
passphrase=""
compressionlevel="9"
port="2222"/>
</sshtunnel>
</target>
so I use the ssh tunnel task to setup an ssh tunnel on port 2222 going
through my bastion_host to the remote host on port 22.
Inside my sshtunnel task I nest an scp task to connect to the remote
host through the tunnel and bring the files back. However I could just
as easily nest a deploy task to a remote tomcat server etc.
Cheers,
Mike
================================================================================
/**
*
* Copyright 2000-2002,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.taskdefs.optional.ssh;
import org.apache.tools.ant.*;
import org.apache.tools.ant.taskdefs.optional.ssh.*;
import java.util.Vector;
import java.util.Iterator;
import com.jcraft.jsch.*;
/**
* Creates an SSH tunnel that nested tasks can utilize to perform tasks on
remote hosts.
*
* @author Mike Elmsly mike.elmsly@ihug.co.nz
* @version $Revision: 1.0 $
* @created July 5, 2004
* @since Ant 1.6.1
*/
public class SSHTunnel extends SSHBase implements TaskContainer {
/**
*
*/
//Set internal attributes here
private String rhost, lport, rport;
private Vector nestedtasks=new Vector();
private long maxwait = 0;
private Session session;
public SSHTunnel() {
super();
}
public void execute() throws BuildException {
//Check for valid configuration of task
if (getHost() == null) {
throw new BuildException("Host is required.");
}
if (getUserInfo().getName() == null) {
throw new BuildException("Username is required.");
}
if (getUserInfo().getKeyfile() == null
&& getUserInfo().getPassword() == null) {
throw new BuildException("Password or Keyfile is required.");
}
if (getRhost()==null || getLport()==null || getRport()==null) {
throw new BuildException("Tunnel information is required. \n Either rhost,
lport or rport is not set.");
}
//Create Connection
try {
session = openSession();
session.setTimeout((int) maxwait);
session.setPortForwardingL(Integer.parseInt(lport), rhost,
Integer.parseInt(rport));
log("SSHTunnel : Connection created successfully.", Project.MSG_INFO);
} catch (Exception e) {
log("SSHTunnel : Connect Failed", Project.MSG_ERR);
//throw exception as if connect fails we want to abort nested tasks
throw new BuildException("SSHTunnel Task Failed: Unable to create tunnel", e);
}
//Execute Nested tasks
try {
executeNestedTasks();
} catch (BuildException e) {
log("Nested Tasks Failed!", Project.MSG_ERR);
//In the event of failure attempt to close the tunnel
log("Attempting Disconnect", Project.MSG_ERR);
if (session != null) {
session.disconnect();
} else {
log("Session is null, can't call disconnect", Project.MSG_ERR);
}
//Once the tunnel is closed throw a build exception.
throw new BuildException("Nested Tasks Failed:", e);
} catch (Exception etwo) {
log("SSHTunnel Disconnect Failed", Project.MSG_ERR);
//Tunnel close may have failed but throw build exception for failed tasks
anyway
throw new BuildException("Nested Tasks Failed:", etwo);
}
//Lastly, if all has gone well, disconnect
try {
log("Attempting Disconnect", Project.MSG_ERR);
if (session != null) {
session.disconnect();
} else {
log("Session is null", Project.MSG_ERR);
}
} catch (Exception e) {
log("SSHTunnel Disconnect Failed", Project.MSG_ERR);
}
}
/**
*
*/
private void executeNestedTasks() throws BuildException {
Iterator taskiterator = nestedtasks.iterator();
while (taskiterator.hasNext()) {
Task thetask = (Task) taskiterator.next();
if ( thetask instanceof UnknownElement) {
((UnknownElement) thetask).maybeConfigure();
thetask = ((UnknownElement) thetask).getTask();
if (thetask == null) {
continue;
}
}
try {
thetask.perform();
} catch (Exception e) {
throw new BuildException(e);
}
}
}
/* (non-Javadoc)
* @see org.apache.tools.ant.TaskContainer#addTask(org.apache.tools.ant.Task)
*/
public void addTask(Task task) throws BuildException {
// TODO Auto-generated method stub
// System.out.println("In addTask with task:" + task.toString());
//log("In addTask with task:" + task.toString());
this.nestedtasks.add(task);
}
public void addTask(UnknownElement task) throws BuildException {
this.nestedtasks.add(task);
}
/**
* @return
*/
public String getLport() {
return lport;
}
/**
* @return
*/
public long getTimeout() {
return maxwait;
}
/**
* @return
*/
public String getRhost() {
return rhost;
}
/**
* @return
*/
public String getRport() {
return rport;
}
/**
* @param string
*/
public void setLport(String string) {
lport = string;
}
/**
* @param l
*/
public void setTimeout(long l) {
maxwait = l;
}
/**
* @param string
*/
public void setRhost(String string) {
rhost = string;
}
/**
* @param string
*/
public void setRport(String string) {
rport = string;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org