Vagrant: Require installed plugins

Whilst working on a project with a team that I don’t normally work with, we needed a way to ensure that we’re all using the same tools. One part of that was ensuring that at least a specific version of a Vagrant plugin was installed.

As the Vagrantfile is valid Ruby, we can write some code in there to make sure that our dependencies are fulfilled.

This code does not automatically install plugins as it’s not fair to automatically change the state of someone’s machine. Instead, it just alerts them to the fact that they need to install/update some plugins.

Vagrant 1.7.3+

Vagrant 1.7.3 isn’t released yet, but this is the correct way to check plugin versions.

[
  { :name => "vagrant-omnibus", :version => ">= 1.4.1" },
  { :name => "vagrant-berkshelf", :version => ">= 4.0.3" },
  { :name => "vagrant-hostmanager", :version => ">= 1.5.0" },
  { :name => "vagrant-cachier", :version => ">= 1.2.0"}
].each do |plugin|

  if not Vagrant.has_plugin?(plugin[:name], plugin[:version])
    raise "#{plugin[:name]} #{plugin[:version]} is required. Please run `vagrant plugin install #{plugin[:name]}`"
  end
end

Vagrant 1.7.2

Unfortunately there’s a bug in Vagrant 1.7.2 that means that if the installed version of any plugin provides what you’re asking for (not just the specific plugin you’re asking about), the check will pass.

To work around this, we can access Vagrant::Plugin::Manager directly and perform the checks ourselves.

[
  { :name => "vagrant-omnibus", :version => ">= 1.4.1" },
  { :name => "vagrant-berkshelf", :version => ">= 4.0.3" },
  { :name => "vagrant-hostmanager", :version => ">= 1.5.0" },
  { :name => "vagrant-cachier", :version => ">= 1.2.0"}
].each do |plugin|

  Vagrant::Plugin::Manager.instance.installed_specs.any? do |s|
    req = Gem::Requirement.new([plugin[:version]])
    if (not req.satisfied_by?(s.version)) && plugin[:name] == s.name 
      raise "#{plugin[:name]} #{plugin[:version]} is required. Please run `vagrant plugin install #{plugin[:name]}`"
    end
  end
end

Michael is a polyglot software engineer, committed to reducing complexity in systems and making them more predictable. Working with a variety of languages and tools, he shares his technical expertise to audiences all around the world at user groups and conferences. You can follow @mheap on Twitter

Thoughts on this post

Leave a comment?

Leave a Reply