如何通过参数’流浪者’,并有它在 Vagrantfile 的范围?

我正在寻找一种方法来传递参数到厨师烹饪书像:

$ vagrant up some_parameter

然后在一本 Chef 烹饪书中使用 some_parameter

44368 次浏览

You cannot pass any parameter to vagrant. The only way is to use environment variables

MY_VAR='my value' vagrant up

And use ENV['MY_VAR'] in recipe.

It is possible to read variables from ARGV and then remove them from it before proceeding to configuration phase. It feels icky to modify ARGV but I couldn't find any other way for command-line options.

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

You also can include the GetoptLong Ruby library that allows you to parse command line options.

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

Then, you can run :

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

Note: Make sure that the custom option is specified before the vagrant command to avoid an invalid option validation error.

More information about the library here.

@benjamin-gauthier 's GetoptLong solution is really neat, fits in with the ruby and vagrant paradigm well.

It however, needs one extra line to fix clean handling of the vagrant arguments, such as 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

which allows this block of code to pause when the custom options are processed. so now, vagrant --custom-option up --provision or vagrant destroy -f are cleanly handled.

Hope this helps,

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