screwcap 0.2 → 0.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/Manifest.txt +0 -1
- data/Rakefile +1 -1
- data/lib/exts.rb +1 -7
- data/lib/screwcap.rb +4 -2
- data/lib/screwcap/base.rb +0 -42
- data/lib/screwcap/deployer.rb +7 -6
- data/lib/screwcap/server.rb +1 -1
- data/lib/screwcap/task.rb +15 -65
- data/screwcap.gemspec +1 -1
- data/spec/command_set_spec.rb +7 -1
- data/spec/deployer_spec.rb +5 -3
- data/spec/sequence_spec.rb +1 -0
- data/spec/server_spec.rb +3 -6
- data/spec/spec_helper.rb +21 -7
- data/spec/task_spec.rb +16 -9
- data/test/config/command_sets.rb +8 -0
- data/test/config/expect.rb +4 -18
- metadata +4 -5
- data/lib/screwcap/command_set.rb +0 -56
data/Manifest.txt
CHANGED
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.3'
|
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/lib/exts.rb
CHANGED
data/lib/screwcap.rb
CHANGED
@@ -8,15 +8,16 @@ require 'ostruct'
|
|
8
8
|
require 'logger'
|
9
9
|
|
10
10
|
require 'exts'
|
11
|
+
require 'screwcap/message_logger'
|
11
12
|
require 'screwcap/base'
|
12
|
-
require 'screwcap/command_set'
|
13
13
|
require 'screwcap/task'
|
14
14
|
require 'screwcap/server'
|
15
|
+
require 'screwcap/runner'
|
15
16
|
require 'screwcap/sequence'
|
16
17
|
require 'screwcap/deployer'
|
17
18
|
|
18
19
|
module Screwcap
|
19
|
-
VERSION='0.
|
20
|
+
VERSION='0.3'
|
20
21
|
|
21
22
|
class TaskNotFound < RuntimeError; end
|
22
23
|
class NoServersDefined < Exception; end
|
@@ -25,5 +26,6 @@ module Screwcap
|
|
25
26
|
class IncludeFileNotFound < Exception; end
|
26
27
|
class InvalidServer < Exception; end
|
27
28
|
class CommandSetDependencyError < Exception; end
|
29
|
+
class CommandError < Exception; end
|
28
30
|
end
|
29
31
|
|
data/lib/screwcap/base.rb
CHANGED
@@ -10,47 +10,5 @@ module Screwcap
|
|
10
10
|
def set(var, *args)
|
11
11
|
method_missing((var.to_s + "=").to_sym, args.first)
|
12
12
|
end
|
13
|
-
|
14
|
-
def log(msg, options = {})
|
15
|
-
$stdout << msg unless self.__options[:silent] == true
|
16
|
-
end
|
17
|
-
|
18
|
-
def errorlog(msg)
|
19
|
-
$stderr << msg unless self.__options[:silent] == true
|
20
|
-
end
|
21
|
-
|
22
|
-
def bluebold(msg, options = {:clear => true})
|
23
|
-
if self.__options[:nocolor] == true
|
24
|
-
msg
|
25
|
-
else
|
26
|
-
"\033[1;36m#{msg}#{"\033[0m" if options[:clear]}"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def blue(msg, options = {:clear => true})
|
31
|
-
if self.__options[:nocolor] == true
|
32
|
-
msg
|
33
|
-
else
|
34
|
-
"\033[0;36m#{msg}#{"\033[0m" if options[:clear]}"
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
|
39
|
-
def red(msg)
|
40
|
-
if self.__options[:nocolor] == true
|
41
|
-
msg
|
42
|
-
else
|
43
|
-
"\033[0;31m#{msg}\033[0m"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def green(msg)
|
48
|
-
if self.__options[:nocolor] == true
|
49
|
-
msg
|
50
|
-
else
|
51
|
-
"\033[0;32m#{msg}\033[0m"
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
13
|
end
|
56
14
|
end
|
data/lib/screwcap/deployer.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# The deployer can be thought of as the "global scope" of your tasks file.
|
4
4
|
class Deployer < Screwcap::Base
|
5
|
+
include MessageLogger
|
5
6
|
|
6
7
|
# create a new deployer.
|
7
8
|
def initialize(opts = {})
|
@@ -16,7 +17,7 @@ class Deployer < Screwcap::Base
|
|
16
17
|
# ensure that deployer options will not be passed to tasks
|
17
18
|
opts.each_key {|k| self.delete_field(k) }
|
18
19
|
|
19
|
-
log "Reading #{self.__options[:recipe_file]}\n" unless self.__options[:silent] == true
|
20
|
+
Deployer.log "Reading #{self.__options[:recipe_file]}\n" unless self.__options[:silent] == true
|
20
21
|
|
21
22
|
file = File.open(File.expand_path("./#{self.__options[:recipe_file]}"))
|
22
23
|
data = file.read
|
@@ -27,14 +28,14 @@ class Deployer < Screwcap::Base
|
|
27
28
|
|
28
29
|
# create a task. Minimally, a task needs a :server specified to run the task on.
|
29
30
|
def task_for name, options = {}, &block
|
30
|
-
t = Task.new(options.merge(:name => name, :nocolor => self.__options[:nocolor], :silent => self.__options[:silent], :deployment_servers => self.__servers), &block)
|
31
|
+
t = Task.new(options.merge(:name => name, :nocolor => self.__options[:nocolor], :silent => self.__options[:silent], :deployment_servers => self.__servers, :command_sets => self.__command_sets), &block)
|
31
32
|
clone_table_for(t)
|
32
33
|
t.instance_eval(&block)
|
33
34
|
self.__tasks << t
|
34
35
|
end
|
35
36
|
|
36
37
|
def command_set(name,options = {},&block)
|
37
|
-
t =
|
38
|
+
t = Task.new(options.merge(:name => name, :validate => false, :command_set => true, :command_sets => self.__command_sets), &block)
|
38
39
|
clone_table_for(t)
|
39
40
|
self.__command_sets << t
|
40
41
|
end
|
@@ -66,9 +67,9 @@ class Deployer < Screwcap::Base
|
|
66
67
|
tasks.each do |t|
|
67
68
|
sequence = self.__sequences.find {|s| s.__name == t }
|
68
69
|
if sequence
|
69
|
-
sequence.__task_names.each {|task_name| self.__tasks.find {|task| task.__name == task_name }.
|
70
|
+
sequence.__task_names.each {|task_name| Runner.execute! self.__tasks.find {|task| task.__name == task_name }, self.__options}
|
70
71
|
else
|
71
|
-
self.__tasks.select {|task| task.name.to_s == t.to_s }.first.
|
72
|
+
Runner.execute! self.__tasks.select {|task| task.name.to_s == t.to_s }.first, self.__options
|
72
73
|
end
|
73
74
|
end
|
74
75
|
$stdout << "\033[0m"
|
@@ -98,7 +99,7 @@ class Deployer < Screwcap::Base
|
|
98
99
|
|
99
100
|
def clone_table_for(object)
|
100
101
|
self.table.each do |k,v|
|
101
|
-
object.set(k, v) unless [:__options, :__tasks, :__servers].include?(k)
|
102
|
+
object.set(k, v) unless [:__options, :__tasks, :__servers, :__command_sets].include?(k)
|
102
103
|
end
|
103
104
|
end
|
104
105
|
end
|
data/lib/screwcap/server.rb
CHANGED
@@ -32,7 +32,7 @@ class Server < Screwcap::Base
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def __upload_to!(address, local, remote)
|
35
|
-
|
35
|
+
self.__with_connection_for(address) {|ssh| ssh.scp.upload! local, remote }
|
36
36
|
end
|
37
37
|
|
38
38
|
protected
|
data/lib/screwcap/task.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
class Task < Screwcap::Base
|
2
|
+
include MessageLogger
|
3
|
+
|
2
4
|
def initialize(opts = {}, &block)
|
3
5
|
super
|
4
6
|
self.__name = opts[:name]
|
5
7
|
self.__options = opts
|
6
8
|
self.__commands = []
|
7
|
-
self.__command_sets = []
|
9
|
+
self.__command_sets = opts[:command_sets] || []
|
8
10
|
self.__server_names = []
|
11
|
+
self.__block = block if opts[:command_set] == true
|
9
12
|
|
10
13
|
|
11
14
|
if opts[:server] and opts[:servers].nil?
|
@@ -14,15 +17,16 @@ class Task < Screwcap::Base
|
|
14
17
|
self.__server_names = opts[:servers]
|
15
18
|
end
|
16
19
|
|
17
|
-
validate(opts[:deployment_servers])
|
20
|
+
validate(opts[:deployment_servers]) unless opts[:validate] == false
|
18
21
|
end
|
19
22
|
|
20
23
|
# run a command. basically just pass it a string containing the command you want to run.
|
21
24
|
def run arg, options = {}
|
25
|
+
|
22
26
|
if arg.class == Symbol
|
23
|
-
self.__commands << {:command => self.send(arg), :type => :remote}
|
27
|
+
self.__commands << options.merge({:command => self.send(arg), :type => :remote, :from => self.__name})
|
24
28
|
else
|
25
|
-
self.__commands << {:command => arg, :type => :remote}
|
29
|
+
self.__commands << options.merge({:command => arg, :type => :remote, :from => self.__name})
|
26
30
|
end
|
27
31
|
end
|
28
32
|
|
@@ -33,25 +37,15 @@ class Task < Screwcap::Base
|
|
33
37
|
# run a command. basically just pass it a string containing the command you want to run.
|
34
38
|
def local arg, options = {}
|
35
39
|
if arg.class == Symbol
|
36
|
-
self.__commands << {:command => self.send(arg), :type => :local}
|
40
|
+
self.__commands << options.merge({:command => self.send(arg), :type => :local, :from => self.__name})
|
37
41
|
else
|
38
|
-
self.__commands << {:command => arg, :type => :local}
|
42
|
+
self.__commands << options.merge({:command => arg, :type => :local, :from => self.__name})
|
39
43
|
end
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
def execute!
|
44
|
-
threads = []
|
45
|
-
self.__servers.each do |_server|
|
46
|
-
_server.__addresses.each do |_address|
|
47
|
-
if self.__options[:parallel] == false
|
48
|
-
execute_on(_server, _address)
|
49
|
-
else
|
50
|
-
threads << Thread.new(_server, _address) { |server, address| execute_on(server, address) }
|
51
|
-
end
|
44
|
+
if failure_cmd = self.__commands.last[:onfailure]
|
45
|
+
unless self.__command_sets.find {|cs| cs.__name == failure_cmd }
|
46
|
+
raise ScrewCap::ConfigurationError, "Could not find failure command set named '#{failure_cmd}' for task '#{self.__name}'"
|
52
47
|
end
|
53
48
|
end
|
54
|
-
threads.each {|t| t.join }
|
55
49
|
end
|
56
50
|
|
57
51
|
protected
|
@@ -60,7 +54,7 @@ class Task < Screwcap::Base
|
|
60
54
|
if m.to_s[0..1] == "__" or [:run].include?(m) or m.to_s.reverse[0..0] == "="
|
61
55
|
super(m, args.first)
|
62
56
|
else
|
63
|
-
if cs = self.__command_sets.find {|cs| cs.
|
57
|
+
if cs = self.__command_sets.find {|cs| cs.__name == m }
|
64
58
|
# eval what is in the block
|
65
59
|
clone_table_for(cs)
|
66
60
|
cs.__commands = []
|
@@ -76,7 +70,7 @@ class Task < Screwcap::Base
|
|
76
70
|
|
77
71
|
def clone_table_for(object)
|
78
72
|
self.table.each do |k,v|
|
79
|
-
object.set(k, v) unless [:
|
73
|
+
object.set(k, v) unless [:__block, :__tasks, :__name, :__command_sets, :__commands, :__options].include?(k)
|
80
74
|
end
|
81
75
|
end
|
82
76
|
|
@@ -91,48 +85,4 @@ class Task < Screwcap::Base
|
|
91
85
|
self.__servers = self.__server_names.map {|name| servers.find {|s| s.name == name } }
|
92
86
|
end
|
93
87
|
|
94
|
-
def execute_on(server, address)
|
95
|
-
begin
|
96
|
-
log blue("\n*** BEGIN executing task #{self.__name} on #{server.name} with address #{address}\n") unless self.__options[:silent] == true
|
97
|
-
|
98
|
-
server.__with_connection_for(address) do |ssh|
|
99
|
-
error = false
|
100
|
-
self.__commands.each do |command|
|
101
|
-
next if error and self.__options[:stop_on_errors]
|
102
|
-
|
103
|
-
if command[:type] == :remote
|
104
|
-
log green(" I: (#{address}): #{command[:command]}\n")
|
105
|
-
|
106
|
-
ssh.exec! command[:command] do |ch,stream,data|
|
107
|
-
if stream == :stderr
|
108
|
-
error = true
|
109
|
-
errorlog red(" E: (#{address}): #{data}")
|
110
|
-
else
|
111
|
-
log green(" O: (#{address}): #{data}")
|
112
|
-
end
|
113
|
-
end # ssh.exec
|
114
|
-
elsif command[:type] == :local
|
115
|
-
ret = `#{command[:command]}`
|
116
|
-
if $?.to_i == 0
|
117
|
-
log blue(" I: (local): #{command[:command]}\n")
|
118
|
-
log blue(" O: (local): #{ret}\n")
|
119
|
-
else
|
120
|
-
log blue(" I: (local): #{command[:command]}\n")
|
121
|
-
errorlog red(" O: (local): #{ret}\n")
|
122
|
-
end
|
123
|
-
elsif command[:type] == :scp
|
124
|
-
server.__upload_to!(address, command[:local], command[:remote])
|
125
|
-
log green(" I: (#{address}): SCP #{command[:local]} to #{server.__user}@#{address}:#{command[:remote]}")
|
126
|
-
end
|
127
|
-
end # commands.each
|
128
|
-
end # net.ssh start
|
129
|
-
rescue Net::SSH::AuthenticationFailed => e
|
130
|
-
raise Net::SSH::AuthenticationFailed, "Authentication failed for server named #{server.name}. Please check your authentication credentials."
|
131
|
-
rescue Exception => e
|
132
|
-
errorlog red(" F: (#{address}): #{e}")
|
133
|
-
ensure
|
134
|
-
log blue("*** END executing task #{self.__name} on #{server.name} with address #{address}\n\n") unless self.__options[:silent] == true
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
88
|
end
|
data/screwcap.gemspec
CHANGED
data/spec/command_set_spec.rb
CHANGED
@@ -4,7 +4,7 @@ describe "Command sets" do
|
|
4
4
|
before(:all) do
|
5
5
|
@stdout = []
|
6
6
|
Deployer.any_instance.stubs(:log).with() { |msg| @stdout << msg}
|
7
|
-
@deployer = Deployer.new(:recipe_file => "./test/config/command_sets.rb", :silent =>
|
7
|
+
@deployer = Deployer.new(:recipe_file => "./test/config/command_sets.rb", :silent => true)
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should be able to define a generic list of commands" do
|
@@ -48,4 +48,10 @@ describe "Command sets" do
|
|
48
48
|
task.__command_sets.first.instance_eval(&task.__command_sets.first.__block)
|
49
49
|
task.__commands.map {|c| c[:command]}.should == %w(birdo nested birdo task)
|
50
50
|
end
|
51
|
+
|
52
|
+
it "should be able to call scp just like a task" do
|
53
|
+
task = @deployer.__tasks.find {|t| t.__name == :task_use_scp}
|
54
|
+
task.__command_sets.first.instance_eval(&task.__command_sets.first.__block)
|
55
|
+
task.__commands.map {|c| c[:command]}.should == [nil]
|
56
|
+
end
|
51
57
|
end
|
data/spec/deployer_spec.rb
CHANGED
@@ -3,6 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe "Deployers" do
|
4
4
|
before(:all) do
|
5
5
|
Net::SSH.stubs(:start).yields(SSHObject.new(:return_stream => :stdout, :return_data => "hostname = asdf\n"))
|
6
|
+
Runner.stubs(:ssh_exec!).returns(["ok","",0,nil])
|
6
7
|
end
|
7
8
|
|
8
9
|
it "should complain if no server was defined" do
|
@@ -40,7 +41,7 @@ describe "Deployers" do
|
|
40
41
|
|
41
42
|
it "should be able to define command sets" do
|
42
43
|
deployer = Deployer.new(:recipe_file => "./test/config/command_sets.rb", :silent => true)
|
43
|
-
deployer.should have(
|
44
|
+
deployer.should have(9).__command_sets
|
44
45
|
end
|
45
46
|
|
46
47
|
it "should be able to define gateways" do
|
@@ -51,12 +52,13 @@ describe "Deployers" do
|
|
51
52
|
|
52
53
|
it "should be able to define sequences" do
|
53
54
|
deployer = Deployer.new(:recipe_file => "./test/config/simple_recipe.rb", :silent => true)
|
54
|
-
deployer.should have
|
55
|
+
deployer.should have(1).__sequences
|
55
56
|
end
|
56
57
|
|
57
58
|
it "should be able to run a single task" do
|
58
59
|
deployer = Deployer.new(:recipe_file => "./test/config/simple_recipe.rb", :silent => true)
|
59
|
-
|
60
|
+
deployer.run! :task1
|
61
|
+
#lambda { deployer.run! :task1 }.should_not raise_error
|
60
62
|
end
|
61
63
|
|
62
64
|
it "should be able to run multiple tasks" do
|
data/spec/sequence_spec.rb
CHANGED
data/spec/server_spec.rb
CHANGED
@@ -4,11 +4,8 @@ describe "Servers" do
|
|
4
4
|
before(:each) do
|
5
5
|
@stdout = []
|
6
6
|
@stderr = []
|
7
|
-
|
8
|
-
|
9
|
-
Deployer.any_instance.stubs(:log).with() { |msg| @stdout << msg }
|
10
|
-
Deployer.any_instance.stubs(:errorlog).with() { |msg| @stderr << msg }
|
11
|
-
|
7
|
+
Runner.stubs(:log).with() { |msg,opts| @stdout << msg }
|
8
|
+
Runner.stubs(:errorlog).with() { |msg,opts| @stderr << msg }
|
12
9
|
Net::SSH::Gateway.stubs(:new).returns(SSHObject.new)
|
13
10
|
end
|
14
11
|
|
@@ -34,7 +31,7 @@ describe "Servers" do
|
|
34
31
|
end
|
35
32
|
|
36
33
|
it "should provide a connection to the server with a gateway" do
|
37
|
-
@deployer = Deployer.new(:recipe_file => "./test/config/gateway.rb", :silent =>
|
34
|
+
@deployer = Deployer.new(:recipe_file => "./test/config/gateway.rb", :silent => true)
|
38
35
|
server = @deployer.__servers.find {|s| s.__name == :test}
|
39
36
|
gateway = @deployer.__servers.find {|s| s.__name == :gateway1}
|
40
37
|
|
data/spec/spec_helper.rb
CHANGED
@@ -7,19 +7,33 @@ require 'mocha'
|
|
7
7
|
require 'ruby-debug' rescue nil
|
8
8
|
require 'net/ssh'
|
9
9
|
|
10
|
-
class SSHObject
|
10
|
+
class SSHObject < OpenStruct
|
11
11
|
attr_accessor :options
|
12
12
|
|
13
13
|
def initialize(options = {})
|
14
|
-
@options = {:return_stream => :stdout}
|
15
|
-
@options = options
|
16
14
|
end
|
17
15
|
|
18
|
-
def
|
19
|
-
yield
|
16
|
+
def on_data
|
17
|
+
yield SSHObject.new, ""
|
20
18
|
end
|
21
19
|
|
22
|
-
def
|
23
|
-
yield
|
20
|
+
def on_extended_data
|
21
|
+
yield SSHObject.new, "", ""
|
22
|
+
end
|
23
|
+
|
24
|
+
def read_long
|
25
|
+
""
|
26
|
+
end
|
27
|
+
|
28
|
+
def upload!(from, to)
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def scp
|
33
|
+
SSHObject.new
|
34
|
+
end
|
35
|
+
|
36
|
+
def on_request(item)
|
37
|
+
yield SSHObject.new, SSHObject.new
|
24
38
|
end
|
25
39
|
end
|
data/spec/task_spec.rb
CHANGED
@@ -4,16 +4,15 @@ describe "Tasks" do
|
|
4
4
|
before(:each) do
|
5
5
|
@stdout = []
|
6
6
|
@stderr = []
|
7
|
-
|
8
|
-
|
9
|
-
Deployer.
|
10
|
-
Deployer.any_instance.stubs(:errorlog).with() { |msg| @stderr << msg }
|
11
|
-
@deployer = Deployer.new(:recipe_file => "./test/config/simple_recipe.rb", :silent => false)
|
7
|
+
Runner.stubs(:log).with() { |msg,opts| @stdout << msg }
|
8
|
+
Runner.stubs(:errorlog).with() { |msg,opts| @stderr << msg }
|
9
|
+
@deployer = Deployer.new(:recipe_file => "./test/config/simple_recipe.rb", :silent => true)
|
12
10
|
end
|
13
11
|
|
14
12
|
before(:all) do
|
15
13
|
Net::SSH.stubs(:start).yields(SSHObject.new(:return_stream => :stdout, :return_data => "hostname = asdf\n"))
|
16
14
|
Net::SCP.stubs(:upload!).returns(nil)
|
15
|
+
Runner.stubs(:ssh_exec!).returns(["ok","",0,nil])
|
17
16
|
end
|
18
17
|
|
19
18
|
it "should be able to create variables" do
|
@@ -28,9 +27,9 @@ describe "Tasks" do
|
|
28
27
|
|
29
28
|
it "should be able to execute statements on a remote server" do
|
30
29
|
task = @deployer.__tasks.find {|t| t.name == :task1 }
|
31
|
-
|
30
|
+
Runner.execute! task, @deployer.__options
|
32
31
|
@stderr.should == []
|
33
|
-
@stdout.size.should ==
|
32
|
+
@stdout.size.should == 26
|
34
33
|
end
|
35
34
|
|
36
35
|
it "should be able to use variables in the run statement" do
|
@@ -52,11 +51,11 @@ describe "Tasks" do
|
|
52
51
|
end
|
53
52
|
|
54
53
|
it "should complain if you do not pass the task a server argument" do
|
55
|
-
lambda { Deployer.new(:recipe_file => "./test/config/no_server.rb", :silent =>
|
54
|
+
lambda { Deployer.new(:recipe_file => "./test/config/no_server.rb", :silent => true)}.should raise_error(Screwcap::ConfigurationError)
|
56
55
|
end
|
57
56
|
|
58
57
|
it "should complain if you pass a server that is not defined" do
|
59
|
-
lambda { Deployer.new(:recipe_file => "./test/config/undefined_server.rb", :silent =>
|
58
|
+
lambda { Deployer.new(:recipe_file => "./test/config/undefined_server.rb", :silent => true)}.should raise_error(Screwcap::ConfigurationError)
|
60
59
|
end
|
61
60
|
|
62
61
|
it "should be able to disable parallel running" do
|
@@ -72,4 +71,12 @@ describe "Tasks" do
|
|
72
71
|
deployer = Deployer.new(:recipe_file => "./test/config/upload.rb", :silent => true)
|
73
72
|
deployer.run! :upload
|
74
73
|
end
|
74
|
+
|
75
|
+
it "should respond to onfailure" do
|
76
|
+
deployer = Deployer.new(:recipe_file => "./test/config/expect.rb", :silent => true)
|
77
|
+
t = deployer.__tasks.find {|t| t.__name == :expect }
|
78
|
+
Runner.stubs(:ssh_exec!).returns(["","fail",1,nil]).then.returns(["ok","",0,nil])
|
79
|
+
Runner.execute! t, deployer.__options
|
80
|
+
t.__commands.map {|c| [c[:command], c[:from]] }.first.should == ["echo 'we failed'", :failover]
|
81
|
+
end
|
75
82
|
end
|
data/test/config/command_sets.rb
CHANGED
@@ -47,6 +47,10 @@ command_set :nested_outside_with_var do
|
|
47
47
|
run :nested_var
|
48
48
|
end
|
49
49
|
|
50
|
+
command_set :use_scp do
|
51
|
+
scp :local => "/tmp/test", :remote => "/tmp/test"
|
52
|
+
end
|
53
|
+
|
50
54
|
|
51
55
|
task_for :use_command_set_no_override, :server => :test do
|
52
56
|
push_to_thang
|
@@ -85,3 +89,7 @@ task_for :nested_scoping, :server => :test do
|
|
85
89
|
nested_outside_with_var
|
86
90
|
run :nested_var
|
87
91
|
end
|
92
|
+
|
93
|
+
task_for :task_use_scp, :server => :test do
|
94
|
+
use_scp
|
95
|
+
end
|
data/test/config/expect.rb
CHANGED
@@ -5,26 +5,12 @@ command_set :revert do
|
|
5
5
|
run "revert"
|
6
6
|
end
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
when 1
|
11
|
-
run "1"
|
12
|
-
when 2
|
13
|
-
run "2"
|
14
|
-
else
|
15
|
-
run "none"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
command_set :fail do
|
20
|
-
run "ls"
|
21
|
-
end
|
22
|
-
|
23
|
-
command_set :success do
|
24
|
-
run "ls"
|
8
|
+
command_set :failover do
|
9
|
+
run "echo 'we failed'"
|
25
10
|
end
|
26
11
|
|
27
12
|
task_for :expect, :server => :test do
|
28
|
-
run "
|
13
|
+
run "this will fail", :onfailure => :failover
|
14
|
+
run "ls"
|
29
15
|
end
|
30
16
|
|
metadata
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: screwcap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 13
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: "0.
|
8
|
+
- 3
|
9
|
+
version: "0.3"
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Grant Ammons
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-10-
|
17
|
+
date: 2010-10-25 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -122,7 +122,6 @@ files:
|
|
122
122
|
- lib/exts.rb
|
123
123
|
- lib/screwcap.rb
|
124
124
|
- lib/screwcap/base.rb
|
125
|
-
- lib/screwcap/command_set.rb
|
126
125
|
- lib/screwcap/deployer.rb
|
127
126
|
- lib/screwcap/sequence.rb
|
128
127
|
- lib/screwcap/server.rb
|
data/lib/screwcap/command_set.rb
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
class CommandSet < Screwcap::Base
|
2
|
-
def initialize(opts = {}, &block)
|
3
|
-
super
|
4
|
-
self.__name = opts[:name]
|
5
|
-
self.__options = opts
|
6
|
-
self.__commands = []
|
7
|
-
self.__command_sets = []
|
8
|
-
self.__block = block
|
9
|
-
end
|
10
|
-
|
11
|
-
# run a command. basically just pass it a string containing the command you want to run.
|
12
|
-
def run arg, options = {}
|
13
|
-
if arg.class == Symbol
|
14
|
-
self.__commands << {:command => self.send(arg), :type => :remote}
|
15
|
-
else
|
16
|
-
self.__commands << {:command => arg, :type => :remote}
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# run a command. basically just pass it a string containing the command you want to run.
|
21
|
-
def local arg, options = {}
|
22
|
-
if arg.class == Symbol
|
23
|
-
self.__commands << {:command => self.send(arg), :type => :local}
|
24
|
-
else
|
25
|
-
self.__commands << {:command => arg, :type => :local}
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
|
30
|
-
protected
|
31
|
-
|
32
|
-
def method_missing(m, *args)
|
33
|
-
if m.to_s[0..1] == "__" or [:run].include?(m) or m.to_s.reverse[0..0] == "="
|
34
|
-
super(m, args.first)
|
35
|
-
else
|
36
|
-
if cs = self.__command_sets.find {|cs| cs.name == m }
|
37
|
-
# eval what is in the block
|
38
|
-
clone_table_for(cs)
|
39
|
-
cs.__commands = []
|
40
|
-
cs.instance_eval(&cs.__block)
|
41
|
-
self.__commands += cs.__commands
|
42
|
-
else
|
43
|
-
raise NoMethodError, "Undefined method '#{m.to_s}' for Command Set :#{self.name.to_s}"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
def clone_table_for(object)
|
51
|
-
self.table.each do |k,v|
|
52
|
-
object.set(k, v) unless [:__command_sets, :name, :__commands, :__options, :__block].include?(k)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
end
|