sshkit 1.22.1 → 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 +27 -0
- data/.gitignore +0 -1
- data/.rubocop_todo.yml +0 -7
- data/CONTRIBUTING.md +2 -2
- 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 +5 -7
- data/lib/sshkit/backends/netssh.rb +0 -1
- data/lib/sshkit/host.rb +18 -0
- data/lib/sshkit/version.rb +1 -1
- data/sshkit.gemspec +0 -1
- data/test/functional/backends/netssh_transfer_tests.rb +1 -1
- data/test/functional/backends/test_netssh.rb +1 -1
- data/test/helper.rb +4 -42
- data/test/support/docker_wrapper.rb +71 -0
- data/test/unit/test_command_map.rb +8 -8
- data/test/unit/test_host.rb +12 -0
- metadata +8 -24
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f40ad7a1382ef707a259094c945692f08c44392e0bba7c37fe4099e748301a5e
|
4
|
+
data.tar.gz: 72f3fea395eaaa0036dd701c04692e75c379867465cffaa4ac6cdf1c4f647813
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab28074eba7cb9bdbfcbca9857f5e74fc89ed06acdf872148fcb7329b45754a714c658dacd879fead076de3bbd2541d84bcfd8ef66369007a1444b3edc2b3ac3
|
7
|
+
data.tar.gz: a6d0deb01db101ba2a41dcfcd861a10c7604b17ebe5e25981eebe6d74a0b5c9a9ea345d2dcbb45a4ba30952b571b6736f3bdcd7721d7d8fe684db772cc723700
|
data/.docker/Dockerfile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
export DEBIAN_FRONTEND=noninteractive
|
6
|
+
apt -y update
|
7
|
+
|
8
|
+
# Create `deployer` user that can sudo without a password
|
9
|
+
apt-get -y install sudo
|
10
|
+
adduser --disabled-password deployer < /dev/null
|
11
|
+
echo "deployer:topsecret" | chpasswd
|
12
|
+
echo "deployer ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
13
|
+
|
14
|
+
# Install and configure sshd
|
15
|
+
apt-get -y install openssh-server
|
16
|
+
{
|
17
|
+
echo "Port 22"
|
18
|
+
echo "PasswordAuthentication yes"
|
19
|
+
echo "ChallengeResponseAuthentication no"
|
20
|
+
} >> /etc/ssh/sshd_config
|
21
|
+
mkdir /var/run/sshd
|
22
|
+
chmod 0755 /var/run/sshd
|
data/.github/release-drafter.yml
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
name-template: "$
|
2
|
-
tag-template: "v$
|
1
|
+
name-template: "$RESOLVED_VERSION"
|
2
|
+
tag-template: "v$RESOLVED_VERSION"
|
3
3
|
categories:
|
4
4
|
- title: "⚠️ Breaking Changes"
|
5
5
|
label: "⚠️ Breaking"
|
@@ -11,7 +11,15 @@ categories:
|
|
11
11
|
label: "📚 Docs"
|
12
12
|
- title: "🏠 Housekeeping"
|
13
13
|
label: "🏠 Housekeeping"
|
14
|
+
version-resolver:
|
15
|
+
minor:
|
16
|
+
labels:
|
17
|
+
- "⚠️ Breaking"
|
18
|
+
- "✨ Feature"
|
19
|
+
default: patch
|
14
20
|
change-template: "- $TITLE (#$NUMBER) @$AUTHOR"
|
15
21
|
no-changes-template: "- No changes"
|
16
22
|
template: |
|
17
23
|
$CHANGES
|
24
|
+
|
25
|
+
**Full Changelog:** https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION
|
data/.github/workflows/ci.yml
CHANGED
@@ -69,3 +69,30 @@ jobs:
|
|
69
69
|
bundler-cache: true
|
70
70
|
- name: Run rubocop
|
71
71
|
run: bundle exec rake lint
|
72
|
+
|
73
|
+
functional:
|
74
|
+
runs-on: ubuntu-latest
|
75
|
+
strategy:
|
76
|
+
matrix:
|
77
|
+
ruby: ["2.0", "ruby"]
|
78
|
+
steps:
|
79
|
+
- uses: actions/checkout@v4
|
80
|
+
- name: Set up Ruby
|
81
|
+
uses: ruby/setup-ruby@v1
|
82
|
+
with:
|
83
|
+
ruby-version: ${{ matrix.ruby }}
|
84
|
+
bundler-cache: true
|
85
|
+
- name: Run functional tests
|
86
|
+
run: bundle exec rake test:functional
|
87
|
+
|
88
|
+
functional-all:
|
89
|
+
runs-on: ubuntu-latest
|
90
|
+
needs: [functional]
|
91
|
+
if: always()
|
92
|
+
steps:
|
93
|
+
- name: All tests ok
|
94
|
+
if: ${{ !(contains(needs.*.result, 'failure')) }}
|
95
|
+
run: exit 0
|
96
|
+
- name: Some tests failed
|
97
|
+
if: ${{ contains(needs.*.result, 'failure') }}
|
98
|
+
run: exit 1
|
data/.gitignore
CHANGED
data/.rubocop_todo.yml
CHANGED
@@ -102,7 +102,6 @@ Layout/IndentHash:
|
|
102
102
|
Exclude:
|
103
103
|
- 'test/functional/backends/test_local.rb'
|
104
104
|
- 'test/functional/backends/test_netssh.rb'
|
105
|
-
- 'test/support/vagrant_wrapper.rb'
|
106
105
|
- 'test/unit/formatters/test_custom.rb'
|
107
106
|
- 'test/unit/formatters/test_pretty.rb'
|
108
107
|
- 'test/unit/test_mapping_interaction_handler.rb'
|
@@ -445,12 +444,6 @@ Style/MethodName:
|
|
445
444
|
Exclude:
|
446
445
|
- 'test/unit/test_color.rb'
|
447
446
|
|
448
|
-
# Offense count: 1
|
449
|
-
# Cop supports --auto-correct.
|
450
|
-
Style/MutableConstant:
|
451
|
-
Exclude:
|
452
|
-
- 'Vagrantfile'
|
453
|
-
|
454
447
|
# Offense count: 1
|
455
448
|
# Cop supports --auto-correct.
|
456
449
|
# Configuration parameters: Strict.
|
data/CONTRIBUTING.md
CHANGED
@@ -24,8 +24,8 @@ using unsupported features.
|
|
24
24
|
|
25
25
|
## Tests
|
26
26
|
|
27
|
-
SSHKit has a unit test suite and a functional test suite. Some functional tests run
|
28
|
-
[
|
27
|
+
SSHKit has a unit test suite and a functional test suite. Some functional tests run using
|
28
|
+
[Docker](https://docs.docker.com/get-docker/). If possible, you should make sure that the
|
29
29
|
tests pass for each commit by running `rake` in the sshkit directory. This is in case we
|
30
30
|
need to cherry pick commits or rebase. You should ensure the tests pass, (preferably on
|
31
31
|
the minimum and maximum ruby version), before creating a PR.
|
data/RELEASING.md
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
## How to release
|
10
10
|
|
11
11
|
1. Run `bundle install` to make sure that you have all the gems necessary for testing and releasing.
|
12
|
-
2. **Ensure the tests are passing by running `rake test`.** If functional tests fail, ensure you have [
|
12
|
+
2. **Ensure the tests are passing by running `rake test`.** If functional tests fail, ensure you have [Docker installed](https://docs.docker.com/get-docker/) and running.
|
13
13
|
3. Determine which would be the correct next version number according to [semver](http://semver.org/).
|
14
14
|
4. Update the version in `./lib/sshkit/version.rb`.
|
15
15
|
5. Commit the `version.rb` change with a message like "Preparing vX.Y.Z"
|
data/Rakefile
CHANGED
@@ -21,10 +21,6 @@ namespace :test do
|
|
21
21
|
|
22
22
|
end
|
23
23
|
|
24
|
-
Rake::Task["test:functional"].enhance do
|
25
|
-
warn "Remember there are still some VMs running, kill them with `vagrant halt` if you are finished using them."
|
26
|
-
end
|
27
|
-
|
28
24
|
desc 'Run RuboCop lint checks'
|
29
25
|
RuboCop::RakeTask.new(:lint) do |task|
|
30
26
|
task.options = ['--lint']
|
data/docker-compose.yml
ADDED
@@ -36,8 +36,8 @@ class SSHKit::Backend::ConnectionPool::Cache
|
|
36
36
|
def evict
|
37
37
|
# Peek at the first connection to see if it is still fresh. If so, we can
|
38
38
|
# return right away without needing to use `synchronize`.
|
39
|
-
first_expires_at,
|
40
|
-
return if (first_expires_at.nil? || fresh?(first_expires_at))
|
39
|
+
first_expires_at, _first_conn = connections.first
|
40
|
+
return if (first_expires_at.nil? || fresh?(first_expires_at))
|
41
41
|
|
42
42
|
connections.synchronize do
|
43
43
|
fresh, stale = connections.partition do |expires_at, conn|
|
@@ -7,12 +7,11 @@ module SSHKit
|
|
7
7
|
class Netssh < Abstract
|
8
8
|
|
9
9
|
class KnownHostsKeys
|
10
|
-
include Mutex_m
|
11
|
-
|
12
10
|
def initialize(path)
|
13
11
|
super()
|
14
12
|
@path = File.expand_path(path)
|
15
13
|
@hosts_keys = nil
|
14
|
+
@mutex = Mutex.new
|
16
15
|
end
|
17
16
|
|
18
17
|
def keys_for(hostlist)
|
@@ -46,7 +45,7 @@ module SSHKit
|
|
46
45
|
end
|
47
46
|
|
48
47
|
def parse_file
|
49
|
-
synchronize do
|
48
|
+
@mutex.synchronize do
|
50
49
|
return if hosts_keys && hosts_hashes
|
51
50
|
|
52
51
|
unless File.readable?(path)
|
@@ -112,11 +111,10 @@ module SSHKit
|
|
112
111
|
end
|
113
112
|
|
114
113
|
class KnownHosts
|
115
|
-
include Mutex_m
|
116
|
-
|
117
114
|
def initialize
|
118
115
|
super()
|
119
116
|
@files = {}
|
117
|
+
@mutex = Mutex.new
|
120
118
|
end
|
121
119
|
|
122
120
|
def search_for(host, options = {})
|
@@ -128,13 +126,13 @@ module SSHKit
|
|
128
126
|
|
129
127
|
def add(*args)
|
130
128
|
::Net::SSH::KnownHosts.add(*args)
|
131
|
-
synchronize { @files = {} }
|
129
|
+
@mutex.synchronize { @files = {} }
|
132
130
|
end
|
133
131
|
|
134
132
|
private
|
135
133
|
|
136
134
|
def known_hosts_file(path)
|
137
|
-
@files[path] || synchronize { @files[path] ||= KnownHostsKeys.new(path) }
|
135
|
+
@files[path] || @mutex.synchronize { @files[path] ||= KnownHostsKeys.new(path) }
|
138
136
|
end
|
139
137
|
end
|
140
138
|
|
data/lib/sshkit/host.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'ostruct'
|
2
|
+
require 'resolv'
|
2
3
|
|
3
4
|
module SSHKit
|
4
5
|
|
@@ -122,6 +123,22 @@ module SSHKit
|
|
122
123
|
|
123
124
|
end
|
124
125
|
|
126
|
+
# @private
|
127
|
+
# :nodoc:
|
128
|
+
class IPv6HostParser < SimpleHostParser
|
129
|
+
def self.suitable?(host_string)
|
130
|
+
host_string.match(Resolv::IPv6::Regex)
|
131
|
+
end
|
132
|
+
|
133
|
+
def port
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
def hostname
|
138
|
+
@host_string.match(Resolv::IPv6::Regex)[0]
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
125
142
|
class HostWithPortParser < SimpleHostParser
|
126
143
|
|
127
144
|
def self.suitable?(host_string)
|
@@ -192,6 +209,7 @@ module SSHKit
|
|
192
209
|
|
193
210
|
PARSERS = [
|
194
211
|
SimpleHostParser,
|
212
|
+
IPv6HostParser,
|
195
213
|
HostWithPortParser,
|
196
214
|
HostWithUsernameAndPortParser,
|
197
215
|
IPv6HostWithPortParser,
|
data/lib/sshkit/version.rb
CHANGED
data/sshkit.gemspec
CHANGED
@@ -21,7 +21,6 @@ Gem::Specification.new do |gem|
|
|
21
21
|
gem.version = SSHKit::VERSION
|
22
22
|
|
23
23
|
gem.add_runtime_dependency('base64') if RUBY_VERSION >= "2.4"
|
24
|
-
gem.add_runtime_dependency('mutex_m')
|
25
24
|
gem.add_runtime_dependency('net-ssh', '>= 2.8.0')
|
26
25
|
gem.add_runtime_dependency('net-scp', '>= 1.1.2')
|
27
26
|
gem.add_runtime_dependency('net-sftp', '>= 2.1.2')
|
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
|
@@ -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
|
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
|
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,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-
|
12
|
+
date: 2024-06-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: base64
|
@@ -25,20 +25,6 @@ dependencies:
|
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '0'
|
28
|
-
- !ruby/object:Gem::Dependency
|
29
|
-
name: mutex_m
|
30
|
-
requirement: !ruby/object:Gem::Requirement
|
31
|
-
requirements:
|
32
|
-
- - ">="
|
33
|
-
- !ruby/object:Gem::Version
|
34
|
-
version: '0'
|
35
|
-
type: :runtime
|
36
|
-
prerelease: false
|
37
|
-
version_requirements: !ruby/object:Gem::Requirement
|
38
|
-
requirements:
|
39
|
-
- - ">="
|
40
|
-
- !ruby/object:Gem::Version
|
41
|
-
version: '0'
|
42
28
|
- !ruby/object:Gem::Dependency
|
43
29
|
name: net-ssh
|
44
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -222,6 +208,8 @@ executables: []
|
|
222
208
|
extensions: []
|
223
209
|
extra_rdoc_files: []
|
224
210
|
files:
|
211
|
+
- ".docker/Dockerfile"
|
212
|
+
- ".docker/ubuntu_setup.sh"
|
225
213
|
- ".github/dependabot.yml"
|
226
214
|
- ".github/release-drafter.yml"
|
227
215
|
- ".github/workflows/ci.yml"
|
@@ -241,7 +229,7 @@ files:
|
|
241
229
|
- README.md
|
242
230
|
- RELEASING.md
|
243
231
|
- Rakefile
|
244
|
-
-
|
232
|
+
- docker-compose.yml
|
245
233
|
- examples/images/example_output.png
|
246
234
|
- examples/images/logo.png
|
247
235
|
- examples/simple_connection.rb
|
@@ -284,18 +272,16 @@ files:
|
|
284
272
|
- lib/sshkit/runners/sequential.rb
|
285
273
|
- lib/sshkit/version.rb
|
286
274
|
- sshkit.gemspec
|
287
|
-
- test/boxes.json
|
288
275
|
- test/functional/backends/netssh_transfer_tests.rb
|
289
276
|
- test/functional/backends/test_local.rb
|
290
277
|
- test/functional/backends/test_netssh.rb
|
291
278
|
- test/functional/backends/test_netssh_scp.rb
|
292
279
|
- test/functional/backends/test_netssh_sftp.rb
|
293
|
-
- test/functional/test_ssh_server_comes_up_for_functional_tests.rb
|
294
280
|
- test/helper.rb
|
295
281
|
- test/known_hosts/github
|
296
282
|
- test/known_hosts/github_hash
|
297
283
|
- test/known_hosts/github_ip
|
298
|
-
- test/support/
|
284
|
+
- test/support/docker_wrapper.rb
|
299
285
|
- test/unit/backends/test_abstract.rb
|
300
286
|
- test/unit/backends/test_connection_pool.rb
|
301
287
|
- test/unit/backends/test_local.rb
|
@@ -338,23 +324,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
338
324
|
- !ruby/object:Gem::Version
|
339
325
|
version: '0'
|
340
326
|
requirements: []
|
341
|
-
rubygems_version: 3.5.
|
327
|
+
rubygems_version: 3.5.13
|
342
328
|
signing_key:
|
343
329
|
specification_version: 4
|
344
330
|
summary: SSHKit makes it easy to write structured, testable SSH commands in Ruby
|
345
331
|
test_files:
|
346
|
-
- test/boxes.json
|
347
332
|
- test/functional/backends/netssh_transfer_tests.rb
|
348
333
|
- test/functional/backends/test_local.rb
|
349
334
|
- test/functional/backends/test_netssh.rb
|
350
335
|
- test/functional/backends/test_netssh_scp.rb
|
351
336
|
- test/functional/backends/test_netssh_sftp.rb
|
352
|
-
- test/functional/test_ssh_server_comes_up_for_functional_tests.rb
|
353
337
|
- test/helper.rb
|
354
338
|
- test/known_hosts/github
|
355
339
|
- test/known_hosts/github_hash
|
356
340
|
- test/known_hosts/github_ip
|
357
|
-
- test/support/
|
341
|
+
- test/support/docker_wrapper.rb
|
358
342
|
- test/unit/backends/test_abstract.rb
|
359
343
|
- test/unit/backends/test_connection_pool.rb
|
360
344
|
- test/unit/backends/test_local.rb
|
data/Vagrantfile
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
VAGRANTFILE_API_VERSION = "2"
|
2
|
-
|
3
|
-
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
4
|
-
config.vm.box = 'bento/ubuntu-22.10'
|
5
|
-
|
6
|
-
config.vm.boot_timeout = 600 # seconds
|
7
|
-
config.ssh.insert_key = false
|
8
|
-
config.vm.provision "shell", inline: <<-SHELL
|
9
|
-
echo 'ClientAliveInterval 3' >> /etc/ssh/sshd_config
|
10
|
-
echo 'ClientAliveCountMax 3' >> /etc/ssh/sshd_config
|
11
|
-
echo 'MaxAuthTries 6' >> /etc/ssh/sshd_config
|
12
|
-
service ssh restart
|
13
|
-
SHELL
|
14
|
-
|
15
|
-
json_config_path = File.join("test", "boxes.json")
|
16
|
-
list = File.open(json_config_path).read
|
17
|
-
list = JSON.parse(list)
|
18
|
-
|
19
|
-
list.each do |vm|
|
20
|
-
config.vm.define vm["name"] do |web|
|
21
|
-
web.vm.network "forwarded_port", guest: 22, host: vm["port"]
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
data/test/boxes.json
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
module SSHKit
|
4
|
-
|
5
|
-
class TestHost < FunctionalTest
|
6
|
-
|
7
|
-
def host
|
8
|
-
@_host ||= Host.new('')
|
9
|
-
end
|
10
|
-
|
11
|
-
def test_that_it_works
|
12
|
-
assert true
|
13
|
-
end
|
14
|
-
|
15
|
-
def test_creating_a_user_gives_us_back_his_private_key_as_a_string
|
16
|
-
skip 'It is not safe to create an user for non vagrant envs' unless VagrantWrapper.running?
|
17
|
-
keys = create_user_with_key(:peter)
|
18
|
-
assert_equal [:one, :two, :three], keys.keys
|
19
|
-
assert keys.values.all?
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
class VagrantWrapper
|
2
|
-
class << self
|
3
|
-
def hosts
|
4
|
-
@vm_hosts ||= begin
|
5
|
-
result = {}
|
6
|
-
|
7
|
-
boxes = boxes_list
|
8
|
-
|
9
|
-
unless running?
|
10
|
-
boxes.map! do |box|
|
11
|
-
box['user'] = ENV['USER']
|
12
|
-
box['port'] = '22'
|
13
|
-
box
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
boxes.each do |vm|
|
18
|
-
result[vm['name']] = vm_host(vm)
|
19
|
-
end
|
20
|
-
|
21
|
-
result
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def running?
|
26
|
-
@running ||= begin
|
27
|
-
status = `#{vagrant_binary} status`
|
28
|
-
status.include?('running')
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def boxes_list
|
33
|
-
json_config_path = File.join('test', 'boxes.json')
|
34
|
-
boxes = File.open(json_config_path).read
|
35
|
-
JSON.parse(boxes)
|
36
|
-
end
|
37
|
-
|
38
|
-
def vagrant_binary
|
39
|
-
'vagrant'
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
def vm_host(vm)
|
45
|
-
host_options = {
|
46
|
-
user: vm['user'] || 'vagrant',
|
47
|
-
hostname: vm['hostname'] || 'localhost',
|
48
|
-
port: vm['port'] || '22',
|
49
|
-
password: vm['password'] || 'vagrant',
|
50
|
-
ssh_options: host_verify_options
|
51
|
-
}
|
52
|
-
|
53
|
-
SSHKit::Host.new(host_options)
|
54
|
-
end
|
55
|
-
|
56
|
-
def host_verify_options
|
57
|
-
if Net::SSH::Version::MAJOR >= 5
|
58
|
-
{ verify_host_key: :never }
|
59
|
-
else
|
60
|
-
{ paranoid: false }
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|