auser-poolparty 1.2.8 → 1.2.9

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 (93) hide show
  1. data/VERSION.yml +1 -1
  2. data/bin/cloud-list +4 -4
  3. data/bin/cloud-provision +2 -0
  4. data/bin/cloud-ssh +1 -1
  5. data/bin/install-poolparty +1 -1
  6. data/examples/fairchild.rb +26 -17
  7. data/examples/metavirt_cloud.rb +2 -4
  8. data/lib/poolparty.rb +2 -7
  9. data/lib/poolparty/core/array.rb +1 -1
  10. data/lib/poolparty/core/exception.rb +1 -1
  11. data/lib/poolparty/core/hash.rb +12 -5
  12. data/lib/poolparty/core/integer.rb +11 -0
  13. data/lib/poolparty/core/object.rb +14 -0
  14. data/lib/poolparty/core/string.rb +6 -1
  15. data/lib/poolparty/core/time.rb +6 -0
  16. data/lib/poolparty/extra/duration.rb +96 -0
  17. data/lib/poolparty/helpers/binary.rb +1 -1
  18. data/lib/poolparty/modules/cloud_resourcer.rb +1 -1
  19. data/lib/poolparty/modules/definable_resource.rb +5 -7
  20. data/lib/poolparty/modules/output.rb +2 -2
  21. data/lib/poolparty/monitors/base_monitor.rb +17 -0
  22. data/lib/poolparty/net/init.rb +4 -11
  23. data/lib/poolparty/net/remote_instance.rb +5 -0
  24. data/lib/poolparty/net/remoter/connections.rb +14 -11
  25. data/lib/poolparty/net/remoter/interactive.rb +13 -2
  26. data/lib/poolparty/net/remoter_base.rb +9 -4
  27. data/lib/poolparty/net/remoter_bases/ec2/ec2.rb +50 -35
  28. data/lib/poolparty/net/remoter_bases/ec2/ec2_remote_instance.rb +46 -5
  29. data/lib/poolparty/net/remoter_bases/ec2/ec2_response_object.rb +57 -1
  30. data/lib/poolparty/plugins/apache2/apache.rb +13 -160
  31. data/lib/poolparty/plugins/apache2/passenger_site.rb +86 -0
  32. data/lib/poolparty/plugins/apache2/php5.rb +40 -0
  33. data/lib/poolparty/plugins/apache2/virtual_host.rb +53 -0
  34. data/lib/poolparty/plugins/authorized_key.rb +2 -2
  35. data/lib/poolparty/plugins/bind.rb +5 -6
  36. data/lib/poolparty/plugins/{chef.rb → chef/chef.rb} +22 -18
  37. data/lib/poolparty/plugins/{chef_deploy.rb → chef/chef_deploy.rb} +20 -19
  38. data/lib/poolparty/plugins/deploy_directory.rb +2 -3
  39. data/lib/poolparty/plugins/gem_package.rb +6 -12
  40. data/lib/poolparty/plugins/git.rb +22 -7
  41. data/lib/poolparty/{base_packages → plugins}/haproxy.rb +2 -2
  42. data/lib/poolparty/{base_packages → plugins}/heartbeat.rb +7 -7
  43. data/lib/poolparty/plugins/line_in_file.rb +4 -2
  44. data/lib/poolparty/plugins/plugin_template.rb +13 -0
  45. data/lib/poolparty/{base_packages/poolparty.rb → plugins/poolparty_base_packages.rb} +2 -2
  46. data/lib/poolparty/plugins/rails_deploy.rb +2 -3
  47. data/lib/poolparty/{base_packages → plugins}/ruby.rb +3 -3
  48. data/lib/poolparty/{base_packages → plugins}/runit.rb +3 -3
  49. data/lib/poolparty/plugins/svn.rb +8 -6
  50. data/lib/poolparty/poolparty/cloud.rb +5 -8
  51. data/lib/poolparty/poolparty/default.rb +1 -1
  52. data/lib/poolparty/poolparty/plugin.rb +36 -15
  53. data/lib/poolparty/poolparty/pool.rb +6 -2
  54. data/lib/poolparty/poolparty/poolparty_base_class.rb +5 -11
  55. data/lib/poolparty/poolparty/resource.rb +2 -1
  56. data/lib/poolparty/poolparty/service.rb +6 -8
  57. data/lib/poolparty/provision/dr_configure.rb +3 -3
  58. data/lib/poolparty/verification/verifier_base.rb +10 -0
  59. data/spec/bin/server-list-active_spec.rb +1 -3
  60. data/spec/poolparty/core/string_spec.rb +1 -1
  61. data/spec/poolparty/dependency_resolver/chef_resolver_spec.rb +0 -2
  62. data/spec/poolparty/dependency_resolver/dependency_resolver_cloud_extensions_spec.rb +16 -13
  63. data/spec/poolparty/extra/deployments_spec.rb +68 -68
  64. data/spec/poolparty/net/remoter_bases/ec2_spec.rb +1 -0
  65. data/spec/poolparty/plugins/deploydirectory_spec.rb +64 -51
  66. data/spec/poolparty/poolparty/cloud_spec.rb +21 -19
  67. data/spec/poolparty/poolparty/configurers/files/ruby_basic.rb +1 -1
  68. data/spec/poolparty/poolparty/configurers/files/ruby_plugins.rb +1 -1
  69. data/spec/poolparty/{base_packages → poolparty}/haproxy_spec.rb +1 -1
  70. data/spec/poolparty/{base_packages → poolparty}/heartbeat_spec.rb +1 -1
  71. data/spec/poolparty/poolparty/plugin_model_spec.rb +6 -13
  72. data/spec/poolparty/poolparty/plugin_spec.rb +7 -7
  73. data/spec/poolparty/poolparty/resource_spec.rb +15 -5
  74. data/spec/poolparty/poolparty/test_plugins/webserver.rb +27 -23
  75. data/test/fixtures/metavirt_cloud.json +1 -0
  76. data/test/poolparty/dependency_resolver/puppet_resolver_test.rb +0 -5
  77. data/test/poolparty/modules/cloud_dsl_test.rb +1 -1
  78. data/test/poolparty/monitors/test_base_monitor.rb +17 -0
  79. data/test/poolparty/monitors/test_monitor_rack.rb +39 -0
  80. data/test/poolparty/net/remoter_base_test.rb +18 -0
  81. data/test/poolparty/plugins/chef_deploy_test.rb +1 -1
  82. data/test/poolparty/plugins/rails_deploy_test.rb +3 -3
  83. data/test/poolparty/poolparty/cloud_test.rb +27 -2
  84. data/test/poolparty/poolparty/isolated_cloud_test.rb +25 -0
  85. data/test/poolparty/poolparty/plugin_test.rb +9 -8
  86. data/test/poolparty/poolparty/schema_test.rb +13 -0
  87. data/test/poolparty/verification/verify_test.rb +4 -0
  88. data/test/test_helper.rb +10 -3
  89. data/test/test_methods.rb +11 -0
  90. data/vendor/gems/dslify/test/dslify_test.rb +28 -0
  91. metadata +29 -15
  92. data/lib/poolparty/extra/deployments.rb +0 -31
  93. data/lib/poolparty/poolparty/plugin_model.rb +0 -46
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :minor: 2
3
- :patch: 8
3
+ :patch: 9
4
4
  :major: 1
@@ -17,21 +17,21 @@ EOS
17
17
 
18
18
  short_desc "show a list of the current instances on the clouds"
19
19
 
20
- run do |command|
20
+ run do |command|
21
21
  @loaded_clouds.each do |cld|
22
22
  if command[:instance_id]
23
23
  require 'pp'
24
- pp result = cld.describe_instance(:instance_id=>command[:instance_id])
24
+ pp result = cld.nodes(:instance_id=>command[:instance_id])
25
25
  else
26
26
  puts "Listing cloud #{cld.name}"
27
27
  puts "Active instances"
28
28
  puts cld.nodes(:status => "running").map{|a| "#{a[:instance_id] || a[:id]}\t#{a[:ip] ||a[:public_ip] }" }.join("\n")
29
-
29
+
30
30
  if cld.nodes(:status => "pending").size > 0
31
31
  puts "Pending instances"
32
32
  puts cld.nodes(:status => "pending").map{|a| "#{a[:instance_id] || a[:id]}\t#{a[:ip] ||a[:public_ip] }" }.join("\n")
33
33
  end
34
34
  end
35
- end
35
+ end
36
36
  end
37
37
  end
@@ -26,11 +26,13 @@ EOS
26
26
  address = cld.nodes[ command[:inst_num] ]
27
27
  ::PoolParty::Provision::BootStrapper.new( address[:ip], :cloud => cld )
28
28
  ::PoolParty::Provision::DrConfigure.new( address[:ip], :cloud => cld )
29
+ cld.call_after_provision_callbacks
29
30
  else
30
31
  cld.nodes(:status => "running").each do |address|
31
32
  cld.vputs "\nConfiguring: #{address[:ip]}\n--------------------"
32
33
  ::PoolParty::Provision::BootStrapper.new( address[:ip], :cloud => cld )
33
34
  ::PoolParty::Provision::DrConfigure.new( address[:ip], :cloud => cld )
35
+ cld.call_after_provision_callbacks
34
36
  end
35
37
  end
36
38
  end
@@ -21,7 +21,7 @@ EOS
21
21
 
22
22
  if !nodes.empty?
23
23
  n = command[:inst_num] ? command[:inst_num].to_i : 0
24
- @cloud.ssh_into( nodes[n].ip ) if @cloud
24
+ @cloud.ssh_into( nodes[n].ip || nodes[n].public_ip ) if @cloud
25
25
  else
26
26
  puts "No running instances can be found"
27
27
  end
@@ -9,7 +9,7 @@ say("\nWhat remoter base would you like to use?")
9
9
  choose do |menu|
10
10
  menu.prompt = "> "
11
11
 
12
- available_bases.each do |base|
12
+ PoolParty::Remote::RemoterBase.available_bases.each do |base|
13
13
  menu.choice base.to_sym do
14
14
 
15
15
  say "Great, we'll be using #{base}"
@@ -1,27 +1,36 @@
1
+ require 'rubygems'
2
+ $:.unshift "#{File.dirname(__FILE__)}/../lib"
3
+ require "poolparty"
4
+
1
5
  # Basic pool spec
2
6
  # Shows global settings for the clouds
3
- pool :application do
7
+ pool :party do
4
8
  instances 1..3
5
- ami 'ami-7cfd1a15'
9
+ image_id 'ami-7cfd1a15'
10
+ debugging true
6
11
 
7
- cloud :example_one do
8
- keypair 'front'
9
- has_directory "/var/www"
10
-
11
- has_file "/etc/motd",
12
- :content => "Welcome to LARubyConf"
13
- has_file :name => "/var/www/index.html" do
14
- content "<h1>Welcome to your new poolparty instance</h1>"
15
- mode 0644
16
- owner "www-data"
12
+ access_key "XXXXXX"
13
+ secret_access_key "XXXXXXX"
14
+
15
+ cloud :app do
16
+ keypair 'app'
17
+ using :ec2 do
18
+ image_id 'ami-7cfd1a15'
19
+ availability_zone 'us-east-1c'
17
20
  end
18
21
 
19
- has_git_repo "paparazzi" do
20
- source "git://github.com/auser/paparazzi.git"
21
- at "/var/www"
22
- end
22
+ has_file "/etc/motd", :content => "Welcome to LARubyConf"
23
+ # has_directory "/var/www"
24
+ # has_file :name => "/var/www/index.html" do
25
+ # content "<h1>Welcome to your new poolparty instance</h1>"
26
+ # mode 0644
27
+ # owner "www-data"
28
+ # end
23
29
 
24
- apache
30
+ # has_git "paparazzi" do
31
+ # source "git://github.com/auser/paparazzi.git"
32
+ # dir "/var/www"
33
+ # end
25
34
 
26
35
  end
27
36
 
@@ -5,17 +5,15 @@ require "poolparty"
5
5
  pool :multiverse do
6
6
 
7
7
  cloud :vv do
8
- keypair "front"
9
8
  instances 2
10
9
  has_file "/etc/motd", :content => "Welcome to your poolparty instance!"
11
10
  using :metavirt do
12
- server_config({:host=>"172.16.68.1", :port=>3000})
11
+ server_config({:host=>"192.168.248.1", :port=>3000})
13
12
  authorized_keys 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCTppECfx7Tb0zoviRfqFaePyAek6+ZktKkHiTHu/jkhG1s4q1oHEe89no21xLxuReyJrDlNe8rLxxZzoYCaAWRdhcqMR3BNqb2w2jpF4pH+bFj0557KrwWP6HSNpRRkyYhxLqZbuH/2t3TzkPevZbcfSYa09jIzqnmTruh9l1s+n5E3cNr/RDdDn7tv3Ok7mKN7GEjkK7F83Pt9xviHevg22xqzm99nS+hg6Kl/fQUTO6pOmC5x+9V47RJz1+9WdhGJ7M83zijX9rMnAwrR5LFoL6aZyyU0G71SpoIL5e8XD/jt1WNKFJOfG8YMLb3i03UABm/Q5Q30+R7UoRxSWRX'
14
13
  using :vmrun do
15
14
  # vmx_files Dir[::File.expand_path("~/Documents/Virtual Machines.localized/metavirts/*/*.vmx")]
16
15
  vmx_files [
17
- "/Users/mfairchild/Documents/Virtual\ Machines.localized/Ubuntu-jaunty.vmwarevm/Ubuntu-jaunty.vmx",
18
- "/Users/mfairchild/Documents/Virtual\ Machines.localized/metavirts/Ubuntu32bitVM copy.vmwarevm/Ubuntu32bitVM.vmx"
16
+ "/Users/alerner/Documents/vm/Ubuntu32bitVM.vmwarevm/Ubuntu32bitVM.vmx"
19
17
  ]
20
18
  end
21
19
  end
@@ -2,7 +2,7 @@ $LOAD_PATH<< File.dirname(__FILE__)
2
2
  # Load required gems
3
3
  #TODO: remove activesupport
4
4
  @required_software = Array.new
5
- %w(rubygems activesupport ftools logging resolv digest/sha2 json pp).each do |lib|
5
+ %w(rubygems fileutils resolv digest/sha2 json pp).each do |lib|
6
6
  begin
7
7
  require lib
8
8
  rescue Exception => e
@@ -75,7 +75,7 @@ $_poolparty_load_directories = [
75
75
  "dependency_resolver",
76
76
  "aska.rb",
77
77
  "config",
78
- "monitors/monitor_rack",
78
+ "monitors/monitor_rack.rb",
79
79
  "capistrano.rb",
80
80
  'provisioners/provisioner_base.rb',
81
81
  'provisioners/capistrano/capistrano.rb',
@@ -132,14 +132,9 @@ class Object
132
132
  include PoolParty
133
133
  include PoolParty::Pool
134
134
  include PoolParty::Cloud
135
-
136
135
  include PoolParty::DefinableResource
137
136
  end
138
137
 
139
- class Class
140
- include PoolParty::PluginModel
141
- end
142
-
143
138
  ## Load PoolParty Plugins and package
144
139
  module PoolParty
145
140
  %w(plugins base_packages).each do |dir|
@@ -34,7 +34,7 @@ class Array
34
34
  def select_with_hash(conditions={})
35
35
  return self if conditions.empty?
36
36
  select do |node|
37
- conditions.any? do |k,v|
37
+ conditions.any? do |k,v|
38
38
  ( node.has_key?(k) && node[k]==v ) or ( node.respond_to?(k) && node.send(k)==v )
39
39
  end
40
40
  end
@@ -2,7 +2,7 @@
2
2
  Exception overloads
3
3
  =end
4
4
  class Exception
5
- alias nice_message to_str
5
+ alias :nice_message :to_s
6
6
  # Gives us a nice_message for exceptions
7
7
  def nice_message(padding="")
8
8
  "#{padding}#{message}\n#{padding}"# + backtrace.join("\n#{padding}")
@@ -97,17 +97,24 @@ class Hash
97
97
  self
98
98
  end
99
99
 
100
- def symbolize_keys
101
- dup.stringify_keys!
100
+ def symbolize_keys(key_modifier=nil)
101
+ dup.symbolize_keys!(key_modifier)
102
102
  end
103
103
 
104
104
  # Converts all of the keys to strings
105
- def symbolize_keys!
105
+ # can pass in a :key_modifier that will be sent to each key, before being symbolized.
106
+ # This can be usefull if you want to downcase, or snake_case each key.
107
+ # >> {'Placement' => {'AvailabilityZone'=>"us-east-1a"} }.symbolize_keys(:snake_case)
108
+ # => {:placement=>{:availability_zone=>"us-east-1a"}}
109
+ def symbolize_keys!(key_modifier=nil)
106
110
  keys.each{|k|
107
111
  v = delete(k)
112
+ if key_modifier && k.respond_to?(key_modifier)
113
+ k = k.send(key_modifier)
114
+ end
108
115
  self[k.to_sym] = v
109
- v.symbolize_keys! if v.is_a?(Hash)
110
- v.each{|p| p.symbolize_keys! if p.is_a?(Hash)} if v.is_a?(Array)
116
+ v.symbolize_keys!(key_modifier) if v.is_a?(Hash)
117
+ v.each{|p| p.symbolize_keys!(key_modifier) if p.is_a?(Hash)} if v.is_a?(Array)
111
118
  }
112
119
  self
113
120
  end
@@ -0,0 +1,11 @@
1
+ class Integer
2
+ def months
3
+ PoolParty::Duration.new(self * 30.days, [[:months, self]])
4
+ end
5
+ alias :month :months
6
+
7
+ def years
8
+ PoolParty::Duration.new(self * 365.25.days, [[:years, self]])
9
+ end
10
+ alias :year :years
11
+ end
@@ -106,4 +106,18 @@ class Object
106
106
  def unix_hide_string
107
107
  "2>&1 > /dev/null"
108
108
  end
109
+
110
+ # Get object's meta (ghost, eigenclass, singleton) class
111
+ # from activesupport
112
+ def metaclass
113
+ class << self
114
+ self
115
+ end
116
+ end
117
+
118
+ # If class_eval is called on an object, add those methods to its metaclass
119
+ # from activesupport
120
+ def class_eval(*args, &block)
121
+ metaclass.class_eval(*args, &block)
122
+ end
109
123
  end
@@ -60,7 +60,7 @@ class String
60
60
  # Refactor this guy to get the class if the class is defined, and not always create a new one
61
61
  # although, it doesn't really matter as ruby will just reopen the class
62
62
  def class_constant(superclass=nil, opts={}, &block)
63
- symc = ((opts && opts[:preserve]) ? ("#{self.camelcase}Class") : "PoolParty#{self.camelcase}Class").classify
63
+ symc = ((opts && opts[:preserve]) ? ("#{self.camelcase}") : "PoolParty#{self.camelcase}").classify
64
64
 
65
65
  kla=<<-EOE
66
66
  class #{symc} #{"< #{superclass}" if superclass}
@@ -203,5 +203,10 @@ class String
203
203
  result.symbolize_keys!
204
204
  end
205
205
  end
206
+
207
+ # dumb and ugly pluralize
208
+ def pluralize(count=2)
209
+ count > 1 ? self + "s" : self
210
+ end
206
211
 
207
212
  end
@@ -53,4 +53,10 @@ class Numeric
53
53
  in_units = (seconds / 1.send(unit))
54
54
  "#{in_units.to_i} #{in_units != 1 ? unit.to_s.pluralize : unit} ago"
55
55
  end
56
+ end
57
+
58
+ class Time
59
+ def to_time
60
+ self
61
+ end
56
62
  end
@@ -0,0 +1,96 @@
1
+ module PoolParty
2
+ # Provides accurate date and time measurements using Date#advance and
3
+ # Time#advance, respectively. It mainly supports the methods on Numeric,
4
+ # such as in this example:
5
+ #
6
+ # 1.month.ago # equivalent to Time.now.advance(:months => -1)
7
+ class Duration
8
+ attr_accessor :value, :parts
9
+
10
+ def initialize(value, parts) #:nodoc:
11
+ @value, @parts = value, parts
12
+ end
13
+
14
+ # Adds another Duration or a Numeric to this Duration. Numeric values
15
+ # are treated as seconds.
16
+ def +(other)
17
+ if Duration === other
18
+ Duration.new(value + other.value, @parts + other.parts)
19
+ else
20
+ Duration.new(value + other, @parts + [[:seconds, other]])
21
+ end
22
+ end
23
+
24
+ # Subtracts another Duration or a Numeric from this Duration. Numeric
25
+ # values are treated as seconds.
26
+ def -(other)
27
+ self + (-other)
28
+ end
29
+
30
+ def -@ #:nodoc:
31
+ Duration.new(-value, parts.map { |type,number| [type, -number] })
32
+ end
33
+
34
+ def is_a?(klass) #:nodoc:
35
+ klass == Duration || super
36
+ end
37
+
38
+ # Returns true if <tt>other</tt> is also a Duration instance with the
39
+ # same <tt>value</tt>, or if <tt>other == value</tt>.
40
+ def ==(other)
41
+ if Duration === other
42
+ other.value == value
43
+ else
44
+ other == value
45
+ end
46
+ end
47
+
48
+ def self.===(other) #:nodoc:
49
+ other.is_a?(Duration) rescue super
50
+ end
51
+
52
+ # Calculates a new Time or Date that is as far in the future
53
+ # as this Duration represents.
54
+ def since(time = ::Time.current)
55
+ sum(1, time)
56
+ end
57
+ alias :from_now :since
58
+
59
+ # Calculates a new Time or Date that is as far in the past
60
+ # as this Duration represents.
61
+ def ago(time = ::Time.current)
62
+ sum(-1, time)
63
+ end
64
+ alias :until :ago
65
+
66
+ def inspect #:nodoc:
67
+ consolidated = parts.inject(::Hash.new(0)) { |h,part| h[part.first] += part.last; h }
68
+ [:years, :months, :days, :minutes, :seconds].map do |length|
69
+ n = consolidated[length]
70
+ "#{n} #{n == 1 ? length.to_s.singularize : length.to_s}" if n.nonzero?
71
+ end.compact.to_sentence
72
+ end
73
+
74
+ protected
75
+
76
+ def sum(sign, time = ::Time.current) #:nodoc:
77
+ parts.inject(time) do |t,(type,number)|
78
+ if t.acts_like?(:time) || t.acts_like?(:date)
79
+ if type == :seconds
80
+ t.since(sign * number)
81
+ else
82
+ t.advance(type => sign * number)
83
+ end
84
+ else
85
+ raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
86
+ end
87
+ end
88
+ end
89
+
90
+ private
91
+
92
+ def method_missing(method, *args, &block) #:nodoc:
93
+ value.send(method, *args)
94
+ end
95
+ end
96
+ end
@@ -1,4 +1,4 @@
1
- require "ftools"
1
+ require "fileutils"
2
2
  module PoolParty
3
3
 
4
4
  # Load a file that contains a pool into memory
@@ -6,7 +6,7 @@
6
6
 
7
7
  method is stored, for instance. It's also where the key convenience methods are written
8
8
  =end
9
- require "ftools"
9
+ require "fileutils"
10
10
 
11
11
  module PoolParty
12
12
  module CloudResourcer
@@ -19,6 +19,9 @@ module PoolParty
19
19
  name.to_s.new_resource_class &block
20
20
  end
21
21
 
22
+ # DEPRICATED
23
+ # use plugin instead
24
+ #
22
25
  # Allow us to create virtual resources
23
26
  # Generally, in plugins
24
27
  # This sets a virtual resource against the Resource class
@@ -41,13 +44,8 @@ module PoolParty
41
44
  #
42
45
  # An example is included in the poolparty-apache-plugin
43
46
  def virtual_resource(name=:virtual_resource, opts={}, &block)
44
- symc = "#{name}".top_level_class.camelcase
45
- klass = symc.class_constant(PoolParty::Plugin::Plugin, {:preserve => true}, &block)
46
-
47
- PoolParty::Service.add_has_and_does_not_have_methods_for(symc)
48
-
49
- klass.module_eval &block if block
50
- klass
47
+ $stderr.puts "virtual_resource (#{name}) is depricated"
48
+ plugin(name, &block)
51
49
  end
52
50
 
53
51
  end
@@ -6,8 +6,8 @@ module PoolParty
6
6
  args.each do |line|
7
7
  (output ||= []) << line
8
8
  end
9
- end
10
- end
9
+ end
10
+ end
11
11
 
12
12
  end
13
13
  end
@@ -5,12 +5,28 @@
5
5
  monitors
6
6
  =end
7
7
  module Monitors
8
+
9
+ @available_monitors =[]
10
+ def self.available
11
+ @available_monitors
12
+ end
13
+
8
14
  class BaseMonitor
9
15
 
16
+ def self.inherited(subclass)
17
+ unless Monitors.available.include?(subclass)
18
+ Monitors.available << subclass
19
+ end
20
+ end
21
+
10
22
  def initialize(env=nil)
11
23
  @env=env
12
24
  end
13
25
 
26
+ def env(env=@env)
27
+ @env=env
28
+ end
29
+
14
30
  %w(close).each do |event|
15
31
  %w(before after).each do |time|
16
32
  module_eval <<-EOE
@@ -28,5 +44,6 @@ module Monitors
28
44
  def after_close_callbacks
29
45
  @after_close_callbacks ||= []
30
46
  end
47
+
31
48
  end
32
49
  end