Rsync (rsync v0.1.0)

View Source

Wrapper for the rsync command, reporting percent completion

The main entry point is sync/3, which starts a linked GenServer to monitor the transfer. The simplest usage would be to simply wait for the subprocess to complete successfully. Progress can be monitored by calling get_progress/1 or the caller can subscribe to receive progress messages as they are emitted by rsync, using the :listener option.

Errors and unrecognized status lines are logged, and overall success or error is reported using the GenServer exit reason.

Be extremely cautious when building source and target arguments, there is no built-in protection against filesystem traversal. Use Path.safe_relative/2 and the included make_remote_path/3 according to your expected needs.

Examples

Push a file to the default user's home directory on a remote server:

Rsync.sync("local_file.txt", "host:")

Retrieve several remote files:

Rsync.sync(
  Rsync.make_remote_paths(user, host, filenames),
  "local_path/"
)

Set up real-time monitoring of a transfer:

Rsync.sync("local_path", "host:remote_path", listener: self())

receive do
  {:progress, fraction_complete} ->
    IO.puts("Transfer #{fraction_complete * 100}% complete")

  {:exit_status, 0} ->
    IO.puts("Transfer successfully completed.")
end

Kill a transfer:

{:ok, pid} = Rsync.sync("local", "remote")

Rsync.stop(pid)

Handle unsuccessful exit using a Supervisor or by trapping the linked signal:

Process.flag(:trap_exit, true)

Rsync.sync("source", "target")

receive do
  {:EXIT, _pid, {:error, exit_status}} ->
    IO.puts("Failed with code: #{exit_status}")
end

Summary

Functions

Returns a specification to start this module under a supervisor.

Return overall tranfer progress as a floating point number between 0 and 1.

Start rsync file copy

Types

option()

@type option() ::
  {:env, [{charlist(), charlist()}]}
  | {:exe, binary()}
  | {:keyfile, binary()}
  | {:listener, pid()}
  | {:ssh_flags, binary()}
  | {:source, binary()}
  | {:sources, [binary()]}
  | {:target, binary()}

options()

@type options() :: [option()]

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

get_progress(pid)

@spec get_progress(pid()) :: float()

Return overall tranfer progress as a floating point number between 0 and 1.

make_remote_path(user, host, path)

make_remote_paths(user, host, paths)

start_link(args, opts \\ [])

@spec start_link(options(), GenServer.options()) :: GenServer.on_start()

stop(pid)

@spec stop(pid()) :: :ok

sync(source, target, opts \\ [])

@spec sync(binary() | [binary()], binary(), options()) :: GenServer.on_start()

Start rsync file copy

Options

  • :env - Charlist tuples of environment variables to set. For example, env: [{~c"RSYNC_PARTIAL_DIR", ~c".rsync-partial"}]

  • :exe - Path to the rsync executable. Defaults to the first rsync in PATH.

  • :keyfile - Path to ssh private identity. Will be shell-expanded. For example, keyfile: "~/.ssh/id_rsa-bot"

  • :listener - Process which will listen for progress updates. This process may receive two message formats:

    • {:progress, float()} - Fractional completion, such as 0.1 for 10% overall progress.

    • {:exit_status, int()} - Sent when the sync is finished, with an exit status that should equal 0 on success.

  • :ssh_flags - Commandline options to pass to ssh. Will be shell-expanded. For example, ssh_flags: "-i ~/.ssh/id_rsa-bot -o StrictHostKeyChecking=no"

  • :source - Source file or directory. For multiple sources use :sources.

  • :sources - List of source files or directories. Follows the same rules as rsync, where any directory name ending in "/" will be copied to the top level without nesting under a directory on the target. Remote sources should each be prepended with user and hostname.

  • :target - Target file or directory. Remote target should be prepended with user and hostname, for example target: "user@host:/path".