Added SCP deloyer.

git-svn-id: https://svn.apache.org/repos/asf/maven/maven-1/plugins/trunk@113537 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
michal
2003-06-25 12:33:11 +00:00
parent f1ac6b0815
commit cd372b2d5f
5 changed files with 568 additions and 161 deletions

View File

@@ -64,7 +64,7 @@ import org.apache.maven.project.Project;
* The Bean which serves as Proxy for Jelly scripts To Artifact Deployement API
*
* @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
* @version $Id: MavenDeployRequest.java,v 1.5 2003/06/24 22:22:55 michal Exp $
* @version $Id: MavenDeployRequest.java,v 1.6 2003/06/25 12:33:11 michal Exp $
*/
public class MavenDeployRequest extends DeployRequest
{
@@ -95,13 +95,11 @@ public class MavenDeployRequest extends DeployRequest
String username =
(String) project.getContext().getVariable(
"maven.repo." + repository + ".username");
String password =
(String) project.getContext().getVariable(
"maven.repo." + repository + ".password");
System.out.println(repository + " password: '" + password + "'");
String passphrase =
(String) project.getContext().getVariable(
"maven.repo." + repository + ".passphrase");
@@ -120,7 +118,7 @@ public class MavenDeployRequest extends DeployRequest
String remoteGroup =
(String) project.getContext().getVariable(
"maven.repo." + repository + ".remote.group");
"maven.repo." + repository + ".group");
String proxyHost =
(String) project.getContext().getVariable(
@@ -142,26 +140,32 @@ public class MavenDeployRequest extends DeployRequest
setPassphrase(passphrase);
setPrivateKey(privateKey);
setGroup(remoteGroup);
setUrl(url.trim());
setUrl(url);
setProxyHost(proxyHost);
setProxyUser(proxyUser);
setProxyPass(proxyPassword);
if (port != null)
{
try
{
try
{
setPort(Integer.parseInt(port));
setPort(Integer.parseInt(port));
}
catch (Exception e)
{
//throw new DeployException("maven.repo." + repository + ".port should be an integer");
}
}
catch (Exception e)
if (proxyPort != null)
{
setProxyHost(proxyHost);
setProxyUser(proxyUser);
setProxyPass(proxyPassword);
}
try
{
setProxyPort(Integer.parseInt(proxyPort.trim()));
}
catch (Exception e)
{
try
{
setProxyPort(Integer.parseInt(proxyPort.trim()));
}
catch (Exception e)
{
//throw new DeployException("maven.repo." + repository + ".proxy.port should be an integer");
}
}
setInputFile(inputFile);

View File

@@ -61,13 +61,14 @@ import org.apache.maven.deploy.deployers.FileDeployer;
import org.apache.maven.deploy.deployers.FtpDeployer;
import org.apache.maven.deploy.deployers.HttpDeployer;
import org.apache.maven.deploy.deployers.SFtpDeployer;
import org.apache.maven.deploy.deployers.ScpDeployer;
import org.apache.maven.deploy.exceptions.DeployException;
import org.apache.maven.deploy.exceptions.UnsupportedProtocolDeployException;
/**
*
* @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
* @version $Id: DeployTool.java,v 1.3 2003/06/24 22:22:55 michal Exp $
* @version $Id: DeployTool.java,v 1.4 2003/06/25 12:33:11 michal Exp $
*/
public class DeployTool
{
@@ -100,6 +101,10 @@ public class DeployTool
{
deployer = new SFtpDeployer();
}
if (url.startsWith(ScpDeployer.PROTOCOL))
{
deployer = new ScpDeployer();
}
if (deployer == null)
{
throw new UnsupportedProtocolDeployException(url);

View File

@@ -0,0 +1,232 @@
package org.apache.maven.deploy.deployers;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache MavenSession" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache MavenSession", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
import java.io.File;
import org.apache.maven.deploy.DeployRequest;
import org.apache.maven.deploy.exceptions.DeployException;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Proxy;
import com.jcraft.jsch.ProxyHTTP;
import com.jcraft.jsch.ProxySOCKS5;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;
/**
* An ssh2 deployer that uses the JSch library and the JCE.
*
* This class deals with authetification stage of the process.
*
* We will first try to
* use public keys for authentication and if that doesn't work then we fall back
* to using the login and password of the user in question. NOTE: We are
* assuming the standard port of 22.
*
*
* @version $Id: GenericSshDeployer.java,v 1.1 2003/06/25 12:33:11 michal Exp $
* @todo still have to account for differing setups for people deploying to
* their own sites and to the central repository.
*/
public abstract class GenericSshDeployer extends AbstractDeployer
{
public final static int DEFAULT_SSH_PORT = 22;
public final static int SOCKS5_PROXY_PORT = 1080;
/**
* @see Deployer#project
*
* @todo better way of guessing what kind of proxy server is used
* by user
*/
public Session getSession(DeployRequest request) throws DeployException
{
try
{
JSch jsch = new JSch();
int port = request.getPort();
if (port == DeployRequest.UNKNOWN_PORT)
{
port = DEFAULT_SSH_PORT;
}
String host = request.getHost();
Session session = jsch.getSession(request.getUser(), host, port);
String proxyHost = request.getProxyHost();
if (proxyHost != null)
{
Proxy proxy = null;
int proxyPort = request.getProxyPort();
//if port == 1080 we will use SOCKS5 Proxy
// otherwise will use HTTP Proxy
if (proxyPort == SOCKS5_PROXY_PORT)
{
proxy = new ProxySOCKS5(proxyHost);
((ProxySOCKS5) proxy).setUserPasswd(
request.getProxyUser(),
request.getProxyPass());
}
else
{
proxy = new ProxyHTTP(proxyHost, proxyPort);
((ProxyHTTP) proxy).setUserPasswd(
request.getProxyUser(),
request.getProxyPass());
}
proxy.connect(session, host, port);
}
// Look for the private key and use it if available.
if (request.getPrivateKey() != null)
{
File privateKey = new File(request.getPrivateKey());
if (privateKey.exists())
{
System.out.println("Using private key: " + privateKey);
jsch.addIdentity(
privateKey.getAbsolutePath(),
request.getPassphrase());
}
}
// username and password will be given via UserInfo interface.
UserInfo ui = new MavenUserInfo(request);
session.setUserInfo(ui);
session.connect();
return session;
}
catch (Exception e)
{
e.printStackTrace();
throw new DeployException(
"Cannot connect. Reason: " + e.getMessage(),
e);
}
}
/**
* MavenUserInfo class which returns the necessary name and password from
* the POM to secure an ssh connection.
*/
public class MavenUserInfo implements UserInfo
{
DeployRequest request;
MavenUserInfo(DeployRequest request)
{
this.request = request;
}
public String getPassphrase()
{
return request.getPassphrase();
}
/* (non-Javadoc)
* @see com.jcraft.jsch.UserInfo#getPassword()
*/
public String getPassword()
{
return request.getPass();
}
/* (non-Javadoc)
* @see com.jcraft.jsch.UserInfo#promptPassphrase(java.lang.String)
*/
public boolean promptPassphrase(String arg0)
{
return true;
}
/* (non-Javadoc)
* @see com.jcraft.jsch.UserInfo#promptPassword(java.lang.String)
*/
public boolean promptPassword(String arg0)
{
return true;
}
/**
* @see com.jcraft.jsch.UserInfo#promptYesNo(java.lang.String)
*/
public boolean promptYesNo(String arg0)
{
return true;
}
/* (non-Javadoc)
* @see com.jcraft.jsch.UserInfo#showMessage(java.lang.String)
*/
public void showMessage(String message)
{
System.out.println(message);
}
}
}

View File

@@ -56,41 +56,28 @@ package org.apache.maven.deploy.deployers;
* ====================================================================
*/
import java.io.File;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.deploy.DeployRequest;
import org.apache.maven.deploy.exceptions.DeployException;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Proxy;
import com.jcraft.jsch.ProxyHTTP;
import com.jcraft.jsch.ProxySOCKS5;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.UserInfo;
import com.jcraft.jsch.SftpException;
/**
* An ssh2 deployer that uses the JSch library and the JCE. We will first try to
* use public keys for authentication and if that doesn't work then we fall back
* to using the login and password of the user in question. NOTE: We are
* assuming the standard port of 22.
*
* @author <a href="mailto:jason@zenplex.com">Jason van Zyl</a>
* @version $Id: SFtpDeployer.java,v 1.1 2003/06/24 22:22:54 michal Exp $
* @todo still have to account for differing setups for people deploying to
* their own sites and to the central repository.
* An SSH2 SFTP deployer
*
* @author Michal Maczka
* @version $Revision: 1.2 $ $Date: 2003/06/25 12:33:11 $
*/
public class SFtpDeployer extends AbstractDeployer
public class SFtpDeployer extends GenericSshDeployer
{
public final static String PROTOCOL = "sftp://";
public final static String SFTP_CHANNEL = "sftp";
public final static int DEFAULT_SSH_PORT = 22;
public final static int SOCKS5_PROXY_PORT = 1080;
public final static int S_IFDIR = 0x4000;
/**
* @see Deployer#project
@@ -111,65 +98,12 @@ public class SFtpDeployer extends AbstractDeployer
{
throw new DeployException("For sftp protocol remote group should be an integer");
}
Session session = getSession(request);
ChannelSftp channel = null;
try
{
JSch jsch = new JSch();
int port = request.getPort();
if (port == DeployRequest.UNKNOWN_PORT)
{
port = DEFAULT_SSH_PORT;
}
String host = request.getHost();
Session session = jsch.getSession(request.getUser(), host, port);
String proxyHost = request.getProxyHost();
if (proxyHost != null)
{
Proxy proxy = null;
int proxyPort = request.getProxyPort();
//if port == 1080 we will use SOCKS5 Proxy
// otherwise will use HTTP Proxy
if (proxyPort == SOCKS5_PROXY_PORT)
{
proxy = new ProxySOCKS5(proxyHost);
((ProxySOCKS5) proxy).setUserPasswd(
request.getProxyUser(),
request.getProxyPass());
}
else
{
proxy = new ProxyHTTP(proxyHost, proxyPort);
((ProxyHTTP) proxy).setUserPasswd(
request.getProxyUser(),
request.getProxyPass());
}
proxy.connect(session, host, port);
}
// Look for the private key and use it if available.
if (request.getPrivateKey() != null)
{
File privateKey = new File(request.getPrivateKey());
if (privateKey.exists())
{
System.out.println("Using private key: " + privateKey);
jsch.addIdentity(
privateKey.getAbsolutePath(),
request.getPassphrase());
}
}
// username and password will be given via UserInfo interface.
UserInfo ui = new MavenUserInfo(request);
session.setUserInfo(ui);
session.connect();
ChannelSftp channel =
(ChannelSftp) session.openChannel(SFTP_CHANNEL);
channel = (ChannelSftp) session.openChannel(SFTP_CHANNEL);
channel.connect();
// iterate over all directories in the path. try to create
// directory
@@ -195,7 +129,7 @@ public class SFtpDeployer extends AbstractDeployer
}
catch (Exception e)
{
// file does not exists
// file most probably does not exists
channel.mkdir(dirs[i]);
channel.cd(dirs[i]);
}
@@ -210,75 +144,38 @@ public class SFtpDeployer extends AbstractDeployer
}
}
catch (Exception e)
catch (SftpException e)
{
e.printStackTrace();
throw new DeployException(
"Cannot deploy. Reason: " + e.getMessage(),
e);
}
}
/**
* MavenUserInfo class which returns the necessary name and password from
* the POM to secure an ssh connection.
*/
public class MavenUserInfo implements UserInfo
{
DeployRequest request;
MavenUserInfo(DeployRequest request)
catch (JSchException e)
{
this.request = request;
throw new DeployException(
"Cannot deploy. Reason: " + e.getMessage(),
e);
}
public String getPassphrase()
finally
{
return request.getPassphrase();
try
{
channel.disconnect();
}
catch (Exception e)
{
//just ignore.
}
try
{
session.disconnect();
}
catch (Exception e)
{
// just ignore.
}
}
/* (non-Javadoc)
* @see com.jcraft.jsch.UserInfo#getPassword()
*/
public String getPassword()
{
return request.getPass();
}
/* (non-Javadoc)
* @see com.jcraft.jsch.UserInfo#promptPassphrase(java.lang.String)
*/
public boolean promptPassphrase(String arg0)
{
return true;
}
/* (non-Javadoc)
* @see com.jcraft.jsch.UserInfo#promptPassword(java.lang.String)
*/
public boolean promptPassword(String arg0)
{
return true;
}
/**
* @see com.jcraft.jsch.UserInfo#promptYesNo(java.lang.String)
*/
public boolean promptYesNo(String arg0)
{
return true;
}
/* (non-Javadoc)
* @see com.jcraft.jsch.UserInfo#showMessage(java.lang.String)
*/
public void showMessage(String message)
{
System.out.println(message);
}
}
}

View File

@@ -0,0 +1,269 @@
package org.apache.maven.deploy.deployers;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache MavenSession" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache MavenSession", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.maven.deploy.DeployRequest;
import org.apache.maven.deploy.exceptions.DeployException;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
/**
* An SSH2 SFTP deployer
*
* @author Michal Maczka
* @version $Revision: 1.1 $ $Date: 2003/06/25 12:33:11 $
*/
public class ScpDeployer extends GenericSshDeployer
{
public final static String PROTOCOL = "scp://";
public final static String EXEC_CHANNEL = "exec";
/**
* @see Deployer#project
*
* @todo better way of guessing what king of proxy server is used
*/
public void deploy(DeployRequest request) throws DeployException
{
Session session = getSession(request);
try
{
//String scpCmd = "scp -t " + request.getOutputFile() + "\n";
executeSimpleCommand(
session,
"mkdir -p " + request.getOutputDir() + "\n");
doCopy(session, request);
if (request.getGroup() != null)
{
executeSimpleCommand(
session,
"chgrp "
+ request.getGroup()
+ " "
+ request.getOutputFile()
+ "\n");
}
}
finally
{
try
{
session.disconnect();
}
catch (Exception e)
{
// just ignore.
}
}
}
/**
* Execute simple command
*/
private void executeSimpleCommand(Session session, String command)
throws DeployException
{
System.out.println("Executing command: " + command);
ChannelExec channel = null;
try
{
channel = (ChannelExec) session.openChannel(EXEC_CHANNEL);
channel.setCommand(command);
OutputStream out = channel.getOutputStream();
InputStream in = channel.getInputStream();
channel.connect();
}
catch (Exception e)
{
throw new DeployException(
"Cannot execute remote command: " + command);
}
finally
{
//when channel cannot be closed it is still ok. this "local"
//failure is not global failure
if (channel != null)
{
try
{
channel.disconnect();
}
catch (Exception e)
{
//ignore
}
}
}
}
/**
* Copy artifact file using streams (pipes)
*/
private void doCopy(Session session, DeployRequest request)
throws DeployException
{
try
{
String inputFile = request.getInputFile();
String outputFile = request.getOutputFile();
String outputDir = request.getOutputDir();
// exec 'scp -t rfile' remotely
String command = "scp -t " + outputDir + "/" + outputFile;
System.out.println("Executing command: " + command);
ChannelExec channel =
(ChannelExec) session.openChannel(EXEC_CHANNEL);
channel.setCommand(command);
// get I/O streams for remote scp
OutputStream out = channel.getOutputStream();
InputStream in = channel.getInputStream();
channel.connect();
byte[] tmp = new byte[1];
// wait for '\0'
do
{
in.read(tmp, 0, 1);
}
while (tmp[0] != 0);
// send "C0644 filesize filename", where filename should not include '/'
int filesize = (int) (new File(inputFile)).length();
command = "C0644 " + filesize + " ";
if (inputFile.lastIndexOf('/') > 0)
{
command += inputFile.substring(inputFile.lastIndexOf('/') + 1);
}
else
{
command += inputFile;
}
command += "\n";
out.write(command.getBytes());
out.flush();
// wait for '\0'
do
{
in.read(tmp, 0, 1);
}
while (tmp[0] != 0);
// send a content of inputFile
FileInputStream fis = new FileInputStream(inputFile);
byte[] buf = new byte[1024];
while (true)
{
int len = fis.read(buf, 0, buf.length);
if (len <= 0)
break;
out.write(buf, 0, len);
out.flush();
}
// send '\0'
buf[0] = 0;
out.write(buf, 0, 1);
out.flush();
// wait for '\0'
do
{
in.read(tmp, 0, 1);
}
while (tmp[0] != 0);
}
catch (FileNotFoundException e)
{
throw new DeployException(
"Input file was not found: " + request.getInputFile(),
e);
}
catch (IOException e)
{
throw new DeployException(
"IO error while sending file: " + request.getInputFile(),
e);
}
catch (JSchException e)
{
throw new DeployException(
"Error occured while copying file to remote host",
e);
}
}
}