如何在“vagrant up”上传递参数并将其置于 Vagrantfile 的范围内?
Posted
技术标签:
【中文标题】如何在“vagrant up”上传递参数并将其置于 Vagrantfile 的范围内?【英文标题】:How to pass parameter on 'vagrant up' and have it in the scope of Vagrantfile? 【发布时间】:2012-12-16 22:46:41 【问题描述】:我正在寻找一种将参数传递给 Chef 食谱的方法,例如:
$ vagrant up some_parameter
然后在其中一本 Chef 食谱中使用 some_parameter
。
【问题讨论】:
【参考方案1】:您不能将任何参数传递给 vagrant。唯一的办法就是使用环境变量
MY_VAR='my value' vagrant up
并在配方中使用ENV['MY_VAR']
。
【讨论】:
谢谢!我已经尝试过gist.github.com/4435297,我可以获得用户输入,但不知道如何将其传递给 Chef 食谱。现在将尝试将其与 ENV 结合起来 您也可以在 Vagrantfile 中访问该 ENV var 并将其放入 chef.json 哈希中(请参阅docs.vagrantup.com/v1/docs/provisioners/…) 是的,这样更方便。 vagrant的作者自己说要使用环境变量:github.com/mitchellh/vagrant/issues/2064 在powershell中你应该使用类似 $Env:MY_VAR='my value' |流浪【参考方案2】:您还可以包含允许您解析命令行选项的 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 命令之前指定自定义选项以避免无效选项验证错误。
更多关于图书馆的信息here。
【讨论】:
自从我发布以来,我整天都在使用它。它工作得很好!你有什么问题? 似乎选项没有列在opts
未处理:vagrant --custom-option=option destroy -f
vagrant: invalid option -- f
是的,这行得通,而且恕我直言比第一个答案更优雅。
@BenjaminGauthier 文档说“空选项——(两个减号)用于结束选项处理。”。所以vagrant --custom-option=option -- up
应该够了
这不再适用于 Vagrant 2。除了自己的参数之外,它不接受任何参数。【参考方案3】:
可以从 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
会在删除额外的自定义参数后显示正确的数组。
这里一样,它不起作用...我在vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/plugin/v2/command.rb
中放了一个puts "#ARGV"
行,它在删除Vagrantfile 中的相关参数之前打印该行,因此意味着删除是徒劳的,因为 ARGV 会在 ARGV 上进行任何操作之前传递给输出 An invalid option was specified
的验证器。【参考方案4】:
@benjamin-gauthier 的 GetoptLong 解决方案非常简洁,非常适合 ruby 和 vagrant 范例。
但是,它需要多一行来修复对 vagrant 参数的干净处理,例如 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
处理干净。
希望对你有帮助,
【讨论】:
【参考方案5】: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
【讨论】:
这是一个很好的解决方案,但你能展示如何以非交互方式使用它吗?例如,是否可以通过管道传输参数?以上是关于如何在“vagrant up”上传递参数并将其置于 Vagrantfile 的范围内?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Java 中添加组件并将其置于 JFrame 的前面?
如何在 Linux 上的 X Window System 中找到一个窗口并将其置于最前面?
React GraphQL Apollo 和 Redux。如何查询数据并将其置于 store 的 initialState 中?