Class: PoolParty::Cloud
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
- #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 22 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.
-
#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
35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/poolparty/cloud.rb', line 35 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
#after_all_loaded ⇒ Object
249 250 251 252 253 |
# File 'lib/poolparty/cloud.rb', line 249 def after_all_loaded run_after_loaded do |b| run_in_context(&b) end end |
#before_compile ⇒ Object
29 30 31 |
# File 'lib/poolparty/cloud.rb', line 29 def before_compile validate_all_resources end |
#cloud_provider(opts = {}, &block) ⇒ Object
The actual cloud_provider instance
76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/poolparty/cloud.rb', line 76 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.basename) @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)
182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/poolparty/cloud.rb', line 182 def compile(caller=nil) callback :before_compile 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) callback :after_compile out end |
#configure!(opts = {}, threaded = true) ⇒ Object
convenience method to loop thru all the nodes and configure them
128 129 130 |
# File 'lib/poolparty/cloud.rb', line 128 def configure!(opts={}, threaded=true) nodes.collect{|n| n.configure! } end |
#contract!(hsh = {}) ⇒ Object
Contract the cloud
119 120 121 122 123 124 125 |
# File 'lib/poolparty/cloud.rb', line 119 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
172 173 174 175 176 177 178 |
# File 'lib/poolparty/cloud.rb', line 172 def dependency_resolver(sym=nil) @dependency_resolver ||= case sym when :chef, nil [:dependency_resolver_name] = :chef DependencyResolvers::Chef end end |
#describe_instance(o = {}) ⇒ Object
68 |
# File 'lib/poolparty/cloud.rb', line 68 def describe_instance(o={}); cloud_provider.describe_instance(o);end |
#describe_instances(o = {}) ⇒ Object
67 |
# File 'lib/poolparty/cloud.rb', line 67 def describe_instances(o={}); cloud_provider.describe_instances(o);end |
#ensure_meta_fun_are_resources ⇒ Object
286 287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/poolparty/cloud.rb', line 286 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
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/poolparty/cloud.rb', line 262 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 22 to be open 4.) Calls call_after_launch_instance callbacks 5.) Executes passed &block, if any 6.) Returns the new instance object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/poolparty/cloud.rb', line 94 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(22, :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 22 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
244 245 246 247 |
# File 'lib/poolparty/cloud.rb', line 244 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
51 52 53 |
# File 'lib/poolparty/cloud.rb', line 51 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
217 218 219 |
# File 'lib/poolparty/cloud.rb', line 217 def monitor(monitor_symbol, &block) monitors[monitor_symbol] ||= PoolParty::Monitor.new(monitor_symbol, &block) end |
#monitors ⇒ Object
Store the monitors in an array
232 233 234 |
# File 'lib/poolparty/cloud.rb', line 232 def monitors @monitors ||= {} end |
#nodes(o = {}) ⇒ Object
Cloud provider methods
64 |
# File 'lib/poolparty/cloud.rb', line 64 def nodes(o={}); delayed_action {cloud_provider.nodes(o)}; 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
196 197 198 199 200 201 202 |
# File 'lib/poolparty/cloud.rb', line 196 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
156 157 158 |
# File 'lib/poolparty/cloud.rb', line 156 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
207 208 209 |
# File 'lib/poolparty/cloud.rb', line 207 def public_ip nodes.first.public_ip end |
#resolve_with(a) ⇒ Object
Resolve with the dependency resolver
163 164 165 166 167 168 169 |
# File 'lib/poolparty/cloud.rb', line 163 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
134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/poolparty/cloud.rb', line 134 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
65 |
# File 'lib/poolparty/cloud.rb', line 65 def run_instance(o={}); cloud_provider.run_instance(o);end |
#run_monitor(monitor_name, value) ⇒ Object
Run the monitor logic
222 223 224 225 226 227 228 229 |
# File 'lib/poolparty/cloud.rb', line 222 def run_monitor(monitor_name, value) mon = monitors[monitor_name.to_sym] if mon mon.run(value.to_f) else "unhandled monitor" end end |
#terminate! ⇒ Object
Terminate all instances in the cloud
71 72 73 |
# File 'lib/poolparty/cloud.rb', line 71 def terminate! nodes.collect{|n| n.terminate! } end |
#terminate_instance!(o = {}) ⇒ Object
66 |
# File 'lib/poolparty/cloud.rb', line 66 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
151 152 153 |
# File 'lib/poolparty/cloud.rb', line 151 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
57 58 59 60 61 |
# File 'lib/poolparty/cloud.rb', line 57 def using(provider_symbol, o={}, &block) return @cloud_provider if @cloud_provider self.cloud_provider_name = provider_symbol cloud_provider(o, &block) end |
#validate_all_resources ⇒ Object
255 256 257 258 259 260 |
# File 'lib/poolparty/cloud.rb', line 255 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 |