sshkit 1.10.0 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9da07f57b3af779a599eacb874eb170a75c70013
4
- data.tar.gz: 547bea80a8bacc021f25188ddb2d031078077a4d
3
+ metadata.gz: 2ea6531109db4fbc073107e4d01ac242f50a4f67
4
+ data.tar.gz: 70ae0a86727e7ba0659049b6b3abfb07e84f4f2b
5
5
  SHA512:
6
- metadata.gz: df5aaafd725f7142083d2d9a8a393561a03456230a01bdfda61d2341e3f7debc39f76a82dd373813ee67837fffeb6add8def675e48eb3139b3874061b8115543
7
- data.tar.gz: f793b26a4fe0bae6c30eda6bea38484fc6faf834a7d3dc0b674f7c04c4b10bcf505fa38dda91a73ae37fa6f4f3dfca92bd1f658fee901eb387296bc44e84207e
6
+ metadata.gz: 58a524ef9892ad8563de08e5f24eac198d22b78b5c193b72dbb8990712bf67cc0346b8a84e2281627a84c0bde28ed14a23d74059b5cb6f9a6ed14b31e69bb9df
7
+ data.tar.gz: ac0d03ae20ca9ef8b72727000d7cdbfb55f74a7806f2e9897d90eb1368b8c1f47ba281ef7e4b5e83deaf1b60d96006640f8eb5ed226aa695ebb45231b6b52c9f
data/CHANGELOG.md CHANGED
@@ -3,16 +3,29 @@
3
3
  This file is written in reverse chronological order, newer releases will
4
4
  appear at the top.
5
5
 
6
- ## `master` (Unreleased)
6
+ ## [Unreleased][]
7
7
 
8
8
  * Add your entries below here, remember to credit yourself however you want
9
9
  to be credited!
10
10
 
11
+ ## [1.11.0][] (2016-06-14)
12
+
13
+ ### Bug fixes
14
+
15
+ * Fixed colorized output alignment in Logger::Pretty. @xavierholt
16
+ [PR #349](https://github.com/capistrano/sshkit/pull/349)
17
+ * Fixed a bug that prevented nested `with` calls
18
+ [#43](https://github.com/capistrano/sshkit/issues/43)
19
+
20
+ ### Other changes
21
+
22
+ * Known hosts lookup optimization is now enabled by default. @byroot
23
+
11
24
  ## 1.10.0 (2016-04-22)
12
25
 
13
26
  * You can now opt-in to caching of SSH's known_hosts file for a speed boost
14
27
  when deploying to a large fleet of servers. Refer to the
15
- [README](https://github.com/capistrano/sshkit#known-hosts-caching) for
28
+ [README](https://github.com/capistrano/sshkit/tree/v1.10.0#known-hosts-caching) for
16
29
  details. We plan to turn this on by default in a future version of SSHKit.
17
30
  [PR #330](https://github.com/capistrano/sshkit/pull/330) @byroot
18
31
  * SSHKit now explicitly closes its pooled SSH connections when Ruby exits;
@@ -615,3 +628,6 @@ version `0.0.5`.
615
628
  ## 0.0.1
616
629
 
617
630
  First release.
631
+
632
+ [Unreleased]: https://github.com/capistrano/sshkit/compare/v1.11.0...HEAD
633
+ [1.11.0]: https://github.com/capistrano/sshkit/compare/v1.10.0...v1.11.0
data/EXAMPLES.md CHANGED
@@ -44,10 +44,10 @@ end
44
44
  ```ruby
45
45
  on hosts do |host|
46
46
  f = '/some/file'
47
- if test("[ -d #{f} ]")
48
- execute :touch, f
49
- else
47
+ if test("[ -f #{f} ]")
50
48
  info "#{f} already exists on #{host}!"
49
+ else
50
+ execute :touch, f
51
51
  end
52
52
  end
53
53
  ```
data/README.md CHANGED
@@ -53,7 +53,7 @@ have no effect.**
53
53
  Typically, you would pass a Symbol for the command name and it's args as follows:
54
54
 
55
55
  ```ruby
56
- on '1.example.com'
56
+ on '1.example.com' do
57
57
  if test("[ -f somefile.txt ]")
58
58
  execute(:cp, 'somefile.txt', 'somewhere_else.txt')
59
59
  end
@@ -508,19 +508,6 @@ pooling behaviour entirely by setting the idle_timeout to zero:
508
508
  SSHKit::Backend::Netssh.pool.idle_timeout = 0 # disabled
509
509
  ```
510
510
 
511
- ## Known hosts caching
512
-
513
- If you connect to many hosts with the `Netssh` backend, looking up `~/.ssh/known_hosts` can significantly impact performances.
514
- You can mitigate this by using SSHKit's lookup caching like this:
515
-
516
- ```ruby
517
- SSHKit::Backend::Netssh.configure do |ssh|
518
- ssh.ssh_options = {
519
- known_hosts: SSHKit::Backend::Netssh::KnownHosts.new,
520
- }
521
- end
522
- ```
523
-
524
511
  ## Tunneling and other related SSH themes
525
512
 
526
513
  In order to do special gymnasitcs with SSH, tunneling, aliasing, complex options, etc with SSHKit it is possible to use [the underlying Net::SSH API](https://github.com/capistrano/sshkit/blob/master/EXAMPLES.md#setting-global-ssh-options) however in many cases it is preferred to use the system SSH configuration file at [`~/.ssh/config`](http://man.cx/ssh_config). This allows you to have personal configuration tied to your machine that does not have to be committed with the repository. If this is not suitable (everyone on the team needs a proxy command, or some special aliasing) a file in the same format can be placed in the project directory at `~/yourproject/.ssh/config`, this will be merged with the system settings in `~/.ssh/config`, and with any configuration specified in [`SSHKit::Backend::Netssh.config.ssh_options`](https://github.com/capistrano/sshkit/blob/master/lib/sshkit/backends/netssh.rb#L133).
@@ -35,6 +35,11 @@ module SSHKit
35
35
  raise "Must pass a Host object" unless host.is_a? Host
36
36
  @host = host
37
37
  @block = block
38
+
39
+ @pwd = nil
40
+ @env = nil
41
+ @user = nil
42
+ @group = nil
38
43
  end
39
44
 
40
45
  def make(commands=[])
@@ -83,12 +88,11 @@ module SSHKit
83
88
  end
84
89
 
85
90
  def with(environment, &_block)
86
- @_env = (@env ||= {})
87
- @env = @_env.merge environment
91
+ env_old = (@env ||= {})
92
+ @env = env_old.merge environment
88
93
  yield
89
94
  ensure
90
- @env = @_env
91
- remove_instance_variable(:@_env)
95
+ @env = env_old
92
96
  end
93
97
 
94
98
  def as(who, &_block)
@@ -7,8 +7,7 @@ module SSHKit
7
7
  class Local < Abstract
8
8
 
9
9
  def initialize(_ = nil, &block)
10
- @host = Host.new(:local) # just for logging
11
- @block = block
10
+ super(Host.new(:local), &block)
12
11
  end
13
12
 
14
13
  def upload!(local, remote, _options = {})
@@ -28,7 +28,13 @@ module SSHKit
28
28
  attr_writer :ssh_options
29
29
 
30
30
  def ssh_options
31
- @ssh_options ||= {}
31
+ default_options.merge(@ssh_options ||= {})
32
+ end
33
+
34
+ private
35
+
36
+ def default_options
37
+ @default_options ||= {known_hosts: SSHKit::Backend::Netssh::KnownHosts.new}
32
38
  end
33
39
  end
34
40
 
@@ -131,9 +131,9 @@ module SSHKit
131
131
 
132
132
  def verbosity
133
133
  if (vb = options[:verbosity])
134
- case vb.class.name
135
- when 'Symbol' then return Logger.const_get(vb.to_s.upcase)
136
- when 'Fixnum' then return vb
134
+ case vb
135
+ when Symbol then return Logger.const_get(vb.to_s.upcase)
136
+ when Integer then return vb
137
137
  end
138
138
  else
139
139
  Logger::INFO
@@ -10,7 +10,10 @@ module SSHKit
10
10
  end
11
11
 
12
12
  def deprecation_logger
13
- self.deprecation_output = $stderr if @deprecation_logger.nil?
13
+ unless defined? @deprecation_logger
14
+ self.deprecation_output = $stderr
15
+ end
16
+
14
17
  @deprecation_logger
15
18
  end
16
19
 
@@ -34,7 +34,7 @@ module SSHKit
34
34
 
35
35
  def log_command_exit(command)
36
36
  runtime = sprintf('%5.3f seconds', command.runtime)
37
- successful_or_failed = command.failure? ? colorize('failed', :red, :bold) : colorize('successful', :green, :bold)
37
+ successful_or_failed = command.failure? ? colorize('failed', :red, :bold) : colorize('successful', :green, :bold)
38
38
  message = "Finished in #{runtime} with exit status #{command.exit_status} (#{successful_or_failed})."
39
39
  write_message(command.verbosity, message, command.uuid)
40
40
  end
@@ -43,8 +43,8 @@ module SSHKit
43
43
 
44
44
  def format_message(verbosity, message, uuid=nil)
45
45
  message = "[#{colorize(uuid, :green)}] #{message}" unless uuid.nil?
46
- level = colorize(Pretty::LEVEL_NAMES[verbosity], Pretty::LEVEL_COLORS[verbosity])
47
- '%6s %s' % [level, message]
46
+ level = colorize(LEVEL_NAMES[verbosity].rjust(6), LEVEL_COLORS[verbosity])
47
+ "#{level} #{message}"
48
48
  end
49
49
 
50
50
  private
data/lib/sshkit/host.rb CHANGED
@@ -17,10 +17,12 @@ module SSHKit
17
17
  end
18
18
 
19
19
  def keys
20
- Array(@keys)
20
+ @keys
21
21
  end
22
22
 
23
23
  def initialize(host_string_or_options_hash)
24
+ @keys = []
25
+ @local = false
24
26
 
25
27
  if host_string_or_options_hash == :local
26
28
  @local = true
@@ -3,17 +3,20 @@ module SSHKit
3
3
  module Runner
4
4
 
5
5
  class Group < Sequential
6
- attr_writer :group_size
6
+ attr_accessor :group_size
7
+
8
+ def initialize(hosts, options = nil, &block)
9
+ super(hosts, options, &block)
10
+ @group_size = @options[:limit] || 2
11
+ end
12
+
7
13
  def execute
8
14
  hosts.each_slice(group_size).collect do |group_hosts|
9
15
  Parallel.new(group_hosts, &block).execute
10
16
  sleep wait_interval
11
17
  end.flatten
12
18
  end
13
- private
14
- def group_size
15
- @group_size || options[:limit] || 2
16
- end
19
+
17
20
  end
18
21
 
19
22
  end
@@ -3,7 +3,13 @@ module SSHKit
3
3
  module Runner
4
4
 
5
5
  class Sequential < Abstract
6
- attr_writer :wait_interval
6
+ attr_accessor :wait_interval
7
+
8
+ def initialize(hosts, options = nil, &block)
9
+ super(hosts, options, &block)
10
+ @wait_interval = @options[:wait] || 2
11
+ end
12
+
7
13
  def execute
8
14
  last_host = hosts.pop
9
15
 
@@ -16,6 +22,7 @@ module SSHKit
16
22
  run_backend(last_host, &block)
17
23
  end
18
24
  end
25
+
19
26
  private
20
27
  def run_backend(host, &block)
21
28
  backend(host, &block).run
@@ -24,9 +31,6 @@ module SSHKit
24
31
  raise e2, "Exception while executing #{host.user ? "as #{host.user}@" : "on host "}#{host}: #{e.message}"
25
32
  end
26
33
 
27
- def wait_interval
28
- @wait_interval || options[:wait] || 2
29
- end
30
34
  end
31
35
 
32
36
  end
@@ -1,3 +1,3 @@
1
1
  module SSHKit
2
- VERSION = "1.10.0".freeze
2
+ VERSION = "1.11.0".freeze
3
3
  end
data/sshkit.gemspec CHANGED
@@ -24,6 +24,5 @@ Gem::Specification.new do |gem|
24
24
  gem.add_development_dependency('minitest-reporters')
25
25
  gem.add_development_dependency('rake')
26
26
  gem.add_development_dependency('rubocop')
27
- gem.add_development_dependency('unindent')
28
27
  gem.add_development_dependency('mocha')
29
28
  end
@@ -33,13 +33,13 @@ module SSHKit
33
33
  end.run
34
34
 
35
35
  command_lines = @output.lines.select { |line| line.start_with?('Command:') }
36
- assert_equal <<-EOEXPECTED.unindent, command_lines.join
37
- Command: /usr/bin/env date
38
- Command: /usr/bin/env ls -l
39
- Command: if test ! -d /tmp; then echo \"Directory does not exist '/tmp'\" 1>&2; false; fi
40
- Command: if ! sudo -u root whoami > /dev/null; then echo \"You cannot switch to user 'root' using sudo, please check the sudoers file\" 1>&2; false; fi
41
- Command: cd /tmp && ( export RAILS_ENV="production" ; sudo -u root RAILS_ENV="production" -- sh -c '/usr/bin/env touch restart.txt' )
42
- EOEXPECTED
36
+ assert_equal [
37
+ "Command: /usr/bin/env date\n",
38
+ "Command: /usr/bin/env ls -l\n",
39
+ "Command: if test ! -d /tmp; then echo \"Directory does not exist '/tmp'\" 1>&2; false; fi\n",
40
+ "Command: if ! sudo -u root whoami > /dev/null; then echo \"You cannot switch to user 'root' using sudo, please check the sudoers file\" 1>&2; false; fi\n",
41
+ "Command: cd /tmp && ( export RAILS_ENV=\"production\" ; sudo -u root RAILS_ENV=\"production\" -- sh -c '/usr/bin/env touch restart.txt' )\n"
42
+ ], command_lines
43
43
  end
44
44
 
45
45
  def test_capture
@@ -59,7 +59,10 @@ module SSHKit
59
59
  capture(:uname)
60
60
  host_ssh_options = host.ssh_options
61
61
  end.run
62
- assert_equal({ forward_agent: false, paranoid: true }, host_ssh_options)
62
+ assert_equal [:forward_agent, :paranoid, :known_hosts].sort, host_ssh_options.keys.sort
63
+ assert_equal false, host_ssh_options[:forward_agent]
64
+ assert_equal true, host_ssh_options[:paranoid]
65
+ assert_instance_of SSHKit::Backend::Netssh::KnownHosts, host_ssh_options[:known_hosts]
63
66
  end
64
67
 
65
68
  def test_env_vars_substituion_in_subshell
data/test/helper.rb CHANGED
@@ -4,7 +4,6 @@ require 'tempfile'
4
4
  require 'minitest/autorun'
5
5
  require 'minitest/reporters'
6
6
  require 'mocha/setup'
7
- require 'unindent'
8
7
  require 'stringio'
9
8
  require 'json'
10
9
 
@@ -21,6 +20,7 @@ class UnitTest < Minitest::Test
21
20
  end
22
21
 
23
22
  SSHKit::Backend::ConnectionPool.class_eval do
23
+ alias_method :old_flush_connections, :flush_connections
24
24
  def flush_connections
25
25
  Thread.current[:sshkit_pool] = {}
26
26
  end
@@ -161,6 +161,7 @@ module SSHKit
161
161
  def initialize(&block)
162
162
  block = block.nil? ? lambda {} : block
163
163
  super(ExampleBackend.example_host, &block)
164
+ @full_stdout = nil
164
165
  end
165
166
 
166
167
  def execute_command(command)
@@ -26,7 +26,7 @@ module SSHKit
26
26
  assert_equal %w(/home/user/.ssh/id_rsa), backend.config.ssh_options[:keys]
27
27
  assert_equal false, backend.config.ssh_options[:forward_agent]
28
28
  assert_equal %w(publickey password), backend.config.ssh_options[:auth_methods]
29
-
29
+ assert_instance_of backend::KnownHosts, backend.config.ssh_options[:known_hosts]
30
30
  end
31
31
 
32
32
  def test_netssh_ext
@@ -18,12 +18,12 @@ module SSHKit
18
18
  end
19
19
 
20
20
  {
21
- log: "\e[0;34;49mINFO\e[0m Test\n",
22
- fatal: "\e[0;31;49mFATAL\e[0m Test\n",
23
- error: "\e[0;31;49mERROR\e[0m Test\n",
24
- warn: "\e[0;33;49mWARN\e[0m Test\n",
25
- info: "\e[0;34;49mINFO\e[0m Test\n",
26
- debug: "\e[0;30;49mDEBUG\e[0m Test\n"
21
+ log: "\e[0;34;49m INFO\e[0m Test\n",
22
+ fatal: "\e[0;31;49m FATAL\e[0m Test\n",
23
+ error: "\e[0;31;49m ERROR\e[0m Test\n",
24
+ warn: "\e[0;33;49m WARN\e[0m Test\n",
25
+ info: "\e[0;34;49m INFO\e[0m Test\n",
26
+ debug: "\e[0;30;49m DEBUG\e[0m Test\n"
27
27
  }.each do |level, expected_output|
28
28
  define_method("test_#{level}_output_with_color") do
29
29
  output.stubs(:tty?).returns(true)
@@ -37,11 +37,11 @@ module SSHKit
37
37
  simulate_command_lifecycle(pretty)
38
38
 
39
39
  expected_log_lines = [
40
- "\e[0;34;49mINFO\e[0m [\e[0;32;49maaaaaa\e[0m] Running \e[1;33;49m/usr/bin/env a_cmd some args\e[0m as \e[0;34;49muser\e[0m@\e[0;34;49mlocalhost\e[0m",
41
- "\e[0;30;49mDEBUG\e[0m [\e[0;32;49maaaaaa\e[0m] Command: \e[0;34;49m/usr/bin/env a_cmd some args\e[0m",
42
- "\e[0;30;49mDEBUG\e[0m [\e[0;32;49maaaaaa\e[0m] \e[0;32;49m\tstdout message\e[0m",
43
- "\e[0;30;49mDEBUG\e[0m [\e[0;32;49maaaaaa\e[0m] \e[0;31;49m\tstderr message\e[0m",
44
- "\e[0;34;49mINFO\e[0m [\e[0;32;49maaaaaa\e[0m] Finished in 1.000 seconds with exit status 0 (\e[1;32;49msuccessful\e[0m)."
40
+ "\e[0;34;49m INFO\e[0m [\e[0;32;49maaaaaa\e[0m] Running \e[1;33;49m/usr/bin/env a_cmd some args\e[0m as \e[0;34;49muser\e[0m@\e[0;34;49mlocalhost\e[0m",
41
+ "\e[0;30;49m DEBUG\e[0m [\e[0;32;49maaaaaa\e[0m] Command: \e[0;34;49m/usr/bin/env a_cmd some args\e[0m",
42
+ "\e[0;30;49m DEBUG\e[0m [\e[0;32;49maaaaaa\e[0m] \e[0;32;49m\tstdout message\e[0m",
43
+ "\e[0;30;49m DEBUG\e[0m [\e[0;32;49maaaaaa\e[0m] \e[0;31;49m\tstderr message\e[0m",
44
+ "\e[0;34;49m INFO\e[0m [\e[0;32;49maaaaaa\e[0m] Finished in 1.000 seconds with exit status 0 (\e[1;32;49msuccessful\e[0m)."
45
45
  ]
46
46
  assert_equal expected_log_lines, output.split("\n")
47
47
  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.10.0
4
+ version: 1.11.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: 2016-04-22 00:00:00.000000000 Z
12
+ date: 2016-06-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: net-ssh
@@ -95,20 +95,6 @@ dependencies:
95
95
  - - ">="
96
96
  - !ruby/object:Gem::Version
97
97
  version: '0'
98
- - !ruby/object:Gem::Dependency
99
- name: unindent
100
- requirement: !ruby/object:Gem::Requirement
101
- requirements:
102
- - - ">="
103
- - !ruby/object:Gem::Version
104
- version: '0'
105
- type: :development
106
- prerelease: false
107
- version_requirements: !ruby/object:Gem::Requirement
108
- requirements:
109
- - - ">="
110
- - !ruby/object:Gem::Version
111
- version: '0'
112
98
  - !ruby/object:Gem::Dependency
113
99
  name: mocha
114
100
  requirement: !ruby/object:Gem::Requirement
@@ -198,7 +184,6 @@ files:
198
184
  - test/unit/backends/test_local.rb
199
185
  - test/unit/backends/test_netssh.rb
200
186
  - test/unit/backends/test_printer.rb
201
- - test/unit/core_ext/test_string.rb
202
187
  - test/unit/formatters/test_custom.rb
203
188
  - test/unit/formatters/test_dot.rb
204
189
  - test/unit/formatters/test_pretty.rb
@@ -233,7 +218,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
233
218
  version: '0'
234
219
  requirements: []
235
220
  rubyforge_project:
236
- rubygems_version: 2.6.2
221
+ rubygems_version: 2.6.4
237
222
  signing_key:
238
223
  specification_version: 4
239
224
  summary: SSHKit makes it easy to write structured, testable SSH commands in Ruby
@@ -251,7 +236,6 @@ test_files:
251
236
  - test/unit/backends/test_local.rb
252
237
  - test/unit/backends/test_netssh.rb
253
238
  - test/unit/backends/test_printer.rb
254
- - test/unit/core_ext/test_string.rb
255
239
  - test/unit/formatters/test_custom.rb
256
240
  - test/unit/formatters/test_dot.rb
257
241
  - test/unit/formatters/test_pretty.rb
@@ -1,12 +0,0 @@
1
- class String
2
-
3
- def unindent
4
- indent = self.split("\n").select do |line|
5
- !line.strip.empty?
6
- end.map do |line|
7
- line.index(/[^\s]/)
8
- end.compact.min || 0
9
- self.gsub(/^[[:blank:]]{#{indent}}/, '')
10
- end
11
-
12
- end