auser-poolparty 1.2.11 → 1.2.12

Sign up to get free protection for your applications and to get access to all the features.
data/README.txt CHANGED
@@ -63,4 +63,5 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
63
63
  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
64
64
  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
65
65
  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
66
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
66
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
67
+
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :minor: 2
3
- :patch: 11
3
+ :patch: 12
4
4
  :major: 1
@@ -5,7 +5,7 @@ require "poolparty"
5
5
  pool :multiverse do
6
6
 
7
7
  cloud :front do
8
- instances 1
8
+ instances 2..4
9
9
  keypair 'multiverse_front'
10
10
  has_file "/etc/motd", :content => "Welcome to your poolparty instance!"
11
11
  using :metavirt do
@@ -7,6 +7,18 @@ class Array
7
7
  map {|a| a.to_os }
8
8
  end
9
9
 
10
+ def histogram
11
+ out = {}
12
+ map do |ele|
13
+ if out.has_key?(ele)
14
+ out[ele] += 1
15
+ else
16
+ out.merge!(ele => 1)
17
+ end
18
+ end
19
+ out
20
+ end
21
+
10
22
  def collect_with_index &block
11
23
  self.enum_for(:each_with_index).collect &block
12
24
  end
@@ -47,7 +47,7 @@ module PoolParty
47
47
  # * /etc/poolparty
48
48
  # * /var/poolparty
49
49
  def default_paths
50
- [
50
+ @default_searchable_paths ||= [
51
51
  Dir.pwd,
52
52
  PoolParty::Default.poolparty_home_path,
53
53
  PoolParty::Default.base_keypair_path,
@@ -58,6 +58,11 @@ module PoolParty
58
58
  ]
59
59
  end
60
60
 
61
+ def add_searchable_path(path)
62
+ default_paths # instantiate @default_searchable_paths
63
+ @default_searchable_paths << path
64
+ end
65
+
61
66
  # returns the full set of valid searchable paths, given the options
62
67
  def searchable_paths
63
68
  return @paths_override if @paths_override && @paths_override.size > 0
@@ -12,7 +12,7 @@ module PoolParty
12
12
  # Add to the suitcase files below the clouds.rb base directory
13
13
  def pack_user_directory(dirname)
14
14
  begin
15
- ::Suitcase::Zipper.add("#{::File.dirname($pool_specfile)}/#{dirname}", "etc")
15
+ ::Suitcase::Zipper.add("#{::File.dirname($pool_specfile)}/#{dirname}", "/etc/poolparty")
16
16
  rescue Exception => e
17
17
  vputs "Error packing user directory #{dirname}: #{e}"
18
18
  end
@@ -12,15 +12,24 @@ module Monitors
12
12
  end
13
13
 
14
14
  class BaseMonitor
15
+ attr_reader :log_file, :log_file_path, :last_cloud_loaded_time
15
16
 
16
17
  def self.inherited(subclass)
17
18
  unless Monitors.available.include?(subclass)
18
- Monitors.available << subclass
19
+ Monitors.available << subclass unless subclass.to_s =~ /MonitorDaemon/
19
20
  end
20
21
  end
21
22
 
22
23
  def initialize(env=nil)
23
24
  @env=env
25
+ log_filename = "poolparty_monitor.log"
26
+ @log_file_path = "/var/log/poolparty/#{log_filename}"
27
+
28
+ unless ::File.file?(log_file_path)
29
+ ::FileUtils.mkdir_p ::File.dirname(log_file_path) unless ::File.directory?(::File.dirname(log_file_path))
30
+ ::File.open(log_file_path, 'a+') {|f| f << "------ #{Time.now} ------"}
31
+ log_file_path
32
+ end
24
33
  end
25
34
 
26
35
  def env(env=@env)
@@ -38,6 +47,22 @@ module Monitors
38
47
 
39
48
  end
40
49
 
50
+ # Load the cloud
51
+ # Reload the cloud if necessary after 60 seconds
52
+ # of cache time
53
+ def my_cloud
54
+ @my_cloud = nil if last_cloud_loaded_time && last_cloud_loaded_time > 60
55
+ @my_cloud ||= begin
56
+ require '/etc/poolparty/clouds.rb'
57
+ name = open("/etc/poolparty/cloud_name").read
58
+ last_cloud_loaded_time = Time.now.to_i
59
+ clouds[name.chomp.to_sym]
60
+ rescue Exception => e
61
+ JSON.parse( open('/etc/poolparty/clouds.json' ).read )
62
+ end
63
+ end
64
+
65
+
41
66
  def before_close_callbacks
42
67
  @before_close_callbacks ||= []
43
68
  end
@@ -45,5 +70,28 @@ module Monitors
45
70
  @after_close_callbacks ||= []
46
71
  end
47
72
 
73
+ def log(msg)
74
+ log_file.flush
75
+ log_file << "[INFO] - #{Time.now} -- #{msg}\n"
76
+ end
77
+
78
+ private
79
+
80
+ def log_file
81
+ if @logfile
82
+ @logfile
83
+ else
84
+ begin
85
+ ::FileUtils.mkdir_p ::File.dirname(log_file_path) unless ::File.directory?(::File.dirname(log_file_path))
86
+ @logfile ||= ::File.open(log_file_path, 'a+')
87
+ rescue Exception => e
88
+ puts "ERROR: #{e.inspect}"
89
+ @logfile = $stdout
90
+ end
91
+
92
+ end
93
+ end
94
+
95
+
48
96
  end
49
97
  end
@@ -1,9 +1,11 @@
1
1
  require "open-uri"
2
+ require "json"
3
+ require "#{::File.dirname(__FILE__)}/base_monitor"
2
4
 
3
5
  module PoolParty
4
- class MonitorDaemon
6
+ class MonitorDaemon < Monitors::BaseMonitor
5
7
 
6
- attr_reader :should_daemonize, :pid_file, :log_file_path, :sleep_time
8
+ attr_reader :should_daemonize, :pid_file, :sleep_time
7
9
 
8
10
  def self.run(o={})
9
11
  new(o).run
@@ -12,23 +14,32 @@ module PoolParty
12
14
  def initialize(o={})
13
15
  @should_daemonize = o.delete(:daemonize)
14
16
  @pid_file = o.delete(:daemonize) || "/tmp/poolparty_monitor.pid"
15
- temp_log_file_path = o.delete(:log_file_path) || "poolparty_monitor.log"
16
- @log_file_path = temp_log_file_path
17
-
18
- unless ::File.file?(temp_log_file_path)
19
- ::FileUtils.mkdir_p ::File.dirname(temp_log_file_path) unless ::File.directory?(::File.dirname(temp_log_file_path))
20
- ::File.open(temp_log_file_path, 'a+')
21
- temp_log_file_path
22
- end
23
- @sleep_time = o.delete(:sleep_time) || 5
17
+ @sleep_time = o.delete(:sleep_time) || 20
18
+
19
+ super
24
20
  end
25
21
 
26
22
  def pass_the_baton
27
- %w(Memory neighborhood elections).each do |monitor|
28
- out = open("http://localhost:8642/#{monitor}").read
29
- log "#{monitor} / #{out.inspect}"
23
+ # Handle stats
24
+ my_nominations = JSON.parse(open("http://localhost:8642/stats/get_nominations").read)
25
+ unless my_nominations.empty?
26
+ running_nodes = my_cloud.nodes(:status => "running")
27
+ nominations = []
28
+ running_nodes.each do |node|
29
+ timeout(10) do
30
+ log "Checking with #{node.internal_ip} for nominations: #{open("http://#{node.internal_ip}:8642/stats/get_nominations").read}"
31
+ nominations << begin
32
+ JSON.parse(open("http://#{node.internal_ip}:8642/stats/nominations").read) || "none"
33
+ rescue
34
+ log "Error when connecting to #{node.internal_ip}: #{e.inspect}"
35
+ "none"
36
+ end
37
+ end
38
+ end
39
+ log "Sending #{nominations.flatten.to_json} to #{server["/elections"].inspect}"
40
+ # put to "http://localhost:8642/elections/handle_election", data => nominations.to_json
41
+ server["/elections"].put(nominations.flatten.to_json)
30
42
  end
31
- sleep sleep_time
32
43
  end
33
44
 
34
45
  def run
@@ -37,7 +48,14 @@ module PoolParty
37
48
  daemonize
38
49
  else
39
50
  log "Starting MonitorDaemon"
40
- loop {pass_the_baton}
51
+ loop {
52
+ begin
53
+ pass_the_baton
54
+ rescue Exception => e
55
+ log "There was an error with pass_the_baton: #{e}"
56
+ end
57
+ sleep sleep_time
58
+ }
41
59
  end
42
60
  end
43
61
 
@@ -71,29 +89,7 @@ module PoolParty
71
89
 
72
90
  Process.detach(pid)
73
91
  end
74
-
75
- def log(msg)
76
- log_file.flush
77
- log_file << "[INFO] - #{Time.now} -- #{msg}\n"
78
- end
79
-
80
- private
81
-
82
- def log_file
83
- if @logfile
84
- @logfile
85
- else
86
- begin
87
- ::FileUtils.mkdir_p ::File.dirname(log_file_path) unless ::File.directory?(::File.dirname(log_file_path))
88
- @logfile ||= ::File.open(log_file_path, 'a+')
89
- rescue Exception => e
90
- puts "ERROR: #{e.inspect}"
91
- @logfile = $stdout
92
- end
93
92
 
94
- end
95
- end
96
-
97
93
  def pid
98
94
  @pid ||= File.file?(pid_file) ? open(pid_file).read.to_i : nil
99
95
  end
@@ -132,7 +128,7 @@ module PoolParty
132
128
  puts "process not found!"
133
129
  nil
134
130
  end
135
-
131
+
136
132
  protected
137
133
  def remove_pid_file
138
134
  File.delete(pid_file) if pid_file && File.exists?(pid_file)
@@ -153,7 +149,20 @@ module PoolParty
153
149
  end
154
150
  end
155
151
  end
156
-
152
+
153
+ def server
154
+ if @server
155
+ @server
156
+ else
157
+ opts = { :content_type =>'application/json',
158
+ :accept => 'application/json',
159
+ :host => 'http://localhost',
160
+ :port => '8642'
161
+ }
162
+ @uri = "#{opts.delete(:host)}:#{opts.delete(:port)}"
163
+ @server = RestClient::Resource.new( @uri, opts)
164
+ end
165
+ end
157
166
 
158
167
  end
159
168
  end
@@ -45,7 +45,11 @@ module Monitors
45
45
  begin
46
46
  path_array= path_map(env['REQUEST_PATH']) || []
47
47
  verb = env['REQUEST_METHOD'].downcase
48
- @response.write map_to_method(path_array, verb).to_json
48
+
49
+ new_body = map_to_method(path_array, verb)
50
+ new_body = new_body.to_json unless (!path_array || path_array.empty? || path_array[0].nil?)
51
+
52
+ @response.write new_body
49
53
  setup_callbacks
50
54
 
51
55
  # rescue Exception=>e
@@ -0,0 +1,34 @@
1
+ =begin rdoc
2
+ Cloud monitor just is a test monitor to hold cloud info
3
+ =end
4
+
5
+ module Monitors
6
+
7
+ class Cloud < BaseMonitor
8
+
9
+ def get(_unused=nil)
10
+ <<-EOE
11
+ #{my_cloud.name}
12
+ #{my_cloud.minimum_instances}..#{my_cloud.maximum_instances}
13
+ EOE
14
+ end
15
+
16
+ def nominations(_unused=nil)
17
+ running_nodes = my_cloud.nodes(:status => "running")
18
+ nominations = []
19
+ running_nodes.each do |node|
20
+ timeout(10) do
21
+ log "Checking with #{node.internal_ip} for nominations: #{open("http://#{node.internal_ip}:8642/stats/get_nominations").read}"
22
+ nominations << begin
23
+ JSON.parse(open("http://#{node.internal_ip}:8642/stats/nominations").read) || "none"
24
+ rescue
25
+ log "Error when connecting to #{node.internal_ip}: #{e.inspect}"
26
+ "none"
27
+ end
28
+ end
29
+ end.histogram
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -1,11 +1,28 @@
1
1
  module Monitors
2
2
  class Elections < BaseMonitor
3
3
 
4
+ # these are the rules that define the
5
+ # elected actions
6
+ def self.candidates
7
+ {
8
+ :expand => :contract,
9
+ :contract => :expand,
10
+ :configure => nil,
11
+ :none => nil
12
+ }
13
+ end
14
+
4
15
  def get(data=nil)
5
16
  'hello'
6
17
  end
7
18
 
8
- def count_ballots(candidates={:expand => 0, :contract => 0}, ballots={})
19
+ def put(data=nil)
20
+ elections = JSON.parse(data)
21
+ log "Received #{elections.histogram.inspect} in Elections Monitor"
22
+ handle_election(elections.histogram)
23
+ end
24
+
25
+ def count_ballots(ballots={}, candidates={:expand => 0, :contract => 0})
9
26
  # Ballots look like:
10
27
  # {host => ["contract"]}
11
28
  # Count the number of nominations for each candidate action
@@ -20,29 +37,39 @@ module Monitors
20
37
  end
21
38
 
22
39
  # Handle the elections
23
- def handle_election(ballots={})
24
- count_votes(ballots)
40
+ # ballots: {"contract" => 1, "expand" => 4}
41
+ def handle_election(ballots={})
25
42
  # Expand the cloud if 50+% of the votes are for expansion
26
43
  # Contract the cloud if 51+% of the votes are for contraction
27
- # Check to make sure an elected action is not already in progress
28
- if (candidates[:expand] - candidates[:contract])/stats.keys.size > 0.5
29
- %x[server-cloud-elections expand] unless elected_action == "expand"
30
- @elected_action = "expand"
31
- elsif (candidates[:contract] - candidates[:expand])/stats.keys.size > 0.5
32
- %x[server-cloud-elections contract] unless elected_action == "contract"
33
- @elected_action = "contract"
44
+ # Check to make sure an elected action is not already in progress
45
+ log "handle_election: #{ballots.inspect}"
46
+ ballots.symbolize_keys!
47
+ total_votes = ballots.inject(0) {|total, arr| total += arr[1] }
48
+
49
+ ballots.each do |ballot, pro_votes|
50
+ contra = self.class.candidates[ballot]
51
+ con_votes = ballots[contra] || 0
52
+
53
+ if (pro_votes - con_votes)/total_votes > 0.5
54
+ return run_elected_action(ballot)
55
+ end
34
56
  end
35
-
36
- reload_data!
37
- stats[my_ip]["elected_action"] = @elected_action if @elected_action
38
- log << "#{Time.now.strftime("%Y-%m-%d-%H-%M")}, #{stats.to_json}\n"
39
- stats.to_json
40
57
  end
41
-
42
- def my_cloud
43
- require '/etc/poolparty/clouds.rb'
44
- name = open("/etc/poolparty/cloudname").read
45
- clouds[name.to_sym]
58
+
59
+ def run_elected_action(ballot)
60
+ log "Electing #{ballot}"
61
+ case ballot
62
+ when :expand
63
+ my_cloud.running_action = :expanding
64
+ my_cloud.launch_instance!(:cloud_name => my_cloud.name)
65
+ my_cloud.running_action = nil
66
+ when :contract
67
+ my_cloud.running_action = :contracting
68
+ my_cloud.terminate_youngest_instance!
69
+ my_cloud.running_action = nil
70
+ else
71
+ "none"
72
+ end
46
73
  end
47
74
 
48
75
  end
@@ -26,7 +26,6 @@ module Monitors
26
26
  })
27
27
  end
28
28
  make_aska_rules(@cloud["options"]["rules"])
29
- log << "#{::Time.now.strftime("%Y-%m-%d-%H-%M")}, #{stats.to_json}\n"
30
29
  end
31
30
 
32
31
  def get(data=nil)
@@ -36,7 +35,6 @@ module Monitors
36
35
  else
37
36
  stats[request.params[0].to_sym] ||= self.send(request.params[0])
38
37
  stats[request.params[0].to_sym]
39
- log << "#{::Time.now.strftime("%Y-%m-%d-%H-%M")}, #{stats.to_json}\n"
40
38
  stats.to_json
41
39
  end
42
40
  rescue Exception => e
@@ -44,11 +42,16 @@ module Monitors
44
42
  end
45
43
  end
46
44
 
45
+ #alias to allow access thru http route GET /stats/nominations
46
+ def get_nominations(_nodes=[])
47
+ nominations
48
+ end
49
+
47
50
  def put(data)
48
51
  if d = JSON.parse(request.params)
49
52
  hsh = d.reject {|ip, _node| ip == my_ip }
50
53
  stats.merge!(hsh)
51
- handle_election
54
+ # handle_election
52
55
  else
53
56
  "boom"
54
57
  end
@@ -57,21 +60,6 @@ module Monitors
57
60
 
58
61
  protected
59
62
 
60
- def log(log_file_path="/var/log/poolparty/stats_monitor.log")
61
- if @logfile
62
- @logfile
63
- else
64
- begin
65
- ::File.file? log_file_path
66
- ::FileUtils.mkdir_p ::File.dirname(log_file_path) unless ::File.directory?(::File.dirname(log_file_path))
67
- @logfile ||= ::File.open(log_file_path, 'a+')
68
- rescue Exception => e
69
- @log_file = $stdout
70
- end
71
-
72
- end
73
- end
74
-
75
63
  # Handle the elections
76
64
  def handle_election
77
65
  # Ballots look like:
@@ -96,7 +84,7 @@ module Monitors
96
84
 
97
85
  reload_data!
98
86
  stats[my_ip]["elected_action"] = @elected_action if @elected_action
99
- log << "#{Time.now.strftime("%Y-%m-%d-%H-%M")}, #{stats.to_json}\n"
87
+ log "#{Time.now.strftime("%Y-%m-%d-%H-%M")}, #{stats.to_json}\n"
100
88
  stats.to_json
101
89
  end
102
90
 
@@ -128,9 +116,7 @@ module Monitors
128
116
  end
129
117
 
130
118
  def instances(_n=nil)
131
- # res = PoolParty::Neighborhoods.load_default.instances
132
- res ||= %x[server-list-active internal_ip].split("\t")
133
- res
119
+ my_cloud.nodes(:status => "running")
134
120
  end
135
121
 
136
122
  def can_expand?(_n=nil)
@@ -142,45 +128,50 @@ module Monitors
142
128
  end
143
129
 
144
130
  def min_instances(_n=nil)
145
- (@cloud["options"]["minimum_instances"] || PoolParty::Default.minimum_instances).to_i
131
+ (my_cloud.minimum_instances || PoolParty::Default.minimum_instances).to_i
146
132
  end
147
133
 
148
134
  def max_instances(_n=nil)
149
- (@cloud["options"]["maximum_instances"] || PoolParty::Default.maximum_instances).to_i
135
+ (my_cloud.maximum_instances || PoolParty::Default.maximum_instances).to_i
150
136
  end
151
137
 
152
138
  def nominations(_n=nil)
153
139
  # return ['expand'] if instances.size<min_instances
154
140
  load = stats[my_ip]["load"] ||= self.send(:load)
155
- stats[my_ip]["nominations"] ||= rules.collect do |k,cld_rules|
141
+ nominations = if my_cloud.running_action
142
+ ["none"]
143
+ else
144
+ collect_nominations
145
+ end
146
+ # Hackity hack hack
147
+ nominations << "expand" if my_cloud.nodes(:status => "running").size < min_instances
148
+ nominations << "contract" if my_cloud.nodes(:status => "running").size > max_instances
149
+ stats[my_ip]["nominations"] = nominations #TODO: Deprecate
150
+ nominations
151
+ end
152
+
153
+ def collect_nominations
154
+ nominations = rules.collect do |k,cld_rules|
156
155
  t = cld_rules.collect do |r|
157
156
  # If the comparison works
158
157
  if self.send(r.key.to_sym).to_f.send(r.comparison, r.var.to_f)
159
158
  # if we are facing an expansion rule
160
159
  if k =~ /expand/
161
160
  k if can_expand?
162
- neigborhood.each do |i|
163
- RestClient.put "#{i.ip}/elections", stats.to_json, :content_type => 'text/x-json'
164
- end
165
161
  # if we are facing a contraction rule
166
162
  elsif k =~ /contract/
167
163
  k if can_contract?
168
164
  else
169
165
  k
170
166
  end
171
- end
167
+ end
172
168
  end.compact
173
- end.flatten.compact
169
+ end.flatten.compact
174
170
  end
175
171
 
176
172
  def neighborhood
177
173
  @neighborhood ||= clouds[open('/etc/poolparty/cloud_name').read].nodes
178
174
  end
179
-
180
- #alias to allow access thru http route GET /stats/nominations
181
- def get_nominations(_nodes=[])
182
- nominations.to_json
183
- end
184
175
 
185
176
  def get_hello(_n=nil)
186
177
  'hi there'
@@ -191,6 +191,10 @@ module PoolParty
191
191
  def self.launch_instance!(o={}, &block)
192
192
  new(o, &block).launch_instance!
193
193
  end
194
+
195
+ def terminate_youngest_instance!(o={})
196
+ terminate_instance!(:instance_id => nodes(:status => "running").last.instance_id)
197
+ end
194
198
 
195
199
  # Called after an instance is launched
196
200
  def after_launch_instance(instance=nil)
@@ -25,6 +25,10 @@ module PoolParty
25
25
  }
26
26
  end
27
27
 
28
+ def instance_id
29
+ vmx_file
30
+ end
31
+
28
32
  def status
29
33
  ping_port(ip, 22, 1) ? "running" : "terminated"
30
34
  end
@@ -29,7 +29,7 @@ module PoolParty
29
29
 
30
30
  def extras(*names)
31
31
  names.each do |name|
32
- has_package(:name => "php5-#{name}", :requires => get_package("php5"))
32
+ has_package(:name => "php5-#{name}")
33
33
  end
34
34
  end
35
35
 
@@ -27,6 +27,7 @@ The sshkey resource specifies an ssh key that should be distributed on all the n
27
27
 
28
28
  dsl_methods(:key,
29
29
  :keypath,
30
+ :content,
30
31
  :name)
31
32
 
32
33
  default_options(:type => 'rsa', :mode => "600")
@@ -39,7 +40,7 @@ The sshkey resource specifies an ssh key that should be distributed on all the n
39
40
 
40
41
  def loaded(opts={}, &block)
41
42
  has_directory(::File.dirname(opts[:name]))
42
- has_file(:name => opts[:name], :content => self.key, :mode => opts[:mode])
43
+ has_file(:name => opts[:name], :content => opts[:content], :mode => opts[:mode])
43
44
  end
44
45
 
45
46
 
@@ -21,7 +21,7 @@ module PoolParty
21
21
 
22
22
  class Cloud < PoolParty::PoolPartyBaseClass
23
23
  attr_reader :templates, :cloud_name, :remote_base
24
- attr_accessor :started_instance
24
+ attr_accessor :started_instance, :running_action
25
25
 
26
26
  # Default set of options. Most take the Default options from the default class
27
27
  default_options(
@@ -51,6 +51,7 @@ module PoolParty
51
51
  #%w(monitors plugins verifiers).each do |lib|
52
52
  # Dir[File.join(::File.dirname(::File.basename(filename)), lib, '*')].each{|f| require f }
53
53
  # end
54
+ call_before_all_loaded(pool_specfile || filename)
54
55
  o = File.open(filename, 'r') do |f|
55
56
  instance_eval f.read, (pool_specfile || filename)
56
57
  end
@@ -58,7 +59,15 @@ module PoolParty
58
59
  o
59
60
  end
60
61
 
61
- # callback
62
+ # callbacks
63
+ def self.call_before_all_loaded(filepath)
64
+ # Load the plugins
65
+ $:.unshift(::File.dirname(filepath))
66
+ Dir["#{::File.dirname(filepath)}/plugins/*"].each do |plugin_path|
67
+ $:.unshift(plugin_path)
68
+ end
69
+ end
70
+
62
71
  def after_all_loaded(&block)
63
72
  @after_all_loaded ||= block
64
73
  end
@@ -134,24 +134,20 @@ module PoolParty
134
134
 
135
135
  commands << [
136
136
  "mkdir -p /etc/poolparty",
137
+ "echo #{cloud.name} > /etc/poolparty/cloud_name",
138
+ "echo #{cloud.pool.name}>/etc/poolparty/pool_name",
137
139
  "mkdir -p /var/log/poolparty",
138
140
  "groupadd -f poolparty",
139
141
  # "useradd poolparty --home-dir /var/poolparty --groups poolparty --create-home",
140
- 'cd /var/poolparty/dependencies',
141
- "cp /var/poolparty/dependencies/etc/poolparty/gemrc_template /etc/poolparty",
142
+ "cd /var/poolparty/dependencies && cp /var/poolparty/dependencies/etc/poolparty/gemrc_template /etc/poolparty",
142
143
  "#{installer} update",
143
144
  "#{installer} install -y ruby ruby1.8-dev irb libopenssl-ruby1.8 build-essential wget", #optional, but nice to have
144
- "tar -zxvf packages/rubygems-1.3.4.tgz",
145
- "cd rubygems-1.3.4",
146
- "ruby setup.rb --no-ri --no-rdoc",
147
- "ln -sfv /usr/bin/gem1.8 /usr/bin/gem", #TODO: check if this is really needed
148
- "cd ../ && rm -rf rubygems-1.3.1*",
145
+ "tar -zxvf packages/rubygems-1.3.4.tgz && cd rubygems-1.3.4 && ruby setup.rb --no-ri --no-rdoc && ln -sfv /usr/bin/gem1.8 /usr/bin/gem && cd ../ && rm -rf rubygems-1.3.1*",
149
146
  "gem source --add http://gems.github.com",
150
- "gem sources -a http://gems.opscode.com",
147
+ "gem source -a http://gems.opscode.com",
151
148
  "cd /var/poolparty/dependencies/gems/",
152
149
  "gem install --no-rdoc --no-ri *.gem",
153
- "cd /var/poolparty/dependencies",
154
- "cp /var/poolparty/dependencies/etc/poolparty/* /etc/poolparty/",
150
+ "cd /var/poolparty/dependencies && cp /var/poolparty/dependencies/etc/poolparty/* /etc/poolparty/",
155
151
  'touch /var/poolparty/POOLPARTY.PROGRESS',
156
152
  "mkdir -p /root/.ssh",
157
153
  "cp /var/poolparty/dependencies/keys/* /root/.ssh/",
@@ -160,7 +156,7 @@ module PoolParty
160
156
  "mkdir -p /var/log/poolparty/",
161
157
  "echo '-- Starting monitor_rack --'",
162
158
  # NOTE: if someone has an old version of thin/rack on their system, this will fail silently and never finish bootstrapping
163
- "thin -R /etc/poolparty/monitor.ru -p 8642 --pid /var/run/stats_monitor.pid --daemon -l /var/log/poolparty/monitor.log start 2>/dev/null",
159
+ "ps aux | grep thin | grep -v grep | awk '{print $2}' | xargs kill -9; thin -R /etc/poolparty/monitor.ru -p 8642 --pid /var/run/stats_monitor.pid --daemon -l /var/log/poolparty/monitor.log start 2>/dev/null",
164
160
  "tail -n 20 /var/log/poolparty/monitor.log",
165
161
  'echo "bootstrap" >> /var/poolparty/POOLPARTY.PROGRESS']
166
162
  commands << self.class.class_commands unless self.class.class_commands.empty?
@@ -97,6 +97,8 @@ module PoolParty
97
97
  commands << [
98
98
  'chmod 644 /var/poolparty/dr_configure/clouds.json',
99
99
  'chmod 644 /var/poolparty/dr_configure/clouds.rb',
100
+ "cp -R /var/poolparty/dr_configure/etc/poolparty/* /etc/poolparty/",
101
+ # TODO: slightly redundant
100
102
  'cp /var/poolparty/dr_configure/clouds.json /etc/poolparty',
101
103
  'cp /var/poolparty/dr_configure/clouds.rb /etc/poolparty',
102
104
  # 'server-manage-election', #ensures that the monitor gets some data
@@ -107,6 +109,8 @@ module PoolParty
107
109
  end
108
110
 
109
111
  def pack_up_and_ship_off_suitcase
112
+ ::Suitcase::Zipper.add(::File.dirname(pool_specfile), "/etc/poolparty")
113
+
110
114
  ::Suitcase::Zipper.build_dir!("#{cloud.tmp_path}/dr_configure")
111
115
  rsync "#{cloud.tmp_path}/dr_configure/", "/var/poolparty/dr_configure/", ['-a --stats']
112
116
  end
@@ -17,7 +17,7 @@ app = Rack::Builder.new do
17
17
  # Dumb daemon for now
18
18
  begin
19
19
  PoolParty::MonitorDaemon.run :daemonize => true,
20
- :sleep_time => 10,
20
+ :sleep_time => 20,
21
21
  :log_file_path => "/var/log/poolparty/monitor_daemon.log"
22
22
 
23
23
  rescue Exception => e
@@ -25,7 +25,7 @@ describe "Key" do
25
25
  before(:each) do
26
26
  @keypair = "sshkey_test"
27
27
  Dir.stub!(:pwd).and_return "#{::File.dirname(__FILE__)}/test_plugins"
28
-
28
+ Key.add_searchable_path("#{::File.dirname(__FILE__)}/test_plugins")
29
29
  @key = Key.new(@keypair)
30
30
  end
31
31
  it "should search in known locations for the key" do
data/tasks/spec.rake CHANGED
@@ -5,7 +5,7 @@ require 'rake/rdoctask'
5
5
 
6
6
  task :default => [:spec, :test, :cleanup_test]
7
7
  desc "Update vendor directory and run tests"
8
- task :ci => ["poolparty:vendor:setup", "poolparty:vendor:update", :spec, :test]
8
+ task :ci => ["pp:vendor:setup", "pp:vendor:update", :spec, :test]
9
9
 
10
10
  task :cleanup_test do
11
11
  ::FileUtils.rm_rf "/tmp/poolparty"
@@ -18,4 +18,15 @@ class TestWrappingArray < Test::Unit::TestCase
18
18
  end
19
19
  end
20
20
 
21
+ context "histogram" do
22
+ should "provide a histogram" do
23
+ out = %w(tart q a b a a b c).histogram
24
+ assert_equal 1, out["tart"]
25
+ assert_equal 3, out["a"]
26
+ assert_equal 2, out["b"]
27
+ assert_equal 1, out["c"]
28
+ end
29
+ end
30
+
31
+
21
32
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: auser-poolparty
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.11
4
+ version: 1.2.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ari Lerner
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-22 00:00:00 -07:00
12
+ date: 2009-06-23 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -165,6 +165,7 @@ files:
165
165
  - lib/poolparty/monitors/monitor_rack.rb
166
166
  - lib/poolparty/monitors/monitors
167
167
  - lib/poolparty/monitors/monitors/clock_monitor.rb
168
+ - lib/poolparty/monitors/monitors/cloud_monitor.rb
168
169
  - lib/poolparty/monitors/monitors/elections_monitor.rb
169
170
  - lib/poolparty/monitors/monitors/favicon_monitor.rb
170
171
  - lib/poolparty/monitors/monitors/load_monitor.rb