如何在'vagrant up'上传递参数并将其置于Vagrantfile的范围内?


Answers:


112

您不能将任何参数传递给无业游民。唯一的方法是使用环境变量

MY_VAR='my value' vagrant up

并用于ENV['MY_VAR']配方。


1
谢谢!我已经尝试过gist.github.com/4435297,我可以得到用户输入,但是不知道如何将其传递到Chef Cookbook。现在将尝试将其与ENV结合使用
Wojciech Bednarski 2013年

6
您也可以访问的环境变量在Vagrantfile,并把它放入chef.json哈希(见docs.vagrantup.com/v1/docs/provisioners/...
StephenKing

是的,这更方便。
Draco Ater

5
vagrant的作者本人说要使用环境变量:github.com/mitchellh/vagrant/issues/2064
Alexander Bird

在Powershell中,您应该使用类似$ Env:MY_VAR ='my value'的东西。无所事事
Alberto R.

70

您还可以包括GetoptLong Ruby库,该库允许您解析命令行选项。

流浪文件

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命令之前指定了custom选项,以避免无效的选项验证错误。

有关图书馆的更多信息,请点击此处


1
自发布以来,我整天都在使用它。效果很好!你怎么了 ?
Benjamin Gauthier

13
似乎这些选项未在opts未处理的列表中未列出:vagrant --custom-option=option destroy -f vagrant: invalid option -- f
Renat Zaripov 2015年

2
是的,这可行,而且恕我直言比第一个答案更优雅。
davidav'9

2
@BenjaminGauthier文档说“空选项-(两个减号)用于结束选项处理。”。所以vagrant --custom-option=option -- up应该足够了
CESCO

2
这不再适用于Vagrant 2。除了其自身之外,它不接受任何参数。
延斯·贝汀格

23

可以从ARGV读取变量,然后从变量中将其删除,然后再进入配置阶段。修改ARGV感觉很棘手,但我找不到命令行选项的其他任何方式。

流浪文件

# 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 2015年

1
同样在这里,它不起作用...我放了puts "#{ARGV}"一行,vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/plugin/v2/command.rb并在删除Vagrantfile中的相关args之前打印了该行,因此这意味着删除是徒劳的,因为ARGV传递给了验证器,该验证器An invalid option was specified在任何输出之前操作可以在ARGV上进行。
BogdanSorlea 2015年

8

@ benjamin-gauthier的GetoptLong解决方案确实很整洁,非常适合红宝石和无业游民的范例。

但是,它需要多一行来修正对无用参数的干净处理,例如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 --provisionvagrant 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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.