module Poise::Helpers::Subresources::Container
A resource mixin for subresource containers.
@since 1.0.0
Attributes
subcontexts[R]
subresources[R]
Public Class Methods
new(*args)
click to toggle source
Calls superclass method
# File lib/poise/helpers/subresources/container.rb, line 49 def initialize(*args) super @subresources = NoPrintingResourceCollection.new @subcontexts = [] end
Public Instance Methods
after_created()
click to toggle source
Calls superclass method
# File lib/poise/helpers/subresources/container.rb, line 55 def after_created super # Register as a default container if needed. Poise::Helpers::Subresources::DefaultContainers.register!(self, run_context) if self.class.container_default # Add all internal subresources to the resource collection. unless @subresources.empty? Chef::Log.debug("[#{self}] Adding subresources to collection:") # Because after_create is run before adding the container to the resource collection # we need to jump through some hoops to get it swapped into place. self_ = self order_fixer = Chef::Resource::RubyBlock.new('subresource_order_fixer', @run_context) # respond_to? is for <= 12.0.2, remove some day when I stop caring. order_fixer.declared_type = 'ruby_block' if order_fixer.respond_to?(:declared_type=) order_fixer.block do Chef::Log.debug("[#{self_}] Running order fixer") collection = self_.run_context.resource_collection # Delete the current container resource from its current position. collection.all_resources.delete(self_) # Replace the order fixer with the container so it runs before all # subresources. collection.all_resources[collection.iterator.position] = self_ # Hack for Chef 11 to reset the resources_by_name position too. # @todo Remove this when I drop support for Chef 11. if resources_by_name = collection.instance_variable_get(:@resources_by_name) resources_by_name[self_.to_s] = collection.iterator.position end # Step back so we re-run the "current" resource, which is now the # container. collection.iterator.skip_back Chef::Log.debug("Collection: #{@run_context.resource_collection.map(&:to_s).join(', ')}") end @run_context.resource_collection.insert(order_fixer) @subcontexts.each do |ctx| # Copy all resources to the outer context. ctx.resource_collection.each do |r| Chef::Log.debug(" * #{r}") # Fix the subresource to use the outer run context. r.run_context = @run_context @run_context.resource_collection.insert(r) end # Copy all notifications to the outer context. %w{immediate delayed}.each do |notification_type| ctx.send(:"#{notification_type}_notification_collection").each do |key, notifications| notifications.each do |notification| parent_notifications = @run_context.send(:"#{notification_type}_notification_collection")[key] unless parent_notifications.any? { |existing_notification| existing_notification.duplicates?(notification) } parent_notifications << notification end end end end end Chef::Log.debug("Collection: #{@run_context.resource_collection.map(&:to_s).join(', ')}") end end
declare_resource(type, name, created_at=nil, &block)
click to toggle source
Calls superclass method
# File lib/poise/helpers/subresources/container.rb, line 111 def declare_resource(type, name, created_at=nil, &block) Chef::Log.debug("[#{self}] Creating subresource from #{type}(#{name})") self_ = self # Used to break block context, non-local return from subcontext_block. resource = [] # Grab the caller so we can make the subresource look like it comes from # correct place. created_at ||= caller[0] # Run this inside a subcontext to avoid adding to the current resource collection. # It will end up added later, indirected via @subresources to ensure ordering. @subcontexts << subcontext_block do namespace = if self.class.container_namespace == true # If the value is true, use the name of the container resource. self.name elsif self.class.container_namespace.is_a?(Proc) instance_eval(&self.class.container_namespace) else self.class.container_namespace end sub_name = if name && !name.empty? if namespace "#{namespace}::#{name}" else name end else # If you pass in nil or '', you just get the namespace or parent name. namespace || self.name end resource << super(type, sub_name, created_at) do # Apply the correct parent before anything else so it is available # in after_created for the subresource. It might raise # NoMethodError is there isn't a real parent. begin parent(self_) if respond_to?(:parent) rescue NoMethodError # This space left intentionally blank. end # Run the resource block. instance_exec(&block) if block end end # Try and add to subresources. For normal subresources this is handled # in the after_created. register_subresource(resource.first) if resource.first # Return whatever we have resource.first end
register_subresource(resource)
click to toggle source
Register a resource as part of this container. Returns true if the resource was added to the collection and false if it was already known.
@note Return value added in 2.4.0. @return [Boolean]
# File lib/poise/helpers/subresources/container.rb, line 166 def register_subresource(resource) subresources.lookup(resource) false rescue Chef::Exceptions::ResourceNotFound Chef::Log.debug("[#{self}] Adding #{resource} to subresources") subresources.insert(resource) true end
Private Instance Methods
to_ary()
click to toggle source
Thanks Array.flatten, big help you are. Specifically the method_missing in the recipe DSL will make a flatten on an array of resources fail, so make this safe.
# File lib/poise/helpers/subresources/container.rb, line 180 def to_ary nil end