Using Vagrant on cloud CI services - continuous-integration

Are there any cloud CI services that allow Vagrant VMs to run using VirtualBox as a provider?
Early investigation shows this seems not to be possible with Travis CI or Circle CI, although the vagrant-aws plugin allows for the use of AWS servers as a Vagrant provider. Is this correct?

Update January 2021: GitHub Actions also supports Vagrant - and Vagrant/VirtualBox are both installed out-of-the-box in the MacOS environment (not on Linux or Windows currently!). See the possible environments here. Therefore I created a fully comprehensible example project at: https://github.com/jonashackt/vagrant-github-actions
1.: Create a Vagrantfile (and you're not limited to libvirt as with Travis, you have a full VirtualBox environment with nested virtualization working on GitHub Actions!) like this:
Vagrant.configure("2") do |config|
config.vm.box = "generic/ubuntu1804"
config.vm.define 'ubuntu'
# Prevent SharedFoldersEnableSymlinksCreate errors
config.vm.synced_folder ".", "/vagrant", disabled: true
end
2.: Create a GitHub Actions workflow like this vagrant-up.yml inside the .github/workflows directory in your repository:
name: vagrant-up
on: [push]
jobs:
vagrant-up:
runs-on: macos-10.15
steps:
- uses: actions/checkout#v2
- name: Run vagrant up
run: vagrant up
- name: ssh into box after boot
run: vagrant ssh -c "echo 'hello world!'"
You can even add caching for the Vagran boxes, this will safe you some seconds :)
Early 2020:
TravisCI is now able to run Vagrant finally! Thanks to this GitHub issue I learned about libvirt and KVM, which could be used together with the vagrant-libvirt Plugin to run Vagrant boxes on TravisCI.
An example TravisCI .travis.yml should look somehow like that:
---
dist: bionic
language: python
install:
# Install libvrt & KVM
- sudo apt-get update && sudo apt-get install -y bridge-utils dnsmasq-base ebtables libvirt-bin libvirt-dev qemu-kvm qemu-utils ruby-dev
# Download Vagrant & Install Vagrant package
- sudo wget -nv https://releases.hashicorp.com/vagrant/2.2.7/vagrant_2.2.7_x86_64.deb
- sudo dpkg -i vagrant_2.2.7_x86_64.deb
# Vagrant correctly installed?
- vagrant --version
# Install vagrant-libvirt Vagrant plugin
- sudo vagrant plugin install vagrant-libvirt
script:
- sudo vagrant up --provider=libvirt
- sudo vagrant ssh -c "echo 'hello world!'"
With the help of the generic Vagrant Box images from Vagrant Cloud you can also establish a workflow of using Vagrant + libvirt + KVM on Travis and Vagrant + VirtualBox on your local machine, if you like:
I created a fully working and 100% comprehensible example project here: https://github.com/jonashackt/vagrant-travisci-libvrt

Many CI services are not allowing to run Vagrant via LXC or Virtualbox as it will require nested virtualization (running VM in VM) or a pure bare metal server provisioned for you.
Current 2021 (updated) situation:
Github Actions can do it.
Travis was able to run Vagrant with some workarounds.
AppVeyor allows running VirtualBox (non-free plans).
You can't under CodeShip
You can't under CircleCI
Don't know about other CI services, will investigate further.
I hope during the time we'll see CI services allowing to run Vagrant with Virtualbox or LXC, but for now Docker (with its limitations) is the only option.
Personally, I would be happy to use it for integration tests against different platforms/linux distros via Test-Kitchen CI or similar.

AppVeyor runs Vagrant using VirtualBox as a provider. Furthermore, you can use other providers like libvirt or Hyper-v.
Updated:
Github Actions is another option. Only Mac OS environment has nested virtualization enabled. An example is here and here.

Related

How to update laravel/homestead?

I need to update laravel/homestead? It is a Vagrant box. I'm using it for my dev environment.
I remember it was a shell command but I don't remember the command and I cannot find it. Please help
This is the sequence I came up with recently (Apr 2020) to upgrade my vagrant box from 9.2.x to 9.5.x
If the VM is not running first do:
vagrant up
Then go into the VM:
vagrant ssh
and back up the databases:
mysqldump -u homestead --all-databases -p > homestead-backup.sql
copy the resulting file to the host machine (only if the above command was not run in a mapped folder)
Close the ssh connection:
exit
then run:
vagrant box update
vagrant destroy
vagrant box prune
Answer yes to all questions. Then
git fetch
git pull origin release
Start the VM again:
vagrant up
once it's started (it will take longer this time) go into the VM:
vagrant ssh
and restore the databases (copy the backup file over from the host if it was not in the mapped folder)
mysql -u homestead -p < homestead-backup.sql
Note: add -p if needed to mysql import and export, it will prompt for password (default: "secret")
Use below command
homestead update
If this doesn't work
homestead box update
If this also doesn't work at all
This command will tell you the state of all active Vagrant environments on the system for the currently logged in user.
vagrant global-status
vagrant box update "laravel/homestead"
I hope i am clear now!
First update your box:
vagrant box update
And, as it is documented here:
https://laravel.com/docs/master/homestead#updating-homestead
You should first destroy the machine and recreate it:
vagrant destroy
vagrant up
Just tested and it worked for me. (updated from homestead: '8.2.0' to '9.0.0')
Do not forget to backup your existing database datas before destroying the machine.
Please follow this url which will guide you to update the laravel/homestead
Update laravel homestead
also the basic steps is cd into your homestead directory and run vagrant box update it will download the latest version
If you used a default settings on installation, you need
1) go to your vagrant folder
$ cd ~/Homestead/
2) run vagrant box update command
$ vagrant box update "homestead-7"
Tested on Laravel 5.6/5.7
First, check the available homestead releases:
https://github.com/laravel/homestead/releases
To check your homestead and vagrant versions use these commands:
for the Vagrant version:
vagrant version
I had Installed Version: 2.2.10, the last version for mac was 2.2.14
for the Homestead version, go to the folder ~\Homestead and:
git branch -v
In my case, I had this output: HEAD detached at v11.4.0
Then, how to update Vagrant and Homestead?
First, make sure you backup the DB!
https://laravel.com/docs/8.x/homestead#database-backups
In my case, the automatic backup didn't work, and the first time I did the vagrant destroy I lost the DBs, so I suggest to backup manually like this:
vagrant ssh
mysqldump -u homestead -p --all-databases > homestead-20210214.sql
Then copy file out from the Vagrant machine before destroying:
from ~/Homestead 
scp -P 2222 vagrant#127.0.0.1:/home/vagrant/homestead-20210214.sql .
Then from the Homestead directory:
vagrant destroy
git fetch
To check the version of your homestead:
vagrant box list
In my case, I had:
laravel/homestead (virtualbox, 10.1.1)
Here you can check the latest stable release of Homestead:
https://github.com/laravel/homestead/releases.
In my case was Homestead 12.
But actually what you are going to install is the latest stable release of the laravel/homestead Vagrant box.
You can see the latest release here.
https://app.vagrantup.com/laravel/boxes/homestead.
In my case was v11.0.0
Then since in my case, the latest Homestead was v12.0.0 I did:
git checkout v12.0.0
vagrant box update
bash init.sh
vagrant up
And you are done.
Then you can restore the DBs.
How if I run
vagrant box list
I see:
laravel/homestead (virtualbox, 11.0.0)
Have a look also at the official documentation here.
https://laravel.com/docs/8.x/homestead#updating-homestead

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.

Vagrant. The box you're attempting to add doesn't support the provider you requested

I created a vagrant box using vagrant package , uploaded it and released it.
Then I did vagrant init <username>/<box> which created a Vagrantfile. I even appended the box version to the Vagrantfile.
Next I did vagrant up --provider virtualbox. This tries to get the box locally and then when it can't find it, i get the error:
The box you're attempting to add doesn't support the provider
you requested. Please find an alternate box or use an alternate
provider. Double-check your requested provider to verify you didn't
simply misspell it.
If you're adding a box from HashiCorp's Atlas, make sure the box is
released.
I have given virtualbox as the provider and virtual box works fine with other boxes I use.
Make sure you have virtualbox installed if you are using ubuntu.
sudo apt install virtualbox-qt
What I figured was that due to some reason vagrant had got corrupted. So doing a fresh install of vagrant did the trick.
Upgrading vagrant version through installing .deb version worked for me (download through vagrant website: https://www.vagrantup.com/downloads - choose tab "Debian" and install the package)
I suffered for 2 hours but I don't want anyone to suffer ;)
1 - access the terminal (sudo) and, remove vagrant files
$ rm -rf /opt/vagrant
$ rm -f /usr/bin/vagrant
2 - then install it again as it has probably been corrupted.
$ curl -O https://releases.hashicorp.com/vagrant/2.2.9/vagrant_2.2.9_x86_64.deb
3 - install vagrant
$ sudo apt install ./vagrant_2.2.9_x86_64.deb
4 - confirm by viewing the installed vagrant version
& vagrant --version
be happy

Create a virtual machine for development with Vagrant

I am using nodejs with ansible and vagrant
I need to create a new machine for development with such things:
on every vagrant up I need to do:
run this script (to install all needed soft for development):
bash <(wget -qO- https://raw.githubusercontent.com/thoughtbot/laptop/master/linux)
NPM install on every submodule in my project
install and run mongodb service
How I can set these stuff to do automatically in vagrant or ansible?
You have a few options:
vagrant up, install your dependencies and repackage it as a box with: vagrant package or vagrant box repackage
Use chef/puppet/ansible provisioners, or even the shell provisioner. This will allow it to happen on vagrant up or vagrant provision
Roll your own in ruby and have vagrant run it (a vagrantfile is basically just ruby). I don't recommend this way.
I personally recommend 2 even though its the slowest (requires you to do all the owrk every time you destroy and up). 1 is a really good choice but I tend to keep vagrant as close to base state as possible so that no surprises pop up during deployment. And it makes it easier to share across people if you don't have to constantly re-package it and maintain that .box

Understanding vagrant with a docker provisioner

So my goal here is to have Vagrant spin me up a VM that I can use as a rails web application development environment. I am very, very new to Vagrant, Docker, etc. and wanted to check if this even makes sense:
Should I be creating one Docker image, or two? My thought was that one image would be for rvm, ruby, and rails, and the other image would be for Apache.
The goal would be something that could be distributed to a few people, who would then get the exact same environment set up easily.
Here is my current Vagrantfile:
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "phusion/ubuntu-12.04-amd64"
config.vm.network "forwarded_port", :guest => 80, :host => 5000
# Share the docker configs
config.vm.synced_folder "./docker", "/docker"
config.vm.provision "docker" do |d|
d.build_image "-t me/rvm-dev /docker/rvm-dev"
d.run "me/rvm-dev"
end
config.vm.host_name = "coursera-rail.dev"
config.vm.network :forwarded_port, guest:80, host:8080
end
And here is my current (probably wrong) Dockerfile
(as an aside, I am trying to find some good guidance on creating a "docker" user account so I don't run everything as root)
## Dockerfile
FROM ubuntu:latest
RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get install -y curl
RUN mkdir -p /tmp/downloads
## Install RVM, Ruby, Rails
RUN cd /tmp/downloads
RUN \curl -L https://get.rvm.io | bash -s stable --ruby --rails
Lastly, the above works, and if I use vagrant ssh I can head in to my VM, but obviously I am unable to use RVM without doing docker run -i -t me/rvm-dev and getting a shell with docker. Is this supposed to be the workflow?
In my humble opinion, the best flow would be to
1) separate your app and db stack into vagrant boxes
or
2) run docker on the host (the physical machine) and your DB instance (mysql, etc..) inside a vagrant box.
Option one is best because you are "sandboxing" both layers of the stack (DB and APP) inside Vagrant thus leaving the OS on your local machine (windows, Linux, Mac OSX) instact. Of course, you could install/run your IDE on the physical machine.

Resources