auser-poolparty 0.0.8

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.
Files changed (109) hide show
  1. data/CHANGELOG +12 -0
  2. data/Manifest +115 -0
  3. data/README.txt +140 -0
  4. data/Rakefile +27 -0
  5. data/bin/instance +61 -0
  6. data/bin/pool +62 -0
  7. data/config/cloud_master_takeover +17 -0
  8. data/config/create_proxy_ami.sh +582 -0
  9. data/config/haproxy.conf +29 -0
  10. data/config/heartbeat.conf +8 -0
  11. data/config/heartbeat_authkeys.conf +2 -0
  12. data/config/installers/ubuntu_install.sh +77 -0
  13. data/config/monit/haproxy.monit.conf +7 -0
  14. data/config/monit/nginx.monit.conf +0 -0
  15. data/config/monit.conf +9 -0
  16. data/config/nginx.conf +24 -0
  17. data/config/reconfigure_instances_script.sh +18 -0
  18. data/config/sample-config.yml +23 -0
  19. data/config/scp_instances_script.sh +12 -0
  20. data/lib/core/array.rb +13 -0
  21. data/lib/core/exception.rb +9 -0
  22. data/lib/core/float.rb +13 -0
  23. data/lib/core/hash.rb +11 -0
  24. data/lib/core/kernel.rb +12 -0
  25. data/lib/core/module.rb +22 -0
  26. data/lib/core/object.rb +18 -0
  27. data/lib/core/proc.rb +15 -0
  28. data/lib/core/string.rb +49 -0
  29. data/lib/core/time.rb +41 -0
  30. data/lib/modules/callback.rb +133 -0
  31. data/lib/modules/ec2_wrapper.rb +82 -0
  32. data/lib/modules/safe_instance.rb +31 -0
  33. data/lib/modules/vlad_override.rb +82 -0
  34. data/lib/poolparty/application.rb +170 -0
  35. data/lib/poolparty/init.rb +6 -0
  36. data/lib/poolparty/master.rb +329 -0
  37. data/lib/poolparty/monitors/cpu.rb +19 -0
  38. data/lib/poolparty/monitors/memory.rb +26 -0
  39. data/lib/poolparty/monitors/web.rb +23 -0
  40. data/lib/poolparty/monitors.rb +13 -0
  41. data/lib/poolparty/optioner.rb +16 -0
  42. data/lib/poolparty/plugin.rb +43 -0
  43. data/lib/poolparty/plugin_manager.rb +67 -0
  44. data/lib/poolparty/provider/packages/essential.rb +6 -0
  45. data/lib/poolparty/provider/packages/git.rb +4 -0
  46. data/lib/poolparty/provider/packages/haproxy.rb +20 -0
  47. data/lib/poolparty/provider/packages/heartbeat.rb +4 -0
  48. data/lib/poolparty/provider/packages/monit.rb +6 -0
  49. data/lib/poolparty/provider/packages/rsync.rb +4 -0
  50. data/lib/poolparty/provider/packages/ruby.rb +37 -0
  51. data/lib/poolparty/provider/packages/s3fuse.rb +11 -0
  52. data/lib/poolparty/provider/provider.rb +60 -0
  53. data/lib/poolparty/provider.rb +2 -0
  54. data/lib/poolparty/remote_instance.rb +216 -0
  55. data/lib/poolparty/remoter.rb +106 -0
  56. data/lib/poolparty/remoting.rb +112 -0
  57. data/lib/poolparty/scheduler.rb +103 -0
  58. data/lib/poolparty/tasks/cloud.rake +57 -0
  59. data/lib/poolparty/tasks/development.rake +38 -0
  60. data/lib/poolparty/tasks/ec2.rake +20 -0
  61. data/lib/poolparty/tasks/instance.rake +63 -0
  62. data/lib/poolparty/tasks/plugins.rake +30 -0
  63. data/lib/poolparty/tasks/server.rake +42 -0
  64. data/lib/poolparty/tasks.rb +29 -0
  65. data/lib/poolparty/tmp.rb +46 -0
  66. data/lib/poolparty.rb +105 -0
  67. data/lib/s3/s3_object_store_folders.rb +44 -0
  68. data/misc/basics_tutorial.txt +142 -0
  69. data/poolparty.gemspec +72 -0
  70. data/spec/application_spec.rb +39 -0
  71. data/spec/callback_spec.rb +194 -0
  72. data/spec/core_spec.rb +15 -0
  73. data/spec/helpers/ec2_mock.rb +44 -0
  74. data/spec/kernel_spec.rb +11 -0
  75. data/spec/master_spec.rb +203 -0
  76. data/spec/monitors/cpu_monitor_spec.rb +38 -0
  77. data/spec/monitors/memory_spec.rb +50 -0
  78. data/spec/monitors/misc_monitor_spec.rb +50 -0
  79. data/spec/monitors/web_spec.rb +39 -0
  80. data/spec/optioner_spec.rb +22 -0
  81. data/spec/plugin_manager_spec.rb +31 -0
  82. data/spec/plugin_spec.rb +101 -0
  83. data/spec/pool_binary_spec.rb +10 -0
  84. data/spec/poolparty_spec.rb +15 -0
  85. data/spec/provider_spec.rb +17 -0
  86. data/spec/remote_instance_spec.rb +149 -0
  87. data/spec/remoter_spec.rb +65 -0
  88. data/spec/remoting_spec.rb +84 -0
  89. data/spec/scheduler_spec.rb +75 -0
  90. data/spec/spec_helper.rb +39 -0
  91. data/spec/string_spec.rb +28 -0
  92. data/web/static/conf/nginx.conf +22 -0
  93. data/web/static/site/images/balloon.png +0 -0
  94. data/web/static/site/images/cb.png +0 -0
  95. data/web/static/site/images/clouds.png +0 -0
  96. data/web/static/site/images/railsconf_preso_img.png +0 -0
  97. data/web/static/site/index.html +71 -0
  98. data/web/static/site/javascripts/application.js +3 -0
  99. data/web/static/site/javascripts/corner.js +178 -0
  100. data/web/static/site/javascripts/jquery-1.2.6.pack.js +11 -0
  101. data/web/static/site/misc.html +42 -0
  102. data/web/static/site/storage/pool_party_presentation.pdf +0 -0
  103. data/web/static/site/stylesheets/application.css +100 -0
  104. data/web/static/site/stylesheets/reset.css +17 -0
  105. data/web/static/src/layouts/application.haml +25 -0
  106. data/web/static/src/pages/index.haml +25 -0
  107. data/web/static/src/pages/misc.haml +5 -0
  108. data/web/static/src/stylesheets/application.sass +100 -0
  109. 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
@@ -0,0 +1,9 @@
1
+ # Configuration for Monit, a monitoring tool
2
+ set daemon 20 # Perform a check every 20 seconds
3
+ set logfile /var/log/monit.log
4
+
5
+ set httpd port 2812 and
6
+ use address 0.0.0.0
7
+ allow localhost
8
+
9
+ include /etc/monit.d/*
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
@@ -0,0 +1,12 @@
1
+ #!/bin/sh
2
+
3
+ :cloud_master_takeover
4
+ :config_file
5
+ :authkeys
6
+ :ha_d
7
+ :haresources
8
+ :resources
9
+ :monitrc
10
+ :monit_d
11
+ :haproxy
12
+ :hosts
data/lib/core/array.rb ADDED
@@ -0,0 +1,13 @@
1
+ =begin rdoc
2
+ Array extensions
3
+ =end
4
+ require "enumerator"
5
+ class Array
6
+ # Collection with the index
7
+ def collect_with_index &block
8
+ self.enum_for(:each_with_index).collect &block
9
+ end
10
+ def runnable
11
+ self.join(" \n ").runnable
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ =begin rdoc
2
+ Exception overloads
3
+ =end
4
+ class Exception
5
+ # Gives us a nice_message for exceptions
6
+ def nice_message(padding="")
7
+ "#{padding}#{message}\n#{padding}" + backtrace.join("\n#{padding}")
8
+ end
9
+ end
data/lib/core/float.rb ADDED
@@ -0,0 +1,13 @@
1
+ class Float
2
+ def round_to(x)
3
+ (self * 10**x).round.to_f / 10**x
4
+ end
5
+
6
+ def ceil_to(x)
7
+ (self * 10**x).ceil.to_f / 10**x
8
+ end
9
+
10
+ def floor_to(x)
11
+ (self * 10**x).floor.to_f / 10**x
12
+ end
13
+ end
data/lib/core/hash.rb ADDED
@@ -0,0 +1,11 @@
1
+ =begin rdoc
2
+ Hash extentions
3
+ =end
4
+ class Hash
5
+ def safe_merge(other_hash)
6
+ merge(other_hash.delete_if {|k,v| has_key?(k) })
7
+ end
8
+ def safe_merge!(other_hash)
9
+ merge!(other_hash.delete_if {|k,v| has_key?(k) })
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ =begin rdoc
2
+ Kernel overloads
3
+ =end
4
+ module Kernel
5
+ # Nice wait instead of sleep
6
+ def wait(time=10)
7
+ sleep time.is_a?(String) ? eval(time) : time
8
+ end
9
+ def as(klass_or_obj, &block)
10
+ block.in_context(klass_or_obj).call
11
+ end
12
+ end
@@ -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
@@ -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
@@ -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