remote_executor 0.9.2 → 0.9.3
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.
- data/bin/remote_executor +1 -6
- data/lib/remote_executor/cli_application.rb +42 -32
- data/lib/remote_executor/command_set.rb +36 -0
- data/lib/remote_executor/version.rb +1 -1
- data/test/test_command_set.rb +28 -0
- data/test/test_system.rb +0 -1
- metadata +6 -3
data/bin/remote_executor
CHANGED
@@ -5,9 +5,4 @@ $:.unshift( File.join( File.dirname( __FILE__ ), %w[.. lib] ) )
|
|
5
5
|
|
6
6
|
require 'loader'
|
7
7
|
|
8
|
-
RemoteExecutor::CliApplication.run
|
9
|
-
Choice.choices[:config],
|
10
|
-
Choice.choices[:log],
|
11
|
-
Choice.choices[:threaded],
|
12
|
-
Choice.choices[:system],
|
13
|
-
Choice.choices[:commands] )
|
8
|
+
RemoteExecutor::CliApplication.run
|
@@ -1,58 +1,68 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
require 'choice'
|
2
3
|
require 'mini_logger'
|
3
4
|
require 'net/ssh'
|
4
5
|
|
5
6
|
|
6
7
|
module RemoteExecutor
|
8
|
+
class SshExecutionError < StandardError
|
9
|
+
end
|
10
|
+
|
7
11
|
##
|
8
12
|
# CLI Application a simple point of entry
|
9
13
|
class CliApplication
|
14
|
+
|
15
|
+
DEFAULT_SSH_OPTIONS = { :config=>true }
|
10
16
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
def self.execute_commands( server, user, commands, ssh_options={ :config=>true } )
|
17
|
+
def self.execute_commands( server, user, commands, ssh_options=DEFAULT_SSH_OPTIONS )
|
15
18
|
|
16
19
|
Net::SSH.start( server, user, ssh_options ) do |ssh|
|
17
20
|
|
18
|
-
commands.
|
21
|
+
commands.each do |command|
|
19
22
|
|
20
23
|
MiniLogger.debug( "Executing command #{user}@#{server} '#{command}'")
|
21
|
-
|
22
|
-
|
24
|
+
|
25
|
+
channel = ssh.open_channel do |ch|
|
26
|
+
|
27
|
+
ch.exec "#{command}" do |ch, success|
|
28
|
+
|
29
|
+
raise SshExecutionError.new( "could not execute: #{command}" ) unless success
|
30
|
+
|
31
|
+
ch.on_data { |c, data| $stdout.print data }
|
32
|
+
ch.on_extended_data { |c, type, data| MiniLogger.error( "STDERR: #{data}" ) }
|
33
|
+
|
34
|
+
ch.on_close { MiniLogger.info( "done!" ) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
channel.wait
|
39
|
+
end
|
23
40
|
end
|
24
41
|
end
|
25
42
|
|
26
43
|
|
27
|
-
def self.
|
44
|
+
def self.run()
|
45
|
+
|
46
|
+
MiniLogger.configure( :log_channel=>Choice.choices[:log], :log_level=>::Logger::DEBUG )
|
47
|
+
|
48
|
+
systems = Systems.new( Choice.choices[:config] )
|
49
|
+
system = systems.find_by_name( Choice.choices[:system] )
|
50
|
+
user = system.user
|
51
|
+
commands = CommandSet.new( Choice.choices[:commands] )
|
28
52
|
|
29
|
-
if( threaded )
|
53
|
+
if( Choice.choices[:threaded] )
|
30
54
|
|
31
|
-
|
32
|
-
|
33
|
-
system.hosts.each
|
34
|
-
|
35
|
-
threads << Thread.new( server ) { |t| execute_commands( server, system.user, commands ) }
|
36
|
-
end
|
37
|
-
|
38
|
-
threads.each { |t| t.join }
|
55
|
+
# Launch the commands in threaded mode
|
56
|
+
ts = []
|
57
|
+
system.hosts.each { |s| ts << Thread.new( s ) { |t| execute_commands( s, user, commands ) } }
|
58
|
+
ts.each { |t| t.join }
|
39
59
|
else
|
40
60
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
def self.run( systems_config, log, threaded, name, commands )
|
49
|
-
|
50
|
-
MiniLogger.configure( :log_channel=>log, :log_level=>::Logger::DEBUG )
|
51
|
-
process_system( Systems.new( systems_config ).find_by_name( name ), commands, threaded )
|
52
|
-
rescue SystemsFileError =>sfe
|
53
|
-
MiniLogger.error( sfe.message )
|
54
|
-
rescue SystemNotFound =>snf
|
55
|
-
MiniLogger.error( snf.message )
|
61
|
+
# Launch the commands in batch mode
|
62
|
+
system.hosts.each { |s| execute_commands( s, user, commands ) }
|
63
|
+
end
|
64
|
+
rescue StandardError =>se
|
65
|
+
MiniLogger.error( se )
|
56
66
|
end
|
57
67
|
end
|
58
68
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module RemoteExecutor
|
2
|
+
##
|
3
|
+
# Command representation
|
4
|
+
class CommandSet
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
DEFAULT_COMMAND_SEPARATOR = ";"
|
8
|
+
|
9
|
+
attr_reader :commands
|
10
|
+
|
11
|
+
def self.parse( commands_str, separator=DEFAULT_COMMAND_SEPARATOR )
|
12
|
+
|
13
|
+
commands = Array.new
|
14
|
+
commands_str.split( separator ).each { |command| commands << command.strip }
|
15
|
+
commands
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def initialize( commands_str )
|
20
|
+
|
21
|
+
@commands = CommandSet.parse( commands_str ) if( commands_str )
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def each( &block )
|
27
|
+
|
28
|
+
@commands.each { |command| block.call( command ) } if block_given?
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def length
|
33
|
+
@commands.length
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
$:.unshift( File.join( File.dirname( __FILE__ ), %w[.. lib] ) )
|
2
|
+
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'shoulda'
|
6
|
+
require 'remote_executor/command_set'
|
7
|
+
|
8
|
+
|
9
|
+
class CommandSetTest < Test::Unit::TestCase
|
10
|
+
|
11
|
+
context "CommandSet" do
|
12
|
+
|
13
|
+
COMMANDSET_TEST_DATA = "command1; command2; command3"
|
14
|
+
|
15
|
+
setup do
|
16
|
+
@command_set = RemoteExecutor::CommandSet.new( COMMANDSET_TEST_DATA )
|
17
|
+
end
|
18
|
+
|
19
|
+
should "parse a command set" do
|
20
|
+
assert_equal( @command_set.commands, [ "command1", "command2", "command3" ] )
|
21
|
+
assert_equal( @command_set.length, [ "command1", "command2", "command3" ].length )
|
22
|
+
end
|
23
|
+
|
24
|
+
should "enumerate a command set" do
|
25
|
+
assert_equal( @command_set.length, 3 )
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/test/test_system.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: remote_executor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.9.
|
5
|
+
version: 0.9.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Javier Juarez
|
@@ -42,7 +42,7 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ">="
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
45
|
+
version: 0.2.4
|
46
46
|
type: :runtime
|
47
47
|
prerelease: false
|
48
48
|
version_requirements: *id003
|
@@ -75,7 +75,7 @@ dependencies:
|
|
75
75
|
requirements:
|
76
76
|
- - ">="
|
77
77
|
- !ruby/object:Gem::Version
|
78
|
-
version:
|
78
|
+
version: 0.2.5
|
79
79
|
type: :runtime
|
80
80
|
prerelease: false
|
81
81
|
version_requirements: *id006
|
@@ -91,11 +91,13 @@ files:
|
|
91
91
|
- bin/remote_executor
|
92
92
|
- lib/loader.rb
|
93
93
|
- lib/remote_executor/cli_application.rb
|
94
|
+
- lib/remote_executor/command_set.rb
|
94
95
|
- lib/remote_executor/options_parser.rb
|
95
96
|
- lib/remote_executor/system.rb
|
96
97
|
- lib/remote_executor/systems.rb
|
97
98
|
- lib/remote_executor/version.rb
|
98
99
|
- README.rdoc
|
100
|
+
- test/test_command_set.rb
|
99
101
|
- test/test_system.rb
|
100
102
|
- test/test_systems.rb
|
101
103
|
has_rdoc: true
|
@@ -127,5 +129,6 @@ signing_key:
|
|
127
129
|
specification_version: 3
|
128
130
|
summary: A very simple gem that helps to launch remote commands over SSH connections
|
129
131
|
test_files:
|
132
|
+
- test/test_command_set.rb
|
130
133
|
- test/test_system.rb
|
131
134
|
- test/test_systems.rb
|