Module: Chef::DSL::DeclareResource

Included in:
Recipe, Resource
Defined in:
lib/chef/dsl/declare_resource.rb

Instance Method Summary collapse

Instance Method Details

#build_resource(type, name, created_at: nil, run_context: self.run_context, enclosing_provider: nil, &resource_attrs_block) ⇒ Chef::Resource

Instantiate a resource of the given type with the given name and attributes as given in the resource_attrs_block.

The resource is NOT added to the resource collection.

Examples:

build_resource(:file, '/x/y.txt', caller[0]) do
  action :delete
end

Parameters:

  • type (Symbol)

    The type of resource (e.g. ‘:file` or `:package`)

  • name (String)

    The name of the resource (e.g. ‘/x/y.txt’ or ‘apache2’)

  • created_at (String) (defaults to: nil)

    The caller of the resource. Use ‘caller` to get the caller of your function. Defaults to the caller of this function.

  • run_context (Chef::RunContext) (defaults to: self.run_context)

    the run_context of the resource collection to operate on

  • resource_attrs_block

    A block that lets you set attributes of the resource (it is instance_eval’d on the resource instance).

Returns:



292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/chef/dsl/declare_resource.rb', line 292

def build_resource(type, name, created_at: nil, run_context: self.run_context, enclosing_provider: nil, &resource_attrs_block)
  created_at ||= caller[0]

  # this needs to be lazy in order to avoid circular dependencies since ResourceBuilder
  # will requires the entire provider+resolver universe
  require_relative "../resource_builder" unless defined?(Chef::ResourceBuilder)

  enclosing_provider ||= self if is_a?(Chef::Provider)

  nr = new_resource if defined?(new_resource)

  Chef::ResourceBuilder.new(
    type:                type,
    name:                name,
    created_at:          created_at,
    params:              @params,
    run_context:         run_context,
    cookbook_name:       cookbook_name,
    recipe_name:         recipe_name,
    enclosing_provider:  enclosing_provider,
    new_resource:        nr
  ).build(&resource_attrs_block)
end

#declare_resource(type, name, created_at: nil, run_context: self.run_context, enclosing_provider: nil, &resource_attrs_block) ⇒ Chef::Resource

Instantiates a resource (via #build_resource), then adds it to the resource collection. Note that resource classes are looked up directly, so this will create the resource you intended even if the method name corresponding to that resource has been overridden.

Examples:

declare_resource(:file, '/x/y.txt', caller[0]) do
  action :delete
end
# Equivalent to
file '/x/y.txt' do
  action :delete
end

Parameters:

  • type (Symbol)

    The type of resource (e.g. ‘:file` or `:package`)

  • name (String)

    The name of the resource (e.g. ‘/x/y.txt’ or ‘apache2’)

  • created_at (String) (defaults to: nil)

    The caller of the resource. Use ‘caller` to get the caller of your function. Defaults to the caller of this function.

  • run_context (Chef::RunContext) (defaults to: self.run_context)

    the run_context of the resource collection to operate on

  • resource_attrs_block

    A block that lets you set attributes of the resource (it is instance_eval’d on the resource instance).

Returns:



262
263
264
265
266
267
268
269
# File 'lib/chef/dsl/declare_resource.rb', line 262

def declare_resource(type, name, created_at: nil, run_context: self.run_context, enclosing_provider: nil, &resource_attrs_block)
  created_at ||= caller[0]

  resource = build_resource(type, name, created_at: created_at, enclosing_provider: enclosing_provider, &resource_attrs_block)

  run_context.resource_collection.insert(resource, resource_type: resource.declared_type, instance_name: resource.name)
  resource
end

#delete_resource(type, name, run_context: self.run_context) ⇒ Chef::Resource

Lookup a resource in the resource collection by name and delete it. Returns nil if the resource is not found and should not fail.

Examples:

delete_resource(:template, '/x/y.txt')

Parameters:

  • type (Symbol)

    The type of resource (e.g. ‘:file` or `:package`)

  • name (String)

    The name of the resource (e.g. ‘/x/y.txt’ or ‘apache2’)

  • run_context (Chef::RunContext) (defaults to: self.run_context)

    the run_context of the resource collection to operate on

Returns:



98
99
100
101
102
# File 'lib/chef/dsl/declare_resource.rb', line 98

def delete_resource(type, name, run_context: self.run_context)
  delete_resource!(type, name, run_context: run_context)
rescue Chef::Exceptions::ResourceNotFound
  nil
end

#delete_resource!(type, name, run_context: self.run_context) ⇒ Chef::Resource

Lookup a resource in the resource collection by name and delete it. This will raise Chef::Exceptions::ResourceNotFound if the resource is not found.

Examples:

delete_resource!(:template, '/x/y.txt')

Parameters:

  • type (Symbol)

    The type of resource (e.g. ‘:file` or `:package`)

  • name (String)

    The name of the resource (e.g. ‘/x/y.txt’ or ‘apache2’)

  • run_context (Chef::RunContext) (defaults to: self.run_context)

    the run_context of the resource collection to operate on

Returns:



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/chef/dsl/declare_resource.rb', line 74

def delete_resource!(type, name, run_context: self.run_context)
  run_context.resource_collection.delete("#{type}[#{name}]").tap do |resource|
    # Purge any pending notifications too. This will not raise an exception
    # if there are no notifications.
    if resource
      run_context.before_notification_collection.delete(resource.declared_key)
      run_context.immediate_notification_collection.delete(resource.declared_key)
      run_context.delayed_notification_collection.delete(resource.declared_key)
    end
  end
end

#edit_resource(type, name, created_at: nil, run_context: self.run_context, &resource_attrs_block) ⇒ Chef::Resource

Lookup a resource in the resource collection by name. If it exists, return it. If it does not exist, create it. This is a useful function for accumulator patterns. In CRUD terminology this is an “upsert” operation and is used to assert that the resource must exist with the specified properties.

Examples:

resource = edit_resource(:template, '/x/y.txt') do
  source "y.txt.erb"
  variables {}
end
resource.variables.merge!({ home: "/home/clowns"  })

Parameters:

  • type (Symbol)

    The type of resource (e.g. ‘:file` or `:package`)

  • name (String)

    The name of the resource (e.g. ‘/x/y.txt’ or ‘apache2’)

  • created_at (String) (defaults to: nil)

    The caller of the resource. Use ‘caller` to get the caller of your function. Defaults to the caller of this function.

  • run_context (Chef::RunContext) (defaults to: self.run_context)

    the run_context of the resource collection to operate on

  • resource_attrs_block

    A block that lets you set attributes of the resource (it is instance_eval’d on the resource instance).

Returns:



156
157
158
159
160
# File 'lib/chef/dsl/declare_resource.rb', line 156

def edit_resource(type, name, created_at: nil, run_context: self.run_context, &resource_attrs_block)
  edit_resource!(type, name, created_at: created_at, run_context: run_context, &resource_attrs_block)
rescue Chef::Exceptions::ResourceNotFound
  declare_resource(type, name, created_at: created_at, run_context: run_context, &resource_attrs_block)
end

#edit_resource!(type, name, created_at: nil, run_context: self.run_context, &resource_attrs_block) ⇒ Chef::Resource

Lookup a resource in the resource collection by name and edit the resource. If the resource is not found this will raise Chef::Exceptions::ResourceNotFound. This is the correct API to use for “chef_rewind” functionality.

Examples:

edit_resource!(:template, '/x/y.txt') do
  cookbook_name: cookbook_name
end

Parameters:

  • type (Symbol)

    The type of resource (e.g. ‘:file` or `:package`)

  • name (String)

    The name of the resource (e.g. ‘/x/y.txt’ or ‘apache2’)

  • run_context (Chef::RunContext) (defaults to: self.run_context)

    the run_context of the resource collection to operate on

  • resource_attrs_block

    A block that lets you set attributes of the resource (it is instance_eval’d on the resource instance).

Returns:



121
122
123
124
125
126
127
128
129
130
131
# File 'lib/chef/dsl/declare_resource.rb', line 121

def edit_resource!(type, name, created_at: nil, run_context: self.run_context, &resource_attrs_block)
  resource = find_resource!(type, name, run_context: run_context)
  if resource_attrs_block
    if defined?(new_resource)
      resource.instance_exec(new_resource, &resource_attrs_block)
    else
      resource.instance_exec(&resource_attrs_block)
    end
  end
  resource
end

#find_resource(type, name, created_at: nil, run_context: self.run_context, &resource_attrs_block) ⇒ Chef::Resource

Lookup a resource in the resource collection by name. If the resource is not found the will be no exception raised and the call will return nil. If a block is given and no resource is found it will create the resource using the block, if the resource is found then the block will not be applied. The block version is similar to create_if_missing

Examples:

if ( find_resource(:template, '/x/y.txt') )
  # do something
else
  # don't worry about the error
end
# this API can be used to return a resource from an outer run context, and will only create
# an action :nothing service if one does not already exist.
resource = with_run_context(:root) do
  find_resource(:service, 'whatever') do
    action :nothing
  end
end

Parameters:

  • type (Symbol)

    The type of resource (e.g. ‘:file` or `:package`)

  • name (String)

    The name of the resource (e.g. ‘/x/y.txt’ or ‘apache2’)

  • run_context (Chef::RunContext) (defaults to: self.run_context)

    the run_context of the resource collection to operate on

Returns:



229
230
231
232
233
234
235
# File 'lib/chef/dsl/declare_resource.rb', line 229

def find_resource(type, name, created_at: nil, run_context: self.run_context, &resource_attrs_block)
  find_resource!(type, name, run_context: run_context)
rescue Chef::Exceptions::ResourceNotFound
  if resource_attrs_block
    declare_resource(type, name, created_at: created_at, run_context: run_context, &resource_attrs_block)
  end # returns nil otherwise
end

#find_resource!(type, name, run_context: self.run_context) ⇒ Chef::Resource

Lookup a resource in the resource collection by name. If the resource is not found this will raise Chef::Exceptions::ResourceNotFound. This API is identical to the resources() call and while it is a synonym it is not intended to deprecate that call.

Examples:

resource = find_resource!(:template, '/x/y.txt')

Parameters:

  • type (Symbol)

    The type of resource (e.g. ‘:file` or `:package`)

  • name (String)

    The name of the resource (e.g. ‘/x/y.txt’ or ‘apache2’)

  • run_context (Chef::RunContext) (defaults to: self.run_context)

    the run_context of the resource collection to operate on

Returns:

Raises:

  • (ArgumentError)


196
197
198
199
200
# File 'lib/chef/dsl/declare_resource.rb', line 196

def find_resource!(type, name, run_context: self.run_context)
  raise ArgumentError, "find_resource! does not take a block" if block_given?

  run_context.resource_collection.find(type => name)
end

#resources(*args) ⇒ Object

Find existing resources by searching the list of existing resources. Possible forms are:

find(:file => "foobar")
find(:file => [ "foobar", "baz" ])
find("file[foobar]", "file[baz]")
find("file[foobar,baz]")

Calls ‘run_context.resource_collection.find(*args)`

The is backcompat API, the use of find_resource, below, is encouraged.

Returns:

  • the matching resource, or an Array of matching resources.

Raises:

  • ArgumentError if you feed it bad lookup information

  • RuntimeError if it can’t find the resources you are looking for.



179
180
181
# File 'lib/chef/dsl/declare_resource.rb', line 179

def resources(*args)
  run_context.resource_collection.find(*args)
end

#with_run_context(rc) ⇒ Object

Helper for switching run_contexts. Allows for using :parent or :root in place of passing the run_context. Executes the block in the run_context. Returns the return value of the passed block.

Examples:

# creates/returns a 'service[foo]' resource in the root run_context
resource = with_run_context(:root)
  edit_resource(:service, "foo") do
    action :nothing
  end
end

Parameters:

Returns:

  • return value of the block



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/chef/dsl/declare_resource.rb', line 42

def with_run_context(rc)
  raise ArgumentError, "with_run_context is useless without a block" unless block_given?

  old_run_context = @run_context
  @run_context =
    case rc
    when Chef::RunContext
      rc
    when :root
      run_context.root_run_context
    when :parent
      run_context.parent_run_context
    else
      raise ArgumentError, "bad argument to run_context helper, must be :root, :parent, or a Chef::RunContext"
    end
  yield
ensure
  @run_context = old_run_context
end