winrm 1.3.0.dev.2 → 1.3.0.dev.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,4 +41,18 @@ describe 'response handler', :unit => true do
41
41
  end
42
42
  end
43
43
  end
44
+
45
+ describe "failed 500 WMI error response" do
46
+ let(:wmi_error) { File.read("spec/stubs/responses/wmi_error_v2.xml") }
47
+
48
+ it 'raises a WinRMWMIError' do
49
+ handler = WinRM::ResponseHandler.new(wmi_error, 500)
50
+ begin
51
+ handler.parse_to_xml()
52
+ rescue WinRM::WinRMWMIError => e
53
+ expect(e.error_code).to eq('2150859173')
54
+ expect(e.error).to include('The WS-Management service cannot process the request.')
55
+ end
56
+ end
57
+ end
44
58
  end
@@ -0,0 +1,41 @@
1
+ <s:Envelope xmlns:a='http://schemas.xmlsoap.org/ws/2004/08/addressing' xmlns:e='http://schemas.xmlsoap.org/ws/2004/08/eventing' xml:lang='en-US' xmlns:n='http://schemas.xmlsoap.org/ws/2004/09/enumeration' xmlns:p='http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd' xmlns:s='http://www.w3.org/2003/05/soap-envelope' xmlns:w='http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd' xmlns:x='http://schemas.xmlsoap.org/ws/2004/09/transfer'>
2
+ <s:Header>
3
+ <a:Action>http://schemas.dmtf.org/wbem/wsman/1/wsman/fault</a:Action>
4
+ <a:MessageID>uuid:B8829021-48C3-4F27-B94B-491DAC4F29B1</a:MessageID>
5
+ <a:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:To>
6
+ </s:Header>
7
+ <s:Body>
8
+ <s:Fault>
9
+ <s:Code>
10
+ <s:Value>s:Sender</s:Value>
11
+ <s:Subcode>
12
+ <s:Value>w:QuotaLimit</s:Value>
13
+ </s:Subcode>
14
+ </s:Code>
15
+ <s:Reason>
16
+ <s:Text xml:lang='en-US'>The WS-Management service cannot process the request. The maximum number of concurrent shells for this user has been exceeded. Close existing shells or raise the quota for this user. </s:Text>
17
+ </s:Reason>
18
+ <s:Detail>
19
+ <p:MSFT_WmiError b:IsCIM_Error='true' xmlns:b='http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd' xmlns:cim='http://schemas.dmtf.org/wbem/wscim/1/common' xmlns:p='http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/MSFT_WmiError' xsi:type='p:MSFT_WmiError_Type' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
20
+ <p:CIMStatusCode xsi:type='cim:cimUnsignedInt'>27</p:CIMStatusCode>
21
+ <p:CIMStatusCodeDescription xsi:nil='true' xsi:type='cim:cimString'/>
22
+ <p:ErrorSource xsi:nil='true' xsi:type='cim:cimString'/>
23
+ <p:ErrorSourceFormat xsi:type='cim:cimUnsignedShort'>0</p:ErrorSourceFormat>
24
+ <p:ErrorType xsi:type='cim:cimUnsignedShort'>0</p:ErrorType>
25
+ <p:Message xsi:type='cim:cimString'>The WS-Management service cannot process the request. This user is allowed a maximum number of 30 concurrent shells, which has been exceeded. Close existing shells or raise the quota for this user. </p:Message>
26
+ <p:MessageID xsi:type='cim:cimString'>HRESULT 0x803381a5</p:MessageID>
27
+ <p:OtherErrorSourceFormat xsi:nil='true' xsi:type='cim:cimString'/>
28
+ <p:OtherErrorType xsi:nil='true' xsi:type='cim:cimString'/>
29
+ <p:OwningEntity xsi:nil='true' xsi:type='cim:cimString'/>
30
+ <p:PerceivedSeverity xsi:type='cim:cimUnsignedShort'>0</p:PerceivedSeverity>
31
+ <p:ProbableCause xsi:type='cim:cimUnsignedShort'>0</p:ProbableCause>
32
+ <p:ProbableCauseDescription xsi:nil='true' xsi:type='cim:cimString'/>
33
+ <p:error_Category xsi:type='cim:cimUnsignedInt'>30</p:error_Category>
34
+ <p:error_Code xsi:type='cim:cimUnsignedInt'>2150859173</p:error_Code>
35
+ <p:error_Type xsi:type='cim:cimString'>HRESULT</p:error_Type>
36
+ <p:error_WindowsErrorMessage xsi:type='cim:cimString'>The WS-Management service cannot process the request. This user is allowed a maximum number of 30 concurrent shells, which has been exceeded. Close existing shells or raise the quota for this user. </p:error_WindowsErrorMessage>
37
+ </p:MSFT_WmiError>
38
+ </s:Detail>
39
+ </s:Fault>
40
+ </s:Body>
41
+ </s:Envelope>
@@ -0,0 +1,75 @@
1
+ describe 'WinRM options', :unit => true do
2
+ let(:subject) { WinRM::WinRMWebService.new('http://localhost:55985/wsman', :plaintext) }
3
+
4
+ context 'when operations timeout is set to 60' do
5
+ before(:each) { subject.set_timeout(60) }
6
+ describe '#receive_timeout' do
7
+ it 'is set to 70s' do
8
+ transportclass = subject.instance_variable_get(:@xfer)
9
+ expect(transportclass.receive_timeout).to eql(70)
10
+ end
11
+ end
12
+ describe '#op_timeout' do
13
+ it 'is set to 60s' do
14
+ expect(subject.timeout).to eql('PT60S')
15
+ end
16
+ end
17
+ end
18
+
19
+ context 'when operations timeout is set to 30 and receive timeout is set to 120' do
20
+ before(:each) { subject.set_timeout(30, 120) }
21
+ describe '#receive_timeout' do
22
+ it 'is set to 120s' do
23
+ transportclass = subject.instance_variable_get(:@xfer)
24
+ expect(transportclass.receive_timeout).to eql(120)
25
+ end
26
+ end
27
+ describe '#op_timeout' do
28
+ it 'is set to 30s' do
29
+ expect(subject.timeout).to eql('PT30S')
30
+ end
31
+ end
32
+ end
33
+
34
+ context 'when max_env_size is set to 614400' do
35
+ before(:each) { subject.max_env_size(614400) }
36
+ describe '@max_env_sz' do
37
+ it 'is set to 614400' do
38
+ expect(subject.instance_variable_get('@max_env_sz')).to eq(614400)
39
+ end
40
+ end
41
+ end
42
+
43
+ context 'when locale is set to en-CA' do
44
+ before(:each) { subject.locale('en-CA') }
45
+ describe '@locale' do
46
+ it 'is set to en-CA' do
47
+ expect(subject.instance_variable_get('@locale')).to eq('en-CA')
48
+ end
49
+ end
50
+ end
51
+
52
+ context 'default' do
53
+ describe '#receive_timeout' do
54
+ it 'should be 3600ms' do
55
+ transportclass = subject.instance_variable_get(:@xfer)
56
+ expect(transportclass.receive_timeout).to eql(3600)
57
+ end
58
+ end
59
+ describe '#timeout' do
60
+ it 'should be 60s' do
61
+ expect(subject.timeout).to eql('PT60S')
62
+ end
63
+ end
64
+ describe '@locale' do
65
+ it 'should be en-US' do
66
+ expect(subject.instance_variable_get('@locale')).to eq('en-US')
67
+ end
68
+ end
69
+ describe '@max_env_sz' do
70
+ it 'should be 153600' do
71
+ expect(subject.instance_variable_get('@max_env_sz')).to eq(153600)
72
+ end
73
+ end
74
+ end
75
+ end
@@ -49,22 +49,4 @@ describe "winrm client primitives" do
49
49
  end
50
50
  end
51
51
 
52
- describe "simple values", :unit => true do
53
- it 'should set #op_timeout' do
54
- expect(@winrm.op_timeout(120)).to eq('PT2M0S')
55
- expect(@winrm.op_timeout(1202)).to eq('PT20M2S')
56
- expect(@winrm.op_timeout(86400)).to eq('PT24H0S')
57
- end
58
-
59
- it 'should set #max_env_size' do
60
- @winrm.max_env_size(153600 * 4)
61
- expect(@winrm.instance_variable_get('@max_env_sz')).to eq(614400)
62
- end
63
-
64
- it 'should set #locale' do
65
- @winrm.locale('en-ca')
66
- expect(@winrm.instance_variable_get('@locale')).to eq('en-ca')
67
- end
68
- end
69
-
70
52
  end
data/winrm.gemspec CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
26
26
  s.bindir = "bin"
27
27
  s.executables = ['rwinrm']
28
28
  s.required_ruby_version = '>= 1.9.0'
29
- s.add_runtime_dependency 'gssapi', '~> 1.0'
29
+ s.add_runtime_dependency 'gssapi', '~> 1.2'
30
30
  s.add_runtime_dependency 'httpclient', '~> 2.2', '>= 2.2.0.2'
31
31
  s.add_runtime_dependency 'rubyntlm', '~> 0.4.0'
32
32
  s.add_runtime_dependency 'uuidtools', '~> 2.1.2'
@@ -34,8 +34,6 @@ Gem::Specification.new do |s|
34
34
  s.add_runtime_dependency 'nori', '~> 2.0'
35
35
  s.add_runtime_dependency 'gyoku', '~> 1.0'
36
36
  s.add_runtime_dependency 'builder', '>= 2.1.2'
37
- s.add_runtime_dependency 'rubyzip', '~> 1.1'
38
- s.add_runtime_dependency 'ruby-progressbar', '~> 1.6'
39
37
  s.add_development_dependency 'rspec', '~> 3.0.0'
40
38
  s.add_development_dependency 'rake', '~> 10.3.2'
41
39
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: winrm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0.dev.2
4
+ version: 1.3.0.dev.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Wanek
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-11-04 00:00:00.000000000 Z
12
+ date: 2015-01-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: gssapi
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - ~>
19
19
  - !ruby/object:Gem::Version
20
- version: '1.0'
20
+ version: '1.2'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - ~>
26
26
  - !ruby/object:Gem::Version
27
- version: '1.0'
27
+ version: '1.2'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: httpclient
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -135,34 +135,6 @@ dependencies:
135
135
  - - '>='
136
136
  - !ruby/object:Gem::Version
137
137
  version: 2.1.2
138
- - !ruby/object:Gem::Dependency
139
- name: rubyzip
140
- requirement: !ruby/object:Gem::Requirement
141
- requirements:
142
- - - ~>
143
- - !ruby/object:Gem::Version
144
- version: '1.1'
145
- type: :runtime
146
- prerelease: false
147
- version_requirements: !ruby/object:Gem::Requirement
148
- requirements:
149
- - - ~>
150
- - !ruby/object:Gem::Version
151
- version: '1.1'
152
- - !ruby/object:Gem::Dependency
153
- name: ruby-progressbar
154
- requirement: !ruby/object:Gem::Requirement
155
- requirements:
156
- - - ~>
157
- - !ruby/object:Gem::Version
158
- version: '1.6'
159
- type: :runtime
160
- prerelease: false
161
- version_requirements: !ruby/object:Gem::Requirement
162
- requirements:
163
- - - ~>
164
- - !ruby/object:Gem::Version
165
- version: '1.6'
166
138
  - !ruby/object:Gem::Dependency
167
139
  name: rspec
168
140
  requirement: !ruby/object:Gem::Requirement
@@ -211,16 +183,16 @@ files:
211
183
  - README.md
212
184
  - Rakefile
213
185
  - VERSION
186
+ - Vagrantfile
214
187
  - bin/rwinrm
215
188
  - changelog.md
216
189
  - lib/winrm.rb
217
190
  - lib/winrm/exceptions/exceptions.rb
218
- - lib/winrm/file_transfer.rb
219
- - lib/winrm/file_transfer/remote_file.rb
220
- - lib/winrm/file_transfer/remote_zip_file.rb
221
191
  - lib/winrm/helpers/iso8601_duration.rb
192
+ - lib/winrm/helpers/powershell_script.rb
222
193
  - lib/winrm/http/response_handler.rb
223
194
  - lib/winrm/http/transport.rb
195
+ - lib/winrm/output.rb
224
196
  - lib/winrm/soap_provider.rb
225
197
  - lib/winrm/winrm_service.rb
226
198
  - preamble
@@ -228,10 +200,8 @@ files:
228
200
  - spec/cmd_spec.rb
229
201
  - spec/config-example.yml
230
202
  - spec/exception_spec.rb
231
- - spec/file_transfer/remote_file_spec.rb
232
- - spec/file_transfer/remote_zip_file_spec.rb
233
- - spec/file_transfer_spec.rb
234
203
  - spec/matchers.rb
204
+ - spec/output_spec.rb
235
205
  - spec/powershell_spec.rb
236
206
  - spec/response_handler_spec.rb
237
207
  - spec/spec_helper.rb
@@ -239,6 +209,8 @@ files:
239
209
  - spec/stubs/responses/open_shell_v2.xml
240
210
  - spec/stubs/responses/soap_fault_v1.xml
241
211
  - spec/stubs/responses/soap_fault_v2.xml
212
+ - spec/stubs/responses/wmi_error_v2.xml
213
+ - spec/winrm_options_spec.rb
242
214
  - spec/winrm_primitives_spec.rb
243
215
  - spec/wql_spec.rb
244
216
  - winrm.gemspec
@@ -1,184 +0,0 @@
1
- require 'io/console'
2
- require 'json'
3
- require 'ruby-progressbar'
4
-
5
- module WinRM
6
- class RemoteFile
7
-
8
- attr_reader :local_path
9
- attr_reader :remote_path
10
- attr_reader :closed
11
- attr_reader :options
12
-
13
- def initialize(service, local_path, remote_path, opts = {})
14
- @logger = Logging.logger[self]
15
- @options = opts
16
- @closed = false
17
- @service = service
18
- @shell = service.open_shell
19
- @local_path = local_path
20
- @remote_path = full_remote_path(local_path, remote_path)
21
- @logger.debug("Creating RemoteFile of local '#{local_path}' at '#{@remote_path}'")
22
- ensure
23
- if !shell.nil?
24
- ObjectSpace.define_finalizer( self, self.class.close(shell, service) )
25
- end
26
- end
27
-
28
- def upload
29
- raise WinRMUploadFailed.new("This RemoteFile is closed.") if closed
30
- raise WinRMUploadFailed.new("Cannot find path: '#{local_path}'") unless File.exist?(local_path)
31
-
32
- @remote_path, should_upload = powershell_batch do | builder |
33
- builder << resolve_remote_command
34
- builder << is_dirty_command
35
- end
36
-
37
- if should_upload
38
- size = upload_to_remote
39
- powershell_batch {|builder| builder << create_post_upload_command}
40
- else
41
- size = 0
42
- logger.debug("Files are equal. Not copying #{local_path} to #{remote_path}")
43
- end
44
- size
45
- end
46
-
47
- def close
48
- service.close_shell(shell) unless shell.nil? or closed
49
- @closed = true
50
- end
51
-
52
- protected
53
-
54
- attr_reader :logger
55
- attr_reader :service
56
- attr_reader :shell
57
-
58
- def self.close(shell_id, service)
59
- proc { service.close_shell(shell_id) }
60
- end
61
-
62
- def full_remote_path(local_path, remote_path)
63
- base_file_name = File.basename(local_path)
64
- if File.basename(remote_path) != base_file_name
65
- remote_path = File.join(remote_path, base_file_name)
66
- end
67
- remote_path
68
- end
69
-
70
- def resolve_remote_command
71
- <<-EOH
72
- $dest_file_path = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath("#{remote_path}")
73
-
74
- if (!(Test-Path $dest_file_path)) {
75
- $dest_dir = ([System.IO.Path]::GetDirectoryName($dest_file_path))
76
- New-Item -ItemType directory -Force -Path $dest_dir | Out-Null
77
- }
78
-
79
- $dest_file_path
80
- EOH
81
- end
82
-
83
- def is_dirty_command
84
- local_md5 = Digest::MD5.file(local_path).hexdigest
85
- <<-EOH
86
- $dest_file_path = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath("#{remote_path}")
87
-
88
- if (Test-Path $dest_file_path) {
89
- $crypto_prov = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
90
- try {
91
- $file = [System.IO.File]::Open($dest_file_path,
92
- [System.IO.Filemode]::Open, [System.IO.FileAccess]::Read)
93
- $guest_md5 = ([System.BitConverter]::ToString($crypto_prov.ComputeHash($file)))
94
- $guest_md5 = $guest_md5.Replace("-","").ToLower()
95
- }
96
- finally {
97
- $file.Dispose()
98
- }
99
- if ($guest_md5 -eq '#{local_md5}') {
100
- return $false
101
- }
102
- }
103
- if(Test-Path $dest_file_path){remove-item $dest_file_path -Force}
104
- return $true
105
- EOH
106
- end
107
-
108
- def upload_to_remote
109
- logger.debug("Uploading '#{local_path}' to temp file '#{remote_path}'")
110
- base64_host_file = Base64.encode64(IO.binread(local_path)).gsub("\n", "")
111
- base64_array = base64_host_file.chars.to_a
112
- unless options[:quiet]
113
- console_width = IO.console.winsize[1]
114
- bar = ProgressBar.create(:title => "Copying #{File.basename(local_path)}...", :total => base64_array.count, :length => console_width-1)
115
- end
116
- base64_array.each_slice(8000 - remote_path.size) do |chunk|
117
- cmd("echo #{chunk.join} >> \"#{remote_path}\"")
118
- bar.progress += chunk.count unless options[:quiet]
119
- end
120
- base64_array.length
121
- end
122
-
123
- def decode_command
124
- <<-EOH
125
- $base64_string = Get-Content '#{remote_path}'
126
- $bytes = [System.Convert]::FromBase64String($base64_string)
127
- [System.IO.File]::WriteAllBytes('#{remote_path}', $bytes) | Out-Null
128
- EOH
129
- end
130
-
131
- def create_post_upload_command
132
- [decode_command]
133
- end
134
-
135
- def powershell_batch(&block)
136
- ps_builder = []
137
- yield ps_builder
138
-
139
- commands = [ "$result = @{}" ]
140
- idx = 0
141
- ps_builder.flatten.each do |cmd_item|
142
- commands << <<-EOH
143
- $result.ret#{idx} = Invoke-Command { #{cmd_item} }
144
- EOH
145
- idx += 1
146
- end
147
- commands << "$(ConvertTo-Json $result)"
148
-
149
- result = []
150
- JSON.parse(powershell(commands.join("\n"))).each do |k,v|
151
- result << v unless v.nil?
152
- end
153
- result unless result.empty?
154
- end
155
-
156
- def powershell(script)
157
- script = "$ProgressPreference='SilentlyContinue';" + script
158
- logger.debug("executing powershell script: \n#{script}")
159
- script = script.encode('UTF-16LE', 'UTF-8')
160
- script = Base64.strict_encode64(script)
161
- cmd("powershell", ['-encodedCommand', script])
162
- end
163
-
164
- def cmd(command, arguments = [])
165
- command_output = nil
166
- out_stream = []
167
- err_stream = []
168
- service.run_command(shell, command, arguments) do |command_id|
169
- command_output = service.get_command_output(shell, command_id) do |stdout, stderr|
170
- out_stream << stdout if stdout
171
- err_stream << stderr if stderr
172
- end
173
- end
174
-
175
- if !command_output[:exitcode].zero? or !err_stream.empty?
176
- raise WinRMUploadFailed,
177
- :from => local_path,
178
- :to => remote_path,
179
- :message => command_output.inspect
180
- end
181
- out_stream.join.chomp
182
- end
183
- end
184
- end
@@ -1,60 +0,0 @@
1
- require 'zip'
2
-
3
- module WinRM
4
- class RemoteZipFile < RemoteFile
5
-
6
- attr_reader :archive
7
-
8
- def initialize(service, remote_path, opts = {})
9
- @logger = Logging.logger[self]
10
- @archive = create_archive(remote_path)
11
- @unzip_remote_path = remote_path
12
- remote_path = "$env:temp/WinRM_file_transfer"
13
- super(service, @archive, remote_path, opts)
14
- end
15
-
16
- def add_file(path)
17
- path = path.gsub("\\","/")
18
- logger.debug("adding '#{path}' to zip file")
19
- raise WinRMUploadFailed.new("Cannot find path: '#{path}'") unless File.exist?(path)
20
- File.directory?(path) ? glob = File.join(path, "**/*") : glob = path
21
- logger.debug("iterating files in '#{glob}'")
22
- Zip::File.open(archive, 'w') do |zipfile|
23
- Dir.glob(glob).each do |file|
24
- logger.debug("adding zip entry for '#{file}'")
25
- entry = Zip::Entry.new(archive, file.sub(File.dirname(path)+'/',''), nil, nil, nil, nil, nil, nil, ::Zip::DOSTime.new(2000))
26
- zipfile.add(entry,file)
27
- end
28
- end
29
- end
30
-
31
- protected
32
-
33
- def create_post_upload_command
34
- super << extract_zip_command
35
- end
36
-
37
- private
38
-
39
- def create_archive(remote_path)
40
- archive_folder = File.join(ENV['TMP'] || ENV['TMPDIR'] || '/tmp', 'WinRM_file_transfer_local')
41
- Dir.mkdir(archive_folder) unless File.exist?(archive_folder)
42
- archive = File.join(archive_folder,File.basename(remote_path))+'.zip'
43
- FileUtils.rm archive, :force=>true
44
-
45
- archive
46
- end
47
-
48
- def extract_zip_command
49
- <<-EOH
50
- $destination = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath("#{@unzip_remote_path}")
51
- $shellApplication = new-object -com shell.application
52
-
53
- $zipPackage = $shellApplication.NameSpace('#{remote_path}')
54
- mkdir $destination -ErrorAction SilentlyContinue | Out-Null
55
- $destinationFolder = $shellApplication.NameSpace($destination)
56
- $destinationFolder.CopyHere($zipPackage.Items(),0x10) | Out-Null
57
- EOH
58
- end
59
- end
60
- end
@@ -1,39 +0,0 @@
1
- require 'winrm/file_transfer/remote_file'
2
- require 'winrm/file_transfer/remote_zip_file'
3
-
4
- module WinRM
5
- # Perform file transfer operations between a local machine and winrm endpoint
6
- class FileTransfer
7
- # Upload one or more local files and directories to a remote directory
8
- # @example copy a single directory to a winrm endpoint
9
- #
10
- # WinRM::FileTransfer.upload(client, 'c:/dev/my_dir', '$env:AppData')
11
- #
12
- # @example copy several paths to the winrm endpoint
13
- #
14
- # WinRM::FileTransfer.upload(client, ['c:/dev/file1.txt','c:/dev/dir1'], '$env:AppData')
15
- #
16
- # @param [WinRM::WinRMService] a winrm service client connected to the endpoint where the remote path resides
17
- # @param [Array<String>] One or more paths that will be copied to the remote path. These can be files or directories to be deeply copied
18
- # @param [String] The directory on the remote endpoint to copy the local items to. This path may contain powershell style environment variables
19
- # @option opts [String] options to be used for the copy. Currently only :quiet is supported to suppress the progress bar
20
- # @return [Fixnum] The total number of bytes copied
21
- def self.upload(service, local_path, remote_path, opts = {})
22
- file = nil
23
- local_path = [local_path] if local_path.is_a? String
24
-
25
- if local_path.count == 1 && !File.directory?(local_path[0])
26
- file = RemoteFile.new(service, local_path[0], remote_path, opts)
27
- else
28
- file = RemoteZipFile.new(service, remote_path, opts)
29
- local_path.each do |path|
30
- file.add_file(path)
31
- end
32
- end
33
-
34
- file.upload
35
- ensure
36
- file.close unless file.nil?
37
- end
38
- end
39
- end
@@ -1,71 +0,0 @@
1
- describe WinRM::RemoteFile, :integration => true do
2
-
3
- let(:this_file) { __FILE__ }
4
- let(:service) { winrm_connection }
5
- let(:destination) {"#{ENV['temp']}/WinRM_tests"}
6
- after {
7
- subject.close
8
- FileUtils.rm_rf(destination)
9
- }
10
-
11
- context 'Upload a new file to directory path' do
12
- subject {WinRM::RemoteFile.new(service, this_file, destination, :quiet => true)}
13
-
14
- it 'copies the file inside the directory' do
15
- expect(subject.upload).to be > 0
16
- expect(File.exist?(File.join(destination, File.basename(this_file)))).to be_truthy
17
- end
18
- it 'copies the exact file content' do
19
- expect(subject.upload).to be > 0
20
- expect(File.read(File.join(destination, File.basename(this_file)))).to eq(File.read(this_file))
21
- end
22
-
23
- end
24
-
25
- context 'Upload an identical file to directory path' do
26
- subject {WinRM::RemoteFile.new(service, this_file, destination, :quiet => true)}
27
- let (:next_transfer) {WinRM::RemoteFile.new(service, this_file, destination, :quiet => true)}
28
-
29
- it 'does not copy the file' do
30
- expect(subject.upload).to be > 0
31
- expect(next_transfer.upload).to be == 0
32
- end
33
- end
34
-
35
- context 'Upload a file to file path' do
36
- subject {WinRM::RemoteFile.new(service, this_file, File.join(destination, File.basename(this_file)), :quiet => true)}
37
-
38
- it 'copies the file to the exact path' do
39
- expect(subject.upload).to be > 0
40
- expect(File.exist?(File.join(destination, File.basename(this_file)))).to be_truthy
41
- end
42
- end
43
-
44
- context 'Upload a new file to nested directory' do
45
- let (:nested) {File.join(destination, 'nested')}
46
- subject {WinRM::RemoteFile.new(service, this_file, nested, :quiet => true)}
47
-
48
- it 'copies the file to the nested path' do
49
- expect(subject.upload).to be > 0
50
- expect(File.exist?(File.join(nested, File.basename(this_file)))).to be_truthy
51
- end
52
- end
53
-
54
- context 'Upload a file after RemoteFile is closed' do
55
- subject {WinRM::RemoteFile.new(service, this_file, destination, :quiet => true)}
56
-
57
- it 'raises WinRMUploadFailed' do
58
- expect(subject.upload).to be > 0
59
- subject.close
60
- expect{subject.upload}.to raise_error(WinRM::WinRMUploadFailed)
61
- end
62
- end
63
-
64
- context 'Upload a bad path' do
65
- subject {WinRM::RemoteFile.new(service, 'c:/some/bad/path', destination, :quiet => true)}
66
-
67
- it 'raises WinRMUploadFailed' do
68
- expect { subject.upload }.to raise_error(WinRM::WinRMUploadFailed)
69
- end
70
- end
71
- end