auser-poolparty 0.2.68 → 0.2.69

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/Manifest.txt +3 -0
  2. data/PostInstall.txt +1 -1
  3. data/README.txt +3 -0
  4. data/Rakefile +3 -3
  5. data/bin/cloud-configure +4 -2
  6. data/bin/cloud-start +4 -3
  7. data/lib/poolparty.rb +5 -3
  8. data/lib/poolparty/helpers/binary.rb +3 -1
  9. data/lib/poolparty/helpers/optioner.rb +27 -18
  10. data/lib/poolparty/helpers/provisioner_base.rb +13 -4
  11. data/lib/poolparty/helpers/provisioners/master.rb +2 -2
  12. data/lib/poolparty/modules/cloud_resourcer.rb +1 -1
  13. data/lib/poolparty/modules/file_writer.rb +2 -2
  14. data/lib/poolparty/monitors/base_monitor.rb +29 -1
  15. data/lib/poolparty/net/messenger.rb +5 -2
  16. data/lib/poolparty/net/remote_bases/ec2.rb +17 -7
  17. data/lib/poolparty/net/remoter.rb +7 -3
  18. data/lib/poolparty/net/remoter_base.rb +18 -0
  19. data/lib/poolparty/plugins/deploydirectory.rb +7 -1
  20. data/lib/poolparty/plugins/git.rb +47 -0
  21. data/lib/poolparty/pool/base.rb +1 -0
  22. data/lib/poolparty/pool/cloud.rb +1 -1
  23. data/lib/poolparty/pool/pool.rb +1 -2
  24. data/lib/poolparty/pool/resource.rb +7 -3
  25. data/lib/poolparty/pool/resources/directory.rb +4 -1
  26. data/lib/poolparty/pool/resources/exec.rb +2 -5
  27. data/lib/poolparty/pool/resources/file.rb +1 -1
  28. data/lib/poolparty/pool/resources/package.rb +1 -1
  29. data/lib/poolparty/version.rb +1 -1
  30. data/lib/poolpartyspec.rb +0 -0
  31. data/poolparty.gemspec +4 -4
  32. data/spec/poolparty/helpers/optioner_spec.rb +3 -4
  33. data/spec/poolparty/modules/configurable_spec.rb +2 -2
  34. data/spec/poolparty/net/remote_bases/ec2_spec.rb +4 -2
  35. data/spec/poolparty/net/remoter_spec.rb +1 -0
  36. data/spec/poolparty/plugins/git_spec.rb +45 -0
  37. data/spec/poolparty/pool/plugin_spec.rb +1 -1
  38. data/spec/poolparty/pool/resource_spec.rb +2 -2
  39. data/spec/poolparty/spec_helper.rb +1 -1
  40. data/tasks/deployment.rake +3 -5
  41. data/website/index.html +1 -1
  42. metadata +337 -3
data/Manifest.txt CHANGED
@@ -273,6 +273,7 @@ lib/poolparty/net/remote_instance.rb
273
273
  lib/poolparty/net/remoter.rb
274
274
  lib/poolparty/net/remoter_base.rb
275
275
  lib/poolparty/plugins/deploydirectory.rb
276
+ lib/poolparty/plugins/git.rb
276
277
  lib/poolparty/plugins/line.rb
277
278
  lib/poolparty/plugins/rsyncmirror.rb
278
279
  lib/poolparty/plugins/runit.rb
@@ -323,6 +324,7 @@ lib/poolparty/templates/puppetrunner
323
324
  lib/poolparty/templates/yaws.conf
324
325
  lib/poolparty/version.rb
325
326
  lib/poolpartycl.rb
327
+ lib/poolpartyspec.rb
326
328
  log/pool.logs
327
329
  poolparty.gemspec
328
330
  script/destroy
@@ -363,6 +365,7 @@ spec/poolparty/net/remote_spec.rb
363
365
  spec/poolparty/net/remoter_base_spec.rb
364
366
  spec/poolparty/net/remoter_spec.rb
365
367
  spec/poolparty/plugins/deploydirectory_spec.rb
368
+ spec/poolparty/plugins/git_spec.rb
366
369
  spec/poolparty/plugins/line_spec.rb
367
370
  spec/poolparty/plugins/svn_spec.rb
368
371
  spec/poolparty/pool/base_spec.rb
data/PostInstall.txt CHANGED
@@ -1,4 +1,4 @@
1
- Get ready to jump in the pool, you just installed PoolParty! (Updated at 11/19/08)
1
+ Get ready to jump in the pool, you just installed PoolParty! (Updated at 22:49 11/24/08)
2
2
 
3
3
  To get started, run the generator:
4
4
 
data/README.txt CHANGED
@@ -40,6 +40,9 @@ sudo gem install auser-poolparty
40
40
 
41
41
  == TODO:
42
42
  * Rewrite the disallowed_options to whitelist allowed_options on resources
43
+ * Add pingback for nodes to master when failure occurs
44
+ * Add become master for the nodes
45
+ * Add soft-stop to haproxy while reconfiguring
43
46
  * Replace services with Runit
44
47
  * Refactor provisioning to use erlang
45
48
  * Add queuing of tasks on the messenger
data/Rakefile CHANGED
@@ -23,12 +23,12 @@ task :build_local_gem => [:clean_tmp, :spec, :clean_pkg, :"manifest:refresh", :p
23
23
  desc "Packge with timestamp"
24
24
  task :update_timestamp do
25
25
  data = open("PostInstall.txt").read
26
- str = "Updated at #{Time.now.strftime("%D")}"
26
+ str = "Updated at #{Time.now.strftime("%H:%M %D")}"
27
27
 
28
28
  if data.scan(/Updated at/).empty?
29
- data = data.gsub(/just installed PoolParty\!/, '\0'+" (#{str})")
29
+ data = data ^ {:updated_at => str}
30
30
  else
31
- data = data ^ {:updated_at => str}
31
+ data = data.gsub(/just installed PoolParty\!(.*)$/, "just installed PoolParty! (#{str})")
32
32
  end
33
33
  ::File.open("PostInstall.txt", "w+") {|f| f << data }
34
34
  end
data/bin/cloud-configure CHANGED
@@ -4,7 +4,8 @@ require "poolparty"
4
4
  require "poolpartycl"
5
5
 
6
6
  o = PoolParty::Optioner.new(ARGV) do |opts, optioner|
7
- opts.on('-n cloudname', '--name name', 'Start cloud by this name') { |c| optioner.cloudname c }
7
+ optioner.cloudnames
8
+ # optioner.daemonizeable
8
9
  end
9
10
 
10
11
  o.loaded_clouds.each do |cloud|
@@ -13,7 +14,8 @@ o.loaded_clouds.each do |cloud|
13
14
 
14
15
  # hide_output do
15
16
  # if provision_class == "master" || provision_class == "all"
16
- Provisioner.configure_master(self, testing)
17
+ @cl = self
18
+ daemon ? daemonize {Provisioner.configure_master(@cl, testing)} : Provisioner.configure_master(self, testing)
17
19
  # end
18
20
  # if provision_class == "slave" || provision_class == "all"
19
21
  # Provisioner.configure_slaves(self, testing)
data/bin/cloud-start CHANGED
@@ -4,8 +4,8 @@ require "poolparty"
4
4
  require "poolpartycl"
5
5
 
6
6
  o = PoolParty::Optioner.new(ARGV) do |opts, optioner|
7
- opts.on('-n cloudname', '--name name', 'Start cloud by this name') { |c| optioner.cloudname c }
8
- opts.on('-d', '--daemonize', 'Daemonize starting the cloud') { optioner.daemon true }
7
+ optioner.cloudnames
8
+ optioner.daemonizeable
9
9
  end
10
10
 
11
11
  o.loaded_clouds.each do |cloud|
@@ -18,7 +18,8 @@ o.loaded_clouds.each do |cloud|
18
18
  # puts("\tNot launching while in testing mode")
19
19
  # else
20
20
  vputs "Launching and configuring the master"
21
- daemon ? daemonize {launch_and_configure_master!} : launch_and_configure_master!
21
+ @cl = self
22
+ daemon ? daemonize {@cl.launch_and_configure_master!} : launch_and_configure_master!
22
23
  # end
23
24
  # end
24
25
  when_no_pending_instances do
data/lib/poolparty.rb CHANGED
@@ -81,8 +81,10 @@ class Class
81
81
  end
82
82
 
83
83
  ## Load PoolParty Plugins and package
84
- %w(plugins base_packages).each do |dir|
85
- Dir[File.dirname(__FILE__) + "/poolparty/#{dir}/**.rb"].each do |file|
86
- require file
84
+ module PoolParty
85
+ %w(plugins base_packages).each do |dir|
86
+ Dir[::File.dirname(__FILE__) + "/poolparty/#{dir}/*.rb"].each do |file|
87
+ require file
88
+ end
87
89
  end
88
90
  end
@@ -47,7 +47,7 @@ module PoolParty
47
47
  def daemonize(&block)
48
48
  vputs "Daemonizing..."
49
49
  trap("CHLD") {Process.wait(-1, Process::WNOHANG)}
50
- fork do
50
+ pid = fork do
51
51
  Signal.trap('HUP', 'IGNORE') # Don't die upon logout
52
52
  File.open("/dev/null", "r+") do |devnull|
53
53
  $stdout.reopen(devnull)
@@ -56,6 +56,8 @@ module PoolParty
56
56
  end
57
57
  block.call if block
58
58
  end
59
+ Process.detach(pid)
60
+ pid
59
61
  end
60
62
 
61
63
  end
@@ -11,17 +11,25 @@ module PoolParty
11
11
  include MethodMissingSugar
12
12
 
13
13
  def initialize(args=[], opts={}, &block)
14
- @arguments = parse_args(args)
15
- @parse_options = opts[:parse_options] ? opts[:parse_options] : true
14
+ @arguments = parse_args(args)
16
15
  @extra_help = opts.has_key?(:extra_help) ? opts[:extra_help] : ""
17
- @abstract = opts[:abstract] ? opts[:abstract] : false
18
- @command = opts[:command] ? opts[:command] : false
16
+ @abstract = opts.has_key?(:abstract) ? opts[:abstract] : false
17
+ @load_pools = opts.has_key?(:load_pools) ? opts[:load_pools] : !@abstract
18
+ @parse_options = opts.has_key?(:parse_options) ? opts[:parse_options] : true
19
+ @command = opts.has_key?(:command) ? opts[:command] : false
19
20
 
20
21
  parse_options(&block) if @parse_options
21
22
  set_default_options
22
23
  self
23
24
  end
24
25
 
26
+ def daemonizeable
27
+ @opts.on('-d', '--daemonize', 'Daemonize starting the cloud') { self.daemon true }
28
+ end
29
+ def cloudnames
30
+ @opts.on('-n cloudname', '--name name', 'Start cloud by this name') { |c| self.cloudname c }
31
+ end
32
+
25
33
  def parse_args(argv, safe=[])
26
34
  argv
27
35
  end
@@ -37,33 +45,34 @@ module PoolParty
37
45
 
38
46
  def parse_options(&blk)
39
47
  progname = $0.include?("-") ? "#{::File.basename($0[/(\w+)-/, 1])} #{::File.basename($0[/-(.*)/, 1])}" : ::File.basename($0)
40
- opts = OptionParser.new
41
- opts.banner = "Usage: #{progname} #{@abstract ? "[command] " : ""}[options]"
48
+ @opts = OptionParser.new
49
+ @opts.banner = "Usage: #{progname} #{@abstract ? "[command] " : ""}[options]"
42
50
 
43
- opts.separator ""
51
+ @opts.separator ""
44
52
 
45
53
  unless @abstract
46
- opts.separator "Options:"
54
+ @opts.separator "Options:"
47
55
 
48
- opts.on('-v', '--verbose', 'Be verbose') { self.verbose true }
49
- opts.on('-s [file]', '--spec-file [file]', 'Set the spec file') { |file| self.spec file.chomp }
50
- opts.on('-t', '--test', 'Testing mode') { self.testing true }
51
-
52
- blk.call(opts, self) if blk
56
+ @opts.on('-v', '--verbose', 'Be verbose') { self.verbose true }
57
+ @opts.on('-s [file]', '--spec-file [file]', 'Set the spec file') { |file| self.spec file.chomp }
58
+ @opts.on('-t', '--test', 'Testing mode') { self.testing true }
59
+
60
+ blk.call(@opts, self) if blk
53
61
  end
54
62
 
55
- opts.on('-V', '--version', 'Display the version') { puts @version ; exit 0 }
56
- opts.on_tail("-h", "--help", "Show this message") do
57
- puts opts
63
+ @opts.on('-V', '--version', 'Display the version') { puts @version ; exit 0 }
64
+ @opts.on_tail("-h", "--help", "Show this message") do
65
+ puts @opts
58
66
  puts @extra_help
59
67
  exit
60
68
  end
61
69
 
62
- opts.parse(@arguments.dup)
70
+ @opts.parse(@arguments.dup)
63
71
 
64
72
  process_options
65
73
  output_options if verbose
66
- unless @abstract
74
+
75
+ if @load_pools
67
76
  self.loaded_pool load_pool(self.spec || Binary.get_existing_spec_location)
68
77
 
69
78
  self.loaded_clouds extract_cloud_from_options(self)
@@ -211,9 +211,10 @@ module PoolParty
211
211
  [
212
212
  "#!/usr/bin/env sh",
213
213
  upgrade_system,
214
- fix_rubygems,
214
+ install_rubygems,
215
215
  make_logger_directory,
216
216
  install_puppet,
217
+ fix_rubygems,
217
218
  custom_install_tasks
218
219
  ] << install_tasks
219
220
  end
@@ -281,11 +282,19 @@ module PoolParty
281
282
  File.join(File.dirname(__FILE__), "..", "templates")
282
283
  end
283
284
 
284
- def fix_rubygems
285
+ def install_rubygems
286
+ <<-EOE
287
+ #{installer_for("ruby rubygems")}
288
+ EOE
289
+ end
290
+
291
+ def fix_rubygems
285
292
  <<-EOE
286
- #{installer_for("ruby rubygems")}
287
- gem update --system # Force rubygems update
288
293
  echo '#{open(::File.join(template_directory, "gem")).read}' > /usr/bin/gem
294
+ echo 'Updating rubygems'
295
+ PAT=`/usr/bin/gem env gemdir`
296
+ /usr/bin/gem update --system #{unix_hide_string}
297
+ /usr/bin/gem update --system #{unix_hide_string}
289
298
  EOE
290
299
  end
291
300
 
@@ -122,7 +122,7 @@ wget http://github.com/auser/poolparty/tree/master%2Fpkg%2Fpoolparty.gem?raw=tru
122
122
  #{
123
123
  %w(rake lockfile rubyforge hoe ZenTest sexp_processor flexmock logging activesupport
124
124
  RubyInline ParseTree ruby2ruby xml-simple poolparty).map do |dep|
125
- "gem install --ignore-dependencies -y --no-ri --no-rdoc #{dep}.gem #{unix_hide_string}"
125
+ "/usr/bin/gem install --ignore-dependencies -y --no-ri --no-rdoc #{dep}.gem #{unix_hide_string}"
126
126
  end.join("\n")
127
127
  }
128
128
  EOE
@@ -186,7 +186,7 @@ cp #{Base.remote_storage_path}/poolparty.pp /etc/puppet/manifests/classes/poolpa
186
186
  s << "puppetca --clean master.compute-1.internal 2>&1 > /dev/null"
187
187
  s << "puppetca --clean master.ec2.internal 2>&1 > /dev/null"
188
188
  end.join(";")
189
- "if [ -f '/usr/bin/puppetcleaner' ]; then /usr/bin/env puppetcleaner; else #{str}; fi"
189
+ "if [ -f '/usr/bin/puppetrerun' ]; then /usr/bin/puppetrerun; else #{str}; fi"
190
190
  end
191
191
 
192
192
  def restart_puppetd
@@ -4,7 +4,7 @@ module PoolParty
4
4
  module CloudResourcer
5
5
 
6
6
  def plugin_directory(*args)
7
- args = ["/plugins"] if args.empty?
7
+ args = ["#{::File.expand_path(Dir.pwd)}/plugins"] if args.empty?
8
8
  args.each {|arg| Dir["#{arg}/*/*.rb"].each {|f| require f rescue "" }}
9
9
  end
10
10
 
@@ -6,7 +6,7 @@ module PoolParty
6
6
  FileUtils.cp file, path unless file == path || ::File.exists?(path)
7
7
  end
8
8
  def cleanup_storage_directory
9
- Dir["#{Base.storage_directory}/**"].each do |f|
9
+ Dir["#{Base.storage_directory}/**/*"].each do |f|
10
10
  ::FileUtils.rm f if ::File.file?(f)
11
11
  end
12
12
  end
@@ -79,7 +79,7 @@ module PoolParty
79
79
  path
80
80
  end
81
81
  def clear_base_directory
82
- Dir["#{Base.storage_directory}/**"].each do |f|
82
+ Dir["#{Base.storage_directory}/**/*"].each do |f|
83
83
  ::FileUtils.rm f if ::File.file?(f)
84
84
  end
85
85
  end
@@ -1,7 +1,33 @@
1
1
  =begin rdoc
2
2
  Monitor class
3
3
 
4
- TODO: Fill this out
4
+ Monitors are the basis for PoolParty scaling. Your cloud will expand and
5
+ contract against these monitors. You can set your cloud to be monitored by these
6
+ monitors simply by using them in the contract_when and the expand_when macros
7
+ on your cloud like so:
8
+
9
+ expand_when "cpu > 1.2", "memory > 0.94"
10
+ contract_when "cpu < 0.4", "memory < 0.3"
11
+
12
+ You can also add your own monitors simply by creating a directory in the same
13
+ directory as the pool spec (the same directory as the plugin directory exists) and
14
+ placing your monitor file (format: [monitorname]_monitor.rb) there.
15
+
16
+ Monitors are simply classes of the name of the monitor. They subclass the BaseMonitor
17
+ class from PoolParty. A sample monitor would look similar to:
18
+
19
+ class SampleMonitor < PoolParty::Monitors::BaseMonitor
20
+ def run
21
+ end
22
+ end
23
+ register_monitor :sample
24
+
25
+ The monitor class must have an instance level method called run. This method is called when
26
+ the cloud is checking the monitor. The output of this method should be the output of
27
+ the monitor.
28
+
29
+ Notice that at the end, you must call register_monitor :monitorname. This will tell your cloud
30
+ that it can monitor it with this monitor.
5
31
  =end
6
32
  require "#{::File.dirname(__FILE__)}/../pool/base"
7
33
 
@@ -49,7 +75,9 @@ module PoolParty
49
75
  end
50
76
  end
51
77
 
78
+ # Require included monitors
52
79
  Dir["#{File.dirname(__FILE__)}/monitors/*.rb"].each {|f| require f}
80
+ # Require custom monitors
53
81
  Dir["#{PoolParty::Base.custom_monitor_directories}/*.rb"].each {|f| require f}
54
82
 
55
83
  module PoolParty
@@ -1,12 +1,15 @@
1
1
  =begin rdoc
2
- The connection to the messenger from poolparty, the client
2
+ The connection to the messenger from poolparty, the client.
3
+
4
+ This class will setup a socket connection to the master's client
5
+ at the messenger_client_port
3
6
  =end
4
7
  module PoolParty
5
8
  module Messenger
6
9
  def with_socket(testing=false, &block)
7
10
  host = testing ? "localhost" : (master.ip)
8
11
  vputs "Pinging #{host} with the messenger"
9
- socket = TCPSocket.open(host, 7050)
12
+ socket = TCPSocket.open(host, Base.messenger_client_port)
10
13
  out = yield(socket)
11
14
  socket.close
12
15
  out
@@ -1,3 +1,9 @@
1
+ =begin rdoc
2
+ EC2 Remoter Base
3
+
4
+ This serves as the basis for running PoolParty on Amazon's ec2 cloud
5
+ cluster.
6
+ =end
1
7
  require "date"
2
8
  require "#{::File.dirname(__FILE__)}/ec2/ec2_response_object"
3
9
 
@@ -65,18 +71,21 @@ begin
65
71
  EC2ResponseObject.get_descriptions(ec2.describe_instances)
66
72
  end
67
73
 
68
- def after_launch_master(instance=nil)
74
+ def after_launch_master(inst=nil)
75
+ instance = master
76
+ vputs "Running tasks after launching the master"
69
77
  begin
70
- when_no_pending_instances do
78
+ # when_no_pending_instances do
71
79
  if instance
72
- ec2.associate_address(:instance_id => instance.instanceId, :public_ip => set_master_ip_to) if set_master_ip_to
73
- ec2.attach_volume(:volume_id => ebs_volume_id, :instance_id => instance.instanceId, :device => ebs_volume_device) if ebs_volume_id && ebs_volume_mount_point
80
+ ec2.associate_address(:instance_id => instance.instance_id, :public_ip => set_master_ip_to) if set_master_ip_to
81
+ ec2.attach_volume(:volume_id => ebs_volume_id, :instance_id => instance.instance_id, :device => ebs_volume_device) if ebs_volume_id && ebs_volume_mount_point
74
82
  end
75
- end
83
+ # end
76
84
  rescue Exception => e
85
+ vputs "Error in after_launch_master: #{e}"
77
86
  end
78
87
  reset_remoter_base!
79
- when_all_assigned_ips {wait "2.seconds"}
88
+ when_all_assigned_ips {wait "5.seconds"}
80
89
  end
81
90
 
82
91
  # Help create a keypair for the cloud
@@ -112,7 +121,8 @@ begin
112
121
  "if [ -z \"$(grep -v '#' /etc/hosts | grep '#{o.name}')\" ]; then echo '127.0.0.1 #{o.name}' >> /etc/hosts; fi",
113
122
  "hostname #{o.name}",
114
123
  "echo #{o.name} > /etc/hostname",
115
- "cd /var/poolparty && wget http://rubyforge.org/frs/download.php/43666/amazon-ec2-0.3.1.gem -O amazon-ec2.gem 2>&1 && gem install -y --no-ri --no-rdoc amazon-ec2.gem 2>&1"
124
+ "cd /var/poolparty && wget http://rubyforge.org/frs/download.php/43666/amazon-ec2-0.3.1.gem -O amazon-ec2.gem 2>&1",
125
+ "/usr/bin/gem install -y --no-ri --no-rdoc amazon-ec2.gem 2>&1"
116
126
  ]
117
127
  end
118
128
 
@@ -82,11 +82,15 @@ module PoolParty
82
82
  out
83
83
  end
84
84
  def request_launch_master_instance
85
- inst = launch_new_instance!
85
+ @inst = launch_new_instance!
86
86
  wait "5.seconds"
87
- when_no_pending_instances {after_launch_master(inst)}
87
+ when_no_pending_instances do
88
+ vputs "Master has launched"
89
+ reset!
90
+ after_launch_master(@inst)
91
+ end
88
92
  end
89
- def after_launch_master(h={})
93
+ def after_launch_master(inst=nil)
90
94
  vputs "After launch master in remoter"
91
95
  end
92
96
  # Let's terminate an instance that is not the master instance
@@ -1,3 +1,21 @@
1
+ =begin rdoc
2
+ The base for Remote Bases
3
+
4
+ By extending this class, you can easily add remoters to
5
+ PoolParty. There are 4 methods that the remote base needs to implement
6
+ in order to be compatible.
7
+
8
+ The four methods are:
9
+ launch_new_instance!
10
+ terminate_instance(id)
11
+ describe_instance(id)
12
+ describe_instances
13
+
14
+ After your remote base is written, make sure to register the base outside the context
15
+ of the remote base, like so:
16
+ register_remote_base :remote_base_name
17
+
18
+ =end
1
19
  module PoolParty
2
20
 
3
21
  def register_remote_base(*args)