Skip to content

Instantly share code, notes, and snippets.

@loren-osborn
Last active September 15, 2015 18:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save loren-osborn/06a6e8a95a235266dcdf to your computer and use it in GitHub Desktop.
Save loren-osborn/06a6e8a95a235266dcdf to your computer and use it in GitHub Desktop.
# Handles auto-installing required vagrant plugins:
class PluginAutoInstaller < Vagrant.plugin("2")
name "Plugin Auto-Installer"
description <<-DESC
This (pseudo-plugin) code fragment is intended to be
pasted into the top of your Vagrantfile to ensure your
required manifest of plugins are automatically installed
(or uninstalled) as your Vagrantfile expects.
DESC
def to_s
name
end
class PluginChecker
def initialize(app, env)
@app = app
end
def self.manifest=(new_manifest)
@@required_plugin_manifest = new_manifest.tap do |map|
map.each do |plugin, expectation|
raise "Invalid plugin expectation #{expectation} for plugin #{plugin}" unless [ :required, :prohibited ].include?(expectation)
end
end
end
@@required_plugin_manifest = {}
def call(env)
env[:ui].output("Checking installed plugins for event #{env[:action_name]}")
plugins_to_alter = @@required_plugin_manifest.select do |plugin, expectation|
(Vagrant.has_plugin? plugin) != (expectation == :required)
end
if not plugins_to_alter.empty?
plugins_by_state = Hash.new { |h, k| h[(k == :required) ? :install : :uninstall ] = [] }
plugins_to_alter.each { |k, v| plugins_by_state[v] << k }
plugins_by_state.each do |action, plugin_alter_list|
env[:ui].output("#{(action == :install) ? 'Installing' : 'Removing'} plugins: #{plugin_alter_list.join(' ')}")
# (un)install the plugin(s) in a separate vagrant process
if system "vagrant plugin #{action} #{plugin_alter_list.join(' ')}"
else
raise "#{(action == :install) ? 'Installation' : 'Removal'} of one or more plugins has failed. Aborting."
end
end
# scrap current vagrant process, and start over:
env[:ui].output("Restarting vagrant...")
exec ‘vagrant’, *ARGV
raise "The Ruby interperter should have already exited!"
end
@app.call(env)
end
end
# Only respond to actions that will create / boot / resume a box (not a halt or destroy,
# for instance)
[ :machine_action_boot, :machine_action_provision, :machine_action_reload,
:machine_action_resume, :machine_action_start, :machine_action_up,
:provisioner_run
]. each do |event_name|
action_hook("auto_install_plugins", event_name) do |hook|
hook.prepend(PluginChecker)
end
end
end
PluginAutoInstaller::PluginChecker.manifest = {
"vagrant-vbguest" => :required,
"vagrant-reload" => :required,
"vagrant-cachier" => :prohibited }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment