Я хотел бы запустить bash-скрипт на хост-машине, когда vagrant подготовит сервер.
Каков будет лучший способ достижения этого?
Я хотел бы запустить bash-скрипт на хост-машине, когда vagrant подготовит сервер.
Каков будет лучший способ достижения этого?
Как минимум два плагина, которые должны помочь:
Если вас не волнует, что скрипт запускается (почти) во всех vagrant
командах, вы также можете просто выложить (или использовать какую-либо рубиновую магию) в Vagrantfile:
system('./myscript.sh')
Vagrant.configure('2') do |config|
# ...
end
(Я говорю завершено, потому что принятый ответ не проверяет, использует ли пользователь 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 сказал об использовании
system('./myscript.sh')
Я нашел это весьма полезным для одноразовых команд, таких как установка бродячих команд или какого-либо провайдера, который может быть не установлен в системе. Я просто избежать его повторного запуска каждый раз , когда я призываю vagrant
команды, добавив СЭД для автоматического прокомментируете 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. Таким образом, он сначала установит плагин vagrant-fabric, fabric и jinja (сначала попробует без sudo
для virtualenvs
и с sudo
если это не удастся), а затем строка прокомментирует себя.
На основании ответа @ 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/