Back to Vagrant

Go Vagrant Plugins

website/content/docs/plugins/go-plugins/index.mdx

2.4.92.9 KB
Original Source

⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️

[!IMPORTANT]
Documentation Update: Product documentation previously located in /website has moved to the hashicorp/web-unified-docs repository, where all product documentation is now centralized. Please make contributions directly to web-unified-docs, since changes to /website in this repository will not appear on developer.hashicorp.com. ⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️

Go Vagrant Plugins

With the introduction of Vagrant-go, Vagrant now supports running plugins implemented in Go. Note that Vagrant-go can run Go and Ruby based plugins while Vagrant-ruby only runs Ruby based plugins.

Anatomy of a Go plugin

When a plugin is started, it runs in its own process and is able to communicate with the other plugins over GRPC.

A Vagrant-go plugin must implement an interface for a plugin component. A plugin may satisfy more than one component interface. The plugin interfaces define the <name>Func functions for the plugin. These functions are meant to return the actual function that represents the named action. For example the Host component defines a DetectFunc. So, a plugin must have a DetectFunc implementation that returns a function that can detect if Vagrant is running on the given host. For example

// DetectFunc implements component.Host
func (h *AlwaysTrueHost) DetectFunc() interface{} {
  return h.Detect
}
 
func (h *AlwaysTrueHost) Detect() bool {
  // This plugin always detects that it is running on the expected host
  return true
}

Using this pattern of <name>Func functions, Vagrant is able to allow flexibility over the receivers of the functions that actually define the behavior of the plugin. This injection of dependencies is done using go-argmapper. So, in the same example, the Detect function may be made to accept some arguments.

// DetectFunc implements component.Host
func (h *AlwaysTrueHost) DetectFunc() interface{} {
  return h.Detect
}
 
func (h *AlwaysTrueHost) Detect(string msg, trm terminal.UI) bool {
  trm.Output(msg)
  return true
}

Now, in order to run the Detect function, the caller must provide a string and terminal.UI argument. By default, Vagrant will always inject the following arguments into a call to a plugin:

  • terminal.UI component
  • basis
  • project (when available)
  • context
  • logger

For each component type, Vagrant may also inject some additional arguments.

Outside of these components, the caller must provide all other arguments that are required. So, in the case above, in order to successfully call this Detect function, the caller must also provide a string. It is recommended that plugin authors do not rely on arguments being injected into their implementations outside of these sets of arguments.