Tôi muốn chạy một tập lệnh bash trên máy chủ khi mơ hồ cung cấp máy chủ.
Điều gì sẽ là phương pháp tốt nhất để đạt được điều này?
Tôi muốn chạy một tập lệnh bash trên máy chủ khi mơ hồ cung cấp máy chủ.
Điều gì sẽ là phương pháp tốt nhất để đạt được điều này?
Câu trả lời:
Ít nhất hai plugin sẽ giúp:
Nếu bạn không quan tâm rằng tập lệnh được chạy trên (gần như) tất cả vagrant
các lệnh, bạn cũng có thể bỏ qua (hoặc sử dụng phép thuật ruby từng có) trong Vagrantfile:
system('./myscript.sh')
Vagrant.configure('2') do |config|
# ...
end
Kernel
mô-đun, được ghi lại ở đây . Các Kernel
mô-đun được bao gồm trong Object
lớp, vì vậy phương pháp của nó có sẵn trong tất cả các phạm vi.
(Tôi nói hoàn thành vì câu trả lời được chấp nhận không kiểm tra xem người dùng có đang sử dụng không. Do đó, tập lệnh được thực thi trên mỗi lệnh, đây không phải là điều OP muốn.)
Tuy nhiên, có một giải pháp đơn giản cho việc này.
ARGV[0]
là đối số đầu tiên của lệnh nhập và có thể up
, down
, status
, vv .. Đơn giản chỉ cần kiểm tra giá trị của ARGV[0]
trong Vagrantfile của bạn.
Một cái gì đó như thế này sẽ làm:
system("
if [ #{ARGV[0]} = 'up' ]; then
echo 'You are doing vagrant up and can execute your script'
./myscript.sh
fi
")
Vagrant.configure('2') do |config|
# ...
end
Đặt cái này gần đầu Vagrantfile của bạn:
module LocalCommand
class Config < Vagrant.plugin("2", :config)
attr_accessor :command
end
class Plugin < Vagrant.plugin("2")
name "local_shell"
config(:local_shell, :provisioner) do
Config
end
provisioner(:local_shell) do
Provisioner
end
end
class Provisioner < Vagrant.plugin("2", :provisioner)
def provision
result = system "#{config.command}"
end
end
end
Sau đó, chỉ cần gọi Vagrantfile của bạn như thế này:
config.vm.provision "list-files", type: "local_shell", command: "ls"
Và thông qua dòng lệnh như thế này:
vagrant provision --provision-with list-files
Đây là một loại hack vì nó trông giống như plugin, nhưng thực sự không phải vậy (nó sẽ không hiển thị khi bạn thực hiện vagrant plugin list
). Tôi không khuyên bạn nên làm theo cách này ngoại trừ việc nó không có lợi thế là không cần cài đặt plugin, vì vậy Vagrantfile của bạn sẽ hoạt động trên bất kỳ máy nào hỗ trợ phiên bản cấu hình mới nhất (phiên bản 2 khi viết bài này). Mặc dù nghe có vẻ khả thi, nhưng cũng có toàn bộ vấn đề đa nền tảng của lệnh thực tế bạn đang ban hành. Bạn sẽ cần cân nhắc nếu bạn muốn Vagrantfile có thể mang theo được, nhưng điều này sẽ giúp bạn bắt đầu.
Dựa trên câu trả lời của @ tmatilai nhưng được cập nhật vào năm 2019, các trình kích hoạt vagrant đã được sáp nhập vào Vagrant. Vì vậy, bây giờ bạn có thể làm một cái gì đó như vậy:
node.trigger.before [:up, :provision] do |trigger|
trigger.info = "Running ./myscript.sh locally..."
trigger.run = {path: "./myscript.sh"}
end
Khối này đi vào bên trong config.vm.define
. Tài liệu khác: https://www.vagrantup.com/docs/triggers/
config.vm.define
không phải là một yêu cầu; chúng có thể được đặt trong đó Vagrant.configure("2") do |config| ... end
là tốt. Như một điểm lưu ý cuối cùng, trên các máy chủ Windows, Vagrant cũng sẵn sàng thực thi các tập lệnh Powershell có .ps1
phần mở rộng.
Phù hợp với những gì @tmatilai nói về việc sử dụng
system('./myscript.sh')
Tôi thấy nó khá hữu ích cho các lệnh một lần như cài đặt các lệnh mơ hồ hoặc một số nhà cung cấp có thể không được cài đặt trong hệ thống. Tôi chỉ tránh nó chạy lại mỗi khi tôi gọi các vagrant
lệnh bằng cách thêm một sed để tự động nhận xét Vagrantfile
.
Ví dụ:
system('vagrant plugin install vagrant-fabric && (pip install fabric jinja2 || sudo pip install fabric jinja2) && sed -i -e "s/^system/#system/g" Vagrantfile')
Và tôi biến nó thành dòng đầu tiên của Vagrantfile. Bằng cách này, đầu tiên nó sẽ cài đặt plugin lang thang-vải, vải và jinja (sẽ cố gắng đầu tiên mà không sudo
cho virtualenvs
và với sudo
nếu có hỏng hóc) và sau đó là dòng bình luận riêng của mình.
if [[ $(vagrant plugin list | grep -c vagrant-host-shell) == "0" ]] then vagrant plugin install vagrant-host-shell fi
vagrant status
trước vagrant up
...