Odpowiedzi:
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
Kernelmodule, udokumentowanym tutaj . KernelModuł jest zawarte w Objectklasie, więc są dostępne we wszystkich zakresach jej metody.
(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
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ąć.
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/
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.
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.
if [[ $(vagrant plugin list | grep -c vagrant-host-shell) == "0" ]] then vagrant plugin install vagrant-host-shell fi
vagrant statuswcześniej vagrant up...