May 5, 2014
Recently at Paperless Post I’ve been working on upgrading our development environment to the latest version of Vagrant. We’re migrating from 1.0.7 (released back in March 2013) to version 1.5.4 (released in April 2014). In the year between these two releases, a new plugin API was introduced and the API for writing middlewares changed dramatically. So if you have some code that looks like this:
You’ll need to update it before being able to use a current version of Vagrant, first by turning it into a Vagrant plugin, and then by making it use Vagrant’s current middleware API. One catch: this API isn’t documented. Though Vagrant provides some decent documentation for developing plugins, middlewares are left out. By RTFS I was able to uncover the new middleware API.
The key to the new system is the method
action_hook. To port the above code to the new system, it must be written like so:
class SSHKeysPlugin < Vagrant.plugin('2') name "ssh_keys" action_hook(:copy_ssh_keys, :machine_action_up) do |hook| hook.before(VagrantPlugins::ProviderVirtualBox::Action::CheckVirtualbox, Middleware::SSHKeys) end end
Let’s walk through this block of code:
- As described in the plugin documentation, a plugin must be a class that inherits from
- You must
nameyour plugin! If you don’t, your plugin won’t be loaded, and there will be no error message pointing out your mistake. Yes, I learned that the hard way.
action_hook. The first argument is an arbitrary name to call your action. The second is the event to attach your action to. You will likely want one of
machine_action_halt. I haven’t found an exhaustive list of events that can be hooked into, but by hacking this code to print the hooks as they happen, you can see what events are being called.
- Insert a class (
Middleware::SSHKeys, in this case) into the middleware stack by calling
hook.before. There are several ways to add your class to the stack. This class, as before, must implement
call, which is passed the Vagrant environment. Here’s a simple example.
- What was previously called
Vagrant::Action::General::CheckVirtualboxis now called
It’s all very simple once you dig through the source code to figure out how it works. Hopefully this post makes it a little easier to get up and running with the Vagrant middleware system.