screwcap 0.3.5 → 0.5
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/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
|