在Vagrantfile中需要Vagrant插件吗?


80

假设要执行,则Vagrantfile需要安装特定的Vagrant插件。因此,基本上您需要做的是

$ vagrant plugin install foobar-plugin
$ vagrant up

如果跳过第一步,则vagrant up失败。

Vagrant中是否有一个选项可以使其自动安装插件?换句话说:是否可以Vagrantfile在创建和启动计算机之前指定在哪个插件中自动安装?

Answers:


24

2019更新:Vagrant现在具有通过以下方式要求插件的功能Vagrantfile

Vagrant.configure("2") do |config|
  config.vagrant.plugins = "vagrant-some-plugin"

  # or as array:
  config.vagrant.plugins = ["vagrant-some-plugin", "vagrant-some-other-plugin"]

  # or as hash
  config.vagrant.plugins = {"vagrant-some-plugin" => {"version" => "1.0.0"}}
end

如果Vagrant检测到尚未安装插件,它将提示用户自己安装它们:

$ vagrant up
Vagrant has detected project local plugins configured for this
project which are not installed.

  vagrant-some-plugin
Install local plugins (Y/N) [N]: y
Installing the 'vagrant-some-plugin' plugin. This can take a few minutes...
Fetching vagrant-some-plugin-1.0.0.gem
Installed the plugin 'vagrant-some-plugin (1.0.0)'!


Vagrant has completed installing local plugins for the current Vagrant
project directory. Please run the requested command again.

参见https://www.vagrantup.com/docs/vagrantfile/vagrant_settings.html


如果我想跳过提示并自动安装所有必需的插件怎么办?
pihentagy

67

更新2018年8月31日:请参阅下面的@Starx修复程序以获取Vagrant的更高版本(1.8及更高版本)

这是基于Louis St.Amour解决方案的版本以及Rob Kinyon关于重新执行的评论(如果安装了新插件),我可以在自己的设置中成功使用它:

required_plugins = %w(vagrant-share vagrant-vbguest...)

plugins_to_install = required_plugins.select { |plugin| not Vagrant.has_plugin? plugin }
if not plugins_to_install.empty?
  puts "Installing plugins: #{plugins_to_install.join(' ')}"
  if system "vagrant plugin install #{plugins_to_install.join(' ')}"
    exec "vagrant #{ARGV.join(' ')}"
  else
    abort "Installation of one or more plugins has failed. Aborting."
  end
end

5
绝对是目前最佳的解决方案
Anis

1
我在4月20日更新了解决方案,以仅使用一个“系统”调用来安装所有丢失的插件。
阿莫斯·夏皮拉

4
这没有用。它进入了安装插件的无限循环。不知何故,新的无业游民进程无法在父级无业游民进程中获取新安装的插件
Arif Akram Khan

1
感谢更新。实际上,我最终遵循了mkuzmin建议的解决方案:github.com/mitchellh/vagrant/issues/4347。它涉及使用名为vagrant插件的插件,然后在Vagrantfile中使用一些代码(与您非常相似)。
阿里夫·阿克拉姆·汗

1
@SteveHenty我很赞同您的评论,但是将其移到插件中会破坏代码的目的(只是能够git clone...; cd ...; vagrant up第一次使用)。
Amos Shapira

51

由于我是Ruby开发人员,并且不再需要对Bindler进行维护,因此我发现最自然的做法是在Vagrantfile的顶部编写一些代码以安装所需的插件(如果缺少的话)(例如,在前Vagrant.configure一行)

以下对我有用:

required_plugins = %w( vagrant-hostmanager vagrant-someotherplugin )
required_plugins.each do |plugin|
  system "vagrant plugin install #{plugin}" unless Vagrant.has_plugin? plugin
end

system与使用反引号不同,它将回显命令到stdout,就像您自己运行命令一样。这样,我就不需要另一个名称奇怪的插件或系统来跟踪所需的插件,无论如何它们都可以由Vagrant更新。


8
您需要'exec“ vagrant#{ARGV.join''}”“,以便在安装了插件的情况下重启流浪者进程。
Rob Kinyon 2014年

1
好点子。就我而言,我遇到了一个错误,但是看到了安装插件的输出,并且知道重新运行该命令。让它自动重新运行将是更好的增强。如果要重写它,也许我会检查是否未安装任何插件,如果是,请先安装插件,然后重新运行脚本,而不是一次检查并安装每个插件……
Louis St -

2
Vagrant.has_plugin?在shell级别上具有命令或仅vagrant plugin install检查插件是否已存在将是非常棒的。
sakovias 2015年

1
好吧,您总是可以做类似的事情,if [ $(vagrant plugin list | egrep 'vagrant-hostsupdater|vagrant-share' -c) == 2 ] ; then echo "All plugins installed." ; else echo "Missing plugin"; fi但是如果没有他们的帮助,那就没有人写bash脚本了;-)也许可以进一步尝试使用vagrant plugin命令?
Louis St-Amour

48

正如我在回答其他问题时指出的那样,您可以使用绑定器通过一个命令安装特定于项目的一组插件。

如果已安装bindler且未安装必需的插件,bindler将会出错并中止该过程。在s上自动安装插件还存在一个未解决的问题vagrant up但到目前为止,还没有人注册。

如果您不想使用绑定程序,则可以使用Vagrant.has_plugin?顶部的(在1.3.0+上可用),Vagrantfile如果未安装所需的插件,则会出错。

就像是:

unless Vagrant.has_plugin?("vagrant-some-plugin")
  raise 'some-plugin is not installed!'
end

Vagrant.configure("2") do |config|
  config.vm.box = "box-name"
end

更新:截至2015年5月11日,Vagrant core不再支持Bindler,并且没有提供同等的功能


14
对于将来的Google员工,请注意,这个答案有些过时了。现在,您可以在Vagrant将检查Gemfile:plugins组中的您的依赖项中指定您的依赖项。有关更多详细信息,请参见下面的答案。
乔纳森·班德

2
Gemfile用于Vagrant插件开发。见github.com/mitchellh/vagrant/issues/8370
mixel

10

请注意,从Vagrant 1.5开始,您可以在中指定依赖项Gemfile。根据更新中博客文章

现在,Vagrant 1.5将自动在Gemfile的“插件”组中加载所有gem。例如,这是“ vagrant-bar”插件的Gemfile:

source "https://rubygems.org"

group :development do
  gem "vagrant",
    git: "https://github.com/mitchellh/vagrant.git"
end

group :plugins do
  gem "vagrant-foo",
  gem "vagrant-bar", path: "."
end

8
那篇博客文章不是指Vagrant插件开发吗?流浪者盒子通常没有Gemfile,它们使用Vagrantfiles。
Don McCurdy

1
你是正确的流浪箱没有Gemfiles本身(你可以有一个Vagrantfile,并不需要任何插件),但如果你正在使用的插件(博客的背景是作为依赖于自己的插件,但同样适用对于Vagrantfiles为true),则应使用Gemfile来指定这些要求。
乔纳森·班德

7
谢谢,这很有帮助。由于许多Vagrant用户不是ruby开发人员,并且还不会拥有Gemfile,所以您介意解释如何设置它吗?我创建了一个与您的示例类似的示例,但是vagrant up不会自动加载任何内容。尝试过,bundle install但这会提示您有关系统Rubygems的权限,这听起来不太正确。
Don McCurdy 2015年

1
我猜测您正在使用库存红宝石安装程序在OSX中工作,并遇到了以下问题:stackoverflow.com/questions/14607193
乔纳森·本德

1
在厨师食谱的世界中,很少有gemfile
mr.buttons'Apr 24'15

6

无法在Louis St-Amour的回答中添加评论,但是我想发布此评论,以防万一有人需要帮助扩展他的解决方案。

# Check for missing plugins
required_plugins = %w(vagrant-list)
plugin_installed = false
required_plugins.each do |plugin|
  unless Vagrant.has_plugin?(plugin)
    system "vagrant plugin install #{plugin}"
    plugin_installed = true
  end
end

# If new plugins installed, restart Vagrant process
if plugin_installed === true
  exec "vagrant #{ARGV.join' '}"
end

//,请注意,vagrant-list上面是一个插件示例,而不是代码的必要部分。您可以在此处看到其他Vagrant插件:vagrant-lists.github.io
Nathan Basanese,

3

在新版本的Vagrant上,@ Amos Shapira的答案陷入了无限循环。这样做的原因是,每个调用vagrant plugin install还处理,Vagrantfile并且在处理时执行与一次又一次安装插件有关的代码,依此类推。

这是我避免循环的解决方案。

# Plugins
#
# Check if the first argument to the vagrant
# command is plugin or not to avoid the loop
if ARGV[0] != 'plugin'

  # Define the plugins in an array format
  required_plugins = [
    'vagrant-vbguest', 'vagrant-hostmanager', 
    'vagrant-disksize'
  ]         
  plugins_to_install = required_plugins.select { |plugin| not Vagrant.has_plugin? plugin }
  if not plugins_to_install.empty?

    puts "Installing plugins: #{plugins_to_install.join(' ')}"
    if system "vagrant plugin install #{plugins_to_install.join(' ')}"
      exec "vagrant #{ARGV.join(' ')}"
    else
      abort "Installation of one or more plugins has failed. Aborting."
    end

  end
end

1

我刚刚在这里注意到http://docs.vagrantup.com/v2/plugins/packaging.html一条说明

Vagrant.require_plugin "vagrant-aws"

这与描述的功能完全相同:如果未安装该插件,则会迅速引发错误。

据我所知,仍然没有办法自动安装插件


6
Vagrant.require_plugin已于1.5+弃用
eis

1
这是有关弃用的官方博客文章:vagrantup.com/blog/vagrant-1-5-plugin-improvements.html据 我有限的理解,由于不再需要它而已被弃用,Vagrant现在将自动检查插件相关性。我不太了解我是否了解博客文章……
Jeff Widman 2014年

这篇文章谈到自动检查插件的依赖关系,但我还没有看到有关Vagrant框本身的依赖关系的任何信息。
Don McCurdy 2015年

Vagrant.require_plugin不推荐使用。检查与流浪汉1.7.4
czerasz 2015年

1

我的答案与Louis St-Amour的答案非常接近,但是它不会自动安装插件,而只会引发错误消息,因此用户必须手动安装插件。

我希望用户知道所有已安装的插件,因为它们全局地应用于所有Vagrant实例,而不仅仅是应用于当前的Vagrantfile。

Vagrantfile对于每个插件,将这样放在每一行的顶部,在本示例中,为vagrant-vbguest

 raise "vagrant-vbguest plugin must be installed" unless Vagrant.has_plugin? "vagrant-vbguest"

1

您可以使用这个项目(我是作者):https : //github.com/DevNIX/Vagrant-dependency-manager

它基于相似的答案,但是试图变得更加完整和稳定。这个想法的最大优点是,您可以分发Vagrantfile,并且该文件将在每台计算机上运行,​​而不管该环境中安装了什么插件。

这个用起来很简单:

  1. 在您的Vagrantfile旁边复制dependency_manager.rb
  2. 包含它并调用check_plugins将依赖项作为数组传递

    例:

    # -*- mode: ruby -*-
    # vi: set ft=ruby :
    
    require File.dirname(__FILE__)+"./dependency_manager"
    
    check_plugins ["vagrant-exec", "vagrant-hostsupdater", "vagrant-cachier", "vagrant-triggers"]
    
    Vagrant.configure(2) do |config|
    
      config.vm.box = "base"
    
    end
    
  3. ???

  4. 利润!

我很想合并合并请求,解决您可能遇到的任何问题,并了解新功能。目前,我正在考虑更新依赖项管理器本身,并要求特定的插件版本:D

问候!


0

我遇到了新安装的Vagrant的问题,其中尚未创建.vagrant.d目录。我能够通过捕获例外使Luis St. Amour的代码片段正常工作。

required_plugins = %w(vagrant-share vagrant-vbguest)

begin
    plugins_to_install = required_plugins.select { |plugin| not Vagrant.has_plugin? plugin }
    if not plugins_to_install.empty?
        puts "Installing plugins: #{plugins_to_install.join(' ')}"
        if system "vagrant plugin install #{plugins_to_install.join(' ')}"
            exec "vagrant #{ARGV.join(' ')}"
        else
            abort "Installation of one or more plugins has failed. Aborting."
        end
    end
rescue
    exec "vagrant #{ARGV.join(' ')}"
end

在Windows上,这给了我错误“使用'virtualbox'提供程序启动计算机'默认'...但是另一个进程已经在该计算机上执行操作”,因为up它正在由运行up。有没有办法避免vagrant up两次运行而避免这种情况?
汤姆B

0

这是我在Vagrant 1.8上使用的工具,它工作正常。将其放在Vagrantfile中configure块之前的某个位置。

# install required plugins if necessary
if ARGV[0] == 'up'
    # add required plugins here
    required_plugins = %w( plugin1 plugin2 plugin3 )
    missing_plugins = []
    required_plugins.each do |plugin|
        missing_plugins.push(plugin) unless Vagrant.has_plugin? plugin
    end

    if ! missing_plugins.empty?
        install_these = missing_plugins.join(' ')
        puts "Found missing plugins: #{install_these}.  Installing using sudo..."
        exec "sudo vagrant plugin install #{install_these}; vagrant up"
    end
end

看来这不是跨平台的。
thorr18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.