nickstenning-outback 0.0.1 → 0.0.2
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/lib/outback/manager.rb +33 -43
- data/lib/outback/shelltask.rb +53 -0
- data/lib/outback.rb +1 -3
- data/outback.gemspec +3 -3
- data/spec/outback/manager_spec.rb +65 -86
- data/spec/outback/shelltask_spec.rb +86 -0
- data/spec/outback/yaml_spec.rb +4 -4
- metadata +4 -6
- data/lib/outback/command.rb +0 -33
- data/lib/outback/task.rb +0 -61
- data/lib/outback/task_helper.rb +0 -21
- data/spec/outback/task_spec.rb +0 -63
data/lib/outback/manager.rb
CHANGED
@@ -1,82 +1,72 @@
|
|
1
1
|
require 'yaml'
|
2
|
-
require 'tempfile'
|
3
2
|
|
4
3
|
module Outback
|
5
4
|
|
6
5
|
class Manager
|
7
6
|
|
8
|
-
|
9
|
-
|
7
|
+
ROLLOUT = 1
|
8
|
+
ROLLBACK = -1
|
9
|
+
|
10
|
+
attr_reader :tasks, :position
|
10
11
|
attr_accessor :workdir
|
12
|
+
attr_writer :watcher
|
11
13
|
|
12
14
|
def initialize
|
13
15
|
@tasks = []
|
14
|
-
@statuses = []
|
15
|
-
@errors = []
|
16
16
|
@position = 0
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
20
|
-
|
19
|
+
def add_tasks( *tasks )
|
20
|
+
[*tasks].each do |task|
|
21
|
+
task.workdir = @workdir unless task.workdir
|
22
|
+
end
|
23
|
+
@tasks += [*tasks]
|
24
|
+
end
|
25
|
+
|
26
|
+
alias_method :add_task, :add_tasks
|
27
|
+
|
28
|
+
def rollout!
|
29
|
+
@direction = ROLLOUT
|
21
30
|
run
|
22
31
|
end
|
23
32
|
|
24
|
-
def rollback
|
25
|
-
@direction =
|
33
|
+
def rollback!
|
34
|
+
@direction = ROLLBACK
|
26
35
|
run
|
27
36
|
end
|
28
37
|
|
29
38
|
def rollout_from( task )
|
30
39
|
@position = @tasks.index(task)
|
31
|
-
rollout
|
40
|
+
rollout!
|
32
41
|
end
|
33
42
|
|
34
43
|
def rollback_from( task )
|
35
44
|
@position = @tasks.index(task) - 1
|
36
|
-
rollback
|
37
|
-
end
|
38
|
-
|
39
|
-
def attempt
|
40
|
-
method = {1 => :rollout, -1 => :rollback}[@direction]
|
41
|
-
Dir.chdir(@workdir || Dir.pwd) do
|
42
|
-
@statuses << [method, *current_task.send(method)]
|
43
|
-
end
|
44
|
-
return latest_okay?
|
45
|
-
end
|
46
|
-
|
47
|
-
def latest_okay?
|
48
|
-
status[1] == 0
|
45
|
+
rollback!
|
49
46
|
end
|
50
47
|
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
@statuses.last
|
48
|
+
def attempt( task )
|
49
|
+
method = {ROLLOUT => :rollout!, ROLLBACK => :rollback!}[@direction]
|
50
|
+
ret = task.send(method)
|
51
|
+
@watcher.notify(task) if @watcher
|
52
|
+
return ret
|
57
53
|
end
|
58
54
|
|
59
55
|
def current_task
|
60
56
|
@tasks[@position]
|
61
57
|
end
|
62
58
|
|
63
|
-
def state
|
64
|
-
{ :position => @position,
|
65
|
-
:direction => @direction,
|
66
|
-
:statuses => @statuses }
|
67
|
-
end
|
68
|
-
|
69
59
|
private
|
70
60
|
|
71
61
|
def run
|
72
|
-
if @direction ==
|
62
|
+
if @direction == ROLLOUT
|
73
63
|
task_list = @tasks[@position..-1]
|
74
|
-
elsif @direction ==
|
64
|
+
elsif @direction == ROLLBACK
|
75
65
|
task_list = @tasks[0..@position + 1].reverse
|
76
66
|
end
|
77
67
|
task_list.each do |task|
|
78
68
|
@position = @tasks.index(task)
|
79
|
-
unless attempt
|
69
|
+
unless attempt current_task
|
80
70
|
fail
|
81
71
|
break
|
82
72
|
end
|
@@ -84,11 +74,11 @@ module Outback
|
|
84
74
|
end
|
85
75
|
|
86
76
|
def fail
|
87
|
-
case
|
88
|
-
when
|
89
|
-
rollback_from current_task
|
90
|
-
raise
|
91
|
-
when
|
77
|
+
case @direction
|
78
|
+
when ROLLOUT
|
79
|
+
#rollback_from current_task
|
80
|
+
raise Error, "Could not rollout task #{current_task}, attempting rollback."
|
81
|
+
when ROLLBACK
|
92
82
|
raise TransactionError, "Could not rollback task #{current_task}, aborting."
|
93
83
|
else
|
94
84
|
raise Error, "Unknown direction!"
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'open4'
|
3
|
+
|
4
|
+
module Outback
|
5
|
+
|
6
|
+
class ShellTask
|
7
|
+
|
8
|
+
attr_accessor :rollout, :rollback, :workdir
|
9
|
+
attr_reader :result, :errors, :exit_code
|
10
|
+
|
11
|
+
def initialize(out, back)
|
12
|
+
@rollout, @rollback = out, back
|
13
|
+
@rolled_out = false
|
14
|
+
end
|
15
|
+
|
16
|
+
def rollout!
|
17
|
+
run @rollout
|
18
|
+
@rolled_out = true
|
19
|
+
return @exit_code == 0
|
20
|
+
end
|
21
|
+
|
22
|
+
def rollback!
|
23
|
+
run @rollback
|
24
|
+
@rolled_out = false
|
25
|
+
return @exit_code == 0
|
26
|
+
end
|
27
|
+
|
28
|
+
def rolled_out?
|
29
|
+
@rolled_out
|
30
|
+
end
|
31
|
+
|
32
|
+
def reset_strings
|
33
|
+
@result, @errors = "", ""
|
34
|
+
end
|
35
|
+
|
36
|
+
def run( command )
|
37
|
+
reset_strings
|
38
|
+
Dir.chdir(@workdir || Dir.getwd) do
|
39
|
+
@status = Open4.popen4(*command) do |pid, i, o, e|
|
40
|
+
@result = o.read
|
41
|
+
@errors = e.read
|
42
|
+
end
|
43
|
+
@exit_code = @status.exitstatus
|
44
|
+
end
|
45
|
+
# Catch nonexistent commands at this point and return a sensible error
|
46
|
+
rescue Errno::ENOENT => e
|
47
|
+
@exit_code = 127
|
48
|
+
@errors = e.message
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/lib/outback.rb
CHANGED
data/outback.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = %q{outback}
|
3
|
-
s.version = "0.0.
|
3
|
+
s.version = "0.0.2"
|
4
4
|
|
5
5
|
s.specification_version = 2 if s.respond_to? :specification_version=
|
6
6
|
|
@@ -8,11 +8,11 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.authors = ["Nick Stenning"]
|
9
9
|
s.date = %q{2008-07-14}
|
10
10
|
s.email = ["nick@whiteink.com"]
|
11
|
-
s.files = ["lib/outback/
|
11
|
+
s.files = ["lib/outback/manager.rb", "lib/outback/shelltask.rb", "lib/outback/yaml.rb", "lib/outback.rb", "outback.gemspec", "spec/outback/manager_spec.rb", "spec/outback/shelltask_spec.rb", "spec/outback/yaml_spec.rb", "spec/spec_helper.rb"]
|
12
12
|
s.has_rdoc = true
|
13
13
|
s.homepage = %q{http://github.com/nickstenning/outback}
|
14
14
|
s.require_paths = ["lib"]
|
15
|
-
s.summary = %q{
|
15
|
+
s.summary = %q{Run pairs of rollout/rollback tasks in a transactional manner.}
|
16
16
|
s.description = %{Run pairs of rollout/rollback tasks in a transactional manner.}
|
17
17
|
|
18
18
|
s.add_dependency("open4", [">= 0.9.0"])
|
@@ -5,121 +5,100 @@ describe Outback::Manager do
|
|
5
5
|
|
6
6
|
before do
|
7
7
|
@obm = Outback::Manager.new
|
8
|
-
@task1 = mock("task1", :
|
9
|
-
@task2 = mock("task2", :
|
8
|
+
@task1 = mock("task1", :workdir => "/tmp")
|
9
|
+
@task2 = mock("task2", :workdir => nil)
|
10
|
+
@task1.stub!(:workdir=)
|
11
|
+
@task2.stub!(:workdir=)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should have a list of tasks" do
|
15
|
+
@obm.tasks.should be_a_kind_of(Enumerable)
|
16
|
+
@obm.should have(0).tasks
|
10
17
|
end
|
11
18
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should have a rollout method" do
|
20
|
-
@obm.should respond_to(:rollout)
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should have a rollback method" do
|
24
|
-
@obm.should respond_to(:rollback)
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should add tasks to its list with standard array operations" do
|
28
|
-
@obm.should have(0).tasks
|
29
|
-
@obm.tasks << @task1
|
30
|
-
@obm.should have(1).tasks
|
31
|
-
@obm.tasks << @task2
|
32
|
-
@obm.should have(2).tasks
|
33
|
-
end
|
34
|
-
|
19
|
+
it "should add a task to its list with #add_task" do
|
20
|
+
@obm.add_task(@task1)
|
21
|
+
@obm.should have(1).tasks
|
22
|
+
@obm.add_task(@task2)
|
23
|
+
@obm.should have(2).tasks
|
35
24
|
end
|
36
25
|
|
26
|
+
it "should add multiple tasks to its list, in order, with #add_tasks" do
|
27
|
+
@obm.add_tasks(@task1, @task2, @task1)
|
28
|
+
@obm.should have(3).tasks
|
29
|
+
@obm.tasks[0].should == @task1
|
30
|
+
@obm.tasks[1].should == @task2
|
31
|
+
@obm.tasks[2].should == @task1
|
32
|
+
end
|
33
|
+
|
37
34
|
describe "(with a few tasks)" do
|
38
35
|
|
39
36
|
before do
|
40
|
-
@obm.
|
37
|
+
@obm.add_tasks(@task1, @task2)
|
41
38
|
end
|
42
39
|
|
43
|
-
it "should call each task's rollout method on rollout
|
44
|
-
@task1.should_receive(:rollout).and_return(
|
45
|
-
@task2.should_receive(:rollout).and_return(
|
46
|
-
@obm.rollout
|
40
|
+
it "should call each task's #rollout! method, in order, on #rollout!" do
|
41
|
+
@task1.should_receive(:rollout!).and_return(true)
|
42
|
+
@task2.should_receive(:rollout!).and_return(true)
|
43
|
+
@obm.rollout!
|
47
44
|
end
|
48
45
|
|
49
|
-
it "should call each task's rollback method
|
50
|
-
@
|
51
|
-
@
|
52
|
-
@obm.
|
46
|
+
it "should call each task's #rollback! method, in reverse order, on #rollback!" do
|
47
|
+
@task1.should_receive(:rollout!).and_return(true)
|
48
|
+
@task2.should_receive(:rollout!).and_return(true)
|
49
|
+
@obm.rollout!
|
53
50
|
end
|
54
51
|
|
55
52
|
it "should raise an Outback::Error if a rollout fails" do
|
56
|
-
@task1.stub!(:rollback)
|
57
|
-
@task1.should_receive(:rollout).and_return(
|
58
|
-
@task2.should_not_receive(:rollout)
|
59
|
-
@task2.should_not_receive(:rollback)
|
60
|
-
lambda { @obm.rollout }.should raise_error(Outback::Error)
|
53
|
+
@task1.stub!(:rollback!)
|
54
|
+
@task1.should_receive(:rollout!).and_return(false)
|
55
|
+
@task2.should_not_receive(:rollout!)
|
56
|
+
@task2.should_not_receive(:rollback!)
|
57
|
+
lambda { @obm.rollout! }.should raise_error(Outback::Error)
|
61
58
|
end
|
62
59
|
|
63
|
-
it "should raise an Outback::
|
64
|
-
@task2.should_receive(:rollback).and_return(
|
65
|
-
@task1.should_not_receive(:rollback)
|
66
|
-
lambda { @obm.rollback }.should raise_error(Outback::
|
60
|
+
it "should raise an Outback::TransactionError if a rollback subsequently fails" do
|
61
|
+
@task2.should_receive(:rollback!).and_return(false)
|
62
|
+
@task1.should_not_receive(:rollback!)
|
63
|
+
lambda { @obm.rollback! }.should raise_error(Outback::TransactionError)
|
67
64
|
end
|
68
65
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
@obm.rollout
|
73
|
-
@obm.status.should == [:rollout, 0, "Another message", ""]
|
74
|
-
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "(with #workdir set)" do
|
75
69
|
|
76
|
-
|
77
|
-
@task1.
|
78
|
-
@task1.
|
79
|
-
@task2.
|
80
|
-
|
81
|
-
|
82
|
-
rescue Outback::Error
|
83
|
-
@obm.status.should == [:rollback, 0, "Getting rolled back", ""]
|
84
|
-
end
|
70
|
+
before do
|
71
|
+
@task1 = Outback::ShellTask.new("", "")
|
72
|
+
@task1.workdir = "/tmp"
|
73
|
+
@task2 = Outback::ShellTask.new("", "")
|
74
|
+
@obm.workdir = "/nonexistent"
|
75
|
+
@obm.add_tasks(@task1, @task2)
|
85
76
|
end
|
86
77
|
|
87
|
-
it "should
|
88
|
-
@task1.
|
89
|
-
@task2.
|
90
|
-
@task2.should_receive(:rollback).and_return([0, "Getting rolled back", ""])
|
91
|
-
@task1.should_receive(:rollback).and_return([3, "", "Error while rolling back"])
|
92
|
-
begin
|
93
|
-
@obm.rollout
|
94
|
-
rescue Outback::Error
|
95
|
-
@obm.should have(2).errors
|
96
|
-
@obm.errors[0].should == [:rollout, 1, "", "Error message"]
|
97
|
-
@obm.errors[1].should == [:rollback, 3, "", "Error while rolling back"]
|
98
|
-
end
|
78
|
+
it "should set the workdir of each of its tasks if it is currently nil" do
|
79
|
+
@task1.workdir.should == "/tmp"
|
80
|
+
@task2.workdir.should == "/nonexistent"
|
99
81
|
end
|
100
82
|
|
101
|
-
it "should rollback previously rolled-out tasks if a rollout fails" do
|
102
|
-
@task1.should_receive(:rollout).ordered.and_return([1, "", "Error message"])
|
103
|
-
@task2.should_not_receive(:rollout)
|
104
|
-
@task1.should_receive(:rollback).ordered
|
105
|
-
@task2.should_not_receive(:rollback)
|
106
|
-
begin
|
107
|
-
@obm.rollout
|
108
|
-
rescue Outback::Error
|
109
|
-
end
|
110
|
-
end
|
111
83
|
end
|
112
84
|
|
113
|
-
describe "(with #
|
85
|
+
describe "(with #watcher set)" do
|
114
86
|
|
115
87
|
before do
|
116
|
-
@
|
117
|
-
@
|
88
|
+
@task1 = Outback::ShellTask.new("pwd", "")
|
89
|
+
@task2 = Outback::ShellTask.new("echo 'hello'", "")
|
90
|
+
require 'tempfile'
|
91
|
+
@obm.workdir = Dir.tmpdir
|
92
|
+
@obm.add_tasks(@task1, @task2)
|
93
|
+
@watcher = mock("watcher")
|
94
|
+
@obm.watcher = @watcher
|
118
95
|
end
|
119
96
|
|
120
|
-
it "should
|
121
|
-
@
|
122
|
-
@
|
97
|
+
it "should call the watcher's #notify method after every task rollout/rollback with the task as an argument" do
|
98
|
+
@watcher.should_receive(:notify).ordered.with(@task1)
|
99
|
+
@watcher.should_receive(:notify).ordered.with(@task2)
|
100
|
+
@obm.rollout!
|
123
101
|
end
|
102
|
+
|
124
103
|
end
|
125
104
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Outback::ShellTask do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@task = Outback::ShellTask.new("out", "back")
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should use the first parameter to the rollout command" do
|
10
|
+
@task.rollout.should == "out"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should use the second parameter as the rollback command" do
|
14
|
+
@task.rollback.should == "back"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should allow its rollout command to be changed with #rollout=" do
|
18
|
+
@task.rollout = "foo"
|
19
|
+
@task.rollout.should == "foo"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should allow its rollback command to be changed with #rollback=" do
|
23
|
+
@task.rollout = "bar"
|
24
|
+
@task.rollout.should == "bar"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should not be rolled out by default" do
|
28
|
+
@task.should_not be_rolled_out
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should rollout when called with #rollout!" do
|
32
|
+
@task.rollout!
|
33
|
+
@task.should be_rolled_out
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should run its commands in the current working directory if #workdir hasn't been set" do
|
37
|
+
@task = Outback::ShellTask.new("pwd", "")
|
38
|
+
@task.rollout!
|
39
|
+
@task.result.chomp.should == Dir.getwd
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should run its commands in the workdir, if set with #workdir=" do
|
43
|
+
@task = Outback::ShellTask.new("pwd", "")
|
44
|
+
@task.workdir = "/private/tmp" ## FIXME for *nix systems
|
45
|
+
@task.rollout!
|
46
|
+
@task.result.chomp.should == @task.workdir
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should return true on successful #rollout! or #rollback!" do
|
50
|
+
@task = Outback::ShellTask.new("echo", "echo")
|
51
|
+
@task.rollout!.should be_true
|
52
|
+
@task.rollback!.should be_true
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should return false on unsuccessful #rollout! or #rollback!" do
|
56
|
+
@task = Outback::ShellTask.new("I-am-a-command-most-unlikely-to-exist", "I-am-a-command-most-unlikely-to-exist")
|
57
|
+
@task.rollout!.should be_false
|
58
|
+
@task.rollback!.should be_false
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "(when rolled out)" do
|
62
|
+
|
63
|
+
before do
|
64
|
+
@task = Outback::ShellTask.new('pwd', 'pwd')
|
65
|
+
@task.rollout!
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should be rolled out" do
|
69
|
+
@task.should be_rolled_out
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should have an integer exit code" do
|
73
|
+
@task.exit_code.should be_a_kind_of(Fixnum)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should have a string result" do
|
77
|
+
@task.result.should be_a_kind_of(String)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should have a string for errors (stderr)" do
|
81
|
+
@task.errors.should be_a_kind_of(String)
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
data/spec/outback/yaml_spec.rb
CHANGED
@@ -35,13 +35,13 @@ describe Outback::YAML do
|
|
35
35
|
end
|
36
36
|
it "should set the rollout_command to the first element of the YAML array" do
|
37
37
|
manager = Outback::YAML.load(@yaml)
|
38
|
-
manager.tasks[0].
|
39
|
-
manager.tasks[1].
|
38
|
+
manager.tasks[0].rollout.should == "touch y"
|
39
|
+
manager.tasks[1].rollout.should == "touch x"
|
40
40
|
end
|
41
41
|
it "should set the rollback_command to the second element of the YAML array" do
|
42
42
|
manager = Outback::YAML.load(@yaml)
|
43
|
-
manager.tasks[0].
|
44
|
-
manager.tasks[1].
|
43
|
+
manager.tasks[0].rollback.should == "rm y"
|
44
|
+
manager.tasks[1].rollback.should == "rm x"
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nickstenning-outback
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Stenning
|
@@ -31,15 +31,13 @@ extensions: []
|
|
31
31
|
extra_rdoc_files: []
|
32
32
|
|
33
33
|
files:
|
34
|
-
- lib/outback/command.rb
|
35
34
|
- lib/outback/manager.rb
|
36
|
-
- lib/outback/
|
37
|
-
- lib/outback/task_helper.rb
|
35
|
+
- lib/outback/shelltask.rb
|
38
36
|
- lib/outback/yaml.rb
|
39
37
|
- lib/outback.rb
|
40
38
|
- outback.gemspec
|
41
39
|
- spec/outback/manager_spec.rb
|
42
|
-
- spec/outback/
|
40
|
+
- spec/outback/shelltask_spec.rb
|
43
41
|
- spec/outback/yaml_spec.rb
|
44
42
|
- spec/spec_helper.rb
|
45
43
|
has_rdoc: true
|
@@ -67,6 +65,6 @@ rubyforge_project:
|
|
67
65
|
rubygems_version: 1.2.0
|
68
66
|
signing_key:
|
69
67
|
specification_version: 2
|
70
|
-
summary:
|
68
|
+
summary: Run pairs of rollout/rollback tasks in a transactional manner.
|
71
69
|
test_files: []
|
72
70
|
|
data/lib/outback/command.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
module Outback
|
2
|
-
|
3
|
-
class Command
|
4
|
-
|
5
|
-
def initialize( script )
|
6
|
-
@manager = Manager.new
|
7
|
-
parse(script)
|
8
|
-
end
|
9
|
-
|
10
|
-
def parse( script )
|
11
|
-
script.each_line do |l|
|
12
|
-
out, back = l[/^([^\^]+)\s*\^\s*(.+)$/]
|
13
|
-
p "o:", out, "b:", back
|
14
|
-
if out and back
|
15
|
-
p out, back
|
16
|
-
t = Task.new("temp")
|
17
|
-
t.rollout { |t| t.sys out }
|
18
|
-
t.rollback { |t| t.sys back }
|
19
|
-
@manager.tasks << t
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def run( command )
|
25
|
-
raise %{Command "#{command}" not understood.} unless [:rollout, :rollback].include? command
|
26
|
-
|
27
|
-
#@manager.tasks.each
|
28
|
-
#@manager.send(command)
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
data/lib/outback/task.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
require 'stringio'
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'open4'
|
5
|
-
|
6
|
-
module Outback
|
7
|
-
|
8
|
-
class Task
|
9
|
-
|
10
|
-
attr_reader :name
|
11
|
-
attr_accessor :stdout, :stderr
|
12
|
-
|
13
|
-
def initialize
|
14
|
-
@rollout, @rollback = lambda {}
|
15
|
-
@stdout = StringIO.new
|
16
|
-
@stderr = StringIO.new
|
17
|
-
end
|
18
|
-
|
19
|
-
def rollout( &block )
|
20
|
-
if block_given?
|
21
|
-
@rollout = block
|
22
|
-
else
|
23
|
-
run @rollout
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def rollback( &block )
|
28
|
-
if block_given?
|
29
|
-
@rollback = block
|
30
|
-
else
|
31
|
-
run @rollback
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def run( proc )
|
38
|
-
proc.call(TaskHelper.new(self))
|
39
|
-
[0, stdout.string, stderr.string]
|
40
|
-
rescue SystemCallError => err
|
41
|
-
[1, stdout.string, stderr.string]
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
|
47
|
-
class ShellTask < Task
|
48
|
-
|
49
|
-
attr_reader :rollout_command, :rollback_command
|
50
|
-
|
51
|
-
def initialize(rollout, rollback)
|
52
|
-
super()
|
53
|
-
@rollout = lambda { |t| t.sys rollout }
|
54
|
-
@rollout_command = rollout
|
55
|
-
@rollback = lambda { |t| t.sys rollback }
|
56
|
-
@rollback_command = rollback
|
57
|
-
end
|
58
|
-
|
59
|
-
end
|
60
|
-
|
61
|
-
end
|
data/lib/outback/task_helper.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
module Outback
|
2
|
-
|
3
|
-
class TaskHelper
|
4
|
-
|
5
|
-
def initialize( task )
|
6
|
-
@task = task
|
7
|
-
end
|
8
|
-
|
9
|
-
def sys( *args )
|
10
|
-
pid, i, o, e = Open4.popen4(*args)
|
11
|
-
o.each_line { |l| @task.stdout.print "[#{pid}] #{l}" }
|
12
|
-
e.each_line { |l| @task.stderr.print "E [#{pid}] #{l}" }
|
13
|
-
end
|
14
|
-
|
15
|
-
def puts( *args )
|
16
|
-
@task.stdout.puts *args
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
data/spec/outback/task_spec.rb
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
-
|
3
|
-
describe Outback::Task do
|
4
|
-
|
5
|
-
before do
|
6
|
-
@task = Outback::Task.new
|
7
|
-
end
|
8
|
-
|
9
|
-
it "should allow its rollout method to be defined with #rollout" do
|
10
|
-
rollout_proc = lambda { |t| t.puts "rollout" }
|
11
|
-
|
12
|
-
lambda do
|
13
|
-
@task.rollout &rollout_proc
|
14
|
-
end.should_not raise_error
|
15
|
-
|
16
|
-
@task.rollout.should == [0, "rollout\n", ""]
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should allow its rollback method to be defined with #rollback" do
|
20
|
-
rollback_proc = lambda { |t| t.puts "rollback" }
|
21
|
-
|
22
|
-
lambda do
|
23
|
-
@task.rollback &rollback_proc
|
24
|
-
end.should_not raise_error
|
25
|
-
|
26
|
-
@task.rollback.should == [0, "rollback\n", ""]
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should have a rollout method" do
|
30
|
-
@task.should respond_to(:rollout)
|
31
|
-
end
|
32
|
-
|
33
|
-
it "should have a rollback method" do
|
34
|
-
@task.should respond_to(:rollback)
|
35
|
-
end
|
36
|
-
|
37
|
-
it "should return an exit code and the command output when rollout or rollback is run" do
|
38
|
-
returns = @task.rollout
|
39
|
-
returns[0].should be_a_kind_of(Numeric)
|
40
|
-
returns[1].should be_a_kind_of(String)
|
41
|
-
returns[2].should be_a_kind_of(String)
|
42
|
-
end
|
43
|
-
|
44
|
-
it "should provide a 'sys' method to rollout and rollback blocks to allow system calls" do
|
45
|
-
@task.rollout do |t|
|
46
|
-
t.sys 'echo', 'system call'
|
47
|
-
end
|
48
|
-
ret = []
|
49
|
-
lambda { ret = @task.rollout }.should_not raise_error
|
50
|
-
ret[0].should == 0
|
51
|
-
ret[1].should match(/\[\d+\] system call\n/)
|
52
|
-
ret[2].should be_empty
|
53
|
-
end
|
54
|
-
|
55
|
-
it "should catch failed system commands and provide an appropriate exit code" do
|
56
|
-
@task.rollout do |t|
|
57
|
-
t.sys "nonexistent"
|
58
|
-
end
|
59
|
-
ret = []
|
60
|
-
lambda { ret = @task.rollout }.should_not raise_error
|
61
|
-
ret[0].should == 1
|
62
|
-
end
|
63
|
-
end
|