lib/kitchen/driver/vagrant.rb in kitchen-vagrant-0.6.0 vs lib/kitchen/driver/vagrant.rb in kitchen-vagrant-0.7.0
- old
+ new
@@ -14,79 +14,139 @@
# 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 'fileutils'
+require 'rubygems/version'
+
require 'kitchen'
+require 'kitchen/vagrant/vagrantfile_creator'
module Kitchen
module Driver
# Vagrant driver for Kitchen. It communicates to Vagrant via the CLI.
#
# @author Fletcher Nichol <fnichol@nichol.ca>
+ #
+ # @todo Vagrant installation check and version will be placed into any
+ # dependency hook checks when feature is released
class Vagrant < Kitchen::Driver::SSHBase
default_config :customize, {:memory => '256'}
no_parallel_for :create, :destroy
def create(state)
- # @todo Vagrantfile setup will be placed in any dependency hook
- # checks when feature is released
- vagrantfile = File.join(config[:kitchen_root], "Vagrantfile")
- create_vagrantfile(vagrantfile) unless File.exists?(vagrantfile)
-
state[:hostname] = instance.name
- run "vagrant up #{state[:hostname]} --no-provision"
+ create_vagrantfile(state)
+ run "vagrant up --no-provision"
info("Vagrant instance <#{state[:hostname]}> created.")
end
def converge(state)
+ create_vagrantfile(state)
ssh_args = build_ssh_args(state)
install_omnibus(ssh_args) if config[:require_chef_omnibus]
- run "vagrant provision #{state[:hostname]}"
+ run "vagrant provision"
end
+ def setup(state)
+ create_vagrantfile(state)
+ super
+ end
+
+ def verify(state)
+ create_vagrantfile(state)
+ super
+ end
+
def destroy(state)
return if state[:hostname].nil?
- run "vagrant destroy #{state[:hostname]} -f"
+ create_vagrantfile(state)
+ run "vagrant destroy -f"
+ FileUtils.rm_rf(vagrant_root)
info("Vagrant instance <#{state[:hostname]}> destroyed.")
state.delete(:hostname)
end
def login_command(state)
- %W{vagrant ssh #{state[:hostname]}}
+ create_vagrantfile(state)
+ LoginCommand.new(%W{vagrant ssh}, :chdir => vagrant_root)
end
+ def verify_dependencies
+ check_vagrant_version
+ check_berkshelf_plugin
+ end
+
protected
+ WEBSITE = "http://downloads.vagrantup.com/"
+ MIN_VER = "1.1.0"
+
def ssh(ssh_args, cmd)
- run %{vagrant ssh #{ssh_args.first} --command '#{cmd}'}
+ run %{vagrant ssh --command '#{cmd}'}
end
- def run(cmd)
+ def run(cmd, options = {})
cmd = "echo #{cmd}" if config[:dry_run]
- run_command(cmd)
+ run_command(cmd, { :cwd => vagrant_root }.merge(options))
end
- def create_vagrantfile(vagrantfile)
- File.open(vagrantfile, "wb") { |f| f.write(vagrantfile_contents) }
+ def silently_run(cmd)
+ run_command(cmd,
+ :live_stream => nil, :quiet => logger.debug? ? false : true)
end
- def vagrantfile_contents
- arr = []
- arr << %{require 'kitchen/vagrant'}
+ def vagrant_root
+ @vagrant_root ||= File.join(
+ config[:kitchen_root], %w{.kitchen kitchen-vagrant}, instance.name
+ )
+ end
+
+ def create_vagrantfile(state)
+ return if @vagrantfile_created
+
+ vagrantfile = File.join(vagrant_root, "Vagrantfile")
+ debug("Creating Vagrantfile for <#{state[:hostname]}> (#{vagrantfile})")
+ FileUtils.mkdir_p(vagrant_root)
+ File.open(vagrantfile, "wb") { |f| f.write(creator.render) }
+ @vagrantfile_created = true
+ end
+
+ def creator
+ Kitchen::Vagrant::VagrantfileCreator.new(instance, config)
+ end
+
+ def vagrant_version
+ version_string = silently_run("vagrant --version")
+ version_string = version_string.chomp.split(" ").last
+ rescue Errno::ENOENT
+ raise UserError, "Vagrant #{MIN_VER} or higher is not installed." +
+ " Please download a package from #{WEBSITE}."
+ end
+
+ def check_vagrant_version
+ version = vagrant_version
+ if Gem::Version.new(version) < Gem::Version.new(MIN_VER)
+ raise UserError, "Detected an old version of Vagrant (#{version})." +
+ " Please upgrade to version #{MIN_VER} or higher from #{WEBSITE}."
+ end
+ end
+
+ def check_berkshelf_plugin
if File.exists?(File.join(config[:kitchen_root], "Berksfile"))
- arr << %{require 'berkshelf/vagrant'}
+ plugins = silently_run("vagrant plugin list").split("\n")
+ if ! plugins.find { |p| p =~ /^berkshelf-vagrant\b/ }
+ raise UserError, "Detected a Berksfile but the berksfile-vagrant" +
+ " plugin was not found in Vagrant. Please run:" +
+ " `vagrant plugin install berkshelf-vagrant' and retry."
+ end
end
- arr << %{}
- arr << %{Vagrant::Config.run do |config|}
- arr << %{ Kitchen::Vagrant.define_vms(config)}
- arr << %{end\n}
- arr.join("\n")
end
end
end
end