From Fedora Project Wiki

m (Move the introduction to Vagrant outside the "Using Vagrant in Fedora" block)
(Update the example Vagrantfile to include several fancy techniques like package caching)
 
Line 7: Line 7:
To quickly get started with Vagrant on a Fedora host, the Fedora developers have conveniently packaged vagrant-libvirt and a handful of handy Vagrant plugins for you. All you need to do is to install vagrant-libvirt and the plugins you wish to use, write a Vagrantfile for your project, and type "vagrant up" to get started. Here's an example Vagrantfile:
To quickly get started with Vagrant on a Fedora host, the Fedora developers have conveniently packaged vagrant-libvirt and a handful of handy Vagrant plugins for you. All you need to do is to install vagrant-libvirt and the plugins you wish to use, write a Vagrantfile for your project, and type "vagrant up" to get started. Here's an example Vagrantfile:


$ cat Vagrantfile
  # -*- mode: ruby -*-
# -*- mode: ruby -*-
  # vi: set ft=ruby :
# vi: set ft=ruby :
  #
  # Copy this file to ``Vagrantfile`` and customize it as you see fit.
# On your host:
 
# git clone https://github.com/fedora-infra/bodhi.git
  VAGRANTFILE_API_VERSION = "2"
# cd bodhi
 
# cp Vagrantfile.example Vagrantfile
  Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# vagrant up
  # If you'd prefer to pull your boxes from Hashicorp's repository, you can
# vagrant ssh -c "cd /vagrant/; pserve development.ini --reload"
  # replace the config.vm.box and config.vm.box_url declarations with the line below.
  #
Vagrant.configure(2) do |config|
  # config.vm.box = "fedora/25-cloud-base"
   config.vm.box_url = "https://download.fedoraproject.org/pub/fedora/linux/releases/24/CloudImages/x86_64/images/Fedora-Cloud-Base-Vagrant-24-1.2.x86_64.vagrant-libvirt.box"
  config.vm.box = "f25-cloud-libvirt"
   config.vm.box = "f24-cloud-libvirt"
   config.vm.box_url = "https://download.fedoraproject.org/pub/fedora/linux/releases"\
   config.vm.network "forwarded_port", guest: 80, host: 80
                      "/25/CloudImages/x86_64/images/Fedora-Cloud-Base-Vagrant-25-1"\
   config.vm.synced_folder ".", "/vagrant", type: "sshfs"
                      ".3.x86_64.vagrant-libvirt.box"
 
   config.vm.provider :libvirt do |domain|
   # Forward traffic on the host to the development server on the guest.
      domain.cpus = 4
  # You can change the host port that is forwarded to 5000 on the guest
      domain.graphics_type = "spice"
  # if you have other services listening on your host's port 80.
       domain.memory = 1024
   config.vm.network "forwarded_port", guest: 5000, host: 80
       domain.video_type = "qxl"
 
   # This is an optional plugin that, if installed, updates the host's /etc/hosts
   # file with the hostname of the guest VM. In Fedora it is packaged as
  # ``vagrant-hostmanager``
  if Vagrant.has_plugin?("vagrant-hostmanager")
       config.hostmanager.enabled = true
       config.hostmanager.manage_host = true
   end
   end
 
   config.vm.provision "shell", inline: "echo hello_world > /home/vagrant/hello_world.txt"
  # Vagrant can share the source directory using rsync, NFS, or SSHFS (with the vagrant-sshfs
  # plugin). Consult the Vagrant documentation if you do not want to use SSHFS.
   # Uncomment the following block if you have a playbook at devel/ansible/playbook.yml you want Vagrant to run on the guest for you
   config.vm.synced_folder ".", "/vagrant", disabled: true
   # # Ansible needs the guest to have these
  config.vm.synced_folder ".", "/home/vagrant/devel", type: "sshfs", sshfs_opts_append: "-o nonempty"
  # config.vm.provision "shell", inline: "sudo dnf install -y libselinux-python python2-dnf"
 
   # To cache update packages (which is helpful if frequently doing `vagrant destroy && vagrant up`)
  # you can create a local directory and share it to the guest's DNF cache. Uncomment the lines below
   # to create and use a dnf cache directory
   #
   #
   # config.vm.provision "ansible" do |ansible|
   # Dir.mkdir('.dnf-cache') unless File.exists?('.dnf-cache')
  #    ansible.playbook = "devel/ansible/playbook.yml"
  # config.vm.synced_folder ".dnf-cache", "/var/cache/dnf", type: "sshfs", sshfs_opts_append: "-o nonempty"
   # end
 
end
  # Comment this line if you would like to disable the automatic update during provisioning
  config.vm.provision "shell", inline: "sudo dnf upgrade -y"
 
  # bootstrap and run with ansible
  config.vm.provision "shell", inline: "sudo dnf -y install python2-dnf libselinux-python"
  config.vm.provision "ansible" do |ansible|
      ansible.playbook = "devel/ansible/vagrant-playbook.yml"
   end
 
 
  # Create the "nuancier" box
  config.vm.define "nuancier" do |nuancier|
      nuancier.vm.host_name = "nuancier-dev.example.com"
 
      nuancier.vm.provider :libvirt do |domain|
          # Season to taste
          domain.cpus = 4
          domain.graphics_type = "spice"
          domain.memory = 2048
          domain.video_type = "qxl"
 
          # Uncomment the following line if you would like to enable libvirt's unsafe cache
          # mode. It is called unsafe for a reason, as it causes the virtual host to ignore all
          # fsync() calls from the guest. Only do this if you are comfortable with the possibility of
          # your development guest becoming corrupted (in which case you should only need to do a
          # vagrant destroy and vagrant up to get a new one).
          #
          # domain.volume_cache = "unsafe"
      end
  end
  end
 


In this example, we're using the Fedora 24 libvirt box and we're assuming that your project has an ansible playbook at the relative path <code>devel/ansible/playbook.yml</code>. Writing ansible playbooks is beyond the scope of this document, and you are free to use config.vm.provision lines to configure your Vagrant guest if you like.
In this example, we're using the Fedora 25 libvirt box and we're assuming that your project has an ansible playbook at the relative path <code>devel/ansible/playbook.yml</code>. Writing ansible playbooks is beyond the scope of this document, and you are free to use config.vm.provision lines to configure your Vagrant guest if you like.


To get started with the above example, simply write the code to a file called Vagrantfile, install vagrant-libvirt and vagrant-sshfs, and run vagrant up:
To get started with the above example, simply write the code to a file called Vagrantfile, install vagrant-libvirt, vagrant-sshfs, and optionally vagrant-hostmanager, then run vagrant up:


  $ cd ~/devel/my_project
  $ cd ~/devel/my_project
  $ vim Vagrantfile  # Write the above Vagrant code here
  $ vim Vagrantfile  # Write the above Vagrant code here
  $ sudo dnf install vagrant-libvirt vagrant-sshfs
  $ sudo dnf install libvirt vagrant vagrant-libvirt vagrant-sshfs
  $ vagrant up
  $ vagrant up


Once your guest is running, you can ssh into the guest. Your code directory from the host will be shared into the guest at the path /vagrant:
Once your guest is running, you can ssh into the guest. Your code directory from the host will be shared into the guest at the path ~/devel:


  $ vagrant ssh
  $ vagrant ssh
  $ [vagrant@localhost ~]$ ls /vagrant/Vagrantfile
  $ [vagrant@localhost ~]$ ls devel/
  /vagrant/Vagrantfile
  Vagrantfile


Now you can edit your project on your host, and the changes you make will be shared into the guest's /vagrant folder live. This allows you to use your editor of choice (even graphical editors!) on the host, while keeping everything that might "dirty" you host system contained in the guest virtual machine. This example Vagrantfile has also set up a port forward from 80 in the guest to 80 on the host, so if there were a web application listening in the guest on port 80, you could browse to http://localhost on the host to access it.
Now you can edit your project on your host, and the changes you make will be shared into the guest's ~/devel/ folder live. This allows you to use your editor of choice (even graphical editors!) on the host, while keeping everything that might "dirty" you host system contained in the guest virtual machine. This example Vagrantfile has also set up a port forward from 5000 in the guest to 5000 on the host, so if there were a web application listening in the guest on port 5000, you could browse to http://localhost:80 on the host to access it. If you installed vagrant-hostmanager, you could also browse http://nuancier-dev.example.com:5000.


When you are done with your Vagrant guest, you can destroy it:
When you are done with your Vagrant guest, you can destroy it:

Latest revision as of 17:15, 12 December 2016

Vagrant is a useful development tool that lowers the barrier to entry to new contributor of your project. With Vagrant, new contributors don't have to spend much time configuring their development environment, but can quickly get one automatically provisioned for them with a few simple commands.

Using Vagrant in Fedora

Fedora's Cloud working group provides Fedora Vagrant boxes for libvirt and Virtualbox. You can see the Fedora 24 Vagrant images here.

To quickly get started with Vagrant on a Fedora host, the Fedora developers have conveniently packaged vagrant-libvirt and a handful of handy Vagrant plugins for you. All you need to do is to install vagrant-libvirt and the plugins you wish to use, write a Vagrantfile for your project, and type "vagrant up" to get started. Here's an example Vagrantfile:

 # -*- mode: ruby -*-
 # vi: set ft=ruby :
 #
 # Copy this file to Vagrantfile and customize it as you see fit.
 
 VAGRANTFILE_API_VERSION = "2"
 
 Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # If you'd prefer to pull your boxes from Hashicorp's repository, you can
  # replace the config.vm.box and config.vm.box_url declarations with the line below.
  #
  # config.vm.box = "fedora/25-cloud-base"
  config.vm.box = "f25-cloud-libvirt"
  config.vm.box_url = "https://download.fedoraproject.org/pub/fedora/linux/releases"\
                      "/25/CloudImages/x86_64/images/Fedora-Cloud-Base-Vagrant-25-1"\
                      ".3.x86_64.vagrant-libvirt.box"
 
  # Forward traffic on the host to the development server on the guest.
  # You can change the host port that is forwarded to 5000 on the guest
  # if you have other services listening on your host's port 80.
  config.vm.network "forwarded_port", guest: 5000, host: 80
 
  # This is an optional plugin that, if installed, updates the host's /etc/hosts
  # file with the hostname of the guest VM. In Fedora it is packaged as
  # vagrant-hostmanager
  if Vagrant.has_plugin?("vagrant-hostmanager")
      config.hostmanager.enabled = true
      config.hostmanager.manage_host = true
  end
 
  # Vagrant can share the source directory using rsync, NFS, or SSHFS (with the vagrant-sshfs
  # plugin). Consult the Vagrant documentation if you do not want to use SSHFS.
  config.vm.synced_folder ".", "/vagrant", disabled: true
  config.vm.synced_folder ".", "/home/vagrant/devel", type: "sshfs", sshfs_opts_append: "-o nonempty"
 
  # To cache update packages (which is helpful if frequently doing vagrant destroy && vagrant up)
  # you can create a local directory and share it to the guest's DNF cache. Uncomment the lines below
  # to create and use a dnf cache directory
  #
  # Dir.mkdir('.dnf-cache') unless File.exists?('.dnf-cache')
  # config.vm.synced_folder ".dnf-cache", "/var/cache/dnf", type: "sshfs", sshfs_opts_append: "-o nonempty"
 
  # Comment this line if you would like to disable the automatic update during provisioning
  config.vm.provision "shell", inline: "sudo dnf upgrade -y"
 
  # bootstrap and run with ansible
  config.vm.provision "shell", inline: "sudo dnf -y install python2-dnf libselinux-python"
  config.vm.provision "ansible" do |ansible|
      ansible.playbook = "devel/ansible/vagrant-playbook.yml"
  end
 
 
  # Create the "nuancier" box
  config.vm.define "nuancier" do |nuancier|
     nuancier.vm.host_name = "nuancier-dev.example.com"
 
     nuancier.vm.provider :libvirt do |domain|
         # Season to taste
         domain.cpus = 4
         domain.graphics_type = "spice"
         domain.memory = 2048
         domain.video_type = "qxl"
 
         # Uncomment the following line if you would like to enable libvirt's unsafe cache
         # mode. It is called unsafe for a reason, as it causes the virtual host to ignore all
         # fsync() calls from the guest. Only do this if you are comfortable with the possibility of
         # your development guest becoming corrupted (in which case you should only need to do a
         # vagrant destroy and vagrant up to get a new one).
         #
         # domain.volume_cache = "unsafe"
     end
  end
 end


In this example, we're using the Fedora 25 libvirt box and we're assuming that your project has an ansible playbook at the relative path devel/ansible/playbook.yml. Writing ansible playbooks is beyond the scope of this document, and you are free to use config.vm.provision lines to configure your Vagrant guest if you like.

To get started with the above example, simply write the code to a file called Vagrantfile, install vagrant-libvirt, vagrant-sshfs, and optionally vagrant-hostmanager, then run vagrant up:

$ cd ~/devel/my_project
$ vim Vagrantfile  # Write the above Vagrant code here
$ sudo dnf install libvirt vagrant vagrant-libvirt vagrant-sshfs
$ vagrant up

Once your guest is running, you can ssh into the guest. Your code directory from the host will be shared into the guest at the path ~/devel:

$ vagrant ssh
$ [vagrant@localhost ~]$ ls devel/
Vagrantfile

Now you can edit your project on your host, and the changes you make will be shared into the guest's ~/devel/ folder live. This allows you to use your editor of choice (even graphical editors!) on the host, while keeping everything that might "dirty" you host system contained in the guest virtual machine. This example Vagrantfile has also set up a port forward from 5000 in the guest to 5000 on the host, so if there were a web application listening in the guest on port 5000, you could browse to http://localhost:80 on the host to access it. If you installed vagrant-hostmanager, you could also browse http://nuancier-dev.example.com:5000.

When you are done with your Vagrant guest, you can destroy it:

$ vagrant destroy

It is good practice to check in a Vagrantfile.example file in your project's source code, rather than the Vagrantfile itself. This allows new developers a quick way to get started by just copying your example into place, but it also allows each contributor to make the changes they prefer to their individual Vagrantfiles.