Git Product home page Git Product logo

grunt-ssh's Introduction

New owner! Starting 12-23-2015, I (@israelroldan) am standing on the shoulders of two giants (@chuckmo and @andrewrjones) as maintainer of this project. Contributions are welcome as always. (This message will be removed on next release as well).

grunt-ssh

Join the chat at https://gitter.im/israelroldan/grunt-ssh

Build Status NPM version Dependencies

SSH and SFTP tasks for Grunt, using a pure JS implementation of ssh2.

Overview

This plugin requires Grunt ~0.4.0

If you haven't used Grunt before, be sure to check out the Getting Started guide, as it explains how to create a Gruntfile as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:

npm install grunt-ssh --save-dev

Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:

grunt.loadNpmTasks('grunt-ssh');

This library provides two Grunt tasks for ssh:

  • sftp
  • sshexec

This plugin was designed to work with Grunt 0.4.x. If you're still using grunt v0.3.x it's strongly recommended that you upgrade, but in case you can't please use v0.1.0.

Synopsis

// don't keep passwords in source control
secret: grunt.file.readJSON('secret.json'),
sftp: {
  test: {
    files: {
      "./": "*json"
    },
    options: {
      path: '/tmp/',
      host: '<%= secret.host %>',
      username: '<%= secret.username %>',
      password: '<%= secret.password %>',
      showProgress: true
    }
  }
},
sshexec: {
  test: {
    command: 'uptime',
    options: {
      host: '<%= secret.host %>',
      username: '<%= secret.username %>',
      password: '<%= secret.password %>'
    }
  }
}

An example secret.json might look like:

{
    "host" : "myhost",
    "username" : "username",
    "password" : "**************"
}

Or, specifying SSH configurations for re-use, and referencing from tasks:

// don't keep passwords in source control
sshconfig: {
  "myhost": grunt.file.readJSON('myhost.json')
},
sshexec: {
  test: {
    command: 'uptime',
    options: {
      config: 'myhost'
    }
  },
  ls: {
    command: 'ls -la',
    options: {
      config: 'myhost'
    }
  }
}

You can also overwrite the username, password, passphrase or config at runtime as a command line option:

$ grunt sshexec:someTask --config myhost --username foo

Description

sftp

Copies one or more files to a remote server over ssh.

Inside your grunt.js file add a section named sftp.

Parameters

files object

The files to copy. Should contain key:value pairs.

If you would like to upload multiple files, use an array. For example:

files: {
  "./": ["<%= dirs.css %>style.css","<%= dirs.css %>login.css","<%= dirs.css %>print.css"]
},

The following will not work:

files: {
  "./": "<%= dirs.css %>style.css",
  "./": "<%= dirs.css %>login.css",
  "./": "<%= dirs.css %>print.css"
},
options object
path string

The path on the remote server. Defaults to /.

minimatch object

Options for minimatch.

username string

The username to authenticate as on remote system.

host string

The remote host to copy to, set up in your ~/.ssh/config.

port number

The remote port, optional, defaults to 22.

srcBasePath string

Optionally strip off an initial part of the file when performing the SFTP operation. This is a string operation, so trailing slashes are important.

For example:

    /* [...] */
    files: {
      "./": "dist/**"
    },
    options: {
      path: '/tmp/',
      /* [...] */
      srcBasePath: "dist/"

Would SFTP the files in dist directly into tmp (eg. dist/index.html ==> /tmp/index.html)

createDirectories boolean

Optionally check whether the directories files will be sftp'd to exist first. This can take a bit of extra time as directories need to be checked, so this option is disabled by default.

See also the directoryPermissions option.

directoryPermissions number

The permissions to apply to directories created with createDirectories. The default is 0755. JSHint will probably yell at you unless you set this using parseInt:

directoryPermissions: parseInt(755, 8)
showProgress boolean

Show a progress bar during the file transfer. The default is false.

chunkSize integer

Size of each read in bytes (default: 32768)

callback function

Callback function called after command execution. Default: empty function

Connection options

There are three mutually exclusive sets of connection options. They are privateKey (with optional passphrase), password, and agent. If any of these options are private, they will be tried exclusively, and other connection options will be ignored. Each is described a bit more below.

privateKey string

A string containing the contents of the private key to use to authenticate with the remote system, you can load this from a file using grunt.file.read. Be careful you don't put this into source control unless you mean it!

If a privateKey and passphrase are required, they

options: {
  privateKey: grunt.file.read("id_rsa"),
  passphrase: <%= secret.passphrase %>
}
passphrase string

The passphrase to use with the privateKey. As per the privateKey, do not expose this in your Gruntfile or anywhere that'll end up public unless you mean it, load it from an external file.

password string

The password to authenticate on remote system.

agent string

Path to ssh-agent's UNIX socket for ssh-agent-based user authentication.

options: {
         host: '<%= pkg.host %>',
         port: '<%= pkg.port %>',
         username: '<%= pkg.username %>',
         agent: process.env.SSH_AUTH_SOCK
}

If you use jshint, remember to add process: true in globals

readyTimeout integer

How often (in milliseconds) to wait for the SSH handshake to complete.

sshexec

Runs a command over ssh.

NOTE: To see the output of your sshexec command locally, use the --verbose flag.

Inside your grunt.js file add a section named sshexec.

Parameters

command string or array

The command or commands to run, if an array is supplied, all the commands are executed on the same connection.

options object
username string

The username to authenticate as on remote system.

host string

The remote host to copy to, set up in your ~/.ssh/config.

port number

The remote port, optional, defaults to 22.

pty boolean/object

Set to true to allocate a pseudo-tty with defaults, or an object containing specific pseudo-tty settings (see 'Pseudo-TTY settings'). Setting up a pseudo-tty can be useful when working with remote processes that expect input from an actual terminal (e.g. sudo's password prompt).

ignoreErrors boolean

Determins if the task should stop or continue if any of the commands returns a code other than 0. Disabled by default.

suppressRemoteErrors boolean

If true only display remote error messages if Grunt is run with the --verbose flag.

Connection options

There are three mutually exclusive sets of connection options. They are privateKey (with optional passphrase), password, and agent. If any of these options are private, they will be tried exclusively, and other connection options will be ignored. Each is described a bit more below.

privateKey string

A string containing the contents of the private key to use to authenticate with the remote system, you can load this from a file using grunt.file.read. Be careful you don't put this into source control unless you mean it!

options: {
  privateKey: grunt.file.read("id_rsa"),
  passphrase: <%= secret.passphrase %>
}
passphrase string

The passphrase to use with the privateKey. As per the privateKey, do not expose this in your Gruntfile or anywhere that'll end up public unless you mean it, load it from an external file.

password string

The password to authenticate on remote system.

agent string

Path to ssh-agent's UNIX socket for ssh-agent-based user authentication.

options: {
         host: '<%= pkg.host %>',
         port: '<%= pkg.port %>',
         username: '<%= pkg.username %>',
         agent: process.env.SSH_AUTH_SOCK
}

If you use jshint, remember to add process: true in globals

readyTimeout integer

How often (in milliseconds) to wait for the SSH handshake to complete.

Note

sshexec runs each command individually, and it does not keep state of the previous command, so when you need to perform 2 commands or more , you could do e.g.:

sshexec: {
  test: {
    command: ['sh -c "cd /; ls; pwd"'],
    options: {
      host: '<%= secret.host %>',
      username: '<%= secret.username %>',
      password: '<%= secret.password %>'
    }
  }
}

Links

Release History

  • 2015/02/07 - v0.12.1 - #92 Fixed ssh2 dependency to version 0.3.x (bostrom (Fredrik Boström))
  • 2014/09/11 - v0.12.0 - #70: Ensure empty directories are created (Robert Price); #71: Enables forwarding of the authentication agent connection (Yannis Sgarra); #73: Downloading files (sheo13666); #75: Doc fix (Alexander Afanasiev).
  • 2014/06/04 - v0.11.2 - #63: sftp improvements (Brian White; #64: Changed error handling for SFTP junglebarry
  • 2014/03/21 - v0.11.1 - #59: Don't add '/' to empty path (David J. Bradshaw).
  • 2014/03/15 - v0.11.0 - #50: Enable setting of chunkSize option (Michael Lam); #51: Fix bad output on close (Eric Kever); #56: Add readyTimeout option for ssh2 connections (calebTomlinson).
  • 2014/01/16 - v0.10.0 - #47: Add an optional progress bar for sftp uploads (Jason Williams).
  • 2013/12/06 - v0.9.1 - #44: Improve doc for SSH connection options (Mark Stosberg); #45: Fix incorrect Connection parameter in execCommand (jabes).
  • 2013/12/06 - v0.9.0 - #28: Pseudo-TTY support; #40: Add trailing slash to path if needed; #31: Print debug messages from ssh2 when --debug option is passed; Use latest version of ssh2 (0.2.14).
  • 2013/11/17 - v0.8.0 - #33: File counter for sftp and suppressRemoteErrors option for sshexec (David J. Bradshaw); #34: Use stat() instead of opendir() for checking existence of a dir (Harri Hälikkä); #38: Doc updates (Alexandre Richonnier).
  • 2013/10/17 - v0.7.0 - #32: Added command line options for username, password and passphrase (David J. Bradshaw); Doc updates.
  • 2013/09/25 - v0.6.2 - Allow sftp task to use the shared sshconfig; Allow overriding sshconfig properties in the task config (Andy Royle). Document using the private key with sshexec.
  • 2013/07/25 - v0.6.2 - Fix error when no passphrase is provided (James Wyse).
  • 2013/07/21 - v0.6.1 - trim options that may be read from files; Allow sshexec to use ssh-agent-based user authentication (Andy Shinn).
  • 2013/06/26 - v0.6.0 - Ability to supply a path to ssh-agent's UNIX socket for ssh-agent-based user authentication (Justin Kulesza).
  • 2013/06/25 - v0.5.1 - Fix srcBasePath (owenmead).
  • 2013/06/02 - v0.5.0 - Add support for multiple comands (Andrew Stewart).
  • 2013/05/11 - v0.4.0 - Support defining and referencing ssh configurations. (Anders Johnson).
  • 2013/05/07 - v0.3.3 - Fix encoding issues. (John Wright).
  • 2013/05/07 - v0.3.2 - Fix race condition when uploading larger files. (John Wright).
  • 2013/03/25 - v0.3.1 - Fix race condition when uploading multiple files. (John Wright).
  • 2013/02/27 - v0.3.0 - Support private key based authentication; Allow sftp to make directories if they do not exist. (marcins).
  • 2013/02/26 - v0.2.1 - Add srcBasePath option to sftp (marcins).
  • 2013/02/20 - v0.2.0 - Update for grunt 0.4.x.
  • 2013/02/13 - v0.1.0 - Initial release with sshexec and sftp tasks.

License

Copyright (c) 2013 Andrew Jones. Licensed under the MIT license.

grunt-ssh's People

Contributors

alecxe avatar alexander-akait avatar andrewrjones avatar andyroyle avatar andyshinn avatar bostrom avatar chuckmo avatar davidjbradshaw avatar dominykas avatar estoner avatar francoaguilera avatar gitter-badger avatar harriha avatar heralight avatar israelroldan avatar jabes avatar jameswyse avatar jaswilli avatar johngeorgewright avatar markstos avatar mlamz avatar mscdex avatar owenmead avatar pinktrink avatar robertprice avatar rysi3k avatar steveoh avatar xescugc 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

grunt-ssh's Issues

Can't seem to change directory

My attempts to use cd to change to the directory I wish to run further commands in does not appear to be working. The verbose log does not display much either.

image

wish: stronger validation of connection options.

In the the source code, there's code like this:

if (options.privateKey) {
connectionOptions.privateKey = options.privateKey;
connectionOptions.passphrase = options.passphrase;
}
else if (options.password) {
connectionOptions.password = options.password;
} else {
connectionOptions.agent = options.agent;
}

This shows that the privateKey options is provided, the 'password' and 'agent' options will be ignored, and if the password option, the agent option will be ignored.

For someone having difficulty connecting, the relationship of these options can be confusing.

How they are related could be clarified in two ways:

  1. The validation could be stricter, so that an exception is thrown if the user attempts to mix any of these options-- it doesn't make sense and could indicate that the user doesn't realize what's going on. That in turn could be a source of a silent bug, as some options are being ignored that are perhaps expected be used.

In particular:

  • If privateKey is provided, it is an error to provide either password or agent.
  • If agent is provided, it's an error to provide privateKey or password.
  • If password is provided, it's an error to provide privateKey or agent.

Likewise, the docs could be updated to better illustrate that these three connection paths are mutually exclusive.

I'll take a pass at improving the docs now.

ppk files

This is rather a question than an issue; it possible to use PuTTY User-Key File (ssh-rsa)? If so, then please any code samples? Thanks 👍

Problem with creating folders when using sftp

I'm having an error with creating the folders when copying files. It checks for a folders existance (in this case folder2). But instead of creating it, the script tries to create a folder two levels above (the basic path I specified in the options) and of course fails because it already exists:

[...]
Checking existence of path /Volumes/Customer-Projects/My-Project/stuff/normal/folder1
Creating /Volumes/Customer-Projects/My-Project/stuff/normal/folder2
Checking existence of path /Volumes/Customer-Projects/My-Project/stuff/normal/folder2
Creating /Volumes/Customer-Projects/My-Project/stuff
>> Path creation failed: Failed to create /Volumes/Customer-Projects/My-Project/stuff

This is my config - I'm removing all files in the folder first with sshexec and then use sftp:

sshexec: {
    dist: {
        command: 'rm -rf /Volumes/Customer-Projects/My-Project/stuff/normal/*',
        options: {
            host: ssh.host,
            username: ssh.username,
            privateKey: grunt.file.read(ssh.privateKey),
            passphrase: ssh.passphrase,
        }
    }
},
sftp: {
    dist: {
        files: {
            './': 'dist/**'
        },
        options: {
            path: '/Volumes/Customer-Projects/My-Project/stuff/normal',
            host: ssh.host,
            username: ssh.username,
            privateKey: grunt.file.read(ssh.privateKey),
            passphrase: ssh.passphrase,
            srcBasePath: 'dist',
            createDirectories: true
        }
    }
}

It always chokes on the same folder, no matter how often I re-run the script.

Preserve file permissions similar to sftp -p

It seems grunt-ssh does not preserve file permissions when deploying via sftp. This is slightly problematic for deploys that need certain files to be executable. The traditional sftp cmdline tool has a -p option for this purpose. Is it possible to add such an option to grunt-ssh?

Doesn't copy all files

Here's my config file:

'use strict';
module.exports = {
publish: {
    files: {
        "./": "app/**"
    },
    options: {
        host: '<%= secret.host %>',
        username: '<%= secret.username %>',
        password: '<%= secret.password %>',
        path: '<%= secret.www_dir %>',
        srcBasePath: "app/",
        showProgress: true
    }
}
};

Not all files are being copied over, and absolutely no sub directories are either. Not sure what the problem is. Tried lots of variations but the documentation doesn't account for this.

Hopefully someone can set me straight, or perhaps this is an issue that needs fixing?

Don't have received response when do sshexec

I'm trying to exec my deploy script like the following:

sshexec: {
  deploy: {
    command: 'sh deploy',
    options: {
      host: 'example.com'
    }
  }
}

But I don't see any resver response only this:

Running "sshexec:deploy" (sshexec) task
|

My deploy script has the single command:

echo "Hello from deploy"

Request: Directory exclusion

From what I can tell, there's currently no way to exclude a single directory.

I would very much like to be able to exclude my node_modules folder.

Using file as input

Could we get the ability to use a shell script as input? It would be equivalent to

$ ssh [email protected] < run-this-script.sh

I wonder if that would be easy to implement or not. It would enable a local shell script to be run by anyone with grunt regardless of their OS.

createDirectories should honor directories excluded via files.

CreateDirectories does not evaluate against the files option so files:{'./':['*', '**/*', '!node_modules', '!.git', '!.bowerrc','!.editorconfig', '!.jshintrc', '!Gruntfile.js', '!README.md', '!CHANGELOG.md', '!CONTRIBUTING.md', '!bower.json', '!package.json']} ends up creating an empty node_modules/ and ..git directory trees, not to mention this takes a long time to evaluate as it's checking paths it doesn't need to 1 at a time.

Run command/SFTP transfer against all defined hosts?

Hi,
Sorry if I miss the document somewhere. Can I define multiple hosts then execute SSH command/SFTP transfer against all hosts?
I have a multi-hosts defined like below and a sshexec command, but I don't know how to execute that command against all defined hosts.

sshconfig: {
    srv01: {
        host: "127.0.0.1",
        port: 2222,
        username: "vagrant",
        privateKey: grunt.file.read("insecure_private_key"),
    },
    srv02: {
        host: "127.0.0.1",
        port: 2200,
        username: "vagrant",
        privateKey: grunt.file.read("insecure_private_key"),
    }
},
sshexec: {
    uptime: {
        command: "uptime",
    }
}

Thanks,
Phu

Not finding password authentication method

Windows 7, node version 0.10.13

I'm unable to connect using a password. My config is as follows:

        sftp:
            dist:
                files:
                    "./": "bower/docs/**/*.*"
                options:
                    path:"/var/www/html/devDocs/myLib/#{VERSION}/"
                    host: 'myHost'
                    username: 'myUsername'
                    password: 'myPassword'

And the error I receive is:

>> Connection :: error :: Error: Authentication failure. Available authentication methods: publickey,gssapi-keyex,gssapi-with-mic,password

Since I am providing a password I'd expect it to go through - am I missing a config option?

What would the structure of a secret.json file look like?

I am looking to configure a secret.json to contain my server config credentials (i.e. username, password, host, etc.) so I don't have to put it directly in my Gruntfile.js.

What would the contents of secret.json look like so I can read it in similar to what you have in the example here: http://d.pr/i/4O2d

Is it an object literal, for example?

[
{
"host": "example.com",
"username": "jonsmith",
"password": "badpassword"
}
]

Use ssh -A option

Hi !
When I connect my server, I use ssh -A option like this :
ssh -A [email protected]

This allows me to send my private key through ssh and I can pull from git repository, directly from server, with my private key.

How can I do this with grunt-ssh ?

Many thanks !

Blank Passphrase Fails

Though not recommended, some of us may choose to have a blank paraphrase when using SSH private/public key authentication. This scenario seems to fail with a warning:

Warning: Encrypted private key detected, but no passphrase given Use --force to continue.

Connection :: connect stall on grunt sshexec:task --verbose

Running "sshexec:test" (sshexec) task
Verifying property sshexec.test exists in config...OK
File: [no files]
Options: config="staging", host=false, username=false, password=false, agent="", port=22, ignoreErrors=false, minimatch={}, pty={}, suppressRemoteErrors=false
Raw Options: config="staging", host=false, username=false, password=false, agent="", port=22, ignoreErrors=false, minimatch={}, pty={}, suppressRemoteErrors=false
Verifying property sshconfig.staging exists in config...OK
Options: config="staging", host="xyz.com", username="root", password=false, agent="", port=22, ignoreErrors=false, minimatch={}, pty={}, suppressRemoteErrors=false, path="/srv", options={"privateKey":"XYZ"}
Connection :: connect

Enhancement: Add trailing slash in path if needed

Hello,

just had a problem with sftp and only found out with --verbose.

If the path has no trailing slash the files are not copied correct because the path for a file would be: '/var/www/foldernameindex.html'

You could add a slash if none is found at the end.

How to only upload the new files, not all?

All works like a charm, but I only want to copy the new files, how can achieve that?
And what about removing a file?

sftp: {
        uploads: {
            files: {
                "./": "public_html/assets/uploads/**/*"
            },
        options: {
            path: '/path/to/my/domain/root/'
            ,srcBasePath: '../'
            ,host: '<%= sshconf.host %>'
            ,port: '<%= sshconf.port %>'
            ,username: '<%= sshconf.username %>'
            ,password: '<%= sshconf.password %>'
            ,showProgress: false
            ,createDirectories: true
        }
    }
}

And add a watch event;

// on watch events configure sftp.test.files to only run on changed file
grunt.event.on('watch', function(action, filepath) {
    grunt.config('sftp.uploads.files', {"./": filepath});
});

forever and other packages not found

my command:

date && cd ~/local/lib/node_modules/forever/bin && ls -la && forever -v

the output

Sun Nov 17 14:45:48 UTC 2013
total 20
drwxr-xr-x 2 nobody root 4096 Nov 17 14:15 .
drwxr-xr-x 6 nobody root 4096 Nov 17 14:15 ..
-rwxr-xr-x 1 nobody root   60 May  9  2013 forever
-rwxr-xr-x 1 nobody root   72 May  9  2013 foreverd
-rwxr-xr-x 1 nobody root 2135 May  9  2013 monitor
>> bash: forever: command not found
  • date command is running ok;
  • the directory shows forever library exists fine;
  • the command "forever -v" returns "command not found"
  • same happens with node, npm, etc...

sshexec code 127

when I use sshexec task running command "pm2 restart all",it falis and return message "stream ::exit :: code :127",but the command is ok when I logon to the server. all the nodejs related PATH have been configured,Does anyone know what the possibility is?

nohup problem

Well I have this command:

nohup java -CONFIG=/config/path/ -jar myBuilded.jar &

But is not attaching the nohup part.

Any sugestions?

tks

Processes not found when using nvm

sshexec does not load bash profiles. So when using node through nvm (https://github.com/creationix/nvm), I get a process not found error. I have found a workaround, but it would be nice to see if someone has a more elegant solution.

Here is my current workaround:
~/.nvm/v0.10.12/bin/node ~/.nvm/v0.10.12/bin/forever start ~/application/deploy.js

tty

Im trying to sudo a command but I'm getting the 'sudo: sorry, you must have a tty to run sudo' error.

To fix this I can send the -t option with ssh. e.g. ssh -t [email protected] "command".

I notice that there is a 'pty' option in ssh2 (which this uses) and I see the pty option if I use the grunt -v option. But alas, it's not working.

I briefly looked at your code and it looks like it should send the option along the chain, but I'm still getting the error. Does it send this option?

sftp does not support files in parent folder

I have config like

sftp: {
   upload: {
    files: {
      "../staging/": "app-patch.zip"
    },
    options: {
                   ......
     }
  }
}

sftp throws error >> Unable to copy; no valid source files were found.. But file ../staging/app-patch.zip does exist.

File path not respected

Hi,

I am probably too stupid to figure it out, but I cannot point SFTP to right subdirectory to pick up files and it is "stuck" in root directory whatever I type in.

My example (I want to upload file .jshintrc from test subdirectory):

files: {
'./': 'test/.jshintrc'
}

I also tried using <%= dirs.subdir %> and './test': '.jshintrc' :/

What should I do to point to sub directory in a project?

Note#1: I'd use SSH, but it isn't compatible with server I want to upload to
Note#2: Having this issue on Windows7

Grunt 0.4 Release

I'm posting this issue to let you know that we will be publishing Grunt 0.4 on Monday, February 18th.

If your plugin is not already Grunt 0.4 compatible, would you please consider updating it? For an overview of what's changed, please see our migration guide.

If you'd like to develop against the final version of Grunt before Monday, please specify "grunt": "0.4.0rc8" as a devDependency in your project. After Monday's release, you'll be able to use "grunt": "~0.4.0" to actually publish your plugin. If you depend on any plugins from the grunt-contrib series, please see our list of release candidates for compatible versions. All of these will be updated to final status when Grunt 0.4 is published.

Also, in an effort to reduce duplication of effort and fragmentation in the developer community, could you review the grunt-contrib series of plugins to see if any of your functionality overlaps significantly with them? Grunt-contrib is community maintained with 40+ contributors—we'd love to discuss any additions you'd like to make.

Finally, we're working on a new task format that doesn't depend on Grunt: it's called node-task. Once this is complete, there will be one more conversion, and then we'll never ask you to upgrade your plugins to support our changes again. Until that happens, thanks for bearing with us!

If you have any questions about how to proceed, please respond here, or join us in #grunt on irc.freenode.net.

Thanks, we really appreciate your work!

Timed out while waiting for handshake

Hi, I would like to upload a file after grunt-less compile files.

But I retrieve this error:

Warning: Connection :: error :: Error: Timed out while waiting for handshake Use --force to continue.

This is my gruntfile part:

watch: {
            less: {
                files: [
                    "css/**/*.less"
                ],
                tasks: [
                    "less:development",
                    "csso:minify",
                    "sftp:deploy"
                ]
            }
        },
        sftp: {
            deploy: {
                files: {
                    "./": "*.css"
                },
                options: {
                    "path": "<%= sftpCredentials.path_to_upload %>",
                    "host": "<%= sftpCredentials.host %>",
                    "username": "<%= sftpCredentials.user %>",
                    "port": "21",
                    "password": "<%= sftpCredentials.password %>",
                    "srcBasePath": "/mybasepath/",
                    "createDirectories": false,
                    "readyTimeout": "100000"
                }
            }
        },

secret.json:

{
    "host": "88.333.444.555",
    "user": "defaultftp",
    "password": "mypwd",
    "path_to_upload": "/Users/alessandrominoccheri/Sites/myclient/css/backend/"
}

How can I fix this?

Add open SSH connection for "watch" functionality to immediately upload files

Currently a new SSH connection is made for each upload when grunt-contrib-watch is used to upload changed files via a sftp task.

Opening a new connection for each change can take a lengthy amount of time.

Add an option / easily configurable way to maintain a connection over multiple a grunt execution lifetime - which make run indefinitely (looping via watch to upload files). It should make an effort to keep the connection from timing out from inactivity and reconnect when connection is lost.

createDirectories doesn't seem to support tilda shortcut

My gruntfile contains:

staging: grunt.file.readJSON('staging.json'),
sftp:{
            staging: {
                files: {
                    "./": ["data.json", "*.html", "css/*", "js/*", "images/*"]
                },
                options: {
                    path: '<%= staging.path %>',
                    host: '<%= staging.host %>',
                    username: '<%= staging.username %>',
                    privateKey: grunt.file.read("id_rsa"),
                    showProgress: true,
                    createDirectories:true
                }
            }
        }

Where staging.json contains:

{
    "host": "**********.com",
    "username": "david",
    "password": "",
    "path": "~/public_html/test/"
}

With createDirectories enabled, and this particular path defined, the verbose output of my task reads (abridged):

Connection :: connect
Checking existence of path ~/public_html/test
Creating /~
>> Path creation failed: Failed to create /~
Connection :: end
SFTP :: SFTP session closed
SFTP :: close
Copied 
Connection :: close

Why is it trying to create "/~" ? I've worked around this by using an absolute path. It isn't the end of the world, but might be worth mentioning in the documentation.

Empty directories not copying using SFTP

I have a project in which I have some empty directories that I wish to SFTP up to a remote server. Those directories will be filled with live data at runtime.

Even though I am using the createDirectories: true flag, empty directories are not copied and are ignored.

Here is some of my config file, the empty directories sit in the root of dist/public_html/

        app: {
            files: {
                "./": [ "dist/lib/**", "dist/public_html/**", "dist/public_html/.htaccess"]
            },
            options: {
                path: '<%= secret.path %>',
                host: '<%= secret.host %>',
                username: '<%= secret.username %>',
                password: '<%= secret.password %>',
                port: '<%= secret.port %>',
                showProgress: true,
                srcBasePath: "dist/",
                createDirectories: true
            }

UPDATE: I have fixed this and issued a pull request to fix the bug.

How to load `secret.json` only for sshexec task?

I don't need a secret.json file in production, but when i run any grunt task, the file will be read and since it doesn't exist, it will error out:

Loading "Gruntfile.js" tasks...ERROR
>> Error: Unable to parse "secret.json" file (Unexpected end of input).
// Gruntfile.js
module.exports = function (grunt) {

  // Project configuration.
  grunt.initConfig({
...
    anothertask: {
...
    },
    secret: grunt.file.readJSON('secret.json'),
    sshexec: {
      deploy: {
        command: "..."

Alternatively, how do I get grunt-ssh to read from the .ssh/config file, so it will use a key/identity file instead of storing the username and password in secret.json file?

Failed SFTP write doesn't cause task failure (using ssh-agent)

Hi,

I'm trying to SFTP some files up to a server through an SSH tunnel. The tunnel connects correctly, but my user doesn't have permissions to write the file to the server. (Yes, I should use a privileged user, but that's not the issue here.)

I would expect the sftp task to fail, but instead it succeeds, after printing an error message. This is in --verbose mode:

Connection :: connect
copying foo.zip to /path/foo.zip
>> Error: Permission denied
Connection :: end
Connection :: close

Done, without errors.

I may have misunderstood what you can and cannot do through an ssh-agent connection, but is there any way to force the task to fail under these circumstances?

It's not a problem for manual runs, but I was hoping to use this in an automated deployment system, where discovering failure is imperative.

Here's my config (credentials withheld, obviously):

"sftp": {
  "staging": {
    "options": {
      "ignoreErrors": false, // this didn't seem to work
      "showProgress": true,
      "agent": process.env.SSH_AUTH_SOCK,
      "username": "<%= deployment.username %>",
      "host": "<%= deployment.host %>",
      "path": "<%= deployment.paths.staging %>"
    },
    "files": {
      "<%= pkg.name %>.zip": "<%= pkg.name %>.zip"
    }
  }
}

NVM

NVM.

Please close or delete this issue

How to configure grunt-ssh in sails 0.10 ?

In sails 0.10, there is a split between configuration of module and registering the tasks.

In the configuration part, I have the following

module.exports = function(grunt) {
  grunt.config.set('sshconfig', {
    "host": grunt.file.readJSON('tasks/deploy/host.json'),
  });

  grunt.config.set('sshexec', {
    uptime: {
      command: 'uptime',
      options: { config: 'host' }
    },
  });
  grunt.config.set('sftp', {
    deploy: {
      files: {
        "./": ["package.json", "app.js", ["config/*.js"], ["api/**/*.js"], ["views/**/*.js"], ["assets/**/*.*"]]
      },
      options: { config: 'host' }
    }
  });

  grunt.loadNpmTasks('grunt-ssh');
};

On the other side, in tasks/register/deploy.js I have:

module.exports = function (grunt) {
  grunt.registerTask('uptime', [
    'sshexec:uptime',
    'sftp:deploy',
  ]);
};

But the following call:

grunt deploy

fails with:

$ grunt deploy
Running "sshexec:uptime" (sshexec) task
 23:20:43 up 151 days,  5:03,  1 user,  load average: 0.04, 0.05, 0.09
Running "sftp:deploy" (sftp) task
Warning: Connection :: error :: Error: connect ECONNREFUSED Use --force to continue.

The first sshexec:uptime task succeed but sftp:deploy failed.

Any things I missed in the configuration ?

Upload large file failed

when i upload a large file, it does not work.

Running "sftp:test" (sftp) task
dist/script/base/base.js [===================] 100% of 16KB
dist/script/vendor/common.js [============       ] 66% of 242KB

if i change the size smaller,it can work.

can you help me, thank you.

Permissions issue

When I upgrade past 0.8 I get a permission denied error message when copying up files to a remote host. Looking at the output of --verbose mode I seem to connect ok, just not able to write even a simple text file.

Connection :: connect
copying package/MANIFEST to /MANIFEST
>> Error: Permission denied

For now I've dropped back to 0.8 which still works fine for me.

Fatal error: Argument must be a string

This is my configuration:

    sshconfig: {
      live: {
        host: 'dev.xxxxx.nl',
        agent: process.env.SSH_AUTH_SOCK,
        showProgress: true
      }
    },
    sftp: {
      copytar: {
        files: {
          './': ['dist.tar.gz']
        },
        options: {
          config: 'live',
          path: '/tmp/'
        }
      }
    }

This is the --verbose output:

Running "sftp:copytar" (sftp) task
Verifying property sftp.copytar exists in config...OK
Files: dist.tar.gz -> ./
Options: path="/tmp/", host=false, username=false, password=false, agent="", port=22, minimatch={}, srcBasePath="", createDirectories=false, directoryPermissions=493, showProgress=false, config="live"
Raw Options: path="/tmp/", host=false, username=false, password=false, agent="", port=22, minimatch={}, srcBasePath="", createDirectories=false, directoryPermissions=493, showProgress=false, config="live"
Verifying property sshconfig.live exists in config...OK
Options: path="/tmp/", host="dev.xxxxxx.nl", username=false, password=false, agent="/tmp/launch-L3FAbH/Listeners", port=22, minimatch={}, srcBasePath="", createDirectories=false, directoryPermissions=493, showProgress, config="live"
Connection :: connect
Fatal error: Argument must be a string

Any clue which configuration option the error message is referring to?

Error when using SFTP with private key

Whenever I run SFTP I get this error.

Warning: Unable to parse private key while generating public key

This is what my config looks like

sftp: {
        build: {
            src: ['build/build.zip'],
            options: {
                path: '<path>',
                host: '<%= secret.host %>',
                username: '<%= secret.username %>',
                password: '<%= secret.password %>',
                createDirectories: true,
                privateKey: grunt.file.read("/Users/<user>/.ssh/id_rsa"),
                passphrase: '<%= secret.passphrase %>'
            }
        }
    }

It looks like the id_rsa file is being read properly because I can see it in one of the options in the grunt terminal output. Maybe it's something wrong with my key or possibly my .ssh/config file.

Host <project>
HostName <project.server.com>
User <username>

I've asled tried setting an IdentityFile in the config

I'm stumped.

Running command with 'sudo' using pty

Not sure what I'm missing here, but I can't seem to figure out how to make it possible for me to enter my password when attempting to run a command remotely with sudo.

Here's my configuration:

sshexec: {
  options: {
    host: '[host]',
    username: '[username]',
    agent: process.env.SSH_AUTH_SOCK,
    pty: true
  },
  ls: {
    command: 'sudo ls -la',
  }
}

So when I run the task just gets to the point where is asks for the password and stops. Doesn't react to anything I type in (which is what I exepected I guess):

Running "sshexec:ls" (sshexec) task
>> [sudo] password for [username]:

I'm using version 0.9 installed via NPM.

Download method - fatal errors

I'm tying to get downloading to work via SFTP. I've tried about a thousand combinations and I always end up getting one of two errors:

Fatal error: Cannot call method 'push' of undefined and Fatal error: Cannot call method 'indexOf' of undefined. The latter error only comes if I put "/home/" in the value of the files hash. If I don't put "/home/" in the hash value, the debug output says Files: [no src] -> ./ and it throws the former error.

I've confirmed the connection works. The only thing I can figure is I just need to rearrange where I'm putting what...

Note: I do not have write permissions on the remote server. Just in case that's relevant. I can sftp through the command line and get what I need with no problems though.

Pertinent entries in Gruntfile:

grunt.initConfig({
    secret: grunt.file.readJSON('secret.json'),
    sftp: {
      mysqldump: {
        files: {
          # I believe this is meant to be local destination: remote source
          'mysqldumps/': '/subfolder/subfolder/file'
        },
        options: {
          path: '/home/'
          host: '<%= secret.host %>',
          username: '<%= secret.username %>',
          privateKey: '<%= grunt.file.read(secret.key_path) %>',
          srcBasePath: '' // because I don't want to chop off anything
          destBasePath: __dirname, // Local base - I assume this means "mysqldumps/" in files hash key will be relative to this
          mode: 'download'
        }
      }
    }
  });

Typical output:

Initializing
Command-line options: --verbose

Reading "Gruntfile.js" Gruntfile...OK

Registering Gruntfile tasks.
Reading secret.json...OK
Parsing secret.json...OK
Initializing config...OK

Registering "grunt-ssh" local Npm module tasks.
Reading /Users/bredonjones/project/.grunt/node_modules/grunt-ssh/package.json...OK
Parsing /Users/bredonjones/project/.grunt/node_modules/grunt-ssh/package.json...OK
Loading "sftp.js" tasks...OK
+ sftp
Loading "sshexec.js" tasks...OK
+ sshexec
Loading "Gruntfile.js" tasks...OK
+ default

Running tasks: sftp:mysqldump

Running "sftp:mysqldump" (sftp) task
Verifying property sftp.mysqldump exists in config...Reading /Users/bredonjones/.ssh/id_rsa...OK
OK
Reading /Users/bredonjones/.ssh/id_rsa...OK
Files: [no src] -> ./ // Note: this line will show "Files: /home/ -> ./" if I put that in the value of the hash
Reading /Users/bredonjones/.ssh/id_rsa...OK
Options: path="/home/", host="redacted", username="redacted", password=false, agent="", port=22, minimatch={}, srcBasePath="", destBasePath="mysqldumps/", createDirectories=false, directoryPermissions=493, showProgress=false, mode="download", privateKey="-----BEGIN RSA PRIVATE KEY-----redacted-----END RSA PRIVATE KEY-----\n"
Raw Options: path="/home/", host="redacted", username="redacted", password=false, agent="", port=22, minimatch={}, srcBasePath="", destBasePath="mysqldumps/", createDirectories=false, directoryPermissions=493, showProgress=false, mode="download", privateKey="-----BEGIN RSA PRIVATE KEY-----redacted-----END RSA PRIVATE KEY-----\n"
Options: path="/home/", host="redacted", username="redacted", password=false, agent="", port=22, minimatch={}, srcBasePath="", destBasePath="mysqldumps/", createDirectories=false, directoryPermissions=493, showProgress=false, mode="download", privateKey="-----BEGIN RSA PRIVATE KEY-----redacted-----END RSA PRIVATE KEY-----\n"
Connection :: connect
Fatal error: Cannot call method 'push' of undefined

cc: @chuckmo any help would be appreciated. I hope it is blazingly obvious.

Better Explain Files Property in docs

This seems to only upload print.css, for some reason twice.

files: {
  "./": "<%= dirs.css %>style.css",
  "./": "<%= dirs.css %>login.css",
  "./": "<%= dirs.css %>print.css"
},

but this works as expected

files: {
  "./": ["<%= dirs.css %>style.css","<%= dirs.css %>login.css","<%= dirs.css %>print.css"]
},

might be helpful to others to explain more about how key/value pairs for files should be setup, or show a few more examples

Better error messages

I have a BUILD folder and I want to upload all filed there, however, regardless what I define I get

>> Unable to copy; no valid source files were found.

It would be nice to have a better error message that would say how exactly I did wrong. My conf was

sftp: {
            deploy: {
                files: {
                    "./BUILD/": "*.tar.gz"
                },
                options: {
                    path    : '/var/www',
                    host    : '<%=ftp.host%>',
                    username: '<%=ftp.user%>',
                    password: '<%=ftp.pass%>',
                    showProgress: true
                }
            }
        },

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.