module Kitchen::Command::RunAction

Common module to execute a Kitchen action such as create, converge, etc.

@author Fletcher Nichol <fnichol@nichol.ca>

Public Instance Methods

concurrency_setting(instances) click to toggle source
# File lib/kitchen/command.rb, line 185
def concurrency_setting(instances)
  concurrency = 1
  if options[:concurrency]
    concurrency = options[:concurrency] || instances.size
    concurrency = instances.size if concurrency > instances.size
  end
  concurrency
end
report_errors() click to toggle source

private

# File lib/kitchen/command.rb, line 177
def report_errors
  unless @action_errors.empty?
    msg = ["#{@action_errors.length} actions failed.",
           @action_errors.map { |e| ">>>>>>     #{e.message}" }].join("\n")
    raise ActionFailed.new(msg, @action_errors)
  end
end
run_action(action, instances, *args) click to toggle source

Run an instance action (create, converge, setup, verify, destroy) on a collection of instances. The instance actions will take place in a seperate thread of execution which may or may not be running concurrently.

@param action [String] action to perform @param instances [Array<Instance>] an array of instances

# File lib/kitchen/command.rb, line 154
def run_action(action, instances, *args)
  concurrency = concurrency_setting(instances)

  queue = Queue.new
  instances.each { |i| queue << i }
  concurrency.times { queue << nil }

  threads = []
  @action_errors = []
  concurrency.times do
    threads << Thread.new do
      while (instance = queue.pop)
        run_action_in_thread(action, instance, *args)
      end
    end
  end
  Thread.abort_on_exception = true if options[:fail_fast]
  threads.map(&:join)
  report_errors
end
run_action_in_thread(action, instance, *args) click to toggle source
# File lib/kitchen/command.rb, line 194
def run_action_in_thread(action, instance, *args)
  instance.public_send(action, *args)
rescue Kitchen::InstanceFailure => e
  @action_errors << e
rescue Kitchen::ActionFailed => e
  new_error = Kitchen::ActionFailed.new("#{e.message} on #{instance.name}")
  new_error.set_backtrace(e.backtrace)
  @action_errors << new_error
ensure
  instance.cleanup!
end