2017-10-07 61 views
0

我的目标是创建一个Vagrantfile,我可以选择使用Docker或VirtualBox使用--provider标志(例如vagrant up --provider = virtualbox)。我遇到了问题,因为Docker提供者说我的盒子不兼容。这是真的,但我不希望Docker使用这个盒子;我有一个我指向Docker使用的Dockerfile。我希望只有当VirtualBox是提供者时才能使用该框。如何让Docker提供程序忽略框声明或仅在VirtualBox是提供程序时才使框声明运行?如何为多个提供者编写一个Vagrantfile,每个提供者使用不同的框?

这是我Vagrantfile:

Vagrant.require_version ">= 1.7.0" 

Vagrant.configure('2') do |config| 
    PROJECT_ROOT = File.expand_path(File.join(File.dirname(File.expand_path(__FILE__)), '..')) 

    config.vm.provider "docker" do |d| 
    d.build_dir = "." 
    d.has_ssh = true 
    end 

    config.vm.box = "ubuntu/trusty64" # <--------- this is the line the Docker provider chokes on 
    config.vm.provider "virtualbox" do |v| 
    v.gui = true 
    end 

    config.vm.network :forwarded_port, guest: 80, host: 9002 
    config.vm.network :forwarded_port, guest: 9000, host: 9000 
    config.vm.network :forwarded_port, guest: 9001, host: 9001 

    config.vm.synced_folder PROJECT_ROOT, '/srv' 

    config.vm.provision :ansible do |ansible| 
    ansible.verbose = "v" 
    ansible.playbook = 'provisioning/playbook.yml' 
    end 
end 

回答

1

你只需要根据供应商

Vagrant.require_version ">= 1.7.0" 

Vagrant.configure('2') do |config| 
    PROJECT_ROOT = File.expand_path(File.join(File.dirname(File.expand_path(__FILE__)), '..')) 

    config.vm.provider "docker" do |d| 
    d.build_dir = "." 
    d.has_ssh = true 
    end 

    config.vm.provider "virtualbox" do |v, override| 
    override.vm.box = "ubuntu/trusty64" 
    v.gui = true 
    end 

    config.vm.network :forwarded_port, guest: 80, host: 9002 
    config.vm.network :forwarded_port, guest: 9000, host: 9000 
    config.vm.network :forwarded_port, guest: 9001, host: 9001 

    config.vm.synced_folder PROJECT_ROOT, '/srv' 

    config.vm.provision :ansible do |ansible| 
    ansible.verbose = "v" 
    ansible.playbook = 'provisioning/playbook.yml' 
    end 
end 
+0

你尝试运行呢?它不起作用。 'config.vm.provider'不是一个条件语句。分析文件时,所有对'config.vm.provider'的调用都是如此。 – hekevintran

+1

@hekevintran,请检查更新后的答案 –

+0

好的发现啊,重写就是答案!谢谢! – hekevintran

0

以移动框条件的问题从根本上归结为一个事实,即无业游民有一个内置的假设箱和供应商是完全独立的,可以任意组合交换。这不是真的。一个盒子只与其设计的提供者兼容。正确的设计将允许每个提供者指定自己的盒子,而不是使盒子成为全局值。这种设计已经存在于Docker提供程序中,该提供程序允许您选择Docker镜像,但不存在于任何其他提供程序中。就我而言,这是Vagrant中的一个错误。

我对这个解决方案是解析通过提供参数和if语句包裹提供商声明:

require 'optparse' 

def get_provider 
    ret = nil 
    opt_parser = OptionParser.new do |opts| 
    opts.on("--provider provider") do |provider| 
     ret = provider 
    end 
    end 
    opt_parser.parse!(ARGV) 
    ret 
end 
provider = get_provider || "virtualbox" 

PROJECT_ROOT = File.expand_path(File.join(File.dirname(File.expand_path(__FILE__)), '..')) 

Vagrant.require_version ">= 1.7.0" 

Vagrant.configure('2') do |config| 
    if provider == "docker" 
    config.vm.provider "docker" do |d| 
     d.build_dir = "." 
     d.has_ssh = true 
    end 
    end 

    if provider == "virtualbox" 
    config.vm.box = "ubuntu/trusty64" 
    config.vm.provider "virtualbox" do |v| 
     v.gui = true 
    end 
    end 

    config.vm.network :forwarded_port, guest: 80, host: 9002 
    config.vm.network :forwarded_port, guest: 9000, host: 9000 
    config.vm.network :forwarded_port, guest: 9001, host: 9001 

    config.vm.synced_folder PROJECT_ROOT, '/srv' 

    config.vm.provision :ansible do |ansible| 
    ansible.verbose = "v" 
    ansible.playbook = 'provisioning/playbook.yml' 
    end 
end 
相关问题