Jalankan skrip pada mesin host selama gelandangan naik

40

Saya ingin menjalankan skrip bash pada mesin host ketika gelandangan menyediakan server.

Apa yang akan menjadi metode terbaik untuk mencapai ini?

digital
sumber

Jawaban:

29

Setidaknya dua plugin yang akan membantu:

Jika Anda tidak peduli bahwa skrip dijalankan pada (hampir) semua vagrantperintah, Anda juga dapat langsung keluar (atau menggunakan apa pun ruby ​​magic) di Vagrantfile:

system('./myscript.sh')

Vagrant.configure('2') do |config|
  # ...
end
tmatilai
sumber
2
Pemicu vagina tampak seperti apa yang saya butuhkan.
digital
Di mana Anda menemukan fungsi system () ini? Saya tidak dapat menemukan dokumentasi tentang hal itu di mana pun ...
Cristiano Fontes
1
@CristianoFontes, ada di Kernelmodul, didokumentasikan di sini . The Kernelmodul termasuk dalam Objectkelas, sehingga metode yang tersedia di semua lingkup.
tmatilai
1
Bodohnya aku. Saya mencari di dokumentasi gelandangan. Terima kasih!
Cristiano Fontes
26

Solusi sederhana (dan lengkap)

(Saya katakan lengkap karena jawaban yang diterima tidak memeriksa apakah pengguna menggunakan gelandangan. Oleh karena itu, skrip dieksekusi pada setiap perintah, yang bukan yang diinginkan OP.)

Namun ada solusi sederhana untuk ini.

ARGV[0]adalah argumen pertama dari perintah masuk dan bisa up, down, status, dll .. Cukup memeriksa nilai ARGV[0]di Vagrantfile Anda.


Sesuatu seperti ini akan dilakukan:

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
Mick
sumber
1
Hai, Mick ... Jawaban yang bagus terima kasih untuk itu. Tapi saya tidak bisa mendapatkannya jika [# {ARGV [0]} = 'naik']; untuk bekerja di windows. Tidak pernah menemukan arg
Cristiano Fontes
1
Ini mengeksekusi skrip Anda terlebih dahulu sebelum hal lain berjalan terlepas dari posisinya di Vagrantfile. Mungkin cukup untuk apa yang Anda lakukan tetapi plugin yang memicu pemicu adalah apa yang saya butuhkan ...
Vigintas Labakojis
3
@CristianoFontes Anda dapat melakukan tes argv di ruby ​​di luar system call dan itu akan bekerja di windows dan * nix. Saya menggunakan ini untuk menetapkan variabel ruby ​​global yang menunjukkan bahwa penyediaan terjadi dengan mencari perintah ke atas atau ketentuan pada baris perintah: jika ARGV [0] = ~ / ^ up | ketentuan $ / i dan bukan ARGV. Termasuk? (" --tidak ada ketentuan ") $ provisioning = true else $ provisioning = false end
Rhubarb
Ini sebenarnya adalah praktik buruk seperti yang disarankan oleh Vagrant, Anda harus menulis sebuah plugin untuk menghubungkan ke perintah "atas", Anda dapat secara spesifik salah satu dari: sebelum, setelah, dan sekitar eksekusi.
SilentICE
1
@Mick hanya dari dokumen Vagrant ( docs.vagrantup.com/v2/plugins/commands.html ). Itu juga membuat skrip yang rapuh karena Anda tidak dapat memastikan bahwa dalam kasus panggilan, argv [0] lebih 'daripada mengatakan sebuah flag. Juga jika Anda masuk ke ruby ​​mentah Anda agak keluar enkapsulasi kerangka kerja seharusnya menyediakan. Ada mekanisme yang terpapar untuk melakukan ini dengan benar sehingga IMHO Anda harus menggunakannya kapan pun memungkinkan
SilentICE
9

Letakkan ini di dekat bagian atas Vagrantfile Anda:

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

Maka cukup panggil di Vagrantfile Anda seperti ini:

config.vm.provision "list-files", type: "local_shell", command: "ls"

Dan melalui baris perintah seperti ini:

vagrant provision --provision-with list-files

Ini jenis peretasan karena terlihat seperti plug-in, tetapi sebenarnya tidak (tidak akan muncul saat Anda melakukannya vagrant plugin list). Saya tidak menyarankan melakukannya dengan cara ini kecuali itu memiliki keuntungan karena tidak perlu menginstal plugin, sehingga Vagrantfile Anda akan bekerja pada mesin apa pun yang mendukung versi konfigurasi terbaru (versi 2 saat menulis ini). Meskipun kedengarannya sangat portabel, ada juga seluruh masalah lintas platform dari perintah aktual yang Anda keluarkan. Anda harus mempertimbangkan jika Anda ingin Vagrantfile Anda portabel, tetapi ini harus Anda mulai.

Joel B
sumber
1
Jawaban yang bagus, saya akan menggunakan ini untuk mengatur penerusan port rendah.
poindexter
6

Berdasarkan jawaban @ tmatilai tetapi diperbarui untuk 2019, pemicu gelandangan telah digabung menjadi Vagrant. Jadi sekarang Anda dapat melakukan sesuatu seperti:

node.trigger.before [:up, :provision] do |trigger|
  trigger.info = "Running ./myscript.sh locally..."
  trigger.run = {path: "./myscript.sh"}
end

Blok ini masuk dari config.vm.define. Dokumentasi lebih lanjut: https://www.vagrantup.com/docs/triggers/

Sean Hood
sumber
Ini adalah Jawaban paling elegan hingga saat ini. Saya harus menambahkan bahwa menempatkan ini dan cuplikan serupa di dalam config.vm.definebukanlah persyaratan; mereka dapat ditempatkan di dalam Vagrant.configure("2") do |config| ... endjuga. Sebagai catatan terakhir, pada host Windows, Vagrant dengan senang hati akan mengeksekusi skrip Powershell yang memiliki .ps1ekstensi juga.
Ben Johnson
4

Sejalan dengan apa yang dikatakan @tmatilai tentang penggunaan

system('./myscript.sh')

Saya menemukan itu cukup membantu untuk satu perintah kali seperti menginstal perintah gelandangan atau beberapa penyedia yang mungkin tidak diinstal dalam sistem. Saya hanya menghindarinya menjalankan kembali setiap kali saya menjalankan vagrantperintah dengan menambahkan sed ke komentar otomatis Vagrantfile.

Sebagai contoh:

system('vagrant plugin install vagrant-fabric && (pip install fabric jinja2 || sudo pip install fabric jinja2) && sed -i -e "s/^system/#system/g" Vagrantfile')

Dan saya membuatnya menjadi baris pertama Vagrantfile saya. Dengan cara ini pertama kali akan menginstal gelandangan-kain Plugin, kain dan jinja (akan mencoba pertama tanpa sudountuk virtualenvsdan dengan sudojika gagal) dan kemudian komentar baris itu sendiri.

kenorb
sumber
Akan lebih mudah untuk hanya memeriksa daftar plugin gelandangan daripada membatalkan komentar pada Vagrantfile, yang dapat menyebabkan masalah bagi orang lain di tim Anda. if [[ $(vagrant plugin list | grep -c vagrant-host-shell) == "0" ]] then vagrant plugin install vagrant-host-shell fi
Jordan
Masalah dengan ini adalah bahwa itu akan dipicu pada perintah lain, bagaimana jika Anda menjalankan vagrant statussebelumnya vagrant up...
Mick