sshkit 0.0.25 → 0.0.26

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cbb3f36f6373d515b4313fc92514655ba7ca36e0
4
+ data.tar.gz: 484fd64e12a264d5bdaffe1e0a680194739930c5
5
+ SHA512:
6
+ metadata.gz: e2d81fb0548c2a2d66763cb9a3ca7afa71753955264da34a8d5c9c6b83cefbaa2a073970f3a4059d87597f3c6998d57c687cdedbf596dbcd6a7efb099725e675
7
+ data.tar.gz: 3c2e49e6cff7cc951097ece2084824ea7350a3d36bb34008a82ce3b14af31b420d9019c5e71c6b9a5cae0217f30f0a70cc70264ea437b994345bd3609391798f
data/.travis.yml CHANGED
@@ -2,5 +2,6 @@ before_install: echo 'yes' | gem uninstall ffi -a -I || true
2
2
  language: ruby
3
3
  rvm:
4
4
  - 1.9.3
5
+ - 2.0.0
5
6
  - jruby-19mode
6
7
  - rbx-19mode
data/CHANGELOG.md CHANGED
@@ -3,6 +3,21 @@
3
3
  This file is written in reverse chronological order, newer releases will
4
4
  appear at the top.
5
5
 
6
+ ## 0.0.26
7
+
8
+ * Pretty output no longer prints white text. ("Command.....")
9
+ * Fixed a double-output bug, where upon receiving the exit status from a
10
+ remote command, the last data packet that it sent would be re-printed
11
+ by the pretty formatter.
12
+ * Integration tests now use an Ubuntu Precise 64 Vagrant base box.
13
+ * Additional host declaration syntax, `SSHKit::Host` can now take a hash of
14
+ host properties in addition to a number of new (common sense) DSN type
15
+ syntaxes.
16
+ * Changes to the constants used for logging, we no longer re-define a
17
+ `Logger::TRACE` constant on the global `Logger` class, rather everyhing
18
+ now uses `SSHKit::Logger` (Thanks to Rafa Garcia)
19
+ * Various syntax and documentation fixes.
20
+
6
21
  ## 0.0.25
7
22
 
8
23
  * `upload!` and `download!` now log to different levels depending on
@@ -34,7 +49,7 @@ appear at the top.
34
49
  * `upload!` and `download!` now print progress reports at the `Logger::INFO`
35
50
  verbosity level.
36
51
 
37
- ## 0.0.23
52
+ ## 0.0.23
38
53
 
39
54
  * Explicitly rely on `net-scp` gem.
40
55
 
@@ -166,7 +181,7 @@ appear at the top.
166
181
  can be used to set, for example a umask of `007` for allowing users with
167
182
  the same primary group to share code without stepping on eachother's toes.
168
183
 
169
- ## 0.0.13
184
+ ## 0.0.13
170
185
 
171
186
  * Correctly quote `as(user)` commands, previously it would expand to:
172
187
  `sudo su user -c /usr/bin/env echo "Hello World"`, in which the command to
@@ -220,7 +235,7 @@ descriptors and redirecting them. Programs that re-open, or otherwise
220
235
  manipulate their own file descriptors may lock up when the SSH session is
221
236
  disconnected, often they block writing to, or reading from stdin/out.
222
237
 
223
- ## 0.0.7
238
+ ## 0.0.7
224
239
 
225
240
  * DSL method `execute()` will now raise `SSHKit::Command::Failed` when the
226
241
  exit status is non-zero. The message of the exception will be whatever the
@@ -314,7 +329,7 @@ version `0.0.5`.
314
329
 
315
330
  * Refactor the runner classes into an abstract heirarchy.
316
331
 
317
- ## 0.0.2
332
+ ## 0.0.2
318
333
 
319
334
  * Include a *Pretty* formatter
320
335
  * Modify example to use Pretty formatter.
data/Vagrantfile CHANGED
@@ -5,15 +5,15 @@
5
5
  Vagrant::Config.run do |config|
6
6
 
7
7
  config.vm.define :one do |one|
8
- one.vm.box = "lucid32"
8
+ one.vm.box = "precise64"
9
9
  end
10
10
 
11
11
  config.vm.define :two do |one|
12
- one.vm.box = "lucid32"
12
+ one.vm.box = "precise64"
13
13
  end
14
14
 
15
15
  config.vm.define :three do |one|
16
- one.vm.box = "lucid32"
16
+ one.vm.box = "precise64"
17
17
  end
18
18
 
19
19
  end
data/lib/sshkit/all.rb CHANGED
@@ -8,6 +8,7 @@ require_relative 'command'
8
8
  require_relative 'configuration'
9
9
  require_relative 'coordinator'
10
10
 
11
+ require_relative 'logger'
11
12
  require_relative 'log_message'
12
13
 
13
14
  require_relative 'formatters/abstract'
@@ -42,6 +42,10 @@ module SSHKit
42
42
  output << LogMessage.new(Logger::DEBUG, messages)
43
43
  end
44
44
 
45
+ def trace(messages)
46
+ output << LogMessage.new(Logger::TRACE, messages)
47
+ end
48
+
45
49
  def make(commands=[])
46
50
  raise MethodUnavailableError
47
51
  end
@@ -2,6 +2,27 @@ require 'net/ssh'
2
2
  require 'net/scp'
3
3
 
4
4
  module SSHKit
5
+
6
+ class Logger
7
+
8
+ class Net::SSH::LogLevelShim
9
+ attr_reader :output
10
+ def initialize(output)
11
+ @output = output
12
+ end
13
+ def debug(args)
14
+ output << LogMessage.new(Logger::TRACE, args)
15
+ end
16
+ def error(args)
17
+ output << LogMessage.new(Logger::ERROR, args)
18
+ end
19
+ def lwarn(args)
20
+ output << LogMessage.new(Logger::WARN, args)
21
+ end
22
+ end
23
+
24
+ end
25
+
5
26
  module Backend
6
27
 
7
28
  class Netssh < Printer
@@ -90,8 +111,9 @@ module SSHKit
90
111
  output << cmd
91
112
  end
92
113
  chan.on_request("exit-status") do |ch, data|
93
- exit_status = data.read_long
94
- cmd.exit_status = exit_status
114
+ cmd.stdout = ''
115
+ cmd.stderr = ''
116
+ cmd.exit_status = data.read_long
95
117
  output << cmd
96
118
  end
97
119
  #chan.on_request("exit-signal") do |ch, data|
@@ -124,8 +146,7 @@ module SSHKit
124
146
  Net::SSH.start(
125
147
  host.hostname,
126
148
  host.username,
127
- port: host.port,
128
- password: host.password,
149
+ host.netssh_options
129
150
  )
130
151
  end
131
152
  end
@@ -106,8 +106,8 @@ module SSHKit
106
106
  args: args,
107
107
  options: options,
108
108
  exit_status: exit_status,
109
- stdout: stdout,
110
- stderr: stderr,
109
+ stdout: full_stdout,
110
+ stderr: full_stderr,
111
111
  started_at: @started_at,
112
112
  finished_at: @finished_at,
113
113
  runtime: runtime,
@@ -23,7 +23,7 @@ module SSHKit
23
23
  unless command.started?
24
24
  original_output << level(command.verbosity) + uuid(command) + "Running #{c.yellow(c.bold(String(command)))} on #{c.blue(command.host.to_s)}\n"
25
25
  if SSHKit.config.output_verbosity == Logger::DEBUG
26
- original_output << level(Logger::DEBUG) + uuid(command) + c.white("Command: #{c.blue(command.to_command)}") + "\n"
26
+ original_output << level(Logger::DEBUG) + uuid(command) + "Command: #{c.blue(command.to_command)}" + "\n"
27
27
  end
28
28
  end
29
29
 
data/lib/sshkit/host.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'etc'
1
2
  require 'ostruct'
2
3
 
3
4
  module SSHKit
@@ -6,34 +7,58 @@ module SSHKit
6
7
 
7
8
  class Host
8
9
 
9
- attr_reader :hostname, :port, :username
10
+ attr_accessor :password, :hostname, :port, :user
10
11
 
11
- attr_accessor :password
12
+ def key=(new_key)
13
+ @keys = [new_key]
14
+ end
12
15
 
13
- def initialize(host_string)
16
+ def keys=(new_keys)
17
+ @keys = new_keys
18
+ end
14
19
 
15
- suitable_parsers = [
16
- SimpleHostParser,
17
- HostWithPortParser,
18
- IPv6HostWithPortParser,
19
- HostWithUsernameParser,
20
- HostWithUsernameAndPortParser
21
- ].select do |p|
22
- p.suitable?(host_string)
23
- end
20
+ def keys
21
+ Array(@keys)
22
+ end
23
+
24
+ def initialize(host_string_or_options_hash)
25
+
26
+ unless host_string_or_options_hash.is_a?(Hash)
27
+ suitable_parsers = [
28
+ SimpleHostParser,
29
+ HostWithPortParser,
30
+ HostWithUsernameAndPortParser,
31
+ IPv6HostWithPortParser,
32
+ HostWithUsernameParser,
33
+ HostWithUsernameAndPortParser
34
+ ].select do |p|
35
+ p.suitable?(host_string_or_options_hash)
36
+ end
24
37
 
25
- if suitable_parsers.any?
26
- suitable_parsers.first.tap do |parser|
27
- @username, @hostname, @port = parser.new(host_string).attributes
38
+ if suitable_parsers.any?
39
+ suitable_parsers.first.tap do |parser|
40
+ @user, @hostname, @port = parser.new(host_string_or_options_hash).attributes
41
+ end
42
+ else
43
+ raise UnparsableHostStringError, "Cannot parse host string #{host_string_or_options_hash}"
28
44
  end
29
45
  else
30
- raise UnparsableHostStringError, "Cannot parse host string #{host_string}"
46
+ host_string_or_options_hash.each do |key, value|
47
+ if self.respond_to?("#{key}=")
48
+ send("#{key}=", value)
49
+ else
50
+ raise ArgumentError, "Unknown host property #{key}"
51
+ end
52
+ end
31
53
  end
32
-
33
54
  end
34
55
 
35
56
  def hash
36
- username.hash ^ hostname.hash ^ port.hash
57
+ user.hash ^ hostname.hash ^ port.hash
58
+ end
59
+
60
+ def username
61
+ user
37
62
  end
38
63
 
39
64
  def eql?(other_host)
@@ -50,6 +75,15 @@ module SSHKit
50
75
  sprintf("%s@%s:%d", username, hostname, port)
51
76
  end
52
77
 
78
+ def netssh_options
79
+ {
80
+ keys: keys,
81
+ port: port,
82
+ user: user,
83
+ password: password
84
+ }
85
+ end
86
+
53
87
  def properties
54
88
  @properties ||= OpenStruct.new
55
89
  end
@@ -69,7 +103,7 @@ module SSHKit
69
103
  end
70
104
 
71
105
  def username
72
- `whoami`.chomp
106
+ Etc.getlogin
73
107
  end
74
108
 
75
109
  def port
@@ -88,6 +122,26 @@ module SSHKit
88
122
 
89
123
  # @private
90
124
  # :nodoc:
125
+ class HostWithUsernameAndPortParser < SimpleHostParser
126
+
127
+ def self.suitable?(host_string)
128
+ !host_string.match /.*@.*\:.*/
129
+ end
130
+
131
+ def username
132
+ @host_string.split('@').last.to_i
133
+ end
134
+
135
+ def port
136
+ @host_string.split(':').last.to_i
137
+ end
138
+
139
+ def hostname
140
+ @host_string.split(/@|\:/)[1]
141
+ end
142
+
143
+ end
144
+
91
145
  class HostWithPortParser < SimpleHostParser
92
146
 
93
147
  def self.suitable?(host_string)
@@ -0,0 +1,10 @@
1
+ module SSHKit
2
+ class Logger
3
+ TRACE = -1
4
+ DEBUG = 0
5
+ INFO = 1
6
+ WARN = 2
7
+ ERROR = 3
8
+ FATAL = 4
9
+ end
10
+ end
@@ -1,3 +1,3 @@
1
1
  module SSHKit
2
- VERSION = "0.0.25"
2
+ VERSION = "0.0.26"
3
3
  end
@@ -17,6 +17,13 @@ module SSHKit
17
17
  assert_equal 'example.com', h.hostname
18
18
  end
19
19
 
20
+ def test_ipv4_with_username_and_port
21
+ h = Host.new 'user@127.0.0.1:2222'
22
+ assert_equal 2222, h.port
23
+ assert_equal 'user', h.username
24
+ assert_equal '127.0.0.1', h.hostname
25
+ end
26
+
20
27
  def test_host_with_port
21
28
  h = Host.new 'example.com:2222'
22
29
  assert_equal 2222, h.port
@@ -67,6 +74,31 @@ module SSHKit
67
74
  assert_equal [:web, :app], h.properties.roles
68
75
  end
69
76
 
77
+ def test_setting_up_a_host_with_a_hash
78
+ h = Host.new(hostname: 'example.com', port: 1234, key: "~/.ssh/example_com.key")
79
+ assert_equal "example.com", h.hostname
80
+ assert_equal 1234, h.port
81
+ assert_equal "~/.ssh/example_com.key", h.keys.first
82
+ end
83
+
84
+ def test_setting_up_a_host_with_a_hash_raises_on_unknown_keys
85
+ assert_raises ArgumentError do
86
+ Host.new({this_key_doesnt_exist: nil})
87
+ end
88
+ end
89
+
90
+ def test_turning_a_host_into_ssh_options
91
+ Host.new('someuser@example.com:2222').tap do |host|
92
+ host.password = "andthisdoesntevenmakeanysense"
93
+ host.keys = ["~/.ssh/some_key_here"]
94
+ host.netssh_options.tap do |sho|
95
+ assert_equal 2222, sho.fetch(:port)
96
+ assert_equal 'andthisdoesntevenmakeanysense', sho.fetch(:password)
97
+ assert_equal ['~/.ssh/some_key_here'], sho.fetch(:keys)
98
+ end
99
+ end
100
+ end
101
+
70
102
  end
71
103
 
72
104
  end
@@ -0,0 +1,18 @@
1
+ require 'helper'
2
+
3
+ module SSHKit
4
+
5
+ class TestLogger < UnitTest
6
+
7
+ def test_logger_severity_constants
8
+ assert_equal Logger::TRACE, -1
9
+ assert_equal Logger::DEBUG, 0
10
+ assert_equal Logger::INFO, 1
11
+ assert_equal Logger::WARN, 2
12
+ assert_equal Logger::ERROR, 3
13
+ assert_equal Logger::FATAL, 4
14
+ end
15
+
16
+ end
17
+
18
+ end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sshkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.25
5
- prerelease:
4
+ version: 0.0.26
6
5
  platform: ruby
7
6
  authors:
8
7
  - Lee Hambley
@@ -10,62 +9,55 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2013-04-04 00:00:00.000000000 Z
12
+ date: 2013-06-14 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: net-ssh
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
- - - ! '>='
18
+ - - '>='
21
19
  - !ruby/object:Gem::Version
22
20
  version: '0'
23
21
  type: :runtime
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
- - - ! '>='
25
+ - - '>='
29
26
  - !ruby/object:Gem::Version
30
27
  version: '0'
31
28
  - !ruby/object:Gem::Dependency
32
29
  name: net-scp
33
30
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
31
  requirements:
36
- - - ! '>='
32
+ - - '>='
37
33
  - !ruby/object:Gem::Version
38
34
  version: '0'
39
35
  type: :runtime
40
36
  prerelease: false
41
37
  version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
38
  requirements:
44
- - - ! '>='
39
+ - - '>='
45
40
  - !ruby/object:Gem::Version
46
41
  version: '0'
47
42
  - !ruby/object:Gem::Dependency
48
43
  name: term-ansicolor
49
44
  requirement: !ruby/object:Gem::Requirement
50
- none: false
51
45
  requirements:
52
- - - ! '>='
46
+ - - '>='
53
47
  - !ruby/object:Gem::Version
54
48
  version: '0'
55
49
  type: :runtime
56
50
  prerelease: false
57
51
  version_requirements: !ruby/object:Gem::Requirement
58
- none: false
59
52
  requirements:
60
- - - ! '>='
53
+ - - '>='
61
54
  - !ruby/object:Gem::Version
62
55
  version: '0'
63
56
  - !ruby/object:Gem::Dependency
64
57
  name: minitest
65
58
  requirement: !ruby/object:Gem::Requirement
66
- none: false
67
59
  requirements:
68
- - - ! '>='
60
+ - - '>='
69
61
  - !ruby/object:Gem::Version
70
62
  version: 2.11.3
71
63
  - - <
@@ -74,9 +66,8 @@ dependencies:
74
66
  type: :development
75
67
  prerelease: false
76
68
  version_requirements: !ruby/object:Gem::Requirement
77
- none: false
78
69
  requirements:
79
- - - ! '>='
70
+ - - '>='
80
71
  - !ruby/object:Gem::Version
81
72
  version: 2.11.3
82
73
  - - <
@@ -85,129 +76,113 @@ dependencies:
85
76
  - !ruby/object:Gem::Dependency
86
77
  name: rake
87
78
  requirement: !ruby/object:Gem::Requirement
88
- none: false
89
79
  requirements:
90
- - - ! '>='
80
+ - - '>='
91
81
  - !ruby/object:Gem::Version
92
82
  version: '0'
93
83
  type: :development
94
84
  prerelease: false
95
85
  version_requirements: !ruby/object:Gem::Requirement
96
- none: false
97
86
  requirements:
98
- - - ! '>='
87
+ - - '>='
99
88
  - !ruby/object:Gem::Version
100
89
  version: '0'
101
90
  - !ruby/object:Gem::Dependency
102
91
  name: turn
103
92
  requirement: !ruby/object:Gem::Requirement
104
- none: false
105
93
  requirements:
106
- - - ! '>='
94
+ - - '>='
107
95
  - !ruby/object:Gem::Version
108
96
  version: '0'
109
97
  type: :development
110
98
  prerelease: false
111
99
  version_requirements: !ruby/object:Gem::Requirement
112
- none: false
113
100
  requirements:
114
- - - ! '>='
101
+ - - '>='
115
102
  - !ruby/object:Gem::Version
116
103
  version: '0'
117
104
  - !ruby/object:Gem::Dependency
118
105
  name: unindent
119
106
  requirement: !ruby/object:Gem::Requirement
120
- none: false
121
107
  requirements:
122
- - - ! '>='
108
+ - - '>='
123
109
  - !ruby/object:Gem::Version
124
110
  version: '0'
125
111
  type: :development
126
112
  prerelease: false
127
113
  version_requirements: !ruby/object:Gem::Requirement
128
- none: false
129
114
  requirements:
130
- - - ! '>='
115
+ - - '>='
131
116
  - !ruby/object:Gem::Version
132
117
  version: '0'
133
118
  - !ruby/object:Gem::Dependency
134
119
  name: mocha
135
120
  requirement: !ruby/object:Gem::Requirement
136
- none: false
137
121
  requirements:
138
- - - ! '>='
122
+ - - '>='
139
123
  - !ruby/object:Gem::Version
140
124
  version: '0'
141
125
  type: :development
142
126
  prerelease: false
143
127
  version_requirements: !ruby/object:Gem::Requirement
144
- none: false
145
128
  requirements:
146
- - - ! '>='
129
+ - - '>='
147
130
  - !ruby/object:Gem::Version
148
131
  version: '0'
149
132
  - !ruby/object:Gem::Dependency
150
133
  name: debugger
151
134
  requirement: !ruby/object:Gem::Requirement
152
- none: false
153
135
  requirements:
154
- - - ! '>='
136
+ - - '>='
155
137
  - !ruby/object:Gem::Version
156
138
  version: '0'
157
139
  type: :development
158
140
  prerelease: false
159
141
  version_requirements: !ruby/object:Gem::Requirement
160
- none: false
161
142
  requirements:
162
- - - ! '>='
143
+ - - '>='
163
144
  - !ruby/object:Gem::Version
164
145
  version: '0'
165
146
  - !ruby/object:Gem::Dependency
166
147
  name: vagrant
167
148
  requirement: !ruby/object:Gem::Requirement
168
- none: false
169
149
  requirements:
170
- - - ! '>='
150
+ - - '>='
171
151
  - !ruby/object:Gem::Version
172
152
  version: '0'
173
153
  type: :development
174
154
  prerelease: false
175
155
  version_requirements: !ruby/object:Gem::Requirement
176
- none: false
177
156
  requirements:
178
- - - ! '>='
157
+ - - '>='
179
158
  - !ruby/object:Gem::Version
180
159
  version: '0'
181
160
  - !ruby/object:Gem::Dependency
182
161
  name: yard
183
162
  requirement: !ruby/object:Gem::Requirement
184
- none: false
185
163
  requirements:
186
- - - ! '>='
164
+ - - '>='
187
165
  - !ruby/object:Gem::Version
188
166
  version: '0'
189
167
  type: :development
190
168
  prerelease: false
191
169
  version_requirements: !ruby/object:Gem::Requirement
192
- none: false
193
170
  requirements:
194
- - - ! '>='
171
+ - - '>='
195
172
  - !ruby/object:Gem::Version
196
173
  version: '0'
197
174
  - !ruby/object:Gem::Dependency
198
175
  name: redcarpet
199
176
  requirement: !ruby/object:Gem::Requirement
200
- none: false
201
177
  requirements:
202
- - - ! '>='
178
+ - - '>='
203
179
  - !ruby/object:Gem::Version
204
180
  version: '0'
205
181
  type: :development
206
182
  prerelease: false
207
183
  version_requirements: !ruby/object:Gem::Requirement
208
- none: false
209
184
  requirements:
210
- - - ! '>='
185
+ - - '>='
211
186
  - !ruby/object:Gem::Version
212
187
  version: '0'
213
188
  description: A comprehensive toolkit for remotely running commands in a structured
@@ -251,6 +226,7 @@ files:
251
226
  - lib/sshkit/formatters/pretty.rb
252
227
  - lib/sshkit/host.rb
253
228
  - lib/sshkit/log_message.rb
229
+ - lib/sshkit/logger.rb
254
230
  - lib/sshkit/runners/abstract.rb
255
231
  - lib/sshkit/runners/group.rb
256
232
  - lib/sshkit/runners/parallel.rb
@@ -269,29 +245,29 @@ files:
269
245
  - test/unit/test_configuration.rb
270
246
  - test/unit/test_coordinator.rb
271
247
  - test/unit/test_host.rb
248
+ - test/unit/test_logger.rb
272
249
  homepage: http://wacku.github.com/sshkit
273
250
  licenses: []
251
+ metadata: {}
274
252
  post_install_message:
275
253
  rdoc_options: []
276
254
  require_paths:
277
255
  - lib
278
256
  required_ruby_version: !ruby/object:Gem::Requirement
279
- none: false
280
257
  requirements:
281
- - - ! '>='
258
+ - - '>='
282
259
  - !ruby/object:Gem::Version
283
260
  version: '0'
284
261
  required_rubygems_version: !ruby/object:Gem::Requirement
285
- none: false
286
262
  requirements:
287
- - - ! '>='
263
+ - - '>='
288
264
  - !ruby/object:Gem::Version
289
265
  version: '0'
290
266
  requirements: []
291
267
  rubyforge_project:
292
- rubygems_version: 1.8.23
268
+ rubygems_version: 2.0.2
293
269
  signing_key:
294
- specification_version: 3
270
+ specification_version: 4
295
271
  summary: SSHKit makes it easy to write structured, testable SSH commands in Ruby
296
272
  test_files:
297
273
  - test/functional/backends/test_netssh.rb
@@ -306,4 +282,5 @@ test_files:
306
282
  - test/unit/test_configuration.rb
307
283
  - test/unit/test_coordinator.rb
308
284
  - test/unit/test_host.rb
285
+ - test/unit/test_logger.rb
309
286
  has_rdoc: