假设执行 aVagrantfile
需要安装特定的 Vagrant 插件。所以,基本上你需要做的是
$ vagrant plugin install foobar-plugin
$ vagrant up
如果跳过第一步,则vagrant up
失败。
Vagrant 中有一个选项可以让它自动安装插件吗?换句话说:是否可以Vagrantfile
在创建和启动机器之前指定自动安装哪些插件?
假设执行 aVagrantfile
需要安装特定的 Vagrant 插件。所以,基本上你需要做的是
$ vagrant plugin install foobar-plugin
$ vagrant up
如果跳过第一步,则vagrant up
失败。
Vagrant 中有一个选项可以让它自动安装插件吗?换句话说:是否可以Vagrantfile
在创建和启动机器之前指定自动安装哪些插件?
2018 年 8 月 31 日更新:请参阅下面的 @Starx 修复以获取更高版本的 Vagrant(1.8 及更高版本)
这是基于 Louis St. Amour 解决方案的版本以及 Rob Kinyon 关于 re-exec 如果安装了新插件的评论,我在自己的设置中成功使用它:
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
由于我是一名 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
与使用反引号不同,它将命令回显到标准输出,就像自己运行命令一样。这样我就不再需要另一个奇怪命名的插件或系统来跟踪所需的插件,这些插件无论如何都可以由 Vagrant 更新。
正如我在回答您的其他问题时指出的那样,您可以使用bindler使用单个命令安装一组特定于项目的插件。
如果安装了 bindler 并且没有安装所需的插件,则 bindler 将出错并中止该过程。还有一个与在 s 上自动安装插件相关的未解决问题vagrant up
,但到目前为止还没有人注册它。
如果你不想使用 bindler,你可以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 日,不再支持 Bindler,并且 Vagrant 核心未提供等效功能
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
请注意,从 Vagrant 1.5 开始,您可以在Gemfile
. 根据有关更新的博客文章:
现在,Vagrant 1.5 将自动加载 Gemfile 中“plugins”组中的所有 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
无法对 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 上,@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
我刚刚注意到这里http://docs.vagrantup.com/v2/plugins/packaging.html一条指令
Vagrant.require_plugin "vagrant-aws"
这与描述的 fgrehm 完全相同:如果未安装插件,则会快速引发错误。
据我所知,仍然没有办法自动安装插件
我的回答与Louis St-Amour 的回答非常接近,但不是自动安装插件,而是引发错误消息,因此用户必须手动安装插件。
我希望用户知道安装的任何插件,因为它们全局应用于所有 Vagrant 实例,而不仅仅是当前的 Vagrantfile。
Vagrantfile
对于每个插件,将这样放在一行的顶部,在这个例子中, vagrant-vbguest
:
raise "vagrant-vbguest plugin must be installed" unless Vagrant.has_plugin? "vagrant-vbguest"
你可以使用这个项目(我是作者):https ://github.com/DevNIX/Vagrant-dependency-manager
它基于类似的答案,但试图更加完整和稳定。这个想法的最大优点是,你可以分发你的 Vagrantfile,它会在每台计算机上运行,而不管在那个环境中安装了插件。
它很容易使用:
包含它并调用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
???
利润!
我很想合并拉取请求,解决您可能遇到的任何问题,并获得新功能的想法。目前我正在考虑更新依赖管理器本身,并需要特定的插件版本:D
问候!
我在新安装 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
这是我在 Vagrant 1.8 上使用的,它运行良好。把它放在你的 Vagrantfile 中配置块之前的某个地方。
# 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