Class: Kitchen::Instance

Inherits:
Object
  • Object
show all
Includes:
Logging
Defined in:
lib/kitchen/instance.rb

Overview

An instance of a suite running on a platform. A created instance may be a local virtual machine, cloud instance, container, or even a bare metal server, which is determined by the platform's driver.

Author:

Defined Under Namespace

Classes: ActionRunner, FSM

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Logging

#debug, #error, #fatal, #info, #warn

Constructor Details

#initialize(options = {}) ⇒ Instance

Creates a new instance, given a suite and a platform.

Parameters:

  • options (Hash) (defaults to: {})

    configuration for a new suite

Options Hash (options):

  • :suite (Suite)

    the suite (Required)

  • :platform (Platform)

    the platform (Required)

  • :driver (Driver::Base)

    the driver (Required)

  • :provisioner (Provisioner::Base)

    the provisioner

  • :transport (Transport::Base)

    the transport (Required)

  • :verifier (Verifier)

    the verifier logger (Required)

  • :logger (Logger)

    the instance logger (default: Kitchen.logger)

  • :state_file (StateFile)

    the state file object to use when tracking instance state (Required)

Raises:

  • (ClientError)

    if one or more required options are omitted



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/kitchen/instance.rb', line 94

def initialize(options = {})
  validate_options(options)

  @suite           = options.fetch(:suite)
  @platform        = options.fetch(:platform)
  @name            = self.class.name_for(@suite, @platform)
  @driver          = options.fetch(:driver)
  @lifecycle_hooks = options.fetch(:lifecycle_hooks)
  @provisioner     = options.fetch(:provisioner)
  @transport       = options.fetch(:transport)
  @verifier        = options.fetch(:verifier)
  @logger          = options.fetch(:logger) { Kitchen.logger }
  @state_file      = options.fetch(:state_file)

  setup_driver
  setup_provisioner
  setup_transport
  setup_verifier
  setup_lifecycle_hooks
end

Class Attribute Details

.mutexesHash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a hash of mutexes, arranged by Plugin class names.

Returns:

  • (Hash)

    a hash of mutexes, arranged by Plugin class names



35
36
37
# File 'lib/kitchen/instance.rb', line 35

def mutexes
  @mutexes
end

Instance Attribute Details

#driverDriver::Base

Returns driver object which will manage this instance's lifecycle actions.

Returns:

  • (Driver::Base)

    driver object which will manage this instance's lifecycle actions



58
59
60
# File 'lib/kitchen/instance.rb', line 58

def driver
  @driver
end

#lifecycle_hooksLifecycleHooks

Returns lifecycle hooks manager object.

Returns:



61
62
63
# File 'lib/kitchen/instance.rb', line 61

def lifecycle_hooks
  @lifecycle_hooks
end

#loggerLogger (readonly)

Returns the logger for this instance.

Returns:

  • (Logger)

    the logger for this instance



77
78
79
# File 'lib/kitchen/instance.rb', line 77

def logger
  @logger
end

#nameString (readonly)

Returns name of this instance.

Returns:

  • (String)

    name of this instance



54
55
56
# File 'lib/kitchen/instance.rb', line 54

def name
  @name
end

#platformPlatform (readonly)

Returns the target platform configuration.

Returns:

  • (Platform)

    the target platform configuration



51
52
53
# File 'lib/kitchen/instance.rb', line 51

def platform
  @platform
end

#provisionerProvisioner::Base

Returns provisioner object which will the setup and invocation instructions for configuration management and other automation tools.

Returns:

  • (Provisioner::Base)

    provisioner object which will the setup and invocation instructions for configuration management and other automation tools



66
67
68
# File 'lib/kitchen/instance.rb', line 66

def provisioner
  @provisioner
end

#suiteSuite (readonly)

Returns the test suite configuration.

Returns:

  • (Suite)

    the test suite configuration



48
49
50
# File 'lib/kitchen/instance.rb', line 48

def suite
  @suite
end

#transportTransport::Base

Returns transport object which will communicate with an instance.

Returns:

  • (Transport::Base)

    transport object which will communicate with an instance.



70
71
72
# File 'lib/kitchen/instance.rb', line 70

def transport
  @transport
end

#verifierVerifier

Returns verifier object for instance to manage the verifier installation on this instance.

Returns:

  • (Verifier)

    verifier object for instance to manage the verifier installation on this instance



74
75
76
# File 'lib/kitchen/instance.rb', line 74

def verifier
  @verifier
end

Class Method Details

.name_for(suite, platform) ⇒ String

Generates a name for an instance given a suite and platform.

Parameters:

Returns:

  • (String)

    a normalized, consistent name for an instance



42
43
44
# File 'lib/kitchen/instance.rb', line 42

def name_for(suite, platform)
  "#{suite.name}-#{platform.name}".gsub(%r{[_,/]}, "-").delete(".")
end

Instance Method Details

#cleanup!void

This method returns an undefined value.

Clean up any per-instance resources before exiting.



335
336
337
# File 'lib/kitchen/instance.rb', line 335

def cleanup!
  @transport.cleanup! if @transport
end

#convergeself

TODO:

rescue Driver::ActionFailed and return some kind of null object to gracefully stop action chaining

Converges this running instance.

Returns:

  • (self)

    this instance, used to chain actions

See Also:



140
141
142
# File 'lib/kitchen/instance.rb', line 140

def converge
  transition_to(:converge)
end

#createself

TODO:

rescue Driver::ActionFailed and return some kind of null object to gracefully stop action chaining

Creates this instance.

Returns:

  • (self)

    this instance, used to chain actions

See Also:



129
130
131
# File 'lib/kitchen/instance.rb', line 129

def create
  transition_to(:create)
end

#current_session_idString?

Returns the current instance session identifier, if one has been established.

Returns:

  • (String, nil)

    the current instance session id



296
297
298
# File 'lib/kitchen/instance.rb', line 296

def current_session_id
  state_file.read[:instance_session_id]
end

#destroyself

TODO:

rescue Driver::ActionFailed and return some kind of null object to gracefully stop action chaining

Destroys this instance.

Returns:

  • (self)

    this instance, used to chain actions

See Also:



173
174
175
# File 'lib/kitchen/instance.rb', line 173

def destroy
  transition_to(:destroy)
end

#diagnoseHash

Returns a Hash of configuration and other useful diagnostic information.

Returns:

  • (Hash)

    a diagnostic hash



250
251
252
253
254
255
256
257
258
259
# File 'lib/kitchen/instance.rb', line 250

def diagnose
  result = {}
  %i{
    platform state_file driver provisioner transport verifier lifecycle_hooks
  }.each do |sym|
    obj = send(sym)
    result[sym] = obj.respond_to?(:diagnose) ? obj.diagnose : :unknown
  end
  result
end

#diagnose_pluginsHash

Returns a Hash of configuration and other useful diagnostic information associated with plugins (such as loaded version, class name, etc.).

Returns:

  • (Hash)

    a diagnostic hash



265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/kitchen/instance.rb', line 265

def diagnose_plugins
  result = {}
  %i{driver provisioner verifier transport}.each do |sym|
    obj = send(sym)
    result[sym] = if obj.respond_to?(:diagnose_plugin)
                    obj.diagnose_plugin
                  else
                    :unknown
                  end
  end
  result
end

#doctor_actionObject

Check system and configuration for common errors.



240
241
242
243
244
245
# File 'lib/kitchen/instance.rb', line 240

def doctor_action
  banner "The doctor is in"
  [driver, provisioner, transport, verifier].any? do |obj|
    obj.doctor(state_file.read)
  end
end

#last_actionString

Returns the last successfully completed action state of the instance.

Returns:

  • (String)

    a named action which was last successfully completed



281
282
283
# File 'lib/kitchen/instance.rb', line 281

def last_action
  state_file.read[:last_action]
end

#last_errorString

Returns the error encountered on the last action on the instance

Returns:

  • (String)

    the message of the last error



288
289
290
# File 'lib/kitchen/instance.rb', line 288

def last_error
  state_file.read[:last_error]
end

#log_pathString?

Returns the path to the text log file for this instance.

Returns:

  • (String, nil)

    the instance text log path



303
304
305
# File 'lib/kitchen/instance.rb', line 303

def log_path
  logger.logdev_path
end

#loginObject

Logs in to this instance by invoking a system command, provided by the instance's transport. This could be an SSH command, telnet, or serial console session.

Note This method calls exec and will not return.



209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/kitchen/instance.rb', line 209

def 
  state = state_file.read
  if state[:last_action].nil?
    raise UserError, "Instance #{to_str} has not yet been created"
  end

  lc = transport.connection(state).

  debug(%{Login command: #{lc.command} #{lc.arguments.join(" ")} } \
    "(Options: #{lc.options})")
  Kernel.exec(*lc.exec_args)
end

#package_actionObject

Perform package.



233
234
235
236
# File 'lib/kitchen/instance.rb', line 233

def package_action
  banner "Packaging remote instance"
  driver.package(state_file.read)
end

#remote_exec(command) ⇒ Object

Executes an arbitrary command on this instance.

Parameters:

  • command (String)

    a command string to execute



225
226
227
228
229
# File 'lib/kitchen/instance.rb', line 225

def remote_exec(command)
  transport.connection(state_file.read) do |conn|
    conn.execute(command)
  end
end

#setupself

TODO:

rescue Driver::ActionFailed and return some kind of null object to gracefully stop action chaining

Sets up this converged instance for suite tests.

Returns:

  • (self)

    this instance, used to chain actions

See Also:

  • Driver::Base#setup


151
152
153
# File 'lib/kitchen/instance.rb', line 151

def setup
  transition_to(:setup)
end

#state_pathString

Returns the path to the state file for this instance.

Returns:

  • (String)

    the instance state file path



317
318
319
# File 'lib/kitchen/instance.rb', line 317

def state_path
  state_file.path
end

#status(probe: false) ⇒ Hash

Returns normalized liveness status for this instance.

Parameters:

  • probe (Boolean) (defaults to: false)

    whether to probe the transport as well

Returns:

  • (Hash)

    normalized status data



325
326
327
328
329
330
# File 'lib/kitchen/instance.rb', line 325

def status(probe: false)
  state = state_file.read
  result = driver_status(state)
  result[:transport_probe] = transport_probe(state) if probe
  result
end

#structured_log_pathString?

Returns the path to the structured log file for this instance.

Returns:

  • (String, nil)

    the instance structured log path



310
311
312
# File 'lib/kitchen/instance.rb', line 310

def structured_log_path
  logger.structured_logdev_path
end

#test(destroy_mode = :passing) ⇒ self

TODO:

rescue Driver::ActionFailed and return some kind of null object to gracefully stop action chaining

Tests this instance by creating, converging and verifying. If this instance is running, it will be pre-emptively destroyed to ensure a clean slate. The instance will be left post-verify in a running state.

Parameters:

  • destroy_mode (Symbol) (defaults to: :passing)

    strategy used to cleanup after instance has finished verifying (default: :passing)

Returns:

  • (self)

    this instance, used to chain actions



187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/kitchen/instance.rb', line 187

def test(destroy_mode = :passing)
  elapsed = Benchmark.measure do
    banner "Cleaning up any prior instances of #{to_str}"
    destroy
    banner "Testing #{to_str}"
    verify
    destroy if destroy_mode == :passing
  end
  info "Finished testing #{to_str} #{Util.duration(elapsed.real)}."
  self
ensure
  destroy if destroy_mode == :always
end

#to_strString

Returns a displayable representation of the instance.

Returns:

  • (String)

    an instance display string



118
119
120
# File 'lib/kitchen/instance.rb', line 118

def to_str
  "<#{name}>"
end

#verifyself

TODO:

rescue Driver::ActionFailed and return some kind of null object to gracefully stop action chaining

Verifies this set up instance by executing suite tests.

Returns:

  • (self)

    this instance, used to chain actions

See Also:

  • Driver::Base#verify


162
163
164
# File 'lib/kitchen/instance.rb', line 162

def verify
  transition_to(:verify)
end