Module: Kitchen::Command::RunAction

Included in:
Action, Test
Defined in:
lib/kitchen/command.rb

Overview

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

Instance Method Summary collapse

Instance Method Details

#concurrency_setting(instances) ⇒ Object



185
186
187
188
189
190
191
192
# 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_errorsObject

private



177
178
179
180
181
182
183
# 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) ⇒ Object

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.



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# 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) ⇒ Object



194
195
196
197
198
199
200
201
202
203
204
# 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