Class: Chef::Mixin::WhyRun::ResourceRequirements
- Inherits:
-
Object
- Object
- Chef::Mixin::WhyRun::ResourceRequirements
- Defined in:
- lib/chef/mixin/why_run.rb
Overview
ResourceRequirements provides a framework for making assertions about the host system’s state. It also provides a mechanism for making assumptions about what the system’s state might have been when running in why run mode.
For example, consider a recipe that consists of a package resource and a service resource. If the service’s init script is installed by the package, and Chef is running in why run mode, then the service resource would fail when attempting to run ‘/etc/init.d/software-name status`. In order to provide a more useful approximation of what would happen in a real chef run, we want to instead assume that the service was created but isn’t running. The logic would look like this:
# Hypothetical service provider demonstrating why run assumption logic.
# This isn't the actual API, it just shows the logic.
class HypotheticalServiceProvider < Chef::Provider
def load_current_resource
# Make sure we have the init script available:
if ::File.exist?("/etc/init.d/some-service"
# If the init script exists, proceed as normal:
status_cmd = shell_out("/etc/init.d/some-service status")
if status_cmd.success?
@current_resource.status(:running)
else
@current_resource.status(:stopped)
end
else
if whyrun_mode?
# If the init script is not available, and we're in why run mode,
# assume that some previous action would've created it:
log("warning: init script '/etc/init.d/some-service' is not available")
log("warning: assuming that the init script would have been created, assuming the state of 'some-service' is 'stopped'")
@current_resource.status(:stopped)
else
raise "expected init script /etc/init.d/some-service doesn't exist"
end
end
end
end
In short, the code above does the following:
-
runs a test to determine if a requirement is met: ‘::File.exist?(“/etc/init.d/some-service”`
-
raises an error if the requirement is not met, and we’re not in why run mode.
-
if we are in why run mode, print a message explaining the situation, and run some code that makes an assumption about what the state of the system would be. In this case, we also skip the normal ‘load_current_resource` logic
-
when the requirement is met, we run the normal ‘load_current_resource` logic
ResourceRequirements encapsulates the above logic in a more declarative API.
Examples
Assertions and assumptions should be created through the WhyRun#assert method, which gets mixed in to providers. See that method’s documentation for examples.
Defined Under Namespace
Classes: Assertion
Instance Attribute Summary collapse
-
#action ⇒ Object
Returns the value of attribute action.
Instance Method Summary collapse
-
#action_blocked?(action) ⇒ Boolean
Check to see if a given action is blocked by a failed assertion.
-
#assert(*actions) {|assertion| ... } ⇒ Object
Define a new Assertion.
- #events ⇒ Object
-
#initialize(resource, run_context, action) ⇒ ResourceRequirements
constructor
A new instance of ResourceRequirements.
-
#run(action) ⇒ Object
Run the assertion and assumption logic.
Constructor Details
#initialize(resource, run_context, action) ⇒ ResourceRequirements
Returns a new instance of ResourceRequirements.
247 248 249 250 251 252 253 |
# File 'lib/chef/mixin/why_run.rb', line 247 def initialize(resource, run_context, action) @resource = resource @run_context = run_context @action = action @assertions = Hash.new { |h, k| h[k] = [] } @blocked_actions = [] end |
Instance Attribute Details
#action ⇒ Object
Returns the value of attribute action.
245 246 247 |
# File 'lib/chef/mixin/why_run.rb', line 245 def action @action end |
Instance Method Details
#action_blocked?(action) ⇒ Boolean
Check to see if a given action is blocked by a failed assertion
Takes the action name to be verified.
262 263 264 |
# File 'lib/chef/mixin/why_run.rb', line 262 def action_blocked?(action) @blocked_actions.include?(action) end |
#assert(*actions) {|assertion| ... } ⇒ Object
Define a new Assertion.
Takes a list of action names for which the assertion should be made.
311 312 313 314 315 316 317 |
# File 'lib/chef/mixin/why_run.rb', line 311 def assert(*actions) return unless actions.include?(action.to_sym) || actions.include?(:all_actions) assertion = Assertion.new yield assertion actions.each { |action| @assertions[action] << assertion } end |
#events ⇒ Object
255 256 257 |
# File 'lib/chef/mixin/why_run.rb', line 255 def events @run_context.events end |
#run(action) ⇒ Object
Run the assertion and assumption logic.
320 321 322 323 324 325 326 327 328 |
# File 'lib/chef/mixin/why_run.rb', line 320 def run(action) @assertions[action.to_sym].each do |a| a.run(action, events, @resource) if a.assertion_failed? && a.block_action? @blocked_actions << action break end end end |