Skip to content

Instantly share code, notes, and snippets.

View mitchellh's full-sized avatar
👻
Building.

Mitchell Hashimoto mitchellh

👻
Building.
View GitHub Profile

Making Plugins Easier in Vagrant

Vagrant plugins currently expose the FULL POWER of Vagrant. Unfortunately, as is often the case, "full power" means "complicated" (relatively), especially for those not familiar with Ruby.

Instead, I'd like to introduce an alternative "simple" API to plugins as well that people can confidently use. Below are some examples of this. I'm not even going to describe what each plugin does because it should be simple enough from the code, that's how simple they are!

The end goal is that it should be much more common to see Vagrant projects ship with custom commands like vagrant run-tests or vagrant start-server, to perform common tasks that previously required SSH.

These "easy" plugins can't do everything but they will be able to do the common things. If you want more power, full (non-easy) plugins should be used.

#!/bin/bash
cat <<EOF | erl_call -s -name foo@localhost -c foo -e
erlv8:stop(),
erlv8:start().
EOF

Gem-Based Plugin Autoloading Removed in Vagrant 1.1

Thanks to @vStone for pointing out the performance issue.

Since plugins were introduced, Vagrant has allowed plugins packaged as gems to autoload themselves by creating a file named "vagrant_init.rb" somewhere on their load path. This was intended as a way for gem authors to make installation ridiculously simple, and it worked!

However, this involved a significant impact on performance and this has been removed for a more manual approach in Vagrant 1.1. In Vagrant 1.1, users will be expected to have a ~/.vagrantrc file which manually includes plugins they've installed via vagrant gem. Gems can also, as always, be loaded in any Vagrantfile as well.

For more information, read on...

@mitchellh
mitchellh / gist:2855234
Created June 1, 2012 21:29
Easy Plugin in Vagrant 1.1
# Just throw this in a Vagrant 1.1 Vagrantfile and you get the
# `vagrant fab` command that does what you expect. The command
# to run in fab should go after "--" in the command line, example:
#
# vagrant fab -- deploy:production
# vagrant fab -- -l
#
# Easy plugins. The future.
class Plugin < Vagrant.plugin("1")
name "fab"

"RuntimeError"

"RuntimeError"?!!!!!

I hate people.

/usr/lib/ruby/vendor_ruby/net/scp.rb:385:in `await_response_state': scp: /tmp/vagrant-chef-1/validation.pem: Permission denied (RuntimeError)
CONSTANT = "in <global>"
class Foo
CONSTANT = "in foo"
end
class Foo::Bar
puts CONSTANT # => "in <global>"
end
module Mixin
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def foo
puts "HELLO!"
end
end
@mitchellh
mitchellh / gist:3707876
Created September 12, 2012 16:25
init file for pg clusters on Ubuntu
#!/bin/sh
set -e
### BEGIN INIT INFO
# Provides: postgresql-cluster-<%= @cluster_name %>
# Required-Start: $local_fs $remote_fs $network $time
# Required-Stop: $local_fs $remote_fs $network $time
# Should-Start: $syslog
# Should-Stop: $syslog
# Default-Start: 2 3 4 5
require "fiber"
module Middleware
# This is a basic runner for middleware stacks based on Ruby fibers.
# By using fibers rather than recursion, the stack is not deepened, and
# therefore cannot stack overflow. This allows middleware sequences of
# thousands to be used without crashing Ruby.
#
# This runner is much more complicated than the normal runner because it
# has to do a lot of work to _simulate_ a call stack. For example, one of
#!/bin/bash
#
# This is the script responsible for updating our Puppet master data,
# which includes modules, manifests, hiera data, etc. All of this data is
# managed in a git repository and upon "deploy" it is synced into the Puppet
# master.
#
# This script mirrors the remote git repository, looking for branches that
# match "env-*" (such as "env-production" or "env-test"). Each of these branches
# is setup as an environment into the Puppet master's data files. The