Потребувати плагіна Vagrant у файлі Vagrant?


80

Припускається, що виконання a Vagrantfileвимагає встановлення певного плагіна Vagrant. Отже, в основному те, що вам потрібно зробити, це

$ vagrant plugin install foobar-plugin
$ vagrant up

Якщо пропустити перший крок, vagrant upне вдається.

Чи є у Vagrant можливість зробити так, щоб він автоматично встановлював плагін? Іншими словами: чи можна вказати, Vagrantfileякі плагіни встановлювати автоматично перед створенням та завантаженням машини?

Відповіді:


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

ОНОВИТИ 31 серпня 2018 року: Дивіться виправлення @ Starx нижче, щоб дізнатись про пізніші версії Vagrant (1.8 і вище)

Ось версія, заснована на рішенні Луї Сент-Амура, разом із коментарем Роба Кіньйона щодо повторного виконання, якщо був встановлений новий плагін, я успішно використовую його у власному налаштуванні:

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
Безумовно, найкраще рішення на даний момент
Аніс,

1
Я оновив рішення 20 квітня, використовуючи лише один "системний" дзвінок для встановлення всіх відсутніх плагінів.
Амос Шапіра,

4
Це не спрацювало. Він увійшов у нескінченний цикл встановлення плагінів. Якось новий процес бродяги не може забрати щойно встановлені плагіни в батьківському процесі бродяги
Аріф Акрам Хан

1
Дякуємо за оновлення. Я насправді дотримувався рішення, запропонованого mkuzmin тут: github.com/mitchellh/vagrant/issues/4347 . Він передбачає використання плагіна з іменами vagrant plugins, а потім використання деякого коду (дуже схожого на вас) у Vagrantfile.
Аріф Акрам Хан

1
@SteveHenty Я співчуваю вашому коментарю, але переміщення цього в плагін начебто переб'є мету коду (просто можливість git clone...; cd ...; vagrant upпершого запуску).
Амос Шапіра,

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
Вам потрібно буде виконати "vagrant # {ARGV.join ''}" ", щоб перезапустити процес бродяги з встановленим плагіном.
Роб Кіньйон,

1
Влучне зауваження. У моєму випадку я потрапив у помилку, але побачив вихідні дані плагіна та знав, що потрібно повторно запустити команду. Якщо його повторно запустити автоматично, це було б ще кращим покращенням. Якщо ви переписуєте його, можливо, я перевірив би, чи не був встановлений якийсь плагін, і якщо так, спочатку встановіть плагіни, а потім перезапустіть скрипт, а не перевіряйте та встановлюйте кожен плагін по одному ...
Луїс Ст -Амур

2
Було б надзвичайно мати Vagrant.has_plugin?команду на рівні оболонки або просто vagrant plugin installперевірити, чи вже є там плагін.
sakovias

1
Ну, ти завжди можеш зробити щось подібне, if [ $(vagrant plugin list | egrep 'vagrant-hostsupdater|vagrant-share' -c) == 2 ] ; then echo "All plugins installed." ; else echo "Missing plugin"; fiале є причина, чому ніхто не пише bash-сценарії, якщо їм це може допомогти ;-) Може, експериментувати з командою плагіна Vagrant далі?
Louis St-Amour

48

Як я зазначив у своїй відповіді на інше ваше запитання , ви можете використовувати bindler для встановлення набору плагінів, специфічних для проекту, за допомогою однієї команди.

Якщо встановлено bindler, а необхідного плагіна немає, bindler помилиться і перерве процес. Існує також відкрита проблема, пов’язана з автоматичним встановленням плагінів на vagrant ups, але поки що ніхто ще не підписався на неї.

Якщо ви не хочете використовувати 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

ОНОВЛЕННЯ : Bindler більше не підтримується, і жодна рівнозначна функціональність не надана ядром Vagrant станом на 11 травня 2015 р.


14
Для майбутніх співробітників Google зауважте, що ця відповідь трохи застаріла. Тепер ви можете вказати залежності в вашому Gemfileпіддають :pluginsгрупу , яка Vagrant буде перевірятися. Детальніше див. У моїй відповіді нижче.
Джонатан Бендер,

2
Gemfileпризначений для розробки плагінів Vagrant. Дивіться github.com/mitchellh/vagrant/issues/8370
mixel

10

Зверніть увагу, що станом на Vagrant 1.5 ви можете вказати свої залежності у вашому Gemfile. Відповідно до публікації в блозі з оновленням :

Тепер Vagrant 1.5 автоматично завантажує будь-які дорогоцінні камені в групу "плагіни" у вашому Gemfile. Як приклад, ось Gemfile для плагіна "vagrant-bar":

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 ? У коробках бродяг зазвичай немає Gemfiles, вони використовують Vagrantfiles.
Дон МакКерді

1
Ви маєте рацію , що Бродячі коробки не мають Gemfiles самі по собі (ви могли б мати Vagrantfile , які не потребують будь - яких плагінів), але якщо ви які з допомогою плагінів (контекст блогу був в якості залежностей для вашого власного плагіна, але те ж саме істина для Vagrantfiles), ви повинні використовувати Gemfile, щоб вказати ці вимоги.
Джонатан Бендер

7
Дякую, це корисно. Оскільки багато користувачів Vagrant не є розробниками ruby, і у них їх ще не буде, не могли Gemfileб ви пояснити, як ви це налаштували? Я створив схожий на ваш приклад, але vagrant upнічого не завантажує автоматично. Спробував, bundle installале це дає підказку про дозволи системи Rubygems, що звучить неправильно.
Дон МакКерді

1
Я здогадуюсь, що ви працюєте в OSX, використовуючи рубінову інсталяцію, і стикаєтесь із цією проблемою: stackoverflow.com/questions/14607193 ?
Джонатан Бендер

1
У світі кулінарних книг шеф-кухарів дуже мало хто матиме gemfile
mr.buttons

6

Не вдалося додати коментар до відповіді Луї Сент-Амура, але я хотів опублікувати це на той випадок, якщо комусь потрібна буде допомога щодо розширення його рішення.

# 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
Натан Басанес

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"

який робить точно те ж саме, що і описаний fgrehm: швидко видає помилку, якщо плагін не встановлений.

Наскільки я знаю, ще немає способу автоматично встановлювати плагіни


6
Vagrant.require_plugin застаріла на 1.5 +
EIS

1
Ось офіційне повідомлення в блозі про припинення використання: vagrantup.com/blog/vagrant-1-5-plugin-improvements.html З мого обмеженого розуміння воно було застарілим, оскільки це більше не потрібно, Vagrant тепер автоматично перевірятиме залежності плагінів. Не до кінця впевнений, що я розумію пост у блозі ...
Джефф Відман

Пост говорить автоматично перевіряючи залежності плагінів , але я нічого не бачив про залежності самого поля Vagrant.
Дон МакКерді

Vagrant.require_pluginзастаріло. Перевірили з Vagrant 1.7.4.
czerasz

1

Моя відповідь дуже близька до відповіді Луї Сент-Амура , але замість того, щоб автоматично встановлювати плагіни, він просто видає повідомлення про помилку, так що користувачеві доведеться встановлювати плагін вручну.

Я волів би, щоб користувачі знали про будь-які встановлені плагіни, оскільки вони застосовуються глобально до всіх екземплярів Vagrant, а не лише до поточного файлу Vagrant.

Помістіть вгорі Vagrantfileодного рядка, як це для кожного плагіна, у цьому прикладі vagrant-vbguest:

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

1

Ви можете використати цей проект (я - автор): https://github.com/DevNIX/Vagrant-dependency-manager

Він базується на подібних відповідях, але намагається бути більш повним та стабільним. Великою перевагою цієї ідеї є те, що ви можете поширювати свій файл Vagrant, і він буде працювати на кожному комп’ютері незалежно від встановлених плагінів у цьому середовищі.

Він простий у використанні:

  1. Скопіюйте dependency_manager.rb поруч із вашим файлом Vagrant
  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 ще не створений. Я зміг змусити фрагмент від Луїса Сент-Амура працювати, вловивши виняток.

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 це призводить до помилки "Підведення машини за замовчуванням до постачальника послуг" віртуальної скриньки "... але інший процес вже виконує дію на машині", оскільки upвона запущена up. Чи є спосіб уникнути цього, не бігаючи vagrant upдвічі?
Tom B

0

Ось те, що я використовую на Vagrant 1.8, і воно працює нормально. Помістіть це десь перед блоком налаштування у вашому файлі Vagrant.

# 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.