Czy potrzebujesz wtyczki Vagrant w pliku Vagrantfile?

80

Przypuszczalne wykonanie a Vagrantfilewymaga zainstalowania określonej wtyczki Vagrant. Więc w zasadzie to, co musisz zrobić, to

$ vagrant plugin install foobar-plugin
$ vagrant up

Jeśli pominiesz pierwszy krok, vagrant upzakończy się niepowodzeniem.

Czy w Vagrant jest opcja automatycznego zainstalowania wtyczki? Innymi słowy: czy można określić, Vagrantfilektóre wtyczki mają zostać automatycznie zainstalowane przed utworzeniem i uruchomieniem komputera?

Golo Roden
źródło

Odpowiedzi:

24

Aktualizacja 2019: Vagrant ma teraz funkcjonalność wymagającą wtyczek poprzez Vagrantfilevia:

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

Jeśli Vagrant wykryje, że istnieją wtyczki, które nie są jeszcze zainstalowane, poprosi użytkownika o ich samodzielną instalację:

$ 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.

Zobacz https://www.vagrantup.com/docs/vagrantfile/vagrant_settings.html

Moritz Gunz
źródło
Co jeśli chciałbym pominąć ten monit i automatycznie zainstalować wszystkie wymagane wtyczki?
pihentagy
67

AKTUALIZACJA 31 sierpnia 2018: Zobacz poprawkę @ Starx poniżej dla nowszych wersji Vagrant (1.8 i nowsze)

Oto wersja oparta na rozwiązaniu Louisa St.Amoura wraz z komentarzem Roba Kinyona o ponownym wykonaniu, jeśli zainstalowano nową wtyczkę, z powodzeniem używam jej w mojej własnej konfiguracji:

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
Amos Shapira
źródło
5
Zdecydowanie najlepsze rozwiązanie w tej chwili
Anis
1
Zaktualizowałem rozwiązanie 20 kwietnia, aby używać tylko jednego wywołania „systemowego” do zainstalowania wszystkich brakujących wtyczek.
Amos Shapira
4
To nie zadziałało. Weszła w nieskończoną pętlę instalacji wtyczek. W jakiś sposób nowy proces włóczęgi nie może odebrać nowo zainstalowanych wtyczek w procesie macierzystego włóczęgi
Arif Akram Khan
1
Dziękuję za aktualizację. Skończyło się na rozwiązaniu sugerowanym przez mkuzmin tutaj: github.com/mitchellh/vagrant/issues/4347 . Obejmuje użycie wtyczki o nazwie vagrant plugins, a następnie użycie kodu (bardzo podobnego do ciebie) w pliku Vagrantfile.
Arif Akram Khan
1
@SteveHenty Zgadzam się z twoim komentarzem, ale przeniesienie go do wtyczki w pewnym sensie zniweczy cel kodu (po prostu możliwość git clone...; cd ...; vagrant uppierwszego użycia ).
Amos Shapira,
51

Ponieważ jestem programistą Ruby, a Bindler nie jest już obsługiwany, wydaje mi się najbardziej naturalne, aby po prostu napisać kod na górze mojego pliku Vagrantfile, aby zainstalować wymagane wtyczki, jeśli ich brakuje (np. Przed Vagrant.configurelinią)

U mnie działa:

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

system, w przeciwieństwie do używania lewych apostrofów, spowoduje wyświetlenie polecenia na stdout, tak jak samo wykonanie polecenia. I w ten sposób nie potrzebuję kolejnej dziwnie nazwanej wtyczki lub systemu do śledzenia wymaganych wtyczek, które i tak mogą być aktualizowane przez Vagrant.

Louis St-Amour
źródło
8
Będziesz musiał 'exec "vagrant # {ARGV.join'}" 'w celu ponownego uruchomienia procesu włóczęgi z zainstalowaną wtyczką.
Rob Kinyon
1
Słuszna uwaga. W moim przypadku napotkałbym błąd, ale zobaczyłem wyjście instalowania wtyczki i wiedziałem, aby ponownie uruchomić polecenie. Automatyczne ponowne uruchomienie byłoby jeszcze lepszym ulepszeniem. Jeśli napiszę go ponownie, być może sprawdzę, czy żadna wtyczka nie została zainstalowana, a jeśli tak, najpierw zainstaluj wtyczki, a następnie ponownie uruchom skrypt, zamiast sprawdzać i instalować każdą wtyczkę pojedynczo ...
Louis St -Amour
2
Byłoby wspaniale mieć Vagrant.has_plugin?polecenie na poziomie powłoki lub po prostu vagrant plugin installsprawdzić, czy wtyczka już tam jest.
sakovias
1
Cóż, zawsze możesz zrobić coś takiego, if [ $(vagrant plugin list | egrep 'vagrant-hostsupdater|vagrant-share' -c) == 2 ] ; then echo "All plugins installed." ; else echo "Missing plugin"; fiale jest powód, dla którego nikt nie pisze skryptów basha, jeśli mogą temu pomóc ;-) Może poeksperymentować z poleceniem wtyczki włóczęgi?
Louis St-Amour
48

Jak wskazałem w odpowiedzi na Twoje drugie pytanie , możesz użyć bindlera do zainstalowania zestawu wtyczek specyficznych dla projektu za pomocą jednego polecenia.

Jeśli program bindler jest zainstalowany, a wymagana wtyczka nie jest, program bindler wyświetli błąd i przerwie proces. Istnieje również otwarty problem związany z automatyczną instalacją wtyczek na vagrant ups, ale jak dotąd nikt się do tego nie zapisał.

Jeśli nie chcesz używać bindlera, możesz skorzystać z Vagrant.has_plugin?(dostępne w wersji 1.3.0+) u góry swojego Vagrantfilei wyświetlić błąd, jeśli wymagana wtyczka nie jest zainstalowana.

Coś jak:

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

AKTUALIZACJA : Bindler nie jest już obsługiwany i od 11 maja 2015 r. Rdzeń Vagrant nie zapewnia żadnej równoważnej funkcjonalności

fgrehm
źródło
14
Dla przyszłych pracowników Google prosimy pamiętać, że ta odpowiedź jest trochę nieaktualna. Teraz można określić swoje w zależności Gemfilepod :pluginsgrupę Vagrant sprawdzi. Zobacz moją odpowiedź poniżej, aby uzyskać więcej informacji.
Jonathan Bender,
2
Gemfilejest przeznaczony do tworzenia wtyczek Vagrant. Zobacz github.com/mitchellh/vagrant/issues/8370
mixel
10

Należy pamiętać, że od wersji Vagrant 1.5 możesz określić swoje zależności w pliku Gemfile. Zgodnie z wpisem na blogu dotyczącym aktualizacji :

Teraz Vagrant 1.5 automatycznie załaduje wszystkie klejnoty z grupy "wtyczek" w twoim Gemfile. Jako przykład, oto plik Gemfile dla wtyczki „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
Jonathan Bender
źródło
8
Czy ten post na blogu nie odnosi się do rozwoju wtyczki Vagrant ? Pudełka Vagrant generalnie nie mają Gemfiles, używają Vagrantfiles.
Don McCurdy
1
Masz rację, że pudełka Vagrant nie mają Gemfiles per se (można mieć Vagrantfile że nie wymaga żadnych wtyczek), ale jeśli za pomocą wtyczek (kontekst blogu był zależnościami dla własnej wtyczki, ale to samo true dla Vagrantfiles), do określenia tych wymagań należy użyć pliku Gemfile.
Jonathan Bender
7
Dzięki, to pomocne. Ponieważ wielu użytkowników Vagranta nie jest programistami Ruby i nie będzie ich posiadało Gemfile, czy mógłbyś wyjaśnić, jak to ustawiłeś? Utworzyłem podobny do twojego przykładu, ale vagrant upniczego nie ładuje automatycznie. Próbowałem, bundle installale to daje pytanie o uprawnienia systemowe Rubygems, co nie brzmi dobrze.
Don McCurdy
1
Zgaduję, że pracujesz w systemie OSX, używając standardowej instalacji ruby ​​i napotykasz ten problem: stackoverflow.com/questions/14607193 ?
Jonathan Bender
1
W świecie kucharskich książek kucharskich bardzo niewielu będzie miało plik klejnotów
pan Buttons
6

Nie mogłem dodać komentarza do odpowiedzi Louisa St-Amoura, ale chciałem to opublikować na wypadek, gdyby ktoś potrzebował pomocy w rozszerzeniu jego rozwiązania.

# 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
James Reimer
źródło
// Zwróć uwagę, że vagrant-listpowyżej jest przykład wtyczki, a nie niezbędna część kodu. Możesz zobaczyć inne wtyczki Vagrant tutaj: vagrant-lists.github.io
Nathan Basanese
3

W nowej wersji Vagrant odpowiedź autorstwa @Amos Shapira utknęła w nieskończonej pętli. Powodem tego jest to, że każde wywołanie vagrant plugin installrównież przetwarza Vagrantfilei po przetworzeniu wykonuje kod związany z instalacją wtyczki raz po raz i tak dalej.

Oto moje rozwiązanie, które pozwala uniknąć pętli.

# 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
Starx
źródło
1

Właśnie zauważyłem tutaj http://docs.vagrantup.com/v2/plugins/packaging.html instrukcję

Vagrant.require_plugin "vagrant-aws"

który robi dokładnie to samo, co opisał fgrehm: szybko zgłasza błąd, jeśli wtyczka nie jest zainstalowana.

O ile wiem, nadal nie ma możliwości automatycznej instalacji wtyczek

Julien
źródło
6
Vagrant.require_plugin został wycofany w dniu 1.5+
eis
1
Oto oficjalny post na blogu dotyczący wycofania: vagrantup.com/blog/vagrant-1-5-plugin-improvements.html Z mojego ograniczonego zrozumienia został on wycofany, ponieważ nie jest już potrzebny. Vagrant będzie teraz automatycznie sprawdzać zależności od wtyczek. Nie jestem do końca przekonany, że rozumiem wpis na blogu ...
Jeff Widman,
Post mówi automatycznie, sprawdzając zależności wtyczek , ale nie widziałem nic o zależnościach samego pola Vagrant.
Don McCurdy
Vagrant.require_pluginjest przestarzałe. Sprawdzone z Vagrantem 1.7.4.
czerasz
1

Moja odpowiedź jest bardzo zbliżona do odpowiedzi Louisa St-Amour , ale zamiast automatycznie instalować wtyczki, po prostu generuje komunikat o błędzie, więc użytkownik musi zainstalować wtyczkę ręcznie.

Wolałbym, aby użytkownicy byli świadomi wszelkich zainstalowanych wtyczek, ponieważ mają one zastosowanie globalnie do wszystkich instancji Vagrant, a nie tylko do bieżącego pliku Vagrantfile.

Umieść na górze Vagrantfilejednej linii, tak jak to, dla każdej wtyczki, w tym przykładzie vagrant-vbguest:

 raise "vagrant-vbguest plugin must be installed" unless Vagrant.has_plugin? "vagrant-vbguest"
Flimm
źródło
1

Możesz skorzystać z tego projektu (jestem autorem): https://github.com/DevNIX/Vagrant-dependency-manager

Opiera się na podobnych odpowiedziach, ale stara się być bardziej kompletny i stabilny. Dużą zaletą tego pomysłu jest to, że możesz rozpowszechniać swój plik Vagrantfile i będzie on działał na każdym komputerze niezależnie od zainstalowanych wtyczek w tym środowisku.

Jest łatwy w użyciu:

  1. Skopiuj plik dependency_manager.rb obok pliku Vagrantfile
  2. Uwzględnij go i wywołaj check_pluginsprzekazywanie zależności jako tablicy

    Przykład:

    # -*- 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. Zysk!

Bardzo chciałbym scalić żądania ściągnięcia, rozwiązać każdy problem i uzyskać pomysły na nowe funkcje. Obecnie myślę o aktualizacji samego menedżera zależności i wymaganiu konkretnych wersji wtyczek: D

Pozdrowienia!

Dev_NIX
źródło
0

Mam problem z nową instalacją Vagranta, gdzie katalog .vagrant.d nie jest jeszcze utworzony. Udało mi się sprawić, że fragment z Luisa St. Amour działał, wychwytując wyjątek.

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
Guillaume Hardy
źródło
W systemie Windows pojawia się komunikat o błędzie „Przełączam domyślną maszynę na dostawcę wirtualnej skrzynki… ale inny proces już wykonuje akcję na maszynie”, ponieważ upjest uruchamiany przez up. Czy można tego uniknąć bez vagrant updwukrotnego uruchamiania ?
Tom B,
0

Oto, czego używam w Vagrant 1.8 i działa dobrze. Umieść to gdzieś przed blokiem konfiguracji w swoim pliku 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
lps
źródło
Wygląda na to, że nie jest to platforma wieloplatformowa.
thorr18