简单(且完整)的解决方案

简单(且完整)的解决方案

当 vagrant 配置服务器时,我想在主机上运行一个 bash 脚本。

实现这一目标的最佳方法是什么?

答案1

至少有两个插件应该有帮助:

如果你不关心脚本是否在(几乎)所有vagrant命令上运行,你也可以在 Vagrantfile 中直接运行(或使用任何 ruby​​ 魔法):

system('./myscript.sh')

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

答案2

简单(且完整)的解决方案

(我说完整是因为接受的答案没有检查用户是否正在使用 vagrant up。因此,脚本在每个命令上执行,这不是 OP 想要的。)

然而,有一个简单的解决方案。

ARGV[0]是输入命令的第一个参数,可以是up、、down等等。只需在 Vagrantfile 中status检查的值即可。ARGV[0]


类似这样的事情就可以了:

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

答案3

根据 @tmatilai 的回答,但已针对 2019 年进行了更新,vagrant-triggers 已合并到 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/

或者直接在Vagrant.configure("2")块中:

config.trigger.before [:up, :provision] do |trigger|
  ...
end

答案4

与 @tmatilai 所说的关于使用

system('./myscript.sh')

vagrant我发现它对于一次性命令(例如安装 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 的第一行。这样,它将首先安装 vagrant-fabric 插件、fabric 和 jinja(如果失败,将首先尝试不使用sudoforvirtualenvs和 with sudo),然后该行本身会进行注释。

相关内容