screwcap 0.3.5 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest.txt +7 -5
- data/README.rdoc +13 -0
- data/Rakefile +1 -1
- data/bin/screwcap +24 -9
- data/lib/screwcap.rb +2 -2
- data/lib/screwcap/base.rb +4 -0
- data/lib/screwcap/message_logger.rb +1 -1
- data/lib/screwcap/runner.rb +68 -75
- data/lib/screwcap/sequence.rb +0 -10
- data/lib/screwcap/server.rb +9 -7
- data/lib/screwcap/task.rb +48 -43
- data/lib/screwcap/{deployer.rb → task_manager.rb} +55 -46
- data/recipes/setup_rails.rb +3 -3
- data/runrdoc +1 -0
- data/screwcap.gemspec +1 -1
- data/spec/runner_spec.rb +51 -0
- data/spec/sequence_spec.rb +2 -16
- data/spec/server_spec.rb +0 -9
- data/spec/task_manager_spec.rb +100 -0
- data/spec/task_spec.rb +123 -60
- data/test/config/bad_use.rb +1 -0
- data/test/config/expect.rb +5 -0
- data/test/config/simple_recipe.rb +0 -6
- data/test/config/super_simple_recipe.rb +11 -0
- data/test/config/use.rb +1 -1
- data/test/config/use2.rb +1 -0
- metadata +10 -9
- data/Gemfile +0 -14
- data/Gemfile.lock +0 -49
- data/spec/command_set_spec.rb +0 -57
- data/spec/deployer_spec.rb +0 -78
data/Manifest.txt
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
Gemfile
|
2
|
-
Gemfile.lock
|
3
1
|
History.txt
|
4
2
|
Manifest.txt
|
5
3
|
README.rdoc
|
@@ -8,23 +6,25 @@ TODO
|
|
8
6
|
bin/screwcap
|
9
7
|
lib/screwcap.rb
|
10
8
|
lib/screwcap/base.rb
|
11
|
-
lib/screwcap/deployer.rb
|
12
9
|
lib/screwcap/message_logger.rb
|
13
10
|
lib/screwcap/runner.rb
|
14
11
|
lib/screwcap/sequence.rb
|
15
12
|
lib/screwcap/server.rb
|
16
13
|
lib/screwcap/task.rb
|
14
|
+
lib/screwcap/task_manager.rb
|
17
15
|
lib/trollop.rb
|
18
16
|
recipes/setup_rails.rb
|
17
|
+
runrdoc
|
19
18
|
screwcap.gemspec
|
20
|
-
spec/
|
21
|
-
spec/deployer_spec.rb
|
19
|
+
spec/runner_spec.rb
|
22
20
|
spec/sequence_spec.rb
|
23
21
|
spec/server_spec.rb
|
24
22
|
spec/spec.opts
|
25
23
|
spec/spec_helper.rb
|
24
|
+
spec/task_manager_spec.rb
|
26
25
|
spec/task_spec.rb
|
27
26
|
tasks/rspec.rake
|
27
|
+
test/config/bad_use.rb
|
28
28
|
test/config/command_sets.rb
|
29
29
|
test/config/expect.rb
|
30
30
|
test/config/gateway.rb
|
@@ -32,9 +32,11 @@ test/config/local_task.rb
|
|
32
32
|
test/config/no_server.rb
|
33
33
|
test/config/rails_tasks.rb
|
34
34
|
test/config/simple_recipe.rb
|
35
|
+
test/config/super_simple_recipe.rb
|
35
36
|
test/config/undefined_command_set.rb
|
36
37
|
test/config/undefined_item.rb
|
37
38
|
test/config/undefined_server.rb
|
38
39
|
test/config/unknown_use.rb
|
39
40
|
test/config/upload.rb
|
40
41
|
test/config/use.rb
|
42
|
+
test/config/use2.rb
|
data/README.rdoc
CHANGED
@@ -20,6 +20,19 @@ For more info, see the main screwcap page at http://gammons.github.com/screwcap
|
|
20
20
|
|
21
21
|
* gem install screwcap
|
22
22
|
|
23
|
+
== TODO:
|
24
|
+
* Explore removing the 'use' keyword, favoring require or load
|
25
|
+
* Add ability to parse user input
|
26
|
+
* Add ability to parse user input
|
27
|
+
* DONE add --dry-run to screwcap
|
28
|
+
|
29
|
+
== RECIPES:
|
30
|
+
|
31
|
+
=== I need help writing rails recipes! Please help contribute some nice rock-solid rails recipes to the following repo:
|
32
|
+
|
33
|
+
http://github.com/gammons/screwcap_recipes
|
34
|
+
|
35
|
+
|
23
36
|
== LICENSE:
|
24
37
|
|
25
38
|
(The MIT License)
|
data/Rakefile
CHANGED
@@ -11,7 +11,7 @@ Hoe.plugin :newgem
|
|
11
11
|
# Generate all the Rake tasks
|
12
12
|
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
13
13
|
$hoe = Hoe.spec 'screwcap' do
|
14
|
-
self.version = '0.
|
14
|
+
self.version = '0.5'
|
15
15
|
self.developer 'Grant Ammons', 'grant@pipelinedeals.com'
|
16
16
|
self.rubyforge_name = self.name # TODO this is default value
|
17
17
|
self.extra_deps = [['net-ssh','>= 2.0.23'],['net-ssh-gateway','>=1.0.1'], ['net-scp','>=1.0.4']]
|
data/bin/screwcap
CHANGED
@@ -4,14 +4,14 @@ require 'rubygems'
|
|
4
4
|
require File.expand_path(File.dirname(__FILE__) + '/../lib/screwcap')
|
5
5
|
require File.expand_path(File.dirname(__FILE__) + '/../lib/trollop')
|
6
6
|
|
7
|
-
|
8
7
|
p = Trollop::Parser.new do
|
9
|
-
opt :silent, "Be silent"
|
8
|
+
opt :silent, "Be silent", :short => "s"
|
10
9
|
opt :nocolor, "Do not color output"
|
11
|
-
opt :debug, "Turn on debugger. Will print full stacktrace if an exeception was raised"
|
12
|
-
opt :help, "Show this message"
|
13
|
-
opt :tasks, "Display available tasks in recipe file"
|
14
|
-
opt :setup_rails, "Setup a rails app to use screwcap"
|
10
|
+
opt :debug, "Turn on debugger. Will print full stacktrace if an exeception was raised", :short => "d"
|
11
|
+
opt :help, "Show this message", :short => "h"
|
12
|
+
opt :tasks, "Display available tasks in recipe file", :short => "t"
|
13
|
+
opt :setup_rails, "Setup a rails app to use screwcap", :short => "r"
|
14
|
+
opt :dry_run, "Setup a rails app to use screwcap", :short => "n"
|
15
15
|
version <<-EOF
|
16
16
|
Screwcap #{Screwcap::VERSION} by Grant Ammons (grant@pipelinedeals.com)
|
17
17
|
More info at http://gammons.github.com/screwcap
|
@@ -31,7 +31,7 @@ opts = Trollop::with_standard_exception_handling p do
|
|
31
31
|
|
32
32
|
if opts[:tasks] == true
|
33
33
|
recipe_file = ARGV.shift
|
34
|
-
deployer =
|
34
|
+
deployer = TaskManager.new(opts.merge(:recipe_file => recipe_file))
|
35
35
|
$stdout << "Tasks Available:\n" if deployer.__tasks.size > 0
|
36
36
|
deployer.__tasks.map {|t| t.__name }.each {|name| $stdout << " #{name}\n" }
|
37
37
|
$stdout << "Sequences Available:\n" if deployer.__sequences.size > 0
|
@@ -39,8 +39,23 @@ opts = Trollop::with_standard_exception_handling p do
|
|
39
39
|
exit
|
40
40
|
end
|
41
41
|
|
42
|
+
if opts[:dry_run] == true
|
43
|
+
recipe_file = ARGV.shift
|
44
|
+
deployer = TaskManager.new(opts.merge(:recipe_file => recipe_file))
|
45
|
+
ARGV.map {|a| a.to_sym }.each do |tname|
|
46
|
+
task = deployer.__tasks.find {|t| t.__name == tname }
|
47
|
+
raise(Screwcap::TaskNotFound, "Could not find task named '#{tname}' in the recipe file.") if task.nil?
|
48
|
+
$stdout << "\n*** BEGIN dry-run task #{task.__name}\n"
|
49
|
+
task.__commands.each do |cmd|
|
50
|
+
$stdout << " I: (dry-run): #{cmd[:command]}\n"
|
51
|
+
end
|
52
|
+
$stdout << "*** END dry-run task #{task.__name}\n"
|
53
|
+
end
|
54
|
+
exit
|
55
|
+
end
|
56
|
+
|
42
57
|
if opts[:setup_rails] == true
|
43
|
-
|
58
|
+
TaskManager.new(:recipe_file => File.expand_path(File.dirname(__FILE__) + "/../recipes/setup_rails.rb")).run! :setup_rails
|
44
59
|
$stdout << "\nYour rails app now has a sample recipe, ready for the editing, in config/screwcap/recipe.rb\n"
|
45
60
|
$stdout << "Your recipes will be automatically available in rake. Screwcap uses the :remote namespace.\n"
|
46
61
|
$stdout << "To see what recipes you can run, type 'rake -T remote'.\n"
|
@@ -51,7 +66,7 @@ opts = Trollop::with_standard_exception_handling p do
|
|
51
66
|
raise Trollop::HelpNeeded if ARGV.size < 2
|
52
67
|
recipe_file = ARGV.shift
|
53
68
|
begin
|
54
|
-
|
69
|
+
TaskManager.new(opts.merge(:recipe_file => recipe_file)).run! ARGV.map {|a| a.to_sym }
|
55
70
|
rescue Exception => e
|
56
71
|
raise e if opts[:debug] == true
|
57
72
|
$stderr << e
|
data/lib/screwcap.rb
CHANGED
@@ -13,10 +13,10 @@ require 'screwcap/task'
|
|
13
13
|
require 'screwcap/server'
|
14
14
|
require 'screwcap/runner'
|
15
15
|
require 'screwcap/sequence'
|
16
|
-
require 'screwcap/
|
16
|
+
require 'screwcap/task_manager'
|
17
17
|
|
18
18
|
module Screwcap
|
19
|
-
VERSION='0.
|
19
|
+
VERSION='0.5'
|
20
20
|
|
21
21
|
class TaskNotFound < RuntimeError; end
|
22
22
|
class NoServersDefined < Exception; end
|
data/lib/screwcap/base.rb
CHANGED
@@ -16,7 +16,7 @@ module MessageLogger
|
|
16
16
|
|
17
17
|
def logmsg(msg, output, options)
|
18
18
|
return if @options and @options[:silent] == true
|
19
|
-
|
19
|
+
unless (@options and @options[:nocolor] == true)
|
20
20
|
case options[:color]
|
21
21
|
when :blue
|
22
22
|
output << "\033[0;36m#{msg}#{"\033[0m" if options[:clear]}"
|
data/lib/screwcap/runner.rb
CHANGED
@@ -1,63 +1,76 @@
|
|
1
1
|
class Runner
|
2
2
|
include MessageLogger
|
3
|
+
@@silent = false
|
3
4
|
|
4
|
-
def self.execute!
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
log " I: (local): #{command[:command]}\n", :color => :blue
|
13
|
-
log(" O: (local): #{ret}\n", :color => :blue) unless ret.nil? or ret == ""
|
14
|
-
else
|
15
|
-
log " I: (local): #{command[:command]}\n", :color => :blue
|
16
|
-
errorlog(" O: (local): #{ret}\n", :color => :red) unless ret.nil? or ret == ""
|
17
|
-
errorlog(" E: (local): #{command[:command]} return exit code: #{$?}\n", :color => :red) if $? != 0
|
5
|
+
def self.execute! options
|
6
|
+
@@silent = options[:silent]
|
7
|
+
begin
|
8
|
+
_log "\n*** BEGIN executing task #{options[:name]} on #{options[:server].name} with address #{options[:address]}\n", :color => :blue unless options[:silent] == true
|
9
|
+
options[:server].__with_connection_for(options[:address]) do |ssh|
|
10
|
+
options[:commands].each do |command|
|
11
|
+
ret = run_command(command, ssh, options)
|
12
|
+
break if ret != 0 and command[:abort_on_fail] == true
|
18
13
|
end
|
19
14
|
end
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
15
|
+
rescue Net::SSH::AuthenticationFailed => e
|
16
|
+
raise Net::SSH::AuthenticationFailed, "Authentication failed for server named #{server.name}. Please check your authentication credentials."
|
17
|
+
#rescue Exception => e
|
18
|
+
# _errorlog " F: (#{options[:address]}): #{e}", :color => :red
|
19
|
+
ensure
|
20
|
+
_log "*** END executing task #{options[:name]} on #{options[:server].name} with address #{options[:address]}\n\n", :color => :blue
|
21
|
+
end
|
22
|
+
options[:commands] # for tests
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.execute_locally! options
|
26
|
+
@@silent = options[:silent]
|
27
|
+
_log "\n*** BEGIN executing local task #{options[:name]}\n", :color => :blue
|
28
|
+
options[:commands].each do |command|
|
29
|
+
command[:stdout] = ret = `#{command[:command]}`
|
30
|
+
|
31
|
+
if $?.to_i == 0
|
32
|
+
_log " I: (local): #{command[:command]}\n", :color => :blue
|
33
|
+
_log(" O: (local): #{ret}\n", :color => :blue) unless ret.nil? or ret == ""
|
34
|
+
else
|
35
|
+
_log " I: (local): #{command[:command]}\n", :color => :blue
|
36
|
+
_errorlog(" O: (local): #{ret}\n", :color => :red) unless ret.nil? or ret == ""
|
37
|
+
_errorlog(" E: (local): #{command[:command]} return exit code: #{$?}\n", :color => :red) if $? != 0
|
30
38
|
end
|
31
39
|
end
|
32
|
-
|
40
|
+
_log "\n*** END executing local task #{options[:name]}\n", :color => :blue
|
41
|
+
options[:commands]
|
33
42
|
end
|
34
43
|
|
35
44
|
private
|
36
45
|
|
37
|
-
def self.
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
46
|
+
def self.run_command(command, ssh, options)
|
47
|
+
if command[:type] == :remote
|
48
|
+
_log " I: (#{options[:address]}): #{command[:command]}\n", :color => :green
|
49
|
+
stdout, stderr, exit_code, exit_signal = ssh_exec! ssh, command[:command]
|
50
|
+
command[:stdout] = stdout
|
51
|
+
command[:stderr] = stderr
|
52
|
+
_log(" O: (#{options[:address]}): #{stdout}", :color => :green) unless stdout.nil? or stdout == ""
|
53
|
+
_errorlog(" O: (#{options[:address]}): #{stderr}", :color => :red) unless stderr.nil? or stderr == ""
|
54
|
+
_errorlog(" E: (#{options[:address]}): #{command[:command]} return exit code: #{exit_code}\n", :color => :red) if exit_code != 0
|
55
|
+
return exit_code
|
56
|
+
elsif command[:type] == :local
|
57
|
+
ret = `#{command[:command]}`
|
58
|
+
command[:stdout] = ret
|
59
|
+
if $?.to_i == 0
|
60
|
+
_log " I: (local): #{command[:command]}\n", :color => :blue
|
61
|
+
_log " O: (local): #{ret}\n", :color => :blue
|
62
|
+
else
|
63
|
+
_log " I: (local): #{command[:command]}\n", :color => :blue
|
64
|
+
_errorlog " O: (local): #{ret}\n", :color => :red
|
65
|
+
_errorlog(" E: (local): #{command[:command]} return exit code: #{$?}\n", :color => :red) if $? != 0
|
54
66
|
end
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
67
|
+
return $?
|
68
|
+
elsif command[:type] == :scp
|
69
|
+
_log " I: (#{options[:address]}): SCP #{command[:local]} to #{options[:server].__user}@#{options[:address]}:#{command[:remote]}\n", :color => :green
|
70
|
+
options[:server].__upload_to!(options[:address], command[:local], command[:remote])
|
71
|
+
|
72
|
+
# this will need to be improved to allow for :onfailure
|
73
|
+
return 0
|
61
74
|
end
|
62
75
|
end
|
63
76
|
|
@@ -91,33 +104,13 @@ class Runner
|
|
91
104
|
[stdout_data, stderr_data, exit_code, exit_signal]
|
92
105
|
end
|
93
106
|
|
107
|
+
def self._log(message, options)
|
108
|
+
return if @@silent == true
|
109
|
+
log(message, options)
|
110
|
+
end
|
94
111
|
|
95
|
-
def self.
|
96
|
-
if
|
97
|
-
|
98
|
-
stdout, stderr, exit_code, exit_signal = ssh_exec! ssh, command[:command]
|
99
|
-
log(" O: (#{address}): #{stdout}", :color => :green) unless stdout.nil? or stdout == ""
|
100
|
-
errorlog(" O: (#{address}): #{stderr}", :color => :red) unless stderr.nil? or stderr == ""
|
101
|
-
errorlog(" E: (#{address}): #{command[:command]} return exit code: #{exit_code}\n", :color => :red) if exit_code != 0
|
102
|
-
return exit_code
|
103
|
-
elsif command[:type] == :local
|
104
|
-
ret = `#{command[:command]}`
|
105
|
-
if $?.to_i == 0
|
106
|
-
log " I: (local): #{command[:command]}\n", :color => :blue
|
107
|
-
log " O: (local): #{ret}\n", :color => :blue
|
108
|
-
else
|
109
|
-
log " I: (local): #{command[:command]}\n", :color => :blue
|
110
|
-
errorlog " O: (local): #{ret}\n", :color => :red
|
111
|
-
errorlog(" E: (local): #{command[:command]} return exit code: #{$?}\n", :color => :red) if $? != 0
|
112
|
-
end
|
113
|
-
return $?
|
114
|
-
elsif command[:type] == :scp
|
115
|
-
log " I: (#{address}): SCP #{command[:local]} to #{server.__user}@#{address}:#{command[:remote]}\n", :color => :green
|
116
|
-
server.__upload_to!(address, command[:local], command[:remote])
|
117
|
-
|
118
|
-
# this will need to be improved to allow for :onfailure
|
119
|
-
return 0
|
120
|
-
end
|
121
|
-
|
112
|
+
def self._errorlog(message, options)
|
113
|
+
return if @@silent == true
|
114
|
+
errorlog(message, options)
|
122
115
|
end
|
123
116
|
end
|
data/lib/screwcap/sequence.rb
CHANGED
@@ -23,16 +23,6 @@ class Sequence < Screwcap::Base
|
|
23
23
|
super
|
24
24
|
self.__options = opts
|
25
25
|
self.__name = opts[:name]
|
26
|
-
self.__deployment_task_names = opts[:deployment_task_names]
|
27
26
|
self.__task_names = opts[:tasks]
|
28
|
-
validate
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def validate
|
34
|
-
self.__task_names.each do |tn|
|
35
|
-
raise(Screwcap::ConfigurationError, "Could not find task #{tn} in the deployment recipe.") unless self.__deployment_task_names.include?(tn)
|
36
|
-
end
|
37
27
|
end
|
38
28
|
end
|
data/lib/screwcap/server.rb
CHANGED
@@ -13,11 +13,14 @@ class Server < Screwcap::Base
|
|
13
13
|
# * *:password* specify the password to connect with. Not recommended. Use keys.
|
14
14
|
def initialize(opts = {})
|
15
15
|
super
|
16
|
+
self.__name = opts.delete(:name)
|
17
|
+
self.__user = opts.delete(:user)
|
18
|
+
self.__options[:keys] = [opts.delete(:key)] if opts[:key]
|
19
|
+
|
20
|
+
servers = opts.delete(:servers)
|
21
|
+
self.__gateway = servers.select {|s| s.__options[:is_gateway] == true }.find {|s| s.__name == opts[:gateway] } if servers
|
22
|
+
|
16
23
|
self.__options = opts
|
17
|
-
self.__name = opts[:name]
|
18
|
-
self.__servers = opts[:servers]
|
19
|
-
self.__user = opts[:user]
|
20
|
-
self.__options[:keys] = [self.__options.delete(:key)] if self.__options[:key]
|
21
24
|
|
22
25
|
if self.__options[:address] and self.__options[:addresses].nil?
|
23
26
|
self.__addresses = [self.__options.delete(:address)]
|
@@ -31,9 +34,8 @@ class Server < Screwcap::Base
|
|
31
34
|
end
|
32
35
|
|
33
36
|
def __with_connection_for(address, &block)
|
34
|
-
if self.
|
35
|
-
|
36
|
-
gateway.__get_gateway_connection.ssh(address, self.__user, options_for_net_ssh) do |ssh|
|
37
|
+
if self.__gateway
|
38
|
+
__gateway.__get_gateway_connection.ssh(address, self.__user, options_for_net_ssh) do |ssh|
|
37
39
|
yield ssh
|
38
40
|
end
|
39
41
|
else
|
data/lib/screwcap/task.rb
CHANGED
@@ -3,21 +3,11 @@ class Task < Screwcap::Base
|
|
3
3
|
|
4
4
|
def initialize(opts = {}, &block)
|
5
5
|
super
|
6
|
-
self.__name = opts
|
6
|
+
self.__name = opts.delete(:name)
|
7
7
|
self.__options = opts
|
8
8
|
self.__commands = []
|
9
|
-
self.
|
10
|
-
self.
|
11
|
-
self.__block = block if opts[:command_set] == true
|
12
|
-
|
13
|
-
|
14
|
-
if opts[:server] and opts[:servers].nil?
|
15
|
-
self.__server_names << opts[:server]
|
16
|
-
else
|
17
|
-
self.__server_names = opts[:servers]
|
18
|
-
end
|
19
|
-
|
20
|
-
validate(opts[:deployment_servers]) unless opts[:validate] == false or opts[:local] == true
|
9
|
+
self.__servers = opts.delete(:servers)
|
10
|
+
self.__block = block
|
21
11
|
end
|
22
12
|
|
23
13
|
# Run a command. This can either be a string, or a symbol that is the name of a command set to run.
|
@@ -45,8 +35,8 @@ class Task < Screwcap::Base
|
|
45
35
|
# task_for :item, :servers => :server do
|
46
36
|
# run "ls -l", :onfailure => :rollback
|
47
37
|
# end
|
38
|
+
|
48
39
|
def run arg, options = {}
|
49
|
-
|
50
40
|
if arg.class == Symbol
|
51
41
|
self.__commands << options.merge({:command => self.send(arg), :type => :remote, :from => self.__name})
|
52
42
|
else
|
@@ -58,6 +48,7 @@ class Task < Screwcap::Base
|
|
58
48
|
# task_for :item, :servers => :server do
|
59
49
|
# scp :local => "/tmp/pirate_booty", :remote => "/mnt/app/config/booty.yml"
|
60
50
|
# end
|
51
|
+
|
61
52
|
def scp options = {}
|
62
53
|
self.__commands << options.merge({:type => :scp})
|
63
54
|
end
|
@@ -78,54 +69,68 @@ class Task < Screwcap::Base
|
|
78
69
|
# task_for :item, :servers => :server do
|
79
70
|
# local "herd_cats", :onfailure => :rollback
|
80
71
|
# end
|
72
|
+
|
81
73
|
def local arg, options = {}
|
82
74
|
if arg.class == Symbol
|
83
75
|
self.__commands << options.merge({:command => self.send(arg), :type => :local, :from => self.__name})
|
84
76
|
else
|
85
77
|
self.__commands << options.merge({:command => arg, :type => :local, :from => self.__name})
|
86
78
|
end
|
87
|
-
if failure_cmd = self.__commands.last[:onfailure]
|
88
|
-
unless self.__command_sets.find {|cs| cs.__name == failure_cmd }
|
89
|
-
raise ScrewCap::ConfigurationError, "Could not find failure command set named '#{failure_cmd}' for task '#{self.__name}'"
|
90
|
-
end
|
91
|
-
end
|
92
79
|
end
|
93
80
|
|
94
|
-
|
81
|
+
def __build_commands(command_sets = [])
|
82
|
+
commands = []
|
95
83
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
84
|
+
self.instance_eval(&self.__block)
|
85
|
+
|
86
|
+
# :before for before_ callback
|
87
|
+
if before = command_sets.find {|cs| cs.__name.to_s == "before_#{self.__name}" or cs.__name == self.__options[:before] } and before != self
|
88
|
+
before.clone_from(self)
|
89
|
+
commands << before.__build_commands(command_sets)
|
90
|
+
end
|
91
|
+
|
92
|
+
self.__commands.each do |command|
|
93
|
+
if command[:type] == :unknown
|
94
|
+
if cs = command_sets.find {|cs| cs.__name == command[:command] }
|
95
|
+
cs.clone_from(self)
|
96
|
+
commands << cs.__build_commands(command_sets)
|
97
|
+
else
|
98
|
+
raise(NoMethodError, "Cannot find task, command set, or other method named '#{command[:command]}'")
|
99
|
+
end
|
106
100
|
else
|
107
|
-
|
101
|
+
commands << command
|
108
102
|
end
|
109
103
|
end
|
110
|
-
end
|
111
|
-
|
112
|
-
private
|
113
104
|
|
114
|
-
|
115
|
-
self.
|
116
|
-
|
105
|
+
# :after for after_ callback
|
106
|
+
if after = command_sets.find {|cs| cs.__name.to_s == "after_#{self.__name}" or cs.__name == self.__options[:after] } and after != self
|
107
|
+
after.clone_from(self)
|
108
|
+
commands << after.__build_commands(command_sets)
|
117
109
|
end
|
110
|
+
|
111
|
+
commands.flatten
|
118
112
|
end
|
119
113
|
|
120
114
|
def validate(servers)
|
121
|
-
raise Screwcap::ConfigurationError, "Could not find a server to run this task on. Please specify :server => :servername or :servers => [:server1, :server2] in the task_for directive." if
|
115
|
+
raise Screwcap::ConfigurationError, "Could not find a server to run this task on. Please specify :server => :servername or :servers => [:server1, :server2] in the task_for directive." if servers == [] or servers.nil?
|
122
116
|
|
123
|
-
|
124
|
-
|
125
|
-
|
117
|
+
# marshal :server into :servers
|
118
|
+
self.__servers = [self.__options.delete(:server)] if self.__options[:server]
|
119
|
+
self.__servers = [self.__servers] if self.__servers.class != Array
|
126
120
|
|
127
|
-
|
128
|
-
self.__servers
|
121
|
+
server_names = servers.map {|s| s.__name }
|
122
|
+
self.__servers.each do |server_name|
|
123
|
+
raise Screwcap::ConfigurationError, "Could not find a server to run this task on. Please specify :server => :servername or :servers => [:server1, :server2] in the task_for directive." unless server_names.include?(server_name)
|
124
|
+
end
|
129
125
|
end
|
130
126
|
|
127
|
+
private
|
128
|
+
|
129
|
+
def method_missing(m, *args) # :nodoc
|
130
|
+
if m.to_s[0..1] == "__" or [:run].include?(m) or m.to_s.reverse[0..0] == "="
|
131
|
+
super(m, args.first)
|
132
|
+
else
|
133
|
+
self.__commands << {:command => m, :type => :unknown, :from => self.__name}
|
134
|
+
end
|
135
|
+
end
|
131
136
|
end
|