Tôi đang tìm cách truyền tham số vào sách nấu ăn Chef như:
$ vagrant up some_parameter
Và sau đó sử dụng some_parameter
bên trong một trong các sách nấu ăn Chef.
Tôi đang tìm cách truyền tham số vào sách nấu ăn Chef như:
$ vagrant up some_parameter
Và sau đó sử dụng some_parameter
bên trong một trong các sách nấu ăn Chef.
Câu trả lời:
Bạn không thể chuyển bất kỳ tham số nào cho vagrant. Cách duy nhất là sử dụng các biến môi trường
MY_VAR='my value' vagrant up
Và sử dụng ENV['MY_VAR']
trong công thức.
Bạn cũng có thể bao gồm thư viện GetoptLong Ruby cho phép bạn phân tích cú pháp các tùy chọn dòng lệnh.
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
Sau đó, bạn có thể chạy:
$ vagrant --custom-option=option up
$ vagrant --custom-option=option provision
Lưu ý: Đảm bảo rằng tùy chọn tùy chỉnh được chỉ định trước lệnh vagrant để tránh lỗi xác thực tùy chọn không hợp lệ.
Thông tin thêm về thư viện tại đây .
opts
không được xử lý: vagrant --custom-option=option destroy -f
vagrant: invalid option -- f
vagrant --custom-option=option -- up
nên có đủ
Có thể đọc các biến từ ARGV và sau đó xóa chúng khỏi nó trước khi tiếp tục giai đoạn cấu hình. Thật khó để sửa đổi ARGV nhưng tôi không thể tìm thấy bất kỳ cách nào khác cho các tùy chọn dòng lệnh.
# 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
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
hiển thị mảng chính xác sau khi loại bỏ các đối số tùy chỉnh bổ sung.
puts "#{ARGV}"
dòng vào vagrant/embedded/gems/gems/vagrant-1.7.2/lib/vagrant/plugin/v2/command.rb
và nó in dòng đó trước khi xóa các vòng có liên quan trong Vagrantfile, do đó có nghĩa là việc xóa là vô ích vì ARGV được chuyển cho trình xác thực xuất An invalid option was specified
trước bất kỳ hoạt động có thể diễn ra trên ARGV.
Giải pháp GetoptLong của @ benjamin-gauthier thực sự rất gọn gàng, rất phù hợp với mô hình ruby và vagrant.
Tuy nhiên, nó cần thêm một dòng để khắc phục việc xử lý sạch sẽ các đối số mơ hồ, chẳng hạn như 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
cho phép khối mã này tạm dừng khi các tùy chọn tùy chỉnh được xử lý. vì vậy bây giờ,
vagrant --custom-option up --provision
hoặc
vagrant destroy -f
được xử lý sạch sẽ.
Hi vọng điêu nay co ich,
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