auser-poolparty 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/CHANGELOG +1 -0
  2. data/README.txt +5 -7
  3. data/Rakefile +27 -12
  4. data/bin/instance +2 -2
  5. data/bin/pool +8 -6
  6. data/config/reconfigure_instances_script.sh +3 -3
  7. data/config/sample-config.yml +1 -1
  8. data/lib/core/array.rb +5 -2
  9. data/lib/core/hash.rb +1 -1
  10. data/lib/core/string.rb +6 -2
  11. data/lib/helpers/plugin_spec_helper.rb +4 -5
  12. data/lib/modules/sprinkle_overrides.rb +24 -29
  13. data/lib/poolparty/application.rb +37 -27
  14. data/lib/poolparty/master.rb +35 -14
  15. data/lib/poolparty/plugin.rb +11 -6
  16. data/lib/poolparty/plugin_manager.rb +2 -2
  17. data/lib/poolparty/provider/{packages/essential.rb → essential.rb} +0 -0
  18. data/lib/poolparty/provider/{packages/git.rb → git.rb} +0 -0
  19. data/lib/poolparty/provider/{packages/haproxy.rb → haproxy.rb} +1 -1
  20. data/lib/poolparty/provider/{packages/heartbeat.rb → heartbeat.rb} +0 -0
  21. data/lib/poolparty/provider/{packages/rsync.rb → rsync.rb} +0 -0
  22. data/lib/poolparty/provider/{packages/ruby.rb → ruby.rb} +1 -1
  23. data/lib/poolparty/provider/{packages/s3fuse.rb → s3fuse.rb} +0 -0
  24. data/lib/poolparty/provider.rb +86 -2
  25. data/lib/poolparty/remote_instance.rb +35 -21
  26. data/lib/poolparty/remoter.rb +4 -1
  27. data/lib/poolparty/remoting.rb +2 -1
  28. data/lib/poolparty/tasks/cloud.rake +1 -1
  29. data/lib/poolparty/tasks/development.rake +48 -13
  30. data/lib/poolparty/tasks.rb +24 -6
  31. data/lib/poolparty.rb +8 -4
  32. data/poolparty.gemspec +10 -7
  33. data/spec/helpers/ec2_mock.rb +5 -2
  34. data/spec/{application_spec.rb → lib/application_spec.rb} +42 -9
  35. data/spec/{callback_spec.rb → lib/callback_spec.rb} +1 -1
  36. data/spec/{core_spec.rb → lib/core_spec.rb} +6 -4
  37. data/spec/{ec2_wrapper_spec.rb → lib/ec2_wrapper_spec.rb} +3 -3
  38. data/spec/{file_writer_spec.rb → lib/file_writer_spec.rb} +2 -2
  39. data/spec/{kernel_spec.rb → lib/kernel_spec.rb} +1 -1
  40. data/spec/{master_spec.rb → lib/master_spec.rb} +38 -16
  41. data/spec/{optioner_spec.rb → lib/optioner_spec.rb} +1 -1
  42. data/spec/{plugin_manager_spec.rb → lib/plugin_manager_spec.rb} +3 -3
  43. data/spec/{plugin_spec.rb → lib/plugin_spec.rb} +12 -1
  44. data/spec/{pool_binary_spec.rb → lib/pool_binary_spec.rb} +1 -1
  45. data/spec/{poolparty_spec.rb → lib/poolparty_spec.rb} +5 -5
  46. data/spec/lib/provider_spec.rb +72 -0
  47. data/spec/{remote_instance_spec.rb → lib/remote_instance_spec.rb} +51 -9
  48. data/spec/{remoter_spec.rb → lib/remoter_spec.rb} +7 -2
  49. data/spec/{remoting_spec.rb → lib/remoting_spec.rb} +60 -4
  50. data/spec/{scheduler_spec.rb → lib/scheduler_spec.rb} +1 -1
  51. data/spec/{string_spec.rb → lib/string_spec.rb} +1 -1
  52. data/spec/monitors/cpu_monitor_spec.rb +2 -2
  53. data/spec/monitors/memory_spec.rb +3 -3
  54. data/spec/monitors/misc_monitor_spec.rb +1 -1
  55. data/spec/monitors/web_spec.rb +3 -3
  56. metadata +46 -41
  57. data/lib/poolparty/provider/packages/monit.rb +0 -6
  58. data/lib/poolparty/provider/provider.rb +0 -100
  59. data/spec/provider_spec.rb +0 -18
data/CHANGELOG CHANGED
@@ -1,3 +1,4 @@
1
+ v0.1.1 * Updated Scheduler to include ThreadPool for threaded safety
1
2
  v0.1.0 * Added poolnotify
2
3
  * Updating gem on github
3
4
  v0.0.9 * Changed configuration style to rsync all files across every instance
data/README.txt CHANGED
@@ -93,26 +93,24 @@ For more help, check http://poolpartyrb.com
93
93
  == REQUIREMENTS:
94
94
 
95
95
  * aws/s3
96
- * SQS
97
96
  * aska
98
97
  * EC2
99
98
 
100
99
  == INSTALL:
101
100
 
102
- gem install poolparty
101
+ gem install auser-poolparty
103
102
 
104
103
  == ROADMAP
105
104
 
106
- * v0.0.5 - Released!
107
- * v0.0.6 - Speed the configuration on the instances
108
- * v0.0.7 - Callback support
109
- * v0.0.8 - Add SQS task support
105
+ v0.1.5 - Add AMI bundling tasks
110
106
 
111
107
  == THANKS
112
108
 
113
109
  Ron Evans, http://deadprogrammersociety.blogspot.com/ for his enthusiasm
114
110
  Tim Goh, http://citrusbyte.com for sanity checks and thoughts
115
- Daniel Fischer, http://citrusbyte.com for initial site design
111
+ PJ Cabrera, http://pjtrix.com for excitement, thoughts and contribution
112
+ Blake Mizerany, http://sinatrarb.com/, for his support and ideas
113
+ Nicolás 'Foca' Sanguinetti, http://nicolassanguinetti.info/
116
114
 
117
115
  == LICENSE:
118
116
 
data/Rakefile CHANGED
@@ -1,14 +1,16 @@
1
1
  require 'rubygems'
2
- require "lib/poolparty"
2
+ require "./lib/poolparty"
3
+
3
4
  begin
4
5
  require 'echoe'
5
6
 
6
7
  Echoe.new("poolparty") do |s|
7
- s.author = "Ari Lerner"
8
+ s.author = ["Ari Lerner"]
9
+ s.rubyforge_name = "poolparty"
8
10
  s.email = "ari.lerner@citrusbyte.com"
9
11
  s.summary = "Run your entire application off EC2, managed and auto-scaling"
10
12
  s.url = "http://poolpartyrb.com"
11
- s.dependencies = ["aws-s3", "amazon-ec2", "auser-aska", "git", "crafterm-sprinkle", "SystemTimer"]
13
+ s.dependencies = ["aws-s3", "amazon-ec2", "auser-aska", "git", "crafterm-sprinkle", "SystemTimer", "open4"]
12
14
  s.install_message = %q{
13
15
 
14
16
  Get ready to jump in the pool, you just installed PoolParty!
@@ -20,20 +22,34 @@ begin
20
22
 
21
23
  For more information, check http://poolpartyrb.com
22
24
  On IRC:
23
- irc.freenode.net
24
- #poolpartyrb
25
+ irc.freenode.net / #poolpartyrb
26
+
25
27
  *** Ari Lerner @ <ari.lerner@citrusbyte.com> ***
26
28
  }
27
29
  end
28
-
29
30
  rescue LoadError => boom
30
31
  puts "You are missing a dependency required for meta-operations on this gem."
31
32
  end
32
33
 
33
- task :default => :test
34
-
35
34
  PoolParty.include_tasks
36
35
 
36
+ # add spec tasks, if you have rspec installed
37
+ begin
38
+ require 'spec/rake/spectask'
39
+
40
+ Spec::Rake::SpecTask.new("spec") do |t|
41
+ t.spec_files = FileList['spec/**/*_spec.rb']
42
+ t.spec_opts = ['--color']
43
+ end
44
+
45
+ Spec::Rake::SpecTask.new("rcov_spec") do |t|
46
+ t.spec_files = FileList['spec/**/*_spec.rb']
47
+ t.spec_opts = ['--color']
48
+ t.rcov = true
49
+ t.rcov_opts = ['--exclude', '^spec,/gems/']
50
+ end
51
+ end
52
+
37
53
  namespace(:pkg) do
38
54
  ## Rake task to create/update a .manifest file in your project, as well as update *.gemspec
39
55
  desc %{Update ".manifest" with the latest list of project filenames. Respect\
@@ -64,9 +80,8 @@ namespace(:pkg) do
64
80
  File.open('Manifest', 'w') {|f| f << list.join("\n") }
65
81
  end
66
82
  desc "Build gemspec for github"
67
- task :gemspec => :manifest do
83
+ task :gemspec => [:manifest, :gem] do
68
84
  require "yaml"
69
- `rake manifest gem`
70
85
  data = YAML.load(open("poolparty.gemspec").read).to_ruby
71
86
  File.open("poolparty.gemspec", "w+") {|f| f << data }
72
87
  end
@@ -82,12 +97,12 @@ namespace(:pkg) do
82
97
  File.open("poolparty.gemspec", "w+") {|f| f << data }
83
98
  end
84
99
  desc "Get ready to release the gem"
85
- task :prerelease => :gemspec_update do
100
+ task :prerelease => [:gemspec_update] do
86
101
  `git add .`
87
102
  `git ci -a -m "Updated gemspec for github"`
88
103
  end
89
104
  desc "Release them gem to the gem server"
90
- task :release => :prerelease do
105
+ task :release => [:prerelease] do
91
106
  `git push origin master`
92
107
  end
93
108
  end
data/bin/instance CHANGED
@@ -13,13 +13,13 @@ Usage: instance [OPTIONS] { #{commandables.join(" | ")} }
13
13
  EOU
14
14
  })
15
15
 
16
- PoolParty.load
16
+ PoolParty.load_app
17
17
 
18
18
  master = PoolParty::Master.new
19
19
  list = PoolParty::Optioner.parse(ARGV.dup, %w(-v --verbose))
20
20
  num = list.reject {|a| commandables.include?(a) }.pop
21
21
 
22
- instance = master.get_node(num)
22
+ instance = master.get_node( num || 0 )
23
23
 
24
24
  unless instance
25
25
  puts "Cloud is not running"
data/bin/pool CHANGED
@@ -1,11 +1,10 @@
1
1
  #!/usr/bin/ruby
2
- require 'rubygems'
3
- $:.unshift(File.join(File.dirname(__FILE__), "lib"))
2
+ $:.unshift(File.join(File.dirname(__FILE__)))
4
3
  require 'poolparty'
5
4
 
6
5
  def display_config_data
7
6
  PoolParty.message <<-EOM
8
- Starting #{PoolParty::Application.app_name ? "#{PoolParty::Application.app_name} " : "" }cloud
7
+ PoolParty cloud: #{PoolParty::Application.app_name ? "#{PoolParty::Application.app_name} " : "" }
9
8
  On #{PoolParty::Application.ami}
10
9
  Minimum instances: #{PoolParty::Application.minimum_instances}
11
10
  Maximum instances: #{PoolParty::Application.maximum_instances}
@@ -16,6 +15,7 @@ Starting #{PoolParty::Application.app_name ? "#{PoolParty::Application.app_name}
16
15
  Monitors available:
17
16
  --------------
18
17
  #{PoolParty.registered_monitors.collect {|a| " #{a}"}}
18
+
19
19
  Plugins:
20
20
  --------------
21
21
  #{Dir["#{PoolParty::Application.plugin_dir}/*"].collect {|a| " #{File.basename(a)}"}.join("\n")}
@@ -30,8 +30,8 @@ Usage: pool [OPTIONS] {start | stop | list | clouds_list | maintain | restart |
30
30
  -----------------------------------------------------------------
31
31
  EOU
32
32
  })
33
-
34
- PoolParty.load
33
+
34
+ PoolParty.load_app
35
35
  master = PoolParty::Master.new
36
36
  list = PoolParty::Optioner.parse(ARGV.dup, %w(-v))
37
37
 
@@ -74,7 +74,9 @@ list.each do |cmd|
74
74
  when "switch"
75
75
  list.shift
76
76
  context = list.shift
77
- context ? `source ~/.#{context}_pool_keys` : puts("You must supply a context to switch to")
77
+ keyfilename = ".#{context}_pool_keys"
78
+ PoolParty.message "switching cloud to #{context}"
79
+ context ? Kernel.system("source $HOME/#{keyfilename}") : puts("You must supply a context to switch to")
78
80
  else
79
81
  puts master.list
80
82
  end
@@ -1,5 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
+ echo "Setting up pem files"
4
+ :setup_pems
3
5
  # Move the hosts file
4
6
  echo "Moving the hosts file into place"
5
7
  :move_hostfile
@@ -15,9 +17,6 @@ echo "If this is the master, I'm configuring it as the master now"
15
17
  # Configure haproxy
16
18
  echo "Configuring and starting haproxy"
17
19
  :configure_haproxy
18
- # Set this hostname as appropriate in the cloud
19
- echo "Setting new hostname"
20
- :set_hostname
21
20
  # Configure heartbeat
22
21
  echo "Moving all the resource.d files into place"
23
22
  :configure_resource_d
@@ -33,5 +32,6 @@ echo "Configuring monit"
33
32
  # Update the plugins
34
33
  echo "Updating plugins"
35
34
  :update_plugins
35
+ # Run user tasks
36
36
  echo "Running user tasks"
37
37
  :user_tasks
@@ -8,7 +8,7 @@
8
8
  :minimum_instances: 2
9
9
  :maximum_instances: 3
10
10
  :ec2_dir: "/Users/auser/.ec2"
11
- :keypair: auser
11
+ :keypair: testappkeypair
12
12
  :os: ubuntu
13
13
  :host_port: 80
14
14
  :client_port: 8001
data/lib/core/array.rb CHANGED
@@ -7,7 +7,10 @@ class Array
7
7
  def collect_with_index &block
8
8
  self.enum_for(:each_with_index).collect &block
9
9
  end
10
- def runnable
11
- self.join(" \n ").runnable
10
+ def runnable(quiet=true)
11
+ self.join(" \n ").runnable(quiet)
12
+ end
13
+ def nice_runnable(quiet=true)
14
+ self.join(" \n ").nice_runnable(quiet)
12
15
  end
13
16
  end
data/lib/core/hash.rb CHANGED
@@ -6,6 +6,6 @@ class Hash
6
6
  merge(other_hash.delete_if {|k,v| has_key?(k) })
7
7
  end
8
8
  def safe_merge!(other_hash)
9
- merge!(other_hash.delete_if {|k,v| has_key?(k) })
9
+ merge!(other_hash.delete_if {|k,v| has_key?(k) && !v.nil? })
10
10
  end
11
11
  end
data/lib/core/string.rb CHANGED
@@ -17,8 +17,12 @@ class String
17
17
  def arrayable
18
18
  self.strip.split(/\n/)
19
19
  end
20
- def runnable
21
- self.strip.gsub(/\n/, " && ")
20
+ def runnable(quite=true)
21
+ # map {|l| l << "#{" >/dev/null 2>/dev/null" if quite}" }.
22
+ self.strip.split(/\n/).join(" && ")
23
+ end
24
+ def nice_runnable(quite=true)
25
+ self.split(/ && /).join("\n")
22
26
  end
23
27
  def classify
24
28
  self.capitalize
@@ -6,8 +6,10 @@ module PoolParty
6
6
  @klass = klass.send :new
7
7
  klass.stub!(:new).and_return @klass
8
8
 
9
- define_master
9
+ @master = Master.new
10
10
  @instances = define_instances(num)
11
+
12
+ Master.stub!(:new).and_return @master
11
13
 
12
14
  @master.stub!(:execute_tasks).and_return true
13
15
  @master.stub!(:launch_minimum_instances).and_return true
@@ -19,13 +21,9 @@ module PoolParty
19
21
  Kernel.stub!(:system).and_return "true"
20
22
 
21
23
  Provider.stub!(:install_poolparty).and_return true
22
- Provider.stub!(:install_userpackages).and_return true
23
24
 
24
25
  [@klass, @master, @instances]
25
26
  end
26
- def self.define_master
27
- @master ||= Master.new
28
- end
29
27
  def self.define_instances(num)
30
28
  # Too many gross evals
31
29
  returning [] do |arr|
@@ -34,6 +32,7 @@ module PoolParty
34
32
  @instance#{i} = RemoteInstance.new
35
33
  @instance#{i}.stub!(:ssh).and_return "true"
36
34
  @instance#{i}.stub!(:scp).and_return "true"
35
+ @instance#{i}.stub!(:run).and_return "true"
37
36
  @instance#{i}.stub!(:name).and_return "node#{i}"
38
37
  @instance#{i}.stub!(:ip).and_return "127.0.0.#{i}"
39
38
  EOE
@@ -1,32 +1,27 @@
1
- require "sprinkle"
2
- module Sprinkle
3
- module Installers
4
- class Source < Installer
5
-
6
- def custom_dir(dir)
7
- @custom_dir = dir
8
- end
9
-
10
- def base_dir
11
- if @custom_dir
12
- return @custom_dir
13
- elsif @source.split('/').last =~ /(.*)\.(tar\.gz|tgz|tar\.bz2|tb2)/
14
- return $1
15
- end
16
- raise "Unknown base path for source archive: #{@source}, please update code knowledge"
17
- end
18
- end
19
-
20
- class Gem < Installer
21
- protected
22
- def install_sequence
23
- cmd = "gem install -y #{gem}"
24
- cmd << " --version '#{version}'" if version
25
- cmd << " --source #{source}" if source
26
- cmd
27
- end
1
+ Sprinkle::Installers::Source.extend Module.new do
2
+ def custom_dir(dir)
3
+ @custom_dir = dir
4
+ end
5
+
6
+ def base_dir
7
+ if @custom_dir
8
+ return @custom_dir
9
+ elsif @source.split('/').last =~ /(.*)\.(tar\.gz|tgz|tar\.bz2|tb2)/
10
+ return $1
28
11
  end
29
-
30
-
12
+ raise "Unknown base path for source archive: #{@source}, please update code knowledge"
13
+ end
14
+ end
15
+ Sprinkle::Installers::Gem.extend Module.new do
16
+ def platform(platform=nil)
17
+ @platform ||= platform
31
18
  end
19
+ protected
20
+ def install_sequence
21
+ cmd = "gem install -y #{gem}"
22
+ cmd << " --version '#{version}'" if version
23
+ cmd << " --source #{source}" if source
24
+ cmd << " --platform #{platform}" if platform
25
+ cmd
26
+ end
32
27
  end
@@ -15,22 +15,20 @@ module PoolParty
15
15
  # Default config file assumed to be at config/config.yml
16
16
  def make_options(opts={})
17
17
  loading_options = opts.delete(:optsparse) || {}
18
- loading_options.merge!( opts.delete(:argv) || {} )
18
+ loading_options.merge!( opts || {})
19
+
20
+ load_options!(loading_options) # Load command-line options
21
+ config_file_location = (default_options[:config_file] || opts[:config_file])
19
22
 
20
- config_file_location = (default_options[:config_file] || opts[:config_file])
21
23
  # If the config_file options are specified and not empty
22
24
  unless config_file_location.nil? || config_file_location.empty?
23
25
  require "yaml"
24
26
  # Try loading the file if it exists
25
27
  filedata = File.open("#{config_file_location}").read if File.file?("#{config_file_location}")
26
- # We want the command-line to overwrite the config file
27
- default_options.merge!( YAML.load(filedata) ) if filedata
28
+ default_options.merge!( YAML.load(filedata) ) if filedata rescue ""
28
29
  end
29
-
30
- default_options.merge!(opts)
31
- load_options!(loading_options) # Load command-line options
32
- default_options.merge!(local_user_data) unless local_user_data.nil?
33
-
30
+ # We want the command-line to overwrite the config file
31
+ default_options.merge!(local_user_data) unless local_user_data.nil?
34
32
  OpenStruct.new(default_options)
35
33
  end
36
34
 
@@ -39,8 +37,8 @@ module PoolParty
39
37
  require 'optparse'
40
38
  OptionParser.new do |op|
41
39
  op.banner = opts[:banner] if opts[:banner]
42
- op.on('-A key', '--access-key key', "Ec2 access key (ENV['ACCESS_KEY'])") { |key| default_options[:access_key] = key }
43
- op.on('-S key', '--secret-access-key key', "Ec2 secret access key (ENV['SECRET_ACCESS_KEY'])") { |key| default_options[:secret_access_key] = key }
40
+ op.on('-A key', '--access-key key', "Ec2 access key (ENV['AWS_ACCESS_KEY'])") { |key| default_options[:access_key] = key }
41
+ op.on('-S key', '--secret-access-key key', "Ec2 secret access key (ENV['AWS_SECRET_ACCESS'])") { |key| default_options[:secret_access_key] = key }
44
42
  op.on('-I ami', '--image-id id', "AMI instance (default: 'ami-40bc5829')") {|id| default_options[:ami] = id }
45
43
  op.on('-k keypair', '--keypair name', "Keypair name (ENV['KEYPAIR_NAME'])") { |key| default_options[:keypair] = key }
46
44
  op.on('-b bucket', '--bucket bucket', "Application bucket") { |bucket| default_options[:shared_bucket] = bucket }
@@ -60,7 +58,7 @@ module PoolParty
60
58
  op.on('-s size', '--size size', "Run specific sized instance") {|s| default_options[:size] = s}
61
59
  op.on('-a name', '--name name', "Application name") {|n| default_options[:app_name] = n}
62
60
  op.on('-u username', '--username name', "Login with the user (default: root)") {|s| default_options[:user] = s}
63
- op.on('-d user-data','--user-data data', "Extra data to send each of the instances (default: "")") { |data| default_options[:user_data] = data }
61
+ op.on('-d user-data','--user-data data', "Extra data to send each of the instances (default: "")") { |data| default_options[:user_data] = data.to_str }
64
62
  op.on('-i', '--install-on-boot', 'Install the PoolParty and custom software on boot (default: false)') {|b| default_options[:install_on_load] = true}
65
63
  op.on('-t seconds', '--polling-time', "Time between polling in seconds (default 50)") {|t| default_options[:polling_time] = t }
66
64
  op.on('-v', '--[no-]verbose', 'Run verbosely (default: false)') {|v| default_options[:verbose] = true}
@@ -97,8 +95,8 @@ module PoolParty
97
95
  :minimum_instances => 2,
98
96
  :maximum_instances => 4,
99
97
  :public_ip => "",
100
- :access_key => ENV["AWS_ACCESS_KEY_ID"],
101
- :secret_access_key => ENV["AWS_SECRET_ACCESS_ID"],
98
+ :access_key => ENV["AWS_ACCESS_KEY"],
99
+ :secret_access_key => ENV["AWS_SECRET_ACCESS"],
102
100
  :config_file => if ENV["CONFIG_FILE"] && !ENV["CONFIG_FILE"].empty?
103
101
  ENV["CONFIG_FILE"]
104
102
  elsif File.file?("config/config.yml")
@@ -108,13 +106,13 @@ module PoolParty
108
106
  end,
109
107
  :username => "root",
110
108
  :ec2_dir => ENV["EC2_HOME"],
111
- :keypair => ENV["KEYPAIR_NAME"],
109
+ :keypair => (ENV["KEYPAIR_NAME"].nil? || ENV["KEYPAIR_NAME"].empty?) ? File.basename(`pwd`).strip : ENV["KEYPAIR_NAME"].empty?,
112
110
  :ami => 'ami-44bd592d',
113
111
  :shared_bucket => "",
114
112
  :expand_when => "web < 1.5\n memory > 0.85",
115
113
  :contract_when => "cpu < 0.20\n memory < 0.10",
116
114
  :os => "ubuntu",
117
- :plugin_dir => "vendor",
115
+ :plugin_dir => "plugins",
118
116
  :install_on_load => false,
119
117
  :working_directory => Dir.pwd
120
118
  }
@@ -125,29 +123,41 @@ module PoolParty
125
123
  end
126
124
  alias_method :managed_services, :master_managed_services
127
125
  def launching_user_data
128
- {:polling_time => polling_time,
126
+ hash_to_launch_with.to_yaml
127
+ end
128
+ def hash_to_launch_with
129
+ @hash ||= { :polling_time => polling_time,
129
130
  :access_key => access_key,
130
131
  :secret_access_key => secret_access_key,
131
- :user_data => user_data}.to_yaml
132
+ :user_data => user_data,
133
+ :keypair_path => "/mnt"
134
+ }
132
135
  end
133
- def local_user_data
134
- begin
135
- @@timer.timeout(3.seconds) do
136
- @local_user_data ||=YAML.load(open("http://169.254.169.254/latest/user-data").read)
137
- end
138
- rescue Exception => e
139
- @local_user_data = {}
136
+ 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
140
145
  end
146
+ @local_user_data
141
147
  end
142
148
  # For testing purposes
143
149
  def reset!
150
+ @options = nil
144
151
  @local_user_data = nil
145
152
  end
146
153
  # Keypair path
147
154
  # Idiom:
148
- # /Users/username/.ec2/id_rsa-name
155
+ # /Users/username/.ec2/[name]
149
156
  def keypair_path
150
- "#{ec2_dir}/id_rsa#{keypair ? "-#{keypair}" : "" }"
157
+ options.keypair_path ? options.keypair_path : "#{ec2_dir}/#{keypair_name}"
158
+ end
159
+ def keypair_name
160
+ "id_rsa-#{keypair}"
151
161
  end
152
162
  # Are we in development or test mode
153
163
  %w(development production test).each do |env|
@@ -67,9 +67,17 @@ module PoolParty
67
67
  build_and_send_config_files_in_temp_directory
68
68
  remote_configure_instances
69
69
 
70
- Master.with_nodes do |node|
70
+ nodes.each do |node|
71
71
  node.configure
72
- end
72
+ end
73
+ end
74
+ before :install_cloud, :add_ssh_key
75
+ after :configure_cloud, :remove_ssh_key
76
+ def add_ssh_key(i)
77
+ Kernel.system("ssh-add #{Application.keypair_path} >/dev/null 2>/dev/null")
78
+ end
79
+ def remove_ssh_key(i)
80
+ Kernel.system("ssh-add -d #{Application.keypair_name} >/dev/null 2>/dev/null")
73
81
  end
74
82
  def install_cloud(bool=false)
75
83
  if Application.install_on_load? || bool
@@ -77,14 +85,13 @@ module PoolParty
77
85
  # update packages.
78
86
  update_apt_string =<<-EOE
79
87
  touch /etc/apt/sources.list
80
- echo 'deb http://mirrors.cs.wmich.edu/ubuntu hardy main universe' >> /etc/apt/sources.list
81
- sudo apt-get update --fix-missing
88
+ echo 'deb http://mirrors.kernel.org/ubuntu hardy main universe' >> /etc/apt/sources.list
89
+ apt-get update --fix-missing
82
90
  EOE
83
91
 
84
92
  ssh(update_apt_string)
85
93
 
86
- Provider.install_poolparty(cloud_ips)
87
- Provider.install_userpackages(cloud_ips)
94
+ Provider.install_poolparty
88
95
 
89
96
  # For plugins
90
97
  nodes.each do |node|
@@ -174,18 +181,20 @@ module PoolParty
174
181
  Kernel.system("tar -czf #{base_tmp_dir}/plugins.tar.gz #{File.basename(Application.plugin_dir)}")
175
182
  end
176
183
 
177
- File.copy(get_config_file_for("cloud_master_takeover"), "#{base_tmp_dir}/cloud_master_takeover")
178
- File.copy(get_config_file_for("heartbeat.conf"), "#{base_tmp_dir}/ha.cf")
184
+ if Master.requires_heartbeat?
185
+ build_and_copy_heartbeat_authkeys_file
186
+ File.copy(get_config_file_for("cloud_master_takeover"), "#{base_tmp_dir}/cloud_master_takeover")
187
+ File.copy(get_config_file_for("heartbeat.conf"), "#{base_tmp_dir}/ha.cf")
188
+ end
179
189
 
180
190
  File.copy(Application.config_file, "#{base_tmp_dir}/config.yml") if Application.config_file && File.exists?(Application.config_file)
181
191
  File.copy(Application.keypair_path, "#{base_tmp_dir}/keypair") if File.exists?(Application.keypair_path)
182
192
 
183
- File.copy(get_config_file_for("monit.conf"), "#{base_tmp_dir}/monitrc")
184
-
193
+ copy_pem_files_to_tmp_dir
194
+
185
195
  copy_config_files_in_directory_to_tmp_dir("config/resource.d")
186
- copy_config_files_in_directory_to_tmp_dir("config/monit.d")
187
-
188
- build_and_copy_heartbeat_authkeys_file
196
+ # copy_config_files_in_directory_to_tmp_dir("config/monit.d")
197
+
189
198
  build_haproxy_file
190
199
  Master.build_user_global_files
191
200
 
@@ -200,6 +209,15 @@ module PoolParty
200
209
  end
201
210
  end
202
211
  end
212
+ def copy_pem_files_to_tmp_dir
213
+ %w(EC2_CERT EC2_PRIVATE_KEY).each do |key|
214
+ begin
215
+ file = `echo $#{key}`.strip
216
+ File.copy(file, "#{base_tmp_dir}/#{File.basename(file)}")
217
+ rescue Exception => e
218
+ end
219
+ end
220
+ end
203
221
  def cleanup_tmp_directory(c)
204
222
  Dir["#{base_tmp_dir}/*"].each {|f| FileUtils.rm_rf f} if File.directory?("tmp/")
205
223
  end
@@ -286,7 +304,7 @@ chmod +x #{script_file}
286
304
  # Build basic configuration script for the node
287
305
  def build_reconfigure_instances_script_for(node)
288
306
  write_to_file_for("configuration", node) do
289
- open(Application.sh_reconfigure_instances_script).read.strip ^ node.configure_tasks
307
+ open(Application.sh_reconfigure_instances_script).read.strip ^ node.configure_tasks( !PoolParty.verbose? )
290
308
  end
291
309
  end
292
310
 
@@ -399,6 +417,9 @@ chmod +x #{script_file}
399
417
  def get_master
400
418
  new.nodes[0]
401
419
  end
420
+ def cloud_ips
421
+ new.cloud_ips
422
+ end
402
423
  def get_next_node(node)
403
424
  new.get_next_node(node)
404
425
  end
@@ -31,12 +31,8 @@ module PoolParty
31
31
  PoolParty::RemoteInstance.user_tasks << str
32
32
  end
33
33
 
34
- def self.install_package_string(str)
35
- PoolParty::Provider.define_user_package str
36
- end
37
-
38
- def self.define_package_string(str)
39
- PoolParty::Provider.define_user_install str
34
+ def self.define_custom_package name=:userpackage, &block
35
+ PoolParty::Provider.define_custom_package name, &block
40
36
  end
41
37
 
42
38
  def self.define_global_file(name, &block)
@@ -47,6 +43,15 @@ module PoolParty
47
43
  PoolParty::Master.define_node_user_file(name, &block)
48
44
  end
49
45
 
46
+ def add_user_data(h={})
47
+ case h.class.to_s
48
+ when "String"
49
+ PoolParty::Application.user_data << h
50
+ when "Hash"
51
+ PoolParty::Application.hash_to_launch_with.merge!(h)
52
+ end
53
+ end
54
+
50
55
  def read_config_file(filename)
51
56
  return {} unless filename
52
57
  YAML.load(open(filename).read)
@@ -51,7 +51,7 @@ module PoolParty
51
51
  end
52
52
 
53
53
  def self.plugin_dirs
54
- Dir["#{PoolParty.user_dir}/vendor/*"]
54
+ Dir["#{PoolParty.user_dir}/plugin/*"]
55
55
  end
56
56
 
57
57
  def self.plugin_directory(path)
@@ -61,7 +61,7 @@ module PoolParty
61
61
  FileUtils.mkdir_p base_plugin_dir rescue ""
62
62
  end
63
63
  def self.base_plugin_dir
64
- File.join(PoolParty.root_dir, "vendor")
64
+ File.join(PoolParty.root_dir, "plugin")
65
65
  end
66
66
  end
67
67
  end
File without changes
@@ -1,5 +1,5 @@
1
1
  # Install haproxy
2
2
  package :haproxy, :provides => :proxy do
3
3
  description 'Haproxy proxy'
4
- apt %w( haproxy )
4
+ apt %w( haproxy )
5
5
  end
@@ -18,7 +18,7 @@ package :rubygems do
18
18
  # custom_install 'ruby setup.rb'
19
19
  # end
20
20
  apt %w( rubygems )
21
- post :install, "gem update --system", "gem sources -a http://gems.github.com"
21
+ post :install, "sed -i s/require\ 'rubygems'/require\ 'rubygems'\nrequire\ 'rubygems\/gem_runner'/g", "gem update --system", "gem sources -a http://gems.github.com"
22
22
  requires :ruby
23
23
  end
24
24