[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