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: 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


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

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 mutxes, arranged by Driver class names.

Returns:

  • (Hash)

    a hash of mutxes, arranged by Driver class names


33
34
35
# File 'lib/kitchen/instance.rb', line 33

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


56
57
58
# File 'lib/kitchen/instance.rb', line 56

def driver
  @driver
end

#lifecycle_hooksLifecycleHooks

Returns lifecycle hooks manager object.

Returns:


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

def lifecycle_hooks
  @lifecycle_hooks
end

#loggerLogger (readonly)

Returns the logger for this instance.

Returns:

  • (Logger)

    the logger for this instance


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

def logger
  @logger
end

#nameString (readonly)

Returns name of this instance.

Returns:

  • (String)

    name of this instance


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

def name
  @name
end

#platformPlatform (readonly)

Returns the target platform configuration.

Returns:

  • (Platform)

    the target platform configuration


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

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


64
65
66
# File 'lib/kitchen/instance.rb', line 64

def provisioner
  @provisioner
end

#suiteSuite (readonly)

Returns the test suite configuration.

Returns:

  • (Suite)

    the test suite configuration


46
47
48
# File 'lib/kitchen/instance.rb', line 46

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.


68
69
70
# File 'lib/kitchen/instance.rb', line 68

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


72
73
74
# File 'lib/kitchen/instance.rb', line 72

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


40
41
42
# File 'lib/kitchen/instance.rb', line 40

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.


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

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

#convergeself

TODO:

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

Converges this running instance.

Returns:

  • (self)

    this instance, used to chain actions

See Also:


138
139
140
# File 'lib/kitchen/instance.rb', line 138

def converge
  transition_to(:converge)
end

#createself

TODO:

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

Creates this instance.

Returns:

  • (self)

    this instance, used to chain actions

See Also:


127
128
129
# File 'lib/kitchen/instance.rb', line 127

def create
  transition_to(:create)
end

#destroyself

TODO:

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

Destroys this instance.

Returns:

  • (self)

    this instance, used to chain actions

See Also:


171
172
173
# File 'lib/kitchen/instance.rb', line 171

def destroy
  transition_to(:destroy)
end

#diagnoseHash

Returns a Hash of configuration and other useful diagnostic information.

Returns:

  • (Hash)

    a diagnostic hash


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

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


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

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.


242
243
244
245
246
247
# File 'lib/kitchen/instance.rb', line 242

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


283
284
285
# File 'lib/kitchen/instance.rb', line 283

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


290
291
292
# File 'lib/kitchen/instance.rb', line 290

def last_error
  state_file.read[:last_error]
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.


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

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

  lc = if legacy_ssh_base_driver?
         (state)
       else
         transport.connection(state).
       end

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

#package_actionObject

Perform package.


235
236
237
238
# File 'lib/kitchen/instance.rb', line 235

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


227
228
229
230
231
# File 'lib/kitchen/instance.rb', line 227

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 gracfully stop action chaining

Sets up this converged instance for suite tests.

Returns:

  • (self)

    this instance, used to chain actions

See Also:

  • Driver::Base#setup

149
150
151
# File 'lib/kitchen/instance.rb', line 149

def setup
  transition_to(:setup)
end

#test(destroy_mode = :passing) ⇒ self

TODO:

rescue Driver::ActionFailed and return some kind of null object to gracfully 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


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

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


116
117
118
# File 'lib/kitchen/instance.rb', line 116

def to_str
  "<#{name}>"
end

#verifyself

TODO:

rescue Driver::ActionFailed and return some kind of null object to gracfully 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

160
161
162
# File 'lib/kitchen/instance.rb', line 160

def verify
  transition_to(:verify)
end