0

我正在尝试建立一个多机 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

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

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

这台机器的配置有错误。请修复以下错误并重试:

vm:
* 必须指定一个框。

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

将机器 'web' 与 'virtualbox' 提供程序一起使用...
将机器 'api' 与 'virtualbox' 提供程序一起使用...

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

4

1 回答 1

0

问题是您没有boxweb机器定义 a 。您需要在外层空间中定义框,例如

config.vm.box = "ubuntu/trusty64"

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

web.vm.box = "another box"

编辑

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

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

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

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

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

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

于 2016-02-23T09:06:47.763 回答