Create aliases on host during vagrant up using vagrant-triggers - vagrant

Hoping someone can help me out here.
I am wanting to create aliases on my local machine (host) when running vagrant up. Through my search for vagrant run command on host, I came across the vagrant-triggers plugin. From the surface it appears to do exactly what I want (executing a script/command on the host machine during the vagrant provisioning process), however I have not been able to get it working successfully.
Below is my example code. I don't receive any errors, but the aliases are not available on the host.
Vagrant.configure("2") do |config|
# Your existing Vagrant configuration
...
# start vagrant-triggers example code
{
:up => [
'alias runscript="$(PWD)/script"',
'alias runscript2="$(PWD)/script2"'
],
[:halt, :destroy] => [
'unalias runscript',
'unalias runscript2'
]
}.each do |trigger, commands|
config.trigger.after trigger, :stdout => true do
commands.each do |command|
run command
end
end
end
...
end

Related

Vagrant destroy execute ruby

I would like to execute a custom ruby code after doing vagrant destroy.
That's the code:
class OnDestroyMiddleware
def initialize(app, env)
#app = app
end
def call(env)
env["config"].vm.provisioners.each do |provisioner|
env.ui.info "Attempting to remove client #{provisioner.config.node_name}"
`knife client show #{provisioner.config.node_name}`
if $?.to_i == 0
env.ui.info "Removing client #{provisioner.config.node_name}"
`knife client delete #{provisioner.config.node_name} -y`
end
env.ui.info "Attempting to remove node #{provisioner.config.node_name}"
`knife node show #{provisioner.config.node_name}`
if $?.to_i == 0
env.ui.info "Removing node #{provisioner.config.node_name}"
`knife node delete #{provisioner.config.node_name} -y`
end
end
#app.call(env)
end
end
I'm trying this but isn't working:
Vagrant::Action[:destroy].use(OnDestroyMiddleware)
All of this code is from https://gist.github.com/skippy/1010660
I've got this error on Vagrant::Action[:destroy]
Message: NoMethodError: undefined method `[]' for Vagrant::Action:Module
You can look at the vagrant trigger plugin. It allows you to run code after a specific vagrant command.
First you need to install the plugin
$ vagrant plugin install vagrant-triggers
You'll add the code directly in your Vagrantfile, like
Vagrant.configure("2") do |config|
# Your existing Vagrant configuration
...
# run some script before the guest is destroyed
config.trigger.after :destroy do
info "Attempting to remove client..."
run "knife client show .."
end

vagrant: how to add GUI to vagrant by modifying Vagrantfile?

I need to see the GUI when I do "vagrant up --provision" because I believe the box was shutdown improperly and now simply time-outs when I try to start it. I see from the [documentation] that I can add a block to my Vagrantfile to enable me to debug the startup process. This post says if the system was shutdown improperly it will ask me if I want to boot up in safe mode (only visible from the GUI). So I am trying to modify the Vagrantfile and have tried two ways (I'm not very familiar with Ruby or modifying config files). When I try this:
VAGRANTFILE_API_VERSION = "2"
path = "#{File.dirname(__FILE__)}"
require 'yaml'
require path + '/scripts/homestead.rb'
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
Homestead.configure(config, YAML::load(File.read(path + '/Homestead.yaml')))
config.vm.provider "virtualbox" do |v|
vb.gui = true
end
end
I get the following error message:
Path: <provider config: virtualbox>
Message: undefined local variable or method `vb' for main:Object
Could anyone please tell me what I am doing wrong? How do I modify the file properly so that I can get the vagrant box up and running again. I am trying to use Homestead for Laravel, by the way. Thank you very much!

How to run several boxes with Vagrant?

I need to run several boxes with Vagrant.
Is there a way to do that?
These don't relate one to another in any way, they can be thought as different environments using for test so it seems that multi-machine setup has nothing to do with this.
The best way is to use an array of hashes. You can define the array like:
servers=[
{
:hostname => "web",
:ip => "192.168.100.10",
:box => "saucy",
:ram => 1024,
:cpu => 2
},
{
:hostname => "db",
:ip => "192.168.100.11",
:box => "saucy",
:ram => 2048,
:cpu => 4
}
]
Then you just iterate each item in server array and define the configs:
Vagrant.configure(2) do |config|
servers.each do |machine|
config.vm.define machine[:hostname] do |node|
node.vm.box = machine[:box]
node.vm.hostname = machine[:hostname]
node.vm.network "private_network", ip: machine[:ip]
node.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--memory", machine[:ram]]
end
end
end
end
You can definitely run multiple Vagrant boxes concurrently, as long as their configuration does not clash with one another in some breaking way, e.g. mapping the same network ports on the host, or using same box names/IDs inside the same provider. There's no difference from having multiple boxes running on a provider manually, say multiple boxes on VirtualBox, or having them registered and started up by Vagrant. The result is the same, Vagrant just streamlines the process.
You can either use so called multi-machine environment to manage these boxes together in one project/Vagrantfile. They don't necessarily have to be somehow connected, ease of management may be the reason alone, e.g. if you need to start them up at the same time.
Or you can use separate projects/Vagrantfiles and manage the machines from their respective directories, completely separated.
In case of running multiple instances of the same project, you need multiple copies of the project directory, as Vagrant stores the box state in the .vagrant directory under the project.
You need just to copy the directory holding Vagrantfile to the new place and run vagrant up from it.
Make sure you copy the dir prior to starting up the box for the first time or Vagrant will think that these two locations refer to the same box. Or, if you already did vagrant up before copying the directory, then delete copied_directory/.vagrant after you make the copy.
You can even use different Vagrantfile(s) in same directory for different machine configuration or boxes
VAGRANT_VAGRANTFILE=Vagrantfile.ubntu_1404_64 VAGRANT_DOTFILE_PATH=.vagrant_ub140464 vagrant up
OR
VAGRANT_VAGRANTFILE=Vagrantfile.ubntu_1404_32 VAGRANT_DOTFILE_PATH=.vagrant_ub140432 vagrant up
Both the Vagrantfile can reside in same directory
I was able to have a single vagrantfile:
Vagrant.configure("2") do |winconfig|
# stuff
end
Vagrant.configure("2") do |nixconfig|
# stuff
end
Vagrant.configure("2") do |macconfig|
# stuff
end
and then I can bring them up with vagrant up --parallel. As others have mentioned, different vagrant files may be better for maintainability.
https://www.vagrantup.com/docs/vagrantfile/tips.html#loop-over-vm-definitions
(1..3).each do |i|
config.vm.define "node-#{i}" do |node|
node.vm.provision "shell",
inline: "echo hello from node #{i}"
end
end
Copying the directory holding Vagrantfile to a new place and spinning up the new machine there is the most straight forward way, if machines are not co-operating.
However, you may not want to copy/paste provisioning scripts for VCS tracking/backtracking purposes. Keep all your scripts in a folder, ex. dev, and put your Vagrantfile under numbered folders under dev, ex. dev/10. When you create a newer version, ex. dev/11 and not need the older one, you may just delete it. And refer to the common provisioning scripts using relative path:
config.vm.provision "shell", path: "../provisioner.sh"

Vagrant not able to find home/vagrant/hiera.yaml

I have inherited a python app that uses Puppet, Vagrant and VirtualBox to provision a local Centos test machine.
This app was written on Mac and I'm developing on Windows.
When I run vagrant up I see a large list of command line errors, the most relevant of which is:
Running Puppet with site.pp..
Warning: Config file /home/vagrant/hiera.yaml not found, using Hiera defaults
WARN: Fri Apr 25 16:32:24 +0100 2014: Not using Hiera::Puppet_logger. It does not report itself to b
e suitable.
I know what Hiera is, and why it's important, but I'm not sure how to fix this.
The file hiera.yaml is present in the repo but it's not found at home/vagrant/hiera.yaml, instead it's found at ./puppet/manifests/hiera.yaml.... Similarly if I ssh into the box, there is absolutely nothing whatsoever inside home/vagrant but I can find this file when I look in /tmp
So I'm confused, is vagrant looking inside the Virtual box and expecting this file to be found at home/vagrant/hiera.yaml? Or have I inherited an app that did not work properly in the first place? I'm really stuck here and I can't get in touch with the original dev.
Here are some details from my Vagrantfile:
Vagrant.configure("2") do |config|
# Base box configuration ommitted
# Forwarded ports ommitted
# Statically set hostname and internal network to match puppet env ommitted
# Enable provisioning with Puppet standalone
config.vm.provision :puppet do |puppet|
# Tell Puppet where to find the hiera config
puppet.options = "--hiera_config hiera.yaml --manifestdir /tmp/vagrant-puppet/manifests"
# Boilerplate Vagrant/Puppet configuration
puppet.module_path = "puppet/modules"
puppet.manifests_path = "puppet/manifests"
puppet.manifest_file = "site.pp"
# Custom facts provided to Puppet
puppet.facter = {
# Tells Puppet that we're running in Vagrant
"is_vagrant" => true,
}
end
# Make the client accessible
config.vm.synced_folder "marflar_client/", "/opt/marflar_client"
end
It's really strange.
There's this puppet.options line that tells Puppet where to look for hiera.yaml and currently it simply specifies the file name. Now, when you run vagrant up, it mounts the current directory (the one that has the Vagrantfile in it) into /vagrant on the guest machine. Since you're saying hiera.yaml is actually found in ./puppet/manifests/hiera.yaml, I believe you want to change the puppet.options line as follows:
puppet.options = "--hiera_config /vagrant/puppet/manifests/hiera.yaml --manifestdir /tmp/vagrant-puppet/manifests"
To solve this warning, you may first try to check from where this file is referenced, i.e.:
$ grep -Rn hiera.yaml /etc/puppet
/etc/puppet/modules/stdlib/spec/spec_helper_acceptance.rb:13: on hosts, '/bin/touch /etc/puppet/hiera.yaml'
/etc/puppet/modules/mysql/spec/spec_helper_acceptance.rb:34: shell("/bin/touch #{default['puppetpath']}/hiera.yaml")
In this case it's your vagrant file.
You may also try to find the right path to it via:
sudo updatedb && locate hiera.yaml
And either follow the #EvgenyChernyavskiy suggestion, create a symbolic link if you found the file:
sudo ln -vs /etc/hiera.yaml /etc/puppet/hiera.yaml
or create the empty file (touch /etc/puppet/hiera.yaml).
In your case you should use the absolute path to your hiera.yaml file, instead of relative.
The warning should be gone.

Specify default provider in Vagrantfile

I'd like to specify directly in the vagrantfile which provider to use by default for each VM.
For example, given this vagrantfile:
# Vagrantfile
[...]
config.vm.define 'dev_vm' do |machine|
machine.vm.provider :libvirt do |os|
[...]
end
# machine.default_provider = :libvirt
end
config.vm.define 'production_vm' do |machine|
machine.vm.provider :openstack do |os|
[...]
end
# machine.default_provider = :openstack
end
To boot up the following to VMs, I have to issue two commands currently:
vagrant up --provider=libvirt dev_vm
vagrant up --provider=openstack production_vm
I'd like to bring up both with a single vagrant up, especially because I'm running quite a few more machines. Some configuration like the commented machine.default_provider = :openstack would be fantastic to have.
Is there a way to do so?
I don't think there is any easy way to do it. Vagrant will currently use the same provider during the whole run so it could possibly be quite big code change to support this.
Maybe wrapper scripts are the easiest solution now.
Another workaround would be to use separate Vagrantfiles for the VMs and set VAGRANT_DEFAULT_PROVIDER in each. If there is a lot of common config, you could extract it to e.g. Vagrantfile.common, which is included by the others. Something like:
# Vagrantfile 1
ENV['VAGRANT_DEFAULT_PROVIDER'] = 'libvirt'
# assume the common config is in parent directory
load File.expand_path('../../Vagrantfile.common', __FILE__)
Vagrant.configure('2') do |config|
# ...
end

Resources