在本地覆盖Vagrant配置设置(每个开发人员)

net*_*key 55 ruby vagrant

我想一般回答这个问题,但为了说明一下,这是一个用例:

我正在使用Vagrant进行简单的LMAP项目.我使用独立的Puppet进行配置.现在,可能有一些开发人员坐在代理后面,他们需要对VM进行一些额外的配置.我有事情在Puppet方面工作:我可以将代理IP(如果有的话)作为事实传递给Ppetpet中的Vagrantfile木偶,如果它已经设置,Puppet会做出相应的反应.

我唯一的问题是:开发人员如何为他们的开发环境指定/覆盖此设置而无需更改Vagrantfile(在版本控制下并且必须保持dev-environment-neutral)?

如果人们可以覆盖一个名为例如Vagrantfile.local我将排除通过的文件中的一些Vagrant设置,那将是非常棒的.gitignore.

由于Vagrantfile只是Ruby,我尝试了以下内容:

# Also load per-dev custom vagrant config
custom_vagrantfile = 'Vagrantfile.local'
load custom_vagrantfile if File.exist?(custom_vagrantfile)
Run Code Online (Sandbox Code Playgroud)

文件包含基本上是可行的,但它看起来像在包含的文件中,我不再在同一个Vagrant上下文中...

Vagrant::Config.run do |config|
  config.vm.provision :puppet do |puppet|
    puppet.facter = { "proxy" => "proxy.host:80" }
  end
end
Run Code Online (Sandbox Code Playgroud)

...还"重置"我在主要部分制作的所有其他木偶配置值Vagrantfile,这让我觉得我在这里朝着错误的方向前进.我应该注意到我在Ruby的总菜鸟;)

任何人都可以给我一个提示,甚至是一个有效的解决方案,可以在这里完成per-dev定制吗?

Wil*_*ler 87

Vagrantfile只是Ruby,所以YAML是另一种选择.

例如,在Vagrantfile我这样做:

# -*- mode: ruby -*-
# vi: set ft=ruby :
require 'yaml'

settings = YAML.load_file 'vagrant.yml'
db_ip_address = settings['db']['ip_address']
api_ip_address = settings['api']['ip_address']

Vagrant.configure("2") do |config|
  config.vm.box = "ffuenf/ubuntu-13.10-server-amd64"
  config.vm.box_url = "https://vagrantcloud.com/ffuenf/ubuntu-13.10-server-amd64/version/4/provider/virtualbox.box"

  config.vm.define "db" do |db|
    db.vm.synced_folder settings['db']['artifacts_dir']['host'], settings['db']['artifacts_dir']['guest']
    db.vm.network "private_network", ip: db_ip_address
    ... other stuff ...
  end

  config.vm.define "api" do |api|
    api.vm.synced_folder settings['api']['artifacts_dir']['host'], settings['api']['artifacts_dir']['guest']
    api.vm.network "private_network", ip: api_ip_address
    api.vm.network "forwarded_port", guest: settings['api']['forwarded_port']['guest'], host: settings['api']['forwarded_port']['host']
  end
end
Run Code Online (Sandbox Code Playgroud)

然后我有一个vagrant.yml文件(我只是编写了名称;你可以使用你喜欢的任何名称)用于特定于开发人员的配置:

db:
  ip_address: 192.168.4.14
  artifacts_dir:
    host: /Users/willie/myapp/db-scripts
    guest: /opt/myapp/db

api:
  ip_address: 192.168.4.15
  forwarded_port:
    host: 9080
    guest: 8080
  artifacts_dir:
    host: /Users/willie/myapp/artifacts
    guest: /opt/myapp/api
Run Code Online (Sandbox Code Playgroud)

  • 这应该是一个流浪汉的成语.这将进入我的所有项目. (3认同)

Phi*_*bin 26

我建议使用环境变量来动态地改变它的行为Vagrantfile而不编辑文件本身.

为了给出一个真实世界的例子,这里是默认情况下如何使用Ubuntu基本框,但是有一个环境变量定义了另一个Linux发行版:

if ENV['OPERATINGSYSTEM']
  if ENV['OPERATINGSYSTEM'].downcase == 'redhat'
    os_name = 'centos'
    config.vm.box     = 'centos'
    config.vm.box_url = 'https://dl.dropbox.com/u/7225008/Vagrant/CentOS-6.3-x86_64-minimal.box'
  else
    raise(Exception, "undefined operatingsystem: #{ENV['OPERATINGSYSTEM']}")
  end
else
  os_name = 'precise64'
  config.vm.box     = 'precise64'
  config.vm.box_url = 'http://files.vagrantup.com/precise64.box'
end
Run Code Online (Sandbox Code Playgroud)

此示例来自https://github.com/puppetlabs/puppetlabs-openstack_dev_env

  • 我一直在使用这种方法并且喜欢它...除了我现在正在管理多个不同的AWS盒子,所有这些盒子都使用来自同一台机器的不同Vagrant脚本进行配置......而且每个设置正确的ENV设置都很痛苦时间.您是否考虑过除ENV变量之外的其他概念?也许在管理所有设置的高级目录中读取未签入的配置文件? (3认同)

Cou*_*les 12

如果您准备定义应用于所有流浪盒的设置,值得注意的是,"Vagrant实际上会加载一系列Vagrantfiles,将设置合并到一起." (参考https://docs.vagrantup.com/v2/vagrantfile/)

所以我定义了以下内容~/.vagrant.d/Vagrantfile来增加我的Vagrant盒子的RAM量:

Vagrant.configure(2) do |config|
    config.vm.provider "virtualbox" do |vb|
      vb.memory = 2048
    end
end
Run Code Online (Sandbox Code Playgroud)


Ser*_*sev 6

这是一个想法.它可能是"丑陋的"和"错误的",但至少,它的工作原理:)

# file2.rb, this is your per-dev configuration file
puts "included external file which uses outer var: #{foo}"

# file1.rb, this would be your Vagrantfile
puts 'first'
foo = 'bar'

external = File.read 'file2.rb'
eval external
puts 'second'
Run Code Online (Sandbox Code Playgroud)

我们来试试吧

$ ruby file1.rb
first
included external file which uses outer var: bar
second
Run Code Online (Sandbox Code Playgroud)

适应您的示例,file2.rb将仅包含使用config而不定义它(config将从外部上下文提供)

  config.vm.provision :puppet do |puppet|
    puppet.facter = { "proxy" => "proxy.host:80" }
  end
Run Code Online (Sandbox Code Playgroud)

你的Vagrant文​​件可能如下所示:

Vagrant::Config.run do |config|
  external = File.read 'Vagrantfile.local'
  eval external

  # proceed with general settings here
  config.vm.provision :puppet do |puppet|
    puppet.facter = { "proxy" => "proxy.host:80" }
  end
end
Run Code Online (Sandbox Code Playgroud)

更新(另一种,"数据驱动"方法)

# Vagranfile.local
config_values[:puppet][:facter][:proxy] = 'proxy.host:80'

# Vargantfile
Vagrant::Config.run do |config|
  config_values = {
    puppet: {
      facter: {
        proxy: nil
      },
      manifests_file: 'my_manifest.pp'

    }
  }
  external = File.read 'Vagrantfile.local'
  eval external # this should overwrite proxy config

  # proceed with general settings here
  config.vm.provision :puppet do |puppet|
    if config_values[:puppet][:facter][:proxy]
      puppet.facter = { "proxy" => config_values[:puppet][:facter][:proxy] } 
    end

    puppet.manifests_file = config_values[:puppet][:manifests_file]
  end
end
Run Code Online (Sandbox Code Playgroud)


Amr*_*afa 5

我相信这是Nugrant插件创建要解决的确切用例.它允许每个开发人员.vagrantuser在YAML中指定自定义配置值(这是一个.gitignore-ed文件),然后轻松地引用这些值Vagrantfile.

在您的情况下,代理开发人员的.vagrantuser文件看起来像这样:

proxy: 'proxy.host:80'
Run Code Online (Sandbox Code Playgroud)

Vagrantfile会看起来像这样(伪代码,我真的不知道ruby):

Vagrant::Config.run do |config|
  config.vm.provision :puppet do |puppet|
    if config.user.has_key?('proxy')
      puppet.facter = { "proxy" => config.user.proxy }
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

您应该vagrantuser.example为您的开发人员捆绑一个示例/参考vagrantuser(ie )文件,以便复制并调整其环境.


Tom*_*mas 5

扩展@Willie Wheeler 的回答。我的设置是:

Root
|-- defaults.yml
|-- env.yml
|-- Vagrantfile
Run Code Online (Sandbox Code Playgroud)

流浪档案

# Load local env config
require 'yaml'
dir = File.dirname(File.expand_path(__FILE__))

# defaults
settings = YAML::load_file("#{dir}/defaults.yml")

if File.exist?("#{dir}/env.yml")
    env_settings = YAML::load_file("#{dir}/env.yml")
    settings.merge!(env_settings)
end
...
# Customize the amount of memory on the VM:
    vb.memory = settings["vb"]["memory"]
Run Code Online (Sandbox Code Playgroud)

默认值.yml

vb:
  memory: 1024
Run Code Online (Sandbox Code Playgroud)

环境.yml

vb:
  memory: 204
Run Code Online (Sandbox Code Playgroud)

这会将您拥有的任何默认值与您的每个开发配置合并。开发人员也很清楚他们可以实际更改哪些值