Class: WinRM::FS::Core::FileTransporter

Inherits:
Object
  • Object
show all
Defined in:
lib/winrm-fs/core/file_transporter.rb

Overview

Object which can upload one or more files or directories to a remote host over WinRM using PowerShell scripts and CMD commands. Note that this form of file transfer is not ideal and extremely costly on both the local and remote sides. Great pains are made to minimize round trips to the remote host and to minimize the number of PowerShell sessions being invoked which can be 2 orders of magnitude more expensive than vanilla CMD commands.

This object is supported by a ‘PowerShell` instance as it depends on the `#run` API contract.

An optional logger can be supplied, assuming it can respond to the ‘#debug` and `#debug?` messages.

Author:

Instance Method Summary collapse

Constructor Details

#initialize(shell, opts = {}) ⇒ FileTransporter

Creates a FileTransporter given a PowerShell object.

Parameters:

  • shell (PowerShell)

    a winrm PowerShell object



66
67
68
69
70
71
# File 'lib/winrm-fs/core/file_transporter.rb', line 66

def initialize(shell, opts = {})
  @shell  = shell
  @logger = shell.logger
  @id_generator = opts.fetch(:id_generator) { -> { SecureRandom.uuid } }
  Zip.unicode_names = true
end

Instance Method Details

#upload(locals, remote) ⇒ Hash

Uploads a collection of files and/or directories to the remote host.

**TODO Notes:**

  • options could specify zip mode, zip options, etc.

  • maybe option to set tmpfile base dir to override $env:PATH?

  • progress yields block like net-scp progress

  • final API: def upload(locals, remote, _options = {}, &_progress)

Parameters:

  • locals (Array<String>, String, StringIO)

    one or more local file or directory paths, StringIO objects also accepted

  • remote (String)

    the base destination path on the remote host

Returns:

  • (Hash)

    report hash, keyed by the local SHA1 digest



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/winrm-fs/core/file_transporter.rb', line 85

def upload(locals, remote)
  files = nil
  report = nil
  remote = remote.to_s
  elapsed1 = Benchmark.measure do
    files = make_files_hash([locals].flatten, remote)
    report = check_files(files)
    merge_with_report!(files, report)
    reconcile_destinations!(files)
  end
  total_size = total_base64_transfer_size(files)

  elapsed2 = Benchmark.measure do
    report = stream_upload_files(files) do |local_path, xfered|
      yield xfered, total_size, local_path, remote if block_given?
    end
    merge_with_report!(files, report)
  end

  elapsed3 = Benchmark.measure do
    report = extract_files(files)
    merge_with_report!(files, report)
    cleanup(files)
  end

  logger.debug(
    "Uploaded #{files.keys.size} items " \
    "dirty_check: #{duration(elapsed1.real)} " \
    "stream_files: #{duration(elapsed2.real)} " \
    "extract: #{duration(elapsed3.real)} " \
  )

  [total_size, files]
end