How can I programmatically query Vagrant for its provisioning status? - ruby

The Goal
I am attempting to conditionally run the vagrant-berkshelf plugin. By default, enabling the plugin causes Berkshelf to resolve and vendor cookbooks on every single vagrant up (which is a relatively expensive operation) even if the current vagrant operation isn't a provisioning run. For example, I expect Berkshelf to run when I run:
vagrant up the first time, or
when I execute vagrant reload --provision.
The source implies there ought to be a way to query Vagrant itself to determine if it's a provisioning run. Specifically, there ought to be a way to hook into #env[:provision_enabled] or vagrant.actions.vm.provision, but I'm unable to figure out how to do this from within the Vagrantfile itself.
Is this method actually bound to the Vagrant object? If not there, then where? And how can I introspect it?
Software Versions
Vagrant 1.8.1
vagrant-berkshelf 4.1.0
What I've Tried
As a workaround, I have tried moving the Berkshelf plugin inside the Chef block, intending that it only run when the Chef provisioner does. For example:
Vagrant.configure(2) do |config|
config.berkshelf.enabled = false
config.vm.provision :chef_solo do |chef|
config.berkshelf.enabled = true
end
end
However, Berkshelf still runs every time I vagrant up or vagrant reload, which is not the desired behavior. The cookbooks are still resolved and vendored on each run. Consider the following elided output:
==> default: Updating Vagrant's Berkshelf...
==> default: Resolving cookbook dependencies...
==> default: Using karaf (0.2.1)
==> default: Vendoring karaf (0.2.1) to /Users/foo/.berkshelf/vagrant-berkshelf/shelves/berkshelf20160215-19428-unzcx1-default/karaf
Questions That Aren't Duplicates of This One
There is a vaguely related question where the accepted answer is an ugly hack that looks for the presence of .vagrant/machines/default/virtualbox/action_provision or similar, but it is not an exact duplicate of this question as it doesn't address how to programmatically query Vagrant's internal state through the runtime objects or API Vagrant exposes. It may hold a pragmatic (if kludgey) answer based on filesystem semaphores, but it does not answer the question I'm actually asking.

If it's possible for you to provision using vagrant provision instead of the --provision flag you can check with the following code in Vagrantfile:
if ARGV[0] == 'provision'
# Run berkshelf plugin
end
The code inside the conditional will only run on vagrant provision. This won't work when using vagrant reload with the --provision flag as you were saying, but you could simply run vagrant provision after running vagrant reload. You can also use if ARGV[0] == 'up' or if ARGV[0] == 'reload' to run when using other commands.
See: Getting command line arguments inside the Vagrantfile

Related

Issues w vagrant ssh: terminating, 1 bad configuration options

first off I'm very new to programming and web development. I'm currently working through a Udacity course on SQL.
I'm trying to install VM and Vagrant and have run into this issue. Vagrant installed fine, and I'm able to run vagrant up, but when I run vagrant ssh I'm getting this message:
.ssh/config: terminating, 1 bad configuration options
I'll attach a screen here.
I'm on a Mac. Big Sur 11.5.2
Vagrant version 2.2.18
Any help provided would be greatly appreciated! Thanks in advance![enter image description here][1]
bash-3.2$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Checking if box 'bento/ubuntu-16.04-i386' version '2.3.5' is up to date...
==> default: Machine already provisioned. Run vagrant provision or use the --provision
==> default: flag to force provisioning. Provisioners marked to run always will still run.
bash-3.2$ vagrant ssh
/Users/scott27/.ssh/config: terminating, 1 bad configuration options
bash-3.2$
Consider moving your config file to a backup and trying again.
mv /Users/scott27/.ssh/config /Users/scott27/.ssh/config.bak
Then try vagrant up again and if it works then the issue is in your config file, troubleshoot that separately.
Instead of moving the existing ssh config file it is better to instead let vagrant point to its own config file using the config.ssh.config in vagrantfile
I am on Windows but I assume it is similar on mac. I updated my Vagrantfile like so:
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.ssh.config = File.expand_path(File.dirname(__FILE__) + '/ssh_config')
As you can see I point to a ssh_config file that I created, since an empty string resulted in an error.

Using Vagrant to set up a VM with KVM/qemu without VirtualBox

I'm getting started Vagrant and want to use it with KVM/qemu (and the Virtual Machine Manager GUI), instead of installing VirtualBox. So I first installed Vagrant:
$ vagrant --version
Vagrant 1.9.1
$ vagrant box list
There are no installed boxes! Use `vagrant box add` to add some
As per these posts, I require vagrant-libvirt for it to work with KVM, so I installed that next:
$ vagrant plugin list
vagrant-libvirt (0.0.37)
vagrant-share (1.1.6, system)
Next, I to add a CentOS(7) box using vagrant box add "centos/7" and selected libvirt, when prompted. After which, I ran vagrant init and didn't encounter any errors:
$ vagrant init centos/7
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.
However, vagrant up seems to be erroring out, like so:
$ vagrant up
No usable default provider could be found for your system.
Vagrant relies on interactions with 3rd party systems, known as
"providers", to provide Vagrant with resources to run development
environments. Examples are VirtualBox, VMware, Hyper-V.
The easiest solution to this message is to install VirtualBox, which
is available for free on all major platforms.
If you believe you already have a provider available, make sure it
is properly installed and configured. You can see more details about
why a particular provider isn't working by forcing usage with
`vagrant up --provider=PROVIDER`, which should give you a more specific
error message for that particular provider.
Here's the provider section in the Vagrantfile
config.vm.provider :libvirt do |domain|
domain.driver = "qemu"
domain.memory = 512
domain.cpus = 1
end
I tried modifying it to:
config.vm.provider :libvirt do |domain|
domain.driver = "kvm"
domain.host = 'localhost'
domain.uri = 'qemu:///system'
domain.memory = 512
domain.cpus = 1
end
I also tried vagrant up --provider=kvm, vagrant up --provider=qemu, and vagrant up --provider=libvirt too, to no avail.
Is there any step that I've missed? Or another package/dependency that needs to be installed?
Edit: After the adding centos/7 using vagrant, it shows up when running vagrant box list.
$ vagrant box list
centos/7 (libvirt, 1611.01)
Start vagrant box with command
vagrant up --provider=kvm
Although it has been said in https://seven.centos.org/2017/08/updated-centos-vagrant-images-available-v1707-01/ that
The vagrant-libvirt plugin is only compatible with Vagrant 1.5 to 1.8
You can use either the command line option --provider=kvm or you can set the VAGRANT_DEFAULT_PROVIDER environment variable:
export VAGRANT_DEFAULT_PROVIDER=kvm # <-- may be in ~/.profile, /etc/profile, or elsewhere
vagrant up
vagrant-libvirt(0.0.40) is compatible with Vagrant 2.0.2 if you are running Ruby 2.3, at least on Linux Mint 18.3 (Ubuntu 16.04). I used vagrant from the Debian download on the vagrantUp website and installed the plugin using it without any problem.

When I do `vagrant provision`, what does it happen in my dev box?

I'm sure the answer is based on how my setup and etc… but I'd like to figure out what file gets called and such. I'm using vagrant-berkshelf and vagrant-omnibus plugins. Berksfile is empty, Vagrantfile is using 'ubuntu/trusty64' and provisioner is chef.
config.vm.provision :chef_solo do |chef|
chef.run_list = []
end
The reason why I'm asking is because I can call vagrant provision, it runs successfully, but when I get in the box and call chef-solo, it fails. So I'd like to understand how that works.
Chef-Omnibus installs Chef into a different location than Vagrant's normal Chef provisioner. So it's there, it's just (apparently) not in your path.

Chef Vagrant, Can't Find Folder

Chef is really confusing me. Can you help me understand why it's not working?
Cliff Notes
I'm using Chef-Solo (not Berkshelf or anything else)
Everything works when I set it up from scratch, I can vagrant provision
But if I reboot the HOST (My main operating system) it breaks!
It appears to be looking inside a .chef folder which I did not specify in my vagrant configuration.
I have to do a vmboxmanage box destroy ubuntu/trusty64 and redownload everything and redo vagrant up if I reboot.
Vagrant Version 1.7.2
Virtual Box Version 4.3.20r96996
Inside Vagrant SSH Error:
Note: The files are not pointing to the .chef folder, but they are here?
[2015-01-30T16:23:44+00:00] WARN: Did not find config file:
/etc/chef/solo.rb, using command line options.
[2015-01-30T16:23:50+00:00] FATAL: None of the cookbook paths set in
Chef::Config[:cookbook_path],
["/vagrant/.chef/cookbooks", "/vagrant/.chef/site-cookbooks"],
contain any cookbooks
$vagrant up and $ vagrant provision error:
==> default: Mounting shared folders...
default: /vagrant => /home/jesse/if/indieflix/vagrant
default: /home/vagrant/chef-recipes => /home/jesse/projects/if/vagrant/chef-recipes
default: /home/vagrant/chef-resources => /home/jesse/projects/if/vagrant/chef-resources
==> default: Running provisioner: chef_solo...
==> default: Detected Chef (latest) is already installed
Shared folders that Chef requires are missing on the virtual machine.
This is usually due to configuration changing after already booting the
machine. The fix is to run a `vagrant reload` so that the proper shared
folders will be prepared and mounted on the VM.
And, vagrant reload does nothing.
Vagrantfile
# ...
config.vm.synced_folder "chef-recipes", "/vagrant/chef-recipes"
config.vm.synced_folder "chef-resources", "/vagrant/chef-resources"
# ...
config.vm.provision "chef_solo" do |chef|
# Relevant to the Vagrantfile path
chef.cookbooks_path = ["chef-recipes"]
# This is just required by Chef, so it's minimal
chef.environments_path = "chef-resources/environments"
# This is the internal flag.
chef.environment = "development"
# This defines the cookbooks to run
chef.roles_path = "chef-resources/roles"
chef.add_role("development")
end
Folder Structure
chef-recipes/ (Git Submodule)
----python/
--------recipes/
------------default.rb
------------pip.rb
chef-resouces/ (Git Submodule)
----environments/
--------development.json
----roles/
--------development.json
Vagranfile
Anthony suggested in a comment I answer my question since it was answered in comments. Here it is!
Instead of using curl to install, I used omnibus which adds another step before provisioning:
$ vagrant plugin install vagrant-omnibus
Second, Chef-Solo/Vagrant has an issue with mounting files from the Host. The only workaround I have found is:
$ rm .vagrant/machines/default/virtualbox/synced_folders vagrant reload --provision
Optional: I created a bash script to make the above a little quicker:
reprovision.sh
#/bin/bash
rm .vagrant/machines/default/virtualbox/synced_folders
vagrant reload --provision
And of course chmod +x reprovision.sh and to run ./reprovision.sh

Vagrant Puppet guest cli output on host

I have been using Vagrant with Puppet for a few days; this is a cool tool in the context of automation.
I have a question. Sometimes apt operations (or git clone) take a few minutes to download all the packages. Vagrant logs all operations on the host's cli, but only those that have already been performed. There is no information about the currently executing task, so I am not sure if the machine hanged or if an operation is still running.
Is there a possibility to output all the guest's cli output on the host's cli in Vagrant?
I am running Vagrant 1.4.3 on Windows 8 via Git Bash and this solution didn't work for me:
Vagrant provision live output
You can pass extra options to the puppet command in the Vagrantfile, among which --verbose and/or --debug. This is the example reported in Vagrant documentation (link):
Vagrant.configure("2") do |config|
config.vm.provision "puppet" do |puppet|
puppet.options = "--verbose --debug"
end
end
By passing these options the output in the host console should be much more verbose.

Resources