script_executor 1.3.2 → 1.3.4

Sign up to get free protection for your applications and to get access to all the features.
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ script_executor
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-1.9.3
data/CHANGES CHANGED
@@ -32,4 +32,12 @@
32
32
 
33
33
  == Version 1.3.2
34
34
 
35
- * Big fix.
35
+ * Big fix.
36
+
37
+ == Version 1.3.3
38
+
39
+ * Big fix.
40
+
41
+ == Version 1.3.4
42
+
43
+ * Internal refactoring.
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source :rubygems
1
+ source "https://rubygems.org"
2
2
 
3
3
  group :default do
4
4
  gem "highline"
@@ -15,16 +15,9 @@ group :test do
15
15
  gem "mocha"
16
16
  end
17
17
 
18
- #group :debug do
19
- # if RUBY_VERSION.include? "1.9"
20
- # unless File.exist? "#{ENV['GEM_HOME']}/gems/linecache19-0.5.13/lib/linecache19.rb"
21
- # `curl -OL http://rubyforge.org/frs/download.php/75414/linecache19-0.5.13.gem`
22
- # `gem i linecache19-0.5.13.gem`
23
- # end
24
- #
25
- # gem "linecache19", "0.5.13"
26
- # gem "ruby-debug-base19x", "0.11.30.pre10"
27
- # gem "ruby-debug-ide", "0.4.17.beta14"
28
- # end
29
- #end
18
+ group :debug do
19
+ gem "ruby-debug-base19x", "0.11.30.pre12"
20
+ gem "ruby-debug-ide", "0.4.17"
21
+ end
22
+
30
23
 
data/Gemfile.lock CHANGED
@@ -1,6 +1,7 @@
1
1
  GEM
2
- remote: http://rubygems.org/
2
+ remote: https://rubygems.org/
3
3
  specs:
4
+ debugger-ruby_core_source (1.2.2)
4
5
  diff-lcs (1.1.3)
5
6
  file_utils (1.0.6)
6
7
  gemcutter (0.7.1)
@@ -11,6 +12,7 @@ GEM
11
12
  mocha (0.13.1)
12
13
  metaclass (~> 0.0.1)
13
14
  net-ssh (2.6.2)
15
+ rake (10.0.4)
14
16
  rspec (2.12.0)
15
17
  rspec-core (~> 2.12.0)
16
18
  rspec-expectations (~> 2.12.0)
@@ -19,6 +21,11 @@ GEM
19
21
  rspec-expectations (2.12.1)
20
22
  diff-lcs (~> 1.1.3)
21
23
  rspec-mocks (2.12.0)
24
+ ruby-debug-base19x (0.11.30.pre12)
25
+ debugger-ruby_core_source (>= 1.1.4)
26
+ rake (>= 0.8.1)
27
+ ruby-debug-ide (0.4.17)
28
+ rake (>= 0.8.1)
22
29
 
23
30
  PLATFORMS
24
31
  ruby
@@ -30,3 +37,5 @@ DEPENDENCIES
30
37
  mocha
31
38
  net-ssh
32
39
  rspec
40
+ ruby-debug-base19x (= 0.11.30.pre12)
41
+ ruby-debug-ide (= 0.4.17)
data/README.md CHANGED
@@ -4,39 +4,115 @@
4
4
 
5
5
  Add this line to your application's Gemfile:
6
6
 
7
- gem 'script_executor'
8
-
7
+ ```bash
8
+ gem 'script_executor'
9
+ ```
9
10
  And then execute:
10
11
 
11
- $ bundle
12
+ ```bash
13
+ bundle
14
+ ```
12
15
 
13
16
  Or install it yourself as:
14
17
 
15
- $ gem install script_executor
18
+ ```bash
19
+ gem install script_executor
20
+ ```
16
21
 
17
22
  ## Usage
18
-
19
- executor = ScriptExecutor.new
20
23
 
21
- executor.execute "ls" # execute locally
24
+ ```ruby
25
+ # Create executor
26
+ executor = ScriptExecutor.new
27
+ ```
28
+
29
+ * Execute local command:
30
+
31
+ ```ruby
32
+ executor.execute "ls"
33
+ ```
34
+
35
+ * Execute remote command:
36
+
37
+ ```ruby
38
+ server_info = {
39
+ :remote => true,
40
+ :domain => "some.host",
41
+ :user => "some.user",
42
+ }
43
+
44
+ executor.execute server_info.merge(:script => "ls -al")
45
+ ```
46
+
47
+ * Execute remote command as 'sudo':
48
+
49
+ ```ruby
50
+ executor.execute server_info.merge({:sudo => true, :script => "/etc/init.d/tomcat stop"})
51
+ ```
52
+
53
+ * Execute remote command with code block:
54
+
55
+ ```ruby
56
+ executor.execute server_info.merge(:sudo => true) do
57
+ %Q(
58
+ /etc/init.d/tomcat stop
59
+ /etc/init.d/tomcat start
60
+ )
61
+ end
62
+ ```
63
+
64
+ * Execute remote command while capturing and suppressing output (default is 'false'):
65
+
66
+ ```ruby
67
+ server_info.merge(:capture_output => true, :suppress_output => true)
68
+
69
+ result = executor.execute server_info.merge(:script => "whoami")
70
+
71
+ puts result # ENV['USER']
72
+ ```
73
+
74
+ * Simulate remote execution:
75
+
76
+ ```ruby
77
+ server_info.merge(:simulate => true)
78
+
79
+ executor.execute server_info.merge(:script => "whoami") # generate commands without actual execution
80
+ ```
81
+
82
+ ## Using ScriptLocator
83
+
84
+ You can keep scripts that needs to be executed embedded into your code (as in examples above),
85
+ move them into separate file or keep them in same file behind "__END__" Ruby directive.
86
+ The latter gives you the ability to keep command and code together thus simplifying
87
+ access to code.
88
+
89
+ For example, if you want to create script with 2 commands (command1, command2), you can use
90
+ "scripts" and "evaluate_script_body" methods:
91
+
92
+ ```ruby
93
+ require 'script_locator'
94
+
95
+ include ScriptLocator
96
+
97
+ puts scripts(__FILE__) # [command1, command2]
98
+
99
+ name = "john"
100
+
101
+ result = evaluate_script_body(result['command1'], binding)
102
+
103
+ puts result # john
104
+ __END__
105
+
106
+ [command1]
22
107
 
23
- executor.execute :remote => true, :script => "ls -al", :domain => "localhost", :user => "user" # execute remote
108
+ echo "<%= name %>"
24
109
 
25
- executor.remote_execute :script => "ls -al", :domain => "localhost", :user => "user" # execute remote
110
+ [command2]
26
111
 
27
- executor.remote_execute :sudo => true, :script => "/etc/init.d/tomcat stop", :domain => "somehost", :user => "user" # execute remote
112
+ echo "test2"
113
+ ```
28
114
 
29
- server_info = {
30
- :domain => "some.host",
31
- :user => "some.user",
32
- }
33
115
 
34
- executor.remote_execute :sudo => true, server_info do # execute remote with sudo
35
- %Q(
36
- /etc/init.d/tomcat stop
37
- /etc/init.d/tomcat start
38
- )
39
- end
40
116
 
41
117
  ## Contributing
42
118
 
data/lib/executable.rb CHANGED
@@ -1,3 +1 @@
1
- require 'rubygems' unless Object.const_defined?(:Gem)
2
-
3
1
  require 'script_executor/executable'
@@ -1,3 +1 @@
1
- require 'rubygems' unless Object.const_defined?(:Gem)
2
-
3
1
  require 'script_executor/script_executor'
@@ -1,14 +1,8 @@
1
- require 'net/ssh'
2
- require "highline/import"
3
-
4
- require 'script_executor/output_buffer'
1
+ require 'script_executor/local_command'
2
+ require 'script_executor/remote_command'
5
3
 
6
4
  module Executable
7
5
 
8
- def output
9
- @output ||= $stdout
10
- end
11
-
12
6
  def execute params={}, &code
13
7
  if params.class != Hash
14
8
  simple_commands = commands_from_object(params)
@@ -21,120 +15,25 @@ module Executable
21
15
  commands = locate_commands script, &code
22
16
 
23
17
  if commands.nil?
24
- output.puts "No commands were provided!"
25
- return
26
- end
27
-
28
- commands = sudo(commands) if params[:sudo]
29
-
30
- remote = params[:remote]
31
- domain = params[:domain]
32
- user = params[:user]
33
- password = params[:password]
34
- capture_output = params[:capture_output]
35
- suppress_output = params[:suppress_output]
36
- simulate = params[:simulate]
37
- line_action = params[:line_action]
38
-
39
- print_execution commands, remote, domain, user, nil, simulate
18
+ output.puts "No command was provided!"
19
+ else
20
+ commands = sudo(commands) if params[:sudo]
40
21
 
41
- unless simulate
42
- storage = capture_output ? OutputBuffer.new : nil
43
- suppress_output = suppress_output.nil? ? capture_output : suppress_output
22
+ remote = params.delete(:remote)
23
+ line_action = params.delete(:line_action)
44
24
 
45
25
  if remote
46
- execute_ssh commands, domain, user, password, line_action, suppress_output, storage
26
+ command = RemoteCommand.new params
47
27
  else
48
- execute_command commands, password, line_action, suppress_output, storage
28
+ command = LocalCommand.new params
49
29
  end
50
30
 
51
- storage.buffer.join("\n") if storage
31
+ command.execute commands, line_action
52
32
  end
53
33
  end
54
34
 
55
35
  private
56
36
 
57
- def print_execution commands, remote, domain, user, identity_file, simulate
58
- if remote
59
- ssh_command = ssh_command(domain, user, identity_file)
60
-
61
- if simulate
62
- output.puts "Remote script: '#{ssh_command}'"
63
- output.puts "-------"
64
- print_commands commands
65
- output.puts "-------"
66
- else
67
- output.puts "Remote execution on: '#{ssh_command}'"
68
- output.puts "-------"
69
- print_commands commands
70
- output.puts "-------"
71
- end
72
- else
73
- if simulate
74
- output.puts "Script:"
75
- output.puts "-------"
76
- print_commands commands
77
- output.puts "-------"
78
- else
79
- output.puts "Local execution:"
80
- output.puts "-------"
81
- print_commands(commands)
82
- output.puts "-------"
83
- end
84
- end
85
- end
86
-
87
- def print_commands commands
88
- lines = StringIO.new commands
89
-
90
- lines.each_line do |line|
91
- output.puts line
92
- end
93
- end
94
-
95
- def execute_command commands, password, line_action, suppress_output, storage
96
- commands = commands + inline_password(password) if password
97
-
98
- IO.popen(commands) do |pipe|
99
- pipe.each("\r") do |line|
100
- output.print(line) unless suppress_output
101
-
102
- storage.save(line.chomp) if storage
103
-
104
- line_action.call(line) if line_action
105
- end
106
- end
107
- end
108
-
109
- def inline_password password
110
- password ? "<<EOF\n#{password}\nEOF" : ""
111
- end
112
-
113
- def execute_ssh commands, domain, user, password, line_action, suppress_output, storage
114
- if password.nil?
115
- password = ask("Enter password for #{user}: ") { |q| q.echo = '*' }
116
- end
117
-
118
- Net::SSH.start(domain, user, :password => password) do |session|
119
- session.exec "#{commands}" do |channel, _, line|
120
- if line =~ /^\[sudo\] password for user:/ || line =~ /sudo password:/
121
- #puts "Password request"
122
- channel.request_pty # <- problem must be here.
123
- channel.send_data password + "\n"
124
- else
125
- output.print(line) unless suppress_output
126
-
127
- storage.save(line.chomp) if storage
128
-
129
- line_action.call(line) if line_action
130
- end
131
- end
132
-
133
- # run the aggregated event loop
134
- session.loop
135
- end
136
- end
137
-
138
37
  def locate_commands script, &code
139
38
  if block_given?
140
39
  commands_from_block &code
@@ -163,16 +62,6 @@ module Executable
163
62
  end
164
63
  end
165
64
 
166
- def ssh_command domain, user, identity_file
167
- cmd = user.nil? ? domain : "#{user}@#{domain}"
168
-
169
- cmd << " -i #{identity_file}" if identity_file
170
-
171
- #cmd << " -t -t"
172
-
173
- "ssh #{cmd}"
174
- end
175
-
176
65
  def sudo commands
177
66
  "sudo -S -p 'sudo password: ' -s -- '#{commands}'"
178
67
  end
@@ -0,0 +1,78 @@
1
+ #require "open3"
2
+ #@stdout, @stderr, @status = Open3.capture3(stdin)
3
+
4
+ class LocalCommand
5
+ attr_accessor :simulate
6
+
7
+ attr_reader :password, :suppress_output, :capture_output, :simulate
8
+
9
+ def initialize params
10
+ @password = params[:password]
11
+ @suppress_output = params[:suppress_output]
12
+ @capture_output = params[:capture_output]
13
+ @simulate = params[:simulate]
14
+ end
15
+
16
+ def execute commands, line_action
17
+ print_commands commands, $stdout
18
+
19
+ unless simulate
20
+ storage = capture_output ? OutputBuffer.new : nil
21
+ output = suppress_output ? nil : $stdout
22
+
23
+ commands = commands + inline_password(password) if password
24
+
25
+ IO.popen(commands) do |pipe|
26
+ pipe.each("\r") do |line|
27
+ output.print(line) if output
28
+ storage.save(line.chomp) if storage
29
+
30
+ line_action.call(line) if line_action
31
+ end
32
+ end
33
+
34
+ storage.buffer.join("\n") if storage
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def print_commands commands, output
41
+ if simulate
42
+ output.puts "Script:"
43
+ output.puts "-------"
44
+
45
+ lines = StringIO.new commands
46
+
47
+ lines.each_line do |line|
48
+ output.puts line
49
+ end
50
+
51
+ output.puts "-------"
52
+ else
53
+ output.puts "Local execution:"
54
+ output.puts "-------"
55
+
56
+ lines = StringIO.new commands
57
+
58
+ lines.each_line do |line|
59
+ output.puts line
60
+ end
61
+
62
+ output.puts "-------"
63
+ end
64
+ end
65
+
66
+ def inline_password password
67
+ password ? "<<EOF\n#{password}\nEOF" : ""
68
+ end
69
+ end
70
+
71
+ #require 'shellwords'
72
+ #
73
+ #def bash(command)
74
+ # escaped_command = Shellwords.escape(command)
75
+ # system "bash -c #{escaped_command}"
76
+ #end
77
+
78
+