Class: PoolParty::Cloud
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
-
#add_monitoring_stack_if_needed ⇒ Object
Add the monitoring stack.
- #after_all_loaded ⇒ Object
- #before_compile ⇒ Object
-
#cloud_provider(opts = {}, &block) ⇒ Object
The actual cloud_provider instance.
-
#compile(caller = nil) ⇒ Object
Take the cloud’s resources and compile them down using the defined (or the default dependency_resolver, chef).
-
#configure!(opts = {}, threaded = true) ⇒ Object
convenience method to loop thru all the nodes and configure them.
-
#contract!(hsh = {}) ⇒ Object
Contract the cloud.
-
#dependency_resolver(sym = nil) ⇒ Object
Set the dependency resolver.
- #describe_instance(o = {}) ⇒ Object
- #describe_instances(o = {}) ⇒ Object
- #ensure_meta_fun_are_resources ⇒ Object
- #ensure_not_cyclic ⇒ Object
-
#expand(opts = {}, &block) ⇒ Object
1.) Launches a new instance, 2.) Waits for the instance to get an ip address 3.) Waits for port ssh_port to be open 4.) Calls call_after_launch_instance callbacks 5.) Executes passed &block, if any 6.) Returns the new instance object.
-
#form_clouds ⇒ Object
Form the cloud Run the init block with the init_opts on the cloud This is run after the cloud.rb file has been consumed.
-
#initialize(n, o = {}, &block) ⇒ Cloud
constructor
Freeze the cloud_name so we can’t modify it at all, set the plugin_directory call and run instance_eval on the block and then call the after_create callback.
-
#keypair(n = nil) ⇒ Object
returns an instance of Keypair You can pass either a filename which will be searched for in ~/.ec2/ and ~/.ssh/ Or you can pass a full filepath.
-
#monitor(monitor_symbol, &block) ⇒ Object
MONITORS ### Create a new monitor on the cloud == Usage monitor :cpu do |v| vote_for(:expand) if v > 0.8 end.
- #monitor_format(mon_name, meth = nil, &block) ⇒ Object
-
#monitors ⇒ Object
Store the monitors in an array.
-
#nodes(o = {}) ⇒ Object
Cloud provider methods.
-
#os(sym = nil) ⇒ Object
(also: #platform)
Get the os of the first node if it was not explicity defined, we’ll assume they are all homogenous.
-
#pool ⇒ Object
The pool this cloud belongs to.
-
#public_ip ⇒ Object
The public_ip of the cloud is equivalent to the public_ip of the cloud’s oldest node.
-
#resolve_with(a) ⇒ Object
Resolve with the dependency resolver.
-
#run(commands, opts = {}) ⇒ Object
Run command/s on all nodes in the cloud.
- #run_instance(o = {}) ⇒ Object
-
#run_monitor(monitor_name, value) ⇒ Object
Run the monitor logic.
-
#terminate! ⇒ Object
Terminate all instances in the cloud.
- #terminate_instance!(o = {}) ⇒ Object
-
#tmp_path ⇒ Object
Temporary path Starts at the global default tmp path and appends the pool name and the cloud name.
-
#using(provider_symbol, o = {}, &block) ⇒ Object
Declare the CloudProvider for a cloud Create an instance of the cloud provider this cloud is using.
- #validate_all_resources ⇒ Object
Methods inherited from DslBase
Methods inherited from Base
#add_ordered_resources_to_result, #after_loaded, #all_resources, #before_load, #clouds_dot_rb_dir, clouds_dot_rb_dir, #clouds_dot_rb_file, clouds_dot_rb_file, #compile_opts, #create_graph, #dependencies, #get_resource, #has_searchable_paths, #method_missing, #ordered_resources, #output_resources_graph, #resources, #resources_graph, #run_in_context, #run_with_callbacks, #to_s, #valid?, #validations
Methods included from Delayed
Methods included from Callbacks
Methods included from SearchablePaths
Constructor Details
#initialize(n, o = {}, &block) ⇒ Cloud
Freeze the cloud_name so we can’t modify it at all, set the plugin_directory call and run instance_eval on the block and then call the after_create callback
38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/poolparty/cloud.rb', line 38 def initialize(n, o={}, &block) @cloud_name = n @cloud_name.freeze # @init_block = block @init_opts = compile_opts(o) @init_block = Proc.new do super(n,o,&block) end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class PoolParty::Base
Instance Method Details
#add_monitoring_stack_if_needed ⇒ Object
Add the monitoring stack
185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/poolparty/cloud.rb', line 185 def add_monitoring_stack_if_needed if monitors.size > 0 run_in_context do %w(collectd hermes).each do |m| self.send m.to_sym end end end end |
#after_all_loaded ⇒ Object
276 277 278 279 280 |
# File 'lib/poolparty/cloud.rb', line 276 def after_all_loaded run_after_loaded do |b| run_in_context(&b) end end |
#before_compile ⇒ Object
30 31 32 33 34 |
# File 'lib/poolparty/cloud.rb', line 30 def before_compile add_monitoring_stack_if_needed validate_all_resources unless ENV["POOLPARTY_NO_VALIDATION"] end |
#cloud_provider(opts = {}, &block) ⇒ Object
The actual cloud_provider instance
80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/poolparty/cloud.rb', line 80 def cloud_provider(opts={}, &block) return @cloud_provider if @cloud_provider klass_name = "CloudProviders::#{cloud_provider_name}".classify if provider_klass = CloudProviders.all.detect {|k| k.to_s == klass_name } opts.merge!(:cloud => self, :keypair_name => self.keypair.full_filepath) @cloud_provider = provider_klass.new(.merge(opts), &block) else raise PoolParty::PoolPartyError.create("UnknownCloudProviderError", "Unknown cloud_provider: #{cloud_provider_name}") end @cloud_provider end |
#compile(caller = nil) ⇒ Object
Take the cloud’s resources and compile them down using the defined (or the default dependency_resolver, chef)
199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/poolparty/cloud.rb', line 199 def compile(caller=nil) callback :before_compile cloud_provider.before_compile(self) FileUtils.mkdir_p tmp_path unless File.directory?(tmp_path) ddputs <<-EOE Compiling cloud #{self.name} to #{tmp_path/"etc"/"#{dependency_resolver_name}"} number of resources: #{ordered_resources.size} EOE out = dependency_resolver.compile_to(ordered_resources, tmp_path/"etc"/"#{dependency_resolver_name}", caller) cloud_provider.after_compile(self) callback :after_compile out end |
#configure!(opts = {}, threaded = true) ⇒ Object
convenience method to loop thru all the nodes and configure them
132 133 134 |
# File 'lib/poolparty/cloud.rb', line 132 def configure!(opts={}, threaded=true) nodes.collect{|n| n.configure! } end |
#contract!(hsh = {}) ⇒ Object
Contract the cloud
123 124 125 126 127 128 129 |
# File 'lib/poolparty/cloud.rb', line 123 def contract!(hsh={}) inst=nodes(hsh).last inst.callback :before_terminate inst.terminate! inst.callback :after_terminate inst end |
#dependency_resolver(sym = nil) ⇒ Object
Set the dependency resolver
176 177 178 179 180 181 182 |
# File 'lib/poolparty/cloud.rb', line 176 def dependency_resolver(sym=nil) @dependency_resolver ||= case sym when :chef, nil [:dependency_resolver_name] = :chef DependencyResolvers::Chef end end |
#describe_instance(o = {}) ⇒ Object
72 |
# File 'lib/poolparty/cloud.rb', line 72 def describe_instance(o={}); cloud_provider.describe_instance(o);end |
#describe_instances(o = {}) ⇒ Object
71 |
# File 'lib/poolparty/cloud.rb', line 71 def describe_instances(o={}); cloud_provider.describe_instances(o);end |
#ensure_meta_fun_are_resources ⇒ Object
313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/poolparty/cloud.rb', line 313 def resources.each do |res| if res. res..each do |ty, arr| arr.each do |nm, action| raise PoolPartyError.create("ResourceNotFound", "A resource required for #{ty}(#{nm}) was not found: #{ty}(#{nm}). Please make sure you've specified this in your configuration.") unless get_resource(ty, nm) end end end end end |
#ensure_not_cyclic ⇒ Object
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/poolparty/cloud.rb', line 289 def ensure_not_cyclic if resources_graph.cyclic? cycles = [] resources_graph.edges.each do |edge| if resources_graph.adjacent?(edge.source, edge.target) && resources_graph.adjacent?(edge.target, edge.source) && !cycles.include?(edge.source) cycles << "#{edge.source.class}(#{edge.source.name}) depends on #{edge.target.class}(#{edge.target.name})" end end msg =<<-EOE Your resource graph is cyclic. Two resources depend on each other, Cannot decide which resource to go first. Dying instead. Correct this and then try again. #{cycles.join("\n ")} Hint: You can see the resource graph by generating it with: cloud compile -g name EOE raise PoolPartyError.create("CyclicResourceGraphError", msg) end end |
#expand(opts = {}, &block) ⇒ Object
1.) Launches a new instance, 2.) Waits for the instance to get an ip address 3.) Waits for port ssh_port to be open 4.) Calls call_after_launch_instance callbacks 5.) Executes passed &block, if any 6.) Returns the new instance object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/poolparty/cloud.rb', line 98 def (opts={}, &block) timeout = opts.delete(:timeout) || 300 callback :before_launch_instance instance = cloud_provider.run_instance(opts) instance.cloud = self @instance = instance #wait for an ip and then wait for ssh port, then configure instance if instance.wait_for_public_ip(timeout) && instance.wait_for_port(ssh_port, :timeout=>timeout) callback :after_launch_instance instance.callback :before_bootstrap instance.bootstrap! instance.callback :after_bootstrap instance.callback :before_configure instance.configure! instance.callback :after_configure block.call(instance) if block instance else raise StandardError.new("Instance port #{ssh_port} not available") end instance.refresh! instance end |
#form_clouds ⇒ Object
Form the cloud Run the init block with the init_opts on the cloud This is run after the cloud.rb file has been consumed
271 272 273 274 |
# File 'lib/poolparty/cloud.rb', line 271 def form_clouds run_with_callbacks(@init_opts, &@init_block) loaded! end |
#keypair(n = nil) ⇒ Object
returns an instance of Keypair You can pass either a filename which will be searched for in ~/.ec2/ and ~/.ssh/ Or you can pass a full filepath
54 55 56 |
# File 'lib/poolparty/cloud.rb', line 54 def keypair(n=nil) @keypair ||= Keypair.new(n) end |
#monitor(monitor_symbol, &block) ⇒ Object
MONITORS ### Create a new monitor on the cloud
Usage
monitor :cpu do |v|
vote_for(:expand) if v > 0.8
end
236 237 238 |
# File 'lib/poolparty/cloud.rb', line 236 def monitor(monitor_symbol, &block) monitors[monitor_symbol.to_sym] ||= PoolParty::Monitor.new(monitor_symbol, &block) end |
#monitor_format(mon_name, meth = nil, &block) ⇒ Object
255 256 257 258 259 260 261 |
# File 'lib/poolparty/cloud.rb', line 255 def monitor_format(mon_name, meth=nil, &block) if monitors.has_key?(mon_name.to_sym) monitors[mon_name.to_sym].format(meth, &block) else raise PoolPartyError.create("MonitorsFormattingError", "You created a monitor format for an unknown monitor. Please check and try again!") end end |
#monitors ⇒ Object
Store the monitors in an array
251 252 253 |
# File 'lib/poolparty/cloud.rb', line 251 def monitors @monitors ||= {} end |
#nodes(o = {}) ⇒ Object
Cloud provider methods
68 |
# File 'lib/poolparty/cloud.rb', line 68 def nodes(o={}); delayed_action {cloud_provider.nodes(o).collect{|n| n.cloud = self; n}}; end |
#os(sym = nil) ⇒ Object Also known as: platform
Get the os of the first node if it was not explicity defined, we’ll assume they are all homogenous
215 216 217 218 219 220 221 |
# File 'lib/poolparty/cloud.rb', line 215 def os(sym=nil) if sym [:os] = sym else nodes.size > 0 ? nodes.first.os : [:os] end end |
#pool ⇒ Object
The pool this cloud belongs to
160 161 162 |
# File 'lib/poolparty/cloud.rb', line 160 def pool parent end |
#public_ip ⇒ Object
The public_ip of the cloud is equivalent to the public_ip of the cloud’s oldest node
226 227 228 |
# File 'lib/poolparty/cloud.rb', line 226 def public_ip nodes.first.public_ip end |
#resolve_with(a) ⇒ Object
Resolve with the dependency resolver
167 168 169 170 171 172 173 |
# File 'lib/poolparty/cloud.rb', line 167 def resolve_with(a) if DependencyResolvers.const_defined?(a.classify) dependency_resolver DependencyResolvers.module_eval("#{a.classify}") else raise PoolParty::PoolPartyError.create("DependencyResolverError", "Undefined dependency resolver: #{a}. Please specify one of the following: #{DependencyResolvers.all.join(", ")}") end end |
#run(commands, opts = {}) ⇒ Object
Run command/s on all nodes in the cloud. Returns a hash of instance_id=>result pairs
138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/poolparty/cloud.rb', line 138 def run(commands, opts={}) results = {} threads = nodes.collect do |n| Thread.new{ results[n.name] = n.run(commands, opts) } end threads.each{ |aThread| aThread.join } results # Serial implementation # # nodes.inject({})do |results, n| # results[n.instance_id] = n.run(commands, opts) # results # end end |
#run_instance(o = {}) ⇒ Object
69 |
# File 'lib/poolparty/cloud.rb', line 69 def run_instance(o={}); cloud_provider.run_instance(o);end |
#run_monitor(monitor_name, value) ⇒ Object
Run the monitor logic
241 242 243 244 245 246 247 248 |
# File 'lib/poolparty/cloud.rb', line 241 def run_monitor(monitor_name, value) mon = monitors[monitor_name.to_sym] if mon mon.run(value) else "unhandled monitor" end end |
#terminate! ⇒ Object
Terminate all instances in the cloud
75 76 77 |
# File 'lib/poolparty/cloud.rb', line 75 def terminate! nodes.collect{|n| n.terminate! } end |
#terminate_instance!(o = {}) ⇒ Object
70 |
# File 'lib/poolparty/cloud.rb', line 70 def terminate_instance!(o={}); cloud_provider.terminate_instance!(o);end |
#tmp_path ⇒ Object
Temporary path Starts at the global default tmp path and appends the pool name and the cloud name
155 156 157 |
# File 'lib/poolparty/cloud.rb', line 155 def tmp_path Default.tmp_path / pool.name / name end |
#using(provider_symbol, o = {}, &block) ⇒ Object
Declare the CloudProvider for a cloud
Create an instance of the cloud provider this cloud is using
60 61 62 63 64 65 |
# File 'lib/poolparty/cloud.rb', line 60 def using(provider_symbol, o={}, &block) return @cloud_provider if @cloud_provider self.cloud_provider_name = provider_symbol cloud_provider(.merge(o), &block) cloud_provider.keypair(keypair) end |
#validate_all_resources ⇒ Object
282 283 284 285 286 287 |
# File 'lib/poolparty/cloud.rb', line 282 def validate_all_resources ddputs("Validating all the resources") [:ensure_not_cyclic, :ensure_meta_fun_are_resources].each do |meth| self.send meth end end |