[DRE-commits] [ruby-kitchen-vagrant] 01/06: Imported Upstream version 0.18.0

Hleb Valoshka tsfgnu-guest at moszumanska.debian.org
Thu Jul 9 16:36:06 UTC 2015


This is an automated email from the git hooks/post-receive script.

tsfgnu-guest pushed a commit to branch master
in repository ruby-kitchen-vagrant.

commit 0d0e018f032a4f88ebd7fef3d11e0efcc3f2135a
Author: Hleb Valoshka <375gnu at gmail.com>
Date:   Wed Jul 8 17:56:53 2015 +0300

    Imported Upstream version 0.18.0
---
 .gitignore                            |   17 +
 .travis.yml                           |   24 +
 CHANGELOG.md                          |  354 +++++++++
 Gemfile                               |   11 +
 Guardfile                             |   23 +
 LICENSE                               |   15 +
 README.md                             |  454 +++++++++++
 Rakefile                              |   37 +
 kitchen-vagrant.gemspec               |   34 +
 lib/kitchen/driver/vagrant.rb         |  433 ++++++++++
 lib/kitchen/driver/vagrant_version.rb |   26 +
 metadata.yml                          |  158 ++++
 spec/kitchen/driver/vagrant_spec.rb   | 1398 +++++++++++++++++++++++++++++++++
 spec/spec_helper.rb                   |   33 +
 templates/Vagrantfile.erb             |  125 +++
 15 files changed, 3142 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d87d4be
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,17 @@
+*.gem
+*.rbc
+.bundle
+.config
+.yardoc
+Gemfile.lock
+InstalledFiles
+_yardoc
+coverage
+doc/
+lib/bundler/man
+pkg
+rdoc
+spec/reports
+test/tmp
+test/version_tmp
+tmp
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..3aef59f
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,24 @@
+language: ruby
+
+rvm:
+  - 2.2
+  - 2.1
+  - 2.0.0
+  - 1.9.3
+  - ruby-head
+
+bundler_args: --without guard
+
+sudo: false
+
+matrix:
+  allow_failures:
+    - rvm: ruby-head
+
+notifications:
+  irc: "chat.freenode.net#kitchenci"
+
+addons:
+  code_climate:
+    repo_token:
+      secure: "jVI7J+yiQcD5T1YNz9eGReGf6vyp8VIGjsyMEM0HBOxrbk4iCm7P5SN5n5cJPRZNzQd175ceqcpPisvJh91oPMetzpmN+PSDPhOzxVNB4rIqQ8ohJNX2jW/VVpaobzWHAQQurC349gfi2a6l7MvgZw3RGyExkacZXdqr+Bbsc38="
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..a536cab
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,354 @@
+## 0.18.0 / 2015-05-07
+
+### Bug fixes
+
+* Pull request [#161][]: Add handling for winrm communicator in username & password handling. ([@atiniir][])
+
+### Improvements
+
+* Pull request [#166][]: Allow a fuzzier match for known Bento box names. ([@fnichol][])
+
+
+## 0.17.0 / 2015-04-28
+
+(*A selected roll-up of 0.17.0 pre-release changelogs*)
+
+### Bug fixes
+
+* Pull request [#156][]: Use RDPPort value from `vagrant winrm-config` for WinRM Transports. ([@fnichol][])
+
+### New features
+
+* Pull request [#154][]: Support for WinRM Transport and Windows-based instances. ([@fnichol][])
+
+### Improvements
+
+* Pull request [#152][]: Translate CPU count for VMWare provider. ([@whiteley][])
+* Pull request [#157][]: Close Transport connection in #destroy. ([@fnichol][])
+* Pull request [#158][]: Add plugin metadata to the Driver. ([@fnichol][])
+
+
+## 0.17.0.rc.1 / 2015-03-29
+
+### Improvements
+
+* Pull request [#157][]: Close Transport connection in #destroy. ([@fnichol][])
+* Pull request [#158][]: Add plugin metadata to the Driver. ([@fnichol][])
+
+
+## 0.17.0.beta.4 / 2015-03-26
+
+### Bug fixes
+
+* Pull request [#156][]: Use RDPPort value from `vagrant winrm-config` for WinRM Transports. ([@fnichol][])
+
+### Improvements
+
+* Pull request [#152][]: Translate CPU count for VMWare provider. ([@whiteley][])
+
+
+## 0.17.0.beta.3 / 2015-03-25
+
+### Bug fixes
+
+* Pull request [#155][]: Use the vagrant-winrm Vagrant plugin to resolve VM IP address. See PR for details. ([@fnichol][])
+
+
+## 0.17.0.beta.2 / 2015-03-25
+
+* Relax version constraint on Test Kitchen. ([@fnichol][])
+
+
+## 0.17.0.beta.1 / 2015-03-24
+
+* Pull request [#154][]: Support for WinRM Transport and Windows-based instances. ([@fnichol][])
+
+
+## 0.16.0 / 2015-03-23
+
+### Bug fixes
+
+* Pull request [#122][], pull request [#151][]: Only set custom `:box` & `:box_url` values for known Bento boxes. ([@ashb][], [@fnichol][])
+
+### New features
+
+* Pull request $84: Add support for Parallels provider. ([@jhx][])
+* Pull request [#107][]: Add support for libvirt provider. ([@bradleyd][])
+* Pull request [#128][]: Add support for LXC provider. ([@tknerr][])
+* Pull request [#142][]: Add support for managed-servers provider. ([@kbruner][])
+* Add `:gui` configuration attribute to override default GUI mode with VirtualBox and VMware-based providers. ([@fnichol][])
+* Pull request [#137][]: Support SoftLayer `:disk_capacity` configuration. ([@hugespoon][])
+* Pull request [#102][]: Add `:box_version` & `:box_check_update` configuration options to support box versioning. ([@mconigliaro][])
+* Pull request [#129][]: Add `:provision` configuration option. ([@gouketsu][])
+* Pull reqwuest [#112][]: Add configuration option for user Vagrantfiles with `:vagrantfiles` configuration option. ([@byggztryng][])
+* Pull request [#95][]: Add SSH ProxyCommand to state if present. ([@bdclark][])
+* Pull request [#121][]: Add `:ssh` configuration hash. ([@Igorshp][])
+* Pull request [#104][]: Add `:communicator` configuration option to support overriding underlying base box's communicator setting. ([@RobertRehberg][])
+* Pull request [#118][]: Vagrant config password (Not Vagrant recommended). ([@philcallister][])
+
+### Improvements
+
+* Pull request [#148][]: Add full test coverage to the codebase. ([@fnichol][])
+* Pull request [#126][]: Disable vagrant-berkshelf plugin by default (this Driver does not need it and can cause confusing errors). ([@tknerr][])
+* Pull request [#101][]: Qualify VM names with project name. ([@petere][])
+* Pull request [#117][]: Change default hostname to be shorter and friendlier for Windows hosts. ([@Annih][])
+* Pull request [#106][], Use correct URLs to download vagrant in README. ([@alex-slynko-wonga][])
+* Pull request [#146][]: Freshen project quality (TravisCI, Tailor-for-Rubocop, Guard support, etc). ([@fnichol][])
+* Pull request [#147][]: Tidy default configuration attributes. ([@fnichol][])
+* Pull request [#134][]: CHANGELOG Champion, Mr. [@miketheman][]. ([@miketheman][])
+* Pull request [#127][]: README updates. ([@vinyar][], fnichol)
+
+
+## 0.15.0 / 2014-04-28
+
+### New features
+
+* Support vagrant-softlayer plugin
+
+### Improvements
+
+* Improved/updated README documentation + typos
+* Remove default memory setting
+* Fix relative paths in synced folders
+
+## 0.14.0 / 2013-12-09
+
+### New features
+
+* Add `config[:vm_hostname]` to set config.vm.hostname in Vagrantfile. ([@fnichol][])
+
+### Improvments
+
+* Add `config[:guest]` documentation in README. ([@fnichol][])
+
+
+## 0.13.0 / 2013-12-04
+
+### New features
+
+* Use Opscode's new buckets for Virtual machines, allowing for downloads of VirtualBox and VMware Fusion/Workstation Bento boxes (Vagrant minimal base boxes). ([@sethvargo][])
+
+
+## 0.12.0 / 2013-11-29
+
+### Breaking changes
+
+* Remove `use_vagrant_provision` configuration option.
+
+### New features
+
+* Major refactor of Vagrantfile generation, to use an ERB template. For more details please consult the `vagrantfile_erb` section of the README. ([@fnichol][])
+* Add `pre_create_command` option to run optional setup such as Bindler. ([@fnichol][])
+
+### Improvments
+
+* Pull request [#56][]: Enabled passing options to the synced folders. ([@antonio-osorio][])
+* Pull request [#55][]: Fix README badges. ([@arangamani][])
+
+
+## 0.11.3 / 2013-11-09
+
+### Bug fixes
+
+* Revert `quiet` option used for Vagrant version checking. ([@fnichol][])
+
+
+## 0.11.2 / 2013-11-05
+
+### Bug fixes
+
+* Remove misleading `quiet` option ([@sethvargo][])
+* Relax dependency on Test Kitchen ([@sethvargo][])
+* Remove deprecated references to `vagrant-berkshelf` ([@sethvargo][])
+
+### Improvements
+
+* Allow users to specify custom SSH private key ([@manul][])
+* Use platform to determine which vagrant box to download (assume Opscode) ([@sethvargo][])
+
+
+## 0.11.1 / 2013-08-29
+
+### Bug fixes
+
+* Pull request [#36][]: README fix for synched_folders. ([@mattray][])
+
+### Improvements
+
+* Pull request [#34][]: Disable synced folders by default. ([@dje][])
+
+
+## 0.11.0 / 2013-07-23
+
+### New features
+
+* Pull request [#30][]: Support computed defaults for a select list of pre-determined platforms (see pull request and readme for quick example). ([@fnichol][])
+* Pull request [#25][]: Add rackspace support. ([@josephholsten][])
+
+### Improvements
+
+* Pull request [#20][]: Respect `VAGRANT_DEFAULT_PROVIDER` environment variable. ([@tmatilai][])
+* Pull request [#24][]: Allow to override Vagrant default SSH username. ([@gildegoma][])
+* Pull request [#21][]: Configure tailor to actually check the code style. ([@tmatilai][])
+
+### Bug fixes
+
+* Pull request [#29][], issue [#28][]: Allow the vagrant guest setting to be set in the generated Vagrantfile via the kitchen.yml. ([@keiths-osc][])
+* Pull request [#31][]: Add some quotes around Vagrantfile value. ([@albertsj1][])
+
+
+## 0.10.0 / 2013-05-08
+
+### New features
+
+* Pull request [#12][]: Use SSHBase functionality (using ChefDataUploader) to manage Chef provisioning in the converge action and make Vagrant's built in provisioning an optional mode by setting `use_vagrant_provision: true` in the `driver_config` section of the .kitchen.yml. As a consequence, the vagrant-berkshelf middleware is now also optional and off by default (can be re-enabled by setting `use_vagrant_berkshelf_plugin: true`). ([@fujin][])
+* Pull request [#18][]: Add VMware Fusion/Workstation support. ([@TheDude05][])
+
+### Improvements
+
+* Issue [#19][]: Recommend the vagrant-wrapper gem in README. ([@fnichol][])
+
+
+## 0.9.0 / 2013-04-19
+
+### Upstream changes
+
+* Pull request [#16][]: Update Vagrant Berkshelf plugin detection for the vagrant-berkshelf and drop detection for berkshelf-vagrant. ([@martinisoft][])
+
+
+## 0.8.0 / 2013-04-16
+
+### Improvements
+
+* Pull request [#15][]: Support berkshelf-vagrant 1.1.0+ in Vagrantfiles. ([@petejkim][], [@fnichol][])
+* Add an explanation of how this driver works in the README. ([@fnichol][])
+
+
+## 0.7.4 / 2013-03-28
+
+### Improvements
+
+* Drop `vagrant ssh -c` & communicate directly via SSH. ([@fnichol][])
+
+
+## 0.7.3 / 2013-03-28
+
+### Bug fixes
+
+* Calling #destroy should not memoize #create_vagrantfile. ([@fnichol][], [@sandfish8][])
+
+
+## 0.7.2 / 2013-03-23
+
+### Bug fixes
+
+* Wrap strings for data_bags_path and roles_path in Vagrantfiles. ([@fnichol][])
+
+
+## 0.7.1 / 2013-03-23
+
+### Bug fixes
+
+* Depend on test-kitchen ~> 1.0.0.alpha.1 to get API updates. ([@fnichol][])
+
+
+## 0.7.0 / 2013-03-22
+
+### New features
+
+* Pull request [#7][]: [Breaking] Support Vagrant 1.1+ and remove vagrant gem dependency. ([@fnichol][])
+* Pull request [#8][]: Add dependency checks for Vagrant and berkshelf-vagrant plugin (if necessary). ([@fnichol][])
+
+
+## 0.6.0 / 2013-03-02
+
+The initial release.
+
+<!--- The following link definition list is generated by PimpMyChangelog --->
+[#7]: https://github.com/test-kitchen/kitchen-vagrant/issues/7
+[#8]: https://github.com/test-kitchen/kitchen-vagrant/issues/8
+[#12]: https://github.com/test-kitchen/kitchen-vagrant/issues/12
+[#15]: https://github.com/test-kitchen/kitchen-vagrant/issues/15
+[#16]: https://github.com/test-kitchen/kitchen-vagrant/issues/16
+[#18]: https://github.com/test-kitchen/kitchen-vagrant/issues/18
+[#19]: https://github.com/test-kitchen/kitchen-vagrant/issues/19
+[#20]: https://github.com/test-kitchen/kitchen-vagrant/issues/20
+[#21]: https://github.com/test-kitchen/kitchen-vagrant/issues/21
+[#24]: https://github.com/test-kitchen/kitchen-vagrant/issues/24
+[#25]: https://github.com/test-kitchen/kitchen-vagrant/issues/25
+[#28]: https://github.com/test-kitchen/kitchen-vagrant/issues/28
+[#29]: https://github.com/test-kitchen/kitchen-vagrant/issues/29
+[#30]: https://github.com/test-kitchen/kitchen-vagrant/issues/30
+[#31]: https://github.com/test-kitchen/kitchen-vagrant/issues/31
+[#34]: https://github.com/test-kitchen/kitchen-vagrant/issues/34
+[#36]: https://github.com/test-kitchen/kitchen-vagrant/issues/36
+[#55]: https://github.com/test-kitchen/kitchen-vagrant/issues/55
+[#56]: https://github.com/test-kitchen/kitchen-vagrant/issues/56
+[#84]: https://github.com/test-kitchen/kitchen-vagrant/issues/84
+[#95]: https://github.com/test-kitchen/kitchen-vagrant/issues/95
+[#101]: https://github.com/test-kitchen/kitchen-vagrant/issues/101
+[#102]: https://github.com/test-kitchen/kitchen-vagrant/issues/102
+[#104]: https://github.com/test-kitchen/kitchen-vagrant/issues/104
+[#106]: https://github.com/test-kitchen/kitchen-vagrant/issues/106
+[#107]: https://github.com/test-kitchen/kitchen-vagrant/issues/107
+[#112]: https://github.com/test-kitchen/kitchen-vagrant/issues/112
+[#117]: https://github.com/test-kitchen/kitchen-vagrant/issues/117
+[#118]: https://github.com/test-kitchen/kitchen-vagrant/issues/118
+[#121]: https://github.com/test-kitchen/kitchen-vagrant/issues/121
+[#122]: https://github.com/test-kitchen/kitchen-vagrant/issues/122
+[#126]: https://github.com/test-kitchen/kitchen-vagrant/issues/126
+[#127]: https://github.com/test-kitchen/kitchen-vagrant/issues/127
+[#128]: https://github.com/test-kitchen/kitchen-vagrant/issues/128
+[#129]: https://github.com/test-kitchen/kitchen-vagrant/issues/129
+[#134]: https://github.com/test-kitchen/kitchen-vagrant/issues/134
+[#137]: https://github.com/test-kitchen/kitchen-vagrant/issues/137
+[#142]: https://github.com/test-kitchen/kitchen-vagrant/issues/142
+[#146]: https://github.com/test-kitchen/kitchen-vagrant/issues/146
+[#147]: https://github.com/test-kitchen/kitchen-vagrant/issues/147
+[#148]: https://github.com/test-kitchen/kitchen-vagrant/issues/148
+[#151]: https://github.com/test-kitchen/kitchen-vagrant/issues/151
+[#152]: https://github.com/test-kitchen/kitchen-vagrant/issues/152
+[#154]: https://github.com/test-kitchen/kitchen-vagrant/issues/154
+[#155]: https://github.com/test-kitchen/kitchen-vagrant/issues/155
+[#156]: https://github.com/test-kitchen/kitchen-vagrant/issues/156
+[#157]: https://github.com/test-kitchen/kitchen-vagrant/issues/157
+[#158]: https://github.com/test-kitchen/kitchen-vagrant/issues/158
+[#161]: https://github.com/test-kitchen/kitchen-vagrant/issues/161
+[#166]: https://github.com/test-kitchen/kitchen-vagrant/issues/166
+[@Annih]: https://github.com/Annih
+[@Igorshp]: https://github.com/Igorshp
+[@RobertRehberg]: https://github.com/RobertRehberg
+[@TheDude05]: https://github.com/TheDude05
+[@albertsj1]: https://github.com/albertsj1
+[@alex-slynko-wonga]: https://github.com/alex-slynko-wonga
+[@antonio-osorio]: https://github.com/antonio-osorio
+[@arangamani]: https://github.com/arangamani
+[@ashb]: https://github.com/ashb
+[@atiniir]: https://github.com/atiniir
+[@bdclark]: https://github.com/bdclark
+[@bradleyd]: https://github.com/bradleyd
+[@byggztryng]: https://github.com/byggztryng
+[@dje]: https://github.com/dje
+[@fnichol]: https://github.com/fnichol
+[@fujin]: https://github.com/fujin
+[@gildegoma]: https://github.com/gildegoma
+[@gouketsu]: https://github.com/gouketsu
+[@hugespoon]: https://github.com/hugespoon
+[@jhx]: https://github.com/jhx
+[@josephholsten]: https://github.com/josephholsten
+[@kbruner]: https://github.com/kbruner
+[@keiths-osc]: https://github.com/keiths-osc
+[@manul]: https://github.com/manul
+[@martinisoft]: https://github.com/martinisoft
+[@mattray]: https://github.com/mattray
+[@mconigliaro]: https://github.com/mconigliaro
+[@miketheman]: https://github.com/miketheman
+[@petejkim]: https://github.com/petejkim
+[@petere]: https://github.com/petere
+[@philcallister]: https://github.com/philcallister
+[@sandfish8]: https://github.com/sandfish8
+[@sethvargo]: https://github.com/sethvargo
+[@tknerr]: https://github.com/tknerr
+[@tmatilai]: https://github.com/tmatilai
+[@vinyar]: https://github.com/vinyar
+[@whiteley]: https://github.com/whiteley
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..17c099c
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,11 @@
+source "https://rubygems.org"
+gemspec
+
+group :guard do
+  gem "guard-rspec",    :require => nil
+  gem "guard-rubocop",  :require => nil
+end
+
+group :test do
+  gem "codeclimate-test-reporter", :require => nil
+end
diff --git a/Guardfile b/Guardfile
new file mode 100644
index 0000000..d628d1e
--- /dev/null
+++ b/Guardfile
@@ -0,0 +1,23 @@
+# -*- encoding: utf-8 -*-
+ignore %r{^\.gem/}
+
+def rspec_opts
+  { :cmd => "bundle exec rspec" }
+end
+
+def rubocop_opts
+  { :all_on_start => false, :keep_failed => false, :cli => "-r finstyle" }
+end
+
+group :red_green_refactor, :halt_on_fail => true do
+  guard :rspec, rspec_opts do
+    watch(%r{^spec/(.*)_spec\.rb})
+    watch(%r{^lib/(.*)([^/]+)\.rb})   { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
+    watch(%r{^spec/spec_helper\.rb})  { "spec" }
+  end
+
+  guard :rubocop, rubocop_opts do
+    watch(%r{.+\.rb$})
+    watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
+  end
+end
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..7a03687
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,15 @@
+Author:: Fletcher Nichol (<fnichol at nichol.ca>)
+
+Copyright (C) 2012, Fletcher Nichol
+
+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.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..79f74ce
--- /dev/null
+++ b/README.md
@@ -0,0 +1,454 @@
+# <a name="title"></a> Kitchen::Vagrant
+
+[![Gem Version](https://badge.fury.io/rb/kitchen-vagrant.svg)](http://badge.fury.io/rb/kitchen-vagrant)
+[![Build Status](https://secure.travis-ci.org/test-kitchen/kitchen-vagrant.svg?branch=master)](https://travis-ci.org/test-kitchen/kitchen-vagrant)
+[![Code Climate](https://codeclimate.com/github/test-kitchen/kitchen-vagrant.svg)](https://codeclimate.com/github/test-kitchen/kitchen-vagrant)
+[![Test Coverage](https://codeclimate.com/github/test-kitchen/kitchen-vagrant/coverage.svg)](https://codeclimate.com/github/test-kitchen/kitchen-vagrant)
+
+A Test Kitchen Driver for Vagrant.
+
+This driver works by generating a single Vagrantfile for each instance in a
+sandboxed directory. Since the Vagrantfile is written out on disk, Vagrant
+needs absolutely no knowledge of Test Kitchen. So no Vagrant plugins are
+required.
+
+## <a name="requirements"></a> Requirements
+
+### <a name="dependencies-vagrant"></a> Vagrant
+
+A Vagrant version of 1.1.0 or higher is required for this driver which means
+that a [native package][vagrant_dl] must be installed on the system running
+Test Kitchen.
+
+**Note:** If you have previously installed Vagrant as a gem (a version prior
+to 1.1.0), this version may be resolved first in your `PATH`. If you receive an
+error message that Vagrant is too old despite having installed Vagrant as a
+package, you may be required to uninstall the gem version or modify your `PATH`
+environment. If you require the vagrant gem for older projects you should
+consider the [vagrant-wrapper][vagrant_wrapper] gem which helps manage both
+styles of Vagrant installations
+([background details][vagrant_wrapper_background]).
+
+If you are creating Windows VMs over a WinRM Transport, then the
+[vagrant-winrm][vagrant_winrm] Vagrant plugin must be installed. As a
+consequence, the minimum version of Vagrant required is 1.6 or higher.
+
+### <a name="dependencies-virtualization"></a> Virtualbox and/or VMware Fusion/Workstation
+
+Currently this driver supports VirtualBox and VMware Fusion/Workstation.
+Virtualbox is free and is the default provider for Vagrant.
+
+[VirtualBox package][virtualbox_dl]
+
+If you would like to use VMware Fusion/Workstation you must purchase the
+software from VMware and then must also purchase the Vagrant VMware plugin.
+
+[Vagrant VMware Plugin][vmware_plugin]
+
+[VMware Fusion][fusion_dl]
+
+[VMware Workstation][workstation_dl]
+
+
+## <a name="installation"></a> Installation and Setup
+
+Please read the [Driver usage][driver_usage] page for more details.
+
+## <a name="default-config"></a> Default Configuration
+
+This driver can predict the Vagrant box name and download URL for a select
+number of platforms (VirtualBox and VMware providers only) that have been published by
+Chef Software Inc, in the [Bento][bento] project such as:
+
+```yaml
+---
+platforms:
+  - name: ubuntu-10.04
+  - name: ubuntu-12.04
+  - name: ubuntu-14.04
+  - name: ubuntu-13.04
+  - name: centos-5.11
+  - name: centos-6.6
+  - name: debian-7.8
+  - name: freebsd-10.1
+```
+
+This will effectively generate a configuration similar to:
+
+```yaml
+---
+platforms:
+  - name: ubuntu-10.04
+    driver:
+      box: opscode-ubuntu-10.04
+      box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_ubuntu-10.04_chef-provisionerless.box
+  - name: ubuntu-12.04
+    driver:
+      box: opscode-ubuntu-12.04
+      box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_ubuntu-12.04_chef-provisionerless.box
+  - name: ubuntu-14.04
+    driver:
+      box: opscode-ubuntu-14.04
+      box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_ubuntu-14.04_chef-provisionerless.box
+  # ...
+```
+
+Any other platform names will set a more reasonable default for `box` and leave `box_url` unset. For example:
+
+```yaml
+---
+platforms:
+  - name: slackware-14.1
+  - name: openbsd-5.6
+  - name: windows-2012r2
+```
+
+This will effectively generate a configuration similar to:
+
+```yaml
+---
+platforms:
+  - name: slackware-14.1
+    driver:
+      box: slackware-14.1
+  - name: openbsd-5.6
+    driver:
+      box: openbsd-5.6
+  - name: windows-2012r2
+    driver:
+      box: windows-2012r2
+```
+
+Many host wide defaults for Vagrant can be set using `$HOME/.vagrant.d/Vagrantfile`. See the [Vagrantfile documentation][vagrantfile] for more information.
+
+## <a name="config"></a> Configuration
+
+### <a name="config-box"></a> box
+
+**Required** This determines which Vagrant box will be used. For more
+details, please read the Vagrant [machine settings][vagrant_machine_settings]
+page.
+
+The default will be computed from the platform name of the instance. Howver, for a small number of common/known platforms in the [Bento][bento] project, the default will prepend `"opscode-"` to the start to match the downloadable `box_url` (see below).
+
+For example, a platform with a Bento box called "ubuntu-14.04" will produce a
+default `box` value of `"opscode-ubuntu-14.04"`. Alternatively, a box called
+`"slackware-14.1"` will produce a default `box` value of `"slackware-14.1".
+
+### <a name="config-box-check-update"></a> box\_check\_update
+
+Whether to check for box updates (disabled by default).
+
+### <a name="config-box-url"></a> box\_url
+
+A default URL will be computed only for a small number of common/known
+platforms in the [Bento][bento] project. Additionally, a URL will only be
+computed if the Vagrant provider is VirtualBox or is VMware based (these are
+the only providers with downloadable base boxes).
+
+### <a name="config-box-version"></a> box\_version
+
+The [version][vagrant_versioning] of the configured box.
+
+The default is `nil`, indicating unset.
+
+### <a name="config-communicator"></a> communicator
+
+**Note:** It should largely be the responsibility of the underlying Vagrant
+base box to properly set the `config.vm.communicator` value. For example, if
+the base box is a Windows operating system and does not have an SSH service
+installed and enabled, then Vagrant will be unable to even boot it (using
+`vagrant up`), without a custom Vagrantfile. If you are authoring a base box,
+please take care to set your value for communicator to give your users the best
+possible out-of-the-box experience.
+
+For overriding the default communicator setting of the base box.
+
+For example:
+
+```yaml
+---
+driver:
+  communicator: ssh
+```
+
+will generate a Vagrantfile configuration similar to:
+
+```ruby
+  config.vm.communicator = "ssh"
+```
+
+The default is `nil` assuming ssh will be used.
+
+### <a name="config-customize"></a> customize
+
+A **Hash** of customizations to a Vagrant virtual machine.  Each key/value
+pair will be passed to your providers customization block. For example, with
+the default `virtualbox` provider:
+
+```yaml
+---
+driver:
+  customize:
+    memory: 1024
+    cpuexecutioncap: 50
+```
+
+will generate a Vagrantfile configuration similar to:
+
+```ruby
+Vagrant.configure("2") do |config|
+  # ...
+
+  config.vm.provider :virtualbox do |virtualbox|
+    virtualbox.customize ["modifyvm", :id, "--memory", "1024"]
+    virtualbox.customize ["modifyvm", :id, "--cpuexecutioncap", "50"]
+  end
+end
+```
+
+Please read the "Customizations" sections for [VirtualBox][vagrant_config_vbox]
+and [VMware][vagrant_config_vmware] for more details.
+
+### <a name="config-guest"></a> guest
+
+**Note:** It should largely be the responsibility of the underlying Vagrant
+base box to properly set the `config.vm.guest` value. For example, if the base
+box is a Windows operating system, then Vagrant will be unable to even boot it
+(using `vagrant up`), without a custom Vagrantfile. If you are authoring a base
+box, please take care to set your value for communicator to give your users the
+best possible out-of-the-box experience.
+
+For overriding the default guest setting of the base box.
+
+The default is unset, or `nil`.
+
+### <a name="config-gui"></a> gui
+
+Allows GUI mode for each defined platform. Default is **nil**. Value is passed
+to the `config.vm.provider` but only for the VirtualBox and VMware-based
+providers.
+
+```yaml
+---
+platforms:
+  - name: ubuntu-14.04
+    driver:
+      gui: true
+```
+
+will generate a Vagrantfile configuration similar to:
+
+```ruby
+Vagrant.configure("2") do |config|
+  # ...
+
+  c.vm.provider :virtualbox do |p|
+    p.gui = true
+  end
+end
+```
+
+For more info about GUI vs. Headless mode please see [vagrant configuration docs][vagrant_config_vbox]
+
+### <a name="config-network"></a> network
+
+An **Array** of network customizations for the virtual machine. Each Array
+element is itself an Array of arguments to be passed to the `config.vm.network`
+method. For example:
+
+```yaml
+---
+driver:
+  network:
+    - ["forwarded_port", {guest: 80, host: 8080}]
+    - ["private_network", {ip: "192.168.33.33"}]
+```
+
+will generate a Vagrantfile configuration similar to:
+
+```ruby
+Vagrant.configure("2") do |config|
+  # ...
+
+  config.vm.network :forwarded_port, guest: 80, host: 8080
+  config.vm.network :private_network, ip: "192.168.33.33"
+end
+```
+
+Please read the Vagrant [networking basic usage][vagrant_networking] page for
+more details.
+
+The default is an empty Array, `[]`.
+
+### <a name="config-pre-create-command"></a> pre\_create\_command
+
+An optional hook to run a command immediately prior to the
+`vagrant up --no-provisioner` command being executed.
+
+There is an optional token, `{{vagrant_root}}` that can be used in the
+`pre_create_command` string which will be expanded by the driver to be the full
+path to the sandboxed Vagrant root directory containing the Vagrantfile. This
+command will be executed from the directory containing the .kitchen.yml file,
+or the `kitchen_root`.
+
+For example, if your project requires
+[Bindler](https://github.com/fgrehm/bindler), this command could be:
+
+```yaml
+---
+driver
+  pre_create_command: cp .vagrant_plugins.json {{vagrant_root}}/ && vagrant plugin bundle
+```
+
+The default is unset, or `nil`.
+
+### <a name="config-provider"></a> provider
+
+This determines which Vagrant provider to use. The value should match
+the provider name in Vagrant. For example, to use VMware Fusion the provider
+should be `vmware_fusion`. Please see the docs on [providers][vagrant_providers]
+for further details.
+
+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="provision"></a> provision
+
+Set to true if you want to do the provision of vagrant in create.
+Useful in case of you want to customize the OS in provision phase of vagrant
+
+### <a name="config-ssh-key"></a> ssh\_key
+
+This is the path to the private key file used for SSH authentication if you
+would like to use your own private ssh key instead of the default vagrant
+insecure private key.
+
+If this value is a relative path, then it will be expanded relative to the
+location of the main Vagrantfile. If this value is nil, then the default
+insecure private key that ships with Vagrant will be used.
+
+The default value is unset, or `nil`.
+
+### <a name="config-synced-folders"></a> synced_folders
+
+Allow the user to specify a collection of synced folders on each Vagrant
+instance. Source paths can be relative to the kitchen root.
+
+The default is an empty Array, or `[]`. The example:
+
+```yaml
+---
+driver:
+  synced_folders:
+    - ["data/%{instance_name}", "/opt/instance_data"]
+    - ["/host_path", "/vm_path", "create: true, type: :nfs"]
+```
+
+will generate a Vagrantfile configuration similar to:
+
+```ruby
+Vagrant.configure("2") do |config|
+  # ...
+
+  c.vm.synced_folder "/Users/mray/cookbooks/pxe_dust/data/default-ubuntu-1204", "/opt/instance_data"
+  c.vm.synced_folder "/host_path", "/vm_path", create: true, type: :nfs
+end
+```
+
+### <a name="config-vagrantfile-erb"></a> vagrantfile\_erb
+
+An alternate Vagrantfile ERB template that will be rendered for use by this
+driver. The binding context for the ERB processing is that of the Driver
+object, which means that methods like `config[:kitchen_root]`, `instance.name`,
+and `instance.provisioner[:run_list]` can be used to compose a custom
+Vagrantfile if necessary.
+
+**Warning:** Be cautious when going down this road as your setup may cease to
+be portable or applicable to other Test Kitchen Drivers such as Ec2 or Docker.
+Using the alternative Vagrantfile template strategy may be a dangerous
+road--be aware.
+
+The default is to use a template which ships with this gem.
+
+### <a name="config-vagrantfiles"></a> vagrantfiles
+
+An array of paths to other Vagrantfiles to be merged with the default one. The
+paths can be absolute or relative to the .kitchen.yml file.
+
+**Note:** the Vagrantfiles must have a .rb extension to satisfy Ruby's
+Kernel#require.
+
+```yaml
+---
+driver:
+  vagrantfiles:
+    - VagrantfileA.rb
+    - /tmp/VagrantfileB.rb
+```
+
+### <a name="config-vm-hostname"></a> vm\_hostname
+
+Sets the internal hostname for the instance. This is not used when connecting
+to the Vagrant virtual machine.
+
+For more details on this setting please read the
+[config.vm.hostname](http://docs.vagrantup.com/v2/vagrantfile/machine_settings.html)
+section of the Vagrant documentation.
+
+To prevent this value from being rendered in the default Vagrantfile, you can
+set this value to `false`.
+
+The default will be computed from the name of the instance. For example, the
+instance was called "default-fuzz-9" will produce a default `vm_hostname` value
+of `"default-fuzz-9"`. For Windows-based platforms, a default of `nil` is used
+to save on boot time and potential rebooting.
+
+## <a name="development"></a> Development
+
+* Source hosted at [GitHub][repo]
+* Report issues/questions/feature requests on [GitHub Issues][issues]
+
+Pull requests are very welcome! Make sure your patches are well tested.
+Ideally create a topic branch for every separate change you make. For
+example:
+
+1. Fork the repo
+2. Create your feature branch (`git checkout -b my-new-feature`)
+3. Commit your changes (`git commit -am 'Added some feature'`)
+4. Push to the branch (`git push origin my-new-feature`)
+5. Create new Pull Request
+
+## <a name="authors"></a> Authors
+
+Created and maintained by [Fletcher Nichol][author] (<fnichol at nichol.ca>)
+
+## <a name="license"></a> License
+
+Apache 2.0 (see [LICENSE][license])
+
+
+[author]:           https://github.com/opscode
+[issues]:           https://github.com/opscode/kitchen-vagrant/issues
+[license]:          https://github.com/opscode/kitchen-vagrant/blob/master/LICENSE
+[repo]:             https://github.com/opscode/kitchen-vagrant
+[driver_usage]:     http://kitchen.ci/docs/getting-started/adding-platform
+
+[bento]:                    https://github.com/chef/bento
+[vagrant_dl]:               http://www.vagrantup.com/downloads.html
+[vagrant_machine_settings]: http://docs.vagrantup.com/v2/vagrantfile/machine_settings.html
+[vagrant_networking]:       http://docs.vagrantup.com/v2/networking/basic_usage.html
+[virtualbox_dl]:            https://www.virtualbox.org/wiki/Downloads
+[vagrantfile]:              http://docs.vagrantup.com/v2/vagrantfile/index.html
+[vagrant_default_provider]: http://docs.vagrantup.com/v2/providers/default.html
+[vagrant_config_vbox]:      http://docs.vagrantup.com/v2/virtualbox/configuration.html
+[vagrant_config_vmware]:    http://docs.vagrantup.com/v2/vmware/configuration.html
+[vagrant_providers]:        http://docs.vagrantup.com/v2/providers/index.html
+[vagrant_versioning]:       https://docs.vagrantup.com/v2/boxes/versioning.html
+[vagrant_winrm]:            https://github.com/criteo/vagrant-winrm
+[vagrant_wrapper]:          https://github.com/org-binbab/gem-vagrant-wrapper
+[vagrant_wrapper_background]: https://github.com/org-binbab/gem-vagrant-wrapper#background---aka-the-vagrant-gem-enigma
+[vmware_plugin]:            http://www.vagrantup.com/vmware
+[fusion_dl]:                http://www.vmware.com/products/fusion/overview.html
+[workstation_dl]:           http://www.vmware.com/products/workstation/
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..138bff3
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,37 @@
+# -*- encoding: utf-8 -*-
+
+require "bundler/gem_tasks"
+
+require "rspec/core/rake_task"
+desc "Run all specs in spec directory"
+RSpec::Core::RakeTask.new(:spec) do |t|
+  t.pattern = "spec/**/*_spec.rb"
+end
+
+desc "Run all test suites"
+task :test => [:spec]
+
+require "cane/rake_task"
+desc "Run cane to check quality metrics"
+Cane::RakeTask.new do |cane|
+  cane.canefile = "./.cane"
+end
+
+require "finstyle"
+require "rubocop/rake_task"
+RuboCop::RakeTask.new(:style) do |task|
+  task.options << "--display-cop-names"
+end
+
+desc "Display LOC stats"
+task :stats do
+  puts "\n## Production Code Stats"
+  sh "countloc -r lib/kitchen"
+  puts "\n## Test Code Stats"
+  sh "countloc -r spec"
+end
+
+desc "Run all quality tasks"
+task :quality => [:cane, :style, :stats]
+
+task :default => [:test, :quality]
diff --git a/kitchen-vagrant.gemspec b/kitchen-vagrant.gemspec
new file mode 100644
index 0000000..f679b8e
--- /dev/null
+++ b/kitchen-vagrant.gemspec
@@ -0,0 +1,34 @@
+# -*- encoding: utf-8 -*-
+lib = File.expand_path("../lib", __FILE__)
+$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
+require "kitchen/driver/vagrant_version.rb"
+require "English"
+
+Gem::Specification.new do |gem|
+  gem.name          = "kitchen-vagrant"
+  gem.version       = Kitchen::Driver::VAGRANT_VERSION
+  gem.license       = "Apache 2.0"
+  gem.authors       = ["Fletcher Nichol"]
+  gem.email         = ["fnichol at nichol.ca"]
+  gem.description   = "Kitchen::Driver::Vagrant - A Vagrant Driver for Test Kitchen."
+  gem.summary       = gem.description
+  gem.homepage      = "https://github.com/test-kitchen/kitchen-vagrant/"
+
+  gem.files         = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
+  gem.executables   = []
+  gem.test_files    = gem.files.grep(%r{^(test|spec|features)/})
+  gem.require_paths = ["lib"]
+
+  gem.add_dependency "test-kitchen", "~> 1.4"
+
+  gem.add_development_dependency "countloc",  "~> 0.4"
+  gem.add_development_dependency "rake"
+  gem.add_development_dependency "rspec",     "~> 3.2"
+  gem.add_development_dependency "simplecov", "~> 0.9"
+
+  # style and complexity libraries are tightly version pinned as newer releases
+  # may introduce new and undesireable style choices which would be immediately
+  # enforced in CI
+  gem.add_development_dependency "finstyle",  "1.4.0"
+  gem.add_development_dependency "cane",      "2.6.2"
+end
diff --git a/lib/kitchen/driver/vagrant.rb b/lib/kitchen/driver/vagrant.rb
new file mode 100644
index 0000000..06c5566
--- /dev/null
+++ b/lib/kitchen/driver/vagrant.rb
@@ -0,0 +1,433 @@
+# -*- encoding: utf-8 -*-
+#
+# Author:: Fletcher Nichol (<fnichol at nichol.ca>)
+#
+# Copyright (C) 2012, Fletcher Nichol
+#
+# 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 "erb"
+require "fileutils"
+require "rubygems/version"
+
+require "kitchen"
+require "kitchen/driver/vagrant_version"
+
+module Kitchen
+
+  module Driver
+
+    # Vagrant driver for Kitchen. It communicates to Vagrant via the CLI.
+    #
+    # @author Fletcher Nichol <fnichol at nichol.ca>
+    class Vagrant < Kitchen::Driver::Base
+
+      include ShellOut
+
+      kitchen_driver_api_version 2
+
+      plugin_version Kitchen::Driver::VAGRANT_VERSION
+
+      default_config(:box) { |driver| driver.default_box }
+      required_config :box
+
+      default_config :box_check_update, nil
+
+      default_config(:box_url) { |driver| driver.default_box_url }
+
+      default_config :box_version, nil
+
+      default_config :customize, {}
+
+      default_config :gui, nil
+
+      default_config :network, []
+
+      default_config :pre_create_command, nil
+
+      default_config :provision, false
+
+      default_config :provider do |_|
+        ENV.fetch("VAGRANT_DEFAULT_PROVIDER", "virtualbox")
+      end
+
+      default_config :ssh, {}
+
+      default_config :synced_folders, []
+
+      default_config :vagrantfile_erb,
+        File.join(File.dirname(__FILE__), "../../../templates/Vagrantfile.erb")
+      expand_path_for :vagrantfile_erb
+
+      default_config :vagrantfiles, []
+      expand_path_for :vagrantfiles
+
+      default_config(:vm_hostname) do |driver|
+        driver.windows_os? ? nil : driver.instance.name
+      end
+
+      no_parallel_for :create, :destroy
+
+      # Creates a Vagrant VM instance.
+      #
+      # @param state [Hash] mutable instance state
+      # @raise [ActionFailed] if the action could not be completed
+      def create(state)
+        create_vagrantfile
+        run_pre_create_command
+        run_vagrant_up
+        update_state(state)
+        instance.transport.connection(state).wait_until_ready
+        info("Vagrant instance #{instance.to_str} created.")
+      end
+
+      # @return [String,nil] the Vagrant box for this Instance
+      def default_box
+        if bento_box?(instance.platform.name)
+          "opscode-#{instance.platform.name}"
+        else
+          instance.platform.name
+        end
+      end
+
+      # @return [String,nil] the Vagrant box URL for this Instance
+      def default_box_url
+        return unless bento_box?(instance.platform.name)
+
+        provider = config[:provider]
+        provider = "vmware" if config[:provider] =~ /^vmware_(.+)$/
+
+        if %w[virtualbox vmware].include?(provider)
+          "https://opscode-vm-bento.s3.amazonaws.com/vagrant/#{provider}/" \
+            "opscode_#{instance.platform.name}_chef-provisionerless.box"
+        end
+      end
+
+      # Destroys an instance.
+      #
+      # @param state [Hash] mutable instance state
+      # @raise [ActionFailed] if the action could not be completed
+      def destroy(state)
+        return if state[:hostname].nil?
+
+        create_vagrantfile
+        @vagrantfile_created = false
+        instance.transport.connection(state).close
+        run("vagrant destroy -f")
+        FileUtils.rm_rf(vagrant_root)
+        info("Vagrant instance #{instance.to_str} destroyed.")
+        state.delete(:hostname)
+      end
+
+      # 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.
+      #
+      # @param instance [Instance] an associated instance
+      # @return [self] itself, for use in chaining
+      # @raise [ClientError] if instance parameter is nil
+      def finalize_config!(instance)
+        super
+        finalize_vm_hostname!
+        finalize_pre_create_command!
+        finalize_synced_folders!
+        self
+      end
+
+      # 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.
+      #
+      # @raise [UserError] if the driver will not be able to perform or if a
+      #   documented dependency is missing from the system
+      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
+
+      # @return [TrueClass,FalseClass] whether or not the transport's name
+      #   implies a WinRM-based transport
+      # @api private
+      def winrm_transport?
+        instance.transport.name.downcase =~ /win_?rm/
+      end
+
+      protected
+
+      WEBSITE = "http://www.vagrantup.com/downloads.html".freeze
+      MIN_VER = "1.1.0".freeze
+
+      class << self
+
+        # @return [true,false] whether or not the vagrant-winrm plugin is
+        #   installed
+        # @api private
+        attr_accessor :winrm_plugin_passed
+
+        # @return [String] the version of Vagrant installed on the workstation
+        # @api private
+        attr_accessor :vagrant_version
+      end
+
+      # Retuns whether or not a platform name could have a correcponding Bento
+      # box produced by the Bento project.
+      # (https://github.com/chef/bento).
+      #
+      # @return [TrueClass,FalseClass] whether or not the name could be a Bento
+      #   box
+      # @api private
+      def bento_box?(name)
+        name =~ /^(centos|debian|fedora|freebsd|opensuse|ubuntu)-/
+      end
+
+      # Renders and writes out a Vagrantfile dedicated to this instance.
+      #
+      # @api private
+      def create_vagrantfile
+        return if @vagrantfile_created
+
+        vagrantfile = File.join(vagrant_root, "Vagrantfile")
+        debug("Creating Vagrantfile for #{instance.to_str} (#{vagrantfile})")
+        FileUtils.mkdir_p(vagrant_root)
+        File.open(vagrantfile, "wb") { |f| f.write(render_template) }
+        debug_vagrantfile(vagrantfile)
+        @vagrantfile_created = true
+      end
+
+      # Logs the Vagrantfile's contents to the debug log level.
+      #
+      # @param vagrantfile [String] path to the Vagrantfile
+      # @api private
+      def debug_vagrantfile(vagrantfile)
+        return unless logger.debug?
+
+        debug("------------")
+        IO.read(vagrantfile).each_line { |l| debug("#{l.chomp}") }
+        debug("------------")
+      end
+
+      # Replaces any `{{vagrant_root}}` tokens in the pre create command.
+      #
+      # @api private
+      def finalize_pre_create_command!
+        return if config[:pre_create_command].nil?
+
+        config[:pre_create_command] = config[:pre_create_command].
+          gsub("{{vagrant_root}}", vagrant_root)
+      end
+
+      # Replaces an `%{instance_name}` tokens in the synced folder items.
+      #
+      # @api private
+      def finalize_synced_folders!
+        config[:synced_folders] = config[:synced_folders].
+          map do |source, destination, options|
+            [
+              File.expand_path(
+                source.gsub("%{instance_name}", instance.name),
+                config[:kitchen_root]
+              ),
+              destination.gsub("%{instance_name}", instance.name),
+              options || "nil"
+            ]
+          end
+      end
+
+      # Truncates the length of `:vm_hostname` to 12 characters for
+      # Windows-based operating systems.
+      #
+      # @api private
+      def finalize_vm_hostname!
+        string = config[:vm_hostname]
+
+        if windows_os? && string.is_a?(String) && string.size >= 12
+          config[:vm_hostname] = "#{string[0...10]}-#{string[-1]}"
+        end
+      end
+
+      # Loads any required third party Ruby libraries or runs any shell out
+      # commands to prepare the plugin. This method will be called in the
+      # context of the main thread of execution and so does not necessarily
+      # have to be thread safe.
+      #
+      # @raise [ClientError] if any library loading fails or any of the
+      #   dependency requirements cannot be satisfied
+      # @api private
+      def load_needed_dependencies!
+        super
+        verify_winrm_plugin if winrm_transport?
+      end
+
+      # Renders the Vagrantfile ERb template.
+      #
+      # @return [String] the contents for a Vagrantfile
+      # @raise [ActionFailed] if the Vagrantfile template was not found
+      # @api private
+      def render_template
+        template = File.expand_path(
+          config[:vagrantfile_erb], config[:kitchen_root])
+
+        if File.exist?(template)
+          ERB.new(IO.read(template)).result(binding).gsub(%r{^\s*$\n}, "")
+        else
+          raise ActionFailed, "Could not find Vagrantfile template #{template}"
+        end
+      end
+
+      # Convenience method to run a command locally.
+      #
+      # @param cmd [String] command to run locally
+      # @param options [Hash] options hash
+      # @see Kitchen::ShellOut.run_command
+      # @api private
+      def run(cmd, options = {})
+        cmd = "echo #{cmd}" if config[:dry_run]
+        run_command(cmd, { :cwd => vagrant_root }.merge(options))
+      end
+
+      # Delegates to Kitchen::ShellOut.run_command, overriding some default
+      # options:
+      #
+      # * `:use_sudo` defaults to the value of `config[:use_sudo]` in the
+      #   Driver object
+      # * `:log_subject` defaults to a String representation of the Driver's
+      #   class name
+      #
+      # @see Kitchen::ShellOut#run_command
+      def run_command(cmd, options = {})
+        merged = {
+          :use_sudo => config[:use_sudo], :log_subject => name
+        }.merge(options)
+        super(cmd, merged)
+      end
+
+      # Runs a local command before `vagrant up` has been called.
+      #
+      # @api private
+      def run_pre_create_command
+        if config[:pre_create_command]
+          run(config[:pre_create_command], :cwd => config[:kitchen_root])
+        end
+      end
+
+      # Runs a local command without streaming the stdout to the logger.
+      #
+      # @param cmd [String] command to run locally
+      # @api private
+      def run_silently(cmd, options = {})
+        merged = {
+          :live_stream => nil, :quiet => (logger.debug? ? false : true)
+        }.merge(options)
+        run(cmd, merged)
+      end
+
+      # Runs the `vagrant up` command locally.
+      #
+      # @api private
+      def run_vagrant_up
+        cmd = "vagrant up"
+        cmd += " --no-provision" unless config[:provision]
+        cmd += " --provider #{config[:provider]}" if config[:provider]
+        run(cmd)
+      end
+
+      # Updates any state after creation.
+      #
+      # @param state [Hash] mutable instance state
+      # @api private
+      def update_state(state)
+        hash = winrm_transport? ? vagrant_config(:winrm) : vagrant_config(:ssh)
+
+        state[:hostname] = hash["HostName"]
+        state[:port] = hash["Port"]
+        state[:username] = hash["User"]
+        state[:password] = hash["Password"] if hash["Password"]
+        state[:ssh_key] = hash["IdentityFile"] if hash["IdentityFile"]
+        state[:proxy_command] = hash["ProxyCommand"] if hash["ProxyCommand"]
+        state[:rdp_port] = hash["RDPPort"] if hash["RDPPort"]
+      end
+
+      # @return [String] full local path to the directory containing the
+      #   instance's Vagrantfile
+      # @api private
+      def vagrant_root
+        @vagrant_root ||= instance.nil? ? nil : File.join(
+          config[:kitchen_root], %w[.kitchen kitchen-vagrant],
+          "kitchen-#{File.basename(config[:kitchen_root])}-#{instance.name}"
+        )
+      end
+
+      # @param type [Symbol] either `:ssh` or `:winrm`
+      # @return [Hash] key/value pairs resulting from parsing a
+      #   `vagrant ssh-config` or `vagrant winrm-config` local command
+      #   invocation
+      # @api private
+      def vagrant_config(type)
+        lines = run_silently("vagrant #{type}-config").split("\n").map do |line|
+          tokens = line.strip.partition(" ")
+          [tokens.first, tokens.last.gsub(/"/, "")]
+        end
+        Hash[lines]
+      end
+
+      # @return [String] version of Vagrant
+      # @raise [UserError] if the `vagrant` command can not be found locally
+      # @api private
+      def vagrant_version
+        self.class.vagrant_version ||= run_silently(
+          "vagrant --version", :cwd => Dir.pwd).chomp.split(" ").last
+      rescue Errno::ENOENT
+        raise UserError, "Vagrant #{MIN_VER} or higher is not installed." \
+          " Please download a package from #{WEBSITE}."
+      end
+
+      # Verify that the vagrant-winrm plugin is installed and a suitable
+      #   version of Vagrant is installed
+      #
+      # @api private
+      def verify_winrm_plugin
+        if Gem::Version.new(vagrant_version) < Gem::Version.new("1.6")
+          raise UserError, "Detected an old version of Vagrant " \
+            "(#{vagrant_version}) that cannot support the vagrant-winrm " \
+            "Vagrant plugin." \
+            " Please upgrade to version 1.6 or higher from #{WEBSITE}."
+        end
+
+        if !winrm_plugin_installed?
+          raise UserError, "WinRM Transport requires the vagrant-winrm " \
+            "Vagrant plugin to properly communicate with this Vagrant VM. " \
+            "Please install this plugin with: " \
+            "`vagrant plugin install vagrant-winrm' and try again."
+        end
+      end
+
+      # @return [true,false] whether or not the vagrant-winrm plugin is
+      #   installed
+      # @api private
+      def winrm_plugin_installed?
+        return true if self.class.winrm_plugin_passed
+
+        self.class.winrm_plugin_passed = run_silently(
+          "vagrant plugin list", :cwd => Dir.pwd).
+          split("\n").find { |line| line =~ /^vagrant-winrm\s+/ }
+      end
+    end
+  end
+end
diff --git a/lib/kitchen/driver/vagrant_version.rb b/lib/kitchen/driver/vagrant_version.rb
new file mode 100644
index 0000000..99e0749
--- /dev/null
+++ b/lib/kitchen/driver/vagrant_version.rb
@@ -0,0 +1,26 @@
+# -*- encoding: utf-8 -*-
+#
+# Author:: Fletcher Nichol (<fnichol at nichol.ca>)
+#
+# Copyright (C) 2012, Fletcher Nichol
+#
+# 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.
+
+module Kitchen
+
+  module Driver
+
+    # Version string for Vagrant Kitchen driver
+    VAGRANT_VERSION = "0.18.0"
+  end
+end
diff --git a/metadata.yml b/metadata.yml
new file mode 100644
index 0000000..234cb28
--- /dev/null
+++ b/metadata.yml
@@ -0,0 +1,158 @@
+--- !ruby/object:Gem::Specification
+name: kitchen-vagrant
+version: !ruby/object:Gem::Version
+  version: 0.18.0
+platform: ruby
+authors:
+- Fletcher Nichol
+autorequire: 
+bindir: bin
+cert_chain: []
+date: 2015-05-07 00:00:00.000000000 Z
+dependencies:
+- !ruby/object:Gem::Dependency
+  name: test-kitchen
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - "~>"
+      - !ruby/object:Gem::Version
+        version: '1.4'
+  type: :runtime
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - "~>"
+      - !ruby/object:Gem::Version
+        version: '1.4'
+- !ruby/object:Gem::Dependency
+  name: countloc
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - "~>"
+      - !ruby/object:Gem::Version
+        version: '0.4'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - "~>"
+      - !ruby/object:Gem::Version
+        version: '0.4'
+- !ruby/object:Gem::Dependency
+  name: rake
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ">="
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ">="
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: rspec
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - "~>"
+      - !ruby/object:Gem::Version
+        version: '3.2'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - "~>"
+      - !ruby/object:Gem::Version
+        version: '3.2'
+- !ruby/object:Gem::Dependency
+  name: simplecov
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - "~>"
+      - !ruby/object:Gem::Version
+        version: '0.9'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - "~>"
+      - !ruby/object:Gem::Version
+        version: '0.9'
+- !ruby/object:Gem::Dependency
+  name: finstyle
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - '='
+      - !ruby/object:Gem::Version
+        version: 1.4.0
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - '='
+      - !ruby/object:Gem::Version
+        version: 1.4.0
+- !ruby/object:Gem::Dependency
+  name: cane
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - '='
+      - !ruby/object:Gem::Version
+        version: 2.6.2
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - '='
+      - !ruby/object:Gem::Version
+        version: 2.6.2
+description: Kitchen::Driver::Vagrant - A Vagrant Driver for Test Kitchen.
+email:
+- fnichol at nichol.ca
+executables: []
+extensions: []
+extra_rdoc_files: []
+files:
+- ".gitignore"
+- ".travis.yml"
+- CHANGELOG.md
+- Gemfile
+- Guardfile
+- LICENSE
+- README.md
+- Rakefile
+- kitchen-vagrant.gemspec
+- lib/kitchen/driver/vagrant.rb
+- lib/kitchen/driver/vagrant_version.rb
+- spec/kitchen/driver/vagrant_spec.rb
+- spec/spec_helper.rb
+- templates/Vagrantfile.erb
+homepage: https://github.com/test-kitchen/kitchen-vagrant/
+licenses:
+- Apache 2.0
+metadata: {}
+post_install_message: 
+rdoc_options: []
+require_paths:
+- lib
+required_ruby_version: !ruby/object:Gem::Requirement
+  requirements:
+  - - ">="
+    - !ruby/object:Gem::Version
+      version: '0'
+required_rubygems_version: !ruby/object:Gem::Requirement
+  requirements:
+  - - ">="
+    - !ruby/object:Gem::Version
+      version: '0'
+requirements: []
+rubyforge_project: 
+rubygems_version: 2.4.5
+signing_key: 
+specification_version: 4
+summary: Kitchen::Driver::Vagrant - A Vagrant Driver for Test Kitchen.
+test_files:
+- spec/kitchen/driver/vagrant_spec.rb
+- spec/spec_helper.rb
diff --git a/spec/kitchen/driver/vagrant_spec.rb b/spec/kitchen/driver/vagrant_spec.rb
new file mode 100644
index 0000000..4970f90
--- /dev/null
+++ b/spec/kitchen/driver/vagrant_spec.rb
@@ -0,0 +1,1398 @@
+# -*- encoding: utf-8 -*-
+#
+# Author:: Fletcher Nichol (<fnichol at nichol.ca>)
+#
+# Copyright (C) 2015, Fletcher Nichol
+#
+# 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_relative "../../spec_helper"
+
+require "logger"
+require "stringio"
+
+require "kitchen/driver/vagrant"
+require "kitchen/provisioner/dummy"
+require "kitchen/transport/dummy"
+require "kitchen/verifier/dummy"
+
+describe Kitchen::Driver::Vagrant do
+
+  let(:logged_output) { StringIO.new }
+  let(:logger)        { Logger.new(logged_output) }
+  let(:config)        { { :kitchen_root => "/kroot" } }
+  let(:platform)      { Kitchen::Platform.new(:name => "fooos-99") }
+  let(:suite)         { Kitchen::Suite.new(:name => "suitey") }
+  let(:verifier)      { Kitchen::Verifier::Dummy.new }
+  let(:provisioner)   { Kitchen::Provisioner::Dummy.new }
+  let(:transport)     { Kitchen::Transport::Dummy.new }
+  let(:state_file)    { double("state_file") }
+  let(:state)         { Hash.new }
+  let(:env)           { Hash.new }
+
+  let(:driver_object) { Kitchen::Driver::Vagrant.new(config) }
+
+  let(:driver) do
+    d = driver_object
+    instance
+    d
+  end
+
+  let(:instance) do
+    Kitchen::Instance.new(
+      :verifier => verifier,
+      :driver => driver_object,
+      :logger => logger,
+      :suite => suite,
+      :platform => platform,
+      :provisioner => provisioner,
+      :transport => transport,
+      :state_file => state_file
+    )
+  end
+
+  before { stub_const("ENV", env) }
+
+  after do
+    driver_object.class.send(:winrm_plugin_passed=, nil)
+    driver_object.class.send(:vagrant_version=, nil)
+  end
+
+  it "driver api_version is 2" do
+    expect(driver.diagnose_plugin[:api_version]).to eq(2)
+  end
+
+  it "plugin_version is set to Kitchen::Vagrant::VERSION" do
+    expect(driver.diagnose_plugin[:version]).to eq(
+      Kitchen::Driver::VAGRANT_VERSION)
+  end
+
+  describe "configuration" do
+
+    %W[centos debian fedora opensuse ubuntu].each do |name|
+
+      context "for known bento platform names starting with #{name}" do
+
+        before { allow(platform).to receive(:name) { "#{name}-99.04" } }
+
+        it "sets :box based on the platform name by default" do
+          expect(driver[:box]).to eq("opscode-#{name}-99.04")
+        end
+
+        it "sets :box to a custom value" do
+          config[:box] = "booya"
+
+          expect(driver[:box]).to eq("booya")
+        end
+
+        it "sets :box_url to a bento box URL for a virtualbox provider" do
+          config[:provider] = "virtualbox"
+
+          expect(driver[:box_url]).to eq(
+            "https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/" \
+            "opscode_#{name}-99.04_chef-provisionerless.box"
+          )
+        end
+
+        it "sets :box_url to a bento box URL for a vmware-based provider" do
+          config[:provider] = "vmware_awesometown"
+
+          expect(driver[:box_url]).to eq(
+            "https://opscode-vm-bento.s3.amazonaws.com/vagrant/vmware/" \
+            "opscode_#{name}-99.04_chef-provisionerless.box"
+          )
+        end
+
+        it "sets :box_url to nil for any other provider" do
+          config[:provider] = "the-next-coolness"
+
+          expect(driver[:box_url]).to eq(nil)
+        end
+      end
+    end
+
+    context "for unknown bento platform names" do
+
+      before { allow(platform).to receive(:name) { "slackware-14.1" } }
+
+      it "sets :box based on the platform name by default" do
+        expect(driver[:box]).to eq("slackware-14.1")
+      end
+
+      it "sets :box to a custom value" do
+        config[:box] = "booya"
+
+        expect(driver[:box]).to eq("booya")
+      end
+
+      it "sets :box_url to nil" do
+        expect(driver[:box_url]).to eq(nil)
+      end
+    end
+
+    it "sets :box_check_update to nil by default" do
+      expect(driver[:box_check_update]).to eq(nil)
+    end
+
+    it "sets :box_check_update to a custom value" do
+      config[:box_check_update] = true
+
+      expect(driver[:box_check_update]).to eq(true)
+    end
+
+    it "sets :box_version to nil by default" do
+      expect(driver[:box_version]).to eq(nil)
+    end
+
+    it "sets :box_version to a custom value" do
+      config[:box_version] = "1.2.3"
+
+      expect(driver[:box_version]).to eq("1.2.3")
+    end
+
+    it "sets :customize to an empty hash by default" do
+      expect(driver[:customize]).to eq({})
+    end
+
+    it "sets :customize to a custom value" do
+      config[:customize] = { :a => "b", :c => { :d => "e" } }
+
+      expect(driver[:customize]).to eq(:a => "b", :c => { :d => "e" })
+    end
+
+    it "sets :gui to nil by default" do
+      expect(driver[:gui]).to eq(nil)
+    end
+
+    it "sets :network to an empty array by default" do
+      expect(driver[:network]).to eq([])
+    end
+
+    it "sets :network to a custom value" do
+      config[:network] = [
+        ["forwarded_port", :guest => 80, :host => 8080]
+      ]
+
+      expect(driver[:network]).to eq([
+        ["forwarded_port", :guest => 80, :host => 8080]
+      ])
+    end
+
+    it "sets :pre_create_command to nil by default" do
+      expect(driver[:pre_create_command]).to eq(nil)
+    end
+
+    it "sets :pre_create_command to a custom value" do
+      config[:pre_create_command] = "execute yo"
+
+      expect(driver[:pre_create_command]).to eq("execute yo")
+    end
+
+    it "replaces {{vagrant_root}} in :pre_create_command" do
+      config[:pre_create_command] = "{{vagrant_root}}/candy"
+
+      expect(driver[:pre_create_command]).to eq(
+        "/kroot/.kitchen/kitchen-vagrant/kitchen-kroot-suitey-fooos-99/candy"
+      )
+    end
+
+    it "sets :provision to false by default" do
+      expect(driver[:provision]).to eq(false)
+    end
+
+    it "sets :provision to a custom value" do
+      config[:provision] = true
+
+      expect(driver[:provision]).to eq(true)
+    end
+
+    it "sets :provider to virtualbox by default" do
+      expect(driver[:provider]).to eq("virtualbox")
+    end
+
+    it "sets :provider to the value of VAGRANT_DEFAULT_PROVIDER from ENV" do
+      env["VAGRANT_DEFAULT_PROVIDER"] = "vcool"
+
+      expect(driver[:provider]).to eq("vcool")
+    end
+
+    it "sets :provider to a custom value" do
+      config[:provider] = "mything"
+
+      expect(driver[:provider]).to eq("mything")
+    end
+
+    it "sets :ssh to an empty hash by default" do
+      expect(driver[:ssh]).to eq({})
+    end
+
+    it "sets :ssh to a custom value" do
+      config[:ssh] = { :a => "b", :c => { :d => "e" } }
+
+      expect(driver[:ssh]).to eq(:a => "b", :c => { :d => "e" })
+    end
+
+    it "sets :synced_folders to an empty array by default" do
+      expect(driver[:synced_folders]).to eq([])
+    end
+
+    it "sets :synced_folders to a custom value" do
+      config[:synced_folders] = [
+        ["/host_path", "/vm_path", "create: true, type: :nfs"]
+      ]
+
+      expect(driver[:synced_folders]).to eq([
+        ["/host_path", "/vm_path", "create: true, type: :nfs"]
+      ])
+    end
+
+    it "replaces %{instance_name} with instance name in :synced_folders" do
+      config[:synced_folders] = [
+        ["/root/%{instance_name}", "/vm_path", "stuff"]
+      ]
+
+      expect(driver[:synced_folders]).to eq([
+        ["/root/suitey-fooos-99", "/vm_path", "stuff"]
+      ])
+    end
+
+    it "expands source paths relative to :kitchen_root in :synced_folders" do
+      config[:synced_folders] = [
+        ["./a", "/vm_path", "stuff"]
+      ]
+
+      expect(driver[:synced_folders]).to eq([
+        ["/kroot/a", "/vm_path", "stuff"]
+      ])
+    end
+
+    it "sets options to 'nil' if not set in :synced_folders entry" do
+      config[:synced_folders] = [
+        ["/host_path", "/vm_path", nil]
+      ]
+
+      expect(driver[:synced_folders]).to eq([
+        ["/host_path", "/vm_path", "nil"]
+      ])
+    end
+
+    it "sets :vagrantfile_erb to a default" do
+      expect(driver[:vagrantfile_erb]).to match(
+        %r{/kitchen-vagrant/templates/Vagrantfile\.erb$}
+      )
+    end
+
+    it "sets :vagrantfile_erb to a default value" do
+      config[:vagrantfile_erb] = "/a/Vagrantfile.erb"
+
+      expect(driver[:vagrantfile_erb]).to eq("/a/Vagrantfile.erb")
+    end
+
+    it "expands path for :vagrantfile_erb" do
+      config[:vagrantfile_erb] = "Yep.erb"
+
+      expect(driver[:vagrantfile_erb]).to eq("/kroot/Yep.erb")
+    end
+
+    it "sets :vagrantfiles to an empty array by default" do
+      expect(driver[:vagrantfiles]).to eq([])
+    end
+
+    it "sets and expands paths in :vagrantfiles" do
+      config[:vagrantfiles] = %W[one two three]
+
+      expect(driver[:vagrantfiles]).to eq(
+        %W[/kroot/one /kroot/two /kroot/three]
+      )
+    end
+
+    context "for unix os_types" do
+
+      before { allow(platform).to receive(:os_type).and_return("unix") }
+
+      it "sets :vm_hostname to the instance name by default" do
+        expect(driver[:vm_hostname]).to eq("suitey-fooos-99")
+      end
+
+      it "sets :vm_hostname to a custom value" do
+        config[:vm_hostname] = "okay"
+
+        expect(driver[:vm_hostname]).to eq("okay")
+      end
+    end
+
+    context "for windows os_types" do
+
+      before { allow(platform).to receive(:os_type).and_return("windows") }
+
+      it "sets :vm_hostname to nil by default" do
+        expect(driver[:vm_hostname]).to eq(nil)
+      end
+
+      it "sets :vm_hostname to a custom value, truncated to 12 chars" do
+        config[:vm_hostname] = "this-is-a-pretty-long-name-ya-think"
+
+        expect(driver[:vm_hostname]).to eq("this-is-a--k")
+      end
+    end
+  end
+
+  describe "#verify_dependencies" do
+
+    it "passes for supported versions of Vagrant" do
+      with_modern_vagrant
+
+      driver.verify_dependencies
+    end
+
+    it "raises a UserError for unsupported versions of Vagrant" do
+      with_unsupported_vagrant
+
+      expect { driver.verify_dependencies }.to raise_error(
+        Kitchen::UserError, /Please upgrade to version 1.1.0 or higher/
+      )
+    end
+
+    it "raises a UserError for a missing Vagrant command" do
+      allow(driver_object).to receive(:run_command).
+        with("vagrant --version", any_args).and_raise(Errno::ENOENT)
+
+      expect { driver.verify_dependencies }.to raise_error(
+        Kitchen::UserError, /Vagrant 1.1.0 or higher is not installed/
+      )
+    end
+  end
+
+  describe "#load_needed_dependencies!" do
+
+    describe "with winrm transport" do
+
+      before { allow(transport).to receive(:name).and_return("WinRM") }
+
+      it "old version of Vagrant raises UserError" do
+        with_vagrant("1.5.0")
+
+        expect { instance }.to raise_error(
+          Kitchen::Error, /Please upgrade to version 1.6 or higher/
+        )
+      end
+
+      it "modern vagrant without plugin installed raises UserError" do
+        with_modern_vagrant
+        allow(driver_object).to receive(:run_command).
+          with("vagrant plugin list", any_args).and_return("nope (1.2.3)")
+
+        expect { instance }.to raise_error(
+          Kitchen::Error, /vagrant plugin install vagrant-winrm/
+        )
+      end
+
+      it "modern vagrant with plugin installed succeeds" do
+        with_modern_vagrant
+        allow(driver_object).to receive(:run_command).
+          with("vagrant plugin list", any_args).
+          and_return("vagrant-winrm (1.2.3)")
+
+        instance
+      end
+    end
+
+    describe "without winrm transport" do
+
+      before { allow(transport).to receive(:name).and_return("Anything") }
+
+      it "old version of Vagrant succeeds" do
+        with_vagrant("1.5.0")
+
+        instance
+      end
+
+      it "modern vagrant without plugin installed succeeds" do
+        with_modern_vagrant
+        allow(driver_object).to receive(:run_command).
+          with("vagrant plugin list", any_args).and_return("nope (1.2.3)")
+
+        instance
+      end
+
+      it "modern vagrant with plugin installed succeeds" do
+        with_modern_vagrant
+        allow(driver_object).to receive(:run_command).
+          with("vagrant plugin list", any_args).
+          and_return("vagrant-winrm (1.2.3)")
+
+        instance
+      end
+    end
+  end
+
+  describe "#create" do
+
+    let(:cmd) { driver.create(state) }
+
+    let(:vagrant_root) do
+      File.join(%W[
+        #{@dir} .kitchen kitchen-vagrant
+        kitchen-#{File.basename(@dir)}-suitey-fooos-99
+      ])
+    end
+
+    before do
+      @dir = Dir.mktmpdir("kitchen_root")
+      config[:kitchen_root] = @dir
+
+      allow(driver).to receive(:run_command).and_return("")
+      with_modern_vagrant
+    end
+
+    after do
+      FileUtils.remove_entry_secure(@dir)
+    end
+
+    it "logs a message on debug level for creating the Vagrantfile" do
+      cmd
+
+      expect(logged_output.string).to match(
+        /^D, .+ DEBUG -- : Creating Vagrantfile for \<suitey-fooos-99\> /
+      )
+    end
+
+    it "creates a Vagrantfile in the vagrant root directory" do
+      cmd
+
+      expect(File.exist?(File.join(vagrant_root, "Vagrantfile"))).to eq(true)
+    end
+
+    it "calls Transport's #wait_until_ready" do
+      conn = double("connection")
+      allow(transport).to receive(:connection).with(state).and_return(conn)
+      expect(conn).to receive(:wait_until_ready)
+
+      cmd
+    end
+
+    it "logs the Vagrantfile contents on debug level" do
+      cmd
+
+      expect(debug_lines).to match(Regexp.new(<<-REGEXP.gsub(/^ {8}/, "")))
+        ------------
+        Vagrant.configure\("2"\) do \|c\|
+        .*
+        end
+        ------------
+      REGEXP
+    end
+
+    it "raises ActionFailed if a custom Vagrantfile template was not found" do
+      config[:vagrantfile_erb] = "/a/bunch/of/nope"
+
+      expect { cmd }.to raise_error(
+        Kitchen::ActionFailed, /^Could not find Vagrantfile template/
+      )
+    end
+
+    it "runs the pre create command, if set" do
+      config[:pre_create_command] = "echo heya"
+      expect(driver).to receive(:run_command).with("echo heya", any_args)
+
+      cmd
+    end
+
+    it "runs vagrant up with --no-provision if :provision is falsey" do
+      config[:provision] = false
+      expect(driver).to receive(:run_command).
+        with("vagrant up --no-provision --provider virtualbox", any_args)
+
+      cmd
+    end
+
+    it "runs vagrant up without --no-provision if :provision is truthy" do
+      config[:provision] = true
+      expect(driver).to receive(:run_command).
+        with("vagrant up --provider virtualbox", any_args)
+
+      cmd
+    end
+
+    it "runs vagrant up with a custom provider if :provider is set" do
+      config[:provider] = "bananas"
+      expect(driver).to receive(:run_command).
+        with("vagrant up --no-provision --provider bananas", any_args)
+
+      cmd
+    end
+
+    describe "for state" do
+
+      context "for non-WinRM-based transports" do
+
+        let(:output) do
+          <<-OUTPUT.gsub(/^ {10}/, "")
+            Host hehe
+              HostName 192.168.32.64
+              User vagrant
+              Port 2022
+              UserKnownHostsFile /dev/null
+              StrictHostKeyChecking no
+              PasswordAuthentication no
+              IdentityFile /path/to/private_key
+              IdentitiesOnly yes
+              LogLevel FATAL
+          OUTPUT
+        end
+
+        before do
+          allow(transport).to receive(:name).and_return("Coolness")
+          allow(driver).to receive(:run_command).
+            with("vagrant ssh-config", any_args).and_return(output)
+        end
+
+        it "sets :hostname from ssh-config" do
+          cmd
+
+          expect(state).to include(:hostname => "192.168.32.64")
+        end
+
+        it "sets :port from ssh-config" do
+          cmd
+
+          expect(state).to include(:port => "2022")
+        end
+
+        it "sets :username from ssh-config" do
+          cmd
+
+          expect(state).to include(:username => "vagrant")
+        end
+
+        it "does not set :password by default" do
+          cmd
+
+          expect(state.keys).to_not include(:password)
+        end
+
+        it "sets :password if Password is in ssh-config" do
+          output.concat("  Password yep\n")
+          cmd
+
+          expect(state).to include(:password => "yep")
+        end
+
+        it "sets :ssh_key from ssh-config" do
+          cmd
+
+          expect(state).to include(:ssh_key => "/path/to/private_key")
+        end
+
+        it "does not set :proxy_command by default" do
+          cmd
+
+          expect(state.keys).to_not include(:proxy_command)
+        end
+
+        it "sets :proxy_command if ProxyCommand is in ssh-config" do
+          output.concat("  ProxyCommand echo proxy\n")
+          cmd
+
+          expect(state).to include(:proxy_command => "echo proxy")
+        end
+      end
+
+      context "for WinRM-based transports" do
+
+        let(:output) do
+          <<-OUTPUT.gsub(/^ {10}/, "")
+            Host hehe
+              HostName 192.168.32.64
+              User vagrant
+              Password yep
+              Port 9999
+              RDPPort 5555
+          OUTPUT
+        end
+
+        before do
+          allow(transport).to receive(:name).and_return("WinRM")
+          allow(driver).to receive(:run_command).
+            with("vagrant winrm-config", any_args).and_return(output)
+        end
+
+        it "sets :hostname from winrm-config" do
+          cmd
+
+          expect(state).to include(:hostname => "192.168.32.64")
+        end
+
+        it "sets :port from winrm-config" do
+          cmd
+
+          expect(state).to include(:port => "9999")
+        end
+
+        it "sets :username from winrm-config" do
+          cmd
+
+          expect(state).to include(:username => "vagrant")
+        end
+
+        it "sets :password from winrm-config" do
+          cmd
+
+          expect(state).to include(:password => "yep")
+        end
+
+        it "sets :rdp_port from winrm-config" do
+          cmd
+
+          expect(state).to include(:rdp_port => "5555")
+        end
+      end
+    end
+
+    it "logs a message on info level" do
+      cmd
+
+      expect(logged_output.string).to match(
+        /I, .+ INFO -- : Vagrant instance \<suitey-fooos-99\> created\.$/
+      )
+    end
+  end
+
+  describe "#destroy" do
+
+    let(:cmd) { driver.destroy(state) }
+
+    let(:vagrant_root) do
+      File.join(%W[
+        #{@dir} .kitchen kitchen-vagrant
+        kitchen-#{File.basename(@dir)}-suitey-fooos-99
+      ])
+    end
+
+    before do
+      @dir = Dir.mktmpdir("kitchen_root")
+      config[:kitchen_root] = @dir
+
+      allow(driver).to receive(:run_command).and_return("")
+      with_modern_vagrant
+
+      FileUtils.mkdir_p(vagrant_root)
+      state[:hostname] = "hosta"
+    end
+
+    after do
+      FileUtils.remove_entry_secure(@dir)
+    end
+
+    it "logs a message on debug level for creating the Vagrantfile" do
+      cmd
+
+      expect(logged_output.string).to match(
+        /^D, .+ DEBUG -- : Creating Vagrantfile for \<suitey-fooos-99\> /
+      )
+    end
+
+    it "logs the Vagrantfile contents on debug level" do
+      cmd
+
+      expect(debug_lines).to match(Regexp.new(<<-REGEXP.gsub(/^ {8}/, "")))
+        ------------
+        Vagrant.configure\("2"\) do \|c\|
+        .*
+        end
+        ------------
+      REGEXP
+    end
+
+    it "does not run vagrant destroy if :hostname is not present in state" do
+      state.delete(:hostname)
+      expect(driver).to_not receive(:run_command).
+        with("vagrant destroy -f", any_args)
+
+      cmd
+    end
+
+    it "closes the transport connection" do
+      connection = double(Kitchen::Transport::Base::Connection)
+      allow(transport).to receive(:connection).with(state) { connection }
+      expect(connection).to receive(:close)
+
+      cmd
+    end
+
+    it "runs vagrant destroy" do
+      expect(driver).to receive(:run_command).
+        with("vagrant destroy -f", any_args)
+
+      cmd
+    end
+
+    it "deletes the vagrant root directory" do
+      expect(File.directory?(vagrant_root)).to eq(true)
+      cmd
+      expect(File.directory?(vagrant_root)).to eq(false)
+    end
+
+    it "logs a message on info level" do
+      cmd
+
+      expect(logged_output.string).to match(
+        /I, .+ INFO -- : Vagrant instance \<suitey-fooos-99\> destroyed\.$/
+      )
+    end
+
+    it "deletes :hostname from state" do
+      cmd
+
+      expect(state.keys).to_not include(:hostname)
+    end
+  end
+
+  describe "Vagrantfile" do
+
+    let(:cmd) { driver.create(state) }
+
+    let(:vagrant_root) do
+      File.join(%W[
+        #{@dir} .kitchen kitchen-vagrant
+        kitchen-#{File.basename(@dir)}-suitey-fooos-99
+      ])
+    end
+
+    before do
+      @dir = Dir.mktmpdir("kitchen_root")
+      config[:kitchen_root] = @dir
+
+      allow(driver).to receive(:run_command).and_return("")
+      with_modern_vagrant
+    end
+
+    after do
+      FileUtils.remove_entry_secure(@dir)
+    end
+
+    it "disables the vagrant-berkshelf plugin is present" do
+      cmd
+
+      expect(vagrantfile).to match(regexify(
+        "c.berkshelf.enabled = false " \
+        "if Vagrant.has_plugin?(\"vagrant-berkshelf\")"
+      ))
+    end
+
+    it "sets the vm.box" do
+      cmd
+
+      expect(vagrantfile).to match(regexify(%{c.vm.box = "fooos-99"}))
+    end
+
+    it "sets the vm.hostname" do
+      config[:vm_hostname] = "charlie"
+      cmd
+
+      expect(vagrantfile).to match(regexify(%{c.vm.hostname = "charlie"}))
+    end
+
+    it "disables the /vagrant synced folder by default" do
+      cmd
+
+      expect(vagrantfile).to match(regexify(
+        %{c.vm.synced_folder ".", "/vagrant", disabled: true}
+      ))
+    end
+
+    it "creates an empty provider block by default" do
+      config[:provider] = "wowza"
+      cmd
+
+      expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {6}/, "").chomp))
+        c.vm.provider :wowza do |p|
+        end
+      RUBY
+    end
+
+    it "requires no Vagrantfiles by default" do
+      cmd
+
+      expect(vagrantfile).to_not match(regexify("require"))
+    end
+
+    it "requires each entry in :vagranfiles" do
+      config[:vagrantfiles] = %W[/a /b /c]
+      cmd
+
+      expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+        require "/a"
+        require "/b"
+        require "/c"
+      RUBY
+    end
+
+    it "sets no vm.box_url if missing" do
+      config[:box_url] = nil
+      cmd
+
+      expect(vagrantfile).to_not match(regexify(%{c.vm.box_url}, :partial))
+    end
+
+    it "sets vm.box_url if :box_url is set" do
+      config[:box_url] = "dat.url"
+      cmd
+
+      expect(vagrantfile).to match(regexify(%{c.vm.box_url = "dat.url"}))
+    end
+
+    it "sets no vm.box_version if missing" do
+      config[:box_version] = nil
+      cmd
+
+      expect(vagrantfile).to_not match(regexify(%{c.vm.box_version}, :partial))
+    end
+
+    it "sets vm.box_version if :box_version is set" do
+      config[:box_version] = "a.b.c"
+      cmd
+
+      expect(vagrantfile).to match(regexify(%{c.vm.box_version = "a.b.c"}))
+    end
+
+    it "sets no vm.box_check_update if missing" do
+      config[:box_check_update] = nil
+      cmd
+
+      expect(vagrantfile).to_not match(
+        regexify(%{c.vm.box_check_update}, :partial)
+      )
+    end
+
+    it "sets vm.box_check_update if :box_check_update is set" do
+      config[:box_check_update] = "um"
+      cmd
+
+      expect(vagrantfile).to match(regexify(%{c.vm.box_check_update = "um"}))
+    end
+
+    it "sets no vm.communicator if missing" do
+      config[:communicator] = nil
+      cmd
+
+      expect(vagrantfile).to_not match(regexify(%{c.vm.communicator}, :partial))
+    end
+
+    it "sets vm.communicator if :communicator is set" do
+      config[:communicator] = "wat"
+      cmd
+
+      expect(vagrantfile).to match(regexify(%{c.vm.communicator = "wat"}))
+    end
+
+    it "sets no vm.guest if missing" do
+      config[:guest] = nil
+      cmd
+
+      expect(vagrantfile).to_not match(regexify(%{c.vm.guest}, :partial))
+    end
+
+    it "sets vm.guest if :guest is set" do
+      config[:guest] = "mac"
+      cmd
+
+      expect(vagrantfile).to match(regexify(%{c.vm.guest = "mac"}))
+    end
+
+    it "sets no ssh.username if missing" do
+      config[:username] = nil
+      cmd
+
+      expect(vagrantfile).to_not match(regexify(%{c.ssh.username}, :partial))
+    end
+
+    it "sets ssh.username if :username is set" do
+      config[:username] = "jdoe"
+      cmd
+
+      expect(vagrantfile).to match(regexify(%{c.ssh.username = "jdoe"}))
+    end
+
+    it "sets no ssh.password if missing" do
+      config[:password] = nil
+      cmd
+
+      expect(vagrantfile).to_not match(regexify(%{c.ssh.password}, :partial))
+    end
+
+    it "sets ssh.password if :password is set" do
+      config[:password] = "okay"
+      cmd
+
+      expect(vagrantfile).to match(regexify(%{c.ssh.password = "okay"}))
+    end
+
+    it "sets communicator.username if :communicator and :username are set" do
+      config[:communicator] = "wat"
+      config[:username] = "jdoe"
+      cmd
+
+      expect(vagrantfile).to match(regexify(%{c.wat.username = "jdoe"}))
+    end
+
+    it "sets communicator.password if :communicator and :password are set" do
+      config[:communicator] = "wat"
+      config[:password] = "okay"
+      cmd
+
+      expect(vagrantfile).to match(regexify(%{c.wat.password = "okay"}))
+    end
+
+    it "sets no ssh.private_key_path if missing" do
+      config[:ssh_key] = nil
+      cmd
+
+      expect(vagrantfile).to_not match(
+        regexify(%{c.ssh.private_key_path}, :partial)
+      )
+    end
+
+    it "sets ssh.private_key_path if :ssh_key is set" do
+      config[:ssh_key] = "okay"
+      cmd
+
+      expect(vagrantfile).to match(regexify(%{c.ssh.private_key_path = "okay"}))
+    end
+
+    it "adds a vm.ssh line for each key/value pair in :ssh" do
+      config[:ssh] = {
+        :username => %{"jdoe"},
+        :password => %{"secret"},
+        :private_key_path => %{"/key"}
+      }
+      cmd
+
+      expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {6}/, "").chomp))
+        c.ssh.username = "jdoe"
+        c.ssh.password = "secret"
+        c.ssh.private_key_path = "/key"
+      RUBY
+    end
+
+    it "adds a vm.network line for each element in :network" do
+      config[:network] = [
+        ["forwarded_port", { :guest => 80, :host => 8080 }],
+        ["private_network", { :ip => "192.168.33.33" }]
+      ]
+      cmd
+
+      expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {6}/, "").chomp))
+        c.vm.network(:forwarded_port, {:guest=>80, :host=>8080})
+        c.vm.network(:private_network, {:ip=>"192.168.33.33"})
+      RUBY
+    end
+
+    it "adds a vm.synced_folder line for each element in :synced_folders" do
+      config[:synced_folders] = [
+        ["/a/b", "/opt/instance_data", "nil"],
+        ["/host_path", "/vm_path", "create: true, type: :nfs"]
+      ]
+      cmd
+
+      expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {6}/, "").chomp))
+        c.vm.synced_folder "/a/b", "/opt/instance_data", nil
+        c.vm.synced_folder "/host_path", "/vm_path", create: true, type: :nfs
+      RUBY
+    end
+
+    context "for virtualbox provider" do
+
+      before { config[:provider] = "virtualbox" }
+
+      it "adds a line for each element in :customize" do
+        config[:customize] = {
+          :a_key => "some value",
+          :something => "else"
+        }
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :virtualbox do |p|
+            p.customize ["modifyvm", :id, "--a_key", "some value"]
+            p.customize ["modifyvm", :id, "--something", "else"]
+          end
+        RUBY
+      end
+
+      it "does not set :gui to nil" do
+        config[:gui] = nil
+        cmd
+
+        expect(vagrantfile).to_not match(regexify(%{p.gui = }, :partial))
+      end
+
+      it "sets :gui to false if set" do
+        config[:gui] = false
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :virtualbox do |p|
+            p.gui = false
+          end
+        RUBY
+      end
+
+      it "sets :gui to true if set" do
+        config[:gui] = true
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :virtualbox do |p|
+            p.gui = true
+          end
+        RUBY
+      end
+    end
+
+    context "for parallels provider" do
+
+      before { config[:provider] = "parallels" }
+
+      it "adds a line for each element in :customize" do
+        config[:customize] = {
+          :a_key => "some value",
+          :something => "else"
+        }
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :parallels do |p|
+            p.customize ["set", :id, "--a-key", "some value"]
+            p.customize ["set", :id, "--something", "else"]
+          end
+        RUBY
+      end
+    end
+
+    context "for rackspace provider" do
+
+      before { config[:provider] = "rackspace" }
+
+      it "adds a line for each element in :customize" do
+        config[:customize] = {
+          :a_key => "some value",
+          :something => "else"
+        }
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :rackspace do |p|
+            p.a_key = "some value"
+            p.something = "else"
+          end
+        RUBY
+      end
+    end
+
+    context "for softlayer provider" do
+
+      before { config[:provider] = "softlayer" }
+
+      it "adds a line for disk_capacity" do
+        config[:customize] = {
+          :disk_capacity => {
+            :"0" => 25,
+            :"2" => 100
+          }
+        }
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :softlayer do |p|
+            p.disk_capacity = {:"0"=>25, :"2"=>100}
+          end
+        RUBY
+      end
+
+      it "adds a line for each element in :customize" do
+        config[:customize] = {
+          :a_key => "some value",
+          :something => "else"
+        }
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :softlayer do |p|
+            p.a_key = "some value"
+            p.something = "else"
+          end
+        RUBY
+      end
+    end
+
+    context "for libvirt provider" do
+
+      before { config[:provider] = "libvirt" }
+
+      it "adds a line for each element in :customize" do
+        config[:customize] = {
+          :a_key => "some value",
+          :something => "else"
+        }
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :libvirt do |p|
+            p.a_key = some value
+            p.something = else
+          end
+        RUBY
+      end
+    end
+
+    context "for lxc provider" do
+
+      before { config[:provider] = "lxc" }
+
+      it "sets container_name to :machine if set" do
+        config[:customize] = {
+          :container_name => ":machine"
+        }
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :lxc do |p|
+            p.container_name = :machine
+          end
+        RUBY
+      end
+
+      it "sets container_name to another value in quotes if set" do
+        config[:customize] = {
+          :container_name => "beans"
+        }
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :lxc do |p|
+            p.container_name = "beans"
+          end
+        RUBY
+      end
+
+      it "sets backingstore if set" do
+        config[:customize] = {
+          :backingstore => "lvm"
+        }
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :lxc do |p|
+            p.backingstore = "lvm"
+          end
+        RUBY
+      end
+
+      it "sets backingstore_option line for each backingstore_options" do
+        config[:customize] = {
+          :backingstore_options => {
+            :vgname => "schroots",
+            :fstype => "xfs"
+          }
+        }
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :lxc do |p|
+            p.backingstore_option "--vgname", "schroots"
+            p.backingstore_option "--fstype", "xfs"
+          end
+        RUBY
+      end
+
+      it "sets all other options to customize lines" do
+        config[:customize] = {
+          :cookies => "cream",
+          :salt => "vinegar"
+        }
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :lxc do |p|
+            p.customize "cookies", "cream"
+            p.customize "salt", "vinegar"
+          end
+        RUBY
+      end
+    end
+
+    context "for vmware_* providers" do
+
+      before { config[:provider] = "vmware_desktop" }
+
+      it "does not set :gui to nil" do
+        config[:gui] = nil
+        cmd
+
+        expect(vagrantfile).to_not match(regexify(%{p.gui = }, :partial))
+      end
+
+      it "sets :gui to false if set" do
+        config[:gui] = false
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :vmware_desktop do |p|
+            p.gui = false
+          end
+        RUBY
+      end
+
+      it "sets :gui to true if set" do
+        config[:gui] = true
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :vmware_desktop do |p|
+            p.gui = true
+          end
+        RUBY
+      end
+
+      it "adds a line for each element in :customize" do
+        config[:customize] = {
+          :a_key => "some value",
+          :something => "else"
+        }
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :vmware_desktop do |p|
+            p.vmx["a_key"] = "some value"
+            p.vmx["something"] = "else"
+          end
+        RUBY
+      end
+
+      it "converts :memory into :memsize" do
+        config[:customize] = {
+          :memory => "222"
+        }
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :vmware_desktop do |p|
+            p.vmx["memsize"] = "222"
+          end
+        RUBY
+      end
+
+      it "skips :memory if key :memsize exists" do
+        config[:customize] = {
+          :memory => "222",
+          :memsize => "444"
+        }
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :vmware_desktop do |p|
+            p.vmx["memsize"] = "444"
+          end
+        RUBY
+      end
+
+      it "converts :cpus into :numvcpus" do
+        config[:customize] = {
+          :cpus => "2"
+        }
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :vmware_desktop do |p|
+            p.vmx["numvcpus"] = "2"
+          end
+        RUBY
+      end
+
+      it "skips :cpus if key :numvcpus exists" do
+        config[:customize] = {
+          :cpus => "2",
+          :numvcpus => "4"
+        }
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :vmware_desktop do |p|
+            p.vmx["numvcpus"] = "4"
+          end
+        RUBY
+      end
+    end
+
+    context "for managed provider" do
+
+      before { config[:provider] = "managed" }
+
+      it "adds a line a server" do
+        config[:customize] = {
+          :server => "my_server"
+        }
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :managed do |p|
+            p.server = "my_server"
+          end
+        RUBY
+      end
+
+      it "ignores all other key types than server" do
+        config[:customize] = {
+          :other => "stuff",
+          :is => "ignored"
+        }
+        cmd
+
+        expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
+          c.vm.provider :managed do |p|
+          end
+        RUBY
+      end
+    end
+  end
+
+  def debug_lines
+    regex = %r{^D, .* : }
+    logged_output.string.lines.
+      select { |l| l =~ regex }.map { |l| l.sub(regex, "") }.join
+  end
+
+  def with_modern_vagrant
+    with_vagrant("1.7.2")
+  end
+
+  def with_unsupported_vagrant
+    with_vagrant("1.0.5")
+  end
+
+  def with_vagrant(version)
+    allow(driver_object).to receive(:run_command).
+      with("vagrant --version", any_args).and_return("Vagrant #{version}")
+  end
+
+  def regexify(str, line = :whole_line)
+    r = Regexp.escape(str)
+    r = "^\s*#{r}$" if line == :whole_line
+    Regexp.new(r)
+  end
+
+  def vagrantfile
+    IO.read(File.join(vagrant_root, "Vagrantfile"))
+  end
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
new file mode 100644
index 0000000..dd841de
--- /dev/null
+++ b/spec/spec_helper.rb
@@ -0,0 +1,33 @@
+# -*- encoding: utf-8 -*-
+#
+# Author:: Fletcher Nichol (<fnichol at nichol.ca>)
+#
+# Copyright (C) 2015, Fletcher Nichol
+#
+# 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.
+
+if ENV["CODECLIMATE_REPO_TOKEN"]
+  require "codeclimate-test-reporter"
+  CodeClimate::TestReporter.start
+elsif ENV["COVERAGE"]
+  require "simplecov"
+  SimpleCov.profiles.define "gem" do
+    command_name "Specs"
+
+    add_filter ".gem/"
+    add_filter "/spec/"
+
+    add_group "Libraries", "/lib/"
+  end
+  SimpleCov.start "gem"
+end
diff --git a/templates/Vagrantfile.erb b/templates/Vagrantfile.erb
new file mode 100644
index 0000000..833a93f
--- /dev/null
+++ b/templates/Vagrantfile.erb
@@ -0,0 +1,125 @@
+<% config[:vagrantfiles].each do |vagrantfile| %>
+require "<%= vagrantfile %>"
+<% end %>
+
+Vagrant.configure("2") do |c|
+  c.berkshelf.enabled = false if Vagrant.has_plugin?("vagrant-berkshelf")
+  c.vm.box = "<%= config[:box] %>"
+
+<% if config[:box_url] %>
+  c.vm.box_url = "<%= config[:box_url] %>"
+<% end %>
+
+<% if config[:box_version] %>
+  c.vm.box_version = "<%= config[:box_version] %>"
+<% end %>
+
+<% if config[:box_check_update] %>
+  c.vm.box_check_update = "<%= config[:box_check_update] %>"
+<% end %>
+
+<% if config[:vm_hostname] %>
+  c.vm.hostname = "<%= config[:vm_hostname] %>"
+<% end %>
+
+<% if config[:communicator] %>
+  c.vm.communicator = "<%= config[:communicator] %>"
+<% end %>
+
+<% if config[:guest] %>
+  c.vm.guest = "<%= config[:guest] %>"
+<% end %>
+
+<% if config[:communicator] %>
+  <% if config[:username] %>
+    c.<%= config[:communicator] %>.username = "<%= config[:username] %>"
+  <% end %>
+  <% if config[:password] %>
+    c.<%= config[:communicator] %>.password = "<%= config[:password] %>"
+  <% end %>
+<% else %>
+  <% if config[:username] %>
+    c.ssh.username = "<%= config[:username] %>"
+  <% end %>
+  <% if config[:password] %>
+    c.ssh.password = "<%= config[:password] %>"
+  <% end %>
+<% end %>
+
+<% if config[:ssh_key] %>
+  c.ssh.private_key_path = "<%= config[:ssh_key] %>"
+<% end %>
+<% config[:ssh].each do |key, value| %>
+  c.ssh.<%= key %> = <%= value %>
+<% end %>
+<% if config[:winrm] %>
+  <% config[:winrm].each do |key, value| %>
+    c.winrm.<%= key %> = <%= value %>
+  <% end %>
+<% end %>
+
+<% Array(config[:network]).each do |opts| %>
+  c.vm.network(:<%= opts[0] %>, <%= opts[1..-1].join(", ") %>)
+<% end %>
+
+  c.vm.synced_folder ".", "/vagrant", disabled: true
+<% config[:synced_folders].each do |source, destination, options| %>
+  c.vm.synced_folder "<%= source %>", "<%= destination %>", <%= options %>
+<% end %>
+
+  c.vm.provider :<%= config[:provider] %> do |p|
+<% case config[:provider]
+   when "virtualbox", /^vmware_/
+     if config[:gui] == true || config[:gui] == false %>
+    p.gui = <%= config[:gui] %>
+<%   end
+   end %>
+<% config[:customize].each do |key, value| %>
+  <% case config[:provider]
+     when "libvirt" %>
+    p.<%= key %> = <%= value%>
+  <% when "lxc" %>
+    <% if key == :container_name %>
+    p.container_name = <%= value == ":machine" ? value : "\"#{value}\"" %>
+    <% elsif key == :backingstore %>
+    p.backingstore = "<%= value %>"
+    <% elsif key == :backingstore_options %>
+      <% config[:customize][:backingstore_options].each do |opt, opt_val| %>
+    p.backingstore_option "--<%= opt %>", "<%= opt_val %>"
+      <% end %>
+    <% else %>
+    p.customize "<%= key %>", "<%= value %>"
+    <% end %>
+  <% when "managed" %>
+    <% if key == :server %>
+    p.server = "<%= value %>"
+    <% end %>
+  <% when "parallels" %>
+    p.customize ["set", :id, "--<%= key.to_s.gsub('_', '-') %>", "<%= value %>"]
+  <% when "rackspace" %>
+    p.<%= key %> = "<%= value%>"
+  <% when "softlayer" %>
+    <% if key == :disk_capacity %>
+    p.<%= key %> = <%= value %>
+    <% else %>
+    p.<%= key %> = "<%= value %>"
+    <% end %>
+  <% when "virtualbox" %>
+    p.customize ["modifyvm", :id, "--<%= key %>", "<%= value %>"]
+  <% when /^vmware_/ %>
+    <% if key == :memory %>
+      <% unless config[:customize].include?(:memsize) %>
+    p.vmx["memsize"] = "<%= value %>"
+      <% end %>
+    <% elsif key == :cpus %>
+      <% unless config[:customize].include?(:numvcpus) %>
+    p.vmx["numvcpus"] = "<%= value %>"
+      <% end %>
+    <% else %>
+    p.vmx["<%= key %>"] = "<%= value %>"
+    <% end %>
+  <% end %>
+<% end %>
+  end
+
+end

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-kitchen-vagrant.git



More information about the Pkg-ruby-extras-commits mailing list