¿Cómo pasar el parámetro en 'vagrant up' y tenerlo en el alcance de Vagrantfile?

85

Estoy buscando una forma de pasar un parámetro al libro de cocina de Chef como:

$ vagrant up some_parameter

Y luego úselo some_parameterdentro de uno de los libros de cocina del Chef.

Wojciech Bednarski
fuente

Respuestas:

112

No puedes pasar ningún parámetro a vagabundo. La única forma es usar variables de entorno

MY_VAR='my value' vagrant up

Y usar ENV['MY_VAR']en receta.

Draco Ater
fuente
1
¡Gracias! He intentado gist.github.com/4435297 y puedo conseguir la entrada del usuario, pero ni idea de cómo pasar en Chef libro de cocina. Ahora intentaré combinar esto con ENV
Wojciech Bednarski
6
Puede acceder a esa var ENV también en el Vagrantfile y ponerla en el hash chef.json (consulte docs.vagrantup.com/v1/docs/provisioners/… )
StephenKing
Sí, eso es más conveniente.
Draco Ater
5
El autor de vagrant mismo dice que use variables de entorno: github.com/mitchellh/vagrant/issues/2064
Alexander Bird
en PowerShell deberías usar algo así $ Env: MY_VAR = 'my value' | vagrant up
Alberto R.
70

También puede incluir la biblioteca GetoptLong Ruby que le permite analizar las opciones de la línea de comandos.

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

Entonces, puedes ejecutar:

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

Nota: asegúrese de que la opción personalizada esté especificada antes del comando vagrant para evitar un error de validación de opción no válida.

Más información sobre la biblioteca aquí .

Benjamin Gauthier
fuente
1
Lo estoy usando todo el día desde que publiqué. Funciona muy bien ! Cuál es tu problema ?
Benjamin Gauthier
13
Parece que las opciones no están enumeradas en el optsno procesado: vagrant --custom-option=option destroy -f vagrant: invalid option -- f
Renat Zaripov
2
Sí, esto funciona, y en mi humilde opinión es más elegante que la primera respuesta.
davidav
2
@BenjaminGauthier Los documentos dicen "La opción vacía - (dos símbolos menos) se usa para finalizar el procesamiento de opciones". Entonces vagrant --custom-option=option -- updebería ser suficiente
CESCO
2
Esto ya no funciona con Vagrant 2. No acepta ningún parámetro además del suyo.
Jens Baitinger
23

Es posible leer variables de ARGV y luego eliminarlas antes de pasar a la fase de configuración. Se siente repugnante modificar ARGV, pero no pude encontrar otra forma de opciones de línea de comandos.

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
fuente
Esto no parece funcionar para mí. Siempre obtengo el error Se especificó una opción no válida . Al hacerlo, se puts ARGVmuestra la matriz correcta después de eliminar los argumentos personalizados adicionales.
Majkinetor
1
Lo mismo aquí, no funciona ... Pongo una puts "#{ARGV}"línea vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/plugin/v2/command.rbe imprime esa línea antes de la eliminación de los argumentos relevantes en el Vagrantfile, lo que significa que la eliminación es inútil ya que el ARGV se pasa al validador que genera An invalid option was specifiedantes de cualquier las operaciones pueden tener lugar en ARGV.
BogdanSorlea
8

La solución GetoptLong de @ benjamin-gauthier es realmente genial, encaja bien con el paradigma rubí y vagabundo.

Sin embargo, necesita una línea adicional para arreglar el manejo limpio de los argumentos vagabundos, 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

lo que permite que este bloque de código se detenga cuando se procesan las opciones personalizadas. tan ahora, vagrant --custom-option up --provision o vagrant destroy -f se manejan limpiamente.

Espero que esto ayude,

Kannan Varadhan
fuente
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
Sofía
fuente