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.
- data/History.txt +25 -0
- data/License.txt +20 -0
- data/Manifest.txt +203 -0
- data/PostInstall.txt +18 -0
- data/README.txt +21 -82
- data/Rakefile +25 -18
- data/bin/cloud +31 -0
- data/bin/cloud-add-keypair +23 -0
- data/bin/cloud-configure +31 -0
- data/bin/cloud-contract +27 -0
- data/bin/cloud-expand +27 -0
- data/bin/cloud-list +32 -0
- data/bin/cloud-maintain +36 -0
- data/bin/cloud-osxcopy +22 -0
- data/bin/cloud-provision +31 -0
- data/bin/cloud-refresh +26 -0
- data/bin/cloud-ssh +18 -0
- data/bin/cloud-start +32 -0
- data/bin/cloud-terminate +23 -0
- data/bin/pool +25 -27
- data/bin/pool-console +12 -0
- data/bin/pool-describe +9 -0
- data/bin/pool-list +28 -0
- data/bin/pool-provision +34 -0
- data/bin/pool-spec +17 -0
- data/bin/pool-start +32 -0
- data/bin/pool-start-monitor +1 -0
- data/config/hoe.rb +115 -0
- data/config/requirements.rb +15 -0
- data/examples/basic.rb +20 -0
- data/examples/plugin_without_plugin_directory.rb +13 -0
- data/examples/poolparty.rb +12 -0
- data/examples/with_apache_plugin.rb +22 -0
- data/generators/poolspec/USAGE +5 -0
- data/generators/poolspec/poolspec_generator.rb +65 -0
- data/generators/poolspec/templates/pool_spec_template.erb +9 -0
- data/lib/erlang/eb_server.erl +27 -0
- data/lib/poolparty.rb +56 -0
- data/lib/poolparty/base_packages/haproxy.rb +42 -0
- data/lib/poolparty/base_packages/heartbeat.rb +45 -0
- data/lib/poolparty/base_packages/poolparty.rb +36 -0
- data/lib/poolparty/base_packages/ruby.rb +43 -0
- data/lib/poolparty/core/array.rb +24 -0
- data/lib/{core → poolparty/core}/exception.rb +0 -0
- data/lib/poolparty/core/float.rb +13 -0
- data/lib/poolparty/core/hash.rb +29 -0
- data/lib/poolparty/core/kernel.rb +37 -0
- data/lib/{core → poolparty/core}/module.rb +18 -0
- data/lib/poolparty/core/my_open_struct.rb +18 -0
- data/lib/poolparty/core/object.rb +54 -0
- data/lib/poolparty/core/proc.rb +7 -0
- data/lib/poolparty/core/string.rb +72 -0
- data/lib/poolparty/core/symbol.rb +8 -0
- data/lib/{core → poolparty/core}/time.rb +15 -0
- data/lib/poolparty/exceptions/RemoteException.rb +12 -0
- data/lib/poolparty/exceptions/ResourceException.rb +7 -0
- data/lib/poolparty/exceptions/RuntimeException.rb +7 -0
- data/lib/poolparty/exceptions/SpecException.rb +7 -0
- data/lib/poolparty/exceptions/TemplateNotFound.rb +7 -0
- data/lib/poolparty/helpers/binary.rb +31 -0
- data/lib/poolparty/helpers/console.rb +30 -0
- data/lib/poolparty/helpers/display.rb +34 -0
- data/lib/poolparty/helpers/optioner.rb +64 -0
- data/lib/poolparty/helpers/provisioner_base.rb +250 -0
- data/lib/poolparty/helpers/provisioners/master.rb +136 -0
- data/lib/poolparty/helpers/provisioners/slave.rb +44 -0
- data/lib/poolparty/modules/cloud_resourcer.rb +89 -0
- data/lib/poolparty/modules/configurable.rb +34 -0
- data/lib/poolparty/modules/definable_resource.rb +59 -0
- data/lib/poolparty/modules/file_writer.rb +55 -0
- data/lib/poolparty/modules/method_missing_sugar.rb +53 -0
- data/lib/poolparty/modules/output.rb +13 -0
- data/lib/poolparty/modules/pretty_printer.rb +39 -0
- data/lib/{core/string.rb → poolparty/modules/s3_string.rb} +5 -22
- data/lib/{modules → poolparty/modules}/safe_instance.rb +0 -0
- data/lib/poolparty/monitors/base_monitor.rb +16 -0
- data/lib/poolparty/net/remote.rb +35 -0
- data/lib/poolparty/net/remote_bases/ec2.rb +148 -0
- data/lib/poolparty/net/remote_instance.rb +69 -0
- data/lib/poolparty/net/remoter.rb +224 -0
- data/lib/poolparty/net/remoter_base.rb +117 -0
- data/lib/poolparty/plugins/gem_package.rb +17 -0
- data/lib/poolparty/plugins/git.rb +41 -0
- data/lib/poolparty/plugins/line.rb +76 -0
- data/lib/poolparty/plugins/svn.rb +48 -0
- data/lib/poolparty/pool/base.rb +75 -0
- data/lib/poolparty/pool/cloud.rb +164 -0
- data/lib/poolparty/pool/custom_resource.rb +61 -0
- data/lib/poolparty/pool/loggable.rb +29 -0
- data/lib/poolparty/pool/plugin.rb +41 -0
- data/lib/poolparty/pool/plugin_model.rb +48 -0
- data/lib/poolparty/pool/pool.rb +55 -0
- data/lib/poolparty/pool/resource.rb +248 -0
- data/lib/poolparty/pool/resources/class_package.rb +64 -0
- data/lib/poolparty/pool/resources/conditional.rb +41 -0
- data/lib/poolparty/pool/resources/cron.rb +14 -0
- data/lib/poolparty/pool/resources/directory.rb +23 -0
- data/lib/poolparty/pool/resources/exec.rb +26 -0
- data/lib/poolparty/pool/resources/file.rb +23 -0
- data/lib/poolparty/pool/resources/gem.rb +14 -0
- data/lib/poolparty/pool/resources/host.rb +14 -0
- data/lib/poolparty/pool/resources/package.rb +14 -0
- data/lib/poolparty/pool/resources/remote_file.rb +22 -0
- data/lib/poolparty/pool/resources/service.rb +21 -0
- data/lib/poolparty/pool/resources/sshkey.rb +19 -0
- data/lib/poolparty/pool/resources/variable.rb +27 -0
- data/lib/poolparty/pool/script.rb +44 -0
- data/lib/poolparty/templates/authkeys +2 -0
- data/{config/monit/nginx.monit.conf → lib/poolparty/templates/cib.xml} +0 -0
- data/lib/poolparty/templates/fileserver.conf +4 -0
- data/lib/poolparty/templates/gem +25 -0
- data/{config/heartbeat.conf → lib/poolparty/templates/ha.cf} +3 -2
- data/{config → lib/poolparty/templates}/haproxy.conf +13 -6
- data/lib/poolparty/templates/namespaceauth.conf +19 -0
- data/lib/poolparty/templates/puppet.conf +17 -0
- data/lib/poolparty/version.rb +9 -0
- data/lib/poolpartycl.rb +3 -0
- data/poolparty.gemspec +56 -47
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +82 -0
- data/setup.rb +1585 -0
- data/spec/poolparty/base_packages/haproxy_spec.rb +13 -0
- data/spec/poolparty/base_packages/heartbeat_spec.rb +30 -0
- data/spec/poolparty/bin/console_spec.rb +80 -0
- data/spec/poolparty/core/array_spec.rb +26 -0
- data/spec/poolparty/core/float.rb +13 -0
- data/spec/poolparty/core/hash_spec.rb +63 -0
- data/spec/poolparty/core/kernel_spec.rb +24 -0
- data/spec/poolparty/core/module_spec.rb +15 -0
- data/spec/poolparty/core/object_spec.rb +40 -0
- data/spec/poolparty/core/string_spec.rb +152 -0
- data/spec/poolparty/core/time_spec.rb +52 -0
- data/spec/poolparty/helpers/binary_spec.rb +26 -0
- data/spec/poolparty/helpers/display_spec.rb +13 -0
- data/spec/poolparty/helpers/optioner_spec.rb +39 -0
- data/spec/poolparty/helpers/provisioner_base_spec.rb +121 -0
- data/spec/poolparty/helpers/provisioners/master_spec.rb +54 -0
- data/spec/poolparty/helpers/provisioners/slave_spec.rb +28 -0
- data/spec/poolparty/modules/cloud_resourcer_spec.rb +135 -0
- data/spec/poolparty/modules/configurable_spec.rb +26 -0
- data/spec/poolparty/modules/definable_resource.rb +9 -0
- data/spec/poolparty/modules/file_writer_spec.rb +49 -0
- data/spec/poolparty/modules/s3_string_spec.rb +15 -0
- data/spec/poolparty/modules/tmp/willy/nilly.rb +1 -0
- data/spec/poolparty/net/remote_bases/ec2_spec.rb +92 -0
- data/spec/poolparty/net/remote_instance_spec.rb +70 -0
- data/spec/poolparty/net/remote_spec.rb +286 -0
- data/spec/poolparty/net/remoter_base_spec.rb +80 -0
- data/spec/poolparty/net/remoter_spec.rb +191 -0
- data/spec/poolparty/plugins/git_spec.rb +33 -0
- data/spec/poolparty/plugins/line_spec.rb +16 -0
- data/spec/poolparty/plugins/svn_spec.rb +16 -0
- data/spec/poolparty/pool/base_spec.rb +108 -0
- data/spec/poolparty/pool/cloud_spec.rb +299 -0
- data/spec/poolparty/pool/configurers/files/ruby_basic.rb +17 -0
- data/spec/poolparty/pool/configurers/files/ruby_plugins.rb +16 -0
- data/spec/poolparty/pool/configurers/ruby_spec.rb +58 -0
- data/spec/poolparty/pool/custom_resource_spec.rb +115 -0
- data/spec/poolparty/pool/example_spec.rb +112 -0
- data/spec/poolparty/pool/plugin_model_spec.rb +63 -0
- data/spec/poolparty/pool/plugin_spec.rb +85 -0
- data/spec/poolparty/pool/pool_spec.rb +83 -0
- data/spec/poolparty/pool/resource_spec.rb +224 -0
- data/spec/poolparty/pool/resources/class_package_spec.rb +84 -0
- data/spec/poolparty/pool/resources/conditional_spec.rb +38 -0
- data/spec/poolparty/pool/resources/cron_spec.rb +49 -0
- data/spec/poolparty/pool/resources/directory_spec.rb +40 -0
- data/spec/poolparty/pool/resources/exec_spec.rb +37 -0
- data/spec/poolparty/pool/resources/file_spec.rb +40 -0
- data/spec/poolparty/pool/resources/gem_spec.rb +16 -0
- data/spec/poolparty/pool/resources/host_spec.rb +28 -0
- data/spec/poolparty/pool/resources/package_spec.rb +44 -0
- data/spec/poolparty/pool/resources/remote_file_spec.rb +40 -0
- data/spec/poolparty/pool/resources/service_spec.rb +45 -0
- data/spec/poolparty/pool/resources/sshkey_spec.rb +48 -0
- data/spec/poolparty/pool/resources/variable_spec.rb +20 -0
- data/spec/poolparty/pool/script_spec.rb +51 -0
- data/spec/poolparty/pool/test_plugins/sshkey_test +2 -0
- data/{test/test_pool_party.rb → spec/poolparty/pool/test_plugins/virtual_host_template.erb} +0 -0
- data/spec/poolparty/pool/test_plugins/webserver.rb +46 -0
- data/spec/poolparty/poolparty_spec.rb +33 -0
- data/spec/poolparty/spec_helper.rb +120 -0
- data/tasks/cloud.rake +57 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/development.rake +78 -0
- data/tasks/ec2.rake +20 -0
- data/tasks/environment.rake +7 -0
- data/tasks/instance.rake +63 -0
- data/tasks/server.rake +42 -0
- data/tasks/spec.rake +17 -0
- data/tasks/website.rake +17 -0
- data/test/test_generator_helper.rb +29 -0
- data/test/test_helper.rb +2 -0
- data/test/test_pool_spec_generator.rb +47 -0
- data/test/test_poolparty.rb +11 -0
- data/test_manifest.pp +538 -0
- data/website/index.html +107 -0
- data/website/index.txt +95 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/code.css +29 -0
- data/website/stylesheets/screen.css +147 -0
- data/website/template.html.erb +49 -0
- metadata +282 -101
- data/CHANGELOG +0 -4
- data/Manifest +0 -55
- data/bin/instance +0 -54
- data/config/config.yml +0 -23
- data/config/create_proxy_ami.sh +0 -582
- data/config/heartbeat_authkeys.conf +0 -2
- data/config/monit.conf +0 -8
- data/config/monit/haproxy.monit.conf +0 -7
- data/config/nginx.conf +0 -24
- data/lib/core/array.rb +0 -10
- data/lib/core/kernel.rb +0 -9
- data/lib/core/object.rb +0 -14
- data/lib/modules/callback.rb +0 -55
- data/lib/modules/ec2_wrapper.rb +0 -74
- data/lib/pool_party.rb +0 -69
- data/lib/pool_party/application.rb +0 -133
- data/lib/pool_party/init.rb +0 -4
- data/lib/pool_party/master.rb +0 -189
- data/lib/pool_party/monitors.rb +0 -13
- data/lib/pool_party/monitors/cpu.rb +0 -18
- data/lib/pool_party/monitors/memory.rb +0 -21
- data/lib/pool_party/monitors/web.rb +0 -18
- data/lib/pool_party/optioner.rb +0 -16
- data/lib/pool_party/os.rb +0 -11
- data/lib/pool_party/os/ubuntu.rb +0 -78
- data/lib/pool_party/remote_instance.rb +0 -180
- data/lib/pool_party/remoting.rb +0 -112
- data/lib/pool_party/scheduler.rb +0 -93
- data/lib/pool_party/tasks.rb +0 -220
- data/lib/s3/s3_object_store_folders.rb +0 -44
- data/spec/application_spec.rb +0 -32
- data/spec/callback_spec.rb +0 -65
- data/spec/helpers/ec2_mock.rb +0 -56
- data/spec/helpers/remote_instance_mock.rb +0 -11
- data/spec/kernel_spec.rb +0 -11
- data/spec/master_spec.rb +0 -147
- data/spec/monitor_spec.rb +0 -16
- data/spec/optioner_spec.rb +0 -22
- data/spec/poolparty_spec.rb +0 -8
- data/spec/remote_instance_spec.rb +0 -29
- data/spec/remoting_spec.rb +0 -75
- data/spec/spec_helper.rb +0 -38
- data/spec/string_spec.rb +0 -28
data/config/monit.conf
DELETED
|
@@ -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
|
data/config/nginx.conf
DELETED
|
@@ -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
|
-
}
|
data/lib/core/array.rb
DELETED
data/lib/core/kernel.rb
DELETED
data/lib/core/object.rb
DELETED
|
@@ -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
|
data/lib/modules/callback.rb
DELETED
|
@@ -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
|
data/lib/modules/ec2_wrapper.rb
DELETED
|
@@ -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
|
data/lib/pool_party.rb
DELETED
|
@@ -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
|
data/lib/pool_party/init.rb
DELETED
data/lib/pool_party/master.rb
DELETED
|
@@ -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
|