sshkit 1.6.1 → 1.7.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: f6b3d2a602578d1cea808691cd6a94345862e87e
4
- data.tar.gz: 1f7d65fb072bb2c9e6fd830d49bfa354cf756296
3
+ metadata.gz: fbc4c4d5b2ac3c6cfda56f6d7582b6c2e4b0814d
4
+ data.tar.gz: 6a260d8a28ed5df45fd14de2140aa0de0f6ef577
5
5
  SHA512:
6
- metadata.gz: 4e0f22c3b4b0bf6e6af4bafc7d3d610c216fea810aebd29ab689819d3953da77f4aa3c5ea599453997f85b5f5bec5fae8fd629c370968a87580755bd23f6044b
7
- data.tar.gz: c789d68ad2b9025a694dd41b58b55640d55443252729bdbbd7d8460419e5fbe9670fde840b437cf2416380a1e19c28613ddd92c1b55d5a27ae0f8fa1c47a5dc8
6
+ metadata.gz: e37e0ac83457d83c0c5d41676830097c5ccd6f24ae5cc636533d2c2bb54a2f7706f387ec9af97a458a332a198b90189fd4263ec3411fb07a75db56cd0db25107
7
+ data.tar.gz: 135cc559ee24611b6f1ccab198445ea7a8efe2df7339c12409e5547a5c3ea0a1ae22d61a640b2a6703b1bb9e7c36af15d1f05fc2103d43d222bcd8fe9a978450
data/.gitignore CHANGED
@@ -1,4 +1,7 @@
1
1
  *.gem
2
+ *.swp
3
+ bin/rake
4
+ .bundle
2
5
  .yardoc
3
6
  .vagrant*
4
7
  test/tmp
@@ -3,11 +3,26 @@
3
3
  This file is written in reverse chronological order, newer releases will
4
4
  appear at the top.
5
5
 
6
- ## (Unreleased)
6
+ ## `master` (Unreleased)
7
7
 
8
8
  * Add your entries here, remember to credit yourself however you want to be
9
9
  credited!
10
10
 
11
+ ## 1.7.0
12
+
13
+ * Update Vagrantfile to use multi-provider Hashicorp precise64 box - remove URLs. @townsen
14
+ * Merge host ssh_options and Netssh defaults @townsen
15
+ Previously if host-level ssh_options were defined the Netssh defaults
16
+ were ignored.
17
+ * Merge host ssh_options and Netssh defaults
18
+ * Fixed race condition where output of failed command would be empty. @townsen
19
+ Caused random failures of `test_execute_raises_on_non_zero_exit_status_and_captures_stdout_and_stderr`
20
+ Also fixes output handling in failed commands, and generally buggy output.
21
+ * Remove override of backtrace() and backtrace_locations() from ExecuteError. @townsen
22
+ This interferes with rake default behaviour and creates duplicate stacktraces.
23
+ * Allow running local commands using `on(:local)`
24
+ * Implement the upload! and download! methods for the local backend
25
+
11
26
  ## 1.6.0
12
27
 
13
28
  * Fix colorize to use the correct API (@fazibear)
@@ -344,3 +344,10 @@ Replace `on` with `run_locally`
344
344
  end
345
345
  end
346
346
 
347
+ You can achieve the same thing with `on(:local)`
348
+
349
+ on(:local) do
350
+ within '/tmp' do
351
+ execute :whoami
352
+ end
353
+ end
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- ![SSHKit Logo](https://raw.github.com/leehambley/sshkit/master/assets/images/logo.png)
1
+ ![SSHKit Logo](https://raw.github.com/leehambley/sshkit/master/examples/images/logo.png)
2
2
 
3
3
  **SSHKit** is a toolkit for running commands in a structured way on one or
4
4
  more servers.
@@ -199,7 +199,7 @@ first argument before attempting to find it in the *command map*.
199
199
 
200
200
  ## Output Handling
201
201
 
202
- ![Example Output](https://raw.github.com/leehambley/sshkit/master/assets/images/example_output.png)
202
+ ![Example Output](https://raw.github.com/leehambley/sshkit/master/examples/images/example_output.png)
203
203
 
204
204
  By default, the output format is set to `:pretty`:
205
205
 
@@ -1,13 +1,7 @@
1
1
  VAGRANTFILE_API_VERSION = "2"
2
2
 
3
3
  Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
4
- config.vm.box = 'precise64'
5
- config.vm.provider "vmware_fusion" do |vmf|
6
- vmf.box_url = "http://files.vagrantup.com/precise64_vmware.box"
7
- end
8
- config.vm.provider "virtualbox" do |vb|
9
- config.vm.box_url = "http://cloud-images.ubuntu.com/vagrant/precise/current/precise-server-cloudimg-amd64-vagrant-disk1.box"
10
- end
4
+ config.vm.box = 'hashicorp/precise64'
11
5
 
12
6
  json_config_path = File.join("test", "boxes.json")
13
7
  list = File.open(json_config_path).read
@@ -15,7 +9,6 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
15
9
 
16
10
  list.each do |vm|
17
11
  config.vm.define vm["name"] do |web|
18
- web.vm.box = "precise64"
19
12
  web.vm.network "forwarded_port", guest: 22, host: vm["port"]
20
13
  end
21
14
  end
File without changes
@@ -1,17 +1,18 @@
1
1
  require 'open3'
2
+ require 'fileutils'
2
3
  module SSHKit
3
4
 
4
5
  module Backend
5
6
 
6
7
  class Local < Printer
7
8
 
8
- def initialize(&block)
9
- @host = Host.new(hostname: 'localhost') # just for logging
9
+ def initialize(_ = nil, &block)
10
+ @host = Host.new(:local) # just for logging
10
11
  @block = block
11
12
  end
12
13
 
13
14
  def run
14
- instance_exec(&@block)
15
+ instance_exec(@host, &@block)
15
16
  end
16
17
 
17
18
  def test(*args)
@@ -31,6 +32,26 @@ module SSHKit
31
32
  _execute(*[*args, options]).full_stdout
32
33
  end
33
34
 
35
+ def upload!(local, remote, options = {})
36
+ if local.is_a?(String)
37
+ FileUtils.cp(local, remote)
38
+ else
39
+ File.open(remote, "wb") do |f|
40
+ IO.copy_stream(local, f)
41
+ end
42
+ end
43
+ end
44
+
45
+ def download!(remote, local=nil, options = {})
46
+ if local.nil?
47
+ FileUtils.cp(remote, File.basename(remote))
48
+ else
49
+ File.open(remote, "rb") do |f|
50
+ IO.copy_stream(f, local)
51
+ end
52
+ end
53
+ end
54
+
34
55
  private
35
56
 
36
57
  def _execute(*args)
@@ -39,23 +60,34 @@ module SSHKit
39
60
 
40
61
  cmd.started = Time.now
41
62
 
42
- stdout, stderr, exit_status =
43
- if RUBY_ENGINE == 'jruby'
44
- _, o, e, t = Open3.popen3('/usr/bin/env', 'sh', '-c', cmd.to_command)
45
- [o.read, e.read, t.value]
46
- else
47
- Open3.capture3(cmd.to_command)
63
+ Open3.popen3(cmd.to_command) do |stdin, stdout, stderr, wait_thr|
64
+ stdout_thread = Thread.new do
65
+ while line = stdout.gets do
66
+ cmd.stdout = line
67
+ cmd.full_stdout += line
68
+
69
+ output << cmd
70
+ end
48
71
  end
49
72
 
50
- cmd.stdout = stdout
51
- cmd.full_stdout += stdout
73
+ stderr_thread = Thread.new do
74
+ while line = stderr.gets do
75
+ cmd.stderr = line
76
+ cmd.full_stderr += line
52
77
 
53
- cmd.stderr = stderr
54
- cmd.full_stderr += stderr
78
+ output << cmd
79
+ end
80
+ end
55
81
 
56
- cmd.exit_status = exit_status.to_i
82
+ stdout_thread.join
83
+ stderr_thread.join
57
84
 
58
- output << cmd
85
+ cmd.exit_status = wait_thr.value.to_i
86
+ cmd.stdout = ''
87
+ cmd.stderr = ''
88
+
89
+ output << cmd
90
+ end
59
91
  end
60
92
  end
61
93
 
@@ -133,6 +133,7 @@ module SSHKit
133
133
  command(*args).tap do |cmd|
134
134
  output << cmd
135
135
  cmd.started = true
136
+ exit_status = nil
136
137
  with_ssh do |ssh|
137
138
  ssh.open_channel do |chan|
138
139
  chan.request_pty if Netssh.config.pty
@@ -148,9 +149,7 @@ module SSHKit
148
149
  output << cmd
149
150
  end
150
151
  chan.on_request("exit-status") do |ch, data|
151
- cmd.stdout = ''
152
- cmd.stderr = ''
153
- cmd.exit_status = data.read_long
152
+ exit_status = data.read_long
154
153
  output << cmd
155
154
  end
156
155
  #chan.on_request("exit-signal") do |ch, data|
@@ -176,11 +175,12 @@ module SSHKit
176
175
  end
177
176
  ssh.loop
178
177
  end
178
+ cmd.exit_status = exit_status if exit_status
179
179
  end
180
180
  end
181
181
 
182
182
  def with_ssh
183
- host.ssh_options ||= Netssh.config.ssh_options
183
+ host.ssh_options = Netssh.config.ssh_options.merge(host.ssh_options || {})
184
184
  conn = self.class.pool.checkout(
185
185
  String(host.hostname),
186
186
  host.username,
@@ -90,10 +90,8 @@ module SSHKit
90
90
  if options[:raise_on_non_zero_exit] && exit_status > 0
91
91
  message = ""
92
92
  message += "#{command} exit status: " + exit_status.to_s + "\n"
93
- message += "#{command} stdout: " + (stdout.strip.empty? ? "Nothing written" : stdout.strip) + "\n"
94
-
95
- stderr_message = [stderr.strip, full_stderr.strip].delete_if(&:empty?).first
96
- message += "#{command} stderr: " + (stderr_message || 'Nothing written') + "\n"
93
+ message += "#{command} stdout: " + (full_stdout.strip.empty? ? "Nothing written" : full_stdout.strip) + "\n"
94
+ message += "#{command} stderr: " + (full_stderr.strip.empty? ? 'Nothing written' : full_stderr.strip) + "\n"
97
95
  raise Failed, message
98
96
  end
99
97
  end
@@ -8,14 +8,6 @@ module SSHKit
8
8
  def initialize cause
9
9
  @cause = cause
10
10
  end
11
-
12
- def backtrace
13
- @cause.backtrace
14
- end
15
-
16
- def backtrace_locations
17
- @cause.backtrace_locations
18
- end
19
11
  end
20
12
  end
21
13
  end
@@ -34,6 +34,7 @@ module SSHKit
34
34
  uuid(command) + c.green("\t" + line)]
35
35
  original_output << "\n" unless line[-1] == "\n"
36
36
  end
37
+ command.stdout = ''
37
38
  end
38
39
 
39
40
  unless command.stderr.empty?
@@ -42,6 +43,7 @@ module SSHKit
42
43
  uuid(command) + c.red("\t" + line)]
43
44
  original_output << "\n" unless line[-1] == "\n"
44
45
  end
46
+ command.stderr = ''
45
47
  end
46
48
  end
47
49
 
@@ -1,4 +1,5 @@
1
1
  require 'ostruct'
2
+ require 'etc'
2
3
 
3
4
  module SSHKit
4
5
 
@@ -22,7 +23,11 @@ module SSHKit
22
23
 
23
24
  def initialize(host_string_or_options_hash)
24
25
 
25
- unless host_string_or_options_hash.is_a?(Hash)
26
+ if host_string_or_options_hash == :local
27
+ @local = true
28
+ @hostname = "localhost"
29
+ @user = Etc.getpwuid.name
30
+ elsif !host_string_or_options_hash.is_a?(Hash)
26
31
  suitable_parsers = [
27
32
  SimpleHostParser,
28
33
  HostWithPortParser,
@@ -51,6 +56,10 @@ module SSHKit
51
56
  end
52
57
  end
53
58
 
59
+ def local?
60
+ @local
61
+ end
62
+
54
63
  def hash
55
64
  user.hash ^ hostname.hash ^ port.hash
56
65
  end
@@ -15,7 +15,11 @@ module SSHKit
15
15
  private
16
16
 
17
17
  def backend(host, &block)
18
- SSHKit.config.backend.new(host, &block)
18
+ if host.local?
19
+ SSHKit::Backend::Local.new(&block)
20
+ else
21
+ SSHKit.config.backend.new(host, &block)
22
+ end
19
23
  end
20
24
 
21
25
  end
@@ -1,3 +1,3 @@
1
1
  module SSHKit
2
- VERSION = "1.6.1"
2
+ VERSION = "1.7.0"
3
3
  end
@@ -65,6 +65,17 @@ module SSHKit
65
65
  end
66
66
  end
67
67
 
68
+ def test_ssh_option_merge
69
+ a_host.ssh_options = { paranoid: true }
70
+ host_ssh_options = {}
71
+ SSHKit::Backend::Netssh.config.ssh_options = { forward_agent: false }
72
+ Netssh.new(a_host) do |host|
73
+ capture(:uname)
74
+ host_ssh_options = host.ssh_options
75
+ end.run
76
+ assert_equal({ forward_agent: false, paranoid: true }, host_ssh_options)
77
+ end
78
+
68
79
  def test_execute_raises_on_non_zero_exit_status_and_captures_stdout_and_stderr
69
80
  err = assert_raises SSHKit::Command::Failed do
70
81
  Netssh.new(a_host) do |host|
@@ -1,4 +1,5 @@
1
1
  require 'helper'
2
+ require 'etc'
2
3
 
3
4
  module SSHKit
4
5
 
@@ -41,6 +42,14 @@ module SSHKit
41
42
  assert_equal 'example.com', h.hostname
42
43
  end
43
44
 
45
+ def test_host_local
46
+ h = Host.new :local
47
+ assert h.local?
48
+ assert_nil h.port
49
+ assert_equal Etc.getpwuid.name, h.username
50
+ assert_equal 'localhost', h.hostname
51
+ end
52
+
44
53
  def test_does_not_confuse_ipv6_hosts_with_port_specification
45
54
  h = Host.new '[1fff:0:a88:85a3::ac1f]:8001'
46
55
  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.6.1
4
+ version: 1.7.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: 2014-12-16 00:00:00.000000000 Z
12
+ date: 2015-03-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: net-ssh
@@ -151,8 +151,8 @@ files:
151
151
  - RELEASING.md
152
152
  - Rakefile
153
153
  - Vagrantfile
154
- - assets/images/example_output.png
155
- - assets/images/logo.png
154
+ - examples/images/example_output.png
155
+ - examples/images/logo.png
156
156
  - lib/core_ext/array.rb
157
157
  - lib/core_ext/hash.rb
158
158
  - lib/sshkit.rb
@@ -227,7 +227,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
227
227
  version: '0'
228
228
  requirements: []
229
229
  rubyforge_project:
230
- rubygems_version: 2.2.2
230
+ rubygems_version: 2.4.3
231
231
  signing_key:
232
232
  specification_version: 4
233
233
  summary: SSHKit makes it easy to write structured, testable SSH commands in Ruby