Vagrant disable Guest Additions - vagrant

I would like to disable VirtualBox Guest Additions. I do not use them for folder syncing, etc. and for the box I am working on (e.g., centos/7), they fail to build anyway. Is there some way to tell vagrant not to try to install them at vagrant up?

In your Vagrantfile, add the following param
Vagrant.configure("2") do |config|
....
config.vbguest.auto_update = false
....
end

Users might not have the vagrant-vbguest plugin, and you could wrap its use in a conditional to avoid confusion.
Vagrant.configure("2") do |config|
....
if Vagrant.has_plugin?("vagrant-vbguest")
config.vbguest.auto_update = false
end
....
end

Related

With vagrant-berkshelf deprecated, will it be possible to drive builds from Vagrant, with Chef solely as a provisioner?

I have had a number of issues recently with vagrant-berkshelf not syncing Chef cookbooks on an existing machine reliably. And, basically, when doing research on workarounds, I see something like:
vagrant-berkshelf is deprecated, use Test Kitchen instead.
My use case is that I have Vagrantfiles, used to build VMs and DigitalOcean droplets, that are hand-written and only use Chef to provision the VMs. I am most definitely approaching Chef as a user, not an author or tester of cookbooks.
So, I am in a case of Vagrant -> Chef, not Chef -> Vagrant.
When looking at Kitche-Vagrant, I see that:
The kitchen-vagrant driver for Kitchen generates a single Vagrantfile for each instance of Kitchen in a sandboxed directory..
My question is: if my workflow relies on hand-written, complex, Vagrantfiles, can I continue to use Chef as a provisioner without having to rely on vagrant-berkshelf?
Some of the possible alternatives I see are:
mangle Test Kitchen configuration to work with my exiting Vagrantfile. I fear that this is not the intent of this tool and will not end well.
use chef.cookbooks_path attribute in vagrant and let it take the place of vagrant-berkshelf.
switch out provisioners and use say Vagrant->Ansible.
The Vagrantfile below is somewhat simplified, but the gist is that the Vagrantfile is in charge and Chef is just used to provision.
# -*- mode: ruby -*-
# vi: set ft=ruby :
#...grab some variables from my host environment...
DJANGO_SECRET_KEY = ENV['BUILD_DJANGO_SECRET_KEY']
Vagrant.configure('2') do |config|
config.vm.define "myserver" do |config|
config.vm.provider :digital_ocean do |provider, override|
override.ssh.private_key_path = digoconf.private_key_path
override.vm.box_url = "https://github.com/devopsgroup-io/vagrant-digitalocean/raw/master/box/digital_ocean.box"
provider.token = digoconf.TOKEN
...
end
#had chef_client before, that worked too.
config.vm.provision "chef_zero" do |chef|
chef.log_level = "info"
#I haven't tested these out
#chef.cookbooks_path = ["../community/cookbooks","../.berkshelf/cookbooks"]
env_for_chef = " DJANGO_SECRET_KEY='#{DJANGO_SECRET_KEY}'"
chef.binary_env = env_for_chef
chef.environment = "digitalocean"
chef.add_recipe "base::install"
end
end
end
It isn't deprecated per se, but it does no longer have a maintainer and does highly recommend against its use. There is no replacement for the workflow you describe. Sorry. If you are interested in taking over as maintainer, I can put you in contact with the team.

Is it possible to load a Vagrantfile config from within another Vagrantfile?

Vagrant Multi-Machine functionality seems pretty cool, however one thing that bothers me (or is isn't immediately apparent) is that there doesn't seem to be a good way to share configuration options between a "parent" Vagrantfile and "children" Vagrantfiles. Is there a way to effectively and maintainably share configuration options between the parent and it's children? An example might make this more clear.
Let's assume I've got a platform which is comprised of 3 apps/services: API, Web, and Worker.
Let's presume a directory structure of the following:
/some_platform
/api
# app code...
Vagrantfile
/web
# app code...
Vagrantfile
/worker
# app code...
Vagrantfile
Vagrantfile
Let's say /some_platform/api/Vagrantfile looks like:
Vagrant.configure("2") do |config|
config.vm.box = "debian/jessie64"
end
Presumably the web and worker Vagrantfiles look similar.
Now, using the wonders of Multi-Machine I rely on Vagrant coordinate these VMs, and /some_platform/Vagrantfile looks like:
Vagrant.configure("2") do |config|
config.vm.define "web" do |api|
api.vm.box = "debian/jessie64"
end
config.vm.define "web" do |web|
web.vm.box = "debian/jessie64"
end
config.vm.define "web" do |worker|
worker.vm.box = "debian/jessie64"
end
end
I realize this example is contrived, but it's easy to see how once you get more and more complex config declarations, it's annoying and hazardous to have that config duplicated in two places.
You might be wondering "Why does each project have it's own Vagrantfile?" Doing so provides a single source of truth for how the server that app runs on should be setup. I realize there are provisioners you can use (and I will use them), but you still have to declare a few other things outside of that and I want to keep that DRY so that I can either bring up a cluster of apps via Multi-Machine, or I can work on a single app and change it's VM/server setup.
What I'd really love is a way to merge other Vagrantfiles into a "parent" file.
Is that possible? Or am I crazy for trying? Any clever ideas on how to achieve this? I've mucked about with some yaml files and POROs to skate around this issue, but none of the hacks feel very satisfying.
Good news!
You can in fact apply DRY principles in a Vagrantfile.
First: Create a file /some_platform/DRY_vagrant/Vagrantfile.sensible to hold some sensible defaults :
Vagrant.configure("2") do |config|
# With the setting below, any vagrantfile VM without a 'config.vm.box' will
# automatically inherit "debian/jessie64"
config.vm.box = "debian/jessie64"
end
Second: Create a file /some_platform/DRY_vagrant/Vagrantfile.worker for the 'worker' virtual machine :
Vagrant.configure("2") do |config|
config.vm.define "worker" do |worker|
# This 'worker' VM will not inherit "debian/jessie64".
# Instead, this VM will explicitly use "debian/stretch64"
worker.vm.box = "debian/stretch64"
end
end
Finally: Create a file /some_platform/Vagrantfile to tie it all together :
# Load Sensible Defaults
sensible_defaults_vagrantfile = '/some_platform/DRY_vagrant/Vagrantfile.sensible'
load sensible_defaults_vagrantfile if File.exists?(sensible_defaults_vagrantfile)
# Define the 'api' VM within the main Vagrantfile
Vagrant.configure("2") do |config|
config.vm.define "api" do |api|
# This 'api' VM will automatically inherit the "debian/jessie64" which we
# configured in Vagrantfile.sensible
# Make customizations to the 'api' VM
api.vm.hostname = "vm-debian-jessie64-api"
end
end
# Load the 'worker' VM
worker_vm_vagrantfile = '/some_platform/DRY_vagrant/Vagrantfile.worker'
load worker_vm_vagrantfile if File.exists?(worker_vm_vagrantfile)
This approach can be used for almost any other vagrantfile config options. It is not limited to just the "config.vm.box" setting.
Hope this helped!
There are 2 things you can look at (probably more, but those two comes to my mind)
look at How to template Vagrantfile using Ruby? its an example how you can read the content of another file, Vagrantfile is just a ruby script so you can use all the power of ruby.
vagrant has a concept of loading and merging, see from doc so if you wanted to do something anytime you run a vagrant command, you could create a Vagrantfile under your ~/.vagrant.d/ folder and it will always run
one drawback (or at least to pay attention) : the Vagrantfile is a ruby script that is evaluated each (and every time) a vagrant command is executed (up, status, halt ....)

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"

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