winrm-fs 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/changelog.md +3 -0
- data/lib/winrm-fs/core/file_transporter.rb +40 -40
- data/lib/winrm-fs/file_manager.rb +2 -2
- data/lib/winrm-fs/scripts/check_files.ps1.erb +5 -5
- data/lib/winrm-fs/scripts/extract_files.ps1.erb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 22bfb44445f8a68db43716cdce53483049420a30
|
4
|
+
data.tar.gz: ae2b5641e2fe84b6e9ee9e017447fe382ace9ce5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 13d3bc1660e11ba10a057bce5d10e7b246f738159885be0a5034bf70c4cd767f9e74d118b47cc29156d809901dbff34d9ec024497315662dbbaaef3032d05dc5
|
7
|
+
data.tar.gz: cb5c3dcbb68cdddad234a354745505d226c5d0edebc5793a7ce545977ef79a426ac98eb6fcd5d115944d9f30136750b5b05a24ce4a0c60558b8b3e4e6ab2173c
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0
|
1
|
+
1.1.0
|
data/changelog.md
CHANGED
@@ -70,7 +70,7 @@ module WinRM
|
|
70
70
|
# @param locals [Array<String>,String] one or more local file or
|
71
71
|
# directory paths
|
72
72
|
# @param remote [String] the base destination path on the remote host
|
73
|
-
# @return [Hash] report hash, keyed by the local
|
73
|
+
# @return [Hash] report hash, keyed by the local SHA1 digest
|
74
74
|
def upload(locals, remote)
|
75
75
|
files = nil
|
76
76
|
report = nil
|
@@ -147,8 +147,8 @@ module WinRM
|
|
147
147
|
# will have the base name of the source file appended. This only
|
148
148
|
# applies to file uploads and not to folder uploads.
|
149
149
|
#
|
150
|
-
# @param files [Hash] files hash, keyed by the local
|
151
|
-
# @return [Hash] a report hash, keyed by the local
|
150
|
+
# @param files [Hash] files hash, keyed by the local SHA1 digest
|
151
|
+
# @return [Hash] a report hash, keyed by the local SHA1 digest
|
152
152
|
# @api private
|
153
153
|
def reconcile_destinations!(files)
|
154
154
|
files.each do |_, data|
|
@@ -158,10 +158,10 @@ module WinRM
|
|
158
158
|
end
|
159
159
|
end
|
160
160
|
|
161
|
-
# Adds an entry to a files Hash (keyed by local
|
161
|
+
# Adds an entry to a files Hash (keyed by local SHA1 digest) for a
|
162
162
|
# directory. When a directory is added, a temporary Zip file is created
|
163
163
|
# containing the contents of the directory and any file-related data
|
164
|
-
# such as
|
164
|
+
# such as SHA1 digest, size, etc. will be referring to the Zip file.
|
165
165
|
#
|
166
166
|
# @param hash [Hash] hash to be mutated
|
167
167
|
# @param dir [String] directory path to be Zipped and added
|
@@ -170,19 +170,19 @@ module WinRM
|
|
170
170
|
def add_directory_hash!(hash, dir, remote)
|
171
171
|
logger.debug "creating hash for directory #{remote}"
|
172
172
|
zip_io = TmpZip.new(dir, logger)
|
173
|
-
|
173
|
+
zip_sha1 = sha1sum(zip_io.path)
|
174
174
|
|
175
|
-
hash[
|
175
|
+
hash[zip_sha1] = {
|
176
176
|
'src' => dir,
|
177
177
|
'src_zip' => zip_io.path.to_s,
|
178
178
|
'zip_io' => zip_io,
|
179
|
-
'tmpzip' => "#{TEMP_UPLOAD_DIRECTORY}\\tmpzip-#{
|
179
|
+
'tmpzip' => "#{TEMP_UPLOAD_DIRECTORY}\\tmpzip-#{zip_sha1}.zip",
|
180
180
|
'dst' => "#{remote}\\#{File.basename(dir)}",
|
181
181
|
'size' => File.size(zip_io.path)
|
182
182
|
}
|
183
183
|
end
|
184
184
|
|
185
|
-
# Adds an entry to a files Hash (keyed by local
|
185
|
+
# Adds an entry to a files Hash (keyed by local SHA1 digest) for a file.
|
186
186
|
#
|
187
187
|
# @param hash [Hash] hash to be mutated
|
188
188
|
# @param local [String] file path
|
@@ -191,7 +191,7 @@ module WinRM
|
|
191
191
|
def add_file_hash!(hash, local, remote)
|
192
192
|
logger.debug "creating hash for file #{remote}"
|
193
193
|
|
194
|
-
hash[
|
194
|
+
hash[sha1sum(local)] = {
|
195
195
|
'src' => local,
|
196
196
|
'dst' => remote,
|
197
197
|
'size' => File.size(local)
|
@@ -199,12 +199,12 @@ module WinRM
|
|
199
199
|
end
|
200
200
|
|
201
201
|
# Runs the check_files PowerShell script against a collection of
|
202
|
-
# destination path/
|
202
|
+
# destination path/SHA1 checksum pairs. The PowerShell script returns
|
203
203
|
# its results as a CSV-formatted report which is converted into a Ruby
|
204
204
|
# Hash.
|
205
205
|
#
|
206
|
-
# @param files [Hash] files hash, keyed by the local
|
207
|
-
# @return [Hash] a report hash, keyed by the local
|
206
|
+
# @param files [Hash] files hash, keyed by the local SHA1 digest
|
207
|
+
# @return [Hash] a report hash, keyed by the local SHA1 digest
|
208
208
|
# @api private
|
209
209
|
def check_files(files)
|
210
210
|
logger.debug 'Running check_files.ps1'
|
@@ -213,16 +213,16 @@ module WinRM
|
|
213
213
|
parse_response(shell.run(script))
|
214
214
|
end
|
215
215
|
|
216
|
-
# Constructs a collection of destination path/
|
216
|
+
# Constructs a collection of destination path/SHA1 checksum pairs as a
|
217
217
|
# String representation of the contents of a PowerShell Hash Table.
|
218
218
|
#
|
219
|
-
# @param files [Hash] files hash, keyed by the local
|
219
|
+
# @param files [Hash] files hash, keyed by the local SHA1 digest
|
220
220
|
# @return [String] the inner contents of a PowerShell Hash Table
|
221
221
|
# @api private
|
222
222
|
def check_files_ps_hash(files)
|
223
|
-
hash = files.map do |
|
223
|
+
hash = files.map do |sha1, data|
|
224
224
|
[
|
225
|
-
|
225
|
+
sha1,
|
226
226
|
{
|
227
227
|
'target' => data.fetch('tmpzip', data['dst']),
|
228
228
|
'src_basename' => File.basename(data['src']),
|
@@ -239,9 +239,9 @@ module WinRM
|
|
239
239
|
# @param files [Hash] a files hash
|
240
240
|
# @api private
|
241
241
|
def cleanup(files)
|
242
|
-
files.select { |_, data| data.key?('zip_io') }.each do |
|
242
|
+
files.select { |_, data| data.key?('zip_io') }.each do |sha1, data|
|
243
243
|
data.fetch('zip_io').unlink
|
244
|
-
files.fetch(
|
244
|
+
files.fetch(sha1).delete('zip_io')
|
245
245
|
logger.debug "Cleaned up src_zip #{data['src_zip']}"
|
246
246
|
end
|
247
247
|
end
|
@@ -252,8 +252,8 @@ module WinRM
|
|
252
252
|
# Hash. The script will not be invoked if there are no zip files
|
253
253
|
# present in the incoming files Hash.
|
254
254
|
#
|
255
|
-
# @param files [Hash] files hash, keyed by the local
|
256
|
-
# @return [Hash] a report hash, keyed by the local
|
255
|
+
# @param files [Hash] files hash, keyed by the local SHA1 digest
|
256
|
+
# @return [Hash] a report hash, keyed by the local SHA1 digest
|
257
257
|
# @api private
|
258
258
|
def extract_files(files)
|
259
259
|
extracted_files = extract_files_ps_hash(files)
|
@@ -273,17 +273,17 @@ module WinRM
|
|
273
273
|
# all zipped folders as a String representation of the contents of a
|
274
274
|
# PowerShell Hash Table.
|
275
275
|
#
|
276
|
-
# @param files [Hash] files hash, keyed by the local
|
276
|
+
# @param files [Hash] files hash, keyed by the local SHA1 digest
|
277
277
|
# @return [String] the inner contents of a PowerShell Hash Table
|
278
278
|
# @api private
|
279
279
|
def extract_files_ps_hash(files)
|
280
280
|
file_data = files.select { |_, data| data.key?('tmpzip') }
|
281
281
|
|
282
|
-
result = file_data.map do |
|
282
|
+
result = file_data.map do |sha1, data|
|
283
283
|
val = { 'dst' => data['dst'] }
|
284
284
|
val['tmpzip'] = data['tmpzip'] if data['tmpzip']
|
285
285
|
|
286
|
-
[
|
286
|
+
[sha1, val]
|
287
287
|
end
|
288
288
|
|
289
289
|
ps_hash(Hash[result])
|
@@ -300,14 +300,14 @@ module WinRM
|
|
300
300
|
format('(%dm%.2fs)', minutes, seconds)
|
301
301
|
end
|
302
302
|
|
303
|
-
# Contructs a Hash of files or directories, keyed by the local
|
303
|
+
# Contructs a Hash of files or directories, keyed by the local SHA1
|
304
304
|
# digest. Each file entry has a source and destination set, at a
|
305
305
|
# minimum.
|
306
306
|
#
|
307
307
|
# @param locals [Array<String>] a collection of local files or
|
308
308
|
# directories
|
309
309
|
# @param remote [String] the base destination path on the remote host
|
310
|
-
# @return [Hash] files hash, keyed by the local
|
310
|
+
# @return [Hash] files hash, keyed by the local SHA1 digest
|
311
311
|
# @api private
|
312
312
|
def make_files_hash(locals, remote)
|
313
313
|
hash = {}
|
@@ -327,17 +327,17 @@ module WinRM
|
|
327
327
|
hash
|
328
328
|
end
|
329
329
|
|
330
|
-
# @return [String] the
|
330
|
+
# @return [String] the SHA1 digest of a local file
|
331
331
|
# @api private
|
332
|
-
def
|
333
|
-
Digest::
|
332
|
+
def sha1sum(local)
|
333
|
+
Digest::SHA1.file(local).hexdigest
|
334
334
|
end
|
335
335
|
|
336
336
|
# Destructively merges a report Hash into an existing files Hash.
|
337
337
|
# **Note:** this method mutates the files Hash.
|
338
338
|
#
|
339
|
-
# @param files [Hash] files hash, keyed by the local
|
340
|
-
# @param report [Hash] report hash, keyed by the local
|
339
|
+
# @param files [Hash] files hash, keyed by the local SHA1 digest
|
340
|
+
# @param report [Hash] report hash, keyed by the local SHA1 digest
|
341
341
|
# @api private
|
342
342
|
def merge_with_report!(files, report)
|
343
343
|
files.merge!(report) { |_, oldval, newval| oldval.merge(newval) }
|
@@ -355,7 +355,7 @@ module WinRM
|
|
355
355
|
#
|
356
356
|
# @param output [WinRM::Output] output object with stdout, stderr, and
|
357
357
|
# exit code
|
358
|
-
# @return [Hash] report hash, keyed by the local
|
358
|
+
# @return [Hash] report hash, keyed by the local SHA1 digest
|
359
359
|
# @api private
|
360
360
|
def parse_response(output)
|
361
361
|
exitcode = output.exitcode
|
@@ -374,7 +374,7 @@ module WinRM
|
|
374
374
|
|
375
375
|
array = CSV.parse(output.stdout, headers: true).map(&:to_hash)
|
376
376
|
array.each { |h| h.each { |key, value| h[key] = nil if value == '' } }
|
377
|
-
Hash[array.map { |entry| [entry.fetch('
|
377
|
+
Hash[array.map { |entry| [entry.fetch('src_sha1'), entry] }]
|
378
378
|
end
|
379
379
|
|
380
380
|
# Converts a Ruby hash into a PowerShell hash table, represented in a
|
@@ -487,20 +487,20 @@ module WinRM
|
|
487
487
|
# Base64-encoded temporary files. A "dirty" file is one which has the
|
488
488
|
# `"chk_dirty"` option set to `"True"` in the incoming files Hash.
|
489
489
|
#
|
490
|
-
# @param files [Hash] files hash, keyed by the local
|
491
|
-
# @return [Hash] a report hash, keyed by the local
|
490
|
+
# @param files [Hash] files hash, keyed by the local SHA1 digest
|
491
|
+
# @return [Hash] a report hash, keyed by the local SHA1 digest
|
492
492
|
# @api private
|
493
493
|
def stream_upload_files(files)
|
494
494
|
response = {}
|
495
|
-
files.each do |
|
495
|
+
files.each do |sha1, data|
|
496
496
|
src = data.fetch('src_zip', data['src'])
|
497
497
|
if data['chk_dirty'] == 'True'
|
498
|
-
response[
|
498
|
+
response[sha1] = { 'dest' => data['tmpzip'] || data['dst'] }
|
499
499
|
chunks, bytes = stream_upload_file(src, data['tmpzip'] || data['dst']) do |xfered|
|
500
500
|
yield data['src'], xfered
|
501
501
|
end
|
502
|
-
response[
|
503
|
-
response[
|
502
|
+
response[sha1]['chunks'] = chunks
|
503
|
+
response[sha1]['xfered'] = bytes
|
504
504
|
else
|
505
505
|
logger.debug "File #{data['dst']} is up to date, skipping"
|
506
506
|
end
|
@@ -512,7 +512,7 @@ module WinRM
|
|
512
512
|
# Calculates count based on the sum of base64 encoded content size
|
513
513
|
# of all files base 64 that are dirty.
|
514
514
|
#
|
515
|
-
# @param files [Hash] files hash, keyed by the local
|
515
|
+
# @param files [Hash] files hash, keyed by the local SHA1 digest
|
516
516
|
# @return [Fixnum] total byte size
|
517
517
|
# @api private
|
518
518
|
def total_base64_transfer_size(files)
|
@@ -29,11 +29,11 @@ module WinRM
|
|
29
29
|
@logger = connection.logger
|
30
30
|
end
|
31
31
|
|
32
|
-
# Gets the
|
32
|
+
# Gets the SHA1 checksum of the specified file if it exists,
|
33
33
|
# otherwise ''
|
34
34
|
# @param [String] The remote file path
|
35
35
|
# @parms [String] The digest method
|
36
|
-
def checksum(path, digest = '
|
36
|
+
def checksum(path, digest = 'SHA1')
|
37
37
|
@logger.debug("checksum with #{digest}: #{path}")
|
38
38
|
script = WinRM::FS::Scripts.render('checksum', path: path, digest: digest)
|
39
39
|
@connection.shell(:powershell) { |e| e.run(script).stdout.chomp }
|
@@ -16,18 +16,18 @@ Function Check-Files($h) {
|
|
16
16
|
}
|
17
17
|
New-Object psobject -Property @{
|
18
18
|
chk_exists = ($exists = Test-Path $dst -PathType Leaf)
|
19
|
-
|
20
|
-
|
19
|
+
src_sha1 = ($sMd5 = $_.Key)
|
20
|
+
dst_sha1 = ($dMd5 = if ($exists) { Get-SHA1Sum $dst } else { $null })
|
21
21
|
chk_dirty = ($dirty = if ($sMd5 -ne $dMd5) { $true } else { $false })
|
22
22
|
verifies = if ($dirty -eq $false) { $true } else { $false }
|
23
23
|
target_is_folder = $dst_changed
|
24
24
|
}
|
25
|
-
} | Select-Object -Property chk_exists,
|
25
|
+
} | Select-Object -Property chk_exists,src_sha1,dst_sha1,chk_dirty,verifies,target_is_folder
|
26
26
|
}
|
27
27
|
|
28
|
-
Function Get-
|
28
|
+
Function Get-SHA1Sum($src) {
|
29
29
|
Try {
|
30
|
-
$c = [System.Security.Cryptography.
|
30
|
+
$c = [System.Security.Cryptography.SHA1]::Create()
|
31
31
|
$bytes = $c.ComputeHash(($in = (Get-Item $src).OpenRead()))
|
32
32
|
return ([System.BitConverter]::ToString($bytes)).Replace("-", "").ToLower()
|
33
33
|
}
|
@@ -17,7 +17,7 @@ Function Decode-Files($hash) {
|
|
17
17
|
$value = $hash[$key]
|
18
18
|
$tzip, $dst = $Value["tmpzip"], $Value["dst"]
|
19
19
|
if ($tzip) {Unzip-File $tzip $dst}
|
20
|
-
New-Object psobject -Property @{dst=$dst;
|
20
|
+
New-Object psobject -Property @{dst=$dst;src_sha1=$key;tmpzip=$tzip}
|
21
21
|
}
|
22
22
|
}
|
23
23
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: winrm-fs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shawn Neal
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-10-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: erubis
|