auser-poolparty 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +12 -0
- data/Manifest +115 -0
- data/README.txt +140 -0
- data/Rakefile +27 -0
- data/bin/instance +61 -0
- data/bin/pool +62 -0
- data/config/cloud_master_takeover +17 -0
- data/config/create_proxy_ami.sh +582 -0
- data/config/haproxy.conf +29 -0
- data/config/heartbeat.conf +8 -0
- data/config/heartbeat_authkeys.conf +2 -0
- data/config/installers/ubuntu_install.sh +77 -0
- data/config/monit/haproxy.monit.conf +7 -0
- data/config/monit/nginx.monit.conf +0 -0
- data/config/monit.conf +9 -0
- data/config/nginx.conf +24 -0
- data/config/reconfigure_instances_script.sh +18 -0
- data/config/sample-config.yml +23 -0
- data/config/scp_instances_script.sh +12 -0
- data/lib/core/array.rb +13 -0
- data/lib/core/exception.rb +9 -0
- data/lib/core/float.rb +13 -0
- data/lib/core/hash.rb +11 -0
- data/lib/core/kernel.rb +12 -0
- data/lib/core/module.rb +22 -0
- data/lib/core/object.rb +18 -0
- data/lib/core/proc.rb +15 -0
- data/lib/core/string.rb +49 -0
- data/lib/core/time.rb +41 -0
- data/lib/modules/callback.rb +133 -0
- data/lib/modules/ec2_wrapper.rb +82 -0
- data/lib/modules/safe_instance.rb +31 -0
- data/lib/modules/vlad_override.rb +82 -0
- data/lib/poolparty/application.rb +170 -0
- data/lib/poolparty/init.rb +6 -0
- data/lib/poolparty/master.rb +329 -0
- data/lib/poolparty/monitors/cpu.rb +19 -0
- data/lib/poolparty/monitors/memory.rb +26 -0
- data/lib/poolparty/monitors/web.rb +23 -0
- data/lib/poolparty/monitors.rb +13 -0
- data/lib/poolparty/optioner.rb +16 -0
- data/lib/poolparty/plugin.rb +43 -0
- data/lib/poolparty/plugin_manager.rb +67 -0
- data/lib/poolparty/provider/packages/essential.rb +6 -0
- data/lib/poolparty/provider/packages/git.rb +4 -0
- data/lib/poolparty/provider/packages/haproxy.rb +20 -0
- data/lib/poolparty/provider/packages/heartbeat.rb +4 -0
- data/lib/poolparty/provider/packages/monit.rb +6 -0
- data/lib/poolparty/provider/packages/rsync.rb +4 -0
- data/lib/poolparty/provider/packages/ruby.rb +37 -0
- data/lib/poolparty/provider/packages/s3fuse.rb +11 -0
- data/lib/poolparty/provider/provider.rb +60 -0
- data/lib/poolparty/provider.rb +2 -0
- data/lib/poolparty/remote_instance.rb +216 -0
- data/lib/poolparty/remoter.rb +106 -0
- data/lib/poolparty/remoting.rb +112 -0
- data/lib/poolparty/scheduler.rb +103 -0
- data/lib/poolparty/tasks/cloud.rake +57 -0
- data/lib/poolparty/tasks/development.rake +38 -0
- data/lib/poolparty/tasks/ec2.rake +20 -0
- data/lib/poolparty/tasks/instance.rake +63 -0
- data/lib/poolparty/tasks/plugins.rake +30 -0
- data/lib/poolparty/tasks/server.rake +42 -0
- data/lib/poolparty/tasks.rb +29 -0
- data/lib/poolparty/tmp.rb +46 -0
- data/lib/poolparty.rb +105 -0
- data/lib/s3/s3_object_store_folders.rb +44 -0
- data/misc/basics_tutorial.txt +142 -0
- data/poolparty.gemspec +72 -0
- data/spec/application_spec.rb +39 -0
- data/spec/callback_spec.rb +194 -0
- data/spec/core_spec.rb +15 -0
- data/spec/helpers/ec2_mock.rb +44 -0
- data/spec/kernel_spec.rb +11 -0
- data/spec/master_spec.rb +203 -0
- data/spec/monitors/cpu_monitor_spec.rb +38 -0
- data/spec/monitors/memory_spec.rb +50 -0
- data/spec/monitors/misc_monitor_spec.rb +50 -0
- data/spec/monitors/web_spec.rb +39 -0
- data/spec/optioner_spec.rb +22 -0
- data/spec/plugin_manager_spec.rb +31 -0
- data/spec/plugin_spec.rb +101 -0
- data/spec/pool_binary_spec.rb +10 -0
- data/spec/poolparty_spec.rb +15 -0
- data/spec/provider_spec.rb +17 -0
- data/spec/remote_instance_spec.rb +149 -0
- data/spec/remoter_spec.rb +65 -0
- data/spec/remoting_spec.rb +84 -0
- data/spec/scheduler_spec.rb +75 -0
- data/spec/spec_helper.rb +39 -0
- data/spec/string_spec.rb +28 -0
- data/web/static/conf/nginx.conf +22 -0
- data/web/static/site/images/balloon.png +0 -0
- data/web/static/site/images/cb.png +0 -0
- data/web/static/site/images/clouds.png +0 -0
- data/web/static/site/images/railsconf_preso_img.png +0 -0
- data/web/static/site/index.html +71 -0
- data/web/static/site/javascripts/application.js +3 -0
- data/web/static/site/javascripts/corner.js +178 -0
- data/web/static/site/javascripts/jquery-1.2.6.pack.js +11 -0
- data/web/static/site/misc.html +42 -0
- data/web/static/site/storage/pool_party_presentation.pdf +0 -0
- data/web/static/site/stylesheets/application.css +100 -0
- data/web/static/site/stylesheets/reset.css +17 -0
- data/web/static/src/layouts/application.haml +25 -0
- data/web/static/src/pages/index.haml +25 -0
- data/web/static/src/pages/misc.haml +5 -0
- data/web/static/src/stylesheets/application.sass +100 -0
- metadata +260 -0
@@ -0,0 +1,77 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
apt-get clean && apt-get update
|
4
|
+
|
5
|
+
echo 'increasing the memory for apt'
|
6
|
+
echo 'APT::Cache-Limit "516777216";' >> /etc/apt/apt.conf.d/70debconf
|
7
|
+
|
8
|
+
echo 'running ubuntu_install.sh'
|
9
|
+
rm -rf /usr/local/src/*
|
10
|
+
|
11
|
+
echo 'updating apt'
|
12
|
+
apt-get update
|
13
|
+
# Get the essentials
|
14
|
+
echo 'building essentials'
|
15
|
+
apt-get -y install build-essential
|
16
|
+
|
17
|
+
echo 'Installing git'
|
18
|
+
apt-get -y install git-core rsync
|
19
|
+
|
20
|
+
# Install ruby
|
21
|
+
echo 'Installing ruby...'
|
22
|
+
apt-get -y install ruby1.8-dev ruby1.8 ri1.8 rdoc1.8 irb1.8 libreadline-ruby1.8 libruby1.8
|
23
|
+
ln -sf /usr/bin/ruby1.8 /usr/local/bin/ruby
|
24
|
+
ln -sf /usr/bin/ri1.8 /usr/local/bin/ri
|
25
|
+
ln -sf /usr/bin/rdoc1.8 /usr/local/bin/rdoc
|
26
|
+
ln -sf /usr/bin/irb1.8 /usr/local/bin/irb
|
27
|
+
|
28
|
+
# Install rubygems
|
29
|
+
echo '-- Installing Rubygems'
|
30
|
+
# if [[ ! -f /usr/local/src/rubygems-1.1.1 ]]; then
|
31
|
+
cd /usr/local/src
|
32
|
+
wget http://rubyforge.org/frs/download.php/35283/rubygems-1.1.1.tgz
|
33
|
+
tar -xzf rubygems-1.1.1.tgz
|
34
|
+
rm rubygems-1.1.1.tgz
|
35
|
+
cd rubygems-1.1.1
|
36
|
+
ruby setup.rb --no-rdoc --no-ri
|
37
|
+
ln -sf /usr/bin/gem1.8 /usr/bin/gem
|
38
|
+
# fi
|
39
|
+
|
40
|
+
# Install gems
|
41
|
+
# if [[ which pool | grep -v "bin" ]]; then
|
42
|
+
gem update --system
|
43
|
+
gem install SQS aws-s3 amazon-ec2 aska rake poolparty --no-rdoc --no-ri --no-test
|
44
|
+
# fi
|
45
|
+
|
46
|
+
# Install haproxy
|
47
|
+
# if [[ which haproxy | grep -v "bin" ]]; then
|
48
|
+
apt-get -y install haproxy
|
49
|
+
echo 'Configuring haproxy logging'
|
50
|
+
sed -i 's/ENABLED=0/ENABLED=1/g' /etc/default/haproxy
|
51
|
+
sed -i 's/SYSLOGD=\"\"/SYSLOGD=\"-r\"/g' /etc/default/syslogd
|
52
|
+
echo 'local0.* /var/log/haproxy.log' >> /etc/syslog.conf && /etc/init.d/sysklogd restart
|
53
|
+
/etc/init.d/haproxy restart
|
54
|
+
# fi
|
55
|
+
# Install heartbeat
|
56
|
+
# if [[ which heartbeat | grep -v "bin" ]]; then
|
57
|
+
apt-get -y install heartbeat-2
|
58
|
+
# fi
|
59
|
+
|
60
|
+
# Install monit
|
61
|
+
# if [[ which monit | grep -v "bin" ]]; then
|
62
|
+
apt-get -y install monit
|
63
|
+
sudo mkdir /etc/monit
|
64
|
+
sed -i 's/startup=0/startup=1/g' /etc/default/monit
|
65
|
+
/etc/init.d/monit start
|
66
|
+
# fi
|
67
|
+
|
68
|
+
# Install s3fuse
|
69
|
+
# if [[ which s3fs | grep -v "bin" ]]; then
|
70
|
+
apt-get install -y libcurl4-openssl-dev libxml2-dev libfuse-dev
|
71
|
+
cd /usr/local/src && wget http://s3fs.googlecode.com/files/s3fs-r166-source.tar.gz
|
72
|
+
tar -zxf s3fs-r166-source.tar.gz
|
73
|
+
cd s3fs/ && make
|
74
|
+
mv s3fs /usr/bin
|
75
|
+
# fi
|
76
|
+
|
77
|
+
echo ' - installed from script!'
|
@@ -0,0 +1,7 @@
|
|
1
|
+
check process haproxy with pidfile /var/run/haproxy.pid
|
2
|
+
start program = "/usr/sbin/haproxy -f /etc/haproxy.cfg -p /var/run/haproxy.pid"
|
3
|
+
stop program = "/usr/bin/killall -9 haproxy"
|
4
|
+
if totalmem is greater than 100.0 MB for 4 cycles then restart
|
5
|
+
if cpu is greater than 50% for 2 cycles then alert
|
6
|
+
if cpu is greater than 80% for 3 cycles then restart
|
7
|
+
if loadavg(5min) greater than 10 for 8 cycles then restart
|
File without changes
|
data/config/monit.conf
ADDED
data/config/nginx.conf
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
user usr usr;
|
2
|
+
worker_processes 2;
|
3
|
+
|
4
|
+
http {
|
5
|
+
sendfile on;
|
6
|
+
tcp_nopush on;
|
7
|
+
|
8
|
+
keepalive_timeout 65;
|
9
|
+
tcp_nodelay on;
|
10
|
+
|
11
|
+
upstream fast_mongrels { server 127.0.0.1:4567; }
|
12
|
+
|
13
|
+
server {
|
14
|
+
listen 80;
|
15
|
+
server_name srv;
|
16
|
+
root /apps/pool-party;
|
17
|
+
|
18
|
+
location / {
|
19
|
+
proxy_pass http://fast_mongrels;
|
20
|
+
break;
|
21
|
+
}
|
22
|
+
|
23
|
+
}
|
24
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
# Reconfigure master
|
4
|
+
:config_master
|
5
|
+
# Start this instance's master maintain script
|
6
|
+
:start_pool_maintain
|
7
|
+
# Make the ha.d/resource.d
|
8
|
+
sudo mkdir /etc/ha.d/resource.d/
|
9
|
+
# Set this hostname as appropriate in the cloud
|
10
|
+
:set_hostname
|
11
|
+
# Configure heartbeat
|
12
|
+
sudo mkdir /etc/ha.d/resource.d/
|
13
|
+
# Start heartbeat
|
14
|
+
/etc/init.d/heartbeat start
|
15
|
+
# Start s3fs
|
16
|
+
:start_s3fs
|
17
|
+
# Configure monit
|
18
|
+
mkdir /etc/monit.d
|
@@ -0,0 +1,23 @@
|
|
1
|
+
:app_name: "test_app"
|
2
|
+
:user_id: "1619-6456-1164"
|
3
|
+
:access_key: ""
|
4
|
+
:secret_access_key: ""
|
5
|
+
:ami: "ami-4f7a9f26"
|
6
|
+
:size: small
|
7
|
+
:polling_time: "30.seconds"
|
8
|
+
:minimum_instances: 2
|
9
|
+
:maximum_instances: 3
|
10
|
+
:ec2_dir: "/Users/auser/.ec2"
|
11
|
+
:keypair: auser
|
12
|
+
:os: ubuntu
|
13
|
+
:host_port: 80
|
14
|
+
:client_port: 8001
|
15
|
+
:shared_bucket: "pool-party-app-data"
|
16
|
+
:services: nginx
|
17
|
+
:environment: production
|
18
|
+
:contract_when:
|
19
|
+
web > 10
|
20
|
+
cpu < 0.2
|
21
|
+
:expand_when:
|
22
|
+
cpu > 0.45
|
23
|
+
web < 10
|
data/lib/core/array.rb
ADDED
data/lib/core/float.rb
ADDED
data/lib/core/hash.rb
ADDED
data/lib/core/kernel.rb
ADDED
data/lib/core/module.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# Module overloads
|
2
|
+
class Module
|
3
|
+
# Gives us alias_method_chain from rails
|
4
|
+
def alias_method_chain(target, feature)
|
5
|
+
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
|
6
|
+
yield(aliased_target, punctuation) if block_given?
|
7
|
+
|
8
|
+
with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation}", "#{aliased_target}_without_#{feature}#{punctuation}"
|
9
|
+
|
10
|
+
alias_method without_method, target
|
11
|
+
alias_method target, with_method
|
12
|
+
|
13
|
+
case
|
14
|
+
when public_method_defined?(without_method)
|
15
|
+
public target
|
16
|
+
when protected_method_defined?(without_method)
|
17
|
+
protected target
|
18
|
+
when private_method_defined?(without_method)
|
19
|
+
private target
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/core/object.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
Basic, add an alias_method to the object class
|
3
|
+
Add returning to the object
|
4
|
+
=end
|
5
|
+
class Object
|
6
|
+
def alias_method(new_id, original_id)
|
7
|
+
original = self.method(original_id).to_proc
|
8
|
+
define_method(new_id){|*args| original.call(*args)}
|
9
|
+
end
|
10
|
+
def returning(receiver)
|
11
|
+
yield receiver
|
12
|
+
receiver
|
13
|
+
end
|
14
|
+
def extended(&block)
|
15
|
+
block.in_context(self).call
|
16
|
+
self
|
17
|
+
end
|
18
|
+
end
|
data/lib/core/proc.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
class Proc
|
2
|
+
def bind(object)
|
3
|
+
block, time = self, Time.now
|
4
|
+
(class << object; self; end).class_eval do
|
5
|
+
method_name = "__bind_#{time.to_i}_#{time.usec}"
|
6
|
+
define_method(method_name, &block)
|
7
|
+
method = instance_method(method_name)
|
8
|
+
remove_method(method_name)
|
9
|
+
method
|
10
|
+
end.bind(object)
|
11
|
+
end
|
12
|
+
def in_context(klass_or_obj)
|
13
|
+
klass_or_obj.send(:eval, self.to_ruby)
|
14
|
+
end
|
15
|
+
end
|
data/lib/core/string.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
class String
|
2
|
+
def hasherize(format=[])
|
3
|
+
hash = {}
|
4
|
+
i = 0
|
5
|
+
self.split(%r{[\n|\t|\s| ]+}).collect {|a| a.strip}.each do |f|
|
6
|
+
break unless format[i]
|
7
|
+
unless f == "" || f.nil?
|
8
|
+
hash[format[i]] = f
|
9
|
+
i+=1
|
10
|
+
end
|
11
|
+
end
|
12
|
+
hash
|
13
|
+
end
|
14
|
+
def ^(h={})
|
15
|
+
self.gsub(/:([\w]+)/) {h[$1.to_sym] if h.include?($1.to_sym)}
|
16
|
+
end
|
17
|
+
def runnable
|
18
|
+
self.strip.gsub(/\n/, " && ")
|
19
|
+
end
|
20
|
+
def classify
|
21
|
+
self.capitalize
|
22
|
+
end
|
23
|
+
def bucket_objects
|
24
|
+
AWS::S3::Bucket.objects(self)
|
25
|
+
end
|
26
|
+
def bucket_object(key)
|
27
|
+
AWS::S3::S3Object.value key, self if bucket_object_exists?(key)
|
28
|
+
end
|
29
|
+
def bucket_object_exists?(key)
|
30
|
+
AWS::S3::S3Object.exists? key, self
|
31
|
+
end
|
32
|
+
def store_bucket_value(key, data)
|
33
|
+
AWS::S3::S3Object.store key, data, self unless bucket_object_exists?(key)
|
34
|
+
end
|
35
|
+
def delete_bucket_value(key)
|
36
|
+
AWS::S3::S3Object.delete(key, self) if bucket_object_exists?(key)
|
37
|
+
end
|
38
|
+
def bucket_exists?
|
39
|
+
begin
|
40
|
+
AWS::S3::Bucket.find(self)
|
41
|
+
return true
|
42
|
+
rescue
|
43
|
+
return false
|
44
|
+
end
|
45
|
+
end
|
46
|
+
def delete_bucket
|
47
|
+
AWS::S3::Bucket.delete(self, :force => true) if bucket_exists?
|
48
|
+
end
|
49
|
+
end
|
data/lib/core/time.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
Based off the rails Numeric class.
|
3
|
+
Gives us the ability to use nice phrases such as
|
4
|
+
30.seconds, 5.days, etc.
|
5
|
+
=end
|
6
|
+
class Numeric
|
7
|
+
def ago(time = Time.now)
|
8
|
+
time - self
|
9
|
+
end
|
10
|
+
alias :until :ago
|
11
|
+
|
12
|
+
def since(time = Time.now)
|
13
|
+
time + self
|
14
|
+
end
|
15
|
+
alias :from_now :since
|
16
|
+
|
17
|
+
def seconds
|
18
|
+
self
|
19
|
+
end
|
20
|
+
alias :second :seconds
|
21
|
+
|
22
|
+
def minutes
|
23
|
+
self * 60
|
24
|
+
end
|
25
|
+
alias :minute :minutes
|
26
|
+
|
27
|
+
def hours
|
28
|
+
self * 60.minutes
|
29
|
+
end
|
30
|
+
alias :hour :hours
|
31
|
+
|
32
|
+
def days
|
33
|
+
self * 24.hours
|
34
|
+
end
|
35
|
+
alias :day :days
|
36
|
+
|
37
|
+
def weeks
|
38
|
+
self * 7.days
|
39
|
+
end
|
40
|
+
alias :week :weeks
|
41
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
Basic callbacks
|
3
|
+
=end
|
4
|
+
module PoolParty
|
5
|
+
module Callbacks
|
6
|
+
module ClassMethods
|
7
|
+
def define_callback_module(mod)
|
8
|
+
callbacks << mod
|
9
|
+
end
|
10
|
+
def define_callback_class(cla)
|
11
|
+
classes << cla
|
12
|
+
end
|
13
|
+
def callback(type, m, *args, &block)
|
14
|
+
arr = []
|
15
|
+
args.each do |arg|
|
16
|
+
arr << case arg.class.to_s
|
17
|
+
when "Hash"
|
18
|
+
arg.collect do |meth, klass|
|
19
|
+
case klass.class.to_s
|
20
|
+
when "String"
|
21
|
+
define_callback_class(klass)
|
22
|
+
"self.#{klass.to_s.downcase}.#{meth}(self)"
|
23
|
+
else
|
24
|
+
"#{klass}.send :#{meth}, self"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
when "Symbol"
|
28
|
+
"self.send :#{arg}, self"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
string = ""
|
33
|
+
if block_given?
|
34
|
+
num = store_proc(block.to_proc)
|
35
|
+
arr << <<-EOM
|
36
|
+
self.class.get_proc(#{num}).bind(self).call
|
37
|
+
EOM
|
38
|
+
end
|
39
|
+
|
40
|
+
string = create_eval_for_mod_with_string_and_type!(m, type) do
|
41
|
+
arr.join("\n")
|
42
|
+
end
|
43
|
+
|
44
|
+
mMode = Module.new {eval string}
|
45
|
+
|
46
|
+
define_callback_module(mMode)
|
47
|
+
end
|
48
|
+
def before(m, *args, &block)
|
49
|
+
callback(:before, m, *args, &block)
|
50
|
+
end
|
51
|
+
def after(m, *args, &block)
|
52
|
+
callback(:after, m, *args, &block)
|
53
|
+
end
|
54
|
+
|
55
|
+
def create_eval_for_mod_with_string_and_type!(meth, type=nil, &block)
|
56
|
+
str = ""
|
57
|
+
case type
|
58
|
+
when :before
|
59
|
+
str << <<-EOD
|
60
|
+
def #{meth}(*args)
|
61
|
+
#{yield}
|
62
|
+
super
|
63
|
+
end
|
64
|
+
EOD
|
65
|
+
when :after
|
66
|
+
str << <<-EOD
|
67
|
+
def #{meth}(*args)
|
68
|
+
super
|
69
|
+
#{yield}
|
70
|
+
end
|
71
|
+
EOD
|
72
|
+
else
|
73
|
+
str << <<-EOD
|
74
|
+
def #{meth}(*args)
|
75
|
+
#{yield}
|
76
|
+
end
|
77
|
+
EOD
|
78
|
+
end
|
79
|
+
str
|
80
|
+
end
|
81
|
+
|
82
|
+
def callbacks
|
83
|
+
@callbacks ||= []
|
84
|
+
end
|
85
|
+
def classes
|
86
|
+
@classes ||= []
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
module InstanceMethods
|
91
|
+
def initialize(*args)
|
92
|
+
extend_callbacks
|
93
|
+
extend_callback_methods
|
94
|
+
end
|
95
|
+
|
96
|
+
def extend_callback_methods
|
97
|
+
unless self.class.classes.empty?
|
98
|
+
self.class.classes.each do |klass|
|
99
|
+
m = %{def #{klass.to_s.downcase};@#{klass.to_s.downcase} ||= #{klass}.new;end}
|
100
|
+
self.class.class_eval m unless self.class.method_defined?(m)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def extend_callbacks
|
106
|
+
unless self.class.callbacks.empty?
|
107
|
+
self.class.callbacks.each do |mod|
|
108
|
+
self.extend(mod)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
module ProcStoreMethods
|
115
|
+
def store_proc(proc)
|
116
|
+
proc_storage << proc
|
117
|
+
proc_storage.index(proc)
|
118
|
+
end
|
119
|
+
def get_proc(num)
|
120
|
+
proc_storage[num]
|
121
|
+
end
|
122
|
+
def proc_storage
|
123
|
+
@proc_store ||= []
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def self.included(receiver)
|
128
|
+
receiver.extend ClassMethods
|
129
|
+
receiver.extend ProcStoreMethods
|
130
|
+
receiver.send :include, InstanceMethods
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module PoolParty
|
2
|
+
extend self
|
3
|
+
|
4
|
+
module Ec2Wrapper
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module InstanceMethods
|
10
|
+
# Run a new instance, with the user_data and the ami described in the config
|
11
|
+
def launch_new_instance!
|
12
|
+
instance = ec2.run_instances(
|
13
|
+
:image_id => Application.ami,
|
14
|
+
:user_data => "#{Application.launching_user_data}",
|
15
|
+
:minCount => 1,
|
16
|
+
:maxCount => 1,
|
17
|
+
:key_name => Application.keypair,
|
18
|
+
:size => "#{Application.size}")
|
19
|
+
|
20
|
+
item = instance.RunInstancesResponse.instancesSet.item
|
21
|
+
EC2ResponseObject.get_hash_from_response(item)
|
22
|
+
end
|
23
|
+
# Shutdown the instance by instance_id
|
24
|
+
def terminate_instance!(instance_id)
|
25
|
+
ec2.terminate_instances(:instance_id => instance_id)
|
26
|
+
end
|
27
|
+
def associate_address_with(ip, instance_id)
|
28
|
+
ec2.associate_address(:instance_id => instance_id, :public_ip => ip)
|
29
|
+
end
|
30
|
+
# Instance description
|
31
|
+
def describe_instance(id)
|
32
|
+
instance = ec2.describe_instances(:instance_id => id)
|
33
|
+
item = instance.DescribeInstancesResponse.reservationSet.item.instancesSet.item
|
34
|
+
EC2ResponseObject.get_hash_from_response(item)
|
35
|
+
end
|
36
|
+
# Get instance by id
|
37
|
+
def get_instance_by_id(id)
|
38
|
+
get_instances_description.select {|a| a.instance_id == id}[0] rescue nil
|
39
|
+
end
|
40
|
+
# Get the s3 description for the response in a hash format
|
41
|
+
def get_instances_description
|
42
|
+
@cached_descriptions ||= EC2ResponseObject.get_descriptions(ec2.describe_instances)
|
43
|
+
end
|
44
|
+
|
45
|
+
# EC2 connections
|
46
|
+
def ec2
|
47
|
+
@ec2 ||= EC2::Base.new(:access_key_id => Application.access_key, :secret_access_key => Application.secret_access_key)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.included(receiver)
|
52
|
+
receiver.extend ClassMethods
|
53
|
+
receiver.send :include, InstanceMethods
|
54
|
+
end
|
55
|
+
end
|
56
|
+
# Provides a simple class to wrap around the amazon responses
|
57
|
+
class EC2ResponseObject
|
58
|
+
def self.get_descriptions(resp)
|
59
|
+
rs = resp.DescribeInstancesResponse.reservationSet.item
|
60
|
+
rs = rs.respond_to?(:instancesSet) ? rs.instancesSet : rs
|
61
|
+
out = begin
|
62
|
+
rs.reject {|a| a.empty? }.collect {|r| EC2ResponseObject.get_hash_from_response(r.instancesSet.item)}.reject {|a| a.nil? }
|
63
|
+
rescue Exception => e
|
64
|
+
begin
|
65
|
+
# Really weird bug with amazon's ec2 gem
|
66
|
+
rs.reject {|a| a.empty? }.collect {|r| EC2ResponseObject.get_hash_from_response(r)}.reject {|a| a.nil? }
|
67
|
+
rescue Exception => e
|
68
|
+
[]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
out
|
72
|
+
end
|
73
|
+
def self.get_hash_from_response(resp)
|
74
|
+
{
|
75
|
+
:instance_id => resp.instanceId,
|
76
|
+
:ip => resp.dnsName,
|
77
|
+
:status => resp.instanceState.name,
|
78
|
+
:launching_time => resp.launchTime
|
79
|
+
} rescue nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
Make a command thread-safe
|
3
|
+
=end
|
4
|
+
require "monitor"
|
5
|
+
module PoolParty
|
6
|
+
extend self
|
7
|
+
|
8
|
+
module ThreadSafeInstance
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def make_safe(meth)
|
12
|
+
original_method = "_unsafe_#{meth}_"
|
13
|
+
alias_method original_method, meth
|
14
|
+
define_method(meth) {|*args| self.class.synchronize { self.send(original_method) } }
|
15
|
+
self
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module InstanceMethods
|
20
|
+
def make_safe meth
|
21
|
+
self.class.make_safe meth
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.included(receiver)
|
26
|
+
receiver.extend MonitorMixin
|
27
|
+
receiver.extend ClassMethods
|
28
|
+
receiver.send :include, InstanceMethods
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|