75 lines
2.7 KiB
Plaintext
75 lines
2.7 KiB
Plaintext
---
|
|
layout: docs
|
|
page_title: Go Based Plugins
|
|
description: |-
|
|
Vagrant comes with many great features out of the box to get your environments
|
|
up and running. Sometimes, however, you want to change the way Vagrant does
|
|
something or add additional functionality to Vagrant. This can be done via
|
|
Vagrant plugins.
|
|
---
|
|
|
|
# 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](https://github.com/hashicorp/vagrant-plugin-sdk/blob/main/component/component.go).
|
|
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.
|