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,142 @@
|
|
1
|
+
PoolParty, a tutorial.
|
2
|
+
|
3
|
+
To get PoolParty up and running on your very own ec2 instances, you have to do a few things in preparation first.
|
4
|
+
|
5
|
+
First, install the gem with:
|
6
|
+
|
7
|
+
sudo gem install auser-poolparty -s http://gems.github.com
|
8
|
+
|
9
|
+
First, head on over to http://aws.amazon.com and sign up for an account. Make sure you make note of the access key and the secret access key on the access identifiers page. Also, scroll down to the bottom of that page and download your x.509 certificate and the private one as well. You only can generate that once, so make sure you download it immediately. Finally, take note of your account id.
|
10
|
+
|
11
|
+
Now, let's get to some PoolParty setup. PoolParty only requires one file, a configuration file. Once you get this setup, PoolParty will do the rest for you, so let's get started editing the config file.
|
12
|
+
|
13
|
+
There is a generator in progress, so if by the time you read this and you have the gem installed, type
|
14
|
+
|
15
|
+
which poolparty
|
16
|
+
|
17
|
+
If you get a response, then the generator has been built and you can skip this section and go right to the next 'using it' section, however, if not or you just want to understand the innerworkings, read on.
|
18
|
+
|
19
|
+
config/config.yml
|
20
|
+
PoolParty makes the guess that your config is in a file and is in config/config.yml in your base project directory. However, this is not necessary if you do not want a configuration file, since all options can be added at runtime using switches on the command-line. That being said, the easiest way is to write a config file.
|
21
|
+
|
22
|
+
The minimal config file looks like this:
|
23
|
+
|
24
|
+
:access_key: "1XCTNEK1CC5BQXXXXXXX"
|
25
|
+
:secret_access_key: "Q2qJHP0S2iOKikn9glB+XXXX/XXXXXXXX/XXXXXXX"
|
26
|
+
:ami: "ami-3057b259"
|
27
|
+
|
28
|
+
That's it. However,a more complete one would look more like this:
|
29
|
+
|
30
|
+
:app_name: "test_app"
|
31
|
+
:user_id: "1619-6456-1111"
|
32
|
+
:access_key: "1XCTNEK1CC5BQXXXXXXX"
|
33
|
+
:secret_access_key: "Q2qJHP0S2iOKikn9glB+XXXX/XXXXXXXX/XXXXXXX"
|
34
|
+
:ami: "ami-3057b259"
|
35
|
+
:size: small
|
36
|
+
:polling_time: "5.minutes"
|
37
|
+
:minimum_instances: 2
|
38
|
+
:maximum_instances: 10
|
39
|
+
:ec2_dir: "/Users/user/.ec2"
|
40
|
+
:keypair: user
|
41
|
+
:os: ubuntu
|
42
|
+
:host_port: 80
|
43
|
+
:shared_bucket: "pool-party-app-data"
|
44
|
+
:environment: production
|
45
|
+
:contract_when:
|
46
|
+
web > 10
|
47
|
+
cpu < 0.2
|
48
|
+
:expand_when:
|
49
|
+
cpu > 0.45
|
50
|
+
web < 10
|
51
|
+
|
52
|
+
Most of it should be self-explanatory, but a few points are necessary to describe. ec2_dir and keypair are for your location development machine. If you didn't create a keypair, not to worry, put in anything here. If you did, it's the name of the keypair you added. This is important for working with the instances after you get them up.
|
53
|
+
|
54
|
+
If you put in a bucket in the shared_bucket key, the instances will automount that bucket to the /data drive. If you leave it out or don't include it, then it won't.
|
55
|
+
|
56
|
+
The master instance takes care of monitoring the cloud for you. If the the parameters you set in the contract_when and expand_when are met, then the cloud will respond accordingly. Those are based on monitors that are included in PoolParty.
|
57
|
+
|
58
|
+
The installation of the required software for PoolParty is taken care of by PoolParty. That being said, PoolParty makes no assumptions of what the cloud's responsibilities will be. See 'Using' later on.
|
59
|
+
|
60
|
+
Monitors
|
61
|
+
The monitors are flexible and extensible. Currently included in PoolParty are monitors that monitor web requests and cpu and memory percentages. Writing a monitor or a plugin are out of the scope of this tutorial, but will be included in future tutorials.
|
62
|
+
|
63
|
+
Configuring
|
64
|
+
It can be tedious setting up just your development machine. This is why PoolParty makes it super easy for you in just one rake task.
|
65
|
+
|
66
|
+
If you are not familiar with ruby, I suggest you look into it, it's a beautiful language. However, PoolParty is language-agnostic, so not to worry.
|
67
|
+
|
68
|
+
Create a file in your development directory called Rakefile and add this to it.
|
69
|
+
|
70
|
+
require 'rubygems'
|
71
|
+
require 'poolparty'
|
72
|
+
|
73
|
+
PoolParty.include_tasks
|
74
|
+
|
75
|
+
That's it, pretty simple and a bunch of tasks are available to you directly!
|
76
|
+
Your development directory should look like this:
|
77
|
+
|
78
|
+
./
|
79
|
+
config/
|
80
|
+
config.yml
|
81
|
+
Rakefile
|
82
|
+
|
83
|
+
Now, once you have this setup and your config file setup, you can type
|
84
|
+
|
85
|
+
rake dev:setup
|
86
|
+
|
87
|
+
That's it and you should be able to type ec2-describe-images (provided you have installed the ec2-api-tools, available here: http://developer.amazonwebservices.com/connect/entry.jspa?externalID=351&categoryID=88) at this point and you are set.
|
88
|
+
|
89
|
+
You will find yourself with a .<keypair_name>_pool_keys file in your home directory. Anytime you want to setup a new cloud or simply check on this one, all you have to do is type:
|
90
|
+
|
91
|
+
source ~/.<keypair_name>_pool_keys
|
92
|
+
|
93
|
+
and your'll be ready to switch over to editing the new cloud.
|
94
|
+
|
95
|
+
Using:
|
96
|
+
When it's easy to maintain a cloud, it's even easier to use.
|
97
|
+
|
98
|
+
There are two binaries included with PoolParty when you install them. Working with the cloud, you can use the binary: pool. Working with the instance, you can use the binary: instance.
|
99
|
+
|
100
|
+
Start your pool by typing:
|
101
|
+
|
102
|
+
pool start
|
103
|
+
|
104
|
+
It may take a minute. PoolParty is starting your cloud and configuring the master at this point. You may be asked to confirm an ssh connection. This only happens the first time so other pool commands won't ask you again.
|
105
|
+
|
106
|
+
To check on your cloud, simply type:
|
107
|
+
|
108
|
+
pool list
|
109
|
+
|
110
|
+
and you will be presented with the list of your cloud and their roles
|
111
|
+
|
112
|
+
If you want to stop the pool, it's as straightforward as:
|
113
|
+
|
114
|
+
pool stop
|
115
|
+
|
116
|
+
There are a other commands you have available to you on the pool site. If you are hosting your master off-site, rather than on EC2, you can type on the master machine:
|
117
|
+
|
118
|
+
pool maintain
|
119
|
+
|
120
|
+
and it will bootup as the master, watching the other instances in the cloud.
|
121
|
+
|
122
|
+
If you want to log into a specific instance, you can do so with the command:
|
123
|
+
|
124
|
+
instance ssh -i num
|
125
|
+
|
126
|
+
The num is the number in the list from: pool list. It defaults to logging into the master if the number is not supplied.
|
127
|
+
|
128
|
+
You have some more options when working with instances. You can
|
129
|
+
|
130
|
+
instance ssh
|
131
|
+
instance scp src='' dest=''
|
132
|
+
instance cmd cmd='ls -la'
|
133
|
+
instance start|stop|install|restart
|
134
|
+
instance start_maintain
|
135
|
+
|
136
|
+
The last command will force the instance to become the new master.
|
137
|
+
|
138
|
+
Those are the basics of PoolParty.
|
139
|
+
|
140
|
+
You can check it out at http://poolpartyrb.com/.
|
141
|
+
|
142
|
+
If you are interested in active development, check out the source at github at http://github.com/auser/pool-party/tree/master. Active discussion is held here: http://groups.google.com/group/poolpartyrb. Of course, the latest and greatest information will always be released first at http://blog.citrusbyte.com.
|
data/poolparty.gemspec
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
|
2
|
+
# Gem::Specification for Poolparty-0.0.8
|
3
|
+
# Originally generated by Echoe
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = %q{poolparty}
|
7
|
+
s.version = "0.0.8"
|
8
|
+
|
9
|
+
s.specification_version = 2 if s.respond_to? :specification_version=
|
10
|
+
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.authors = ["Ari Lerner"]
|
13
|
+
s.date = %q{2008-06-20}
|
14
|
+
s.description = %q{Run your entire application off EC2, managed and auto-scaling}
|
15
|
+
s.email = %q{ari.lerner@citrusbyte.com}
|
16
|
+
s.executables = ["instance", "pool"]
|
17
|
+
s.extra_rdoc_files = ["bin/instance", "bin/pool", "CHANGELOG", "lib/core/array.rb", "lib/core/exception.rb", "lib/core/float.rb", "lib/core/hash.rb", "lib/core/kernel.rb", "lib/core/module.rb", "lib/core/object.rb", "lib/core/proc.rb", "lib/core/string.rb", "lib/core/time.rb", "lib/modules/callback.rb", "lib/modules/ec2_wrapper.rb", "lib/modules/safe_instance.rb", "lib/modules/vlad_override.rb", "lib/poolparty/application.rb", "lib/poolparty/init.rb", "lib/poolparty/master.rb", "lib/poolparty/monitors/cpu.rb", "lib/poolparty/monitors/memory.rb", "lib/poolparty/monitors/web.rb", "lib/poolparty/monitors.rb", "lib/poolparty/optioner.rb", "lib/poolparty/plugin.rb", "lib/poolparty/plugin_manager.rb", "lib/poolparty/provider/packages/essential.rb", "lib/poolparty/provider/packages/git.rb", "lib/poolparty/provider/packages/haproxy.rb", "lib/poolparty/provider/packages/heartbeat.rb", "lib/poolparty/provider/packages/monit.rb", "lib/poolparty/provider/packages/rsync.rb", "lib/poolparty/provider/packages/ruby.rb", "lib/poolparty/provider/packages/s3fuse.rb", "lib/poolparty/provider/provider.rb", "lib/poolparty/provider.rb", "lib/poolparty/remote_instance.rb", "lib/poolparty/remoter.rb", "lib/poolparty/remoting.rb", "lib/poolparty/scheduler.rb", "lib/poolparty/tasks/cloud.rake", "lib/poolparty/tasks/development.rake", "lib/poolparty/tasks/ec2.rake", "lib/poolparty/tasks/instance.rake", "lib/poolparty/tasks/plugins.rake", "lib/poolparty/tasks/server.rake", "lib/poolparty/tasks.rb", "lib/poolparty/tmp.rb", "lib/poolparty.rb", "lib/s3/s3_object_store_folders.rb", "README.txt"]
|
18
|
+
s.files = ["archives/ruby-1.8.6-p111.tar.gz", "bin/instance", "bin/pool", "CHANGELOG", "config/cloud_master_takeover", "config/create_proxy_ami.sh", "config/haproxy.conf", "config/heartbeat.conf", "config/heartbeat_authkeys.conf", "config/installers/ubuntu_install.sh", "config/monit/haproxy.monit.conf", "config/monit/nginx.monit.conf", "config/monit.conf", "config/nginx.conf", "config/reconfigure_instances_script.sh", "config/sample-config.yml", "config/scp_instances_script.sh", "lib/core/array.rb", "lib/core/exception.rb", "lib/core/float.rb", "lib/core/hash.rb", "lib/core/kernel.rb", "lib/core/module.rb", "lib/core/object.rb", "lib/core/proc.rb", "lib/core/string.rb", "lib/core/time.rb", "lib/modules/callback.rb", "lib/modules/ec2_wrapper.rb", "lib/modules/safe_instance.rb", "lib/modules/vlad_override.rb", "lib/poolparty/application.rb", "lib/poolparty/init.rb", "lib/poolparty/master.rb", "lib/poolparty/monitors/cpu.rb", "lib/poolparty/monitors/memory.rb", "lib/poolparty/monitors/web.rb", "lib/poolparty/monitors.rb", "lib/poolparty/optioner.rb", "lib/poolparty/plugin.rb", "lib/poolparty/plugin_manager.rb", "lib/poolparty/provider/packages/essential.rb", "lib/poolparty/provider/packages/git.rb", "lib/poolparty/provider/packages/haproxy.rb", "lib/poolparty/provider/packages/heartbeat.rb", "lib/poolparty/provider/packages/monit.rb", "lib/poolparty/provider/packages/rsync.rb", "lib/poolparty/provider/packages/ruby.rb", "lib/poolparty/provider/packages/s3fuse.rb", "lib/poolparty/provider/provider.rb", "lib/poolparty/provider.rb", "lib/poolparty/remote_instance.rb", "lib/poolparty/remoter.rb", "lib/poolparty/remoting.rb", "lib/poolparty/scheduler.rb", "lib/poolparty/tasks/cloud.rake", "lib/poolparty/tasks/development.rake", "lib/poolparty/tasks/ec2.rake", "lib/poolparty/tasks/instance.rake", "lib/poolparty/tasks/plugins.rake", "lib/poolparty/tasks/server.rake", "lib/poolparty/tasks.rb", "lib/poolparty/tmp.rb", "lib/poolparty.rb", "lib/s3/s3_object_store_folders.rb", "Manifest", "misc/basics_tutorial.txt", "Rakefile", "README.txt", "spec/application_spec.rb", "spec/callback_spec.rb", "spec/core_spec.rb", "spec/helpers/ec2_mock.rb", "spec/kernel_spec.rb", "spec/master_spec.rb", "spec/monitors/cpu_monitor_spec.rb", "spec/monitors/memory_spec.rb", "spec/monitors/misc_monitor_spec.rb", "spec/monitors/web_spec.rb", "spec/optioner_spec.rb", "spec/plugin_manager_spec.rb", "spec/plugin_spec.rb", "spec/pool_binary_spec.rb", "spec/poolparty_spec.rb", "spec/provider_spec.rb", "spec/remote_instance_spec.rb", "spec/remoter_spec.rb", "spec/remoting_spec.rb", "spec/scheduler_spec.rb", "spec/spec_helper.rb", "spec/string_spec.rb", "tmp/node0-pool-party-ha.cf", "tmp/node0-pool-party-haresources", "tmp/node0-pool-party-hosts", "tmp/node1-pool-party-ha.cf", "tmp/node1-pool-party-haresources", "tmp/node1-pool-party-hosts", "tmp/pool-party-haproxy.cfg", "web/static/conf/nginx.conf", "web/static/site/images/balloon.png", "web/static/site/images/cb.png", "web/static/site/images/clouds.png", "web/static/site/images/railsconf_preso_img.png", "web/static/site/index.html", "web/static/site/javascripts/application.js", "web/static/site/javascripts/corner.js", "web/static/site/javascripts/jquery-1.2.6.pack.js", "web/static/site/misc.html", "web/static/site/storage/pool_party_presentation.pdf", "web/static/site/stylesheets/application.css", "web/static/site/stylesheets/reset.css", "web/static/src/layouts/application.haml", "web/static/src/pages/index.haml", "web/static/src/pages/misc.haml", "web/static/src/stylesheets/application.sass", "poolparty.gemspec"]
|
19
|
+
s.has_rdoc = true
|
20
|
+
s.homepage = %q{http://blog.citrusbyte.com}
|
21
|
+
s.post_install_message = %q{ Thanks for installing PoolParty!
|
22
|
+
|
23
|
+
Please check out the documentation for any questions or check out the google groups at
|
24
|
+
http://groups.google.com/group/poolpartyrb
|
25
|
+
|
26
|
+
Don't forget to check out the plugins for extending PoolParty!
|
27
|
+
|
28
|
+
For more information, check http://poolpartyrb.com
|
29
|
+
*** Ari Lerner @ <ari.lerner@citrusbyte.com> ***
|
30
|
+
}
|
31
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Poolparty", "--main", "README.txt"]
|
32
|
+
s.require_paths = ["lib"]
|
33
|
+
s.rubyforge_project = %q{poolparty}
|
34
|
+
s.rubygems_version = %q{1.1.1}
|
35
|
+
s.summary = %q{Run your entire application off EC2, managed and auto-scaling}
|
36
|
+
|
37
|
+
s.add_dependency(%q<aws-s3>, [">= 0"])
|
38
|
+
s.add_dependency(%q<amazon-ec2>, [">= 0"])
|
39
|
+
s.add_dependency(%q<aska>, [">= 0"])
|
40
|
+
s.add_dependency(%q<git>, [">= 0"])
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
# # Original Rakefile source (requires the Echoe gem):
|
45
|
+
#
|
46
|
+
# require 'rubygems'
|
47
|
+
# require 'echoe'
|
48
|
+
# require 'lib/poolparty'
|
49
|
+
#
|
50
|
+
# task :default => :test
|
51
|
+
#
|
52
|
+
# Echoe.new("poolparty") do |p|
|
53
|
+
# p.author = "Ari Lerner"
|
54
|
+
# p.email = "ari.lerner@citrusbyte.com"
|
55
|
+
# p.summary = "Run your entire application off EC2, managed and auto-scaling"
|
56
|
+
# p.url = "http://blog.citrusbyte.com"
|
57
|
+
# p.dependencies = %w(aws-s3 amazon-ec2 aska git)
|
58
|
+
# p.install_message =<<-EOM
|
59
|
+
# Thanks for installing PoolParty!
|
60
|
+
#
|
61
|
+
# Please check out the documentation for any questions or check out the google groups at
|
62
|
+
# http://groups.google.com/group/poolpartyrb
|
63
|
+
#
|
64
|
+
# Don't forget to check out the plugins for extending PoolParty!
|
65
|
+
#
|
66
|
+
# For more information, check http://poolpartyrb.com
|
67
|
+
# *** Ari Lerner @ <ari.lerner@citrusbyte.com> ***
|
68
|
+
# EOM
|
69
|
+
# p.include_rakefile = true
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# PoolParty.include_tasks
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe "Application" do
|
4
|
+
it "should be able to send options in the Application.options" do
|
5
|
+
options({:optparse => {:banner => "hi"}})
|
6
|
+
end
|
7
|
+
it "should have the root_dir defined" do
|
8
|
+
PoolParty.root_dir.should_not be_nil
|
9
|
+
end
|
10
|
+
it "should be able to call on the haproxy_config_file" do
|
11
|
+
Application.haproxy_config_file.should_not be_nil
|
12
|
+
end
|
13
|
+
it "should be able to find the client_port" do
|
14
|
+
Application.options.should_receive(:client_port).and_return(7788)
|
15
|
+
Application.client_port.should == 7788
|
16
|
+
end
|
17
|
+
it "should always have cloud_master_takeover in the managed services list" do
|
18
|
+
Application.master_managed_services.should =~ /cloud_master_takeover/
|
19
|
+
end
|
20
|
+
it "should be able to say it is in development mode if it is in dev mode" do
|
21
|
+
Application.stub!(:environment).and_return("development")
|
22
|
+
Application.development?.should == true
|
23
|
+
end
|
24
|
+
it "should be able to say it is in production if it is in production" do
|
25
|
+
Application.stub!(:environment).and_return("production")
|
26
|
+
Application.production?.should == true
|
27
|
+
end
|
28
|
+
it "should be able to say it's keypair path is in the $HOME/ directory" do
|
29
|
+
Application.stub!(:ec2_dir).and_return("~/.ec2")
|
30
|
+
Application.stub!(:keypair).and_return("poolparty")
|
31
|
+
Application.keypair_path.should == "~/.ec2/id_rsa-poolparty"
|
32
|
+
end
|
33
|
+
it "should be able to show the version of the gem" do
|
34
|
+
Application.version.should_not be_nil
|
35
|
+
end
|
36
|
+
it "should show the version as a string" do
|
37
|
+
Application.version.class.should == String
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
class TestCallbacks
|
4
|
+
include Callbacks
|
5
|
+
attr_reader :str
|
6
|
+
|
7
|
+
before :world, :hello
|
8
|
+
after :world, :thanks
|
9
|
+
|
10
|
+
def hello(caller)
|
11
|
+
string << "hello "
|
12
|
+
end
|
13
|
+
def world
|
14
|
+
string << "world"
|
15
|
+
end
|
16
|
+
def thanks(caller)
|
17
|
+
string << ", thank you"
|
18
|
+
end
|
19
|
+
after :pop, :boom
|
20
|
+
def pop
|
21
|
+
string << "pop"
|
22
|
+
end
|
23
|
+
def boom(caller)
|
24
|
+
string << " goes boom"
|
25
|
+
end
|
26
|
+
def string
|
27
|
+
@str ||= String.new
|
28
|
+
end
|
29
|
+
end
|
30
|
+
describe "Callbacks" do
|
31
|
+
before(:each) do
|
32
|
+
@klass = TestCallbacks.new
|
33
|
+
end
|
34
|
+
it "should retain it's class identifier" do
|
35
|
+
@klass.class.should == TestCallbacks
|
36
|
+
end
|
37
|
+
it "should callback the method before the method runs" do
|
38
|
+
@klass.world.should == "hello world, thank you"
|
39
|
+
end
|
40
|
+
it "should callback the method before the method runs" do
|
41
|
+
@klass.pop.should == "pop goes boom"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
class TestMultipleCallbacks
|
45
|
+
include Callbacks
|
46
|
+
attr_reader :str
|
47
|
+
def hi(caller)
|
48
|
+
string << "hi, "
|
49
|
+
end
|
50
|
+
def hello(caller)
|
51
|
+
string << "hello "
|
52
|
+
end
|
53
|
+
def world
|
54
|
+
string << "world"
|
55
|
+
end
|
56
|
+
def string
|
57
|
+
@str ||= String.new
|
58
|
+
end
|
59
|
+
before :world, :hi, :hello
|
60
|
+
end
|
61
|
+
describe "Multiple callbacks" do
|
62
|
+
before(:each) do
|
63
|
+
@klass = TestMultipleCallbacks.new
|
64
|
+
end
|
65
|
+
it "should be able to have multiple callbacks on the same call" do
|
66
|
+
@klass.world.should == "hi, hello world"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
class OutsideClass
|
70
|
+
def self.hello(caller)
|
71
|
+
puts "hello"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
class TestOutsideClass
|
75
|
+
include Callbacks
|
76
|
+
before :world, {:hello => OutsideClass}
|
77
|
+
def world
|
78
|
+
"world"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
describe "Options" do
|
82
|
+
before(:each) do
|
83
|
+
@c = TestOutsideClass.new
|
84
|
+
end
|
85
|
+
it "should be able to pass external class options to the callback" do
|
86
|
+
OutsideClass.should_receive(:hello).and_return "hello"
|
87
|
+
@c.world
|
88
|
+
end
|
89
|
+
end
|
90
|
+
class BlockClass
|
91
|
+
include Callbacks
|
92
|
+
before :world do
|
93
|
+
string << "hello "
|
94
|
+
end
|
95
|
+
def world
|
96
|
+
string << "world"
|
97
|
+
end
|
98
|
+
def string
|
99
|
+
@string ||= ""
|
100
|
+
end
|
101
|
+
end
|
102
|
+
describe "Block callbacks" do
|
103
|
+
it "should call the block on the callback" do
|
104
|
+
BlockClass.new.world.should == "hello world"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
class BlockAndMethodClass
|
108
|
+
include Callbacks
|
109
|
+
before :world, :hi do
|
110
|
+
string << "hello "
|
111
|
+
end
|
112
|
+
def world
|
113
|
+
string << "world"
|
114
|
+
end
|
115
|
+
def hi(caller)
|
116
|
+
string << "hi, "
|
117
|
+
end
|
118
|
+
def string
|
119
|
+
@string ||= ""
|
120
|
+
end
|
121
|
+
end
|
122
|
+
describe "Block and method callbacks" do
|
123
|
+
it "should call the block on the callback and add the block" do
|
124
|
+
BlockAndMethodClass.new.world.should == "hi, hello world"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
class ExternalMethodCallClass
|
128
|
+
include Callbacks
|
129
|
+
before :world, :hello
|
130
|
+
after :hello, :peter
|
131
|
+
|
132
|
+
def world
|
133
|
+
string << "world"
|
134
|
+
end
|
135
|
+
def hello(caller)
|
136
|
+
string << "hello "
|
137
|
+
end
|
138
|
+
def peter(caller)
|
139
|
+
string << "peter "
|
140
|
+
end
|
141
|
+
def string
|
142
|
+
@string ||= ""
|
143
|
+
end
|
144
|
+
end
|
145
|
+
describe "External method callbacks inside a method" do
|
146
|
+
it "should call the block on the callback and add the " do
|
147
|
+
ExternalMethodCallClass.new.world.should == "hello peter world"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
class OutsideBindingClass
|
151
|
+
def hello(caller)
|
152
|
+
caller.string << "hello"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
class BindingClass
|
156
|
+
include Callbacks
|
157
|
+
before :world, :hello => "OutsideBindingClass"
|
158
|
+
def world
|
159
|
+
string << "#{@hello} world"
|
160
|
+
end
|
161
|
+
def string
|
162
|
+
@string ||= ""
|
163
|
+
end
|
164
|
+
end
|
165
|
+
describe "Methods" do
|
166
|
+
it "should have access to the local variables of the call" do
|
167
|
+
BindingClass.new.world.should == "hello world"
|
168
|
+
end
|
169
|
+
end
|
170
|
+
class EvilOutsideClass
|
171
|
+
attr_reader :name
|
172
|
+
def get_name(caller)
|
173
|
+
@name = caller.hello
|
174
|
+
end
|
175
|
+
def show_name(caller)
|
176
|
+
@name
|
177
|
+
end
|
178
|
+
end
|
179
|
+
class BindingClass
|
180
|
+
include Callbacks
|
181
|
+
before :print, :get_name => "EvilOutsideClass"
|
182
|
+
def print
|
183
|
+
"hello"
|
184
|
+
end
|
185
|
+
def hello
|
186
|
+
"franke"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
describe "Variables on the plugin callbacker class" do
|
190
|
+
it "should have a new method of the class" do
|
191
|
+
BindingClass.new.print
|
192
|
+
BindingClass.new.methods.include?("eviloutsideclass").should == true
|
193
|
+
end
|
194
|
+
end
|
data/spec/core_spec.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe "Hash" do
|
4
|
+
it "should preserve the contents of the original hash when safe_merge'ing" do
|
5
|
+
a = {:a => "10", :b => "20"}
|
6
|
+
b = {:b => "30", :c => "40"}
|
7
|
+
a.safe_merge(b).should == {:a => "10", :b => "20", :c => "40"}
|
8
|
+
end
|
9
|
+
it "should preserve the contents of the original hash when safe_merge!'ing" do
|
10
|
+
a = {:a => "10", :b => "20"}
|
11
|
+
b = {:b => "30", :c => "40"}
|
12
|
+
a.safe_merge!(b)
|
13
|
+
a.should == {:a => "10", :b => "20", :c => "40"}
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module PoolParty
|
2
|
+
class Master
|
3
|
+
def launch_new_instance!
|
4
|
+
letter = ("a".."z").to_a[instances.size] # For unique instance_ids
|
5
|
+
h = {:instance_id => "i-58ba56#{letter}", :ip => "ip-127-0-0-1.aws.amazonaws.com", :status => "pending", :launching_time => Time.now }
|
6
|
+
instances << h
|
7
|
+
Thread.new {wait 0.1;h[:status] = "running"} # Simulate the startup time
|
8
|
+
return h
|
9
|
+
end
|
10
|
+
# Shutdown the instance by instance_id
|
11
|
+
def terminate_instance!(instance_id)
|
12
|
+
instances.select {|a| a[:instance_id] == instance_id}[0][:status] = "terminating"
|
13
|
+
end
|
14
|
+
# Instance description
|
15
|
+
def describe_instance(id)
|
16
|
+
item = instances.select {|a| a[:instance_id] == id}[0]
|
17
|
+
EC2ResponseObject.get_hash_from_response(item)
|
18
|
+
end
|
19
|
+
# Get instance by id
|
20
|
+
def get_instance_by_id(id)
|
21
|
+
get_instances_description.select {|a| a.instance_id == id}[0] rescue nil
|
22
|
+
end
|
23
|
+
# Get the s3 description for the response in a hash format
|
24
|
+
def get_instances_description
|
25
|
+
instances
|
26
|
+
end
|
27
|
+
# Fake the ec2 connection
|
28
|
+
def ec2
|
29
|
+
@ec2 ||= EC2::Base.new(:access_key_id => "not a key", :secret_access_key => "not a key")
|
30
|
+
end
|
31
|
+
# Some basic instances, not totally necessary
|
32
|
+
def instances
|
33
|
+
@instances ||= []
|
34
|
+
end
|
35
|
+
end
|
36
|
+
class RemoteInstance
|
37
|
+
def ssh(l="")
|
38
|
+
"true"
|
39
|
+
end
|
40
|
+
def scp(s,d,o={})
|
41
|
+
"true"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/spec/kernel_spec.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe "Kernel extensions" do
|
4
|
+
before(:each) do
|
5
|
+
@host = Master.new
|
6
|
+
end
|
7
|
+
it "should eval the string into time" do
|
8
|
+
@host.should_receive(:sleep).once.and_return true
|
9
|
+
@host.wait "10.seconds"
|
10
|
+
end
|
11
|
+
end
|