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