diff --git a/website/docs/source/layouts/layout.erb b/website/docs/source/layouts/layout.erb index 9b301a3aa..1d05c5b79 100644 --- a/website/docs/source/layouts/layout.erb +++ b/website/docs/source/layouts/layout.erb @@ -219,6 +219,7 @@ >Guests >Guest Capabilities >Hosts + >Host Capabilities >Providers >Provisioners >Packaging & Distribution diff --git a/website/docs/source/v2/plugins/guests.html.md b/website/docs/source/v2/plugins/guests.html.md index 529ead41f..4cc1b8739 100644 --- a/website/docs/source/v2/plugins/guests.html.md +++ b/website/docs/source/v2/plugins/guests.html.md @@ -64,7 +64,7 @@ end ``` After detecting an OS, that OS is used for various -[guest capabilities](/v2/plugins/guest_capabilities.html) that may be +[guest capabilities](/v2/plugins/guest-capabilities.html) that may be required. ## Guest Inheritance @@ -76,7 +76,7 @@ Inheritance allows guests to share a lot of common behavior while allowing distro-specific overrides. Inheritance is not done via standard Ruby class inheritance because Vagrant -uses a custom [capability-based](/v2/plugins/guest_capabilities.html) system. +uses a custom [capability-based](/v2/plugins/guest-capabilities.html) system. Vagrant handles inheritance dispatch for you. To subclass another guest, specify that guest's name as a second parameter diff --git a/website/docs/source/v2/plugins/host-capabilities.html.md b/website/docs/source/v2/plugins/host-capabilities.html.md new file mode 100644 index 000000000..b11ebe208 --- /dev/null +++ b/website/docs/source/v2/plugins/host-capabilities.html.md @@ -0,0 +1,63 @@ +--- +page_title: "Host Capabilities - Plugin Development" +sidebar_current: "plugins-hostcapabilities" +--- + +# Plugin Development: Host Capabilities + +This page documents how to add new capabilities for [hosts](/v2/plugins/hosts.html) +to Vagrant, allowing Vagrant to perform new actions on specific host +operating systems. +Prior to reading this, you should be familiar +with the [plugin development basics](/v2/plugins/development-basics.html). + +
+

+ Warning: Advanced Topic! Developing plugins is an + advanced topic that only experienced Vagrant users who are reasonably + comfortable with Ruby should approach. +

+
+ +Host capabilities augment [hosts](/v2/plugins/hosts.html) by attaching +specific "capabilities" to the host, which are actions that can be performed +in the context of that host operating system. + +The power of capabilities is that plugins can add new capabilities to +existing host operating systems without modifying the core of Vagrant. +In earlier versions of Vagrant, all the host logic was contained in the +core of Vagrant and wasn't easily augmented. + +## Definition and Implementation + +The definition and implementation of host capabilities is identical +to [guest capabilities](/v2/plugins/guest-capabilities.html). + +The main difference from guest capabilities, however, is that instead of +taking a machine as the first argument, all host capabilities take an +instance of `Vagrant::Environment` as their first argument. + +Access to the environment allows host capabilities to access global state, +specific machines, and also allows them to call other host capabilities. + +## Calling Capabilities + +Since you have access to the environment in every capability, capabilities can +also call _other_ host capabilities. This is useful for using the inheritance +mechanism of capabilities to potentially ask helpers for more information. +For example, the "linux" guest has a "nfs\_check\_command" capability that +returns the command to use to check if NFS is running. + +Capabilities on child guests of Linux such as RedHat or Arch use this +capability to mostly inherit the Linux behavior, except for this minor +detail. + +Capabilities can be called like so: + +```ruby +environment.host.capability(:capability_name) +``` + +Any additional arguments given to the method will be passed on to the +capability, and the capability will return the value that the actual +capability returned. diff --git a/website/docs/source/v2/plugins/hosts.html.md b/website/docs/source/v2/plugins/hosts.html.md index cf8d72f4e..aaf1d6bdf 100644 --- a/website/docs/source/v2/plugins/hosts.html.md +++ b/website/docs/source/v2/plugins/hosts.html.md @@ -5,9 +5,9 @@ sidebar_current: "plugins-hosts" # Plugin Development: Hosts -This page documents how to add new host OS implementations to Vagrant, -allowing Vagrant to properly configure new host operating systems -for features such as NFS shared folders. Prior to reading this, you should be familiar +This page documents how to add new host OS detection to Vagrant, allowing +Vagrant to properly execute host-specific operations on new operating systems. +Prior to reading this, you should be familiar with the [plugin development basics](/v2/plugins/development-basics.html).
@@ -18,29 +18,78 @@ with the [plugin development basics](/v2/plugins/development-basics.html).

+Vagrant has some features that require host OS-specific actions, such as +exporting NFS folders. These tasks vary from operating system to operating +system. Vagrant uses host detection as well as +[host capabilities](/v2/plugins/host-capabilities.html) to perform these +host OS-specific operations. + ## Definition Component Within the context of a plugin definition, new hosts can be defined like so: ```ruby -host "some_os" do +host "ubuntu" do require_relative "host" Host end ``` -Guests are defined with the `host` method. The first argument is th -name of the host. This name isn't actually used anywhere, but may in -the future, so choose something helpful. Then, the block argument returns a +Hosts are defined with the `host` method. The first argument is the +name of the host. This name isn't actually used anywhere, but may in the +future, so choose something helpful. Then, the block argument returns a class that implements the `Vagrant.plugin(2, :host)` interface. ## Implementation -Implementations of hosts subclass `Vagrant.plugin(2, :host)`. Within -this implementation, various methods for different tasks must be implemented. -Instead of going over each task, the easiest example would be to take a -look at an existing host implementation. +Implementations of hosts subclass `Vagrant.plugin("2", "host")`. Within +this implementation, only the `detect?` method needs to be implemented. -There are [many host implementations](https://github.com/mitchellh/vagrant/tree/master/plugins/hosts), -but you can view the [BSD host implementation](https://github.com/mitchellh/vagrant/blob/master/plugins/hosts/bsd/host.rb) as a starting point. +The `detect?` method is called by Vagrant very early on in its initialization +process to determine if the OS that Vagrant is running on is this hsot. +If you detect that it is your operating system, return `true` from `detect?`. +Otherwise, return `false`. + +``` +class MyHost < Vagrant.plugin("2", "host") + def detect?(environment) + File.file?("/etc/arch-release") + end +end +``` + +After detecting an OS, that OS is used for various +[host capabilities](/v2/plugins/host-capabilities.html) that may be +required. + +## Host Inheritance + +Vagrant also supports a form of inheritance for hosts, since sometimes +operating systems stem from a common root. A good example of this is Linux +is 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 allowing +distro-specific overrides. + +Inheritance is not done via standard Ruby class inheritance because Vagrant +uses a custom [capability-based](/v2/plugins/host-capabilities.html) system. +Vagrant handles inheritance dispatch for you. + +To subclass another host, specify that host's name as a second parameter +in the host definition: + +```ruby +host "ubuntu", "debian" do + require_relative "host" + Host +end +``` + +With the above component, the "ubuntu" host inherits from "debian." When +a capability is looked up for "ubuntu", all capabilities from "debian" are +also available, and any capabilities in "ubuntu" override parent capabilities. + +When detecting operating systems with `detect?`, Vagrant always does a +depth-first search by searching the children operating systems before +checking their parents. Therefore, it is guaranteed in the above example +that the `detect?` method on "ubuntu" will be called before "debian."