Uruchom skrypt na maszynie hosta podczas włóczęgowania

40

Chciałbym uruchomić skrypt bash na maszynie hosta, gdy włóczęga zapewnia serwerowi.

Jaka byłaby najlepsza metoda osiągnięcia tego?

cyfrowy
źródło

Odpowiedzi:

29

Co najmniej dwie wtyczki, które powinny pomóc:

Jeśli nie obchodzi cię, że skrypt jest uruchamiany na (prawie) wszystkich vagrantpoleceniach, możesz także po prostu wyrzucić (lub użyć jakiejkolwiek rubinowej magii) w Vagrantfile:

system('./myscript.sh')

Vagrant.configure('2') do |config|
  # ...
end
Tmatilai
źródło
2
Wyzwalające wyzwalacze wyglądają dokładnie tak, jak potrzebuję.
cyfrowy
Gdzie znalazłeś tę funkcję system ()? Nigdzie nie mogę znaleźć żadnej dokumentacji na ten temat ...
Cristiano Fontes
1
@CristianoFontes, jest w Kernelmodule, udokumentowanym tutaj . KernelModuł jest zawarte w Objectklasie, więc są dostępne we wszystkich zakresach jej metody.
tmatilai
1
Głupi ja. Patrzyłem na włóczęgowską dokumentację. Dzięki!
Cristiano Fontes
26

Proste (i kompletne) rozwiązanie

(Mówię kompletne, ponieważ zaakceptowana odpowiedź nie sprawdza, czy użytkownik używa włóczęgi w górę. Dlatego skrypt jest wykonywany dla każdej komendy, co nie jest tym, czego chce OP).

Istnieje jednak proste rozwiązanie tego problemu.

ARGV[0]Jest to pierwszy argument polecenia i może być wprowadzony up, down, statusitp .. Wystarczy sprawdzić wartość ARGV[0]w Vagrantfile.


Coś takiego zrobi:

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
Mick
źródło
1
Cześć Mick ... Dobra odpowiedź, dziękuję za to. Ale nie mogę dostać, jeśli [# {ARGV [0]} = 'up']; do pracy w systemie Windows. Nigdy nie znajdzie argumentu
Cristiano Fontes
1
Spowoduje to wykonanie skryptu w pierwszej kolejności, zanim cokolwiek innego zostanie uruchomione, niezależnie od jego pozycji w pliku Vagrantfile. To może być wystarczające do tego, co robisz, ale potrzebowałem
wtyczki Vagrant-Trigger
3
@CristianoFontes możesz wykonać test argv w ruby ​​poza wywołaniem systemowym i będzie działał w systemie Windows i * nix. Używam tego, aby ustawić globalną zmienną ruby ​​wskazującą, że inicjowanie obsługi administracyjnej odbywa się, szukając polecenia w górę lub w wierszu poleceń: jeśli ARGV [0] = ~ / ^ up | prowizja $ / i, a nie ARGV.include? (" --no-prowizja ") $ prowizja = true else $ prowizja = fałszywy koniec
Rabarbar
Jest to w rzeczywistości zła praktyka zalecana przez Vagrant, powinieneś napisać wtyczkę, aby podłączyć się do polecenia „w górę”, możesz określić dowolne z: przed, po i wokół wykonania.
SilentICE,
1
@ Usuń zaznaczenie z Vagrant docs ( docs.vagrantup.com/v2/plugins/commands.html ). To także tworzy delikatny skrypt, ponieważ nie możesz być pewien, że w przypadkach wywołania argument argv [0] jest „w górę”, a nie mówi flagę. Również, jeśli wpadasz do surowego rubinu, przełamujesz enkapsulację, którą ma zapewnić framework. Istnieją mechanizmy narażone na to, aby zrobić to poprawnie, więc IMHO powinieneś używać ich, gdy tylko jest to możliwe
SilentICE,
9

Umieść to w górnej części pliku Vagrantfile:

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

Następnie po prostu przywołaj swój plik Vagrantfile w następujący sposób:

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

I za pomocą wiersza polecenia takiego:

vagrant provision --provision-with list-files

Jest to rodzaj włamania, ponieważ wygląda jak wtyczka, ale tak naprawdę nie jest (nie pojawi się, gdy to zrobisz vagrant plugin list). Nie polecam robić tego w ten sposób, z tą różnicą, że ma tę zaletę, że nie trzeba instalować wtyczki, więc plik Vagrantfile będzie działał na każdym komputerze, który obsługuje najnowszą wersję konfiguracji (od wersji 2 w momencie pisania tego). Choć brzmi to obiecująco przenośnie, istnieje także kwestia wydawania poleceń na wiele platform. Musisz wziąć pod uwagę, jeśli chcesz, aby Twój Vagrantfile był przenośny, ale to powinno zacząć.

Joel B.
źródło
1
Dobra odpowiedź, użyję tego do skonfigurowania przekierowania niskiego portu.
poindexter
6

W oparciu o odpowiedź @ tmatilai, ale zaktualizowaną do 2019 r., Wyzwalacze Vagrant zostały połączone w Vagrant. Możesz teraz zrobić coś takiego:

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

Ten blok wchodzi w skład config.vm.define. Dalsza dokumentacja: https://www.vagrantup.com/docs/triggers/

Sean Hood
źródło
To jak dotąd najbardziej elegancka odpowiedź. Powinienem dodać, że umieszczenie tego i podobnych fragmentów w środku config.vm.definenie jest wymogiem; można je również umieścić w Vagrant.configure("2") do |config| ... endśrodku. Na koniec, na hostach Windows, Vagrant chętnie wykona skrypty Powershell, które również mają .ps1rozszerzenie.
Ben Johnson,
4

Zgodnie z tym, co @tmatilai powiedział o używaniu

system('./myscript.sh')

Uznałem, że jest to bardzo pomocne dla jednorazowych poleceń, takich jak instalowanie błędnych poleceń lub jakiegoś dostawcy, który może nie zostać zainstalowany w systemie. Po prostu unikam jego ponownego uruchamiania za każdym razem, gdy wywołuję vagrantpolecenia, dodając sed, aby automatycznie komentować Vagrantfile.

Na przykład:

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

I czynię to pierwszą linią mojego Vagrantfile. W ten sposób najpierw zainstaluje wtyczkę Vagrant-fabric, fabric i jinja (najpierw spróbuje bez sudofor virtualenvsand with, sudojeśli to się nie powiedzie), a następnie linia sama się komentuje.

kenorb
źródło
Łatwiej byłoby po prostu grepować listę włóczęgów zamiast odkomentować plik Vagrantfile, co może powodować problemy dla innych osób w twoim zespole. if [[ $(vagrant plugin list | grep -c vagrant-host-shell) == "0" ]] then vagrant plugin install vagrant-host-shell fi
Jordan
Problem polega na tym, że będzie on uruchamiany na innych poleceniach, co jeśli uruchomisz vagrant statuswcześniej vagrant up...
Mick