Переопределение параметров конфигурации Vagrant локально (для каждого разработчика)
Я бы хотел, чтобы на этот вопрос был дан ответ в целом, но чтобы проиллюстрировать его, вот пример использования:
Я использую Vagrant для простого проекта LMAP. Я использую автономную марионетку для подготовки. Теперь могут быть некоторые разработчики, которые сидят за прокси, и им потребуется дополнительная конфигурация для виртуальной машины. У меня есть вещи, работающие на стороне марионетки: я могу передать IP-адрес прокси (если таковой имеется) как факт марионетке в Vagrantfile
и кукла реагирует соответственно, если это набор.
единственная проблема у меня есть: как разработчики могут указать / переопределить этот параметр для своей среды разработки без необходимости изменять Vagrantfile
(который находится под контролем версий и должен оставаться dev-environment-neutral)?
было бы здорово, если бы люди могли переопределить некоторые настройки Бродяги в файле под названием, например,Vagrantfile.local
, который я бы исключил через .gitignore
.
так как Vagrantfile - это просто Ruby, я попробовал следующее:
# Also load per-dev custom vagrant config
custom_vagrantfile = 'Vagrantfile.local'
load custom_vagrantfile if File.exist?(custom_vagrantfile)
включение файла в основном работает, но похоже, что в включенном файле я больше не в том же бродячем контексте...
Vagrant::Config.run do |config|
config.vm.provision :puppet do |puppet|
puppet.facter = { "proxy" => "proxy.host:80" }
end
end
... также "сбрасывает" все остальные значения конфигурации марионетки, которые я сделал в основном Vagrantfile
, что заставляет меня думать, что я иду в неправильном направлении здесь. Я должен отметить, что я полный нуб в Рубин ;)
может ли кто-нибудь дать мне подсказку или даже рабочее решение для того, как настройка per-dev может быть выполнена здесь генерал?
7 ответов:
Я бы предложил использовать переменные среды для динамического изменения поведения
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
этот пример исходит из https://github.com/puppetlabs/puppetlabs-openstack_dev_env
The
Vagrantfile
это просто Рубин, поэтому 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
тогда у меня есть (Я только что придумал ему имя, вы можете использовать любое имя, которое вам нравится) для разработчика конфигурации:
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
Если вы готовы определить настройки, которые применяются ко всем вашим коробкам vagrant, стоит отметить, что "Vagrant фактически загружает серию Vagrantfiles, объединяя настройки по мере их поступления."(ref https://docs.vagrantup.com/v2/vagrantfile/)
поэтому у меня есть следующее определение в
~/.vagrant.d/Vagrantfile
чтобы увеличить объем оперативной памяти для моих бродячих ящиков:Vagrant.configure(2) do |config| config.vm.provider "virtualbox" do |vb| vb.memory = 2048 end end
вот идея. Это может быть "некрасиво" и "неправильно", но, по крайней мере, это работает :)
# 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'
играем
$ ruby file1.rb first included external file which uses outer var: bar second
адаптация к вашему примеру, file2.РБ будет содержать только использование
config
без определения его (config
будет предоставлено из внешнего контекста)config.vm.provision :puppet do |puppet| puppet.facter = { "proxy" => "proxy.host:80" } end
и ваш бродячий файл может выглядеть так:
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
обновление (другой," управляемый данными " подход)
# 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
Я считаю, что это точный случай использования, что плагин Nugrant был создан, чтобы решить. Это позволяет каждому из ваших разработчиков иметь
.vagrantuser
(что является a .gitignore-ed file) в YAML, указывая пользовательские значения конфигурации, затем легко ссылаться на эти значения вVagrantfile
.в вашем случае, проксированный разработчик будет иметь их
.vagrantuser
файл выглядит так:proxy: 'proxy.host:80'
и свой
Vagrantfile
будет выглядеть так (псевдокод, я не знаю Рубин):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
вы должны связать образец / ссылку vagrantuser (т. е.
vagrantuser.example
) файл для ваших разработчиков, чтобы скопировать и настроить их среду.
чтобы продлить ответ @Willie Wheeler. Моя настройка:
Root |-- defaults.yml |-- env.yml |-- Vagrantfile
Vagrantfile
# 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"]
по умолчанию.в формате YML
vb: memory: 1024
env.в формате YML
vb: memory: 204
это объединит все значения по умолчанию, которые у вас есть с вашей конфигурацией per-dev. Также разработчикам понятно, какие значения они могут реально изменить
вы можете загрузить настройки из файла YAML. Это показано в Drupal VM как показано ниже:
# Use config.yml for basic VM configuration. require 'yaml' dir = File.dirname(File.expand_path(__FILE__)) if !File.exist?("#{dir}/config.yml") raise 'Configuration file not found! Please copy example.config.yml to config.yml and try again.' end vconfig = YAML::load_file("#{dir}/config.yml")
так что вы можете создать
config.yml
как:vagrant_box: geerlingguy/ubuntu1404 vagrant_user: vagrant vagrant_ip: 192.168.88.88
и
Vagrantfile
вы можете использовать переменные как:config.vm.box = vconfig['vagrant_box'] config.vm.network "private_network", ip: vconfig['vagrant_ip']