Class: Chef::Mixin::WhyRun::ResourceRequirements::Assertion

Inherits:
Object
  • Object
show all
Defined in:
lib/chef/mixin/why_run.rb

Overview

Implements the logic for a single assertion/assumption. See the documentation for ResourceRequirements for full discussion.

Defined Under Namespace

Classes: AssertionFailure

Instance Method Summary collapse

Constructor Details

#initializeAssertion

Returns a new instance of Assertion.



130
131
132
133
134
135
136
137
138
# File 'lib/chef/mixin/why_run.rb', line 130

def initialize
  @block_action = false
  @assertion_proc = nil
  @failure_message = nil
  @whyrun_message = nil
  @resource_modifier = nil
  @assertion_failed = false
  @exception_type = AssertionFailure
end

Instance Method Details

#assertion(&assertion_proc) ⇒ Object

Defines the code block that determines if a requirement is met. The block should return a truthy value to indicate that the requirement is met, and a falsey value if the requirement is not met.

# in a provider:
assert(:some_action) do |a|
  # This provider requires the file /tmp/foo to exist:
  a.assertion { ::File.exist?("/tmp/foo") }
end


148
149
150
# File 'lib/chef/mixin/why_run.rb', line 148

def assertion(&assertion_proc)
  @assertion_proc = assertion_proc
end

#assertion_failed?Boolean

Returns:

  • (Boolean)


219
220
221
# File 'lib/chef/mixin/why_run.rb', line 219

def assertion_failed?
  @assertion_failed
end

#block_action!Object

Prevents associated actions from being invoked in whyrun mode. This will also stop further processing of assertions for a given action.

An example from the template provider: if the source template doesn’t exist we can’t parse it in the action_create block of template - something that we do even in whyrun mode. Because the source template may have been created in an earlier step, we still want to keep going in whyrun mode.

assert(:create, :create_if_missing) do |a|

a.assertion { File::exists?(@new_resource.source) }
a.whyrun "Template source file does not exist, assuming it would have been created."
a.block_action!

end



211
212
213
# File 'lib/chef/mixin/why_run.rb', line 211

def block_action!
  @block_action = true
end

#block_action?Boolean

Returns:

  • (Boolean)


215
216
217
# File 'lib/chef/mixin/why_run.rb', line 215

def block_action?
  @block_action
end

#failure_message(*args) ⇒ Object

Defines the failure message, and optionally the Exception class to use when a requirement is not met. It works like ‘raise`:

# in a provider:
assert(:some_action) do |a|
  # This example shows usage with 1 or 2 args by calling #failure_message twice.
  # In practice you should only call this once per Assertion.

  # Set the Exception class explicitly
  a.failure_message(Chef::Exceptions::MissingRequiredFile, "File /tmp/foo doesn't exist")
  # Fallback to the default error class (AssertionFailure)
  a.failure_message("File /tmp/foo" doesn't exist")
end


164
165
166
167
168
169
170
171
172
173
# File 'lib/chef/mixin/why_run.rb', line 164

def failure_message(*args)
  case args.size
  when 1
    @failure_message = args[0]
  when 2
    @exception_type, @failure_message = args[0], args[1]
  else
    raise ArgumentError, "#{self.class}#failure_message takes 1 or 2 arguments, you gave #{args.inspect}"
  end
end

#run(action, events, resource) ⇒ Object

Runs the assertion/assumption logic. Will raise an Exception of the type specified in #failure_message (or AssertionFailure by default) if the requirement is not met and Chef is not running in why run mode. An exception will also be raised if running in why run mode and no why run message or block has been declared.



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/chef/mixin/why_run.rb', line 228

def run(action, events, resource)
  if !@assertion_proc || !@assertion_proc.call
    @assertion_failed = true
    if Chef::Config[:why_run] && @whyrun_message
      events.provider_requirement_failed(action, resource, @exception_type, @failure_message)
      events.whyrun_assumption(action, resource, @whyrun_message) if @whyrun_message
      @resource_modifier.call if @resource_modifier
    else
      if @failure_message
        events.provider_requirement_failed(action, resource, @exception_type, @failure_message)
        raise @exception_type, @failure_message
      end
    end
  end
end

#whyrun(message, &resource_modifier) ⇒ Object

Defines a message and optionally provides a code block to execute when the requirement is not met and Chef is executing in why run mode

If no failure_message is provided (above), then execution will be allowed to continue in both whyrun and non-whyrun mode

Examples:

With a service resource that requires /etc/init.d/service-name to exist:

# in a provider
assert(:start, :restart) do |a|
  a.assertion { ::File.exist?("/etc/init.d/service-name") }
  a.whyrun("Init script '/etc/init.d/service-name' doesn't exist, assuming a prior action would have created it.") do
    # blindly assume that the service exists but is stopped in why run mode:
    @new_resource.status(:stopped)
  end
end


192
193
194
195
# File 'lib/chef/mixin/why_run.rb', line 192

def whyrun(message, &resource_modifier)
  @whyrun_message = message
  @resource_modifier = resource_modifier
end