Using vagrant to run virtual machines with desktop environment - virtual-machine

My company's development environment is based on virtual machines, running on VirtualBox. We would like to move one step further, and use the capabilities of Vagrant to have the description of the machine in a text file and then be able to "raise" that machine based on that text file. Combined to puppet, this would solve us the problem that everyone have different software versions installed in the VM.
However, Vagrant seems very focused to develop on the host, letting the machine in the background. We would need to have our development environment within the machine, so we would need a complete GUI, so when typing "vagrant up" a machine with a complete desktop environment (XFCE, KDE...) should appear.
So far, I've managed to create a "base" box from a Xubuntu distribution. But when I type "vagrant up", although the desktop appears, and I am able to login properly, Vagrant freezes at the message "Waiting for machine to boot. This may take a few minutes...". After a while Vagrant crashes due timeout. So shared folders are not created, nor the package provisioner -puppet- is executed.
How to create a virtual machine with a complete GUI using vagrant?

I just got this working with basically three steps. The advice from askubuntu.com didn't quite work for me, so try this simplified version:
Get a basic Ubuntu image working. You should be able to boot it and vagrant ssh.
Next, enable the VirtualBox display, which is off by default. Halt the VM and uncomment these lines in Vagrantfile:
config.vm.provider :virtualbox do |vb|
vb.gui = true
end
Boot the VM and observe the new display window. Now you just need to install and start xfce4. Use vagrant ssh and:
sudo apt-get install xfce4
sudo startxfce4&
If this is the first time you're running this Ubuntu environment, you'll need to run the following command before installing xfce4:
sudo apt-get update
That's it, you should be landed in a xfce4 session.
Update: For a better experience, I recommend these improvements:
Don't start the GUI as root. You really want to stay the vagrant user. To do this you need to permit anyone to start the GUI: sudo vim /etc/X11/Xwrapper.config and edit it to allowed_users=anybody.
Next, install the VirtualBox guest tools before starting the GUI. This will give you a healthy screen resolution, integrated mouse, etc.
$ sudo apt-get install -y xfce4 virtualbox-guest-dkms virtualbox-guest-utils virtualbox-guest-x11
$ sudo VBoxClient-all
Only now should you start the GUI as the vagrant user, with $ startxfce4&.
Update 2: Tried this today and the VBoxClient-all script isn't always installed. If it's missing, you can replace with the equivalent:
sudo VBoxClient --clipboard
sudo VBoxClient --draganddrop
sudo VBoxClient --display
sudo VBoxClient --checkhostversion
sudo VBoxClient --seamless

Here's Air's excellent answer in the form of a Vagrantfile
Vagrant.configure(2) do |config|
# Ubuntu 15.10
config.vm.box = "ubuntu/wily64"
config.vm.provider "virtualbox" do |vb|
# Display the VirtualBox GUI when booting the machine
vb.gui = true
end
# Install xfce and virtualbox additions
config.vm.provision "shell", inline: "sudo apt-get update"
config.vm.provision "shell", inline: "sudo apt-get install -y xfce4 virtualbox-guest-dkms virtualbox-guest-utils virtualbox-guest-x11"
# Permit anyone to start the GUI
config.vm.provision "shell", inline: "sudo sed -i 's/allowed_users=.*$/allowed_users=anybody/' /etc/X11/Xwrapper.config"
end
To start the vm
vagrant up
Login with username: vagrant, password: vagrant via the login prompt on the virtualbox GUI.
Start xfce
startx

Here is a slightly adapted Vagrantfile for Ubuntu 18.04 LTS / bionic - thanks to Air's and Nik's answers, and this post explaining how to increase the disk size when using VirtualBox (default = 10 GB).
The VM includes a LightDM login screen.
Update: I've created a GitHub repo from this example, and added many software packages for frontend + backend development.
# Optional - enlarge disk:
#vagrant plugin install vagrant-disksize
vagrant up
vagrant reload
# After reboot, the VM screen should show the LightDM login screen.
# Log in as user "vagrant", password "vagrant".
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/bionic64"
# Optional - enlarge disk (will also convert the format from VMDK to VDI):
#config.disksize.size = "50GB"
config.vm.provider "virtualbox" do |vb|
# Display the VirtualBox GUI when booting the machine
vb.gui = true
end
# https://askubuntu.com/questions/1067929/on-18-04-package-virtualbox-guest-utils-does-not-exist
config.vm.provision "shell", inline: "sudo apt-add-repository multiverse && sudo apt-get update"
# Install xfce and virtualbox additions.
# (Not sure if these packages could be helpful as well: virtualbox-guest-utils-hwe virtualbox-guest-x11-hwe)
config.vm.provision "shell", inline: "sudo apt-get install -y xfce4 virtualbox-guest-dkms virtualbox-guest-utils virtualbox-guest-x11"
# Permit anyone to start the GUI
config.vm.provision "shell", inline: "sudo sed -i 's/allowed_users=.*$/allowed_users=anybody/' /etc/X11/Xwrapper.config"
# Optional: Use LightDM login screen (-> not required to run "startx")
config.vm.provision "shell", inline: "sudo apt-get install -y lightdm lightdm-gtk-greeter"
# Optional: Install a more feature-rich applications menu
config.vm.provision "shell", inline: "sudo apt-get install -y xfce4-whiskermenu-plugin"
end

My 2 cents
Make sure you are running latest vagrant (1.3.3 now) + VirtualBox (4.2.18) to avoid bugs.
You can use shell script or inline command to install a desktop environment or a light weight window manager
For example install LXDE on top of Ubuntu 12.04 Precise base box from vagrantbox.es
Vagrant.configure("2") do |config|
# ... other configuration
config.vm.provision "shell" do |s|
s.inline = "apt-get install lubuntu-desktop -y"
end
end
If you build your own vagrant base boxes, make sure you follow the base box packaging instructions or consider tools like packer (or veewee) to automate the build.

I'm using ubuntu desktop image, it works nicely with two monitors on windows with virtual box provider.
Vagrant.configure(2) do |config|
config.vm.box = "box-cutter/ubuntu1404-desktop"
config.ssh.forward_agent = true
config.vm.network "forwarded_port", guest: 8080, host: 8080
config.vm.network "forwarded_port", guest: 3000, host: 3000
config.vm.synced_folder "../../git", "/home/vagrant/git"
config.vm.provider "virtualbox" do |vb|
vb.gui = true
vb.customize ["modifyvm", :id, "--monitorcount", "2"]
vb.memory = "2048"
end
end

You might also consider using Packer to create VirtualBox images for developers to use.
Rather than sharing the Vagrantfile which developers each use to build and run their VM, you would have a packer template (json) which is used to create a VM image. Developers download or copy the image and run it locally, directly in VB, without having to build it themselves.
Many of the publicly shared Vagrant base boxes are created with Packer.

https://askubuntu.com/questions/300799/does-ubuntu-12-04-lts-32-bit-have-graphic-user-interface/300805#300805
After installing the desktop, you'll also want to install GDM which
will let you boot directly into a graphical environment. You'll also
want to configure it.
So maybe add this?
Vagrant::Config.run do |config|
config.vm.provision :shell, :inline => "sudo apt-get install gdm"
config.vm.provision :shell, :inline => "sudo dpkg-reconfigure gdm"
end

I've patched Nik's answer a bit to avoid HTTP 404:
Vagrant.configure(2) do |config|
# Ubuntu 15.10
config.vm.box = "bento/ubuntu-18.04"
config.vm.provider "virtualbox" do |vb|
# Display the VirtualBox GUI when booting the machine
vb.gui = true
end
# Install xfce and virtualbox additions
config.vm.provision "shell", inline: "sudo apt-get update"
config.vm.provision "shell", inline: "sudo apt-get install -y xfce4 virtualbox-guest-dkms virtualbox-guest-utils virtualbox-guest-x11"
# Permit anyone to start the GUI
config.vm.provision "shell", inline: "sudo sed -i 's/allowed_users=.*$/allowed_users=anybody/' /etc/X11/Xwrapper.config"
end

Adding to billmalarky's comment above, on fedora 20 the following was necessary before starting xfce:
Install VirtualBox-guest.rpm (available from rpmfusion repos)
yum groups mark install 'graphical_environment'
yum groupinstall "Xfce"
yum install xorg-x11-drivers
Here is the code:
config.vm.provision "shell", inline: <<-SHELL
#Install Virtual Box guest additions from rpmfusion repos
cd /vagrant
yum install -y rpmfusion-free-release-20.noarch.rpm
yum install -y rpmfusion-nonfree-release-20.noarch.rpm
yum update -y
yum install -y VirtualBox-guest
#Add XFCE desktop to fedora server
yum groups mark install 'graphical_environment'
yum groupinstall -y "Xfce"
yum install -y xorg-x11-drivers
SHELL

Like the xfce4 solution by #Air. Once I had success, but today I failed with ubuntu16.04. I got this error:
xrdb can't open display 1
But luckily, I found this works:
startx

I see a few people are having problems with "startx: command not found". I had this too and it was because I was trying login and startx before the first-time provisioning had completed. Be patient, go grab a coffee. Check the original console window to see what is happening especially when the provisioning has finished.

Related

Is there a way to make the root user use agent forwarding in vagrant

When I use the following config in Vagrant:
Vagrant.configure("2") do |config|
config.ssh.forward_agent = true
end
While running git, I can use ssh agent forwarding on the guest with user: vagrant, but it does not work with the user: root (I get permission denied).
I need it to work with the user: root as puppet provisioning runs as root.
Is there a way to force vagrant to also allow ssh agent forwarding with the user: root?
My understanding is that it isn't possible to make a privileged vm.provision section work with SSH agent forwarding. Fundamentally, a privileged section needs to do a sudo, which breaks the link to the SSH agent.
That said, I use agent forwarding for accessing Git repos when provisioning with Puppet. I split the git and puppet commands into separate sections, privileged or not as needed:
Vagrant.configure(2) do |config|
config.vm.box = "centos/7"
config.ssh.forward_agent = true
config.vm.provision "shell", inline: <<-SHELL
yum -y update
yum install -y git
rpm -Uvh https://yum.puppet.com/puppet6-release-el-7.noarch.rpm
yum install -y puppet-agent
SHELL
config.vm.provision "shell", inline: <<-SHELL, privileged: false
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# You may get failure to autenticate error messages without this.
ssh-keyscan -H github.com >> ~/.ssh/known_hosts
git clone git#github.com:group/control.git /vagrant/control
cd /vagrant/control
git checkout branch
SHELL
config.vm.provision "shell", inline: <<-SHELL
cd /vagrant/control
/opt/puppetlabs/bin/puppet apply manifest/site.pp
SHELL
end

Vagrant/Mac port forwarding is not working

Mac OS here. I am unable to get Vagrant port-forwarding to work from my guest VMs to my host. I am following the Networking/Port-Forwarding tutorial verbatim.
Here's my project:
testvm/
Vagrantfile
bootstrap.sh
Where bootstrap.sh installs Apache httpd:
#!/usr/bin/env bash
apt-get update
apt-get install -y apache2
if ! [ -L /var/www ]; then
rm -rf /var/www
ln -fs /vagrant /var/www
fi
And my Vagrantfile:
Vagrant.configure(2) do |config|
config.vm.provision :shell, path: "bootstrap.sh"
config.vm.network :forwarded_port, guest: 80, host: 4567
config.vm.box = "hashicorp/precise32"
end
When I vagrant up I get no errors, but when I open a web browser and go to http://127.0.0.1:4567 and I get a Safari "Failed to open page", instead of the "Hey it works!"-type page you typically get with httpd.
Any ideas as to what is going wrong here?
Have you checked the firewall on the VM is disabled/allows access to port 80?
Inside of the VM does it work as expected with
$ curl http://localhost

Apache fails to start on Vagrant

In my Vagrant environment I have a guest Ubuntu Virtualbox with a LAMP with default settings.
I have my source code on the host machine in the same folder as my Vagrantfile. So on the guest Ubuntu I can access the files in the mounted /vagrant dir like this
/vagrant
/mysite
/index.php
/Vagrantfile
Now in my Apache config I add a line
Alias /mysite /vagrant/mysite
After reloading config and restarting apache I can go to localhost:8558/mysite/index.php and it works.
The problem is that when I reload Virtualbox with vagrant reload it starts Apache service before mounting the /vagrant folder. So Apache can't find the aliased dir and fails to start. i have to start it manually then
My question is - is there a way to delay Apache start so that it starts after the mounting?
Update: As a workaround I added script to the crontab that starts apache 30 seconds after the boot as described here. But I wonder if there is a better solution.
while upstart probably is a valid option, I had several issues using it with vagrant. I had to run several tasks that needed to be run as a privileged user, which I did not manage to get working with upstart.
Starting from version 1.6.0 (May 6, 2014), vagrant provides the option to run a specific provisioner every time, so also after booting a halted VM with vagrant up.
In your Vagrantfile, add:
# a file, eg after-boot.sh
config.vm.provision "shell", path: "after-boot.sh", run: "always"
# or just inline
config.vm.provision "shell", inline: "service apache2 restart", run: "always"
note the run: "always", this will force vagrant to run the provisioner always, obviously it works just as well with any other provisioning system like chef or puppet.
I would like to add a little to Zauberfisch's answer (Apache fails to start on Vagrant)
What needed to happen was this command needed to be run as a superuser AKA 'Sudo' so this was the command that was needed:
`config.vm.provision "shell", inline: "sudo service apache2 restart", run: "always"`
The reason why this didn't work for you without the sudo appears to be that Vagrant tries to run the command without /usr/sbin in PATH. For me, this worked just as well:
`config.vm.provision "shell", inline: "/usr/sbin/service apache2 restart", run: "always"`
If upstart is installed (as in Ubuntu), Vagrant emits "vagrant-mounted" event. See https://serverfault.com/a/568033/179583 to get the idea. In your script you can (re)start the Apache server.
Btw, I have a feeling that newer Apache versions just warn, but still start even if the doc root doesn't exist. The same with nginx.

rvm cookbook fails installing ruby within vagrant

I've been running into issues when trying to run the rvm::user recipe from fnichol/chef-rvm. I'm using chef along with a Vagrant box. rvm installs fine, but every time chef tries to install a ruby, it fails with this error:
WARN: Failed to install rvm_ruby[ruby-1.9.3-p448]. Check logs in /log/ruby-1.9.3-p448
Here's my Vagrantfile:
Vagrant.configure("2") do |config|
config.vm.box = 'precise32'
config.vm.box_url = 'http://files.vagrantup.com/precise32.box'
config.vm.provision "chef_solo" do |chef|
chef.add_recipe "rvm::vagrant"
chef.add_recipe "rvm::user"
chef.json = {
:rvm => {
:user_installs => [
{
:user => "vagrant",
:default_ruby => "1.9.3",
:rubies => ["1.9.3"],
:global_gems => [
{ :name => 'bundler' }
],
}
]
}
end
end
Environment Details:
Vagrant version: 1.2.7
Vagrant vm: precise32
rvm version: 1.22.11
chef-rvm ref: 59dc482
It turns out that Vagrant was running chef in a non-interactive/non-tty session. The sudo command doesn't like to run in non-interactive sessions, and causes rvm to fail when it tries install dependencies (via apt-get in ubuntu).
You can allow sudo to run non-interactively by adding this to /etc/sudoers:
vagrant ALL= (ALL:ALL) NOPASSWD: ALL
Once I added this, chef installed the rvm::user recipe successfully.
My setup was much more complicated, however the error was the same. Ultimately i found that adding the apt chef recipe fixed everything.
chef.add_recipe "apt"
chef.add_recipe "rvm::vagrant"
chef.add_recipe "rvm::user"
> Run List is [recipe[apt], recipe[curl], recipe[rvm::vagrant], recipe[rvm::user]]
Adding the line
vagrant ALL=(ALL:ALL) NOPASSWD: ALL
didn't work for my scenario.
I believe the apt chef recipe runs apt update which fixes an issue with old and ill matched versions.
The error messages i received were
Error executing action `install` on resource 'package[libxml2-dev]'
apt-get -q -y install libxml2-dev=2.7.8.dfsg-5.1ubuntu4.1 returned 100, expected 0
....
Error executing action `install` on resource 'rvm_ruby[2.1.1]'

Vagrant fails to mount NFS shared folders because of corrupted /etc/exports. How do I fix that file?

I recently tried to install a VM with vagrant but "vagrant up" always failed with the error:
Mounting NFS shared folders failed. This is most often caused by the NFS
client software not being installed on the guest machine. Please verify
that the NFS client software is properly installed, and consult any resources
specific to the linux distro you're using for more information on how to
do this.
NFS client was properly installed on my machine so I looked for other causes of errors and found a blogpost explaining that my /etc/exports might be corrupted. I restored exportsbak (which contains only commented examples), hoping that vagrant would reconfigure that file properly... but it doesn't, and the error is still there.
How can I force vagrant to regenerate that file or fix it? Thanks.
Just delete the file.
sudo rm -f /etc/exports
The file will be recreated during the vagrant up process.
I was not able to get nfs running on my Ubuntu, because I used the vagrant packages from apt (V 1.2.2)
I installed the latest Vagrant Version (1.5) from here: http://www.vagrantup.com/downloads
and nfs worked.
Check the NSF server is not installed, you can do…
dpkg -l | grep nfs-kernel-server
If it is not installed, install the required packages…
apt-get install nfs-kernel-server
apt-get install nfs-common
service nfs-kernel-server restart
sudo service portmap restart
mkdir -p /var/exports
Then in Vagranfile add line under #shared folders...
config.vm.synced_folder "www", "/var/www", :nfs => { :mount_options => "dmode=755","fmode=755"] }
When vagrant is starting it will ask for root password, to run it without root password you can edit /etc/sudoers and add following lines…
Cmnd_Alias VAGRANT_EXPORTS_ADD = /usr/bin/tee -a /etc/exports
Cmnd_Alias VAGRANT_NFSD_CHECK = /etc/init.d/nfs-kernel-server status
Cmnd_Alias VAGRANT_NFSD_START = /etc/init.d/nfs-kernel-server start
Cmnd_Alias VAGRANT_NFSD_APPLY = /usr/sbin/exportfs -ar
Cmnd_Alias VAGRANT_EXPORTS_REMOVE = /bin/sed -r -e * d -ibak /etc/exports
%sudo ALL=(root) NOPASSWD: VAGRANT_EXPORTS_ADD, VAGRANT_NFSD_CHECK, VAGRANT_NFSD_START, VAGRANT_NFSD_APPLY, VAGRANT_EXPORTS_REMOVE
if your host is Windows, then you need to install a vagrant plugin Vagrant WinNFSd.
$ vagrant plugin install vagrant-winnfsd