Esegui lo script sul computer host durante il vagrant up


40

Vorrei eseguire uno script bash sul computer host quando vagabondi effettua il provisioning del server.

Quale sarebbe il metodo migliore per raggiungere questo obiettivo?

Risposte:


29

Almeno due plugin che dovrebbero aiutare:

Se non ti interessa che lo script venga eseguito su (quasi) tutti i vagrantcomandi, puoi anche sborsare (o usare qualsiasi cosa ruby ​​magic) in Vagrantfile:

system('./myscript.sh')

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

2
I trigger vagabondi sembrano esattamente ciò di cui ho bisogno.
digitale

Dove hai trovato questa funzione di sistema ()? Non riesco a trovare alcuna documentazione al riguardo da nessuna parte ...
Cristiano Fontes,

1
@CristianoFontes, è nel Kernelmodulo, documentato qui . Il Kernelmodulo è incluso nella Objectclasse, quindi i suoi metodi sono disponibili in tutti gli ambiti.
tmatilai,

1
Che stupido. Stavo cercando nella documentazione vagabonda. Grazie!
Cristiano Fontes,

26

Soluzione semplice (e completa)

(Dico completo perché la risposta accettata non verifica se l'utente sta usando Vagrant up. Pertanto, lo script viene eseguito su ogni comando, che non è quello che l'OP vuole.)

C'è comunque una soluzione semplice a questo.

ARGV[0]è il primo argomento del comando immesso e può essere up, down, status, ecc .. Basta controllare il valore di ARGV[0]nel vostro Vagrantfile.


Qualcosa del genere farà:

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
Ciao Mick ... Bella risposta grazie per questo. Ma non riesco a capire se [# {ARGV [0]} = 'up']; lavorare su windows. Non trova mai l'arg
Cristiano Fontes,

1
Questo esegue la tua sceneggiatura prima di tutto, indipendentemente dalla sua posizione in Vagrantfile. Potrebbe essere sufficiente per quello che stai facendo, ma il plug
Vagrant-Triggers

3
@CristianoFontes è possibile eseguire il test argv in ruby ​​al di fuori della chiamata di sistema e funzionerà in Windows e * Nix. Uso questo per impostare una variabile ruby ​​globale che indica che il provisioning sta avvenendo cercando il comando up o provision nella riga di comando: se ARGV [0] = ~ / ^ up | provision $ / ie non ARGV.include? (" --no-provision ") $ provisioning = true else $ provisioning = false end
Rabarbaro

Questa è in realtà una cattiva pratica come consigliato da Vagrant, dovresti scrivere un plug-in da agganciare al comando "su", puoi specificarne uno qualsiasi: prima, dopo e intorno all'esecuzione.
SilentICE,

1
@Mick è solo dai documenti di Vagrant ( docs.vagrantup.com/v2/plugins/commands.html ). Inoltre crea uno script fragile poiché non si può essere certi che nei casi call argv [0] sia "attivo" anziché dire una bandiera. Inoltre, se stai entrando nel rubino grezzo, stai quasi rompendo l'incapsulamento che il framework dovrebbe fornire. Ci sono meccanismi esposti per farlo correttamente, quindi IMHO dovresti usarli quando possibile
SilentICE il

9

Metti questo vicino alla cima del tuo Vagrantfile:

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

Quindi invoca semplicemente il tuo Vagrantfile in questo modo:

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

E tramite la riga di comando in questo modo:

vagrant provision --provision-with list-files

Questo è un tipo di hack in quanto sembra un plug-in, ma in realtà non lo è (non verrà visualizzato quando lo fai vagrant plugin list). Non consiglio di farlo in questo modo, tranne per il fatto che ha il vantaggio di non dover installare un plugin, quindi il tuo Vagrantfile funzionerà su qualsiasi macchina che supporti l'ultima versione di configurazione (versione 2 al momento della stesura di questo). Anche se sembra promettentemente portatile, c'è anche l'intero problema multipiattaforma del comando effettivo che stai emettendo. Dovrai prendere in considerazione se vuoi che il tuo Vagrantfile sia portatile, ma questo dovrebbe iniziare.


1
Buona risposta, userò questo per impostare il port forwarding basso.
poindexter,

6

Basato sulla risposta di @ tmatilai ma aggiornato per il 2019, i trigger di Vagrant sono stati fusi in Vagrant. Quindi ora puoi fare qualcosa del genere:

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

Questo blocco va dentro config.vm.define. Ulteriore documentazione: https://www.vagrantup.com/docs/triggers/


Questa è la risposta più elegante fino ad oggi. Vorrei aggiungere che inserire questo e frammenti simili all'interno config.vm.definenon è un requisito; possono anche essere inseriti all'interno Vagrant.configure("2") do |config| ... end. Come ultimo punto da notare, su host Windows, Vagrant eseguirà volentieri anche gli script Powershell che hanno l' .ps1estensione.
Ben Johnson,

4

In linea con quanto affermato da @tmatilai sull'uso

system('./myscript.sh')

L'ho trovato abbastanza utile per i comandi di una volta come l'installazione di comandi vagabondi o alcuni provisioner che potrebbero non essere installati nel sistema. Lo evito solo di rieseguirlo ogni volta che invoco i vagrantcomandi aggiungendo un sed per commentare automaticamente il file Vagrantfile.

Per esempio:

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

E lo faccio come prima riga del mio Vagrantfile. In questo modo installerà prima il plug-in vagrant-fabric, fabric e jinja (proverà prima senza sudoper virtualenvse con sudose ciò fallisce) e quindi la riga stessa commenta.


Sarebbe più semplice semplicemente grep l'elenco dei plugin vagabondi piuttosto che scommentare il file Vagrant, che potrebbe causare problemi ad altre persone nella tua squadra. if [[ $(vagrant plugin list | grep -c vagrant-host-shell) == "0" ]] then vagrant plugin install vagrant-host-shell fi
Giordania,

Il problema è che verrà attivato su altri comandi, cosa succede se si esegue vagrant statusprima vagrant up...
Mick
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.