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.
@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.
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