auser-poolparty 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/CHANGELOG +1 -0
  2. data/LICENSE +22 -0
  3. data/{README.txt → README} +1 -0
  4. data/Rakefile +3 -2
  5. data/lib/helpers/plugin_spec_helper.rb +1 -1
  6. data/lib/modules/ec2_wrapper.rb +5 -6
  7. data/lib/poolparty.rb +2 -2
  8. data/lib/poolparty/application.rb +9 -11
  9. data/lib/poolparty/init.rb +1 -1
  10. data/lib/poolparty/master.rb +8 -1
  11. data/lib/poolparty/provider.rb +27 -9
  12. data/lib/poolparty/provider/git.rb +4 -0
  13. data/lib/poolparty/provider/haproxy.rb +4 -0
  14. data/lib/poolparty/provider/heartbeat.rb +3 -1
  15. data/lib/poolparty/provider/rsync.rb +4 -0
  16. data/lib/poolparty/provider/ruby.rb +46 -9
  17. data/lib/poolparty/provider/s3fuse.rb +4 -0
  18. data/lib/poolparty/remote_instance.rb +14 -2
  19. data/lib/poolparty/tasks/development.rake +17 -12
  20. data/poolparty.gemspec +11 -10
  21. data/spec/helpers/ec2_mock.rb +7 -0
  22. data/spec/lib/{core_spec.rb → core/core_spec.rb} +1 -1
  23. data/spec/lib/{kernel_spec.rb → core/kernel_spec.rb} +1 -1
  24. data/spec/lib/{string_spec.rb → core/string_spec.rb} +1 -1
  25. data/spec/lib/{callback_spec.rb → modules/callback_spec.rb} +1 -1
  26. data/spec/lib/{file_writer_spec.rb → modules/file_writer_spec.rb} +1 -1
  27. data/spec/lib/{application_spec.rb → poolparty/application_spec.rb} +21 -5
  28. data/spec/lib/{ec2_wrapper_spec.rb → poolparty/ec2_wrapper_spec.rb} +26 -3
  29. data/spec/lib/{master_spec.rb → poolparty/master_spec.rb} +55 -55
  30. data/spec/lib/{optioner_spec.rb → poolparty/optioner_spec.rb} +1 -1
  31. data/spec/lib/{plugin_spec.rb → poolparty/plugin_spec.rb} +2 -2
  32. data/spec/lib/{poolparty_spec.rb → poolparty/poolparty_spec.rb} +1 -1
  33. data/spec/lib/poolparty/provider_spec.rb +74 -0
  34. data/spec/lib/{remote_instance_spec.rb → poolparty/remote_instance_spec.rb} +2 -2
  35. data/spec/lib/{remoter_spec.rb → poolparty/remoter_spec.rb} +2 -2
  36. data/spec/lib/{remoting_spec.rb → poolparty/remoting_spec.rb} +2 -2
  37. data/spec/lib/{scheduler_spec.rb → poolparty/scheduler_spec.rb} +1 -1
  38. data/spec/spec_helper.rb +11 -0
  39. metadata +30 -27
  40. data/lib/poolparty/plugin_manager.rb +0 -67
  41. data/spec/lib/plugin_manager_spec.rb +0 -23
  42. data/spec/lib/pool_binary_spec.rb +0 -13
  43. data/spec/lib/provider_spec.rb +0 -72
data/CHANGELOG CHANGED
@@ -1,3 +1,4 @@
1
+ v0.1.2 * Added development tasks for easy setup
1
2
  v0.1.1 * Updated Scheduler to include ThreadPool for threaded safety
2
3
  v0.1.0 * Added poolnotify
3
4
  * Updating gem on github
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2008 <Ari Lerner>
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -102,6 +102,7 @@ For more help, check http://poolpartyrb.com
102
102
 
103
103
  == ROADMAP
104
104
 
105
+ v0.1.4 - Add documentation
105
106
  v0.1.5 - Add AMI bundling tasks
106
107
 
107
108
  == THANKS
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ begin
10
10
  s.email = "ari.lerner@citrusbyte.com"
11
11
  s.summary = "Run your entire application off EC2, managed and auto-scaling"
12
12
  s.url = "http://poolpartyrb.com"
13
- s.dependencies = ["aws-s3", "amazon-ec2", "auser-aska", "git", "crafterm-sprinkle", "SystemTimer", "open4"]
13
+ s.dependencies = ["aws-s3", "amazon-ec2", "auser-aska", "git", "sprinkle", "SystemTimer", "open4"]
14
14
  s.install_message = %q{
15
15
 
16
16
  Get ready to jump in the pool, you just installed PoolParty!
@@ -22,7 +22,8 @@ begin
22
22
 
23
23
  For more information, check http://poolpartyrb.com
24
24
  On IRC:
25
- irc.freenode.net / #poolpartyrb
25
+ irc.freenode.net
26
+ #poolpartyrb
26
27
 
27
28
  *** Ari Lerner @ <ari.lerner@citrusbyte.com> ***
28
29
  }
@@ -1,7 +1,7 @@
1
1
  module PoolParty
2
2
  class PluginSpecHelper
3
3
  def self.define_stubs(klass, num=1)
4
- require File.dirname(__FILE__) + "/../../spec/helpers/ec2_mock"
4
+ require File.dirname(__FILE__) + '/../../spec/helpers/ec2_mock'
5
5
 
6
6
  @klass = klass.send :new
7
7
  klass.stub!(:new).and_return @klass
@@ -14,7 +14,8 @@ module PoolParty
14
14
  :user_data => "#{Application.launching_user_data}",
15
15
  :minCount => 1,
16
16
  :maxCount => 1,
17
- :key_name => Application.keypair,
17
+ :key_name => "#{Application.keypair}",
18
+ :availability_zone => nil,
18
19
  :size => "#{Application.size}")
19
20
  begin
20
21
  item = instance#.instancesSet.item
@@ -31,8 +32,6 @@ module PoolParty
31
32
  end
32
33
  # Instance description
33
34
  def describe_instance(id)
34
- # instance = ec2.describe_instances(:instance_id => id)
35
- # item = instance.reservationSet.item.first.instancesSet.item.first
36
35
  EC2ResponseObject.get_hash_from_response(ec2.describe_instances(:instance_id => id))
37
36
  end
38
37
  # Get instance by id
@@ -43,12 +42,12 @@ module PoolParty
43
42
  def get_instances_description
44
43
  @cached_descriptions ||= EC2ResponseObject.get_descriptions(ec2.describe_instances)
45
44
  end
46
- def reset!
47
- @cached_descriptions = nil
48
- end
49
45
  # EC2 connections
50
46
  def ec2
51
47
  @ec2 ||= EC2::Base.new(:access_key_id => Application.access_key, :secret_access_key => Application.secret_access_key)
48
+ end
49
+ def reset!
50
+ @cached_descriptions = nil
52
51
  end
53
52
  end
54
53
 
@@ -13,7 +13,7 @@ require "aska"
13
13
  begin
14
14
  require 'crafterm-sprinkle'
15
15
  rescue LoadError
16
- require "sprinkle"
16
+ require 'sprinkle'
17
17
  end
18
18
  require "pp"
19
19
  require "tempfile"
@@ -48,7 +48,7 @@ module PoolParty
48
48
  class Version #:nodoc:
49
49
  @major = 0
50
50
  @minor = 1
51
- @tiny = 1
51
+ @tiny = 2
52
52
 
53
53
  def self.string
54
54
  [@major, @minor, @tiny].join('.')
@@ -105,8 +105,8 @@ module PoolParty
105
105
  nil
106
106
  end,
107
107
  :username => "root",
108
- :ec2_dir => ENV["EC2_HOME"],
109
- :keypair => (ENV["KEYPAIR_NAME"].nil? || ENV["KEYPAIR_NAME"].empty?) ? File.basename(`pwd`).strip : ENV["KEYPAIR_NAME"].empty?,
108
+ :ec2_dir => (ENV["EC2_HOME"].nil? || ENV["EC2_HOME"].empty?) ? "~/.ec2" : ENV["EC2_HOME"],
109
+ :keypair => (ENV["KEYPAIR_NAME"].nil? || ENV["KEYPAIR_NAME"].empty?) ? File.basename(`pwd`).strip : ENV["KEYPAIR_NAME"],
110
110
  :ami => 'ami-44bd592d',
111
111
  :shared_bucket => "",
112
112
  :expand_when => "web < 1.5\n memory > 0.85",
@@ -130,20 +130,18 @@ module PoolParty
130
130
  :access_key => access_key,
131
131
  :secret_access_key => secret_access_key,
132
132
  :user_data => user_data,
133
+ :keypair => keypair,
133
134
  :keypair_path => "/mnt"
134
135
  }
135
136
  end
136
137
  def local_user_data
137
- unless @local_user_data
138
- begin
139
- @@timer.timeout(3.seconds) do
140
- @local_user_data ||=YAML.load(open("http://169.254.169.254/latest/user-data").read)
141
- end
142
- rescue Exception => e
143
- @local_user_data = {}
144
- end
138
+ @local_user_data ||= begin
139
+ @@timer.timeout(2.seconds) do
140
+ YAML.load(open("http://169.254.169.254/latest/user-data").read)
141
+ end
142
+ rescue Exception => e
143
+ {}
145
144
  end
146
- @local_user_data
147
145
  end
148
146
  # For testing purposes
149
147
  def reset!
@@ -1,6 +1,6 @@
1
1
  =begin rdoc
2
2
  Load the files in order
3
3
  =end
4
- %w(optioner application thread_pool scheduler provider remoter remoting remote_instance master monitors tasks plugin plugin_manager).each do |f|
4
+ %w(optioner application thread_pool scheduler provider remoter remoting remote_instance master monitors tasks plugin).each do |f|
5
5
  require File.join(File.dirname(__FILE__), f)
6
6
  end
@@ -188,7 +188,7 @@ module PoolParty
188
188
  end
189
189
 
190
190
  File.copy(Application.config_file, "#{base_tmp_dir}/config.yml") if Application.config_file && File.exists?(Application.config_file)
191
- File.copy(Application.keypair_path, "#{base_tmp_dir}/keypair") if File.exists?(Application.keypair_path)
191
+ File.copy(Application.keypair_path, "#{base_tmp_dir}/keypair") if File.exists?(Application.keypair_path)
192
192
 
193
193
  copy_pem_files_to_tmp_dir
194
194
 
@@ -197,6 +197,8 @@ module PoolParty
197
197
 
198
198
  build_haproxy_file
199
199
  Master.build_user_global_files
200
+
201
+ build_nodes_list
200
202
 
201
203
  Master.with_nodes do |node|
202
204
  build_hosts_file_for(node)
@@ -283,6 +285,11 @@ chmod +x #{script_file}
283
285
  "#{nodes.collect {|node| node.ip == n.ip ? node.local_hosts_entry : node.hosts_entry}.join("\n")}"
284
286
  end
285
287
  end
288
+ def build_nodes_list
289
+ write_to_file_for(RemoteInstance.node_list_name) do
290
+ "#{cloud_ips.join("\n")}"
291
+ end
292
+ end
286
293
  # Build the basic auth file for the heartbeat
287
294
  def build_and_copy_heartbeat_authkeys_file
288
295
  write_to_file_for("authkeys") do
@@ -2,13 +2,12 @@ module PoolParty
2
2
  class Provider
3
3
  include Sprinkle
4
4
 
5
- def install_poolparty
5
+ def install_poolparty(testing=false)
6
6
  PoolParty.message "Installing required poolparty paraphernalia"
7
7
  load_packages
8
8
  user_packages.map {|blk| blk.call if blk }
9
9
 
10
10
  policy :poolparty, :roles => :app do
11
- requires :git
12
11
  requires :ruby
13
12
  requires :heartbeat
14
13
  requires :haproxy
@@ -17,17 +16,16 @@ module PoolParty
17
16
  requires :required_gems
18
17
 
19
18
  PoolParty::Provider.user_install_packages.each do |req|
20
- requires req.to_sym
19
+ self.send :requires, req.to_sym
21
20
  end
22
21
  end
23
22
 
24
- set_start_with_sprinkle
25
- @deployment.process if @deployment
23
+ testing ? show_process : process
26
24
  end
27
25
 
28
26
  def self.define_custom_package name=:userpackages, &block
29
27
  (user_install_packages << name).uniq!
30
- user_packages << block
28
+ user_packages << yield if block_given?
31
29
  end
32
30
 
33
31
  def user_packages
@@ -66,16 +64,36 @@ module PoolParty
66
64
  prefix '/usr/local'
67
65
  archives '/root/sources'
68
66
  builds '/root/builds'
69
- end
67
+ end
70
68
  end
71
69
 
72
70
  end
71
+
72
+ def process
73
+ set_start_with_sprinkle
74
+ @deployment.process if @deployment
75
+ end
76
+
77
+ def show_process
78
+ Sprinkle::OPTIONS[:testing] = true
79
+ Sprinkle::OPTIONS[:verbose] = true
80
+ Object.logger.level = ActiveSupport::BufferedLogger::Severity::DEBUG
81
+ deployment do
82
+ delivery :vlad do
83
+ end
84
+ source do
85
+ prefix '/usr/local'
86
+ archives '/root/sources'
87
+ builds '/root/builds'
88
+ end
89
+ end.process
90
+ end
73
91
 
74
92
  class << self
75
93
  require "sprinkle"
76
94
 
77
- def install_poolparty
78
- singleton.install_poolparty
95
+ def install_poolparty(testing=false)
96
+ singleton.install_poolparty(testing)
79
97
  end
80
98
  def singleton
81
99
  @singleton ||= new
@@ -1,4 +1,8 @@
1
1
  package :git do
2
2
  description "Git SCM"
3
3
  apt %w( zlib1g-dev git-core )
4
+
5
+ verify do
6
+ has_executable 'git'
7
+ end
4
8
  end
@@ -2,4 +2,8 @@
2
2
  package :haproxy, :provides => :proxy do
3
3
  description 'Haproxy proxy'
4
4
  apt %w( haproxy )
5
+
6
+ verify do
7
+ has_executable 'haproxy'
8
+ end
5
9
  end
@@ -1,4 +1,6 @@
1
1
  package :heartbeat, :provides => :failover do
2
2
  description "Heartbeat Linux HA project"
3
- apt %w( heartbeat-2 )
3
+ apt %w( heartbeat )
4
+
5
+ has_executable 'heartbeat'
4
6
  end
@@ -1,4 +1,8 @@
1
1
  package :rsync do
2
2
  description "Rsync"
3
3
  apt %w( rsync )
4
+
5
+ verify do
6
+ has_executable 'rsync'
7
+ end
4
8
  end
@@ -1,9 +1,11 @@
1
1
  package :ruby do
2
2
  description 'Ruby Virtual Machine'
3
- # version '1.8.6'
4
- # source "ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-#{version}-p111.tar.gz" # implicit :style => :gnu
5
3
  apt %w( ruby ruby1.8-dev )
6
4
  requires :ruby_dependencies
5
+
6
+ verify do
7
+ has_executable 'ruby'
8
+ end
7
9
  end
8
10
 
9
11
  package :ruby_dependencies do
@@ -13,16 +15,51 @@ end
13
15
 
14
16
  package :rubygems do
15
17
  description 'Ruby Gems Package Management System'
16
- # version '1.0.1'
17
- # source "http://rubyforge.org/frs/download.php/29548/rubygems-#{version}.tgz" do
18
- # custom_install 'ruby setup.rb'
19
- # end
20
- apt %w( rubygems )
18
+ version '1.2.0'
19
+ source "http://rubyforge.org/frs/download.php/38646/rubygems-#{version}.tgz" do
20
+ custom_install 'ruby setup.rb'
21
+ end
22
+
21
23
  post :install, "sed -i s/require\ 'rubygems'/require\ 'rubygems'\nrequire\ 'rubygems\/gem_runner'/g", "gem update --system", "gem sources -a http://gems.github.com"
24
+
22
25
  requires :ruby
26
+
27
+ verify do
28
+ has_executable 'gem'
29
+ end
23
30
  end
24
31
 
25
32
  package :required_gems do
26
- description "Pool party gem"
27
- gems %w( SQS aws-s3 amazon-ec2 auser-aska rake rcov auser-poolparty vlad --no-ri --no-rdoc)
33
+ description "Poolparty required gem"
34
+ gem 'auser-poolparty'
35
+ requires :s3
36
+ requires :ec2
37
+ requires :aska
38
+
39
+ has_gem 'auser-poolparty'
40
+ end
41
+
42
+ package :s3 do
43
+ description "Amazon s3"
44
+ gem 'aws-s3'
45
+
46
+ has_gem 'aws-s3'
47
+ end
48
+ package :ec2 do
49
+ description "Amazon EC2"
50
+ gem 'amazon-ec2'
51
+
52
+ has_gem 'amazon-ec2'
53
+ end
54
+ package :aska do
55
+ description "Aska - Expert System"
56
+ gem 'auser-aska'
57
+
58
+ has_gem 'auser-aska'
59
+ end
60
+ package :rake do
61
+ description "Rake"
62
+ gem 'rake'
63
+
64
+ has_gem 'rake'
28
65
  end
@@ -6,6 +6,10 @@ package :s3fs do
6
6
 
7
7
  post :install, "mv s3fs /usr/bin"
8
8
  end
9
+
10
+ verify do
11
+ has_executable 's3fs'
12
+ end
9
13
 
10
14
  requires :s3fs_deps
11
15
  end
@@ -79,7 +79,8 @@ module PoolParty
79
79
  :configure_resource_d => configure_resource_d,
80
80
  :configure_haproxy => setup_haproxy,
81
81
  :configure_heartbeat => configure_heartbeat,
82
- :user_tasks => user_tasks
82
+ :user_tasks => user_tasks,
83
+ :node_list => move_node_list
83
84
  }#.map {|k,v| {k.to_sym => v.nice_runnable(quiet)} }.inject({}) {|a,s| s.merge(a) }
84
85
  end
85
86
  def user_tasks
@@ -166,7 +167,18 @@ module PoolParty
166
167
  mkdir -p /data && /usr/bin/s3fs #{Application.shared_bucket} -o accessKeyId=#{Application.access_key} -o secretAccessKey=#{Application.secret_access_key} -o nonempty /data
167
168
  EOC
168
169
  end
169
- end
170
+ end
171
+ def move_node_list
172
+ <<-EOC
173
+ #{if_exists node_list_name, "mv #{remote_base_tmp_dir}/nodes.lst ~/.#{node_list_name}"}
174
+ EOC
175
+ end
176
+ def node_list_name
177
+ self.class.node_list_name
178
+ end
179
+ def self.node_list_name
180
+ "nodes.lst"
181
+ end
170
182
  # Installs with one commandline and an scp, rather than 10
171
183
  def install
172
184
  end
@@ -1,7 +1,7 @@
1
1
  namespace(:dev) do
2
2
  task :initialize do
3
3
  setup_application
4
- run "mkdir ~/.ec2 >/dev/null 2>/dev/null" unless File.directory?("~/.ec2")
4
+ run "mkdir $HOME/.ec2 >/dev/null 2>/dev/null" unless File.directory?("$HOME/.ec2")
5
5
  end
6
6
  # Setup a basic development environment for the user
7
7
  desc "Setup development environment specify the config_file"
@@ -29,27 +29,26 @@ exiting...
29
29
  puts <<-EOM
30
30
  To work on this cloud, source the file like:
31
31
 
32
- source #{Application.ec2_dir}/#{keyfilename}
32
+ source $HOME/#{keyfilename}
33
33
 
34
34
  EOM
35
35
  end
36
36
  desc "Generate a new keypair"
37
37
  task :setup_keypair => [:initialize] do
38
- unless File.file?(Application.keypair_path)
39
- Application.keypair ||= "cloud"
40
- puts "-- setting up keypair named #{Application.keypair}"
41
- run <<-EOR
42
- chmod 600 #{Application.keypair_path} 2>/dev/null
43
- mkdir ~/.ec2/#{Application.keypair} 2>/dev/null
44
- ec2-add-keypair #{Application.keypair} > #{Application.keypair_path}
45
- EOR
46
- end
38
+ Application.keypair ||= "#{File.basename(Dir.pwd)}"
39
+ run "ec2-delete-keypair #{Application.keypair}" if File.file?(Application.keypair_path)
40
+ puts "-- setting up keypair named #{Application.keypair} in #{Application.keypair_path}"
41
+ run <<-EOR
42
+ chmod 600 #{Application.keypair_path} 2>/dev/null
43
+ mkdir $HOME/.ec2/#{Application.keypair} 2>/dev/null
44
+ ec2-add-keypair #{Application.keypair} > #{Application.keypair_path}
45
+ EOR
47
46
  end
48
47
  desc "Setup pem keys"
49
48
  task :setup_pemkeys => [:initialize] do
50
49
  puts "Setting up stubbed pem keys in ~/.ec2/#{Application.keypair}"
51
50
  run <<-EOR
52
- mkdir -p ~/.ec2/#{Application.keypair} 2>/dev/null
51
+ mkdir -p $HOME/.ec2/#{Application.keypair} 2>/dev/null
53
52
  echo 'UPDATE ME' > #{Application.ec2_dir}/#{Application.keypair}/cert-UPDATEME.pem
54
53
  echo 'UPDATE ME' > #{Application.ec2_dir}/#{Application.keypair}/pk-UPDATEME.pem
55
54
  EOR
@@ -62,6 +61,12 @@ To work on this cloud, source the file like:
62
61
  task :test => :initialize do
63
62
  puts "---- Testing ----"
64
63
  puts PoolParty.options(ARGV.dup)
64
+ puts "Using keypair at: #{Application.keypair_path}"
65
+ end
66
+ desc "Installation listing"
67
+ task :list_install => :initialize do
68
+ puts "-- packages to install --"
69
+ Provider.install_poolparty(true)
65
70
  end
66
71
  desc "Authorize base ports for application"
67
72
  task :authorize_ports => :initialize do