auser-poolparty 0.0.9 → 0.1.0
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/CHANGELOG +3 -2
- data/Rakefile +61 -4
- data/bin/instance +3 -1
- data/bin/pool +6 -2
- data/config/sample-config.yml +4 -4
- data/lib/core/object.rb +3 -0
- data/lib/helpers/plugin_spec_helper.rb +59 -0
- data/lib/modules/ec2_wrapper.rb +3 -1
- data/lib/modules/file_writer.rb +1 -1
- data/lib/modules/vlad_override.rb +83 -83
- data/lib/poolparty.rb +31 -13
- data/lib/poolparty/application.rb +22 -15
- data/lib/poolparty/init.rb +1 -1
- data/lib/poolparty/master.rb +41 -28
- data/lib/poolparty/monitors.rb +1 -3
- data/lib/poolparty/monitors/cpu.rb +7 -3
- data/lib/poolparty/monitors/memory.rb +14 -7
- data/lib/poolparty/monitors/web.rb +11 -5
- data/lib/poolparty/provider/packages/essential.rb +1 -1
- data/lib/poolparty/provider/packages/heartbeat.rb +1 -1
- data/lib/poolparty/provider/packages/ruby.rb +1 -10
- data/lib/poolparty/remote_instance.rb +5 -18
- data/lib/poolparty/remoter.rb +55 -4
- data/lib/poolparty/scheduler.rb +15 -25
- data/lib/poolparty/thread_pool.rb +94 -0
- data/poolparty.gemspec +9 -6
- data/spec/application_spec.rb +32 -13
- data/spec/callback_spec.rb +20 -1
- data/spec/file_writer_spec.rb +1 -0
- data/spec/kernel_spec.rb +13 -0
- data/spec/master_spec.rb +50 -20
- data/spec/monitors/cpu_monitor_spec.rb +1 -1
- data/spec/plugin_manager_spec.rb +9 -17
- data/spec/plugin_spec.rb +34 -34
- data/spec/poolparty_spec.rb +41 -1
- data/spec/remote_instance_spec.rb +5 -18
- data/spec/scheduler_spec.rb +7 -6
- data/spec/spec_helper.rb +8 -18
- metadata +19 -6
- data/lib/poolparty/tasks/package.rake +0 -53
data/lib/poolparty/remoter.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
=begin rdoc
|
2
2
|
Handle the remoting aspects of the remote_instances
|
3
3
|
=end
|
4
|
+
require 'open4'
|
4
5
|
module PoolParty
|
5
6
|
module Remoter
|
6
7
|
module ClassMethods
|
@@ -66,10 +67,8 @@ module PoolParty
|
|
66
67
|
run_array_of_tasks arr
|
67
68
|
end
|
68
69
|
|
69
|
-
def run_now command
|
70
|
-
unless command.empty?
|
71
|
-
Kernel.system "#{self.class.ssh_string} #{self.ip} #{command.runnable}"
|
72
|
-
end
|
70
|
+
def run_now command
|
71
|
+
run command unless command.empty?
|
73
72
|
end
|
74
73
|
|
75
74
|
def ssh_tasks;@ssh_tasks ||= [];end
|
@@ -107,6 +106,58 @@ module PoolParty
|
|
107
106
|
def set_hosts(c=nil)
|
108
107
|
end
|
109
108
|
|
109
|
+
# Nearly Directly from vlad
|
110
|
+
def run command, on=self
|
111
|
+
cmd = [self.class.ssh_string, on.ip].compact
|
112
|
+
result = []
|
113
|
+
|
114
|
+
commander = cmd.join(" ") << " \"#{command.runnable}\""
|
115
|
+
|
116
|
+
pid, inn, out, err = Open4::popen4(commander)
|
117
|
+
|
118
|
+
inn.sync = true
|
119
|
+
streams = [out, err]
|
120
|
+
out_stream = {
|
121
|
+
out => $stdout,
|
122
|
+
err => $stderr,
|
123
|
+
}
|
124
|
+
|
125
|
+
# Handle process termination ourselves
|
126
|
+
status = nil
|
127
|
+
Thread.start do
|
128
|
+
status = Process.waitpid2(pid).last
|
129
|
+
end
|
130
|
+
|
131
|
+
until streams.empty? do
|
132
|
+
# don't busy loop
|
133
|
+
selected, = select streams, nil, nil, 0.1
|
134
|
+
|
135
|
+
next if selected.nil? or selected.empty?
|
136
|
+
|
137
|
+
selected.each do |stream|
|
138
|
+
if stream.eof? then
|
139
|
+
streams.delete stream if status # we've quit, so no more writing
|
140
|
+
next
|
141
|
+
end
|
142
|
+
|
143
|
+
data = stream.readpartial(1024)
|
144
|
+
out_stream[stream].write data
|
145
|
+
|
146
|
+
if stream == err and data =~ /^Password:/ then
|
147
|
+
inn.puts sudo_password
|
148
|
+
data << "\n"
|
149
|
+
$stderr.write "\n"
|
150
|
+
end
|
151
|
+
|
152
|
+
result << data
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
PoolParty.message "execution failed with status #{status.exitstatus}: #{cmd.join ' '}" unless status.success?
|
157
|
+
|
158
|
+
result.join
|
159
|
+
end
|
160
|
+
|
110
161
|
end
|
111
162
|
|
112
163
|
def self.included(receiver)
|
data/lib/poolparty/scheduler.rb
CHANGED
@@ -9,28 +9,21 @@ module PoolParty
|
|
9
9
|
end
|
10
10
|
# Synchronize the running threaded tasks
|
11
11
|
def run
|
12
|
-
unless tasks.empty?
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
a.join
|
18
|
-
rescue Exception => e
|
19
|
-
puts "There was an error in the task: #{e} #{e.backtrace.join("\n")}"
|
20
|
-
end
|
21
|
-
true
|
22
|
-
}
|
12
|
+
unless tasks.empty? && !running?
|
13
|
+
running = true
|
14
|
+
pool = ThreadPool.new(10)
|
15
|
+
tasks.reject! do |task|
|
16
|
+
pool.process {task.call}
|
23
17
|
end
|
18
|
+
pool.join() # When all the tasks are done
|
19
|
+
running = false
|
24
20
|
end
|
25
21
|
end
|
22
|
+
def running?;@running == true;end
|
23
|
+
def running;@running ||= false;end
|
26
24
|
# Add a task in a new thread
|
27
25
|
def <<(a, *args)
|
28
|
-
|
29
|
-
Thread.stop rescue ""
|
30
|
-
Thread.current[:callee] = task
|
31
|
-
a.call args
|
32
|
-
end
|
33
|
-
tasks << thread
|
26
|
+
tasks << a
|
34
27
|
end
|
35
28
|
alias_method :push, :<<
|
36
29
|
# In the ThreadSafeInstance
|
@@ -45,7 +38,7 @@ module PoolParty
|
|
45
38
|
end
|
46
39
|
# Add a task to the new threaded block
|
47
40
|
def add_task(&blk)
|
48
|
-
_tasker.push
|
41
|
+
_tasker.push blk
|
49
42
|
end
|
50
43
|
# Grab the polling_time
|
51
44
|
def interval
|
@@ -74,16 +67,17 @@ module PoolParty
|
|
74
67
|
end
|
75
68
|
# Run the loop and wait the amount of time between running the tasks
|
76
69
|
# You can send it daemonize => true and it will daemonize
|
77
|
-
def run_thread_loop(opts={}, &
|
70
|
+
def run_thread_loop(opts={}, &blk)
|
78
71
|
block = lambda {
|
79
72
|
loop do
|
80
73
|
begin
|
81
74
|
yield if block_given?
|
75
|
+
add_task { Signal.trap("INT") { exit } }
|
82
76
|
run_thread_list
|
77
|
+
PoolParty.message "Waiting: #{interval}"
|
83
78
|
wait interval
|
84
|
-
reset!
|
85
79
|
rescue Exception => e
|
86
|
-
|
80
|
+
Process.kill("INT", Process.pid)
|
87
81
|
end
|
88
82
|
end
|
89
83
|
}
|
@@ -94,10 +88,6 @@ module PoolParty
|
|
94
88
|
def run_thread_list
|
95
89
|
run_threads
|
96
90
|
end
|
97
|
-
# Reset
|
98
|
-
def reset!
|
99
|
-
cached_variables.each {|cached| cached = nil }
|
100
|
-
end
|
101
91
|
|
102
92
|
end
|
103
93
|
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module PoolParty
|
2
|
+
class ThreadPool
|
3
|
+
class Worker
|
4
|
+
def initialize
|
5
|
+
@mutex = Mutex.new
|
6
|
+
@thread = Thread.new do
|
7
|
+
while true
|
8
|
+
sleep 0.001
|
9
|
+
block = get_block
|
10
|
+
if block
|
11
|
+
block.call
|
12
|
+
reset_block
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_block
|
19
|
+
@mutex.synchronize {@block}
|
20
|
+
end
|
21
|
+
|
22
|
+
def set_block(block)
|
23
|
+
@mutex.synchronize do
|
24
|
+
raise RuntimeError, "Thread already busy." if @block
|
25
|
+
@block = block
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def reset_block
|
30
|
+
@mutex.synchronize {@block = nil}
|
31
|
+
end
|
32
|
+
|
33
|
+
def busy?
|
34
|
+
@mutex.synchronize {!@block.nil?}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
attr_accessor :max_size
|
39
|
+
attr_reader :workers
|
40
|
+
|
41
|
+
def initialize(max_size = 10)
|
42
|
+
@max_size = max_size
|
43
|
+
@workers = []
|
44
|
+
@mutex = Mutex.new
|
45
|
+
end
|
46
|
+
|
47
|
+
def size
|
48
|
+
@mutex.synchronize {@workers.size}
|
49
|
+
end
|
50
|
+
|
51
|
+
def busy?
|
52
|
+
@mutex.synchronize {@workers.any? {|w| w.busy?}}
|
53
|
+
end
|
54
|
+
|
55
|
+
def join
|
56
|
+
sleep 0.01 while busy?
|
57
|
+
end
|
58
|
+
|
59
|
+
def process(&block)
|
60
|
+
while true
|
61
|
+
@mutex.synchronize do
|
62
|
+
worker = find_available_worker
|
63
|
+
if worker
|
64
|
+
return worker.set_block(block)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
sleep 0.01
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def find_available_worker
|
72
|
+
free_worker || create_worker
|
73
|
+
end
|
74
|
+
|
75
|
+
def wait_for_worker
|
76
|
+
while true
|
77
|
+
worker = find_available_worker
|
78
|
+
return worker if worker
|
79
|
+
sleep 0.01
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def free_worker
|
84
|
+
@workers.each {|w| return w unless w.busy?}; nil
|
85
|
+
end
|
86
|
+
|
87
|
+
def create_worker
|
88
|
+
return nil if @workers.size >= @max_size
|
89
|
+
worker = Worker.new
|
90
|
+
@workers << worker
|
91
|
+
worker
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/poolparty.gemspec
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = %q{poolparty}
|
3
|
-
s.version = "0.0
|
3
|
+
s.version = "0.1.0"
|
4
4
|
|
5
5
|
s.required_rubygems_version = Gem::Requirement.new("= 1.2") if s.respond_to? :required_rubygems_version=
|
6
6
|
s.authors = ["Ari Lerner"]
|
7
7
|
s.cert_chain = nil
|
8
|
-
s.date = %q{2008-
|
8
|
+
s.date = %q{2008-07-02}
|
9
9
|
s.description = %q{Run your entire application off EC2, managed and auto-scaling}
|
10
10
|
s.email = %q{ari.lerner@citrusbyte.com}
|
11
11
|
s.executables = ["instance", "pool", "poolnotify"]
|
12
|
-
s.extra_rdoc_files = ["CHANGELOG", "README.txt", "bin", "bin/instance", "bin/pool", "bin/poolnotify", "lib", "lib/core", "lib/core/array.rb", "lib/core/exception.rb", "lib/core/float.rb", "lib/core/hash.rb", "lib/core/kernel.rb", "lib/core/module.rb", "lib/core/object.rb", "lib/core/proc.rb", "lib/core/string.rb", "lib/core/time.rb", "lib/modules", "lib/modules/callback.rb", "lib/modules/ec2_wrapper.rb", "lib/modules/file_writer.rb", "lib/modules/safe_instance.rb", "lib/modules/sprinkle_overrides.rb", "lib/modules/vlad_override.rb", "lib/poolparty", "lib/poolparty.rb", "lib/poolparty/application.rb", "lib/poolparty/init.rb", "lib/poolparty/master.rb", "lib/poolparty/monitors", "lib/poolparty/monitors.rb", "lib/poolparty/monitors/cpu.rb", "lib/poolparty/monitors/memory.rb", "lib/poolparty/monitors/web.rb", "lib/poolparty/optioner.rb", "lib/poolparty/plugin.rb", "lib/poolparty/plugin_manager.rb", "lib/poolparty/provider", "lib/poolparty/provider.rb", "lib/poolparty/provider/packages", "lib/poolparty/provider/packages/essential.rb", "lib/poolparty/provider/packages/git.rb", "lib/poolparty/provider/packages/haproxy.rb", "lib/poolparty/provider/packages/heartbeat.rb", "lib/poolparty/provider/packages/monit.rb", "lib/poolparty/provider/packages/rsync.rb", "lib/poolparty/provider/packages/ruby.rb", "lib/poolparty/provider/packages/s3fuse.rb", "lib/poolparty/provider/provider.rb", "lib/poolparty/remote_instance.rb", "lib/poolparty/remoter.rb", "lib/poolparty/remoting.rb", "lib/poolparty/scheduler.rb", "lib/poolparty/tasks", "lib/poolparty/tasks.rb", "lib/poolparty/tasks/cloud.rake", "lib/poolparty/tasks/development.rake", "lib/poolparty/tasks/ec2.rake", "lib/poolparty/tasks/instance.rake", "lib/poolparty/tasks/
|
13
|
-
s.files = ["CHANGELOG", "README.txt", "Rakefile", "assets", "assets/clouds.png", "bin", "bin/instance", "bin/pool", "bin/poolnotify", "config", "config/cloud_master_takeover", "config/create_proxy_ami.sh", "config/haproxy.conf", "config/heartbeat.conf", "config/heartbeat_authkeys.conf", "config/installers", "config/installers/ubuntu_install.sh", "config/monit", "config/monit.conf", "config/monit/haproxy.monit.conf", "config/monit/nginx.monit.conf", "config/nginx.conf", "config/reconfigure_instances_script.sh", "config/sample-config.yml", "config/scp_instances_script.sh", "lib", "lib/core", "lib/core/array.rb", "lib/core/exception.rb", "lib/core/float.rb", "lib/core/hash.rb", "lib/core/kernel.rb", "lib/core/module.rb", "lib/core/object.rb", "lib/core/proc.rb", "lib/core/string.rb", "lib/core/time.rb", "lib/modules", "lib/modules/callback.rb", "lib/modules/ec2_wrapper.rb", "lib/modules/file_writer.rb", "lib/modules/safe_instance.rb", "lib/modules/sprinkle_overrides.rb", "lib/modules/vlad_override.rb", "lib/poolparty", "lib/poolparty.rb", "lib/poolparty/application.rb", "lib/poolparty/init.rb", "lib/poolparty/master.rb", "lib/poolparty/monitors", "lib/poolparty/monitors.rb", "lib/poolparty/monitors/cpu.rb", "lib/poolparty/monitors/memory.rb", "lib/poolparty/monitors/web.rb", "lib/poolparty/optioner.rb", "lib/poolparty/plugin.rb", "lib/poolparty/plugin_manager.rb", "lib/poolparty/provider", "lib/poolparty/provider.rb", "lib/poolparty/provider/packages", "lib/poolparty/provider/packages/essential.rb", "lib/poolparty/provider/packages/git.rb", "lib/poolparty/provider/packages/haproxy.rb", "lib/poolparty/provider/packages/heartbeat.rb", "lib/poolparty/provider/packages/monit.rb", "lib/poolparty/provider/packages/rsync.rb", "lib/poolparty/provider/packages/ruby.rb", "lib/poolparty/provider/packages/s3fuse.rb", "lib/poolparty/provider/provider.rb", "lib/poolparty/remote_instance.rb", "lib/poolparty/remoter.rb", "lib/poolparty/remoting.rb", "lib/poolparty/scheduler.rb", "lib/poolparty/tasks", "lib/poolparty/tasks.rb", "lib/poolparty/tasks/cloud.rake", "lib/poolparty/tasks/development.rake", "lib/poolparty/tasks/ec2.rake", "lib/poolparty/tasks/instance.rake", "lib/poolparty/tasks/
|
12
|
+
s.extra_rdoc_files = ["CHANGELOG", "README.txt", "bin", "bin/instance", "bin/pool", "bin/poolnotify", "lib", "lib/core", "lib/core/array.rb", "lib/core/exception.rb", "lib/core/float.rb", "lib/core/hash.rb", "lib/core/kernel.rb", "lib/core/module.rb", "lib/core/object.rb", "lib/core/proc.rb", "lib/core/string.rb", "lib/core/time.rb", "lib/helpers", "lib/helpers/plugin_spec_helper.rb", "lib/modules", "lib/modules/callback.rb", "lib/modules/ec2_wrapper.rb", "lib/modules/file_writer.rb", "lib/modules/safe_instance.rb", "lib/modules/sprinkle_overrides.rb", "lib/modules/vlad_override.rb", "lib/poolparty", "lib/poolparty.rb", "lib/poolparty/application.rb", "lib/poolparty/init.rb", "lib/poolparty/master.rb", "lib/poolparty/monitors", "lib/poolparty/monitors.rb", "lib/poolparty/monitors/cpu.rb", "lib/poolparty/monitors/memory.rb", "lib/poolparty/monitors/web.rb", "lib/poolparty/optioner.rb", "lib/poolparty/plugin.rb", "lib/poolparty/plugin_manager.rb", "lib/poolparty/provider", "lib/poolparty/provider.rb", "lib/poolparty/provider/packages", "lib/poolparty/provider/packages/essential.rb", "lib/poolparty/provider/packages/git.rb", "lib/poolparty/provider/packages/haproxy.rb", "lib/poolparty/provider/packages/heartbeat.rb", "lib/poolparty/provider/packages/monit.rb", "lib/poolparty/provider/packages/rsync.rb", "lib/poolparty/provider/packages/ruby.rb", "lib/poolparty/provider/packages/s3fuse.rb", "lib/poolparty/provider/provider.rb", "lib/poolparty/remote_instance.rb", "lib/poolparty/remoter.rb", "lib/poolparty/remoting.rb", "lib/poolparty/scheduler.rb", "lib/poolparty/tasks", "lib/poolparty/tasks.rb", "lib/poolparty/tasks/cloud.rake", "lib/poolparty/tasks/development.rake", "lib/poolparty/tasks/ec2.rake", "lib/poolparty/tasks/instance.rake", "lib/poolparty/tasks/plugins.rake", "lib/poolparty/tasks/server.rake", "lib/poolparty/thread_pool.rb", "lib/s3", "lib/s3/s3_object_store_folders.rb"]
|
13
|
+
s.files = ["CHANGELOG", "README.txt", "Rakefile", "assets", "assets/clouds.png", "bin", "bin/instance", "bin/pool", "bin/poolnotify", "config", "config/cloud_master_takeover", "config/create_proxy_ami.sh", "config/haproxy.conf", "config/heartbeat.conf", "config/heartbeat_authkeys.conf", "config/installers", "config/installers/ubuntu_install.sh", "config/monit", "config/monit.conf", "config/monit/haproxy.monit.conf", "config/monit/nginx.monit.conf", "config/nginx.conf", "config/reconfigure_instances_script.sh", "config/sample-config.yml", "config/scp_instances_script.sh", "lib", "lib/core", "lib/core/array.rb", "lib/core/exception.rb", "lib/core/float.rb", "lib/core/hash.rb", "lib/core/kernel.rb", "lib/core/module.rb", "lib/core/object.rb", "lib/core/proc.rb", "lib/core/string.rb", "lib/core/time.rb", "lib/helpers", "lib/helpers/plugin_spec_helper.rb", "lib/modules", "lib/modules/callback.rb", "lib/modules/ec2_wrapper.rb", "lib/modules/file_writer.rb", "lib/modules/safe_instance.rb", "lib/modules/sprinkle_overrides.rb", "lib/modules/vlad_override.rb", "lib/poolparty", "lib/poolparty.rb", "lib/poolparty/application.rb", "lib/poolparty/init.rb", "lib/poolparty/master.rb", "lib/poolparty/monitors", "lib/poolparty/monitors.rb", "lib/poolparty/monitors/cpu.rb", "lib/poolparty/monitors/memory.rb", "lib/poolparty/monitors/web.rb", "lib/poolparty/optioner.rb", "lib/poolparty/plugin.rb", "lib/poolparty/plugin_manager.rb", "lib/poolparty/provider", "lib/poolparty/provider.rb", "lib/poolparty/provider/packages", "lib/poolparty/provider/packages/essential.rb", "lib/poolparty/provider/packages/git.rb", "lib/poolparty/provider/packages/haproxy.rb", "lib/poolparty/provider/packages/heartbeat.rb", "lib/poolparty/provider/packages/monit.rb", "lib/poolparty/provider/packages/rsync.rb", "lib/poolparty/provider/packages/ruby.rb", "lib/poolparty/provider/packages/s3fuse.rb", "lib/poolparty/provider/provider.rb", "lib/poolparty/remote_instance.rb", "lib/poolparty/remoter.rb", "lib/poolparty/remoting.rb", "lib/poolparty/scheduler.rb", "lib/poolparty/tasks", "lib/poolparty/tasks.rb", "lib/poolparty/tasks/cloud.rake", "lib/poolparty/tasks/development.rake", "lib/poolparty/tasks/ec2.rake", "lib/poolparty/tasks/instance.rake", "lib/poolparty/tasks/plugins.rake", "lib/poolparty/tasks/server.rake", "lib/poolparty/thread_pool.rb", "lib/s3", "lib/s3/s3_object_store_folders.rb", "spec", "spec/application_spec.rb", "spec/callback_spec.rb", "spec/core_spec.rb", "spec/ec2_wrapper_spec.rb", "spec/file_writer_spec.rb", "spec/files", "spec/files/describe_response", "spec/files/multi_describe_response", "spec/files/remote_desc_response", "spec/helpers", "spec/helpers/ec2_mock.rb", "spec/kernel_spec.rb", "spec/master_spec.rb", "spec/monitors", "spec/monitors/cpu_monitor_spec.rb", "spec/monitors/memory_spec.rb", "spec/monitors/misc_monitor_spec.rb", "spec/monitors/web_spec.rb", "spec/optioner_spec.rb", "spec/plugin_manager_spec.rb", "spec/plugin_spec.rb", "spec/pool_binary_spec.rb", "spec/poolparty_spec.rb", "spec/provider_spec.rb", "spec/remote_instance_spec.rb", "spec/remoter_spec.rb", "spec/remoting_spec.rb", "spec/scheduler_spec.rb", "spec/spec_helper.rb", "spec/string_spec.rb", "poolparty.gemspec"]
|
14
14
|
s.has_rdoc = true
|
15
|
-
s.homepage = %q{http://
|
15
|
+
s.homepage = %q{http://poolpartyrb.com}
|
16
16
|
s.post_install_message = %q{
|
17
17
|
|
18
|
-
Get ready to jump in the pool, you just installed PoolParty! (Updated at
|
18
|
+
Get ready to jump in the pool, you just installed PoolParty! (Updated at 02:12PM, 07/02/08)
|
19
19
|
|
20
20
|
Please check out the documentation for any questions or check out the google groups at
|
21
21
|
http://groups.google.com/group/poolpartyrb
|
@@ -45,6 +45,7 @@ Gem::Specification.new do |s|
|
|
45
45
|
s.add_runtime_dependency(%q<git>, [">= 0"])
|
46
46
|
s.add_runtime_dependency(%q<crafterm-sprinkle>, [">= 0"])
|
47
47
|
s.add_runtime_dependency(%q<SystemTimer>, [">= 0"])
|
48
|
+
s.add_development_dependency(%q<echoe>, [">= 0"])
|
48
49
|
else
|
49
50
|
s.add_dependency(%q<aws-s3>, [">= 0"])
|
50
51
|
s.add_dependency(%q<amazon-ec2>, [">= 0"])
|
@@ -52,6 +53,7 @@ Gem::Specification.new do |s|
|
|
52
53
|
s.add_dependency(%q<git>, [">= 0"])
|
53
54
|
s.add_dependency(%q<crafterm-sprinkle>, [">= 0"])
|
54
55
|
s.add_dependency(%q<SystemTimer>, [">= 0"])
|
56
|
+
s.add_dependency(%q<echoe>, [">= 0"])
|
55
57
|
end
|
56
58
|
else
|
57
59
|
s.add_dependency(%q<aws-s3>, [">= 0"])
|
@@ -60,5 +62,6 @@ Gem::Specification.new do |s|
|
|
60
62
|
s.add_dependency(%q<git>, [">= 0"])
|
61
63
|
s.add_dependency(%q<crafterm-sprinkle>, [">= 0"])
|
62
64
|
s.add_dependency(%q<SystemTimer>, [">= 0"])
|
65
|
+
s.add_dependency(%q<echoe>, [">= 0"])
|
63
66
|
end
|
64
67
|
end
|
data/spec/application_spec.rb
CHANGED
@@ -3,6 +3,7 @@ require File.dirname(__FILE__) + '/spec_helper'
|
|
3
3
|
describe "Application" do
|
4
4
|
before(:each) do
|
5
5
|
stub_option_load
|
6
|
+
Application.reset!
|
6
7
|
end
|
7
8
|
it "should be able to send options in the Application.options" do
|
8
9
|
options({:optparse => {:banner => "hi"}})
|
@@ -39,29 +40,47 @@ describe "Application" do
|
|
39
40
|
it "should show the version as a string" do
|
40
41
|
Application.version.class.should == String
|
41
42
|
end
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
43
|
+
describe "User data" do
|
44
|
+
before(:each) do
|
45
|
+
@str = ":access_key: 3.14159\n:secret_access_key: pi"
|
46
|
+
Application.options = nil
|
47
|
+
Application.stub!(:open).with("http://169.254.169.254/latest/user-data").and_return(@str)
|
48
|
+
@str.stub!(:read).and_return ":access_key: 3.14159\n:secret_access_key: pi"
|
49
|
+
Application.default_options.stub!(:merge!).with({})
|
50
|
+
Application.default_options.stub!(:merge!).with({:access_key => 3.14159, :secret_access_key => "pi"})
|
51
|
+
end
|
52
|
+
it "should try to load the user data into a yaml hash" do
|
53
|
+
YAML.should_receive(:load).with(":access_key: 3.14159\n:secret_access_key: pi")
|
54
|
+
Application.local_user_data
|
55
|
+
end
|
56
|
+
it "should be able to start instances with the the key access information on the user-data" do
|
57
|
+
Application.launching_user_data.should =~ /:access_key/
|
58
|
+
Application.launching_user_data.should =~ /:secret_access_key/
|
59
|
+
end
|
60
|
+
it "should be able to pull out the access_key from the user data" do
|
61
|
+
Application.local_user_data[:access_key].should == 3.14159
|
62
|
+
end
|
63
|
+
it "should be able tp pull out the secret_access_key from the user-data" do
|
64
|
+
Application.local_user_data[:secret_access_key].should == "pi"
|
65
|
+
end
|
66
|
+
it "should overwrite the default_options when passing in to the instance data" do
|
67
|
+
Application.stub!(:default_options).and_return({:access_key => 42})
|
68
|
+
Application.local_user_data
|
69
|
+
Application.options.access_key.should == 3.14159
|
70
|
+
end
|
52
71
|
end
|
53
72
|
it "should parse and use a config file if it is given for the options" do
|
54
|
-
YAML.should_receive(:load).and_return({:config_file => "config/sample-config.yml"})
|
73
|
+
YAML.should_receive(:load).at_least(1).and_return({:config_file => "config/sample-config.yml"})
|
55
74
|
Application.make_options(:config_file => "config/sample-config.yml")
|
56
75
|
end
|
57
76
|
it "should not read the config file if it is not passed and doesn't exist" do
|
58
77
|
File.stub!(:file?).and_return false
|
59
|
-
YAML.should_not_receive(:load)
|
78
|
+
YAML.should_not_receive(:load).with("config/config.yml")
|
60
79
|
Application.make_options
|
61
80
|
end
|
62
81
|
it "should not read the config file if it is passed and doesn't exist" do
|
63
82
|
File.stub!(:file?).and_return false
|
64
|
-
YAML.should_not_receive(:load)
|
83
|
+
YAML.should_not_receive(:load).with("config/config.yml")
|
65
84
|
Application.make_options(:config_file => "ted")
|
66
85
|
end
|
67
86
|
end
|
data/spec/callback_spec.rb
CHANGED
@@ -68,7 +68,7 @@ describe "Multiple callbacks" do
|
|
68
68
|
end
|
69
69
|
class OutsideClass
|
70
70
|
def self.hello(caller)
|
71
|
-
|
71
|
+
"hello"
|
72
72
|
end
|
73
73
|
end
|
74
74
|
class TestOutsideClass
|
@@ -191,4 +191,23 @@ describe "Variables on the plugin callbacker class" do
|
|
191
191
|
BindingClass.new.print
|
192
192
|
BindingClass.new.methods.include?("eviloutsideclass").should == true
|
193
193
|
end
|
194
|
+
end
|
195
|
+
class DoubleClass
|
196
|
+
include Callbacks
|
197
|
+
before :print, :hello => "OutsideBindingClass"
|
198
|
+
after :print, :hello => "OutsideBindingClass"
|
199
|
+
|
200
|
+
def print
|
201
|
+
string
|
202
|
+
end
|
203
|
+
def string
|
204
|
+
@string ||= ""
|
205
|
+
end
|
206
|
+
end
|
207
|
+
describe "Chaining" do
|
208
|
+
it "should be able to call both a before and an after spec" do
|
209
|
+
@d = DoubleClass.new
|
210
|
+
@d.print
|
211
|
+
@d.string.should == "hellohello"
|
212
|
+
end
|
194
213
|
end
|
data/spec/file_writer_spec.rb
CHANGED
data/spec/kernel_spec.rb
CHANGED
@@ -8,4 +8,17 @@ describe "Kernel extensions" do
|
|
8
8
|
@host.should_receive(:sleep).once.and_return true
|
9
9
|
@host.wait "10.seconds"
|
10
10
|
end
|
11
|
+
end
|
12
|
+
describe "Object extensions" do
|
13
|
+
before(:each) do
|
14
|
+
@klass = Object.new
|
15
|
+
@klass.instance_eval <<-EOE
|
16
|
+
def hello
|
17
|
+
puts "hello"
|
18
|
+
end
|
19
|
+
EOE
|
20
|
+
end
|
21
|
+
it "should be able to get a list of the defined methods on the object" do
|
22
|
+
@klass.my_methods.should == ["hello"]
|
23
|
+
end
|
11
24
|
end
|
data/spec/master_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/helpers/ec2_mock'
|
2
3
|
|
3
4
|
describe "Master" do
|
4
5
|
before(:each) do
|
@@ -86,22 +87,25 @@ describe "Master" do
|
|
86
87
|
it "should be able to get a specific node in the nodes from the master" do
|
87
88
|
@master.get_node(2).instance_id.should == "i-5849bc"
|
88
89
|
end
|
90
|
+
it "should be able to get the next node" do
|
91
|
+
@master.get_next_node(@instance).instance_id.should == "i-5849bb"
|
92
|
+
end
|
89
93
|
it "should be able to build a hosts file" do
|
90
94
|
open(@master.build_hosts_file_for(@instance).path).read.should == "127.0.0.1 node0\n127.0.0.1 localhost.localdomain localhost ubuntu\n127.0.0.2 node1\n127.0.0.3 node2"
|
91
95
|
end
|
92
96
|
it "should be able to build a hosts file for a specific instance" do
|
93
|
-
open(@master.build_hosts_file_for(@instance).path).read.should =~
|
97
|
+
open(@master.build_hosts_file_for(@instance).path).read.should =~ /127\.0\.0\.1 node0/
|
94
98
|
end
|
95
99
|
it "should be able to build a haproxy file" do
|
96
|
-
open(@master.build_haproxy_file.path).read.should =~
|
100
|
+
open(@master.build_haproxy_file.path).read.should =~ /server node0 127\.0\.0\.1:#{Application.client_port}/
|
97
101
|
end
|
98
102
|
it "should be able to reconfigure the instances (working on two files a piece)" do
|
99
103
|
@master.should_receive(:remote_configure_instances).and_return true
|
100
104
|
@master.stub!(:number_of_unconfigured_nodes).and_return 1
|
101
105
|
@master.reconfigure_cloud_when_necessary
|
102
106
|
end
|
103
|
-
it "should return the number of unconfigured nodes when asked" do
|
104
|
-
@master.nodes.each {|node| node.stub!(:stack_installed?).and_return(
|
107
|
+
it "should return the number of unconfigured nodes when asked" do
|
108
|
+
@master.nodes.each {|node| node.stub!(:stack_installed?).and_return(node.master? ? false : true) }
|
105
109
|
@master.number_of_unconfigured_nodes.should == 1
|
106
110
|
end
|
107
111
|
it "should be able to return the size of the cloud" do
|
@@ -118,39 +122,50 @@ describe "Master" do
|
|
118
122
|
describe "sending configuration files" do
|
119
123
|
before(:each) do
|
120
124
|
Master.stub!(:new).and_return(@master)
|
125
|
+
@master.stub!(:ssh)
|
126
|
+
@master.stub!(:scp)
|
127
|
+
@master.nodes.each do |node|
|
128
|
+
node.stub!(:ssh)
|
129
|
+
node.stub!(:scp)
|
130
|
+
node.stub!(:stack_installed?).and_return true
|
131
|
+
end
|
121
132
|
end
|
122
133
|
it "should be able to build a heartbeat resources file for the specific node" do
|
123
|
-
open(
|
134
|
+
open(@master.build_heartbeat_resources_file_for(@master.nodes.first).path).read.should == "node0 127.0.0.1\nnode1 127.0.0.2"
|
124
135
|
end
|
125
136
|
it "should be able to build a heartbeat config file" do
|
126
|
-
open(
|
137
|
+
open(@master.build_heartbeat_config_file_for(@master.nodes.first).path).read.should =~ /\nnode node0\nnode node1/
|
127
138
|
end
|
128
139
|
it "should be able to say if heartbeat is necessary with more than 1 server or not" do
|
129
140
|
Master.requires_heartbeat?.should == true
|
130
141
|
end
|
131
142
|
it "should be able to say that heartbeat is not necessary if there is 1 server" do
|
132
|
-
@master.stub!(:
|
143
|
+
@master.stub!(:nodes).and_return([
|
133
144
|
{:instance_id => "i-5849ba", :ip => "127.0.0.1", :status => "running"}
|
134
145
|
])
|
135
146
|
Master.requires_heartbeat?.should == false
|
136
147
|
end
|
137
148
|
it "should only install the stack on nodes that don't have it marked locally as installed" do
|
138
|
-
@master.nodes.each {|i| i.should_receive(:stack_installed?).and_return(true)}
|
149
|
+
@master.nodes.each {|i| i.should_receive(:stack_installed?).at_least(1).and_return(true)}
|
139
150
|
@master.should_not_receive(:reconfigure_running_instances)
|
140
151
|
@master.reconfigure_cloud_when_necessary
|
141
152
|
end
|
142
153
|
it "should install the stack on all the nodes (because it needs reconfiguring) if there is any node that needs the stack" do
|
143
|
-
@master.nodes.first.should_receive(:stack_installed?).and_return(false)
|
154
|
+
@master.nodes.first.should_receive(:stack_installed?).at_least(1).and_return(false)
|
144
155
|
@master.should_receive(:configure_cloud).once.and_return(true)
|
145
156
|
@master.reconfigure_cloud_when_necessary
|
146
157
|
end
|
147
158
|
describe "rsync'ing the files to the instances" do
|
159
|
+
it "should cleanup the tmp directory before sending configuration to the nodes" do
|
160
|
+
@master.should_receive(:cleanup_tmp_directory).once
|
161
|
+
@master.build_and_send_config_files_in_temp_directory
|
162
|
+
end
|
148
163
|
it "should receive send_config_files_to_nodes after it builds the config files in the temp directory" do
|
149
|
-
@master.should_receive(:send_config_files_to_nodes).
|
164
|
+
@master.should_receive(:send_config_files_to_nodes).at_least(1)
|
150
165
|
@master.build_and_send_config_files_in_temp_directory
|
151
166
|
end
|
152
167
|
it "should run_array_of_tasks(scp_tasks)" do
|
153
|
-
@master.should_receive(:run_array_of_tasks).and_return true
|
168
|
+
@master.should_receive(:run_array_of_tasks).at_least(1).and_return true
|
154
169
|
@master.build_and_send_config_files_in_temp_directory
|
155
170
|
end
|
156
171
|
it "should compile a list of files to rsync" do
|
@@ -184,14 +199,18 @@ describe "Master" do
|
|
184
199
|
before(:each) do
|
185
200
|
Application.stub!(:install_on_load?).and_return true
|
186
201
|
Sprinkle::Script.stub!(:sprinkle).and_return true
|
187
|
-
@master.stub!(:
|
202
|
+
@master.stub!(:ssh).and_return true
|
203
|
+
@master.nodes.each do |node|
|
204
|
+
node.stub!(:run_now).and_return true
|
205
|
+
end
|
188
206
|
end
|
189
207
|
it "should install on the instances if the application says it should" do
|
208
|
+
Provider.stub!(:install_userpackages)
|
190
209
|
Provider.should_receive(:install_poolparty)
|
191
210
|
@master.install_cloud
|
192
211
|
end
|
193
212
|
it "should execute the remote tasks on all of the instances" do
|
194
|
-
@master.should_receive(:
|
213
|
+
@master.should_receive(:ssh).and_return true
|
195
214
|
@master.install_cloud
|
196
215
|
end
|
197
216
|
describe "stubbing installation" do
|
@@ -244,30 +263,35 @@ describe "Master" do
|
|
244
263
|
@master.should_receive(:request_termination_of_instance).and_return(true)
|
245
264
|
@master.terminate_instance_if_load_is_low
|
246
265
|
end
|
266
|
+
it "should launch the minimum_instances when the minimum aren't launched"
|
267
|
+
it "should reconfigure the cloud if it's necessary to do so"
|
268
|
+
it "should try to scale the cloud when monitoring"
|
269
|
+
it "should check the stats of the cloud"
|
247
270
|
end
|
248
|
-
describe "expanding and contracting" do
|
271
|
+
describe "expanding and contracting" do
|
249
272
|
it "should be able to say that it should not contract" do
|
250
273
|
@master.stub!(:web).and_return(10.2)
|
251
274
|
@master.stub!(:cpu).and_return(0.32)
|
252
275
|
|
253
276
|
@master.contract?.should == false
|
254
277
|
end
|
255
|
-
it "should be able to say that it should contract" do
|
256
|
-
@master.
|
257
|
-
@master.
|
258
|
-
|
278
|
+
it "should be able to say that it should contract" do
|
279
|
+
@master.should_receive(:cpu).once.and_return(0.05)
|
280
|
+
@master.should_receive(:web).once.and_return(35.2)
|
281
|
+
|
259
282
|
@master.contract?.should == true
|
260
283
|
end
|
261
284
|
it "should be able to say that it should not expand if it shouldn't expand" do
|
262
285
|
@master.stub!(:web).and_return(30.2)
|
263
286
|
@master.stub!(:cpu).and_return(0.92)
|
264
|
-
|
287
|
+
|
265
288
|
@master.expand?.should == false
|
266
289
|
end
|
267
290
|
it "should be able to say that it should expand if it should expand" do
|
268
291
|
@master.stub!(:web).and_return(1.2)
|
269
292
|
@master.stub!(:cpu).and_return(0.92)
|
270
|
-
|
293
|
+
|
294
|
+
@master.should_receive(:web).once.and_return(1.2)
|
271
295
|
@master.expand?.should == true
|
272
296
|
end
|
273
297
|
describe "scaling" do
|
@@ -313,6 +337,12 @@ describe "Master" do
|
|
313
337
|
File.should_receive(:copy).exactly(3).and_return true
|
314
338
|
@master.build_and_send_config_files_in_temp_directory
|
315
339
|
end
|
340
|
+
it "should tar the plugin_dir into the tmp directory" do
|
341
|
+
FileUtils.mkdir_p Application.plugin_dir rescue ""
|
342
|
+
|
343
|
+
Kernel.should_receive(:system).with("tar -czf #{@master.base_tmp_dir}/plugins.tar.gz #{File.basename(Application.plugin_dir)}").and_return true
|
344
|
+
@master.build_and_send_config_files_in_temp_directory
|
345
|
+
end
|
316
346
|
describe "get configs" do
|
317
347
|
before(:each) do
|
318
348
|
@master.stub!(:user_dir).and_return("user")
|