upload(from, to, options={}, &block)

The upload action is used to transfer files (or even entire directory trees, though that'll be slow) from the local host to multiple remote hosts, in parallel. It may be configured to use either SFTP or SCP to copy the files, defaulting to SFTP.

Note that because this helper uses the SCP and SFTP protocols, it isn't possible to "sudo" with them. You need to make sure that the user you are logging into the server(s) as has the necessary permissions to create and write to the files.



This may be either a String, or an IO object (e.g. an open file handle, or a StringIO instance).

When it is a String, it must identify a file name on the local host of the file or directory you want to upload. It may include the special string $CAPISTRANO:HOST$, which will be replaced with the actual host name of the server being uploaded to. (In the event that you are uploading to multiple different hosts, this means you could have multiple different files locally, named for the target hosts, and Capistrano could upload them all in parallel in a single command!)

upload("files/hosts.conf", ...)
upload("files/$CAPISTRANO:HOST$.conf", ...)
upload("/home/bob/.ssh/id_dsa.pub", ...)

When from is an IO object, data will be read from it and transferred to the remote hosts. This lets you do things like upload from an in-memory buffer (wrapped in a StringIO) or forward data directly from a local network socket to multiple remote files.

config = { ... }
config_contents = StringIO.new(config.to_yaml)
upload(config_contents, ...)


This must be a string indicating the path on the remote server that should be uploaded to. As with from, it may include the string $CAPISTRANO:HOST$, which will be replaced with the actual host name when the file is uploaded. This way you can name the same file for each uploaded host.

upload("init.d/start-nginx.sh", "/etc/init.d/start-nginx.sh")
upload("config/hosts", "/etc/hosts-$CAPISTRANO:HOST$")


The options hash can be used to modify the default behavior of upload. Recognized options are:

This should a string indicating the desired permissions of the destination file or directory, after it is uploaded. Permissions are changed via a separate call to chmod, so any valid argument to chmod will work (either octal numbers or symbolic permissions).
This is a symbol indicating which protocol should be used to transfer the file or directory. If given, it must be either :sftp (the default), or :scp.
Either a string (for a single target host) or an array of strings, indicating which hosts should be uploaded to. By default, the hosts are determined from current task's roles.
Either a string or symbol (for a single target role) or an array of strings or symbols, indicating which roles should be uploaded to. If :hosts is specified, :roles will be ignored. By default, the roles are taken from the current task.
Specifies a condition limiting which hosts will be selected to receive the upload. This should refer to values set in the role. For example, if a role is defined with :primary => true, then you could select only hosts with that setting by specifying :only => { :primary => true }.
Specifies a condition limiting which hosts will be selected to receive the upload. This is the inverse of :only (hosts that do not match the condition will be selected).
If true, only the first matching server will be selected. The default is false (all matching servers will be selected).
Specifies the maximum number of hosts that should be selected at a time. If this value is less than the number of hosts that are selected to receive the upload, then the hosts will be uploaded to in groups of max_hosts. The default is nil, which indicates that there is no maximum host limit. Warning: this setting will probably be removed in a future release.

Note that the options are also passed directly through to the Net::SFTP (for :sftp) and Net::SCP (for :scp) libraries. Options exposed by those libraries are documented in those libraries. (For SFTP, see the Net::SFTP::Operations::Upload module. For SCP, see the Net::SCP#upload method.)


If no block is passed to upload, a minimal amount of progress reporting on the upload will be provided by default. (You'll see when each file is sent to the server, and for SFTP, when transfer finishes.) However, if you pass a block, it will be called to report status on the progress of the upload.

The format of the block is different, depending on whether you are using SFTP or SCP.

SFTP progress callbacks

For SFTP transfers, the block should take three parameters:

 upload("source", "target", :via => :sftp) do |event, options, *others|
   # ...

The event parameter is a symbol and will be indicate which event is being reported. It will be one of:

Indicates that a file is being opened in preparation for sending to the remote server. In this case, others[0] will be an object representing the file to be uploaded (see below).
Indicates that part (possibly all) of the current file is being uploaded. others[0] will be the file object (see below), others[1] will be the byte offset from which data is being sent, and others[2] will be the actual data being sent.
Indicates that a file has finished uploading. others[0] will be the file object (see below).
This event is used to indicate that a remote directory is being created (as part of uploading a directory tree). others[0] is the remote path name in this case.
Indicates that all files have been transfered for the current server.

The file object mentioned above is a simple structure with a few useful attributes. You can do object.local to get the local file name, object.remote to get the remote file name, and object.size to get the size of the file.

The options parameter is a hash of useful properties specific to the current server. It will contain at least the following keys:

The host name of the current server.
A Capistrano::ServerDefinition object for the current server.

The others parameter is an array of additional arguments, interpreted differently by the different progress events.

SCP progress callbacks

The SCP protocol doesn't give as much notification a the SFTP protocol does. In this case, the block takes four arguments:

upload("source", "target", :via => :scp) do |channel, name, sent, total|
  # ...

Here, channel is the SSH channel over which the transfer is occurring. It can be used like a hash with the following keys:

The host name of the current server.
A Capistrano::ServerDefinition object for the current server.

The name argument is the name of the file being transfered. sent is the total number of bytes that have been sent so far for the file, and total is the full size of the file being transferred.

See Also