Class: Kitchen::Driver::Vagrant

Inherits:
Base
  • Object
show all
Includes:
HypervHelpers, ShellOut
Defined in:
lib/kitchen/driver/vagrant.rb

Overview

Vagrant driver for Kitchen. It communicates to Vagrant via the CLI.

Author:

Constant Summary collapse

LIVE_STATES =

Machine states Vagrant reports for a box that is up and reachable.

Returns:

  • (Array<String>)
%w{running}.freeze

Class Attribute Summary collapse

Instance Method Summary collapse

Methods included from HypervHelpers

#encode_command, #execute_command, #hyperv_default_switch_ps, #hyperv_switch, #is_32bit?, #is_64bit?, #os_architecture, #powershell_64_bit, #ruby_64bit?, #run_ps, #sanitize_stdout, #wrap_command

Class Attribute Details

.vagrant_versionString

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 the version of Vagrant installed on the workstation.

Returns:

  • (String)

    the version of Vagrant installed on the workstation



308
309
310
# File 'lib/kitchen/driver/vagrant.rb', line 308

def vagrant_version
  @vagrant_version
end

Instance Method Details

#cache_directoryString, false

The guest-side directory that the host's omnibus package cache should be shared into, so repeated converges do not re-download packages.

Returns:

  • (String, false)

    the guest path, or false if caching does not apply to this box and provider combination



289
290
291
292
293
294
295
# File 'lib/kitchen/driver/vagrant.rb', line 289

def cache_directory
  if enable_cache?
    config[:cache_directory]
  else
    false
  end
end

#create(state) ⇒ Object

Creates a Vagrant VM instance.

Parameters:

  • state (Hash)

    mutable instance state

Raises:

  • (ActionFailed)

    if the action could not be completed



129
130
131
132
133
134
135
136
137
138
139
# File 'lib/kitchen/driver/vagrant.rb', line 129

def create(state)
  create_vagrantfile
  run_pre_create_command
  check_box_outdated
  run_box_auto_update
  run_box_auto_prune
  run_vagrant_up
  update_state(state)
  instance.transport.connection(state).wait_until_ready
  info("Vagrant instance #{instance.to_str} created.")
end

#default_boxString?

The box this Instance should use when the user has not named one.

Platforms the Bento project builds are mapped onto their bento/ box; anything else is assumed to name a box directly.

Returns:

  • (String, nil)

    the Vagrant box for this Instance



147
148
149
150
151
152
153
# File 'lib/kitchen/driver/vagrant.rb', line 147

def default_box
  if bento_box?(instance.platform.name)
    "bento/#{instance.platform.name}"
  else
    instance.platform.name
  end
end

#default_box_urlString?

The box URL this Instance should use when the user has not named one.

Always nil: modern Vagrant resolves boxes through Vagrant Cloud, so an explicit URL is only needed for privately hosted boxes.

Returns:

  • (String, nil)

    the Vagrant box URL for this Instance



161
162
163
# File 'lib/kitchen/driver/vagrant.rb', line 161

def default_box_url
  nil
end

#destroy(state) ⇒ Object

Destroys an instance.

Parameters:

  • state (Hash)

    mutable instance state

Raises:

  • (ActionFailed)

    if the action could not be completed



169
170
171
172
173
174
175
176
177
178
179
# File 'lib/kitchen/driver/vagrant.rb', line 169

def destroy(state)
  return if state[:hostname].nil?

  create_vagrantfile
  @vagrantfile_created = false
  instance.transport.connection(state).close
  run("#{config[:vagrant_binary]} destroy -f")
  FileUtils.rm_rf(vagrant_root)
  info("Vagrant instance #{instance.to_str} destroyed.")
  state.delete(:hostname)
end

#doctor(state) ⇒ Boolean

Checks the host-side things a Vagrant run needs, reporting rather than raising so kitchen doctor can list every problem at once.

#verify_dependencies already raises on an old or absent Vagrant, but it only runs on the actions that need it. This repeats the version rule as a report and adds the file and folder checks that nothing validates today.

Parameters:

  • state (Hash)

    mutable instance and driver state

Returns:

  • (Boolean)

    true when a problem was reported



270
271
272
273
274
275
# File 'lib/kitchen/driver/vagrant.rb', line 270

def doctor(state) # rubocop:disable Lint/UnusedMethodArgument
  problems = vagrant_problems + template_problems + synced_folder_problems

  problems.each { |problem| warn(problem) }
  !problems.empty?
end

#finalize_config!(instance) ⇒ self

A lifecycle method that should be invoked when the object is about ready to be used. A reference to an Instance is required as configuration dependant data may be access through an Instance. This also acts as a hook point where the object may wish to perform other last minute checks, validations, or configuration expansions.

Parameters:

  • instance (Instance)

    an associated instance

Returns:

  • (self)

    itself, for use in chaining

Raises:

  • (ClientError)

    if instance parameter is nil



232
233
234
235
236
237
238
239
240
241
242
# File 'lib/kitchen/driver/vagrant.rb', line 232

def finalize_config!(instance)
  super
  finalize_vm_hostname!
  finalize_box_auto_update!
  finalize_box_auto_prune!
  finalize_pre_create_command!
  finalize_synced_folders!
  finalize_ca_cert!
  finalize_network!
  self
end

#package(state) ⇒ Object

Packages a created instance into a redistributable .box file in the current working directory, then destroys the instance.

Parameters:

  • state (Hash)

    mutable instance state

Raises:

  • (UserError)

    if the instance has not been created

  • (ActionFailed)

    if the action could not be completed



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

def package(state)
  if state[:hostname].nil?
    raise UserError, "Vagrant instance not created!"
  end

  unless config[:ssh] && config[:ssh][:insert_key] == false
    m = "Disable vagrant ssh key replacement to preserve the default key!"
    warn(m)
  end
  instance.transport.connection(state).close
  box_name = File.join(Dir.pwd, instance.name + ".box")
  run("#{config[:vagrant_binary]} package --output #{box_name}")
  destroy(state)
end

#status(state) ⇒ Hash

Reports what Vagrant currently thinks of the machine.

Parameters:

  • state (Hash)

    instance state naming the machine

Returns:

  • (Hash)

    a Test Kitchen status hash, or the base implementation's answer when there is nothing to ask Vagrant about



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

def status(state)
  return super unless state[:hostname]

  machine_state = vagrant_machine_state
  return super unless machine_state

  {
    live: LIVE_STATES.include?(machine_state),
    state: machine_state,
    source: "driver",
    resource_id: instance.name,
    message: "Vagrant reports the machine as #{machine_state}",
    checked_at: Time.now.utc.iso8601,
  }
end

#verify_dependenciesObject

Performs whatever tests that may be required to ensure that this driver will be able to function in the current environment. This may involve checking for the presence of certain directories, software installed, etc.

Raises:

  • (UserError)

    if the driver will not be able to perform or if a documented dependency is missing from the system



251
252
253
254
255
256
257
258
# File 'lib/kitchen/driver/vagrant.rb', line 251

def verify_dependencies
  super
  if Gem::Version.new(vagrant_version) < Gem::Version.new(MIN_VER.dup)
    raise UserError, "Detected an old version of Vagrant " \
      "(#{vagrant_version})." \
      " Please upgrade to version #{MIN_VER} or higher from #{WEBSITE}."
  end
end

#winrm_transport?TrueClass, FalseClass

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 whether or not the transport's name implies a WinRM-based transport.

Returns:

  • (TrueClass, FalseClass)

    whether or not the transport's name implies a WinRM-based transport



280
281
282
# File 'lib/kitchen/driver/vagrant.rb', line 280

def winrm_transport?
  instance.transport.name.downcase =~ /win_?rm/
end