Fordern Sie ein Vagrant-Plugin in der Vagrant-Datei an?

80

Angenommen, für die Ausführung von a Vagrantfilemuss ein bestimmtes Vagrant-Plugin installiert sein. Im Grunde müssen Sie also Folgendes tun

$ vagrant plugin install foobar-plugin
$ vagrant up

Wenn Sie den ersten Schritt überspringen, vagrant upschlägt dies fehl.

Gibt es in Vagrant eine Option, um das Plugin automatisch zu installieren? Mit anderen Worten: Ist es möglich, innerhalb eines VagrantfilePlugins anzugeben, welche Plugins automatisch installiert werden sollen, bevor der Computer erstellt und gestartet wird?

Golo Roden
quelle

Antworten:

24

Update 2019: Vagrant verfügt nun über die Funktionalität, Plugins über das VagrantfileVia zu benötigen :

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

Wenn Vagrant feststellt, dass Plugins noch nicht installiert sind, wird der Benutzer aufgefordert, diese selbst zu installieren:

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

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

Moritz Gunz
quelle
Was ist, wenn ich die Eingabeaufforderung überspringen und alle erforderlichen Plugins automatisch installieren möchte?
pihentagy
67

UPDATE 31. August 2018: Siehe @ Starx's Fix unten für spätere Versionen von Vagrant (1.8 und höher)

Hier ist eine Version, die auf der Lösung von Louis St. Amour basiert, zusammen mit Rob Kinyons Kommentar zur erneuten Ausführung, wenn ein neues Plugin installiert wurde. Ich verwende es erfolgreich in meinem eigenen Setup:

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
quelle
5
Auf jeden Fall die beste Lösung im Moment
Anis
1
Ich habe die Lösung am 20. April aktualisiert, um nur einen "System" -Aufruf zum Installieren aller fehlenden Plugins zu verwenden.
Amos Shapira
4
Das hat nicht funktioniert. Es ging in eine Endlosschleife der Installation der Plugins. Irgendwie kann der neue Vagabundprozess die neu installierten Plugins im übergeordneten Vagabundprozess nicht abholen
Arif Akram Khan
1
Danke für das Update. Am Ende folgte ich der von mkuzmin hier vorgeschlagenen Lösung: github.com/mitchellh/vagrant/issues/4347 . Es beinhaltet die Verwendung eines Plugins namens Vagrant Plugins und die Verwendung von Code (der Ihnen sehr ähnlich ist) in Vagrantfile.
Arif Akram Khan
1
@SteveHenty Ich sympathisiere mit Ihrem Kommentar, aber wenn Sie dies in ein Plugin verschieben, wird der Zweck des Codes (nur das git clone...; cd ...; vagrant uperste Mal in der Lage zu sein) zunichte gemacht .
Amos Shapira
51

Da ich ein Ruby-Entwickler bin und Bindler nicht mehr gewartet wird, fand ich es am natürlichsten, einfach einen Code oben in meine Vagrant-Datei zu schreiben, um die erforderlichen Plugins zu installieren, falls sie fehlen (z. B. vor der Vagrant.configureZeile).

Folgendes funktioniert für mich:

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

systemIm Gegensatz zur Verwendung von Backticks wird der Befehl an stdout zurückgegeben, genau wie Sie den Befehl selbst ausführen würden. Und auf diese Weise brauche ich kein weiteres seltsam benanntes Plugin oder System, um die erforderlichen Plugins zu verfolgen, die ohnehin von Vagrant aktualisiert werden können.

Louis St-Amour
quelle
8
Sie müssen 'vagrant # {ARGV.join' '} "' ausführen, um den Vagrant-Prozess mit installiertem Plugin neu zu starten.
Rob Kinyon
1
Guter Punkt. In meinem Fall habe ich einen Fehler festgestellt, sehe aber die Ausgabe des Installations-Plugins und weiß, dass ich den Befehl erneut ausführen muss. Eine automatische Wiederholung wäre eine noch bessere Verbesserung. Wenn ich es neu schreibe, würde ich vielleicht prüfen, ob kein Plugin installiert ist, und wenn ja, zuerst die Plugins installieren und dann das Skript erneut ausführen, anstatt jedes Plugin einzeln zu überprüfen und zu installieren ...
Louis St. - Am
2
Es wäre fantastisch, einen Vagrant.has_plugin?Befehl auf Shell-Ebene zu haben oder einfach zu vagrant plugin installüberprüfen, ob das Plugin bereits vorhanden ist.
Sakovias
1
Du könntest immer so etwas machen, if [ $(vagrant plugin list | egrep 'vagrant-hostsupdater|vagrant-share' -c) == 2 ] ; then echo "All plugins installed." ; else echo "Missing plugin"; fiaber es gibt einen Grund, warum niemand Bash-Skripte schreibt, wenn sie helfen können ;-) Vielleicht weiter mit dem Vagrant-Plugin-Befehl experimentieren?
Louis St-Amour
48

Wie ich in meiner Antwort auf Ihre andere Frage dargelegt habe , können Sie Bindler verwenden, um eine Reihe von projektspezifischen Plugins mit einem einzigen Befehl zu installieren.

Wenn Bindler installiert ist und das erforderliche Plugin nicht installiert ist, tritt ein Bindler auf und der Vorgang wird abgebrochen. Es gibt auch ein offenes Problem im Zusammenhang mit der automatischen Installation von Plugins auf vagrant ups, aber bisher hat sich noch niemand dafür angemeldet.

Wenn Sie Bindler nicht verwenden möchten, können Sie Vagrant.has_plugin?(verfügbar ab 1.3.0) oben auf Ihrem Computer verwenden Vagrantfileund Fehler ausgeben , wenn das erforderliche Plugin nicht installiert ist.

Etwas wie:

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

UPDATE : Bindler wird nicht mehr unterstützt und Vagrant Core bietet seit dem 11. Mai 2015 keine gleichwertige Funktionalität mehr

fgrehm
quelle
14
Bitte beachten Sie, dass diese Antwort für zukünftige Googler etwas veraltet ist. Sie können jetzt Ihre Abhängigkeiten in Ihrer Gruppe Gemfileunter einer :pluginsGruppe angeben , nach der Vagrant sucht. Siehe meine Antwort unten für weitere Details.
Jonathan Bender
2
Gemfileist für die Entwicklung von Vagrant-Plugins vorgesehen. Siehe github.com/mitchellh/vagrant/issues/8370
mixel
10

Bitte beachten Sie, dass Sie ab Vagrant 1.5 Ihre Abhängigkeiten in Ihrem angeben können Gemfile. Per Blogbeitrag zum Update :

Jetzt lädt Vagrant 1.5 automatisch alle Edelsteine ​​in der Gruppe "Plugins" in Ihre Gemfile. Als Beispiel ist hier die Gemfile für ein "Vagrant-Bar" -Plugin:

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
quelle
8
Bezieht sich dieser Blog-Beitrag nicht auf die Entwicklung von Vagrant- Plugins ? Vagrant- Boxen haben im Allgemeinen keine Gemfiles, sie verwenden Vagrantfiles.
Don McCurdy
1
Sie sind richtig , dass Vagrant Boxen haben nicht Gemfiles per se (Sie könnten eine Vagrantfile haben , die keine Plugins erforderlich war), aber wenn Sie sind Plugins (den Kontext des Blogs war als Abhängigkeiten für Ihr eigenes Plugin, aber das gleiche gilt (wahr für Vagrantfiles), sollten Sie eine Gemfile verwenden, um diese Anforderungen anzugeben.
Jonathan Bender
7
Danke, das ist hilfreich. Da viele Vagrant-Benutzer keine Ruby-Entwickler sind und noch keine haben Gemfile, würde es Ihnen etwas ausmachen , zu erklären, wie Sie das eingerichtet haben? Ich habe eine erstellt, die Ihrem Beispiel ähnelt, aber vagrant upnichts automatisch lädt. Versucht, bundle installaber das gibt eine Eingabeaufforderung über System-Rubygems-Berechtigungen, die nicht richtig klingt.
Don McCurdy
1
Ich vermute, dass Sie in OSX mit der Standard- Ruby-Installation arbeiten und auf dieses Problem stoßen : stackoverflow.com/questions/14607193 ?
Jonathan Bender
1
In der Welt der Kochbücher werden nur sehr wenige eine gemfile haben
mr.buttons
6

Ich konnte Louis St-Amours Antwort keinen Kommentar hinzufügen, aber ich wollte dies posten, nur für den Fall, dass jemand Hilfe bei der Erweiterung seiner Lösung benötigt.

# 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
quelle
//, Beachten Sie, dass vagrant-listoben ein Beispiel für ein Plugin ist, nicht ein notwendiger Teil des Codes. Sie können andere Vagrant Plugins hier sehen: vagrant-lists.github.io
Nathan Basanese
3

Bei der neuen Version von Vagrant bleibt die Antwort von @Amos Shapira in einer Endlosschleife stecken. Der Grund dafür ist, dass jeder Aufruf vagrant plugin installauch verarbeitet Vagrantfileund bei der Verarbeitung den Code für die Installation des Plugins immer wieder und so weiter ausführt.

Hier ist meine Lösung, die die Schleife vermeidet.

# 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
quelle
1

Ich habe gerade hier http://docs.vagrantup.com/v2/plugins/packaging.html eine Anweisung bemerkt

Vagrant.require_plugin "vagrant-aws"

Das macht genau das Gleiche wie das, was fgrehm beschrieben hat: schnell einen Fehler auslösen, wenn das Plugin nicht installiert ist.

Soweit ich weiß, gibt es immer noch keine Möglichkeit, Plugins automatisch zu installieren

Julien
quelle
6
Vagrant.require_plugin wurde am 1.5+
eis
1
Hier ist der offizielle Blog-Beitrag über die Ablehnung : vagrantup.com/blog/vagrant-1-5-plugin-improvements.html Nach meinem begrenzten Verständnis wurde er abgelehnt, da er nicht mehr erforderlich ist. Vagrant überprüft nun automatisch die Plugin-Abhängigkeiten. Ich bin mir nicht ganz sicher, ob ich den Blog-Beitrag verstehe ...
Jeff Widman
Der Beitrag spricht automatisch über das Überprüfen von Plugin- Abhängigkeiten, aber ich habe nichts über Abhängigkeiten der Vagrant-Box selbst gesehen.
Don McCurdy
Vagrant.require_pluginist veraltet. Mit Vagrant überprüft 1.7.4.
Czerasz
1

Meine Antwort kommt der Antwort von Louis St-Amour sehr nahe , aber anstatt Plugins automatisch zu installieren, wird nur eine Fehlermeldung ausgegeben, sodass der Benutzer das Plugin manuell installieren muss.

Ich möchte lieber, dass Benutzer alle Plugins kennen, die installiert werden, da sie global für alle Vagrant-Instanzen gelten, nicht nur für die aktuelle Vagrant-Datei.

Setzen Sie Vagrantfilefür jedes Plugin in diesem Beispiel den oberen Rand einer Zeile wie folgt ein vagrant-vbguest:

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

Sie können dieses Projekt verwenden (ich bin der Autor): https://github.com/DevNIX/Vagrant-dependency-manager

Es basiert auf ähnlichen Antworten, versucht jedoch, vollständiger und stabiler zu sein. Der große Vorteil dieser Idee ist, dass Sie Ihr Vagrantfile verteilen können und es auf jedem Computer ausgeführt wird, unabhängig von den in dieser Umgebung installierten Plugins.

Es ist einfach zu bedienen:

  1. Kopieren Sie dependency_manager.rb neben Ihre Vagrant-Datei
  2. Schließen Sie es ein und rufen Sie die check_pluginsÜbergabe Ihrer Abhängigkeiten als Array auf

    Beispiel:

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

Ich würde gerne Pull-Anfragen zusammenführen, mögliche Probleme beheben und Ideen für neue Funktionen erhalten. Derzeit denke ich darüber nach, den Abhängigkeitsmanager selbst zu aktualisieren und bestimmte Plugin-Versionen zu benötigen: D.

Grüße!

Dev_NIX
quelle
0

Ich habe ein Problem mit der Neuinstallation von Vagrant, bei der das Verzeichnis .vagrant.d noch nicht erstellt wurde. Ich konnte das Snippet von Luis St. Amour zum Laufen bringen, indem ich die Ausnahme abfing.

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
quelle
Unter Windows wird der Fehler "Computer 'Standard' mit 'Virtualbox'-Provider hochfahren ... aber ein anderer Prozess führt bereits eine Aktion auf dem Computer aus" angezeigt, da uper ausgeführt wird up. Gibt es eine Möglichkeit, dies zu vermeiden, ohne vagrant upzweimal zu laufen ?
Tom B
0

Hier ist, was ich auf Vagrant 1.8 verwende und es funktioniert gut. Platzieren Sie dies irgendwo vor dem Konfigurationsblock in Ihrer Vagrant-Datei.

# 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
quelle
Es scheint, dass dies nicht plattformübergreifend ist.
Donnerstag,