เรียกใช้สคริปต์บนเครื่องโฮสต์ระหว่างคนจรจัดขึ้น


40

ฉันต้องการเรียกใช้สคริปต์ทุบตีบนเครื่องโฮสต์เมื่อคนจัดระเบียบกำหนดเซิร์ฟเวอร์

อะไรจะเป็นวิธีที่ดีที่สุดในการบรรลุเป้าหมายนี้?

คำตอบ:


29

อย่างน้อยสองปลั๊กอินที่ควรช่วย:

หากคุณไม่สนใจว่าสคริปต์นั้นรันอยู่ (เกือบ) vagrantคำสั่งทั้งหมดคุณยังสามารถใช้คำสั่งเชลล์ (หรือใช้เวทมนตร์ ruby) ใน Vagrantfile:

system('./myscript.sh')

Vagrant.configure('2') do |config|
  # ...
end

2
ทริกเกอร์คนจรจัดดูเหมือนว่าสิ่งที่ฉันต้องการ
ดิจิตอล

คุณพบฟังก์ชันของระบบนี้ () ที่ใด ฉันไม่สามารถหาเอกสารเกี่ยวกับที่ใดก็ได้ ...
Cristiano Fontes

1
@CristianoFontes ก็ในKernelโมดูลการบันทึกไว้ที่นี่ Kernelโมดูลรวมอยู่ในObjectระดับดังนั้นวิธีการที่มีอยู่ในขอบเขตทั้งหมด
tmatilai

1
ฉันโง่ ฉันกำลังมองหาเอกสารร่อนเร่ ขอบคุณ!
Cristiano Fontes

26

โซลูชันที่ง่ายและสมบูรณ์

(ฉันบอกว่าสมบูรณ์เพราะคำตอบที่ยอมรับไม่ได้ตรวจสอบว่าผู้ใช้กำลังใช้คนพเนจรหรือไม่ดังนั้นสคริปต์จะถูกดำเนินการในแต่ละคำสั่งซึ่งไม่ใช่สิ่งที่ OP ต้องการ)

อย่างไรก็ตามมีวิธีง่ายๆในการนี้

ARGV[0]เป็นอาร์กิวเมนต์แรกของคำสั่งเข้ามาและสามารถup, down, statusฯลฯ .. เพียงแค่ตรวจสอบค่าของARGV[0]ใน Vagrantfile ของคุณ


สิ่งนี้จะทำ:

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
สวัสดีมิก ... คำตอบที่ดีขอบคุณสำหรับมัน แต่ฉันไม่สามารถรับได้ถ้า [# {ARGV [0]} = 'up']; ทำงานบน windows มันไม่เคยหาเรื่องหาเรื่อง
Cristiano Fontes

1
สิ่งนี้จะเรียกใช้งานสคริปต์ของคุณก่อนสิ่งอื่นใดทำงานโดยไม่คำนึงถึงสถานะใน Vagrantfile มันอาจจะเพียงพอสำหรับสิ่งที่คุณกำลังทำ แต่ปลั๊กอินตัวกระตุ้นคนจรจัดคือสิ่งที่ฉันต้องการ ...
Vigintas Labakojis

3
@CristianoFontes คุณสามารถทำการทดสอบ argv ใน ruby ​​นอกการเรียกของระบบและมันจะทำงานใน windows และ * ระวัง ฉันใช้สิ่งนี้เพื่อตั้งค่าตัวแปร ruby ​​โกลบอลที่ระบุว่าการจัดเตรียมเกิดขึ้นโดยการค้นหาคำสั่ง up หรือ provision บนบรรทัดคำสั่ง: ถ้า ARGV [0] = ~ / ^ up | บทบัญญัติ $ / i และไม่ใช่ ARGV.include? (" - ไม่มีการจัดเตรียม ") $ provisioning = เป็นจริงการจัดเตรียม $ = สิ้นสุดที่ผิด
Rhubarb

นี่เป็นวิธีปฏิบัติที่ไม่ดีตามคำแนะนำของ Vagrant คุณควรเขียนปลั๊กอินเพื่อขอคำสั่ง "up" คุณสามารถระบุใด ๆ ของ: ก่อน, หลัง, และรอบการดำเนินการ
SilentICE

1
@ เลือกจากเอกสาร Vagrant ( docs.vagrantup.com/v2/plugins/commands.html ) นอกจากนี้ยังทำให้สคริปต์ที่บอบบางเนื่องจากคุณไม่สามารถมั่นใจได้ว่าในกรณีโทร argv [0] เป็น 'ขึ้น' มากกว่าพูดธง นอกจากนี้หากคุณกำลังตกหลุมรักทับทิมดิบคุณกำลังแยกออกจากการห่อหุ้มที่กรอบควรจะให้ มีกลไกในการทำเช่นนี้อย่างถูกต้องดังนั้น IMHO คุณควรใช้สิ่งเหล่านั้นเมื่อเป็นไปได้
SilentICE

9

วางสิ่งนี้ไว้ที่ด้านบนสุดของไฟล์ Vagrant ของคุณ:

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

จากนั้นเพียงเรียกใช้ไฟล์ Vagrant ของคุณเช่นนี้:

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

และผ่านทางบรรทัดคำสั่งเช่นนี้:

vagrant provision --provision-with list-files

นี่เป็นแฮ็คที่ดูเหมือนปลั๊กอิน แต่จริงๆแล้วไม่ใช่ (มันจะไม่ปรากฏเมื่อคุณทำvagrant plugin list) ฉันไม่แนะนำให้ทำเช่นนี้ยกเว้นว่ามันจะมีข้อได้เปรียบที่ไม่จำเป็นต้องติดตั้งปลั๊กอินดังนั้น Vagrantfile ของคุณจะทำงานบนเครื่องใดก็ได้ที่รองรับการกำหนดค่าเวอร์ชันล่าสุด (รุ่น 2 เมื่อเขียนสิ่งนี้) แม้ว่าฟังดูเหมือนจะพกพาได้ดี แต่ก็ยังมีปัญหาข้ามแพลตฟอร์มทั้งหมดของคำสั่งจริงที่คุณกำลังออก คุณจะต้องคำนึงถึงว่าคุณต้องการให้ Vagrantfile ของคุณพกพาได้หรือไม่ แต่คุณควรเริ่มใช้งาน


1
คำตอบที่ดีฉันจะใช้สิ่งนี้เพื่อตั้งค่าการส่งต่อพอร์ตต่ำ
poindexter

6

จากคำตอบของ @ tmatilai แต่ได้รับการปรับปรุงสำหรับปี 2019 ทริกเกอร์คนเร่ร่อนได้ถูกรวมเข้ากับคนพเนจร ดังนั้นตอนนี้คุณสามารถทำสิ่งที่ต้องการ:

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

config.vm.defineบล็อกนี้ไปภายในของ เอกสารเพิ่มเติม: https://www.vagrantup.com/docs/triggers/


นี่คือคำตอบที่หรูหราที่สุดในปัจจุบัน ฉันควรเพิ่มว่าการวางตัวอย่างนี้และตัวอย่างที่คล้ายกันไว้ข้างในconfig.vm.defineนั้นไม่ใช่ข้อกำหนด พวกเขาสามารถวางไว้ภายในVagrant.configure("2") do |config| ... endเช่นกัน ในฐานะที่เป็นจุดสุดท้ายของการบันทึกบนโฮสต์ของ Windows Vagrant ยินดีที่จะใช้งานสคริปต์ Powershell ที่มี.ps1ส่วนขยายเช่นกัน
Ben Johnson

4

สอดคล้องกับสิ่งที่ @tmatilai พูดเกี่ยวกับการใช้

system('./myscript.sh')

ฉันพบว่ามันค่อนข้างมีประโยชน์สำหรับคำสั่งครั้งเดียวเช่นการติดตั้งคำสั่ง vagrant หรือตัวจัดสรรบางตัวที่อาจไม่ได้ติดตั้งในระบบ ฉันเพียงแค่หลีกเลี่ยงได้อีกครั้งการทำงานทุกครั้งที่ผมเรียกvagrantคำสั่งโดยการเพิ่ม sed Vagrantfileอัตโนมัติแสดงความคิดเห็น

ตัวอย่างเช่น:

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

และฉันทำบรรทัดแรกของ Vagrantfile ของฉัน วิธีนี้มันจะติดตั้งปลั๊กอินผ้าคนจรจัด, ผ้าและจินจา (จะลองก่อนโดยไม่ต้องsudoใช้virtualenvsและsudoถ้าล้มเหลว) และจากนั้นบรรทัดจะแสดงความคิดเห็นเอง


มันจะง่ายกว่าถ้าจะ grep vagrant plugins แทนการไม่ใส่เครื่องหมายในไฟล์ Vagrantfile ซึ่งอาจทำให้เกิดปัญหากับคนอื่น ๆ ในทีมของคุณ if [[ $(vagrant plugin list | grep -c vagrant-host-shell) == "0" ]] then vagrant plugin install vagrant-host-shell fi
Jordan

ปัญหานี้ก็คือว่ามันจะถูกเรียกในคำสั่งอื่น ๆ สิ่งที่ถ้าคุณทำงานvagrant statusก่อนvagrant up...
มิก
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.