Как передать параметр на "бродяга" и включить его в Vagrantfile?

85

Я ищу способ передать параметр в поваренную книгу Chef, например:

$ vagrant up some_parameter

А затем используйте some_parameterв одной из кулинарных книг шеф-повара.

Войцех Беднарски
источник

Ответы:

112

Вы не можете передать какой-либо параметр vagrant. Единственный способ - использовать переменные среды

MY_VAR='my value' vagrant up

И использовать ENV['MY_VAR']в рецепте.

Драко Атер
источник
1
Благодарность! Я пробовал gist.github.com/4435297, и я могу получить ввод пользователя, но не знаю, как передать его в поваренную книгу Chef. Сейчас попробую совместить это с ENV
Войцех Беднарски
6
Вы можете получить доступ к этой переменной ENV также в файле Vagrantfile и поместить ее в хэш chef.json (см. Docs.vagrantup.com/v1/docs/provisioners/… )
StephenKing 02
Да, так удобнее.
Draco Ater
5
Сам автор vagrant говорит, что нужно использовать переменные окружения: github.com/mitchellh/vagrant/issues/2064
Александр Берд
в PowerShell вы должны использовать что-то вроде этого $ Env: MY_VAR = 'my value' | vagrant up
Альберто Р.
70

Вы также можете включить библиотеку GetoptLong Ruby, которая позволяет анализировать параметры командной строки.

Vagrantfile

require 'getoptlong'

opts = GetoptLong.new(
  [ '--custom-option', GetoptLong::OPTIONAL_ARGUMENT ]
)

customParameter=''

opts.each do |opt, arg|
  case opt
    when '--custom-option'
      customParameter=arg
  end
end

Vagrant.configure("2") do |config|
             ...
    config.vm.provision :shell do |s|
        s.args = "#{customParameter}"
    end
end

Затем вы можете запустить:

$ vagrant --custom-option=option up
$ vagrant --custom-option=option provision

Примечание. Убедитесь, что настраиваемая опция указана перед командой vagrant, чтобы избежать ошибки проверки недопустимой опции.

Подробнее о библиотеке здесь .

Бенджамин Готье
источник
1
Пользуюсь им весь день с момента публикации. Работает очень хорошо! В чем твоя проблема ?
Benjamin Gauthier
13
Похоже, что варианты не указаны в optsнеобработанном: vagrant --custom-option=option destroy -f vagrant: invalid option -- f
Ренат Зарипов
2
Да, это работает, и имхо более элегантно, чем первый ответ.
Давидав 01
2
@BenjaminGauthier В документации говорится: «Пустая опция - (два символа минус) используется для завершения обработки опции.». Так что vagrant --custom-option=option -- upдолжно быть достаточно
CESCO
2
Это больше не работает с Vagrant 2. Он не принимает никаких параметров, кроме своих собственных.
Jens Baitinger
23

Можно считать переменные из ARGV, а затем удалить их из него, прежде чем перейти к этапу настройки. Кажется неприятным изменять ARGV, но я не мог найти другого способа для параметров командной строки.

Vagrantfile

# Parse options
options = {}
options[:port_guest] = ARGV[1] || 8080
options[:port_host] = ARGV[2] || 8080
options[:port_guest] = Integer(options[:port_guest])
options[:port_host] = Integer(options[:port_host])

ARGV.delete_at(1)
ARGV.delete_at(1)

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # Create a forwarded port mapping for web server
  config.vm.network :forwarded_port, guest: options[:port_guest], host: options[:port_host]

  # Run shell provisioner
  config.vm.provision :shell, :path => "provision.sh", :args => "-g" + options[:port_guest].to_s + " -h" + options[:port_host].to_s

 

Provision.sh

port_guest=8080
port_host=8080

while getopts ":g:h:" opt; do
    case "$opt" in
        g)
            port_guest="$OPTARG" ;;
        h)
            port_host="$OPTARG" ;;
    esac
done
цурига
источник
Похоже, у меня это не работает. Я всегда получаю сообщение об ошибке. Указана неверная опция . Выполнение puts ARGVотображает правильный массив после удаления дополнительных настраиваемых аргументов.
majkinetor
1
То же самое здесь, это не работает ... Я вставляю puts "#{ARGV}"строку, vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/plugin/v2/command.rbи она печатает эту строку перед удалением соответствующих аргументов в Vagrantfile, что означает, что удаление бесполезно, поскольку ARGV передается валидатору, который выводит An invalid option was specifiedперед любым операции могут проходить на ARGV.
BogdanSorlea
8

Решение GetoptLong от @ benjamin-gauthier действительно изящное, хорошо вписывается в парадигму рубина и бродяг.

Однако ему нужна одна дополнительная строка, чтобы исправить чистую обработку бродячих аргументов, таких как vagrant destroy -f.

require 'getoptlong'

opts = GetoptLong.new(
  [ '--custom-option', GetoptLong::OPTIONAL_ARGUMENT ]
)

customParameter=''

opts.ordering=(GetoptLong::REQUIRE_ORDER)   ### this line.

opts.each do |opt, arg|
  case opt
    when '--custom-option'
      customParameter=arg
  end
end

что позволяет приостанавливать этот блок кода при обработке пользовательских параметров. так что сейчас vagrant --custom-option up --provision или vagrant destroy -f аккуратно обращаются.

Надеюсь это поможет,

Каннан Варадхан
источник
1
Vagrant.configure("2") do |config|

    class Username
        def to_s
            print "Virtual machine needs you proxy user and password.\n"
            print "Username: " 
            STDIN.gets.chomp
        end
    end

    class Password
        def to_s
            begin
            system 'stty -echo'
            print "Password: "
            pass = URI.escape(STDIN.gets.chomp)
            ensure
            system 'stty echo'
            end
            pass
        end
    end

    config.vm.provision "shell", env: {"USERNAME" => Username.new, "PASSWORD" => Password.new}, inline: <<-SHELL
        echo username: $USERNAME
        echo password: $PASSWORD
SHELL
    end
end
София
источник