poolparty 0.0.4 → 0.2.6

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 (247) hide show
  1. data/History.txt +25 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +203 -0
  4. data/PostInstall.txt +18 -0
  5. data/README.txt +21 -82
  6. data/Rakefile +25 -18
  7. data/bin/cloud +31 -0
  8. data/bin/cloud-add-keypair +23 -0
  9. data/bin/cloud-configure +31 -0
  10. data/bin/cloud-contract +27 -0
  11. data/bin/cloud-expand +27 -0
  12. data/bin/cloud-list +32 -0
  13. data/bin/cloud-maintain +36 -0
  14. data/bin/cloud-osxcopy +22 -0
  15. data/bin/cloud-provision +31 -0
  16. data/bin/cloud-refresh +26 -0
  17. data/bin/cloud-ssh +18 -0
  18. data/bin/cloud-start +32 -0
  19. data/bin/cloud-terminate +23 -0
  20. data/bin/pool +25 -27
  21. data/bin/pool-console +12 -0
  22. data/bin/pool-describe +9 -0
  23. data/bin/pool-list +28 -0
  24. data/bin/pool-provision +34 -0
  25. data/bin/pool-spec +17 -0
  26. data/bin/pool-start +32 -0
  27. data/bin/pool-start-monitor +1 -0
  28. data/config/hoe.rb +115 -0
  29. data/config/requirements.rb +15 -0
  30. data/examples/basic.rb +20 -0
  31. data/examples/plugin_without_plugin_directory.rb +13 -0
  32. data/examples/poolparty.rb +12 -0
  33. data/examples/with_apache_plugin.rb +22 -0
  34. data/generators/poolspec/USAGE +5 -0
  35. data/generators/poolspec/poolspec_generator.rb +65 -0
  36. data/generators/poolspec/templates/pool_spec_template.erb +9 -0
  37. data/lib/erlang/eb_server.erl +27 -0
  38. data/lib/poolparty.rb +56 -0
  39. data/lib/poolparty/base_packages/haproxy.rb +42 -0
  40. data/lib/poolparty/base_packages/heartbeat.rb +45 -0
  41. data/lib/poolparty/base_packages/poolparty.rb +36 -0
  42. data/lib/poolparty/base_packages/ruby.rb +43 -0
  43. data/lib/poolparty/core/array.rb +24 -0
  44. data/lib/{core → poolparty/core}/exception.rb +0 -0
  45. data/lib/poolparty/core/float.rb +13 -0
  46. data/lib/poolparty/core/hash.rb +29 -0
  47. data/lib/poolparty/core/kernel.rb +37 -0
  48. data/lib/{core → poolparty/core}/module.rb +18 -0
  49. data/lib/poolparty/core/my_open_struct.rb +18 -0
  50. data/lib/poolparty/core/object.rb +54 -0
  51. data/lib/poolparty/core/proc.rb +7 -0
  52. data/lib/poolparty/core/string.rb +72 -0
  53. data/lib/poolparty/core/symbol.rb +8 -0
  54. data/lib/{core → poolparty/core}/time.rb +15 -0
  55. data/lib/poolparty/exceptions/RemoteException.rb +12 -0
  56. data/lib/poolparty/exceptions/ResourceException.rb +7 -0
  57. data/lib/poolparty/exceptions/RuntimeException.rb +7 -0
  58. data/lib/poolparty/exceptions/SpecException.rb +7 -0
  59. data/lib/poolparty/exceptions/TemplateNotFound.rb +7 -0
  60. data/lib/poolparty/helpers/binary.rb +31 -0
  61. data/lib/poolparty/helpers/console.rb +30 -0
  62. data/lib/poolparty/helpers/display.rb +34 -0
  63. data/lib/poolparty/helpers/optioner.rb +64 -0
  64. data/lib/poolparty/helpers/provisioner_base.rb +250 -0
  65. data/lib/poolparty/helpers/provisioners/master.rb +136 -0
  66. data/lib/poolparty/helpers/provisioners/slave.rb +44 -0
  67. data/lib/poolparty/modules/cloud_resourcer.rb +89 -0
  68. data/lib/poolparty/modules/configurable.rb +34 -0
  69. data/lib/poolparty/modules/definable_resource.rb +59 -0
  70. data/lib/poolparty/modules/file_writer.rb +55 -0
  71. data/lib/poolparty/modules/method_missing_sugar.rb +53 -0
  72. data/lib/poolparty/modules/output.rb +13 -0
  73. data/lib/poolparty/modules/pretty_printer.rb +39 -0
  74. data/lib/{core/string.rb → poolparty/modules/s3_string.rb} +5 -22
  75. data/lib/{modules → poolparty/modules}/safe_instance.rb +0 -0
  76. data/lib/poolparty/monitors/base_monitor.rb +16 -0
  77. data/lib/poolparty/net/remote.rb +35 -0
  78. data/lib/poolparty/net/remote_bases/ec2.rb +148 -0
  79. data/lib/poolparty/net/remote_instance.rb +69 -0
  80. data/lib/poolparty/net/remoter.rb +224 -0
  81. data/lib/poolparty/net/remoter_base.rb +117 -0
  82. data/lib/poolparty/plugins/gem_package.rb +17 -0
  83. data/lib/poolparty/plugins/git.rb +41 -0
  84. data/lib/poolparty/plugins/line.rb +76 -0
  85. data/lib/poolparty/plugins/svn.rb +48 -0
  86. data/lib/poolparty/pool/base.rb +75 -0
  87. data/lib/poolparty/pool/cloud.rb +164 -0
  88. data/lib/poolparty/pool/custom_resource.rb +61 -0
  89. data/lib/poolparty/pool/loggable.rb +29 -0
  90. data/lib/poolparty/pool/plugin.rb +41 -0
  91. data/lib/poolparty/pool/plugin_model.rb +48 -0
  92. data/lib/poolparty/pool/pool.rb +55 -0
  93. data/lib/poolparty/pool/resource.rb +248 -0
  94. data/lib/poolparty/pool/resources/class_package.rb +64 -0
  95. data/lib/poolparty/pool/resources/conditional.rb +41 -0
  96. data/lib/poolparty/pool/resources/cron.rb +14 -0
  97. data/lib/poolparty/pool/resources/directory.rb +23 -0
  98. data/lib/poolparty/pool/resources/exec.rb +26 -0
  99. data/lib/poolparty/pool/resources/file.rb +23 -0
  100. data/lib/poolparty/pool/resources/gem.rb +14 -0
  101. data/lib/poolparty/pool/resources/host.rb +14 -0
  102. data/lib/poolparty/pool/resources/package.rb +14 -0
  103. data/lib/poolparty/pool/resources/remote_file.rb +22 -0
  104. data/lib/poolparty/pool/resources/service.rb +21 -0
  105. data/lib/poolparty/pool/resources/sshkey.rb +19 -0
  106. data/lib/poolparty/pool/resources/variable.rb +27 -0
  107. data/lib/poolparty/pool/script.rb +44 -0
  108. data/lib/poolparty/templates/authkeys +2 -0
  109. data/{config/monit/nginx.monit.conf → lib/poolparty/templates/cib.xml} +0 -0
  110. data/lib/poolparty/templates/fileserver.conf +4 -0
  111. data/lib/poolparty/templates/gem +25 -0
  112. data/{config/heartbeat.conf → lib/poolparty/templates/ha.cf} +3 -2
  113. data/{config → lib/poolparty/templates}/haproxy.conf +13 -6
  114. data/lib/poolparty/templates/namespaceauth.conf +19 -0
  115. data/lib/poolparty/templates/puppet.conf +17 -0
  116. data/lib/poolparty/version.rb +9 -0
  117. data/lib/poolpartycl.rb +3 -0
  118. data/poolparty.gemspec +56 -47
  119. data/script/destroy +14 -0
  120. data/script/generate +14 -0
  121. data/script/txt2html +82 -0
  122. data/setup.rb +1585 -0
  123. data/spec/poolparty/base_packages/haproxy_spec.rb +13 -0
  124. data/spec/poolparty/base_packages/heartbeat_spec.rb +30 -0
  125. data/spec/poolparty/bin/console_spec.rb +80 -0
  126. data/spec/poolparty/core/array_spec.rb +26 -0
  127. data/spec/poolparty/core/float.rb +13 -0
  128. data/spec/poolparty/core/hash_spec.rb +63 -0
  129. data/spec/poolparty/core/kernel_spec.rb +24 -0
  130. data/spec/poolparty/core/module_spec.rb +15 -0
  131. data/spec/poolparty/core/object_spec.rb +40 -0
  132. data/spec/poolparty/core/string_spec.rb +152 -0
  133. data/spec/poolparty/core/time_spec.rb +52 -0
  134. data/spec/poolparty/helpers/binary_spec.rb +26 -0
  135. data/spec/poolparty/helpers/display_spec.rb +13 -0
  136. data/spec/poolparty/helpers/optioner_spec.rb +39 -0
  137. data/spec/poolparty/helpers/provisioner_base_spec.rb +121 -0
  138. data/spec/poolparty/helpers/provisioners/master_spec.rb +54 -0
  139. data/spec/poolparty/helpers/provisioners/slave_spec.rb +28 -0
  140. data/spec/poolparty/modules/cloud_resourcer_spec.rb +135 -0
  141. data/spec/poolparty/modules/configurable_spec.rb +26 -0
  142. data/spec/poolparty/modules/definable_resource.rb +9 -0
  143. data/spec/poolparty/modules/file_writer_spec.rb +49 -0
  144. data/spec/poolparty/modules/s3_string_spec.rb +15 -0
  145. data/spec/poolparty/modules/tmp/willy/nilly.rb +1 -0
  146. data/spec/poolparty/net/remote_bases/ec2_spec.rb +92 -0
  147. data/spec/poolparty/net/remote_instance_spec.rb +70 -0
  148. data/spec/poolparty/net/remote_spec.rb +286 -0
  149. data/spec/poolparty/net/remoter_base_spec.rb +80 -0
  150. data/spec/poolparty/net/remoter_spec.rb +191 -0
  151. data/spec/poolparty/plugins/git_spec.rb +33 -0
  152. data/spec/poolparty/plugins/line_spec.rb +16 -0
  153. data/spec/poolparty/plugins/svn_spec.rb +16 -0
  154. data/spec/poolparty/pool/base_spec.rb +108 -0
  155. data/spec/poolparty/pool/cloud_spec.rb +299 -0
  156. data/spec/poolparty/pool/configurers/files/ruby_basic.rb +17 -0
  157. data/spec/poolparty/pool/configurers/files/ruby_plugins.rb +16 -0
  158. data/spec/poolparty/pool/configurers/ruby_spec.rb +58 -0
  159. data/spec/poolparty/pool/custom_resource_spec.rb +115 -0
  160. data/spec/poolparty/pool/example_spec.rb +112 -0
  161. data/spec/poolparty/pool/plugin_model_spec.rb +63 -0
  162. data/spec/poolparty/pool/plugin_spec.rb +85 -0
  163. data/spec/poolparty/pool/pool_spec.rb +83 -0
  164. data/spec/poolparty/pool/resource_spec.rb +224 -0
  165. data/spec/poolparty/pool/resources/class_package_spec.rb +84 -0
  166. data/spec/poolparty/pool/resources/conditional_spec.rb +38 -0
  167. data/spec/poolparty/pool/resources/cron_spec.rb +49 -0
  168. data/spec/poolparty/pool/resources/directory_spec.rb +40 -0
  169. data/spec/poolparty/pool/resources/exec_spec.rb +37 -0
  170. data/spec/poolparty/pool/resources/file_spec.rb +40 -0
  171. data/spec/poolparty/pool/resources/gem_spec.rb +16 -0
  172. data/spec/poolparty/pool/resources/host_spec.rb +28 -0
  173. data/spec/poolparty/pool/resources/package_spec.rb +44 -0
  174. data/spec/poolparty/pool/resources/remote_file_spec.rb +40 -0
  175. data/spec/poolparty/pool/resources/service_spec.rb +45 -0
  176. data/spec/poolparty/pool/resources/sshkey_spec.rb +48 -0
  177. data/spec/poolparty/pool/resources/variable_spec.rb +20 -0
  178. data/spec/poolparty/pool/script_spec.rb +51 -0
  179. data/spec/poolparty/pool/test_plugins/sshkey_test +2 -0
  180. data/{test/test_pool_party.rb → spec/poolparty/pool/test_plugins/virtual_host_template.erb} +0 -0
  181. data/spec/poolparty/pool/test_plugins/webserver.rb +46 -0
  182. data/spec/poolparty/poolparty_spec.rb +33 -0
  183. data/spec/poolparty/spec_helper.rb +120 -0
  184. data/tasks/cloud.rake +57 -0
  185. data/tasks/deployment.rake +34 -0
  186. data/tasks/development.rake +78 -0
  187. data/tasks/ec2.rake +20 -0
  188. data/tasks/environment.rake +7 -0
  189. data/tasks/instance.rake +63 -0
  190. data/tasks/server.rake +42 -0
  191. data/tasks/spec.rake +17 -0
  192. data/tasks/website.rake +17 -0
  193. data/test/test_generator_helper.rb +29 -0
  194. data/test/test_helper.rb +2 -0
  195. data/test/test_pool_spec_generator.rb +47 -0
  196. data/test/test_poolparty.rb +11 -0
  197. data/test_manifest.pp +538 -0
  198. data/website/index.html +107 -0
  199. data/website/index.txt +95 -0
  200. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  201. data/website/stylesheets/code.css +29 -0
  202. data/website/stylesheets/screen.css +147 -0
  203. data/website/template.html.erb +49 -0
  204. metadata +282 -101
  205. data/CHANGELOG +0 -4
  206. data/Manifest +0 -55
  207. data/bin/instance +0 -54
  208. data/config/config.yml +0 -23
  209. data/config/create_proxy_ami.sh +0 -582
  210. data/config/heartbeat_authkeys.conf +0 -2
  211. data/config/monit.conf +0 -8
  212. data/config/monit/haproxy.monit.conf +0 -7
  213. data/config/nginx.conf +0 -24
  214. data/lib/core/array.rb +0 -10
  215. data/lib/core/kernel.rb +0 -9
  216. data/lib/core/object.rb +0 -14
  217. data/lib/modules/callback.rb +0 -55
  218. data/lib/modules/ec2_wrapper.rb +0 -74
  219. data/lib/pool_party.rb +0 -69
  220. data/lib/pool_party/application.rb +0 -133
  221. data/lib/pool_party/init.rb +0 -4
  222. data/lib/pool_party/master.rb +0 -189
  223. data/lib/pool_party/monitors.rb +0 -13
  224. data/lib/pool_party/monitors/cpu.rb +0 -18
  225. data/lib/pool_party/monitors/memory.rb +0 -21
  226. data/lib/pool_party/monitors/web.rb +0 -18
  227. data/lib/pool_party/optioner.rb +0 -16
  228. data/lib/pool_party/os.rb +0 -11
  229. data/lib/pool_party/os/ubuntu.rb +0 -78
  230. data/lib/pool_party/remote_instance.rb +0 -180
  231. data/lib/pool_party/remoting.rb +0 -112
  232. data/lib/pool_party/scheduler.rb +0 -93
  233. data/lib/pool_party/tasks.rb +0 -220
  234. data/lib/s3/s3_object_store_folders.rb +0 -44
  235. data/spec/application_spec.rb +0 -32
  236. data/spec/callback_spec.rb +0 -65
  237. data/spec/helpers/ec2_mock.rb +0 -56
  238. data/spec/helpers/remote_instance_mock.rb +0 -11
  239. data/spec/kernel_spec.rb +0 -11
  240. data/spec/master_spec.rb +0 -147
  241. data/spec/monitor_spec.rb +0 -16
  242. data/spec/optioner_spec.rb +0 -22
  243. data/spec/poolparty_spec.rb +0 -8
  244. data/spec/remote_instance_spec.rb +0 -29
  245. data/spec/remoting_spec.rb +0 -75
  246. data/spec/spec_helper.rb +0 -38
  247. data/spec/string_spec.rb +0 -28
@@ -1,2 +0,0 @@
1
- auth 1
2
- 1 md5 PasswordForPoolPartyClusterApplicationButItIsOnlyADefault
@@ -1,8 +0,0 @@
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
-
8
- include /etc/monit.d/*
@@ -1,7 +0,0 @@
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
@@ -1,24 +0,0 @@
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:8100; }
12
-
13
- server {
14
- listen 80;
15
- server_name srv;
16
- root /home/usr;
17
-
18
- location / {
19
- proxy_pass http://fast_mongrels;
20
- break;
21
- }
22
-
23
- }
24
- }
@@ -1,10 +0,0 @@
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
- end
@@ -1,9 +0,0 @@
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
- end
@@ -1,14 +0,0 @@
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
- end
@@ -1,55 +0,0 @@
1
- module PoolParty
2
- module Callbacks
3
- module ClassMethods
4
- def callback(type,m,e,*args, &block)
5
-
6
- # Save the old method
7
- if method_defined?("#{type}_#{m}".to_sym)
8
- puts "method already defined"
9
- end
10
-
11
- case type
12
- when :before
13
- str=<<-EOD
14
- def #{type}_#{m}
15
- #{e}
16
- yield if block_given?
17
- super
18
- end
19
- EOD
20
- when :after
21
- str=<<-EOD
22
- def #{type}_#{m}
23
- super
24
- yield if block_given?
25
- #{e}
26
- end
27
- EOD
28
- end
29
-
30
- mMod = Module.new {eval str}
31
-
32
- module_eval %{alias_method :#{type}_#{m}, :#{m}}
33
-
34
- self.send :define_method, "#{m}".to_sym, Proc.new {
35
- extend(mMod)
36
- method("#{type}_#{m}".to_sym).call
37
- }
38
- end
39
- def before(m,e,*args, &block)
40
- callback(:before,m,e,*args, &block)
41
- end
42
- def after(m,e,*args, &block)
43
- callback(:after,m,e,*args,&block)
44
- end
45
- end
46
-
47
- module InstanceMethods
48
- end
49
-
50
- def self.included(receiver)
51
- receiver.extend ClassMethods
52
- receiver.send :include, InstanceMethods
53
- end
54
- end
55
- end
@@ -1,74 +0,0 @@
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
- # Instance description
28
- def describe_instance(id)
29
- instance = ec2.describe_instances(:instance_id => id)
30
- item = instance.DescribeInstancesResponse.reservationSet.item.instancesSet.item
31
- EC2ResponseObject.get_hash_from_response(item)
32
- end
33
- # Get instance by id
34
- def get_instance_by_id(id)
35
- get_instances_description.select {|a| a.instance_id == id}[0] rescue nil
36
- end
37
- # Get the s3 description for the response in a hash format
38
- def get_instances_description
39
- @cached_descriptions ||= EC2ResponseObject.get_descriptions(ec2.describe_instances)
40
- end
41
-
42
- # EC2 connections
43
- def ec2
44
- @ec2 ||= EC2::Base.new(:access_key_id => Application.access_key, :secret_access_key => Application.secret_access_key)
45
- end
46
- end
47
-
48
- def self.included(receiver)
49
- receiver.extend ClassMethods
50
- receiver.send :include, InstanceMethods
51
- end
52
- end
53
- # Provides a simple class to wrap around the amazon responses
54
- class EC2ResponseObject
55
- def self.get_descriptions(resp)
56
- rs = resp.DescribeInstancesResponse.reservationSet.item
57
- rs = rs.respond_to?(:instancesSet) ? rs.instancesSet : rs
58
- out = begin
59
- rs.reject {|a| a.empty? }.collect {|r| EC2ResponseObject.get_hash_from_response(r.instancesSet.item)}.reject {|a| a.nil? }
60
- rescue Exception => e
61
- begin
62
- # Really weird bug with amazon's ec2 gem
63
- rs.reject {|a| a.empty? }.collect {|r| EC2ResponseObject.get_hash_from_response(r)}.reject {|a| a.nil? }
64
- rescue Exception => e
65
- []
66
- end
67
- end
68
- out
69
- end
70
- def self.get_hash_from_response(resp)
71
- {:instance_id => resp.instanceId, :ip => resp.dnsName, :status => resp.instanceState.name, :launching_time => resp.launchTime} rescue nil
72
- end
73
- end
74
- end
@@ -1,69 +0,0 @@
1
- =begin rdoc
2
- The main file, contains the client and the server application methods
3
- =end
4
- $:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
5
-
6
- # rubygems
7
- require 'rubygems'
8
- require "aws/s3"
9
- require "sqs"
10
- require "EC2"
11
- require 'thread'
12
- require "pp"
13
- require "tempfile"
14
- require "aska"
15
- begin
16
- require 'fastthread'
17
- require 'thin'
18
- rescue LoadError
19
- end
20
-
21
- ## Load PoolParty
22
- pwd = File.dirname(__FILE__)
23
-
24
- # Load the required files
25
- # If there is an init file, load that, otherwise
26
- # require all the files in each directory
27
- %w(core modules s3 pool_party).each do |dir|
28
- Dir["#{pwd}/#{dir}"].each do |dir|
29
- begin
30
- require File.join(dir, "init")
31
- rescue LoadError => e
32
- Dir["#{pwd}/#{File.basename(dir)}/**"].each {|file| require File.join(dir, File.basename(file))}
33
- end
34
- end
35
- end
36
-
37
- module PoolParty
38
- module Version
39
- MAJOR = '0'
40
- MINOR = '0'
41
- REVISION = '4'
42
- def self.combined
43
- [MAJOR, MINOR, REVISION].join('.')
44
- end
45
- end
46
- # PoolParty options
47
- def options(opts={})
48
- Application.options(opts)
49
- end
50
- # Are we working in verbose-mode
51
- def verbose?
52
- Application.verbose == true
53
- end
54
- # Send a message if we are in verbose-mode
55
- def message(msg="")
56
- pp "-- #{msg}" if verbose?
57
- end
58
- # Root directory of the application
59
- def root_dir
60
- File.dirname(__FILE__)
61
- end
62
- # Write string to a tempfile
63
- def write_to_temp_file(str="")
64
- tempfile = Tempfile.new("rand#{rand(1000)}-#{rand(1000)}")
65
- tempfile.print(str)
66
- tempfile.flush
67
- tempfile
68
- end
69
- end
@@ -1,133 +0,0 @@
1
- =begin rdoc
2
- Application
3
- This handles user interaction
4
- =end
5
- $:.unshift File.dirname(__FILE__)
6
-
7
- module PoolParty
8
- extend self
9
-
10
- class Application
11
- class << self
12
-
13
- # The application options
14
- def options(opts={})
15
- @options ||= make_options(opts)
16
- end
17
- # Make the options with the config_file overrides included
18
- # Default config file assumed to be at config/config.yml
19
- def make_options(opts={})
20
- load_options!
21
- default_options.merge!(opts)
22
- # If the config_file options are specified and not empty
23
- unless default_options[:config_file].nil? || default_options[:config_file].empty?
24
- require "yaml"
25
- # Try loading the file if it exists
26
- filedata = open(default_options[:config_file]).read if File.file?(default_options[:config_file])
27
- default_options.merge!( YAML.load(filedata) ) if filedata
28
- end
29
-
30
- OpenStruct.new(default_options)
31
- end
32
-
33
- # Load options via commandline
34
- def load_options!
35
- require 'optparse'
36
- OptionParser.new do |op|
37
- op.on('-A key', '--access-key key', "Ec2 access key (ENV['ACCESS_KEY'])") { |key| default_options[:access_key] = key }
38
- op.on('-S key', '--secret-access-key key', "Ec2 secret access key (ENV['SECRET_ACCESS_KEY'])") { |key| default_options[:secret_access_key] = key }
39
- op.on('-I ami', '--image-id id', "AMI instance (default: 'ami-4a46a323')") {|id| default_options[:ami] = id }
40
- op.on('-k keypair', '--keypair name', "Keypair name (ENV['KEYPAIR_NAME'])") { |key| default_options[:keypair] = key }
41
- op.on('-b bucket', '--bucket bucket', "Application bucket") { |bucket| default_options[:shared_bucket] = bucket }
42
- op.on('-D ec2 directory', '--ec2-dir dir', "Directory with ec2 data (default: '~/.ec2')") {|id| default_options[:ec2_dir] = id }
43
- op.on('-S services', '--services names', "Monitored services (default: '')") {|id| default_options[:services] = id }
44
- op.on('-c file', '--config-file file', "Config file (default: '')") {|file| default_options[:config_file] = file }
45
- op.on('-p port', '--host_port port', "Run on specific host_port (default: 7788)") { |host_port| default_options[:host_port] = host_port }
46
- op.on('-m monitors', '--monitors names', "Monitor instances using (default: 'web,memory,cpu')") {|s| default_options[:monitor_load_on] = s }
47
- op.on('-o port', '--client_port port', "Run on specific client_port (default: 7788)") { |client_port| default_options[:client_port] = client_port }
48
- op.on('-O os', '--os os', "Configure for os (default: ubuntu)") { |os| default_options[:os] = os }
49
- op.on('-e env', '--environment env', "Run on the specific environment (default: development)") { |env| default_options[:env] = env }
50
- op.on('-s size', '--size size', "Run specific sized instance") {|s| default_options[:size] = s}
51
- op.on('-u username', '--username name', "Login with the user (default: root)") {|s| default_options[:user] = s}
52
- op.on('-d user-data','--user-data data', "Extra data to send each of the instances (default: "")") { |data| default_options[:user_data] = data }
53
- op.on('-t seconds', '--polling-time', "Time between polling in seconds (default 50)") {|t| default_options[:polling_time] = t }
54
- op.on('-v', '--[no-]verbose', 'Run verbosely (default: false)') {|v| default_options[:verbose] = v}
55
- op.on('-i number', '--minimum-instances', "The minimum number of instances to run at all times (default 1)") {|i| default_options[:minimum_instances] = i}
56
- op.on('-x number', '--maximum-instances', "The maximum number of instances to run (default 3)") {|x| default_options[:maximum_instances] = x}
57
-
58
- op.on_tail("-h", "--help", "Show this message") do |o|
59
- puts "op: #{o}"
60
- exit
61
- end
62
- end.parse!(ARGV.dup)
63
- end
64
-
65
- # Basic default options
66
- # All can be overridden by the command line
67
- # or in a config.yml file
68
- def default_options
69
- @default_options ||= {
70
- :host_port => 80,
71
- :client_port => 8001,
72
- :environment => 'development',
73
- :verbose => true,
74
- :logging => true,
75
- :size => "small",
76
- :polling_time => "30.seconds",
77
- :user_data => "",
78
- :heavy_load => 0.80,
79
- :light_load => 0.15,
80
- :minimum_instances => 1,
81
- :maximum_instances => 3,
82
- :access_key => ENV["ACCESS_KEY"],
83
- :secret_access_key => ENV["SECRET_ACCESS_KEY"],
84
- :config_file => ((ENV["CONFIG_FILE"] && ENV["CONFIG_FILE"].empty?) ? "config/config.yml" : ENV["CONFIG_FILE"]),
85
- :username => "root",
86
- :ec2_dir => ENV["EC2_HOME"],
87
- :keypair => ENV["KEYPAIR_NAME"],
88
- :ami => 'ami-4a46a323',
89
- :shared_bucket => "",
90
- :services => "nginx sinatra",
91
- :expand_when => "web_usage < 1.5\n memory_usage > 0.85",
92
- :contract_when => "cpu_usage < 0.20\n memory_usage < 0.10",
93
- :os => "ubuntu"
94
- }
95
- end
96
- # Services monitored by Heartbeat
97
- # Always at least monitors haproxy
98
- def managed_services
99
- "haproxy #{services}"
100
- end
101
- def launching_user_data
102
- {:polling_time => polling_time}.to_yaml
103
- end
104
- # Keypair path
105
- # Idiom:
106
- # /Users/username/.ec2/id_rsa-name
107
- def keypair_path
108
- "#{ec2_dir}/id_rsa-#{keypair}"
109
- end
110
- # Are we in development or test mode
111
- def development?
112
- environment == 'development'
113
- end
114
- # Are we in production mode?
115
- def production?
116
- environment == "production"
117
- end
118
- # Standard configuration files
119
- %w(haproxy monit heartbeat heartbeat_authkeys).each do |file|
120
- define_method "#{file}_config_file" do
121
- File.join(File.dirname(__FILE__), "../..", "config", "#{file}.conf")
122
- end
123
- end
124
-
125
- # Call the options from the Application
126
- def method_missing(m,*args)
127
- options.methods.include?("#{m}") ? options.send(m,args) : super
128
- end
129
- end
130
-
131
- end
132
-
133
- end
@@ -1,4 +0,0 @@
1
- =begin rdoc
2
- Load the files in order
3
- =end
4
- %w(optioner application monitors scheduler remoting os remote_instance master tasks).each {|f| require File.join(File.dirname(__FILE__), f)}
@@ -1,189 +0,0 @@
1
- =begin rdoc
2
- The basic master for PoolParty
3
- =end
4
- require "aska"
5
- module PoolParty
6
- class Master < Remoting
7
- include Aska
8
-
9
- def initialize
10
- super
11
-
12
- self.class.send :rules, :contract_when, Application.options.contract_when
13
- self.class.send :rules, :expand_when, Application.options.expand_when
14
- end
15
- # Start the cloud
16
- def start_cloud!
17
- start!
18
- end
19
- # Start the cloud, which launches the minimum_instances
20
- def start!
21
- message "Launching minimum_instances"
22
- launch_minimum_instances
23
- message "Waiting for master to boot up"
24
- reset!
25
- while !number_of_pending_instances.zero?
26
- wait "2.seconds"
27
- reset!
28
- end
29
- message "Give some time for the instance ssh to start up"
30
- wait "10.seconds"
31
- message "Configuring master"
32
- get_node(0).configure
33
- end
34
- # Launch the minimum number of instances.
35
- def launch_minimum_instances
36
- request_launch_new_instances(Application.minimum_instances - number_of_pending_and_running_instances)
37
- nodes
38
- end
39
- # Start monitoring the cloud with the threaded loop
40
- def start_monitor!
41
- begin
42
- trap("INT") do
43
- on_exit
44
- exit
45
- end
46
- run_thread_loop(:daemonize => true) do
47
- add_task {launch_minimum_instances} # If the base instances go down...
48
- add_task {reconfigure_cloud_when_necessary}
49
- add_task {add_instance_if_load_is_high}
50
- add_task {terminate_instance_if_load_is_low}
51
- end
52
- rescue Exception => e
53
- puts "There was an error: #{e.nice_message}"
54
- end
55
- end
56
- # Tough method:
57
- # We need to make sure that all the instances have the required software installed
58
- # This is a basic check against the local store of the instances that have the
59
- # stack installed.
60
- def reconfigure_cloud_when_necessary
61
- reconfigure_running_instances if number_of_unconfigured_nodes > 0
62
- end
63
- def number_of_unconfigured_nodes
64
- nodes.reject {|a| a.stack_installed? }.size
65
- end
66
- # Add an instance if the load is high
67
- def add_instance_if_load_is_high
68
- request_launch_new_instance if expand?
69
- end
70
- # Teardown an instance if the load is pretty low
71
- def terminate_instance_if_load_is_low
72
- if contract?
73
- node = nodes.reject {|a| a.master? }[-1]
74
- request_termination_of_instance(node.instance_id) if node
75
- end
76
- end
77
- # FOR MONITORING
78
- def contract?
79
- valid_rules?(:contract_when)
80
- end
81
- def expand?
82
- valid_rules?(:expand_when)
83
- end
84
- # Get the average web requests per cloud
85
- def web_requests
86
- nodes.collect {|a| a.web } / nodes.size
87
- end
88
- # Get the average cpu usage per cloud
89
- def cpu_usage
90
- nodes.collect {|a| a.cpu } / nodes.size
91
- end
92
- # Get the average memory usage over the cloud
93
- def memory_usage
94
- nodes.collect {|a| a.memory } / nodes.size
95
- end
96
- # Restart the running instances services with monit on all the nodes
97
- def restart_running_instances_services
98
- nodes.each do |node|
99
- node.restart_with_monit
100
- end
101
- end
102
- # Reconfigure the running instances
103
- def reconfigure_running_instances
104
- nodes.each do |node|
105
- node.configure if node.status =~ /running/
106
- end
107
- end
108
- # Build the basic haproxy config file from the config file in the config directory and return a tempfile
109
- def build_haproxy_file
110
- servers=<<-EOS
111
- #{nodes.collect {|node| node.haproxy_entry}.join("\n")}
112
- EOS
113
- write_to_temp_file(open(Application.haproxy_config_file).read.strip ^ {:servers => servers, :host_port => Application.host_port})
114
- end
115
- # Build the hosts file and return a tempfile
116
- def build_hosts_file
117
- write_to_temp_file(nodes.collect {|a| a.hosts_entry }.join("\n"))
118
- end
119
- # Build host file for a specific node
120
- def build_hosts_file_for(n)
121
- servers=<<-EOS
122
- #{nodes.collect {|node| node.ip == n.ip ? node.local_hosts_entry : node.hosts_entry}.join("\n")}
123
- EOS
124
- write_to_temp_file(servers)
125
- end
126
- # Build the basic auth file for the heartbeat
127
- def build_heartbeat_authkeys_file
128
- write_to_temp_file(open(Application.heartbeat_authkeys_config_file).read)
129
- end
130
- # Return a list of the nodes and cache them
131
- def nodes
132
- @nodes ||= list_of_nonterminated_instances.collect_with_index do |inst, i|
133
- RemoteInstance.new(inst.merge({:number => i}))
134
- end
135
- end
136
- # Get the node at the specific index from the cached nodes
137
- def get_node(i=0)
138
- nodes.select {|a| a.number == i}.first
139
- end
140
- # Get the next node in sequence, so we can configure heartbeat to monitor the next node
141
- def get_next_node(node)
142
- i = node.number + 1
143
- i = 0 if i >= (nodes.size - 1)
144
- get_node(i)
145
- end
146
- # On exit command
147
- def on_exit
148
- end
149
- # List the clouds
150
- def list
151
- if number_of_pending_and_running_instances > 0
152
- out = "-- CLOUD (#{number_of_pending_and_running_instances})--\n"
153
- out << nodes.collect {|node| node.description }.join("\n")
154
- else
155
- out = "Cloud is not running"
156
- end
157
- out
158
- end
159
- # Reset and clear the caches
160
- def reset!
161
- @cached_descriptions = nil
162
- @nodes = nil
163
- end
164
-
165
- class << self
166
- def requires_heartbeat?
167
- new.nodes.size > 1
168
- end
169
- def get_next_node(node)
170
- new.get_next_node(node)
171
- end
172
- # Build a heartbeat_config_file from the config file in the config directory and return a tempfile
173
- def build_heartbeat_config_file_for(node)
174
- return nil unless node
175
- servers = "#{node.node_entry}\n#{get_next_node(node).node_entry}"
176
- write_to_temp_file(open(Application.heartbeat_config_file).read.strip ^ {:nodes => servers})
177
- end
178
- # Build a heartbeat resources file from the config directory and return a tempfile
179
- def build_heartbeat_resources_file_for(node)
180
- return nil unless node
181
- write_to_temp_file("#{node.haproxy_resources_entry}\n#{get_next_node(node).haproxy_resources_entry}")
182
- end
183
- def build_hosts_file_for(node)
184
- new.build_hosts_file_for(node)
185
- end
186
- end
187
-
188
- end
189
- end