Respostas:
Pelo menos dois plugins que devem ajudar:
Se você não se importa que o script seja executado em (quase) todos os vagrant
comandos, você também pode usar (ou usar o que for ruby magic) no Vagrantfile:
system('./myscript.sh')
Vagrant.configure('2') do |config|
# ...
end
Kernel
módulo, documentado aqui . O Kernel
módulo está incluído na Object
classe, portanto, seus métodos estão disponíveis em todos os escopos.
(Digo completo porque a resposta aceita não verifica se o usuário está usando o vagrant up. Portanto, o script é executado em cada comando, que não é o que o OP deseja.)
Existe, no entanto, uma solução simples para isso.
ARGV[0]
é o primeiro argumento do comando inserido e pode ser up
, down
, status
, etc .. Basta verificar o valor ARGV[0]
em sua Vagrantfile.
Algo assim 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
Coloque isso perto do topo do seu arquivo 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
Em seguida, basta chamar no seu Vagrantfile assim:
config.vm.provision "list-files", type: "local_shell", command: "ls"
E através da linha de comando como esta:
vagrant provision --provision-with list-files
Isso é meio que um hack, pois parece um plug-in, mas na verdade não é (não será exibido quando você aparecer vagrant plugin list
). Eu não recomendo fazê-lo dessa maneira, exceto que ele tem a vantagem de não precisar instalar um plug-in, portanto, o seu Vagrantfile funcionará em qualquer máquina que suporte a versão mais recente da configuração (versão 2, neste momento). Embora isso pareça prometidamente portátil, também há toda a questão de plataforma cruzada do comando real que você está emitindo. Você precisará levar em consideração se deseja que o seu Vagrantfile seja portátil, mas isso deve ajudá-lo a começar.
Com base na resposta de @ tmatilai, mas atualizada para 2019, o vagrant-triggers foi fundido no Vagrant. Agora você pode fazer algo assim:
node.trigger.before [:up, :provision] do |trigger|
trigger.info = "Running ./myscript.sh locally..."
trigger.run = {path: "./myscript.sh"}
end
Este bloco vai para dentro config.vm.define
. Mais documentação: https://www.vagrantup.com/docs/triggers/
config.vm.define
não é um requisito; eles podem ser colocados dentro Vagrant.configure("2") do |config| ... end
também. Como observação final, nos hosts do Windows, o Vagrant executará com prazer os scripts do Powershell que também possuem a .ps1
extensão.
De acordo com o que @tmatilai disse sobre o uso
system('./myscript.sh')
Eu achei bastante útil para comandos de uma só vez, como instalar comandos vagrantes ou algum provisionador que pode não estar instalado no sistema. Eu apenas evito que ele seja executado novamente toda vez que chamo os vagrant
comandos adicionando um sed para comentar automaticamente o Vagrantfile
.
Por exemplo:
system('vagrant plugin install vagrant-fabric && (pip install fabric jinja2 || sudo pip install fabric jinja2) && sed -i -e "s/^system/#system/g" Vagrantfile')
E eu faço isso a primeira linha do meu arquivo Vagrant. Desta forma, ele irá primeiro instalar o plugin vagabundo-tecido, tecido e Jinja (vai tentar primeiro sem sudo
para virtualenvs
e com sudo
se isso falhar) e então o próprio comentários de linha.
if [[ $(vagrant plugin list | grep -c vagrant-host-shell) == "0" ]] then vagrant plugin install vagrant-host-shell fi
vagrant status
antes vagrant up
...