hadouken 0.1.4.pre

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.
@@ -0,0 +1,58 @@
1
+ module Hadouken::Task
2
+ class Base
3
+ attr_reader :plan
4
+ attr_reader :group_name
5
+
6
+ def initialize(opts)
7
+ @group_name = opts[:group]
8
+ @plan = opts[:plan ]
9
+ end
10
+
11
+ def group?
12
+ !! @group_name
13
+ end
14
+
15
+ def group
16
+ @plan.group(@group_name)
17
+ end
18
+
19
+ def self.create!(instance, opts)
20
+ return case instance
21
+ # autovivify
22
+ when String then Hadouken::Task::Command.new instance, opts
23
+ when Array then Hadouken::Task::Command.new instance, opts
24
+ when Proc then Hadouken::Task::Callback.new instance, opts
25
+
26
+ # go with it
27
+ when Hadouken::Strategy::Base then instance
28
+ when Hadouken::Task::Base then instance
29
+
30
+ # no chance
31
+ else raise ArgumentError
32
+ end
33
+ end
34
+ end
35
+
36
+ class Command < Base
37
+ def initialize(command, opts)
38
+ @command = command
39
+ super(opts)
40
+ end
41
+
42
+ # TODO: sanitize command so it has a chance of working
43
+ def command
44
+ @command
45
+ end
46
+ end
47
+
48
+ class Callback < Base
49
+ def initialize(fn, opts)
50
+ @proc = fn
51
+ super opts
52
+ end
53
+
54
+ def call(opts)
55
+ @proc.call(*opts)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,17 @@
1
+ class Hadouken::Tasks
2
+ include Enumerable
3
+
4
+ def initialize
5
+ @tasks = []
6
+ end
7
+
8
+ def each
9
+ @tasks.each do |task|
10
+ yield task
11
+ end
12
+ end
13
+
14
+ def add(task, opts={})
15
+ @tasks << Hadouken::Task::Base.create!(task, opts)
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ begin
5
+ Bundler.setup(:default, :development)
6
+ rescue Bundler::BundlerError => e
7
+ $stderr.puts e.message
8
+ $stderr.puts "Run `bundle install` to install missing gems"
9
+ exit e.status_code
10
+ end
11
+ require 'test/unit'
12
+ require 'shoulda'
13
+ require 'mocha'
14
+ require 'pp'
15
+
16
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
17
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
18
+ require 'hadouken'
19
+
20
+ class Test::Unit::TestCase
21
+ end
@@ -0,0 +1,118 @@
1
+ require 'helper'
2
+
3
+ class TestHadouken < Test::Unit::TestCase
4
+
5
+ context "yeah" do
6
+ setup do
7
+ Net::SSH::Multi::Session.any_instance.stubs(:exec).returns(true)
8
+ Net::SSH::Multi::Subsession.any_instance.stubs(:exec).returns(true)
9
+ end
10
+
11
+ should "create a group" do
12
+ g = Hadouken::Group.new(:name => :pony, :range => (1..5), :pattern => "pony-%05d")
13
+ assert_equal g.name, :pony
14
+ assert_equal g.range, (1..5)
15
+ assert_equal g.pattern, "pony-%05d"
16
+ assert_equal g.size, 5
17
+ assert_equal g.hosts, g.range.map{|i| g.pattern % i}
18
+ end
19
+
20
+ should "create a collection of groups" do
21
+ plan = Hadouken::Plan.new
22
+ plan.verbose = true
23
+ plan.add_group Hadouken::Group.new(:name => :cat, :range => (1..3), :pattern => "cat-%05d")
24
+ plan.add_group Hadouken::Group.new(:name => :dog, :range => (1..5), :pattern => "dog-%05d")
25
+
26
+ assert_equal 8, plan.groups.hosts.size
27
+ assert_equal plan.groups.fetch(:cat), plan.groups[:cat]
28
+ assert_equal 'cat-00003', plan.groups.fetch(:cat).hosts.last
29
+ assert_equal 'dog-00005', plan.groups.fetch(:dog).hosts.last
30
+ end
31
+
32
+ should "use by-host strategy" do
33
+ plan = Hadouken::Plan.new
34
+ plan.verbose = true
35
+ plan.add_group Hadouken::Group.new(:name => :cat, :range => (1..3), :pattern => "cat-%05d")
36
+ plan.add_group Hadouken::Group.new(:name => :dog, :range => (1..3), :pattern => "dog-%05d")
37
+
38
+ cats = (1..3).map{|i| "cat-%05d" % i}
39
+ dogs = (1..3).map{|i| "dog-%05d" % i}
40
+ crazy = [ cats + dogs ]
41
+
42
+ servers = Hadouken::Strategy::ByHost.new(plan).host_strategy
43
+ assert_equal crazy, servers
44
+ end
45
+
46
+ should "use by-host strategy with two at a time" do
47
+ plan = Hadouken::Plan.new
48
+ plan.verbose = true
49
+ plan.add_group Hadouken::Group.new(:name => :cat, :range => (1..3), :pattern => "cat-%05d")
50
+ plan.add_group Hadouken::Group.new(:name => :dog, :range => (1..3), :pattern => "dog-%05d")
51
+
52
+ cats = (1..3).map{|i| "cat-%05d" % i}
53
+ dogs = (1..3).map{|i| "dog-%05d" % i}
54
+ crazy = []
55
+ (cats + dogs).each_slice(2) do |s|
56
+ crazy << s
57
+ end
58
+
59
+ servers = Hadouken::Strategy::ByHost.new(plan, :max_hosts => 2).host_strategy
60
+ assert_equal crazy, servers
61
+ end
62
+
63
+
64
+ should "use by-group strategy with two at a time" do
65
+ plan = Hadouken::Plan.new
66
+ plan.verbose = true
67
+ plan.add_group Hadouken::Group.new(:name => :cat, :range => (1..3), :pattern => "cat-%05d")
68
+ plan.add_group Hadouken::Group.new(:name => :dog, :range => (1..3), :pattern => "dog-%05d")
69
+
70
+ cats = (1..3).map{|i| "cat-%05d" % i}
71
+ dogs = (1..3).map{|i| "dog-%05d" % i}
72
+
73
+ servers = Hadouken::Strategy::ByGroup.new(plan, :max_hosts => 2).host_strategy
74
+ assert_equal cats[0..1], servers[0]
75
+ assert_equal [cats[2]], servers[1]
76
+ assert_equal dogs[0..1], servers[2]
77
+ assert_equal [dogs[2]], servers[3]
78
+ end
79
+
80
+
81
+ should "use by-group-parallel strategy" do
82
+ plan = Hadouken::Plan.new
83
+ plan.verbose = true
84
+ plan.name = :pet_store
85
+ plan.add_group Hadouken::Group.new(:name => :cat, :range => (1..3), :pattern => "cat-%05d")
86
+ plan.add_group Hadouken::Group.new(:name => :dog, :range => (1..3), :pattern => "dog-%05d")
87
+ plan.add_group Hadouken::Group.new(:name => :hog, :range => (1..3), :pattern => "hog-%05d")
88
+
89
+ cats = (1..3).map{|i| "cat-%05d" % i}
90
+ dogs = (1..3).map{|i| "dog-%05d" % i}
91
+ hogs = (1..3).map{|i| "hog-%05d" % i}
92
+
93
+ crazy = []
94
+ crazy << [ cats[0], dogs[0], hogs[0] ]
95
+ crazy << [ cats[1], dogs[1], hogs[1] ]
96
+ crazy << [ cats[2], dogs[2], hogs[2] ]
97
+
98
+ plan.tasks.add Hadouken::Strategy::ByHost.new(plan)
99
+ plan.tasks.add Hadouken::Task::Command.new("aaa", :plan => plan)
100
+ plan.tasks.add "bbb", :plan => plan
101
+ plan.tasks.add Proc.new{|host|
102
+ }, :plan => plan
103
+
104
+ plan.tasks.add Hadouken::Strategy::ByGroupParallel.new(plan, :max_hosts => 4, :traversal => :depth)
105
+ plan.tasks.add Hadouken::Task::Command.new("doggie", :plan => plan, :group_name => :dog)
106
+ plan.tasks.add Hadouken::Task::Command.new("kitty", :plan => plan, :group_name => :cat)
107
+ plan.tasks.add Hadouken::Task::Command.new("pig", :plan => plan, :group_name => :hog)
108
+ plan.tasks.add Proc.new{|host|
109
+ puts "**************** #{host} ******************"
110
+ }, :plan => plan
111
+
112
+ Hadouken::Executor.run!(plan)
113
+ end
114
+
115
+
116
+
117
+ end
118
+ end
metadata ADDED
@@ -0,0 +1,164 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hadouken
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.4.pre
5
+ prerelease: 6
6
+ platform: ruby
7
+ authors:
8
+ - Matt Knopp
9
+ - Chris Gray
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-01-27 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: net-ssh
17
+ requirement: &70333320089840 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *70333320089840
26
+ - !ruby/object:Gem::Dependency
27
+ name: net-ssh-multi
28
+ requirement: &70333320089100 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *70333320089100
37
+ - !ruby/object:Gem::Dependency
38
+ name: yajl-ruby
39
+ requirement: &70333320088360 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *70333320088360
48
+ - !ruby/object:Gem::Dependency
49
+ name: shoulda
50
+ requirement: &70333320087540 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *70333320087540
59
+ - !ruby/object:Gem::Dependency
60
+ name: mocha
61
+ requirement: &70333320086600 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: *70333320086600
70
+ - !ruby/object:Gem::Dependency
71
+ name: bundler
72
+ requirement: &70333320085440 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 1.0.0
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: *70333320085440
81
+ - !ruby/object:Gem::Dependency
82
+ name: jeweler
83
+ requirement: &70333320084320 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ~>
87
+ - !ruby/object:Gem::Version
88
+ version: 1.6.4
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: *70333320084320
92
+ - !ruby/object:Gem::Dependency
93
+ name: rcov
94
+ requirement: &70333320098940 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ type: :development
101
+ prerelease: false
102
+ version_requirements: *70333320098940
103
+ description: run commands over ssh in a way that makes sense for deploying artifacts
104
+ email:
105
+ - mknopp@yammer-inc.com, cgray@yammer-inc.com
106
+ executables: []
107
+ extensions: []
108
+ extra_rdoc_files:
109
+ - LICENSE.txt
110
+ - README.md
111
+ files:
112
+ - .document
113
+ - Gemfile
114
+ - Gemfile.lock
115
+ - LICENSE.txt
116
+ - README.md
117
+ - Rakefile
118
+ - VERSION
119
+ - hadouken.gemspec
120
+ - lib/hadouken.rb
121
+ - lib/hadouken/executor.rb
122
+ - lib/hadouken/ext/net_ssh_multi_session_actions.rb
123
+ - lib/hadouken/group.rb
124
+ - lib/hadouken/groups.rb
125
+ - lib/hadouken/host.rb
126
+ - lib/hadouken/plan.rb
127
+ - lib/hadouken/runner.rb
128
+ - lib/hadouken/strategy/base.rb
129
+ - lib/hadouken/strategy/by_group.rb
130
+ - lib/hadouken/strategy/by_group_parallel.rb
131
+ - lib/hadouken/strategy/by_host.rb
132
+ - lib/hadouken/task.rb
133
+ - lib/hadouken/tasks.rb
134
+ - test/helper.rb
135
+ - test/test_hadouken.rb
136
+ homepage: http://github.com/mhat/hadouken
137
+ licenses:
138
+ - MIT
139
+ post_install_message:
140
+ rdoc_options: []
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ none: false
145
+ requirements:
146
+ - - ! '>='
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ segments:
150
+ - 0
151
+ hash: -2045406218975922941
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>'
156
+ - !ruby/object:Gem::Version
157
+ version: 1.3.1
158
+ requirements: []
159
+ rubyforge_project:
160
+ rubygems_version: 1.8.11
161
+ signing_key:
162
+ specification_version: 3
163
+ summary: run commands over ssh in a way that makes sense for deploying artifacts
164
+ test_files: []