auser-poolparty 0.2.68 → 0.2.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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)