sshkit 1.21.5 → 1.23.0
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/.docker/Dockerfile +6 -0
- data/.docker/ubuntu_setup.sh +22 -0
- data/.github/release-drafter.yml +10 -2
- data/.github/workflows/ci.yml +19 -34
- data/.github/workflows/push.yml +1 -1
- data/.gitignore +0 -1
- data/.rubocop_todo.yml +0 -7
- data/CONTRIBUTING.md +2 -2
- data/EXAMPLES.md +25 -13
- data/README.md +2 -1
- data/RELEASING.md +1 -1
- data/Rakefile +0 -4
- data/docker-compose.yml +8 -0
- data/lib/sshkit/backends/connection_pool/cache.rb +2 -2
- data/lib/sshkit/backends/netssh/known_hosts.rb +8 -8
- 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 -7
- data/lib/sshkit/host.rb +25 -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 +1 -67
- data/test/functional/backends/test_netssh_scp.rb +23 -0
- data/test/functional/backends/test_netssh_sftp.rb +23 -0
- data/test/helper.rb +4 -42
- data/test/support/docker_wrapper.rb +71 -0
- data/test/unit/backends/test_abstract.rb +1 -1
- data/test/unit/backends/test_netssh.rb +48 -0
- data/test/unit/test_command_map.rb +8 -8
- data/test/unit/test_deprecation_logger.rb +1 -1
- data/test/unit/test_host.rb +39 -0
- metadata +44 -10
- data/Vagrantfile +0 -24
- data/test/boxes.json +0 -17
- data/test/functional/test_ssh_server_comes_up_for_functional_tests.rb +0 -24
- data/test/support/vagrant_wrapper.rb +0 -64
@@ -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
|
+
DockerWrapper.host
|
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
|
@@ -16,7 +15,7 @@ module SSHKit
|
|
16
15
|
end
|
17
16
|
|
18
17
|
def a_host
|
19
|
-
|
18
|
+
DockerWrapper.host
|
20
19
|
end
|
21
20
|
|
22
21
|
def test_simple_netssh
|
@@ -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
|
data/test/helper.rb
CHANGED
@@ -28,51 +28,13 @@ class UnitTest < Minitest::Test
|
|
28
28
|
end
|
29
29
|
|
30
30
|
class FunctionalTest < Minitest::Test
|
31
|
-
|
32
31
|
def setup
|
33
|
-
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def create_user_with_key(username, password = :secret)
|
41
|
-
username, password = username.to_s, password.to_s
|
42
|
-
|
43
|
-
keys = VagrantWrapper.hosts.collect do |_name, host|
|
44
|
-
Net::SSH.start(host.hostname, host.user, port: host.port, password: host.password) do |ssh|
|
45
|
-
|
46
|
-
# Remove the user, make it again, force-generate a key for him
|
47
|
-
# short keys save us a few microseconds
|
48
|
-
ssh.exec!("sudo userdel -rf #{username}; true") # The `rescue nil` of the shell world
|
49
|
-
ssh.exec!("sudo useradd -m #{username}")
|
50
|
-
ssh.exec!("sudo echo y | ssh-keygen -b 1024 -f #{username} -N ''")
|
51
|
-
ssh.exec!("sudo chown vagrant:vagrant #{username}*")
|
52
|
-
ssh.exec!("sudo echo #{username}:#{password} | chpasswd")
|
32
|
+
require_relative "support/docker_wrapper"
|
33
|
+
return if DockerWrapper.running?
|
53
34
|
|
54
|
-
|
55
|
-
|
56
|
-
ssh.exec!("sudo chown #{username}:#{username} /home/#{username}/.ssh")
|
57
|
-
ssh.exec!("sudo chmod 700 /home/#{username}/.ssh")
|
58
|
-
|
59
|
-
# Move the key to authorized keys and chown and chmod it
|
60
|
-
ssh.exec!("sudo cat #{username}.pub > /home/#{username}/.ssh/authorized_keys")
|
61
|
-
ssh.exec!("sudo chown #{username}:#{username} /home/#{username}/.ssh/authorized_keys")
|
62
|
-
ssh.exec!("sudo chmod 600 /home/#{username}/.ssh/authorized_keys")
|
63
|
-
|
64
|
-
key = ssh.exec!("cat /home/vagrant/#{username}")
|
65
|
-
|
66
|
-
# Clean Up Files
|
67
|
-
ssh.exec!("sudo rm #{username} #{username}.pub")
|
68
|
-
|
69
|
-
key
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
Hash[VagrantWrapper.hosts.collect { |n, _h| n.to_sym }.zip(keys)]
|
35
|
+
DockerWrapper.start
|
36
|
+
DockerWrapper.wait_for_ssh_server
|
74
37
|
end
|
75
|
-
|
76
38
|
end
|
77
39
|
|
78
40
|
#
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require "socket"
|
2
|
+
|
3
|
+
Minitest.after_run do
|
4
|
+
DockerWrapper.stop if DockerWrapper.running?
|
5
|
+
end
|
6
|
+
|
7
|
+
module DockerWrapper
|
8
|
+
SSH_SERVER_PORT = 2122
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def host
|
12
|
+
SSHKit::Host.new(
|
13
|
+
user: "deployer",
|
14
|
+
hostname: "localhost",
|
15
|
+
port: SSH_SERVER_PORT,
|
16
|
+
password: "topsecret",
|
17
|
+
ssh_options: host_verify_options
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def running?
|
22
|
+
out, status = run_compose_command("ps --status running", false)
|
23
|
+
status.success? && out.include?("ssh_server")
|
24
|
+
end
|
25
|
+
|
26
|
+
def start
|
27
|
+
run_compose_command("up -d")
|
28
|
+
end
|
29
|
+
|
30
|
+
def stop
|
31
|
+
run_compose_command("down")
|
32
|
+
end
|
33
|
+
|
34
|
+
def wait_for_ssh_server(retries=3)
|
35
|
+
Socket.tcp("localhost", SSH_SERVER_PORT, connect_timeout: 1).close
|
36
|
+
sleep(1)
|
37
|
+
rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT
|
38
|
+
retries -= 1
|
39
|
+
sleep(2) && retry if retries.positive?
|
40
|
+
raise
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def run_compose_command(command, echo=true)
|
46
|
+
$stderr.puts "[docker compose] #{command}" if echo
|
47
|
+
Open3.popen2e("docker compose #{command}") do |stdin, outerr, wait_thread|
|
48
|
+
stdin.close
|
49
|
+
output = Thread.new { capture_stream(outerr, echo) }
|
50
|
+
[output.value, wait_thread.value]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def capture_stream(stream, echo=true)
|
55
|
+
buffer = String.new
|
56
|
+
while (line = stream.gets)
|
57
|
+
buffer << line
|
58
|
+
$stderr.puts("[docker compose] #{line}") if echo
|
59
|
+
end
|
60
|
+
buffer
|
61
|
+
end
|
62
|
+
|
63
|
+
def host_verify_options
|
64
|
+
if Net::SSH::Version::MAJOR >= 5
|
65
|
+
{ verify_host_key: :never }
|
66
|
+
else
|
67
|
+
{ paranoid: false }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
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
|
@@ -27,26 +27,26 @@ module SSHKit
|
|
27
27
|
|
28
28
|
def test_prefix
|
29
29
|
map = CommandMap.new
|
30
|
-
map.prefix[:rake].push("/home/
|
30
|
+
map.prefix[:rake].push("/home/deployer/.rbenv/bin/rbenv exec")
|
31
31
|
map.prefix[:rake].push("bundle exec")
|
32
32
|
|
33
|
-
assert_equal map[:rake], "/home/
|
33
|
+
assert_equal map[:rake], "/home/deployer/.rbenv/bin/rbenv exec bundle exec rake"
|
34
34
|
end
|
35
35
|
|
36
36
|
def test_prefix_procs
|
37
37
|
map = CommandMap.new
|
38
|
-
map.prefix[:rake].push("/home/
|
38
|
+
map.prefix[:rake].push("/home/deployer/.rbenv/bin/rbenv exec")
|
39
39
|
map.prefix[:rake].push(proc{ "bundle exec" })
|
40
40
|
|
41
|
-
assert_equal map[:rake], "/home/
|
41
|
+
assert_equal map[:rake], "/home/deployer/.rbenv/bin/rbenv exec bundle exec rake"
|
42
42
|
end
|
43
43
|
|
44
44
|
def test_prefix_unshift
|
45
45
|
map = CommandMap.new
|
46
46
|
map.prefix[:rake].push("bundle exec")
|
47
|
-
map.prefix[:rake].unshift("/home/
|
47
|
+
map.prefix[:rake].unshift("/home/deployer/.rbenv/bin/rbenv exec")
|
48
48
|
|
49
|
-
assert_equal map[:rake], "/home/
|
49
|
+
assert_equal map[:rake], "/home/deployer/.rbenv/bin/rbenv exec bundle exec rake"
|
50
50
|
end
|
51
51
|
|
52
52
|
def test_indifferent_setter
|
@@ -59,10 +59,10 @@ module SSHKit
|
|
59
59
|
|
60
60
|
def test_indifferent_prefix
|
61
61
|
map = CommandMap.new
|
62
|
-
map.prefix[:rake].push("/home/
|
62
|
+
map.prefix[:rake].push("/home/deployer/.rbenv/bin/rbenv exec")
|
63
63
|
map.prefix["rake"].push("bundle exec")
|
64
64
|
|
65
|
-
assert_equal map[:rake], "/home/
|
65
|
+
assert_equal map[:rake], "/home/deployer/.rbenv/bin/rbenv exec bundle exec rake"
|
66
66
|
end
|
67
67
|
|
68
68
|
def test_prefix_initialization_is_thread_safe
|
@@ -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
@@ -28,6 +28,12 @@ module SSHKit
|
|
28
28
|
assert_equal 'example.com', h.hostname
|
29
29
|
end
|
30
30
|
|
31
|
+
def test_custom_host_with_port
|
32
|
+
h = Host.new 'db:22'
|
33
|
+
assert_equal 22, h.port
|
34
|
+
assert_equal 'db', h.hostname
|
35
|
+
end
|
36
|
+
|
31
37
|
def test_host_with_username
|
32
38
|
h = Host.new 'root@example.com'
|
33
39
|
assert_equal 'root', h.username
|
@@ -50,6 +56,12 @@ module SSHKit
|
|
50
56
|
assert_equal 'localhost', h.hostname
|
51
57
|
end
|
52
58
|
|
59
|
+
def test_ipv6_without_brackets
|
60
|
+
h = Host.new '1fff:0:a88:85a3::ac1f'
|
61
|
+
assert_nil h.port
|
62
|
+
assert_equal '1fff:0:a88:85a3::ac1f', h.hostname
|
63
|
+
end
|
64
|
+
|
53
65
|
def test_does_not_confuse_ipv6_hosts_with_port_specification
|
54
66
|
h = Host.new '[1fff:0:a88:85a3::ac1f]:8001'
|
55
67
|
assert_equal 8001, h.port
|
@@ -142,6 +154,33 @@ module SSHKit
|
|
142
154
|
end
|
143
155
|
end
|
144
156
|
|
157
|
+
def test_transfer_method_defaults_to_nil
|
158
|
+
host = Host.new 'example.com'
|
159
|
+
assert_nil host.transfer_method
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_transfer_method_can_be_configured
|
163
|
+
host = Host.new 'example.com'
|
164
|
+
|
165
|
+
host.transfer_method = :scp
|
166
|
+
assert_equal :scp, host.transfer_method
|
167
|
+
|
168
|
+
host.transfer_method = :sftp
|
169
|
+
assert_equal :sftp, host.transfer_method
|
170
|
+
|
171
|
+
host.transfer_method = nil
|
172
|
+
assert_nil host.transfer_method
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_transfer_method_prohibits_invalid_values
|
176
|
+
host = Host.new 'example.com'
|
177
|
+
|
178
|
+
error = assert_raises ArgumentError do
|
179
|
+
host.transfer_method = :nope
|
180
|
+
end
|
181
|
+
|
182
|
+
assert_match ":nope is not a valid transfer method", error.message
|
183
|
+
end
|
145
184
|
end
|
146
185
|
|
147
186
|
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.23.0
|
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-06-23 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: net-ssh
|
16
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,6 +53,20 @@ dependencies:
|
|
39
53
|
- - ">="
|
40
54
|
- !ruby/object:Gem::Version
|
41
55
|
version: 1.1.2
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: net-sftp
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 2.1.2
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 2.1.2
|
42
70
|
- !ruby/object:Gem::Dependency
|
43
71
|
name: danger
|
44
72
|
requirement: !ruby/object:Gem::Requirement
|
@@ -180,6 +208,8 @@ executables: []
|
|
180
208
|
extensions: []
|
181
209
|
extra_rdoc_files: []
|
182
210
|
files:
|
211
|
+
- ".docker/Dockerfile"
|
212
|
+
- ".docker/ubuntu_setup.sh"
|
183
213
|
- ".github/dependabot.yml"
|
184
214
|
- ".github/release-drafter.yml"
|
185
215
|
- ".github/workflows/ci.yml"
|
@@ -199,7 +229,7 @@ files:
|
|
199
229
|
- README.md
|
200
230
|
- RELEASING.md
|
201
231
|
- Rakefile
|
202
|
-
-
|
232
|
+
- docker-compose.yml
|
203
233
|
- examples/images/example_output.png
|
204
234
|
- examples/images/logo.png
|
205
235
|
- examples/simple_connection.rb
|
@@ -214,6 +244,8 @@ files:
|
|
214
244
|
- lib/sshkit/backends/local.rb
|
215
245
|
- lib/sshkit/backends/netssh.rb
|
216
246
|
- lib/sshkit/backends/netssh/known_hosts.rb
|
247
|
+
- lib/sshkit/backends/netssh/scp_transfer.rb
|
248
|
+
- lib/sshkit/backends/netssh/sftp_transfer.rb
|
217
249
|
- lib/sshkit/backends/printer.rb
|
218
250
|
- lib/sshkit/backends/skipper.rb
|
219
251
|
- lib/sshkit/color.rb
|
@@ -240,15 +272,16 @@ files:
|
|
240
272
|
- lib/sshkit/runners/sequential.rb
|
241
273
|
- lib/sshkit/version.rb
|
242
274
|
- sshkit.gemspec
|
243
|
-
- test/
|
275
|
+
- test/functional/backends/netssh_transfer_tests.rb
|
244
276
|
- test/functional/backends/test_local.rb
|
245
277
|
- test/functional/backends/test_netssh.rb
|
246
|
-
- test/functional/
|
278
|
+
- test/functional/backends/test_netssh_scp.rb
|
279
|
+
- test/functional/backends/test_netssh_sftp.rb
|
247
280
|
- test/helper.rb
|
248
281
|
- test/known_hosts/github
|
249
282
|
- test/known_hosts/github_hash
|
250
283
|
- test/known_hosts/github_ip
|
251
|
-
- test/support/
|
284
|
+
- test/support/docker_wrapper.rb
|
252
285
|
- test/unit/backends/test_abstract.rb
|
253
286
|
- test/unit/backends/test_connection_pool.rb
|
254
287
|
- test/unit/backends/test_local.rb
|
@@ -291,20 +324,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
291
324
|
- !ruby/object:Gem::Version
|
292
325
|
version: '0'
|
293
326
|
requirements: []
|
294
|
-
rubygems_version: 3.
|
327
|
+
rubygems_version: 3.5.13
|
295
328
|
signing_key:
|
296
329
|
specification_version: 4
|
297
330
|
summary: SSHKit makes it easy to write structured, testable SSH commands in Ruby
|
298
331
|
test_files:
|
299
|
-
- test/
|
332
|
+
- test/functional/backends/netssh_transfer_tests.rb
|
300
333
|
- test/functional/backends/test_local.rb
|
301
334
|
- test/functional/backends/test_netssh.rb
|
302
|
-
- test/functional/
|
335
|
+
- test/functional/backends/test_netssh_scp.rb
|
336
|
+
- test/functional/backends/test_netssh_sftp.rb
|
303
337
|
- test/helper.rb
|
304
338
|
- test/known_hosts/github
|
305
339
|
- test/known_hosts/github_hash
|
306
340
|
- test/known_hosts/github_ip
|
307
|
-
- test/support/
|
341
|
+
- test/support/docker_wrapper.rb
|
308
342
|
- test/unit/backends/test_abstract.rb
|
309
343
|
- test/unit/backends/test_connection_pool.rb
|
310
344
|
- test/unit/backends/test_local.rb
|