» Plugin Development: Hosts

This page documents how to add new host OS detection to Vagrant, allowingVagrant to properly execute host-specific operations on new operating systems.Prior to reading this, you should be familiarwith the plugin development basics.

Warning: Advanced Topic! Developing plugins is anadvanced topic that only experienced Vagrant users who are reasonablycomfortable with Ruby should approach.

Vagrant has some features that require host OS-specific actions, such asexporting NFS folders. These tasks vary from operating system to operatingsystem. Vagrant uses host detection as well ashost capabilities to perform thesehost OS-specific operations.

» Definition Component

Within the context of a plugin definition, new hosts can be definedlike so:

  1. host "ubuntu" do
  2. require_relative "host"
  3. Host
  4. end

Hosts are defined with the host method. The first argument is thename of the host. This name is not actually used anywhere, but may in thefuture, so choose something helpful. Then, the block argument returns aclass that implements the Vagrant.plugin(2, :host) interface.

» Implementation

Implementations of hosts subclass Vagrant.plugin("2", "host"). Withinthis implementation, only the detect? method needs to be implemented.

The detect? method is called by Vagrant very early on in its initializationprocess to determine if the OS that Vagrant is running on is this host.If you detect that it is your operating system, return true from detect?.Otherwise, return false.

  1. class MyHost < Vagrant.plugin("2", "host")
  2. def detect?(environment)
  3. File.file?("/etc/arch-release")
  4. end
  5. end

After detecting an OS, that OS is used for varioushost capabilities that may berequired.

» Host Inheritance

Vagrant also supports a form of inheritance for hosts, since sometimesoperating systems stem from a common root. A good example of this is Linuxis the root of Debian, which further is the root of Ubuntu in many cases.Inheritance allows hosts to share a lot of common behavior while allowingdistro-specific overrides.

Inheritance is not done via standard Ruby class inheritance because Vagrantuses a custom capability-based system.Vagrant handles inheritance dispatch for you.

To subclass another host, specify that host's name as a second parameterin the host definition:

  1. host "ubuntu", "debian" do
  2. require_relative "host"
  3. Host
  4. end

With the above component, the "ubuntu" host inherits from "debian." Whena capability is looked up for "ubuntu", all capabilities from "debian" arealso available, and any capabilities in "ubuntu" override parent capabilities.

When detecting operating systems with detect?, Vagrant always does adepth-first search by searching the children operating systems beforechecking their parents. Therefore, it is guaranteed in the above examplethat the detect? method on "ubuntu" will be called before "debian."