Module: Poise::Helpers::Subresources::Container

Includes:
Chef::DSL::Recipe, Poise::Helpers::SubcontextBlock
Defined in:
lib/poise/helpers/subresources/container.rb

Overview

A resource mixin for subresource containers.

Since:

  • 1.0.0

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#subresourcesObject (readonly)

Since:

  • 1.0.0



42
43
44
# File 'lib/poise/helpers/subresources/container.rb', line 42

def subresources
  @subresources
end

Class Method Details

.container_namespace(val = nil) ⇒ Object

Since:

  • 1.0.0



147
148
149
150
151
152
153
154
155
# File 'lib/poise/helpers/subresources/container.rb', line 147

def container_namespace(val=nil)
  @container_namespace = val unless val.nil?
  if @container_namespace.nil?
    # Not set here, look at the superclass of true by default for backwards compat.
    superclass.respond_to?(:container_namespace) ? superclass.container_namespace : true
  else
    @container_namespace
  end
end

Instance Method Details

#after_createdObject

Since:

  • 1.0.0



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/poise/helpers/subresources/container.rb', line 49

def after_created
  super
  # Register
  Poise::Helpers::Subresources::DefaultContainers.register!(self, run_context)
  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)
    order_fixer.declared_type = 'ruby_block'
    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
    end
    @run_context.resource_collection.insert(order_fixer)
    @subresources.each do |r|
      Chef::Log.debug("   * #{r}")
      @run_context.resource_collection.insert(r)
    end
  end
end

#declare_resource(type, name, created_at = nil, &block) ⇒ Object

Since:

  • 1.0.0



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/poise/helpers/subresources/container.rb', line 85

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.
  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.
      parent(self_) if respond_to?(:parent)
      # 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

#initialize(*args) ⇒ Object

Since:

  • 1.0.0



44
45
46
47
# File 'lib/poise/helpers/subresources/container.rb', line 44

def initialize(*args)
  super
  @subresources = NoPrintingResourceCollection.new
end

#register_subresource(resource) ⇒ Object

Since:

  • 1.0.0



129
130
131
132
133
134
# File 'lib/poise/helpers/subresources/container.rb', line 129

def register_subresource(resource)
  subresources.lookup(resource)
rescue Chef::Exceptions::ResourceNotFound
  Chef::Log.debug("[#{self}] Adding #{resource} to subresources")
  subresources.insert(resource)
end