» Plugin Development: Guest Capabilities

This page documents how to add new capabilities for gueststo Vagrant, allowing Vagrant to perform new actions on specific guestoperating 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.

Guest capabilities augment guests by attachingspecific "capabilities" to the guest, which are actions that can be performedin the context of that guest operating system.

The power of capabilities is that plugins can add new capabilities toexisting guest operating systems without modifying the core of Vagrant.In earlier versions of Vagrant, all the guest logic was contained in thecore of Vagrant and was not easily augmented.

» Definition Component

Within the context of a plugin definition, guest capabilities can bedefined like so:

  1. guest_capability "ubuntu", "my_custom_capability" do
  2. require_relative "cap/my_custom_capability"
  3. Cap::MyCustomCapability
  4. end

Guest capabilities are defined by calling the guest_capability method,which takes two parameters: the guest to add the capability to, and thename of the capability itself. Then, the block argument returns a classthat implements a method named the same as the capability. This iscovered in more detail in the next section.

» Implementation

Implementations should be classes or modules that have a method withthe same name as the capability. The method must be immediately accessibleon the class returned from the guest_capability component, meaning thatif it is an instance method, an instance should be returned.

In general, class methods are used for capabilities. For example, hereis the implementation for the capability above:

  1. module Cap
  2. class MyCustomCapability
  3. def self.my_custom_capability(machine)
  4. # implementation
  5. end
  6. end
  7. end

All capabilities get the Vagrant machine object as the first argument.Additional arguments are determined by the specific capability, so view thedocumentation or usage of the capability you are trying to implement for moreinformation.

Some capabilities must also return values back to the caller, so be awareof that when implementing a capability.

Capabilities always have access to communication channels such as SSHon the machine, and the machine can generally be assumed to be booted.

» Calling Capabilities

Since you have access to the machine in every capability, capabilities canalso call other capabilities. This is useful for using the inheritancemechanism of capabilities to potentially ask helpers for more information.For example, the "redhat" guest has a "network_scripts_dir" capability thatsimply returns the directory where networking scripts go.

Capabilities on child guests of RedHat such as CentOS or Fedora use thiscapability to determine where networking scripts go, while sometimes overridingit themselves.

Capabilities can be called like so:

  1. machine.guest.capability(:capability_name)

Any additional arguments given to the method will be passed on to thecapability, and the capability will return the value that the actualcapability returned.