Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ platforms:
driver:
box: opscode-ubuntu-12.04
box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/opscode_ubuntu-12.04_provisionerless.box
- name: windows2012r2_cloud
driver:
box: windows2012r2_cloud
box_url: https://s3.amazonaws.com/box-cutter-us-east-1-cloudtrail/windows/virtualbox4.3.12/win2012r2-datacenter-chef11.12.8.box
transport:
name: winrm
- name: ubuntu-12.10
driver:
box: opscode-ubuntu-12.10
Expand Down Expand Up @@ -119,6 +125,17 @@ By default the value is unset, or `nil`. In this case the driver will use the
Vagrant [default provider][vagrant_default_provider] which at this current time
is `virtualbox` unless set by `VAGRANT_DEFAULT_PROVIDER` environment variable.

### <a name="config-gui"></a> gui

This is the vm console gui configuration and is used to make the console
visible/hidden following a create action.

If this value is `nil` or `false` then the console will be hidden, if `true`
the console will be visble.

This is particularly helpful for debugging local Virtualbox/VMware Fusion/VMware Workstation guests along with
adding `clipboard: bidirectional` to the customize section.

### <a name="config-customize"></a> customize

A **Hash** of customizations to a Vagrant virtual machine. Each key/value
Expand All @@ -130,6 +147,7 @@ driver:
customize:
memory: 1024
cpuexecutioncap: 50
clipboard: bidirectional
```

will generate a Vagrantfile configuration similar to:
Expand Down
5 changes: 4 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
require "bundler/gem_tasks"
require 'cane/rake_task'
require 'tailor/rake_task'
require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:test)

desc "Run cane to check quality metrics"
Cane::RakeTask.new
Expand All @@ -16,6 +19,6 @@ task :stats do
end

desc "Run all quality tasks"
task :quality => [:cane, :tailor, :stats]
task :quality => [:cane, :tailor, :stats, :test]

task :default => [ :quality ]
1 change: 1 addition & 0 deletions kitchen-vagrant.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ Gem::Specification.new do |gem|
gem.add_development_dependency 'cane'
gem.add_development_dependency 'tailor'
gem.add_development_dependency 'countloc'
gem.add_development_dependency 'rspec'
end
68 changes: 54 additions & 14 deletions lib/kitchen/driver/vagrant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@

require 'kitchen'

# Useful VBox Machine Class
require 'kitchen/provider/machine'

module Kitchen

module Driver
Expand All @@ -31,7 +34,7 @@ module Driver
#
# @todo Vagrant installation check and version will be placed into any
# dependency hook checks when feature is released
class Vagrant < Kitchen::Driver::SSHBase
class Vagrant < Kitchen::Driver::Base

default_config :customize, {}
default_config :network, []
Expand All @@ -44,12 +47,16 @@ class Vagrant < Kitchen::Driver::SSHBase
default_config :provider,
ENV.fetch('VAGRANT_DEFAULT_PROVIDER', "virtualbox")

default_config :box do |driver|
"opscode-#{driver.instance.platform.name}"
end

default_config :vm_hostname do |driver|
"#{driver.instance.name}.vagrantup.com"
driver.instance.name
end

default_config :box do |driver|
"opscode-#{driver.instance.platform.name}"
default_config :communicator do |driver|
driver.instance.transport.class.name.split('::').last.downcase
end

default_config :box_url do |driver|
Expand All @@ -66,7 +73,7 @@ def create(state)
cmd = "vagrant up --no-provision"
cmd += " --provider=#{config[:provider]}" if config[:provider]
run cmd
set_ssh_state(state)
set_state(state)
info("Vagrant instance #{instance.to_str} created.")
end

Expand Down Expand Up @@ -178,15 +185,6 @@ def template
File.expand_path(config[:vagrantfile_erb], config[:kitchen_root])
end

def set_ssh_state(state)
hash = vagrant_ssh_config

state[:hostname] = hash["HostName"]
state[:username] = hash["User"]
state[:ssh_key] = hash["IdentityFile"]
state[:port] = hash["Port"]
end

def vagrant_ssh_config
output = run("vagrant ssh-config", :live_stream => nil)
lines = output.split("\n").map do |line|
Expand Down Expand Up @@ -230,6 +228,48 @@ def check_vagrant_version
" Please upgrade to version #{MIN_VER} or higher from #{WEBSITE}."
end
end

def set_state(state)
hash = vagrant_ssh_config

state[:hostname] = hash["HostName"]
state[:username] = config[:username] || hash["User"]
state[:password] = config[:password] || 'vagrant'
state[:ssh_key] = hash["IdentityFile"]
state[:port] = port_from_config
if config[:communicator] == "ssh"
state[:port] = hash["Port"]
end
refresh_forwarded_port(state)
end

def port_from_config
port = config[:port]
if port.nil?
guest_port = config[:guest_port] || instance.transport.default_port
if !config[:network].empty?
forwards = config[:network].select do |net|
net[0] == "forwarded_port" && net[1][:guest] == guest_port
end
forwards.each do |forward|
port = forward[1][:host]
end
end
end
port || instance.transport.default_port
end

# Get forwarded_port from Provider
#
# Working with: VirtualBox
def refresh_forwarded_port(state)
case config[:provider]
when "virtualbox"
Provider::VirtualBox::Machine.new(vagrant_root) do |machine|
state[:port] = machine.host_port(default_port)
end
end
end
end
end
end
2 changes: 1 addition & 1 deletion lib/kitchen/driver/vagrant_version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ module Kitchen
module Driver

# Version string for Vagrant Kitchen driver
VAGRANT_VERSION = "0.15.0"
VAGRANT_VERSION = '0.16.0'
end
end
155 changes: 155 additions & 0 deletions lib/kitchen/provider/machine.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# -*- encoding: utf-8 -*-
#
# Author:: Salim Afiune (<salim@afiunemaya.com.mx>)
#
# Copyright (C) 2014, Salim Afiune
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require 'mixlib/shellout'

module Kitchen

module Provider

module VirtualBox
# This class will simulate one Virtual Box Machine
# It will give us the latest Forwarded Ports list
# where we can check if the port has changed
#
# Supported Virtual Box
# => version 4.2.x
# => version 4.3.x
class Machine
# The UUID of the virtual machine
attr_reader :uuid

# The forwarded_ports of the virtual machine
attr_reader :forwarded_ports


def initialize(root_path, uuid=nil)
# Did we get the UUID
@uuid = uuid

# The VBoxID that Vagrant spun up
id = File.expand_path(File.join(root_path,
%w{.vagrant machines default virtualbox id}))

# If UUID was not given but the VBoxID exist.
@uuid = File.read(id) if File.exists?(id) && @uuid.nil?

# Report that the VM is missing.
vm_notfound unless exists?

yield self if block_given?
end

def execute(*command)
# Easy shellout method to execute something! :D
command.insert(0, vboxmanage)
c = Mixlib::ShellOut.new(*command.join(' '), :timeout => 10800)
c.run_command
c.error!
c
end

# Conveniente method for executing a method.
def self.host_port(guest_port, root_path)
new(root_path).host_port(guest_port)
end

def get_vboxmanage_path
# Set the path to VBoxManage
vboxmanage_path = 'VBoxManage'

if RUBY_PLATFORM =~ /cygwin|mswin|mingw|bccwin|wince|emx/
# On Windows, search for VBOX_INSTALL_PATH environmental
# variable to find VBoxManage.
if ENV.has_key?('VBOX_INSTALL_PATH')
# Get the path.
path = ENV['VBOX_INSTALL_PATH']

# There can actually be multiple paths in here, so we need to
# split by the separator ";" and see which is a good one.
path.split(";").each do |single|
# Make sure it ends with a \
single += '\\' if !single.end_with?('\\')

# If the executable exists, then set it as the main path
# and break out
vboxmanage = "#{path}VBoxManage.exe"
if File.file?(vboxmanage)
vboxmanage_path = "\"#{vboxmanage}\""
break
end
end
end
end
@vboxmanage = vboxmanage_path
end

def read_forwarded_ports(uuid=nil)
uuid ||= @uuid

results = []
current_nic = nil
info = execute('showvminfo', uuid, '--machinereadable')
info.stdout.split("\n").each do |line|
# This is how we find the nic that a FP is attached to,
# since this comes first.
current_nic = $1.to_i if line =~ /^nic(\d+)=".+?"/

# Parse out the forwarded port information
if line =~ /^Forwarding.+?="(.+?),.+?,.*?,(.+?),.*?,(.+?)"/
result = [current_nic, $1.to_s, $2.to_i, $3.to_i]
results << result
end
end
@forwarded_ports = results
end

def host_port(guest_port)
port=nil
# Verify forwarded_ports
read_forwarded_ports.each do |forwarded_port|
# Checking that this is the WinRM port
if forwarded_port.include?(guest_port)
# For Virtual Box 4.2 the host port position is (2)
port=forwarded_port[2]
break
end
end
# This is the actual port that the VM is using.
port
end

def exists?(uuid=nil)
uuid ||= @uuid
execute('showvminfo', uuid).exitstatus == 0
end

# Command to manage Virtual Box `vboxmanage`
def vboxmanage
get_vboxmanage_path if @vboxmanage.nil?
@vboxmanage
end

def vm_notfound
raise 'Missing Virtual Box Machine. Run `kitchen create` and retry.'
end

end # => Machine
end # => VirtualBox
end # => Provider
end # => Kitchen
Loading