【问题标题】:Multi-machine Vagrant project not provisioning as per docs多机 Vagrant 项目未按照文档进行配置
【发布时间】:2016-02-22 23:31:03
【问题描述】:

我正在尝试建立一个多机 Vagrant 项目。根据文档 (https://www.vagrantup.com/docs/multi-machine/),配置是“由外而内”的,这意味着在单个机器块中配置脚本之前执行任何顶级配置脚本。

该项目包含一个 Laravel 项目和一个 Symfony 项目。我的Vagrantfile 看起来像这样:

require "json"
require "yaml"

confDir = $confDir ||= File.expand_path("vendor/laravel/homestead", File.dirname(__FILE__))

homesteadYamlPath = "web/Homestead.yaml"
homesteadJsonPath = "web/Homestead.json"
afterScriptPath = "web/after.sh"
aliasesPath = "web/aliases"

require File.expand_path(confDir + "/scripts/homestead.rb")

Vagrant.configure(2) do |config|
  config.vm.provision "shell", path: "init.sh"

  config.vm.define "web" do |web|
    web.ssh.forward_x11 = true

    if File.exists? aliasesPath then
      web.vm.provision "file", source: aliasesPath, destination: "~/.bash_aliases"
    end

    if File.exists? homesteadYamlPath then
      Homestead.configure(web, YAML::load(File.read(homesteadYamlPath)))
    elsif File.exists? homesteadJsonPath then
      Homestead.configure(web, JSON.parse(File.read(homesteadJsonPath)))
    end

    if File.exists? afterScriptPath then
      web.vm.provision "shell", path: afterScriptPath
    end
  end

  config.vm.define "api" do |api|
    api.vm.box = "ubuntu/trusty64"

    api.vm.provider :virtualbox do |vb|
      vb.customize ["modifyvm", :id, "--memory", "2048"]
    end

    api.vm.network "private_network", ip: "10.1.1.34"
    api.vm.network "forwarded_port", guest: 80, host: 8001
    api.vm.network "forwarded_port", guest: 3306, host: 33061
    api.vm.network "forwarded_port", guest: 9200, host: 9201

    api.vm.synced_folder "api", "/var/www/api"

    api.vm.provision "shell", path: "api/provision.sh"
  end
end

我有一个用于 Laravel 项目的块 (web),其中我复制了基于 Homestead 的 Vagrantfile 的内容,以及一个使用“标准”Vagrant 配置的 api 块。

为了引导项目,我创建了一个简单的 shell 脚本 (init.sh),它只是将 Git 存储库克隆到 git-ignored 目录中。鉴于文档说配置工作由外而内,因此我希望该脚本能够运行,然后是特定于机器的块,但这似乎没有发生。相反,在vagrant up 上,我收到以下错误:

这台机器的配置有错误。请修正以下错误,然后重试:

虚拟机:
* 必须指定一个框。

在运行 shell 脚本之前,它似乎仍在尝试配置单个机器。我知道 shell 脚本没有被调用,因为我向它添加了 echo 语句。相反,终端只输出以下内容:

通过“virtualbox”提供程序将机器“web”启动...
使用 'virtualbox' 提供者将机器 'api' 启动...

那么我怎样才能让 Vagrant 先运行我的 shell 脚本呢?我认为它失败了,因为web 组正在检查我的 web/Homestead.yaml 文件是否存在,如果存在,则使用其中的值进行配置(包括框名称),但作为我的外壳脚本尚未运行,也没有克隆该文件不存在的存储库,因此没有指定 box,这是 Vagrant 抱怨的。

【问题讨论】:

    标签: vagrant homestead vagrant-provision


    【解决方案1】:

    问题是您没有为web 机器定义box。您需要在外部空间中定义框,例如

    config.vm.box = "ubuntu/trusty64"
    

    如果您打算为两台机器使用相同的机器/操作系统或在web 范围内定义

    web.vm.box = "another box"
    

    编辑

    使用provision 属性将在VM 中运行脚本,这不是您想要的,因为您希望脚本在您的主机上运行。 (而且因为运行在虚拟机中,所以需要先启动虚拟机)

    Vagrantfile 只是一个简单的 ruby​​ 脚本,因此您可以添加脚本甚至执行(来自 ruby​​ 调用),我可以看到的一个潜在问题是您不能保证执行,特别是您的 init 的执行脚本将在 vagrant 在 VM 上执行之前完成。

    一种可能性是使用vagrant trigger plugin 并在up 事件之前执行您的shell 脚本

      config.trigger.before :up do
        info "Dumping the database before destroying the VM..."
        run  "init.sh"   
      end
    

    以这种方式运行,vagrant 将等待脚本执行,然后再运行 up 命令的一部分。

    您需要检查您的脚本以确保它仅在需要时运行,否则,它将在您每次启动机器时运行(调用 vagrant up),例如您可以检查 yaml 文件是否存在

    【讨论】:

    • 根据我的问题,包括盒子名称的值在 web/Homestead.yaml 中。我需要 Vagrant 运行我的 init.sh 脚本首先克隆包含此文件的项目。
    • 不是因为你在你的yaml文件中声明了vagrant就会知道它,你仍然需要声明config.vm.boxweb.vm.box的值并指向你的yaml文件中的值
    • 我想我知道我的 Homestead.yaml 文件中有什么。你可能想看看 Laravel Homestead,它就是这样提供 Vagrant 的。
    • 来自 vagrant 的错误很明显 * A box must be specified. 所以你不要粘贴你的 yaml 文件,但明确 vagrant 无法从你的所有配置文件中找到它需要使用哪个框,所以它不会开始
    • 是的,因为我的 init.sh 脚本没有运行,它将克隆包含 Homestead.yaml 文件的项目Vagrant 应该用来配置.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-11
    • 1970-01-01
    • 2016-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多