Coder Social home page Coder Social logo

gradle-ssh-plugin's Introduction

Gradle SSH Plugin build

Gradle SSH Plugin provides SSH facilities such as command execution or file transfer on Gradle.

https://gradle-ssh-plugin.github.io

Contributions

This is an open source software licensed under the Apache License Version 2.0. Feel free to open issues or pull requests.

Development

Gradle SSH Plugin internally uses Groovy SSH library. It depends on JSch.

The document is maintained on the repository of Groovy SSH.

Acceptance Test

TODO: fix it

Release

Create a new release in GitHub Releases. GitHub Actions will publish an artifact to Gradle Plugin Portal.

gradle-ssh-plugin's People

Contributors

elijahfhopp avatar ganta avatar int128 avatar johnjaylward avatar jwalkiew avatar matthiasbalke avatar mlipper avatar nobusue avatar renovate[bot] avatar rm-- avatar rundis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gradle-ssh-plugin's Issues

Could not publish to the Maven Central

Mmm...
using same script as 0.1.3 but something wrong...

$ gradle clean uploadArchives
Enter password for PGP key XXXXXXXX: 
Enter password for [email protected]: 
:clean
:compileJava UP-TO-DATE
:compileGroovy
:processResources
:classes
:jar
:groovydoc
:javadocJar
:sourcesJar
:signArchives
:uploadArchives
Uploading: org/hidetake/gradle-ssh-plugin/0.1.4/gradle-ssh-plugin-0.1.4.jar to repository remote at https://oss.sonatype.org/service/local/staging/deploy/maven2/
Transferring 103K from remote
:uploadArchives FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':uploadArchives'.
> Could not publish configuration 'archives'
   > Error deploying artifact 'org.hidetake:gradle-ssh-plugin:jar': Error deploying artifact: Failed to transfer file: https://oss.sonatype.org/service/local/staging/deploy/maven2/org/hidetake/gradle-ssh-plugin/0.1.4/gradle-ssh-plugin-0.1.4.jar. Return code is: 401

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

remote specific identity key seems global

Session#getIdentityRepository() returns result of JSch#getIdentityRepository(), that is a global repository, by default. Once an identity is registered, that seems to be set globally.

Copying of directory fails

I want to copy all files in directory build/libs to a remote server. The documentation lead me to believe that it would be possible specify the following:

task deployLibs(type: SshTask) {
session(remotes.deployserver) {
put("/build/libs/", "/srv/testlibs")
}
}

However, this gives me an error message: "java.io.FileNotFoundException: C:\util\myproject\build\libs at com.jcraft.jsch.ChannelSftp.put(ChannelSftp.java:474)"

If I configure a specific file, it works:
task deployLibs(type: SshTask) {
session(remotes.deployserver) {
put("/build/libs/myproject.jar", "/srv/testlibs")
}
}

For us it's vital to be able to copy a whole directory, but it doesn't seem possible.

Bug associated with usage of ssh agent

There is a bug. When I try this:

remotes {
    example1 {
        host = 'example1.com'
        user = 'username1'
        agent = true
    }
    example2 {
        host = 'example2.com'
        user = 'username2'
        agent = true
    }
}

//...

task sshtest() << {
    sshexec {               
        session([remotes.example1, remotes.example2]) {
            execute('ls -la')
        }
    }
}

or

remotes {
    example1 {
        role('web')
        host = 'example1.com'
        user = 'username1'
        agent = true
    }
    example2 {
        role('web')
        host = 'example2.com'
        user = 'username2'
        agent = true
    }
}

//...

task sshtest() << {
    sshexec {               
        session(remotes.role('web')) {
            execute('ls -la')
        }
    }
}

my key is removed from repository of Putty Agent (I try this on windows).

But when I try this:

remotes {
    example1 {
        host = 'example1.com'
        user = 'username1'
        agent = true
    }
    example2 {
        host = 'example2.com'
        user = 'username2'
        agent = true
    }
}

//...

task sshtest() << {
    for(String host : [remotes.example1, remotes.example2])
        sshexec {               
            session(host) {
                execute('ls -la')
            }
        }
}

everything is all right.

For some reason private key is removed from storage when I declare array of hosts in session.

could not execute sudo

session(remote) {
  execute 'sudo hogehoge'
}

causes below:

sorry, you must have a tty to run sudo

execute() requires at least 500ms

Due to Thread.sleep(500) in execute(), it requires at least 500ms even if remote command is finished immediately. Same in executeSudo().
Maybe this causes slow tests.

pty: true does not work for ssh execute

I have a sudo configuration on a server that is set up to accept password-less sudo for certain tasks, and then I have a gradle-ssh configuration set up as follows:

task stopService(type: SshTask) {
session(remotes.deployserver) {
execute("sudo mycommand stop", pty: true)
}
}

When I run this, I get the error message "sorry, you must have a tty to run sudo"

If I change the gradle configuration to this:

task stopService(type: SshTask) {
session(remotes.deployserver) {
executeBackground("sudo mycommand stop", pty: true)
}
}

i.e. I have only changed execute -> executeBackground, it works without an error.

Unless I am missing something, this seems like a bug to me.

dymamic remotes

is there a way to create a remote on the fly? for instance I want to load a remote info from an environment and loop across them to execute commands.

Change coding style

Many open source projects seems to adopt 4-width soft tab.
This project is written with hard tab, but now I think soft tab is better.

JSchException: verify: false

Sometimes happens:

Caused by: com.jcraft.jsch.JSchException: verify: false
    at com.jcraft.jsch.Session.connect(Session.java:309)
    at com.jcraft.jsch.Session.connect(Session.java:162)
    at com.jcraft.jsch.Session$connect.call(Unknown Source)
    at org.hidetake.gradle.ssh.internal.DefaultSshService$_wetRun_closure2.doCall(DefaultSshService.groovy:51)
    at org.hidetake.gradle.ssh.internal.DefaultSshService.wetRun(DefaultSshService.groovy:43)
    at org.hidetake.gradle.ssh.internal.DefaultSshService$wetRun.callCurrent(Unknown Source)
    at org.hidetake.gradle.ssh.internal.DefaultSshService.execute(DefaultSshService.groovy:28)
    at org.hidetake.gradle.ssh.api.SshService$execute.call(Unknown Source)
    at org.hidetake.gradle.ssh.SshPluginConvention.sshexec(SshPluginConvention.groovy:53)
    at org.hidetake.gradle.ssh.SshPluginConvention.invokeMethod(SshPluginConvention.groovy)

How to disable stout output of commands ?

Hi,

I'm writing a build script where I would like not to display raw ssh command output, but only parsed / formatted values of the output.

How can I disable the default stdout output ?
I saw in the code that it is possible to call setOutputStream on a channel but is there a way to control it through the plugin ?

Best Regards,
Gilles

Add support for gateways

In many deployment scenarios you will only get access to production servers though a gateway server. Providing functionality to support this would certainly help increase the popularity and usefullness of this plugin.

Create sessions with a map instead of a Remote

It would be really nice to easily parameterize a remote without having to define it first.

I.e I don't want to add the following

remotes {
    myremote {
        host = 'localhost'
        user = 'someone'
        password = 'something'     
    }
}

Instead, I'd like to do this:

sshexec {
    session([host: 'localhost', user: 'someone', password: 'something']) {
       execute "ls -la"
    }
}

This enables me to parameterize the remote parameters from the command line for any server. I've hacked around it now by instantiating a new Remote() object, but it should be easier.

LoggingOutputStreamSpec test failure on windows

Unit test org.hidetake.gradle.ssh.internal.LoggingOutputStreamSpec#multi-platforms has been failed on Windows, but passed on OS X and Linux.

Condition not satisfied:

stream.lines == ['line1', '', 'line2', 'line3', '', 'line4', 'line5']
|      |     |
|      |     false
|      [line1, , line2?line3, ?line4?line5]
org.hidetake.gradle.ssh.internal.LoggingOutputStream@84731c

    at org.hidetake.gradle.ssh.internal.LoggingOutputStreamSpec.multi-platforms(LoggingOutputStreamSpec.groovy:125)

Strange messages in output

I got follow message multiple times during ssh calls:

tput: No value for $TERM and no -T specified
...
tput: No value for $TERM and no -T specified

Is where any setting to hide this annoying message?

remotes container in multi-project

Remote hosts defined in the parent project did not appear in the child project.

parent project:

apply plugin: 'ssh'
remotes {
  server {...}
}

child project:

apply plugin: 'ssh'
task something(type: SshTask) {
  // below causes error
  session(remotes.server) {}
}

executeBackground() did not check exit status

If remote command returns error status (1 or greater) but the task has been finished without any exception.

task executeBadCommand(type: SshTask) {
    session(remotes.localhost) {
        // should be failure
        executeBackground 'touch /root/test'
    }
}

Why would execute fail when sftp works?

I have a question. Under what circumstances would SFTP transfers work, but any attempt to execute commands fail?

My set-up is as follows. I am trying to SFTP a file and uncompress it on the server. For testing, I'm just using an sshd configured on my local machine:

remotes {
  staging {
    host = '127.0.0.1'
    port = '2223'
    user = 'dev'
    password = 'dev'
  }
}

My task is as follows:

task deploy(type: SshTask) << {
  sshexec {
    session(remotes.staging) {
      put('/localpath/app.tgz', 'app.tgz')
      execute('tar -zxvf /remotepath/app.tgz')
    }
  }
}

The put connects and transfers the file without any problem. However, the execute always fails with the error:

Channel #1 finished with exit status -1

This happens no matter what command I try to run, or what options I supply. If there's a problem with my configuration, I don't understand why the SFTP works? And if there's a problem with my command, I don't understand why I'm able to manually connect via a client and run it without problem?

Some tests fail on Windows

Some tests fail.

public key authentication

JSch causes error while reading the private key.

  • AuthenticationSpec. public key authentication
  • AuthenticationSpec. public key authentication but denied
  • AuthenticationSpec. public key authentication with global identity
Caused by: org.gradle.internal.UncheckedException: com.jcraft.jsch.JSchException: java.lang.ArrayIndexOutOfBoundsException: 382
    at org.gradle.internal.UncheckedException.throwAsUncheckedException(UncheckedException.java:39)
    at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:66)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:219)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:212)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:201)
    at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:533)
    at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:516)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
    ... 11 more
Caused by: com.jcraft.jsch.JSchException: java.lang.ArrayIndexOutOfBoundsException: 382
    at com.jcraft.jsch.IdentityFile.<init>(IdentityFile.java:428)
    at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:135)
    at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:130)
    at com.jcraft.jsch.JSch.addIdentity(JSch.java:224)
    at com.jcraft.jsch.JSch.addIdentity(JSch.java:218)
    at org.hidetake.gradle.ssh.internal.DefaultSshService.execute_closure2_closure6(DefaultSshService.groovy:41)
    at org.hidetake.gradle.ssh.internal.DefaultSshService.execute_closure2_closure6(DefaultSshService.groovy)
    at org.hidetake.gradle.ssh.internal.DefaultSshService.retry(DefaultSshService.groovy:89)
    at org.hidetake.gradle.ssh.internal.DefaultSshService.execute_closure2(DefaultSshService.groovy:33)
    at groovy.lang.Closure.call(Closure.java:412)
    at groovy.lang.Closure.call(Closure.java:425)
    at org.hidetake.gradle.ssh.internal.DefaultSshService.execute(DefaultSshService.groovy:32)
    at org.hidetake.gradle.ssh.SshTask.perform(SshTask.groovy:35)
    at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)
    ... 18 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: 382
    at com.jcraft.jsch.Util.fromBase64(Util.java:48)
    at com.jcraft.jsch.IdentityFile.<init>(IdentityFile.java:414)
    ... 31 more

file transfer

SFTP server does not work correctly on Windows, due to Apache sshd implementation. It seems there is no workaround.

  • FileTransferSpec. get a file
  • FileTransferSpec. put a file

Pipe closed on put/get operations

Hello.

I get a stacktrace when doing put/get operations:

Caused by: org.gradle.internal.UncheckedException: com.jcraft.jsch.JSchException: java.io.IOException: Pipe closed
        at org.gradle.internal.UncheckedException.throwAsUncheckedException(UncheckedException.java:39)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:66)
        at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:219)
        at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:212)
        at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:201)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:533)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:516)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
        ... 52 more
Caused by: com.jcraft.jsch.JSchException: java.io.IOException: Pipe closed
        at com.jcraft.jsch.ChannelSftp.start(ChannelSftp.java:315)
        at com.jcraft.jsch.Channel.connect(Channel.java:152)
        at com.jcraft.jsch.Channel.connect(Channel.java:145)
        at com.jcraft.jsch.Channel$connect.call(Unknown Source)
        at org.hidetake.gradle.ssh.internal.DefaultOperationHandler.get(DefaultOperationHandler.groovy:144)
        at org.hidetake.gradle.ssh.api.OperationHandler$get.callCurrent(Unknown Source)
        at org.hidetake.gradle.ssh.internal.AbstractOperationHandler.get(AbstractOperationHandler.groovy:39)
        at build_7g48o7v4l0o1ohft2g1asbu1d1$_run_closure10_closure16.doCall(C:\workspace\katia\katia-device-v1\build.gradle:107)
        at org.hidetake.gradle.ssh.internal.DefaultSshService$_execute_closure4.doCall(DefaultSshService.groovy:76)
        at org.hidetake.gradle.ssh.internal.DefaultSshService.execute(DefaultSshService.groovy:74)
        at org.hidetake.gradle.ssh.api.SshService$execute.call(Unknown Source)
        at org.hidetake.gradle.ssh.SshTask.perform(SshTask.groovy:35)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)
        ... 59 more
Caused by: java.io.IOException: Pipe closed
        at com.jcraft.jsch.ChannelSftp.fill(ChannelSftp.java:2869)
        at com.jcraft.jsch.ChannelSftp.header(ChannelSftp.java:2895)
        at com.jcraft.jsch.ChannelSftp.start(ChannelSftp.java:262)
        ... 71 more
$ gradlew.bat --version

------------------------------------------------------------
Gradle 1.10
------------------------------------------------------------

Build time:   2013-12-17 09:28:15 UTC
Build number: none
Revision:     36ced393628875ff15575fa03d16c1349ffe8bb6

Groovy:       1.8.6
Ant:          Apache Ant(TM) version 1.9.2 compiled on July 8 2013
Ivy:          2.2.0
JVM:          1.7.0_51 (Oracle Corporation 24.51-b03)
OS:           Windows 7 6.1 amd64

ssh version : 0.2.3

task integrationTests(type: SshTask) {
    doFirst{
        //put for testing
    }
    session(remotes.integration) {
        execute('echo hello')
        get('/tmp/dhcp.leases','dhcp.txt')
    }

    doLast{
     //put for testing
    }
}

Any idea if I'm doing something wrong ?

NPE if no identity is given

build.gradle

    myhost {
        role 'webServers'
        host = '127.0.0.1'
        user = System.properties['user.name']
        password = 'xxx'
    }

result:

Caused by: java.lang.NullPointerException
    at org.hidetake.gradle.ssh.internal.DefaultSshService$_wetRun_closure2.doCall(DefaultSshService.groovy:45)
    at org.hidetake.gradle.ssh.internal.DefaultSshService.wetRun(DefaultSshService.groovy:42)
    at org.hidetake.gradle.ssh.internal.DefaultSshService$wetRun.callCurrent(Unknown Source)
    at org.hidetake.gradle.ssh.internal.DefaultSshService.execute(DefaultSshService.groovy:27)
    at org.hidetake.gradle.ssh.api.SshService$execute.call(Unknown Source)
    at org.hidetake.gradle.ssh.SshTask.perform(SshTask.groovy:29)

Possible to sudo su - and run a command?

I would like to know if it is possible to ssh into a machine with one user account and then $sudo su - (root) , provide a password and then execute a command?

I have tried a few things but nothing works. If there is a way to do this, please let me know.

Ignores dead remote hosts

For example:

remotes {
  web01 { /* ... */ }
  web02 { /* ... */ } 
  web03  { /* ... */ }
}

session(remotes.role('webServers')) {
  execute(/* ... */)
}

If web02 is unreachable, ignore web02 connection error.

cd command is not working

execute('cd somedir', pty: true)
execute('ls -l', pty: true)

the first command is not executed. 2nd command is showing all the files in the parent director. My indent is to list files from 'somedir'.

execute() returns wrong value if output contains no newline

task obtainValue(type: SshTask) {
    outputLogLevel = LogLevel.DEBUG
    session(remotes.localhost) {
        def result = execute('echo -n hogehoge')
        println "Result is ${result}."
    }
}

expected:

Result is hogehoge.

actual:

Result is hogehoge
hogehoge.

retry connection

Currently an exception will be thrown and cause Gradle termination if error occurs. Retry connection if error occurs.

Long term refactoring

Refactoring toward v0.3.0.

  • Reconstruct domain classes (session, operation and infrastructure)
  • Introduce dependency injection
  • Improve overload hell of Operation method
  • Extensible architecture

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.