Chạy script trên máy chủ trong khi di chuyển lên


40

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:


29

Í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ả vagrantcá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

2
Kích hoạt Vagrant trông giống như chính xác những gì tôi cần.
kỹ thuật số

Bạn đã tìm thấy hàm system () này ở đâu? Tôi không thể tìm thấy bất kỳ tài liệu nào về nó ở bất cứ đâu ...
Cristiano Fontes

1
@CristianoFontes, nó nằm trong Kernelmô-đun, được ghi lại ở đây . Các Kernelmô-đun được bao gồm trong Objectlớp, vì vậy phương pháp của nó có sẵn trong tất cả các phạm vi.
tmatilai 21/07/2015

1
Ngốc tôi Tôi đã tìm kiếm trong tài liệu mơ hồ. Cảm ơn!
Phông chữ Cristiano

26

Giải pháp đơn giản (và đầy đủ)

(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

1
Xin chào, Mick ... Câu trả lời tốt đẹp cảm ơn vì điều đó. Nhưng tôi không thể nhận được nếu [# {ARGV [0]} = 'up']; để làm việc trên windows. Nó không bao giờ tìm thấy arg
Cristiano Fontes

1
Điều này thực thi kịch bản của bạn trước tiên trước khi mọi thứ khác chạy bất kể vị trí của nó trong Vagrantfile. Nó có thể đủ cho những gì bạn đang làm nhưng plugin kích hoạt mơ hồ là những gì tôi cần ...
Vigintas Labakojis

3
@CristianoFontes bạn có thể thực hiện kiểm tra argv trong ruby ​​bên ngoài lệnh gọi hệ thống và nó sẽ hoạt động trong windows và * nix. Tôi sử dụng điều này để đặt biến ruby ​​toàn cầu cho biết việc cung cấp đang diễn ra bằng cách tìm kiếm lệnh tăng hoặc cung cấp trên dòng lệnh: if ARGV [0] = ~ / ^ up | cung cấp $ / i chứ không phải ARGV.include? (" --no-cung cấp ") $ cung cấp = đúng khác $ cung cấp = kết thúc sai
hoàng

Đây thực sự là một thực hành tồi như lời khuyên của Vagrant, bạn nên viết một plugin để nối vào lệnh "lên", bạn có thể chỉ định bất kỳ: trước, sau và xung quanh thực thi.
Im lặng

1
@Mick chỉ từ tài liệu Vagrant ( docs.vagrantup.com/v2/plugins/commands.html ). Nó cũng tạo ra một tập lệnh dễ vỡ vì bạn không thể chắc chắn rằng trong các trường hợp cuộc gọi argv [0] là 'lên' thay vì nói một cờ. Ngoài ra, nếu bạn rơi vào viên ruby ​​thô, bạn sẽ phá vỡ sự đóng gói mà khung được cho là sẽ cung cấp. Có các cơ chế được thực hiện để làm điều này một cách chính xác, vì vậy IMHO bạn nên sử dụng chúng bất cứ khi nào có thể
Im lặng

9

Đặ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.


1
Câu trả lời hay, tôi sẽ sử dụng điều này để thiết lập chuyển tiếp cổng thấp.
poindexter

6

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/


Đây là câu trả lời thanh lịch nhất cho đến nay. Tôi nên thêm rằng việc đặt đoạn mã này và các đoạn tương tự bên trong config.vm.definekhông phải là một yêu cầu; chúng có thể được đặt trong đó Vagrant.configure("2") do |config| ... endlà 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ó .ps1phần mở rộng.
Ben Johnson

4

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 vagrantlệ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 sudocho virtualenvsvà với sudonếu có hỏng hóc) và sau đó là dòng bình luận riêng của mình.


Nó sẽ dễ dàng hơn chỉ đơn giản là danh sách các plugin grant vagrant thay vì không chú ý đến Vagrantfile, điều này có thể gây ra vấn đề cho những người khác trong nhóm của bạn. if [[ $(vagrant plugin list | grep -c vagrant-host-shell) == "0" ]] then vagrant plugin install vagrant-host-shell fi
Jordan

Vấn đề với điều này là nó sẽ được kích hoạt trên các lệnh khác, nếu bạn chạy vagrant statustrước vagrant up...
Mick
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.