From 3e02e852712e4a4e42b6591e3fd3ff8d05b63bca Mon Sep 17 00:00:00 2001 From: michal Date: Sat, 2 Aug 2003 22:51:45 +0000 Subject: [PATCH] Added flush() method to Deployer SCP delpoyer now creates zip, delpoys and then unzip (need to check how portable accross variuos Unixes this code is) git-svn-id: https://svn.apache.org/repos/asf/maven/maven-1/plugins/trunk@113775 13f79535-47bb-0310-9956-ffa450edef68 --- .../deploy/deployers/AbstractDeployer.java | 9 +- .../maven/deploy/deployers/Deployer.java | 37 +-- .../maven/deploy/deployers/FileDeployer.java | 4 +- .../deploy/deployers/GenericSshDeployer.java | 4 +- .../maven/deploy/deployers/SFtpDeployer.java | 10 +- .../maven/deploy/deployers/ScpDeployer.java | 234 +++++++++++++++--- .../apache/maven/deploy/util/Packager.java | 152 ++++++++++++ 7 files changed, 395 insertions(+), 55 deletions(-) create mode 100644 artifact/src/main/org/apache/maven/deploy/util/Packager.java diff --git a/artifact/src/main/org/apache/maven/deploy/deployers/AbstractDeployer.java b/artifact/src/main/org/apache/maven/deploy/deployers/AbstractDeployer.java index c227ba13..cda1197e 100644 --- a/artifact/src/main/org/apache/maven/deploy/deployers/AbstractDeployer.java +++ b/artifact/src/main/org/apache/maven/deploy/deployers/AbstractDeployer.java @@ -1,4 +1,7 @@ package org.apache.maven.deploy.deployers; + +import org.apache.maven.deploy.exceptions.TransferFailedException; + /* ==================================================================== * The Apache Software License, Version 1.1 * @@ -60,9 +63,11 @@ package org.apache.maven.deploy.deployers; * * @author Jason van Zyl * @author Michal Maczka - * @version $Id: AbstractDeployer.java,v 1.1 2003/06/17 22:05:59 michal Exp $ + * @version $Id: AbstractDeployer.java,v 1.2 2003/08/02 22:48:39 michal Exp $ */ public abstract class AbstractDeployer implements Deployer { - + public void flush() throws TransferFailedException + { + } } diff --git a/artifact/src/main/org/apache/maven/deploy/deployers/Deployer.java b/artifact/src/main/org/apache/maven/deploy/deployers/Deployer.java index 8f6b515c..1e086307 100644 --- a/artifact/src/main/org/apache/maven/deploy/deployers/Deployer.java +++ b/artifact/src/main/org/apache/maven/deploy/deployers/Deployer.java @@ -1,9 +1,6 @@ package org.apache.maven.deploy.deployers; -import org.apache.maven.deploy.RepositoryInfo; import org.apache.maven.deploy.DeployRequest; -import org.apache.maven.deploy.exceptions.AuthenticationException; -import org.apache.maven.deploy.exceptions.TransferFailedException; /* ==================================================================== * The Apache Software License, Version 1.1 @@ -60,45 +57,53 @@ import org.apache.maven.deploy.exceptions.TransferFailedException; * * ==================================================================== */ +import org.apache.maven.deploy.RepositoryInfo; +import org.apache.maven.deploy.exceptions.AuthenticationException; +import org.apache.maven.deploy.exceptions.TransferFailedException; /** - * - * Common interface for classes capable of uploading a file to remote host - + * + * Common interface for classes capable of uploading a file to remote host + * * @author Michal Maczka - * @version $Id: Deployer.java,v 1.3 2003/07/17 11:13:16 michal Exp $ + * @version $Id: Deployer.java,v 1.4 2003/08/02 22:48:39 michal Exp $ */ public interface Deployer { - /** * Set the information about host to which we will deploy. - * In this method deployer can allocate the resources which will + * In this method deployer can allocate the resources which will * be needed to perform an upload. E.g. connection to remote host - * can be opened, + * can be opened, * Resources allocated in this metod should * be release when deloyer is not needed any more - * @see #release() + * @see #release() * * @param repoInfo * @throws AuthenticationException when connection to remote host cannot be established */ - public void init(RepositoryInfo repoInfo) + public void init( RepositoryInfo repoInfo ) throws AuthenticationException; /** - * Release all resources which were allocated + * Release all resources which were allocated * by this deployer (e.g. a connection to remote host) * */ - public void release(); + public void release( ); /** * Perform an upload of single file to remote host * @param request DeployRequest which should contatin all parameters * which are necessery to upload a file - * to remote host. + * to remote host. */ - public void deploy(DeployRequest request) throws TransferFailedException; + public void deploy( DeployRequest request ) + throws TransferFailedException; + + /** + * + */ + public void flush() throws TransferFailedException; } diff --git a/artifact/src/main/org/apache/maven/deploy/deployers/FileDeployer.java b/artifact/src/main/org/apache/maven/deploy/deployers/FileDeployer.java index 6df068be..2866e40f 100644 --- a/artifact/src/main/org/apache/maven/deploy/deployers/FileDeployer.java +++ b/artifact/src/main/org/apache/maven/deploy/deployers/FileDeployer.java @@ -69,9 +69,9 @@ import org.apache.maven.deploy.exceptions.TransferFailedException; * file system. * * @author Michal Maczka - * @version $Id: FileDeployer.java,v 1.8 2003/07/17 11:13:17 michal Exp $ + * @version $Id: FileDeployer.java,v 1.9 2003/08/02 22:48:39 michal Exp $ */ -public class FileDeployer implements Deployer +public class FileDeployer extends AbstractDeployer { private RepositoryInfo repoInfo; diff --git a/artifact/src/main/org/apache/maven/deploy/deployers/GenericSshDeployer.java b/artifact/src/main/org/apache/maven/deploy/deployers/GenericSshDeployer.java index 1a555357..12a73741 100644 --- a/artifact/src/main/org/apache/maven/deploy/deployers/GenericSshDeployer.java +++ b/artifact/src/main/org/apache/maven/deploy/deployers/GenericSshDeployer.java @@ -79,7 +79,7 @@ import com.jcraft.jsch.UserInfo; * and if that doesn't work then we fall back * to using the login and password * - * @version $Id: GenericSshDeployer.java,v 1.5 2003/07/18 07:37:17 bwalding Exp $ + * @version $Id: GenericSshDeployer.java,v 1.6 2003/08/02 22:48:39 michal Exp $ * @todo still have to account for differing setups for people deploying to * their own sites and to the central repository. * @todo improve exception handling @@ -108,7 +108,7 @@ public abstract class GenericSshDeployer extends AbstractDeployer /* (non-Javadoc) * @see org.apache.maven.deploy.deployers.Deployer#getAuthenticationInfo() */ - public RepositoryInfo getAuthenticationInfo() + public RepositoryInfo getRepositoryInfo() { return repoInfo; } diff --git a/artifact/src/main/org/apache/maven/deploy/deployers/SFtpDeployer.java b/artifact/src/main/org/apache/maven/deploy/deployers/SFtpDeployer.java index 878f3b80..e4b08464 100644 --- a/artifact/src/main/org/apache/maven/deploy/deployers/SFtpDeployer.java +++ b/artifact/src/main/org/apache/maven/deploy/deployers/SFtpDeployer.java @@ -71,7 +71,7 @@ import com.jcraft.jsch.SftpProgressMonitor; * An SSH2/SFTP deployer * * @author Michal Maczka - * @version $Revision: 1.6 $ $Date: 2003/07/17 11:13:17 $ + * @version $Revision: 1.7 $ $Date: 2003/08/02 22:48:39 $ */ public class SFtpDeployer extends GenericSshDeployer { @@ -166,7 +166,7 @@ public class SFtpDeployer extends GenericSshDeployer } } - if (getAuthenticationInfo().isDebugOn()) + if (getRepositoryInfo().isDebugOn()) { channel.put( request.getSrcFile(), @@ -182,12 +182,12 @@ public class SFtpDeployer extends GenericSshDeployer if (groupId != null) { - if (getAuthenticationInfo().isDebugOn()) + if (getRepositoryInfo().isDebugOn()) { System.out.println("Changing group to: " + groupId); } channel.chgrp(groupId.intValue(), request.getDestFile()); - if (getAuthenticationInfo().isDebugOn()) + if (getRepositoryInfo().isDebugOn()) { System.out.println("Group successfully changed"); } @@ -204,7 +204,7 @@ public class SFtpDeployer extends GenericSshDeployer String msg = "Error occured while deploying to remote host:" - + getAuthenticationInfo().getHost() + + getRepositoryInfo().getHost() + ":" + e.getMessage(); throw new TransferFailedException(msg, e); diff --git a/artifact/src/main/org/apache/maven/deploy/deployers/ScpDeployer.java b/artifact/src/main/org/apache/maven/deploy/deployers/ScpDeployer.java index f20d88ec..13054cf4 100644 --- a/artifact/src/main/org/apache/maven/deploy/deployers/ScpDeployer.java +++ b/artifact/src/main/org/apache/maven/deploy/deployers/ScpDeployer.java @@ -1,5 +1,4 @@ package org.apache.maven.deploy.deployers; - /* ==================================================================== * The Apache Software License, Version 1.1 * @@ -56,22 +55,29 @@ package org.apache.maven.deploy.deployers; * ==================================================================== */ -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.io.OutputStream; - -import org.apache.maven.deploy.DeployRequest; -import org.apache.maven.deploy.exceptions.TransferFailedException; - import com.jcraft.jsch.ChannelExec; import com.jcraft.jsch.Session; +import org.apache.maven.deploy.DeployRequest; +import org.apache.maven.deploy.RepositoryInfo; +import org.apache.maven.deploy.exceptions.AuthenticationException; +import org.apache.maven.deploy.exceptions.TransferFailedException; +import org.apache.maven.deploy.util.Packager; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import java.util.LinkedList; +import java.util.List; + /** - * An SSH2/SCP deployer - * + * An SSH2/SCP deployer + * * @author Michal Maczka - * @version $Revision: 1.5 $ $Date: 2003/07/17 11:13:17 $ + * @version $Revision: 1.6 $ $Date: 2003/08/02 22:48:39 $ */ public class ScpDeployer extends GenericSshDeployer { @@ -80,54 +86,216 @@ public class ScpDeployer extends GenericSshDeployer /** SSH2 Channel name used to communicate with the server*/ public final static String EXEC_CHANNEL = "exec"; + public final static String COMPRESS = "maven.deployer.scp.compress"; + + /** + * I want to have compression by default + * so if system property is missing flag will be set to false + * that's why I am using deployNotCompressed variable name instead of + * straight forward deployCompressed + */ + public boolean deployNotCompressed = true; + private List srcFiles = new LinkedList(); + private List destFiles = new LinkedList(); + + /** + * @see org.apache.maven.deploy.deployers.Deployer#release() + */ + public void flush() throws TransferFailedException + { + if (!deployNotCompressed) + { + doDeployCompressed(); + } + + super.flush(); + } + + /** + * @return + */ + public boolean isDeployNotCompressed() + { + return deployNotCompressed; + } + + /** + * @param deployCompressed + */ + public void setDeployNotCompressed(boolean deployNotCompressed) + { + this.deployNotCompressed = deployNotCompressed; + } + + /** + * @todo Find better way to configure deployer + * @see org.apache.maven.deploy.deployers.Deployer#init(org.apache.maven.deploy.RepositoryInfo) + */ + public void init(RepositoryInfo repoInfo) throws AuthenticationException + { + setDeployNotCompressed(Boolean.getBoolean(COMPRESS)); + super.init(repoInfo); + } + + /* (non-Javadoc) + * @see org.apache.maven.deploy.deployers.Deployer#deploy(org.apache.maven.deploy.DeployRequest) + */ + public void deploy(DeployRequest request) throws TransferFailedException + { + if (deployNotCompressed) + { + doDeployNotCompressed(request); + } + else + { + srcFiles.add(request.getSrcFile()); + destFiles.add(request.getDestFile()); + } + } /** * @see Deployer#deploy(DeployRequest) * */ - public void deploy(DeployRequest request) throws TransferFailedException - { + public void doDeployNotCompressed(DeployRequest request) + throws TransferFailedException + { Session session = getSession(); String mkdirCmd = "mkdir -p " - + getAuthenticationInfo().getBasedir() + + getRepositoryInfo().getBasedir() + "/" + request.dirname() + "\n"; + executeSimpleCommand(session, mkdirCmd); doCopy(session, request); - if (getAuthenticationInfo().getGroup() != null) - { + if (getRepositoryInfo().getGroup() != null) + { String chgrpCmd = "chgrp " - + getAuthenticationInfo().getGroup() + + getRepositoryInfo().getGroup() + " " - + getAuthenticationInfo().getBasedir() + + getRepositoryInfo().getBasedir() + "/" + request.getDestFile() + "\n"; + executeSimpleCommand(session, chgrpCmd); } - } /** - * Execute "simple" remote command using exec channel + * @see Deployer#deploy(DeployRequest) + * + */ + public void doDeployCompressed() throws TransferFailedException + { + Session session = getSession(); + File zip = null; + + try + { + zip = File.createTempFile("maven-deployer-", ".zip"); + Packager.createZip(srcFiles, destFiles, zip); + } + catch (IOException e) + { + if ((zip != null) && zip.exists()) + { + try + { + zip.delete(); + } + catch (Exception ee) + { + // ignore + // file is left in temp directory + // no tragedy + } + } + + throw new TransferFailedException("Cannot create ZIP file"); + } + + try + { + DeployRequest request = + new DeployRequest(zip.getAbsolutePath(), zip.getName()); + + doCopy(session, request); + + String unzipCmd = + "unzip -d -u " + + getRepositoryInfo().getBasedir() + + " " + + getRepositoryInfo().getBasedir() + + "/" + + request.getDestFile() + + "\n"; + executeSimpleCommand(session, unzipCmd); + + //@ this is not working! + String rmCmd = + "rm -f " + + getRepositoryInfo().getBasedir() + + "/" + + request.getDestFile() + + "\n"; + + executeSimpleCommand(session, rmCmd); + + if (getRepositoryInfo().getGroup() != null) + { + String chgrpCmd = + "chgrp -r" + + getRepositoryInfo().getGroup() + + " " + + getRepositoryInfo().getBasedir() + + "\n"; + + executeSimpleCommand(session, chgrpCmd); + } + + } + finally + { + if ((zip != null) && zip.exists()) + { + try + { + zip.delete(); + } + catch (Exception ee) + { + // ignore + // file is left in temp directory + // no tragedy + } + } + } + } + + /** + * Execute "simple" remote command using exec channel */ private void executeSimpleCommand(Session session, String command) throws TransferFailedException { - 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) @@ -151,23 +319,25 @@ public class ScpDeployer extends GenericSshDeployer private void doCopy(Session session, DeployRequest request) throws TransferFailedException { - ChannelExec channel = null; + try { String srcFile = request.getSrcFile(); String destFile = - getAuthenticationInfo().getBasedir() - + "/" - + request.getDestFile(); + getRepositoryInfo().getBasedir() + "/" + request.getDestFile(); + // exec 'scp -t rfile' remotely String command = "scp -t " + destFile; + System.out.println("Executing command: " + command); 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]; @@ -181,7 +351,9 @@ public class ScpDeployer extends GenericSshDeployer // send "C0644 filesize filename", where filename should not include '/' int filesize = (int) (new File(srcFile)).length(); + command = "C0644 " + filesize + " "; + if (srcFile.lastIndexOf('/') > 0) { command += srcFile.substring(srcFile.lastIndexOf('/') + 1); @@ -190,6 +362,7 @@ public class ScpDeployer extends GenericSshDeployer { command += srcFile; } + command += "\n"; out.write(command.getBytes()); @@ -205,11 +378,16 @@ public class ScpDeployer extends GenericSshDeployer // send a content of inputFile FileInputStream fis = new FileInputStream(srcFile); 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(); } @@ -230,7 +408,8 @@ public class ScpDeployer extends GenericSshDeployer { String msg = "Error occured while deploying to remote host:" - + getAuthenticationInfo().getHost(); + + getRepositoryInfo().getHost(); + throw new TransferFailedException(msg, e); } finally @@ -241,5 +420,4 @@ public class ScpDeployer extends GenericSshDeployer } } } - } diff --git a/artifact/src/main/org/apache/maven/deploy/util/Packager.java b/artifact/src/main/org/apache/maven/deploy/util/Packager.java new file mode 100644 index 00000000..c7934203 --- /dev/null +++ b/artifact/src/main/org/apache/maven/deploy/util/Packager.java @@ -0,0 +1,152 @@ +package org.apache.maven.deploy.util; + + +/* ==================================================================== + * 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 Maven" 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 Maven", 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 + * . + * + * ==================================================================== + */ +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +import java.util.Iterator; +import java.util.List; +import java.util.zip.Deflater; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/** + * + * @author Michal Maczka + * @version $Id: Packager.java,v 1.1 2003/08/02 22:51:45 michal Exp $ + */ +public class Packager +{ + /** + * + * @param inputFiles + * @param outputFiles + * @param archive + * @throws IOException + */ + public static void createZip( List srcFiles, List destFiles, String archive ) + throws IOException + { + createZip( srcFiles, destFiles, new File( archive ) ); + } + + /** + * + * @param inputFiles + * @param outputFiles + * @param archive + * @throws IOException + */ + public static void createZip( List srcFiles, List destFiles, File archive ) + throws IOException + { + byte[] buf = new byte[1024]; + + ZipOutputStream out = null; + + try + { + out = new ZipOutputStream( new FileOutputStream( archive ) ); + out.setLevel( Deflater.BEST_COMPRESSION ); + out.setMethod( ZipOutputStream.DEFLATED ); + + Iterator iter1 = srcFiles.iterator( ); + Iterator iter2 = destFiles.iterator( ); + + while ( iter1.hasNext( ) ) + { + String inputFilename = ( String ) iter1.next( ); + String outputFilename = ( String ) iter2.next( ); + + FileInputStream in = new FileInputStream( inputFilename ); + + // Add ZIP entry to output stream. + out.putNextEntry( new ZipEntry( outputFilename ) ); + + // Transfer bytes from the file to the ZIP file + int len; + + while ( ( len = in.read( buf ) ) > 0 ) + { + out.write( buf, 0, len ); + } + + // Complete the entry + out.closeEntry( ); + in.close( ); + } + } + + // Complete the ZIP file + finally + { + if ( out != null ) + { + try + { + out.close( ); + } + catch ( Exception e ) + { + } + } + } + } +}