Передайте змінні середовища бродячому постачальнику оболонки


77

Схоже, передача змінних середовища під час виклику vagrant upпроста, якщо ви використовуєте провайдер Ruby:

VAR=123 vagrant up

У файлі Vagrant:

ENV['VAR']

Як це зробити з :shellпровізором? Просто робити це, здається, не працює:

$VAR

Відповіді:


81

З Vagrant 1.8.0 ви можете забути потворні хаки з інших відповідей тут. Просто використовуйте envопцію для постачальника оболонки ( docs ).

Використовуйте його так у вашому файлі Vagrant:

config.vm.provision "shell", path: "provisionscript.sh", env: {"MYVAR" => "value"}

Це встановить середовище лише для сценарію підготовки. Якщо вам потрібен постійний набір змінних середовища для всіх процесів у віртуальній машині, це виходить за рамки надання Vagrant і дивіться тут: Змінні середовища оболонки у файлах бродяги передаються лише спочатку .


У Vagrant 1.8.5, envздається , параметр працює лише при використанні pathсценарію, а не inlineсценарію.
шпиль

1
@spyle Я запускаю Vagrant 1.8.5 (з VirtualBox 5.1.2 на Mac OS X 10.11.6) і працюю envз inline.
jonatan

Хм ... мені чогось тут не вистачає? Це не працює для мене: config.vm.provision :shell, path: "bootstrap.sh", env: {"MYSQL_DB_USERNAME"=>"django", "MYSQL_DB_PASSWORD"=>"supersecretpasswordwasreplaced"} з іншого боку os.environ['MYSQL_DB_USERNAME'] видає ключову помилку :(
Tadhg

1
@Tadhg Перевірте свою версію Vagrant. І, можливо, задати нове запитання, якщо воно не працює? Це може бути не пов’язана проблема (наприклад, версія Vagrantfile або середовище, яке не збережено у вашому ланцюжку інструментів).
gertvdijk

Версія хороша. Ви маєте рацію, дивлячись на документ, здається, що ця конфігурація повинна працювати лише під час підготовки, тому я поставив це як нове питання stackoverflow.com/questions/40270391/…
Tadhg

42

Це не ідеально, але поки що я працюю так:

config.vm.provision "shell" do |s|
    s.inline = "VAR1 is $1 and VAR2 is $2"
    s.args   = "#{ENV['VAR1']} #{ENV['VAR2']}"
end

3
Ви також можете замінити s.inlineна s.pathі використовувати той же сценарій , ви б пройшли з :path => "". (Мій
постачальник

3
Як варіант, використовуючи метод ruby ​​з :args => ""параметром, приблизно так .
msanford

4
Чи справді у вас повинна бути кома всередині s.args?
Маріус Гедмінас

17

Для нащадків (він же на випадок, якщо я знову загуглю) ... Можна передати пари ключ-значення через env :

box.vm.provision :shell do |s|
  s.env = {AWS_ACCESS_KEY:ENV['AWS_ACCESS_KEY'], AWS_SECRET_KEY:ENV['AWS_SECRET_KEY']}
  s.path = 'scripts/bootstrap.sh'
end

Потім згадайте їх у своєму сценарії:

export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_KEY}

Бонусна функція:

Vagrant буде обробляти цитування значень змінних середовища, але клавіші залишаються недоторканими


Дивіться також відповідь, опубліковану @gertvdijk (у мене не було оновлення сторінки при розміщенні)
Аль Бельський

16

Я запропонував це рішення для підготовки на основі CentOS: розміщення всіх необхідних змінних середовища у /etc/profile.d/vagrant.shфайлі, а потім доступ до них у будь-якому сценарії надання.

коротко:

  $before_script = <<SCRIPT
  echo # vagrant profile script > /etc/profile.d/vagrant.sh
  echo export ENV_VAR1=foo.com/bar >> /etc/profile.d/vagrant.sh
  echo export ENV_VAR2=bar.com/foo >> /etc/profile.d/vagrant.sh
  chmod +x /etc/profile.d/vagrant.sh
SCRIPT

  $after_script = <<SCRIPT
    rm -rf /etc/profile.d/vagrant.sh
SCRIPT

  config.vm.provision "shell", inline: $before_script
  config.vm.provision "shell", path: "build.sh"
  config.vm.provision "shell", inline: $after_script

Повний текст Vagrantfileможна знайти тут https://gist.github.com/bivas/6192d6e422f8ff87c29d


Працює у мене під Linux (для віртуальних машин на базі Ubuntu). Чудово!
Нікос Александріс

1
Проте зараз існує vagrantup.com/docs/provisioning/shell.html#env . Я це бачив, але через відсутність прикладів пропустив. Колега зазначив, що це працює.
Нікос Александріс

1
@NikosAlexandris: Подивіться мою відповідь :)
gertvdijk

8

Ви можете використовувати #{ENV['VAR']}всередині вбудованого сценарію, наприклад:

config.vm.provision "shell", inline: <<-END
  ...
  # Install my dotfiles are there.  If you're in a hurry you can do
  # SKIP_DOTFILES=1 vagrant up
  if ! [ -d /home/vagrant/dotfiles ] && [ -z '#{ENV['SKIP_DOTFILES']}']; then
    if ! [ -x /usr/bin/git ]; then
      DEBIAN_FRONTEND=noninteractive apt-get install -y git
    fi
    su - vagrant -c 'git clone https://github.com/mgedmin/dotfiles'
    su - vagrant -c 'dotfiles/install.sh'
  fi
  ...
  END

Приклад взято з робочого файлу Vagrant.

У цього є деякі недоліки: якщо $ VAR містить одинарні лапки, все зламається.


Звичайно, я помічаю, що @Bob по суті надав ту саму відповідь (у біті NEW WAY) відразу після того, як я опублікував свою. Ой!
Маріус Гедмінас

7

Якщо хтось в кінцевому підсумку шукає, як встановити змінні в середовищі сценарію підготовки, це спрацювало для мене.

config.vm.provision :shell, :inline => <<-SH
  export GRAPHITE_HOST=192.168.33.10
  /vagrant/install_app_with_monitoring.sh
SH

Зверніть увагу, що це передбачає, що ви ділитесь своїм робочим каталогом як /vagrantна віртуальній машині, але це має бути за замовчуванням.


але чому б цього не зробити всередині install_app_with_monitoring.sh?
Stephan Bijzitter

В основному, щоб зберегти знання там же. Ви можете побачити приклад тут github.com/forty9ten/monitoring-with-graphite/blob/master/... Зберігаючи var у файлі Vagrant, легко забезпечити паритет між private_networkі GRAPHITE_HOST. Можна навіть зробити крок далі і використовувати export GRAPHITE_HOST=#{ip}для посилання на єдиний загальний рубіновий var.
Mat Schaffer

5

Більшість із цих відповідей застарілі. З Vagrant 2.1.1 це мені вдалося:

  VAGRANTFILE_API_VERSION = "2" //...

  machine.vm.provision "shell", 
    env: {
      "ELASTIC_XMS" => servers["elastic"]["memory_xms"], 
      "ELASTIC_XMX" => servers["elastic"]["memory_xmx"]
    }, 
    inline: "sed -i -e \"s/-Xms.*/$ELASTIC_XMS/g\" /etc/elasticsearch/jvm.options"

2

Бродяга-окр плагін робить саме це. За допомогою нього ви можете додавати змінні середовища до .envфайлу в локальному каталозі, який буде завантажений у Vagrantфайл. Я пропоную зберігати .envу вашому .gitignore, таким чином ви гарантуєте вашу конфіденційність.


1
Плагін помер ще у 2015 році, це не зараз.
Лігемер,

1

Ось як у мене це працює.

Я перейшов від використання бродячого маріонеткового способу до простого використання снаряда оболонки. Я зробив це головним чином тому, що хотів, щоб маріонетка не запускалася як root, постачальник оболонки дає вам: privileged => false.

МОЙ СТАРИЙ ШЛЯХ:

config.vm.provision :puppet do |puppet|
  puppet.module_path = ENV.fetch('MODULES_PATH', 'modules')
  puppet.manifests_path = ENV.fetch('MANIFESTS_PATH', 'manifests')
  puppet.manifest_file  = ENV.fetch('MANIFEST_FILE', 'site.pp')
  puppet.options = "--debug"
end

МОЙ НОВИЙ ШЛЯХ:

config.vm.provision :shell, :privileged => false do |shell|
  shell.inline = "puppet apply --debug --modulepath '/vagrant/#{ENV.fetch('MODULES_PATH', 'modules')}' --detailed-exitcodes '/vagrant/#{ENV.fetch('MANIFESTS_PATH', 'manifests')}/#{ENV.fetch('MANIFEST_FILE', 'site.pp')}'"
end

1

Ви можете просто вказати для shellвикористанняinline у своєму Vagrantfileфайлі:

config.vm.provision "shell", inline: %Q(/usr/bin/env FOO=1 BAR=1 bash /path/to/script.sh)

Або завантажте додаткові змінні з файлу YAML:

require 'yaml'
dir = File.dirname(File.expand_path(__FILE__))
vconfig = YAML::load_file("#{dir}/config.yml")
config.vm.provision "shell", inline: %Q(/usr/bin/env FOO=#{vconfig['foo']} bash /path/to/script.sh)

Крім того, ви можете реалізувати деякі додаткові аргументи з командного рядка, наприклад:

# Parse optional arguments.
opts = GetoptLong.new(
  [ '--foo',  GetoptLong::OPTIONAL_ARGUMENT ], # With optional parameter.
  [ '--bar',  GetoptLong::OPTIONAL_ARGUMENT ], # With optional parameter.files.
)
opts.each do |opt, arg|
  case opt
    when '--foo'
      foo==arg
    when '--bar'
      bar=arg
  end
end

потім використовувати: opt['--foo'].to_s.

Дивіться також: Як передати параметр на Vagrant і включити його в обсяг кулінарної книги шеф-кухаря?


-2

це спрацювало для мене

VAGRANTFILE_API_VERSION = "2"

kettle_dir = ENV['KETTLE_DIR']
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
   config.vm.synced_folder kettle_dir, "/pentaho"
   config.vm.box = "ubuntu/trusty64"
end

Чи можете ви дещо детальніше вказати, чому це правильна відповідь?
rfornal

Тут використовується змінна середовища у файлі Vagrant, але насправді не встановлюється така для постачальника, як задано у питанні.
btubbs

-3

На коробці ubutnu я просто зробив наступне у своєму bootstrap.sh:

echo "DBHOST=localhost" >> /etc/environment
echo "DBNAME=foo" >> /etc/environment
echo "DBUSER=root" >> /etc/environment
echo "DBPASSWD=root" >> /etc/environment
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.