Ответы:
Как минимум два плагина, которые должны помочь:
Если вас не волнует, что скрипт запускается (почти) для всех vagrant
команд, вы также можете просто раскошелиться (или использовать какую-либо рубиновую магию) в Vagrantfile:
system('./myscript.sh')
Vagrant.configure('2') do |config|
# ...
end
Kernel
модуле, задокументирован здесь . Kernel
Модуль входит в Object
класс, поэтому его методы доступны во всех областях.
(Я говорю «завершено», потому что принятый ответ не проверяет, использует ли пользователь vagrant up. Поэтому сценарий выполняется для каждой команды, а это не то, что хочет OP).
Однако есть простое решение.
ARGV[0]
является первым аргументом команды вошел и может быть up
, down
, status
и т.д .. Просто проверьте значение ARGV[0]
в вашем Vagrantfile.
Что-то вроде этого подойдет:
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
Поместите это в верхнюю часть вашего 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
Затем просто вызовите в своем Vagrantfile вот так:
config.vm.provision "list-files", type: "local_shell", command: "ls"
И через командную строку вот так:
vagrant provision --provision-with list-files
Это своего рода хак, так как выглядит как плагин, но на самом деле это не так (он не появится, когда вы это сделаете vagrant plugin list
). Я не рекомендую делать это таким образом, за исключением того, что он имеет то преимущество, что не требует установки плагина, поэтому ваш Vagrantfile будет работать на любом компьютере, который поддерживает последнюю версию конфигурации (версия 2 на момент написания этой статьи). Хотя это звучит многообещающе переносимо, есть также и кросс-платформенная проблема самой команды, которую вы выдаете. Вам нужно будет учесть, хотите ли вы, чтобы ваш Vagrantfile был переносимым, но это должно помочь вам начать.
На основании ответа @ tmatilai, но обновленного до 2019 года, vagrant-триггеры были объединены в Vagrant. Теперь вы можете сделать что-то вроде этого:
node.trigger.before [:up, :provision] do |trigger|
trigger.info = "Running ./myscript.sh locally..."
trigger.run = {path: "./myscript.sh"}
end
Этот блок идет внутри config.vm.define
. Дополнительная документация: https://www.vagrantup.com/docs/triggers/
config.vm.define
не является обязательным требованием; они также могут быть размещены внутри Vagrant.configure("2") do |config| ... end
. В заключение отметим, что на хостах Windows Vagrant с удовольствием выполнит сценарии Powershell, которые также имеют .ps1
расширение.
В соответствии с тем, что @tmatilai сказал об использовании
system('./myscript.sh')
Я нашел это очень полезным для одноразовых команд, таких как установка бродячих команд или какого-либо провайдера, который может быть не установлен в системе. Я просто избегаю его повторного запуска каждый раз, когда я вызываю vagrant
команды, добавляя sed для автоматического комментирования Vagrantfile
.
Например:
system('vagrant plugin install vagrant-fabric && (pip install fabric jinja2 || sudo pip install fabric jinja2) && sed -i -e "s/^system/#system/g" Vagrantfile')
И я делаю это первой строкой моего Vagrantfile. Таким образом , он будет сначала установить бродягу-ткань плагин, ткань и дзиндзя (будет попробовать сначала без sudo
на virtualenvs
и sudo
если это не удается) , а затем сама линия комментарии.
if [[ $(vagrant plugin list | grep -c vagrant-host-shell) == "0" ]] then vagrant plugin install vagrant-host-shell fi
vagrant status
раньше vagrant up
...