Como passar o parâmetro 'vagrant up' e colocá-lo no escopo do Vagrantfile?

86

Estou procurando uma maneira de passar parâmetros para o livro de receitas do Chef como:

$ vagrant up some_parameter

E, em seguida, use some_parameterdentro de um dos livros de receitas do Chef.

Wojciech Bednarski
fonte

Respostas:

113

Você não pode passar nenhum parâmetro para o vagrant. A única maneira é usar variáveis ​​de ambiente

MY_VAR='my value' vagrant up

E use ENV['MY_VAR']na receita.

Draco Ater
fonte
1
Obrigado! Tentei gist.github.com/4435297 e consigo obter a entrada do usuário, mas não tenho ideia de como passá-la para o livro de receitas do Chef. Agora tentarei combinar isso com ENV
Wojciech Bednarski
6
Você pode acessar esse ENV var também no Vagrantfile e colocá-lo no hash chef.json (consulte docs.vagrantup.com/v1/docs/provisioners/… )
StephenKing
Sim, isso é mais conveniente.
Draco Ater
5
O próprio autor do vagrant diz para usar variáveis ​​de ambiente: github.com/mitchellh/vagrant/issues/2064
Alexander Bird
no PowerShell você deve usar algo como $ Env: MY_VAR = 'meu valor' | vagabundo up
Alberto R.
70

Você também pode incluir a biblioteca GetoptLong Ruby que permite analisar opções de linha de comando.

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

Então, você pode executar:

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

Observação: certifique-se de que a opção personalizada seja especificada antes do comando vagrant para evitar um erro de validação de opção inválida.

Mais informações sobre a biblioteca aqui .

Benjamin Gauthier
fonte
1
Estou usando o dia todo desde que postei. Funciona muito bem ! Qual é o seu problema ?
Benjamin Gauthier
13
Parece que as opções não estão listadas no optsnão processado: vagrant --custom-option=option destroy -f vagrant: invalid option -- f
Renat Zaripov
2
Sim, funciona, e imho é mais elegante do que a primeira resposta.
Davidav 01 de
2
@BenjaminGauthier Os documentos dizem "A opção vazia - (dois símbolos de menos) é usada para encerrar o processamento da opção.". Então, vagrant --custom-option=option -- updeve ser o suficiente
CESCO de
2
Isso não funciona mais com o Vagrant 2. Ele não aceita nenhum parâmetro além do seu.
Jens Baitinger de
23

É possível ler as variáveis ​​do ARGV e removê-las dele antes de prosseguir para a fase de configuração. Parece nojento modificar o ARGV, mas não consegui encontrar outra forma de opções de linha de comando.

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
tsuriga
fonte
Isso não parece funcionar para mim. Sempre recebo o erro Uma opção inválida foi especificada . Fazendo puts ARGVexibe a matriz correta após a remoção de argumentos personalizados extras.
majkinetor,
1
Mesmo aqui, não funciona ... Eu coloco uma puts "#{ARGV}"linha vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/plugin/v2/command.rbe ela imprime essa linha antes da remoção dos args relevantes no Vagrantfile, o que significa que a remoção é fútil já que o ARGV é passado para o validador que retorna An invalid option was specifiedantes de qualquer as operações podem ocorrer em ARGV.
BogdanSorlea
8

A solução GetoptLong de @benjamin-gauthier é realmente legal, se encaixa bem no paradigma do rubi e do vagabundo.

No entanto, precisa de uma linha extra para corrigir o manuseio limpo dos argumentos vagrant, como 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

o que permite que este bloco de código faça uma pausa quando as opções personalizadas são processadas. então agora, vagrant --custom-option up --provision ou vagrant destroy -f são tratados de forma limpa.

Espero que isto ajude,

Kannan Varadhan
fonte
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
Sofia
fonte