Führen Sie das Skript auf dem Hostcomputer aus, während der Vagabund läuft


40

Ich möchte ein Bash-Skript auf dem Host-Computer ausführen, wenn Vagrant den Server bereitstellt.

Was wäre die beste Methode, um dies zu erreichen?

Antworten:


29

Mindestens zwei Plugins, die helfen sollten:

Wenn es Ihnen egal ist, ob das Skript mit (fast) allen vagrantBefehlen ausgeführt wird, können Sie in Vagrantfile auch einfach die Rubinmagie ausgeben (oder verwenden):

system('./myscript.sh')

Vagrant.configure('2') do |config|
  # ...
end

2
Vagabundauslöser sehen genau so aus, wie ich es brauche.
Digital

Wo hast du diese system () Funktion gefunden? Ich kann nirgendwo Unterlagen darüber finden ...
Cristiano Fontes

1
@ CristianoFontes, es ist im KernelModul, hier dokumentiert . Das KernelModul ist in der ObjectKlasse enthalten, sodass seine Methoden in allen Bereichen verfügbar sind.
Tmatilai

1
Ich Idiot. Ich habe in vagabundierenden Dokumenten gesucht. Vielen Dank!
Cristiano Fontes

26

Einfache (und vollständige) Lösung

(Ich sage vollständig, weil die akzeptierte Antwort nicht prüft, ob der Benutzer Vagabund verwendet. Daher wird das Skript bei jedem Befehl ausgeführt, was das OP nicht wünscht.)

Hierfür gibt es jedoch eine einfache Lösung.

ARGV[0]ist das erste Argument des Befehls eingegeben und sein kann up, down, status, etc .. Sie einfach den Wert überprüfen ARGV[0]in Ihrem Vagrantfile.


So etwas reicht aus:

system("
    if [ #{ARGV[0]} = 'up' ]; then
        echo 'You are doing vagrant up and can execute your script'
        ./myscript.sh
    fi
")

Vagrant.configure('2') do |config|
  # ...
end

1
Hi, Mick ... Schöne Antwort, danke dafür. Aber ich kann nicht bekommen, wenn [# {ARGV [0]} = 'up']; an Fenstern arbeiten. Es findet nie die arg
Cristiano Fontes

1
Dadurch wird Ihr Skript als erstes ausgeführt, bevor etwas anderes ausgeführt wird, unabhängig von der Position in Vagrantfile. Es könnte ausreichen, was Sie tun, aber
Vigintas

3
@CristianoFontes Sie können den argv-Test in Ruby außerhalb des Systemaufrufs ausführen und er funktioniert unter Windows und * nix. Ich verwende dies, um eine globale Ruby-Variable festzulegen, die angibt, dass die Bereitstellung erfolgt, indem ich in der Befehlszeile nach dem Befehl up oder provision suche: if ARGV [0] = ~ / ^ up | provision $ / i und nicht ARGV.include? (" --no-provision ") $ provisioning = true else $ provisioning = false end
Rhabarber

Dies ist eigentlich eine schlechte Praxis, wie von Vagrant empfohlen. Sie sollten ein Plugin schreiben, um sich an den Befehl "up" anzuschließen. Sie können Folgendes festlegen: vor, nach und um die Ausführung.
SilentICE

1
@Mick ist nur aus den Vagrant-Dokumenten ( docs.vagrantup.com/v2/plugins/commands.html ). Es ist auch ein fragiles Skript, da Sie nicht sicher sein können, dass argv [0] in Anrufsfällen 'up' ist, anstatt ein Flag zu sagen. Auch wenn Sie zu rohem Rubin kommen, brechen Sie die Kapselung aus, die das Framework bereitstellen soll. Es gibt Mechanismen, die dies korrekt
ausführen.

9

Legen Sie dies oben in Ihre Vagrantdatei:

module LocalCommand
    class Config < Vagrant.plugin("2", :config)
        attr_accessor :command
    end

    class Plugin < Vagrant.plugin("2")
        name "local_shell"

        config(:local_shell, :provisioner) do
            Config
        end

        provisioner(:local_shell) do
            Provisioner
        end
    end

    class Provisioner < Vagrant.plugin("2", :provisioner)
        def provision
            result = system "#{config.command}"
        end
    end
end

Dann rufen Sie einfach in Ihrem Vagrantfile auf:

config.vm.provision "list-files", type: "local_shell", command: "ls"

Und über die Kommandozeile so:

vagrant provision --provision-with list-files

Dies ist eine Art Hack, da es wie ein Plug-In aussieht, es aber nicht ist (es wird nicht angezeigt, wenn Sie es tun vagrant plugin list). Ich empfehle nicht, dies auf diese Weise zu tun, außer dass es den Vorteil hat, dass kein Plugin installiert werden muss, sodass Ihr Vagrantfile auf jedem Computer funktioniert, der die neueste Konfigurationsversion unterstützt (Version 2 zum Zeitpunkt der Erstellung dieses Dokuments). Das klingt zwar vielversprechend portabel, aber es gibt auch die gesamte plattformübergreifende Ausgabe des tatsächlichen Befehls, den Sie ausgeben. Sie müssen berücksichtigen, ob Ihr Vagrantfile portabel sein soll, aber dies sollte Ihnen den Einstieg erleichtern.


1
Gute Antwort, ich werde dies verwenden, um eine niedrige Portweiterleitung einzurichten.
Poindexter

6

Basierend auf der Antwort von @ tmatilai, die für 2019 aktualisiert wurde, wurden Vagrant-Trigger in Vagrant zusammengeführt. So können Sie jetzt so etwas tun:

node.trigger.before [:up, :provision] do |trigger|
  trigger.info = "Running ./myscript.sh locally..."
  trigger.run = {path: "./myscript.sh"}
end

Dieser Block geht rein von config.vm.define. Weitere Dokumentation: https://www.vagrantup.com/docs/triggers/


Dies ist die bisher eleganteste Antwort. Ich sollte hinzufügen, dass das Platzieren dieses und ähnlicher Snippets config.vm.definenicht erforderlich ist. Sie können auch darin platziert werden Vagrant.configure("2") do |config| ... end. Abschließend sei angemerkt, dass Vagrant auf Windows-Hosts gerne auch Powershell-Skripte mit der .ps1Erweiterung ausführt .
Ben Johnson

4

Im Einklang mit dem, was @ tmatilai über die Verwendung gesagt hat

system('./myscript.sh')

Ich fand es sehr hilfreich für einmalige Befehle wie die Installation von vagrant-Befehlen oder eines Provisioners, der möglicherweise nicht im System installiert ist. Ich vermeide einfach, dass es jedes Mal neu ausgeführt wird, wenn ich die vagrantBefehle aufrufe , indem ich ein sed hinzufüge, um das automatisch zu kommentieren Vagrantfile.

Beispielsweise:

system('vagrant plugin install vagrant-fabric && (pip install fabric jinja2 || sudo pip install fabric jinja2) && sed -i -e "s/^system/#system/g" Vagrantfile')

Und ich mache das zur ersten Zeile meines Vagrantfiles. Auf diese Weise wird es zuerst den Vagabund-Stoff - Plugin, Stoff und jinja installiert (wird zunächst versuchen , ohne sudofür virtualenvsund mit sudowenn das fehlschlägt) und dann der Linie Kommentare selbst.


Es wäre einfacher, die Liste der Vagrant-Plugins zu durchsuchen, als die Vagrant-Datei zu dekommentieren, was anderen Leuten in Ihrem Team Probleme bereiten könnte. if [[ $(vagrant plugin list | grep -c vagrant-host-shell) == "0" ]] then vagrant plugin install vagrant-host-shell fi
Jordanien

Das Problem dabei ist, dass es bei anderen Befehlen ausgelöst wird, was passiert, wenn Sie vagrant statusvorher laufen vagrant up...
Mick
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.