sshkit 1.21.7 → 1.22.1
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.
- checksums.yaml +4 -4
- data/.github/workflows/push.yml +1 -1
- data/EXAMPLES.md +25 -13
- data/README.md +2 -1
- data/lib/sshkit/backends/netssh/known_hosts.rb +3 -1
- data/lib/sshkit/backends/netssh/scp_transfer.rb +26 -0
- data/lib/sshkit/backends/netssh/sftp_transfer.rb +46 -0
- data/lib/sshkit/backends/netssh.rb +36 -6
- data/lib/sshkit/host.rb +7 -0
- data/lib/sshkit/version.rb +1 -1
- data/sshkit.gemspec +2 -0
- data/test/functional/backends/netssh_transfer_tests.rb +83 -0
- data/test/functional/backends/test_netssh.rb +0 -66
- data/test/functional/backends/test_netssh_scp.rb +23 -0
- data/test/functional/backends/test_netssh_sftp.rb +23 -0
- data/test/unit/backends/test_abstract.rb +1 -1
- data/test/unit/backends/test_netssh.rb +48 -0
- data/test/unit/test_deprecation_logger.rb +1 -1
- data/test/unit/test_host.rb +27 -0
- metadata +39 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9678c16acec683a599b5cca548346060ba08fd5616e79109af71deac743d33f3
|
4
|
+
data.tar.gz: 6213ece3ddf070a9bf715452da5883f27eb0d3cff81bc5b8a5ccd73f4649c03d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 265bf603d9c5d7557beaf9e33270acb8e626238016f4bd892017ac4cf2afa1a3f7364612c85d10a239c93fc278a2a6fe2904011688fac78e871388b4b9249c0b
|
7
|
+
data.tar.gz: ee46c52f728b8d550182332f88c07dd8b885717afe12291248a6b5a200a3d8180dacc7de863ef3e0ee8f23c264def9dff670cd97e84eea6cfee4d8c3534d2350
|
data/.github/workflows/push.yml
CHANGED
data/EXAMPLES.md
CHANGED
@@ -121,9 +121,6 @@ on hosts do |host|
|
|
121
121
|
end
|
122
122
|
```
|
123
123
|
|
124
|
-
**Note:** The `upload!()` method doesn't honor the values of `as()` etc, this
|
125
|
-
will be improved as the library matures, but we're not there yet.
|
126
|
-
|
127
124
|
## Upload a file from a stream
|
128
125
|
|
129
126
|
```ruby
|
@@ -148,9 +145,6 @@ end
|
|
148
145
|
This spares one from having to figure out the correct escaping sequences for
|
149
146
|
something like "echo(:cat, '...?...', '> /etc/sudoers.d/yolo')".
|
150
147
|
|
151
|
-
**Note:** The `upload!()` method doesn't honor the values of `within()`, `as()`
|
152
|
-
etc, this will be improved as the library matures, but we're not there yet.
|
153
|
-
|
154
148
|
## Upload a directory of files
|
155
149
|
|
156
150
|
```ruby
|
@@ -160,7 +154,25 @@ end
|
|
160
154
|
```
|
161
155
|
|
162
156
|
In this case the `recursive: true` option mirrors the same options which are
|
163
|
-
available to [`Net::
|
157
|
+
available to [`Net::SCP`](https://github.com/net-ssh/net-scp) and
|
158
|
+
[`Net::SFTP`](https://github.com/net-ssh/net-sftp).
|
159
|
+
|
160
|
+
## Set the upload/download method (SCP or SFTP).
|
161
|
+
|
162
|
+
SSHKit can use SCP or SFTP for file transfers. The default is SCP, but this can be changed to SFTP per host:
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
host = SSHKit::Host.new('user@example.com')
|
166
|
+
host.transfer_method = :sftp
|
167
|
+
```
|
168
|
+
|
169
|
+
or globally:
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
SSHKit::Backend::Netssh.configure do |ssh|
|
173
|
+
ssh.transfer_method = :sftp
|
174
|
+
end
|
175
|
+
```
|
164
176
|
|
165
177
|
## Setting global SSH options
|
166
178
|
|
@@ -235,16 +247,16 @@ end
|
|
235
247
|
|
236
248
|
```ruby
|
237
249
|
# The default format is pretty, which outputs colored text
|
238
|
-
SSHKit.config.
|
250
|
+
SSHKit.config.use_format :pretty
|
239
251
|
|
240
252
|
# Text with no coloring
|
241
|
-
SSHKit.config.
|
253
|
+
SSHKit.config.use_format :simpletext
|
242
254
|
|
243
255
|
# Red / Green dots for each completed step
|
244
|
-
SSHKit.config.
|
256
|
+
SSHKit.config.use_format :dot
|
245
257
|
|
246
258
|
# No output
|
247
|
-
SSHKit.config.
|
259
|
+
SSHKit.config.use_format :blackhole
|
248
260
|
```
|
249
261
|
|
250
262
|
## Implement a dirt-simple formatter class
|
@@ -254,7 +266,7 @@ module SSHKit
|
|
254
266
|
module Formatter
|
255
267
|
class MyFormatter < SSHKit::Formatter::Abstract
|
256
268
|
def write(obj)
|
257
|
-
|
269
|
+
if obj.is_a? SSHKit::Command
|
258
270
|
# Do something here, see the SSHKit::Command documentation
|
259
271
|
end
|
260
272
|
end
|
@@ -263,7 +275,7 @@ module SSHKit
|
|
263
275
|
end
|
264
276
|
|
265
277
|
# If your formatter is defined in the SSHKit::Formatter module configure with the format option:
|
266
|
-
SSHKit.config.
|
278
|
+
SSHKit.config.use_format :myformatter
|
267
279
|
|
268
280
|
# Or configure the output directly
|
269
281
|
SSHKit.config.output = MyFormatter.new($stdout)
|
data/README.md
CHANGED
@@ -68,7 +68,8 @@ you can pass the `strip: false` option: `capture(:ls, '-l', strip: false)`
|
|
68
68
|
### Transferring files
|
69
69
|
|
70
70
|
All backends also support the `upload!` and `download!` methods for transferring files.
|
71
|
-
For the remote backend, the file is transferred with scp
|
71
|
+
For the remote backend, the file is transferred with scp by default, but sftp is also
|
72
|
+
supported. See [EXAMPLES.md](EXAMPLES.md) for details.
|
72
73
|
|
73
74
|
```ruby
|
74
75
|
on '1.example.com' do
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "net/scp"
|
2
|
+
|
3
|
+
module SSHKit
|
4
|
+
module Backend
|
5
|
+
class Netssh < Abstract
|
6
|
+
class ScpTransfer
|
7
|
+
def initialize(ssh, summarizer)
|
8
|
+
@ssh = ssh
|
9
|
+
@summarizer = summarizer
|
10
|
+
end
|
11
|
+
|
12
|
+
def upload!(local, remote, options)
|
13
|
+
ssh.scp.upload!(local, remote, options, &summarizer)
|
14
|
+
end
|
15
|
+
|
16
|
+
def download!(remote, local, options)
|
17
|
+
ssh.scp.download!(remote, local, options, &summarizer)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_reader :ssh, :summarizer
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "net/sftp"
|
2
|
+
|
3
|
+
module SSHKit
|
4
|
+
module Backend
|
5
|
+
class Netssh < Abstract
|
6
|
+
class SftpTransfer
|
7
|
+
def initialize(ssh, summarizer)
|
8
|
+
@ssh = ssh
|
9
|
+
@summarizer = summarizer
|
10
|
+
end
|
11
|
+
|
12
|
+
def upload!(local, remote, options)
|
13
|
+
options = { progress: self }.merge(options || {})
|
14
|
+
ssh.sftp.connect!
|
15
|
+
ssh.sftp.upload!(local, remote, options)
|
16
|
+
ensure
|
17
|
+
ssh.sftp.close_channel
|
18
|
+
end
|
19
|
+
|
20
|
+
def download!(remote, local, options)
|
21
|
+
options = { progress: self }.merge(options || {})
|
22
|
+
destination = local ? local : StringIO.new.tap { |io| io.set_encoding('BINARY') }
|
23
|
+
|
24
|
+
ssh.sftp.connect!
|
25
|
+
ssh.sftp.download!(remote, destination, options)
|
26
|
+
local ? true : destination.string
|
27
|
+
ensure
|
28
|
+
ssh.sftp.close_channel
|
29
|
+
end
|
30
|
+
|
31
|
+
def on_get(download, entry, offset, data)
|
32
|
+
entry.size ||= download.sftp.file.open(entry.remote) { |file| file.stat.size }
|
33
|
+
summarizer.call(nil, entry.remote, offset + data.bytesize, entry.size)
|
34
|
+
end
|
35
|
+
|
36
|
+
def on_put(_upload, file, offset, data)
|
37
|
+
summarizer.call(nil, file.local, offset + data.bytesize, file.size)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
attr_reader :ssh, :summarizer
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -2,7 +2,6 @@ require 'English'
|
|
2
2
|
require 'strscan'
|
3
3
|
require 'mutex_m'
|
4
4
|
require 'net/ssh'
|
5
|
-
require 'net/scp'
|
6
5
|
|
7
6
|
module Net
|
8
7
|
module SSH
|
@@ -23,10 +22,27 @@ module SSHKit
|
|
23
22
|
module Backend
|
24
23
|
|
25
24
|
class Netssh < Abstract
|
25
|
+
def self.assert_valid_transfer_method!(method)
|
26
|
+
return if [:scp, :sftp].include?(method)
|
27
|
+
|
28
|
+
raise ArgumentError, "#{method.inspect} is not a valid transfer method. Supported methods are :scp, :sftp."
|
29
|
+
end
|
30
|
+
|
26
31
|
class Configuration
|
27
32
|
attr_accessor :connection_timeout, :pty
|
33
|
+
attr_reader :transfer_method
|
28
34
|
attr_writer :ssh_options
|
29
35
|
|
36
|
+
def initialize
|
37
|
+
self.transfer_method = :scp
|
38
|
+
end
|
39
|
+
|
40
|
+
def transfer_method=(method)
|
41
|
+
Netssh.assert_valid_transfer_method!(method)
|
42
|
+
|
43
|
+
@transfer_method = method
|
44
|
+
end
|
45
|
+
|
30
46
|
def ssh_options
|
31
47
|
default_options.merge(@ssh_options ||= {})
|
32
48
|
end
|
@@ -64,16 +80,16 @@ module SSHKit
|
|
64
80
|
def upload!(local, remote, options = {})
|
65
81
|
summarizer = transfer_summarizer('Uploading', options)
|
66
82
|
remote = File.join(pwd_path, remote) unless remote.to_s.start_with?("/") || pwd_path.nil?
|
67
|
-
|
68
|
-
|
83
|
+
with_transfer(summarizer) do |transfer|
|
84
|
+
transfer.upload!(local, remote, options)
|
69
85
|
end
|
70
86
|
end
|
71
87
|
|
72
88
|
def download!(remote, local=nil, options = {})
|
73
89
|
summarizer = transfer_summarizer('Downloading', options)
|
74
90
|
remote = File.join(pwd_path, remote) unless remote.to_s.start_with?("/") || pwd_path.nil?
|
75
|
-
|
76
|
-
|
91
|
+
with_transfer(summarizer) do |transfer|
|
92
|
+
transfer.download!(remote, local, options)
|
77
93
|
end
|
78
94
|
end
|
79
95
|
|
@@ -105,7 +121,7 @@ module SSHKit
|
|
105
121
|
last_percentage = nil
|
106
122
|
proc do |_ch, name, transferred, total|
|
107
123
|
percentage = (transferred.to_f * 100 / total.to_f)
|
108
|
-
unless percentage.nan?
|
124
|
+
unless percentage.nan? || percentage.infinite?
|
109
125
|
message = "#{action} #{name} #{percentage.round(2)}%"
|
110
126
|
percentage_r = (percentage / log_percent).truncate * log_percent
|
111
127
|
if percentage_r > 0 && (last_name != name || last_percentage != percentage_r)
|
@@ -183,6 +199,20 @@ module SSHKit
|
|
183
199
|
)
|
184
200
|
end
|
185
201
|
|
202
|
+
def with_transfer(summarizer)
|
203
|
+
transfer_method = host.transfer_method || self.class.config.transfer_method
|
204
|
+
transfer_class = if transfer_method == :sftp
|
205
|
+
require_relative "netssh/sftp_transfer"
|
206
|
+
SftpTransfer
|
207
|
+
else
|
208
|
+
require_relative "netssh/scp_transfer"
|
209
|
+
ScpTransfer
|
210
|
+
end
|
211
|
+
|
212
|
+
with_ssh do |ssh|
|
213
|
+
yield(transfer_class.new(ssh, summarizer))
|
214
|
+
end
|
215
|
+
end
|
186
216
|
end
|
187
217
|
end
|
188
218
|
|
data/lib/sshkit/host.rb
CHANGED
@@ -7,6 +7,7 @@ module SSHKit
|
|
7
7
|
class Host
|
8
8
|
|
9
9
|
attr_accessor :password, :hostname, :port, :user, :ssh_options
|
10
|
+
attr_reader :transfer_method
|
10
11
|
|
11
12
|
def key=(new_key)
|
12
13
|
@keys = [new_key]
|
@@ -41,6 +42,12 @@ module SSHKit
|
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
45
|
+
def transfer_method=(method)
|
46
|
+
Backend::Netssh.assert_valid_transfer_method!(method) unless method.nil?
|
47
|
+
|
48
|
+
@transfer_method = method
|
49
|
+
end
|
50
|
+
|
44
51
|
def local?
|
45
52
|
@local
|
46
53
|
end
|
data/lib/sshkit/version.rb
CHANGED
data/sshkit.gemspec
CHANGED
@@ -20,9 +20,11 @@ Gem::Specification.new do |gem|
|
|
20
20
|
gem.require_paths = ["lib"]
|
21
21
|
gem.version = SSHKit::VERSION
|
22
22
|
|
23
|
+
gem.add_runtime_dependency('base64') if RUBY_VERSION >= "2.4"
|
23
24
|
gem.add_runtime_dependency('mutex_m')
|
24
25
|
gem.add_runtime_dependency('net-ssh', '>= 2.8.0')
|
25
26
|
gem.add_runtime_dependency('net-scp', '>= 1.1.2')
|
27
|
+
gem.add_runtime_dependency('net-sftp', '>= 2.1.2')
|
26
28
|
|
27
29
|
gem.add_development_dependency('danger')
|
28
30
|
gem.add_development_dependency('minitest', '>= 5.0.0')
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module SSHKit
|
4
|
+
module Backend
|
5
|
+
module NetsshTransferTests
|
6
|
+
def setup
|
7
|
+
super
|
8
|
+
@output = String.new
|
9
|
+
SSHKit.config.output_verbosity = :debug
|
10
|
+
SSHKit.config.output = SSHKit::Formatter::SimpleText.new(@output)
|
11
|
+
end
|
12
|
+
|
13
|
+
def a_host
|
14
|
+
VagrantWrapper.hosts['one']
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_upload_and_then_capture_file_contents
|
18
|
+
actual_file_contents = ""
|
19
|
+
file_name = File.join("/tmp", SecureRandom.uuid)
|
20
|
+
File.open file_name, 'w+' do |f|
|
21
|
+
f.write "Some Content\nWith a newline and trailing spaces \n "
|
22
|
+
end
|
23
|
+
Netssh.new(a_host) do
|
24
|
+
upload!(file_name, file_name)
|
25
|
+
actual_file_contents = capture(:cat, file_name, strip: false)
|
26
|
+
end.run
|
27
|
+
assert_equal "Some Content\nWith a newline and trailing spaces \n ", actual_file_contents
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_upload_within
|
31
|
+
file_name = SecureRandom.uuid
|
32
|
+
file_contents = "Some Content"
|
33
|
+
dir_name = SecureRandom.uuid
|
34
|
+
actual_file_contents = ""
|
35
|
+
Netssh.new(a_host) do |_host|
|
36
|
+
within("/tmp") do
|
37
|
+
execute :mkdir, "-p", dir_name
|
38
|
+
within(dir_name) do
|
39
|
+
upload!(StringIO.new(file_contents), file_name)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
actual_file_contents = capture(:cat, "/tmp/#{dir_name}/#{file_name}", strip: false)
|
43
|
+
end.run
|
44
|
+
assert_equal file_contents, actual_file_contents
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_upload_string_io
|
48
|
+
file_contents = ""
|
49
|
+
Netssh.new(a_host) do |_host|
|
50
|
+
file_name = File.join("/tmp", SecureRandom.uuid)
|
51
|
+
upload!(StringIO.new('example_io'), file_name)
|
52
|
+
file_contents = download!(file_name)
|
53
|
+
end.run
|
54
|
+
assert_equal "example_io", file_contents
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_upload_large_file
|
58
|
+
size = 25
|
59
|
+
fills = SecureRandom.random_bytes(1024*1024)
|
60
|
+
file_name = "/tmp/file-#{size}.txt"
|
61
|
+
File.open(file_name, 'wb') do |f|
|
62
|
+
(size).times {f.write(fills) }
|
63
|
+
end
|
64
|
+
file_contents = ""
|
65
|
+
Netssh.new(a_host) do
|
66
|
+
upload!(file_name, file_name)
|
67
|
+
file_contents = download!(file_name)
|
68
|
+
end.run
|
69
|
+
assert_equal File.open(file_name, 'rb').read, file_contents
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_upload_via_pathname
|
73
|
+
file_contents = ""
|
74
|
+
Netssh.new(a_host) do |_host|
|
75
|
+
file_name = Pathname.new(File.join("/tmp", SecureRandom.uuid))
|
76
|
+
upload!(StringIO.new('example_io'), file_name)
|
77
|
+
file_contents = download!(file_name)
|
78
|
+
end.run
|
79
|
+
assert_equal "example_io", file_contents
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'helper'
|
2
|
-
require 'securerandom'
|
3
2
|
require 'benchmark'
|
4
3
|
|
5
4
|
module SSHKit
|
@@ -136,71 +135,6 @@ module SSHKit
|
|
136
135
|
end.run
|
137
136
|
end
|
138
137
|
|
139
|
-
def test_upload_and_then_capture_file_contents
|
140
|
-
actual_file_contents = ""
|
141
|
-
file_name = File.join("/tmp", SecureRandom.uuid)
|
142
|
-
File.open file_name, 'w+' do |f|
|
143
|
-
f.write "Some Content\nWith a newline and trailing spaces \n "
|
144
|
-
end
|
145
|
-
Netssh.new(a_host) do
|
146
|
-
upload!(file_name, file_name)
|
147
|
-
actual_file_contents = capture(:cat, file_name, strip: false)
|
148
|
-
end.run
|
149
|
-
assert_equal "Some Content\nWith a newline and trailing spaces \n ", actual_file_contents
|
150
|
-
end
|
151
|
-
|
152
|
-
def test_upload_within
|
153
|
-
file_name = SecureRandom.uuid
|
154
|
-
file_contents = "Some Content"
|
155
|
-
dir_name = SecureRandom.uuid
|
156
|
-
actual_file_contents = ""
|
157
|
-
Netssh.new(a_host) do |_host|
|
158
|
-
within("/tmp") do
|
159
|
-
execute :mkdir, "-p", dir_name
|
160
|
-
within(dir_name) do
|
161
|
-
upload!(StringIO.new(file_contents), file_name)
|
162
|
-
end
|
163
|
-
end
|
164
|
-
actual_file_contents = capture(:cat, "/tmp/#{dir_name}/#{file_name}", strip: false)
|
165
|
-
end.run
|
166
|
-
assert_equal file_contents, actual_file_contents
|
167
|
-
end
|
168
|
-
|
169
|
-
def test_upload_string_io
|
170
|
-
file_contents = ""
|
171
|
-
Netssh.new(a_host) do |_host|
|
172
|
-
file_name = File.join("/tmp", SecureRandom.uuid)
|
173
|
-
upload!(StringIO.new('example_io'), file_name)
|
174
|
-
file_contents = download!(file_name)
|
175
|
-
end.run
|
176
|
-
assert_equal "example_io", file_contents
|
177
|
-
end
|
178
|
-
|
179
|
-
def test_upload_large_file
|
180
|
-
size = 25
|
181
|
-
fills = SecureRandom.random_bytes(1024*1024)
|
182
|
-
file_name = "/tmp/file-#{size}.txt"
|
183
|
-
File.open(file_name, 'wb') do |f|
|
184
|
-
(size).times {f.write(fills) }
|
185
|
-
end
|
186
|
-
file_contents = ""
|
187
|
-
Netssh.new(a_host) do
|
188
|
-
upload!(file_name, file_name)
|
189
|
-
file_contents = download!(file_name)
|
190
|
-
end.run
|
191
|
-
assert_equal File.open(file_name, 'rb').read, file_contents
|
192
|
-
end
|
193
|
-
|
194
|
-
def test_upload_via_pathname
|
195
|
-
file_contents = ""
|
196
|
-
Netssh.new(a_host) do |_host|
|
197
|
-
file_name = Pathname.new(File.join("/tmp", SecureRandom.uuid))
|
198
|
-
upload!(StringIO.new('example_io'), file_name)
|
199
|
-
file_contents = download!(file_name)
|
200
|
-
end.run
|
201
|
-
assert_equal "example_io", file_contents
|
202
|
-
end
|
203
|
-
|
204
138
|
def test_interaction_handler
|
205
139
|
captured_command_result = nil
|
206
140
|
Netssh.new(a_host) do
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require_relative 'netssh_transfer_tests'
|
3
|
+
|
4
|
+
module SSHKit
|
5
|
+
module Backend
|
6
|
+
class TestNetsshScp < FunctionalTest
|
7
|
+
include NetsshTransferTests
|
8
|
+
|
9
|
+
def setup
|
10
|
+
super
|
11
|
+
SSHKit::Backend::Netssh.configure do |ssh|
|
12
|
+
ssh.transfer_method = :scp
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_scp_implementation_is_used
|
17
|
+
Netssh.new(a_host).send(:with_transfer, nil) do |transfer|
|
18
|
+
assert_instance_of Netssh::ScpTransfer, transfer
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require_relative 'netssh_transfer_tests'
|
3
|
+
|
4
|
+
module SSHKit
|
5
|
+
module Backend
|
6
|
+
class TestNetsshSftp < FunctionalTest
|
7
|
+
include NetsshTransferTests
|
8
|
+
|
9
|
+
def setup
|
10
|
+
super
|
11
|
+
SSHKit::Backend::Netssh.configure do |ssh|
|
12
|
+
ssh.transfer_method = :sftp
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_sftp_implementation_is_used
|
17
|
+
Netssh.new(a_host).send(:with_transfer, nil) do |transfer|
|
18
|
+
assert_instance_of Netssh::SftpTransfer, transfer
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -124,7 +124,7 @@ module SSHKit
|
|
124
124
|
assert_equal 2, lines.length
|
125
125
|
|
126
126
|
assert_equal("[Deprecated] The background method is deprecated. Blame badly behaved pseudo-daemons!\n", lines[0])
|
127
|
-
assert_match(/ \(Called from.*test_abstract.rb:\d+:in
|
127
|
+
assert_match(/ \(Called from.*test_abstract.rb:\d+:in .block in .*test_background_logs_deprecation_warnings.\)\n/, lines[1])
|
128
128
|
end
|
129
129
|
|
130
130
|
def test_calling_abstract_with_undefined_execute_command_raises_exception
|
@@ -5,6 +5,12 @@ module SSHKit
|
|
5
5
|
module Backend
|
6
6
|
class TestNetssh < UnitTest
|
7
7
|
|
8
|
+
def teardown
|
9
|
+
super
|
10
|
+
# Reset config to defaults after each test
|
11
|
+
backend.instance_variable_set :@config, nil
|
12
|
+
end
|
13
|
+
|
8
14
|
def backend
|
9
15
|
@backend ||= Netssh
|
10
16
|
end
|
@@ -13,6 +19,7 @@ module SSHKit
|
|
13
19
|
backend.configure do |ssh|
|
14
20
|
ssh.pty = true
|
15
21
|
ssh.connection_timeout = 30
|
22
|
+
ssh.transfer_method = :sftp
|
16
23
|
ssh.ssh_options = {
|
17
24
|
keys: %w(/home/user/.ssh/id_rsa),
|
18
25
|
forward_agent: false,
|
@@ -21,6 +28,7 @@ module SSHKit
|
|
21
28
|
end
|
22
29
|
|
23
30
|
assert_equal 30, backend.config.connection_timeout
|
31
|
+
assert_equal :sftp, backend.config.transfer_method
|
24
32
|
assert_equal true, backend.config.pty
|
25
33
|
|
26
34
|
assert_equal %w(/home/user/.ssh/id_rsa), backend.config.ssh_options[:keys]
|
@@ -29,6 +37,46 @@ module SSHKit
|
|
29
37
|
assert_instance_of backend::KnownHosts, backend.config.ssh_options[:known_hosts]
|
30
38
|
end
|
31
39
|
|
40
|
+
def test_transfer_method_prohibits_invalid_values
|
41
|
+
error = assert_raises ArgumentError do
|
42
|
+
backend.configure do |ssh|
|
43
|
+
ssh.transfer_method = :nope
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
assert_match ":nope is not a valid transfer method", error.message
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_transfer_method_does_not_allow_nil
|
51
|
+
error = assert_raises ArgumentError do
|
52
|
+
backend.configure do |ssh|
|
53
|
+
ssh.transfer_method = nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
assert_match "nil is not a valid transfer method", error.message
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_transfer_method_defaults_to_scp
|
61
|
+
assert_equal :scp, backend.config.transfer_method
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_host_can_override_transfer_method
|
65
|
+
backend.configure do |ssh|
|
66
|
+
ssh.transfer_method = :scp
|
67
|
+
end
|
68
|
+
|
69
|
+
host = Host.new("fake")
|
70
|
+
host.transfer_method = :sftp
|
71
|
+
|
72
|
+
netssh = backend.new(host)
|
73
|
+
netssh.stubs(:with_ssh).yields(nil)
|
74
|
+
|
75
|
+
netssh.send(:with_transfer, nil) do |transfer|
|
76
|
+
assert_instance_of Netssh::SftpTransfer, transfer
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
32
80
|
def test_netssh_ext
|
33
81
|
assert_includes Net::SSH::Config.default_files, "#{Dir.pwd}/.ssh/config"
|
34
82
|
end
|
@@ -20,7 +20,7 @@ module SSHKit
|
|
20
20
|
|
21
21
|
assert_equal(2, actual_lines.size)
|
22
22
|
assert_equal "[Deprecated] Some message\n", actual_lines[0]
|
23
|
-
assert_match %r{ \(Called from .*sshkit/test/unit/test_deprecation_logger.rb:#{line_number}:in
|
23
|
+
assert_match %r{ \(Called from .*sshkit/test/unit/test_deprecation_logger.rb:#{line_number}:in .*generate_warning.\)\n}, actual_lines[1]
|
24
24
|
end
|
25
25
|
|
26
26
|
def test_handles_nil_output
|
data/test/unit/test_host.rb
CHANGED
@@ -142,6 +142,33 @@ module SSHKit
|
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
145
|
+
def test_transfer_method_defaults_to_nil
|
146
|
+
host = Host.new 'example.com'
|
147
|
+
assert_nil host.transfer_method
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_transfer_method_can_be_configured
|
151
|
+
host = Host.new 'example.com'
|
152
|
+
|
153
|
+
host.transfer_method = :scp
|
154
|
+
assert_equal :scp, host.transfer_method
|
155
|
+
|
156
|
+
host.transfer_method = :sftp
|
157
|
+
assert_equal :sftp, host.transfer_method
|
158
|
+
|
159
|
+
host.transfer_method = nil
|
160
|
+
assert_nil host.transfer_method
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_transfer_method_prohibits_invalid_values
|
164
|
+
host = Host.new 'example.com'
|
165
|
+
|
166
|
+
error = assert_raises ArgumentError do
|
167
|
+
host.transfer_method = :nope
|
168
|
+
end
|
169
|
+
|
170
|
+
assert_match ":nope is not a valid transfer method", error.message
|
171
|
+
end
|
145
172
|
end
|
146
173
|
|
147
174
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sshkit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.22.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lee Hambley
|
@@ -9,8 +9,22 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2024-04-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: base64
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
14
28
|
- !ruby/object:Gem::Dependency
|
15
29
|
name: mutex_m
|
16
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,6 +67,20 @@ dependencies:
|
|
53
67
|
- - ">="
|
54
68
|
- !ruby/object:Gem::Version
|
55
69
|
version: 1.1.2
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: net-sftp
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 2.1.2
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 2.1.2
|
56
84
|
- !ruby/object:Gem::Dependency
|
57
85
|
name: danger
|
58
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -228,6 +256,8 @@ files:
|
|
228
256
|
- lib/sshkit/backends/local.rb
|
229
257
|
- lib/sshkit/backends/netssh.rb
|
230
258
|
- lib/sshkit/backends/netssh/known_hosts.rb
|
259
|
+
- lib/sshkit/backends/netssh/scp_transfer.rb
|
260
|
+
- lib/sshkit/backends/netssh/sftp_transfer.rb
|
231
261
|
- lib/sshkit/backends/printer.rb
|
232
262
|
- lib/sshkit/backends/skipper.rb
|
233
263
|
- lib/sshkit/color.rb
|
@@ -255,8 +285,11 @@ files:
|
|
255
285
|
- lib/sshkit/version.rb
|
256
286
|
- sshkit.gemspec
|
257
287
|
- test/boxes.json
|
288
|
+
- test/functional/backends/netssh_transfer_tests.rb
|
258
289
|
- test/functional/backends/test_local.rb
|
259
290
|
- test/functional/backends/test_netssh.rb
|
291
|
+
- test/functional/backends/test_netssh_scp.rb
|
292
|
+
- test/functional/backends/test_netssh_sftp.rb
|
260
293
|
- test/functional/test_ssh_server_comes_up_for_functional_tests.rb
|
261
294
|
- test/helper.rb
|
262
295
|
- test/known_hosts/github
|
@@ -305,14 +338,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
305
338
|
- !ruby/object:Gem::Version
|
306
339
|
version: '0'
|
307
340
|
requirements: []
|
308
|
-
rubygems_version: 3.5.
|
341
|
+
rubygems_version: 3.5.6
|
309
342
|
signing_key:
|
310
343
|
specification_version: 4
|
311
344
|
summary: SSHKit makes it easy to write structured, testable SSH commands in Ruby
|
312
345
|
test_files:
|
313
346
|
- test/boxes.json
|
347
|
+
- test/functional/backends/netssh_transfer_tests.rb
|
314
348
|
- test/functional/backends/test_local.rb
|
315
349
|
- test/functional/backends/test_netssh.rb
|
350
|
+
- test/functional/backends/test_netssh_scp.rb
|
351
|
+
- test/functional/backends/test_netssh_sftp.rb
|
316
352
|
- test/functional/test_ssh_server_comes_up_for_functional_tests.rb
|
317
353
|
- test/helper.rb
|
318
354
|
- test/known_hosts/github
|