sshkit 0.0.34 → 1.0.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/EXAMPLES.md +11 -0
- data/lib/sshkit/all.rb +3 -1
- data/lib/sshkit/backends/abstract.rb +10 -0
- data/lib/sshkit/backends/local.rb +38 -0
- data/lib/sshkit/backends/printer.rb +11 -3
- data/lib/sshkit/backends/skipper.rb +31 -0
- data/lib/sshkit/coordinator.rb +12 -9
- data/lib/sshkit/dsl.rb +4 -0
- data/lib/sshkit/runners/null.rb +12 -0
- data/lib/sshkit/runners/parallel.rb +0 -45
- data/lib/sshkit/version.rb +1 -1
- data/test/functional/backends/test_local.rb +22 -0
- data/test/unit/backends/test_printer.rb +8 -20
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 729d775d8b75d0236bd1756c0c4d3bd1e0ace0b1
|
4
|
+
data.tar.gz: ed4c442b6db439862659f9d5588adf6d4a91e678
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0edeec6c8678ad5307b1221614ab207f76c213034502474c96c438bf6fa68a01355522ea7be34c688a1007936fa2c84d565cd869fdce58ef1c4bb35b3a84f22c
|
7
|
+
data.tar.gz: 6e5aeb51f35d0269d0f4ac89308fa43d5d23c757e1bbe08b76d1cc6294f1e3c07e72cb364a9cecb530bbcd534683aefe3fd5c53208ad13f6ebf36b1ca0553328
|
data/EXAMPLES.md
CHANGED
@@ -352,3 +352,14 @@ Implemented since `v0.0.6`
|
|
352
352
|
The `SSHKit::Host#properties` is an [`OpenStruct`](http://ruby-doc.org/stdlib-1.9.3/libdoc/ostruct/rdoc/OpenStruct.html)
|
353
353
|
which is not verified or validated in any way, it is up to you, or your
|
354
354
|
library to attach meanings or conventions to this mechanism.
|
355
|
+
|
356
|
+
## Running local commands
|
357
|
+
|
358
|
+
Replace `on` with `run_locally`
|
359
|
+
|
360
|
+
run_locally do
|
361
|
+
within '/tmp' do
|
362
|
+
execute :whoami
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
data/lib/sshkit/all.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require_relative '../core_ext/array'
|
2
2
|
require_relative '../core_ext/hash'
|
3
3
|
|
4
|
-
require_relative 'dsl'
|
5
4
|
require_relative 'host'
|
6
5
|
|
7
6
|
require_relative 'command'
|
@@ -20,7 +19,10 @@ require_relative 'runners/abstract'
|
|
20
19
|
require_relative 'runners/sequential'
|
21
20
|
require_relative 'runners/parallel'
|
22
21
|
require_relative 'runners/group'
|
22
|
+
require_relative 'runners/null'
|
23
23
|
|
24
24
|
require_relative 'backends/abstract'
|
25
25
|
require_relative 'backends/printer'
|
26
26
|
require_relative 'backends/netssh'
|
27
|
+
require_relative 'backends/local'
|
28
|
+
require_relative 'backends/skipper'
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'open3'
|
2
|
+
module SSHKit
|
3
|
+
|
4
|
+
module Backend
|
5
|
+
|
6
|
+
class Local < Printer
|
7
|
+
|
8
|
+
def initialize(&block)
|
9
|
+
@block = block
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
instance_exec(&@block)
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute(*args)
|
17
|
+
command(*args).tap do |cmd|
|
18
|
+
output << cmd
|
19
|
+
|
20
|
+
cmd.started = Time.now
|
21
|
+
|
22
|
+
stdout, stderr, exit_status = Open3.capture3(cmd.to_command)
|
23
|
+
|
24
|
+
cmd.stdout = stdout
|
25
|
+
cmd.full_stdout += stdout
|
26
|
+
|
27
|
+
cmd.stderr = stderr
|
28
|
+
cmd.full_stderr += stderr
|
29
|
+
|
30
|
+
cmd.exit_status = exit_status.to_i
|
31
|
+
|
32
|
+
output << cmd
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -10,12 +10,20 @@ module SSHKit
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def execute(*args)
|
13
|
-
|
13
|
+
command(*args).tap do |cmd|
|
14
|
+
output << cmd
|
15
|
+
end
|
14
16
|
end
|
17
|
+
alias :upload! :execute
|
18
|
+
alias :download! :execute
|
19
|
+
alias :test :execute
|
20
|
+
alias :invoke :execute
|
15
21
|
|
16
|
-
def capture(
|
17
|
-
|
22
|
+
def capture(*args)
|
23
|
+
String.new.tap { execute(*args) }
|
18
24
|
end
|
25
|
+
alias :capture! :capture
|
26
|
+
|
19
27
|
|
20
28
|
private
|
21
29
|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module SSHKit
|
2
|
+
module Backend
|
3
|
+
|
4
|
+
class Skipper < Printer
|
5
|
+
|
6
|
+
def initialize(&block)
|
7
|
+
@block = block
|
8
|
+
end
|
9
|
+
|
10
|
+
def execute(*args)
|
11
|
+
command(*args).tap do |cmd|
|
12
|
+
warn "[SKIPPING] No Matching Host for #{cmd}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
alias :upload! :execute
|
16
|
+
alias :download! :execute
|
17
|
+
alias :test :execute
|
18
|
+
alias :invoke :execute
|
19
|
+
|
20
|
+
def info(messages)
|
21
|
+
# suppress all messages except `warn`
|
22
|
+
end
|
23
|
+
alias :log :info
|
24
|
+
alias :fatal :info
|
25
|
+
alias :error :info
|
26
|
+
alias :debug :info
|
27
|
+
alias :trace :info
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/sshkit/coordinator.rb
CHANGED
@@ -6,19 +6,22 @@ module SSHKit
|
|
6
6
|
|
7
7
|
def initialize(raw_hosts)
|
8
8
|
@raw_hosts = Array(raw_hosts)
|
9
|
-
|
10
|
-
resolve_hosts!
|
9
|
+
resolve_hosts! if Array(raw_hosts).any?
|
11
10
|
end
|
12
11
|
|
13
12
|
def each(options={}, &block)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
if hosts
|
14
|
+
options = default_options.merge(options)
|
15
|
+
case options[:in]
|
16
|
+
when :parallel then Runner::Parallel
|
17
|
+
when :sequence then Runner::Sequential
|
18
|
+
when :groups then Runner::Group
|
19
|
+
else
|
20
|
+
raise RuntimeError, "Don't know how to handle run style #{options[:in].inspect}"
|
21
|
+
end.new(hosts, &block).execute
|
19
22
|
else
|
20
|
-
|
21
|
-
end
|
23
|
+
Runner::Null.new(hosts, &block).execute
|
24
|
+
end
|
22
25
|
end
|
23
26
|
|
24
27
|
private
|
data/lib/sshkit/dsl.rb
CHANGED
@@ -4,23 +4,6 @@ module SSHKit
|
|
4
4
|
|
5
5
|
module Runner
|
6
6
|
|
7
|
-
class Abstract
|
8
|
-
|
9
|
-
attr_reader :hosts, :block
|
10
|
-
|
11
|
-
def initialize(hosts, &block)
|
12
|
-
@hosts = Array(hosts)
|
13
|
-
@block = block
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def backend(host, &block)
|
19
|
-
SSHKit.config.backend.new(host, &block)
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
7
|
class Parallel < Abstract
|
25
8
|
def execute
|
26
9
|
threads = []
|
@@ -33,34 +16,6 @@ module SSHKit
|
|
33
16
|
end
|
34
17
|
end
|
35
18
|
|
36
|
-
class Sequential < Abstract
|
37
|
-
attr_writer :wait_interval
|
38
|
-
def execute
|
39
|
-
hosts.each do |host|
|
40
|
-
backend(host, &block).run
|
41
|
-
sleep wait_interval
|
42
|
-
end
|
43
|
-
end
|
44
|
-
private
|
45
|
-
def wait_interval
|
46
|
-
@wait_interval ||= 2
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
class Group < Sequential
|
51
|
-
attr_writer :group_size
|
52
|
-
def execute
|
53
|
-
hosts.each_slice(group_size).collect do |group_hosts|
|
54
|
-
Parallel.new(group_hosts, &block).execute
|
55
|
-
sleep wait_interval
|
56
|
-
end.flatten
|
57
|
-
end
|
58
|
-
private
|
59
|
-
def group_size
|
60
|
-
@group_size ||= 2
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
19
|
end
|
65
20
|
|
66
21
|
end
|
data/lib/sshkit/version.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'helper'
|
2
|
+
module SSHKit
|
3
|
+
|
4
|
+
module Backend
|
5
|
+
|
6
|
+
class TestLocal < MiniTest::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
SSHKit.config.output = SSHKit::Formatter::BlackHole.new($stdout)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_execute_raises_on_non_zero_exit_status_and_captures_stdout_and_stderr
|
13
|
+
err = assert_raises SSHKit::Command::Failed do
|
14
|
+
Local.new do
|
15
|
+
execute :echo, "'Test capturing stderr' 1>&2; false"
|
16
|
+
end.run
|
17
|
+
end
|
18
|
+
assert_equal "echo stdout: Nothing written\necho stderr: Test capturing stderr\n", err.message
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -8,17 +8,7 @@ module SSHKit
|
|
8
8
|
|
9
9
|
def block_to_run
|
10
10
|
lambda do |host|
|
11
|
-
|
12
|
-
execute 'date'
|
13
|
-
execute :ls, '-l', '/some/directory'
|
14
|
-
with rails_env: :production do
|
15
|
-
within :tmp do
|
16
|
-
as :root do
|
17
|
-
execute :touch, 'restart.txt'
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
11
|
+
execute :ls, '-l', '/some/directory'
|
22
12
|
end
|
23
13
|
end
|
24
14
|
|
@@ -26,19 +16,17 @@ module SSHKit
|
|
26
16
|
Printer.new(Host.new(:'example.com'), &block_to_run)
|
27
17
|
end
|
28
18
|
|
19
|
+
def setup
|
20
|
+
SSHKit.config.output_verbosity = :debug
|
21
|
+
end
|
22
|
+
|
29
23
|
def test_simple_printing
|
30
|
-
result =
|
24
|
+
result = StringIO.new
|
31
25
|
SSHKit.capture_output(result) do
|
32
26
|
printer.run
|
33
27
|
end
|
34
|
-
|
35
|
-
|
36
|
-
cd /opt/sites/example.com && /usr/bin/env date
|
37
|
-
cd /opt/sites/example.com && /usr/bin/env ls -l /some/directory
|
38
|
-
if test ! -d /opt/sites/example.com/tmp; then echo "Directory does not exist '/opt/sites/example.com/tmp'" 1>&2; false; fi
|
39
|
-
if ! sudo su root -c whoami > /dev/null; then echo "You cannot switch to user 'root' using sudo, please check the sudoers file" 1>&2; false; fi
|
40
|
-
cd /opt/sites/example.com/tmp && ( RAILS_ENV=production sudo su root -c \"/usr/bin/env touch restart.txt\" )
|
41
|
-
EOEXPECTED
|
28
|
+
result.rewind
|
29
|
+
assert_equal '/usr/bin/env ls -l /some/directory', result.read
|
42
30
|
end
|
43
31
|
|
44
32
|
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: 0.0
|
4
|
+
version: 1.0.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: 2013-
|
12
|
+
date: 2013-10-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: net-ssh
|
@@ -214,8 +214,10 @@ files:
|
|
214
214
|
- lib/sshkit.rb
|
215
215
|
- lib/sshkit/all.rb
|
216
216
|
- lib/sshkit/backends/abstract.rb
|
217
|
+
- lib/sshkit/backends/local.rb
|
217
218
|
- lib/sshkit/backends/netssh.rb
|
218
219
|
- lib/sshkit/backends/printer.rb
|
220
|
+
- lib/sshkit/backends/skipper.rb
|
219
221
|
- lib/sshkit/command.rb
|
220
222
|
- lib/sshkit/configuration.rb
|
221
223
|
- lib/sshkit/coordinator.rb
|
@@ -229,10 +231,12 @@ files:
|
|
229
231
|
- lib/sshkit/logger.rb
|
230
232
|
- lib/sshkit/runners/abstract.rb
|
231
233
|
- lib/sshkit/runners/group.rb
|
234
|
+
- lib/sshkit/runners/null.rb
|
232
235
|
- lib/sshkit/runners/parallel.rb
|
233
236
|
- lib/sshkit/runners/sequential.rb
|
234
237
|
- lib/sshkit/version.rb
|
235
238
|
- sshkit.gemspec
|
239
|
+
- test/functional/backends/test_local.rb
|
236
240
|
- test/functional/backends/test_netssh.rb
|
237
241
|
- test/functional/test_coordinator.rb
|
238
242
|
- test/functional/test_ssh_server_comes_up_for_functional_tests.rb
|
@@ -270,6 +274,7 @@ signing_key:
|
|
270
274
|
specification_version: 4
|
271
275
|
summary: SSHKit makes it easy to write structured, testable SSH commands in Ruby
|
272
276
|
test_files:
|
277
|
+
- test/functional/backends/test_local.rb
|
273
278
|
- test/functional/backends/test_netssh.rb
|
274
279
|
- test/functional/test_coordinator.rb
|
275
280
|
- test/functional/test_ssh_server_comes_up_for_functional_tests.rb
|
@@ -283,4 +288,3 @@ test_files:
|
|
283
288
|
- test/unit/test_coordinator.rb
|
284
289
|
- test/unit/test_host.rb
|
285
290
|
- test/unit/test_logger.rb
|
286
|
-
has_rdoc:
|