diff --git a/lib/vagrant/machine.rb b/lib/vagrant/machine.rb index 2f2a9fb7c..7dd643434 100644 --- a/lib/vagrant/machine.rb +++ b/lib/vagrant/machine.rb @@ -110,6 +110,7 @@ module Vagrant @ui = Vagrant::UI::Prefixed.new(@env.ui, @name) @ui_mutex = Mutex.new @state_mutex = Mutex.new + @triggers = Vagrant::Plugin::V2::Trigger.new(@env, @ui, @config.trigger) # Read the ID, which is usually in local storage @id = nil @@ -159,6 +160,7 @@ module Vagrant # as extra data set on the environment hash for the middleware # runner. def action(name, opts=nil) + @triggers.fire_before_triggers(name, @name) @logger.info("Calling action: #{name} on provider #{@provider}") opts ||= {} @@ -203,6 +205,8 @@ module Vagrant ui.machine("action", name.to_s, "end") action_result end + + @triggers.fire_after_triggers(name, @name) rescue Errors::EnvironmentLockedError raise Errors::MachineActionLockedError, action: name, diff --git a/lib/vagrant/plugin/v2/command.rb b/lib/vagrant/plugin/v2/command.rb index 94e554dc5..5b39ef49f 100644 --- a/lib/vagrant/plugin/v2/command.rb +++ b/lib/vagrant/plugin/v2/command.rb @@ -45,7 +45,7 @@ module Vagrant def parse_options(opts=nil) # make sure optparse doesn't use POSIXLY_CORRECT parsing ENV["POSIXLY_CORRECT"] = nil - + # Creating a shallow copy of the arguments so the OptionParser # doesn't destroy the originals. argv = @argv.dup diff --git a/lib/vagrant/plugin/v2/trigger.rb b/lib/vagrant/plugin/v2/trigger.rb index 175529e48..d30326d17 100644 --- a/lib/vagrant/plugin/v2/trigger.rb +++ b/lib/vagrant/plugin/v2/trigger.rb @@ -1,22 +1,122 @@ require 'log4r' +require 'pry' + module Vagrant module Plugin module V2 - # This is the base class for a trigger for the V2 API. A provisioner - # is primarily responsible for installing software on a Vagrant guest. class Trigger + # @return [Kernel_V2/Config/Trigger] attr_reader :config - # Trigger + # This class is responsible for setting up basic triggers that were + # defined inside a Vagrantfile. It should take the Trigger config + # and convert it to action hooks. # # @param [Object] env Vagrant environment + # @param [Object] ui Machines ui object # @param [Object] config Trigger configuration - def initialize(env, config) + def initialize(env, ui, config) @env = env + @machine_ui = ui @config = config + @logger = Log4r::Logger.new("vagrant::trigger::#{self.class.to_s.downcase}") end + + # Fires all before triggers, if any are defined for the action and guest + # + # @param [Symbol] action Vagrant command to fire trigger on + # @param [String] guest_name The guest that invoked firing the triggers + def fire_before_triggers(action, guest_name) + # get all triggers matching action + triggers = [] + triggers << config.before_triggers.map do |trigger| + trigger if trigger.command == action + end.compact + triggers = triggers.first + triggers = filter_triggers(triggers, guest_name) + + binding.pry + unless triggers.empty? + @logger.info("Firing trigger for action #{action} on guest #{guest_name}") + # TODO I18N me + @machine_ui.info("Running triggers before #{action}...") + fire(triggers, guest_name) + end + end + + # Fires all after triggers, if any are defined for the action and guest + # + # @param [Symbol] action Vagrant command to fire trigger on + # @param [String] guest_name The guest that invoked firing the triggers + def fire_after_triggers(action, guest_name) + # get all triggers matching action + triggers = [] + triggers << config.after_triggers.map do |trigger| + trigger if trigger.command == action + end.compact + triggers = triggers.first + triggers = filter_triggers(triggers, guest_name) + + binding.pry + unless triggers.empty? + @logger.info("Firing triggers for action #{action} on guest #{guest_name}") + # TODO I18N me + @machine_ui.info("Running triggers after #{action}...") + fire(triggers, guest_name) + end + end + + protected + + #------------------------------------------------------------------- + # Internal methods, don't call these. + #------------------------------------------------------------------- + + # Filters triggers to be fired based on restraints + # + # @param [Array] triggers An array of triggers to be filtered + # @return [Array] The filtered array of triggers + def filter_triggers(triggers, guest_name) + return triggers + end + + # Fires off all triggers in the given array + # + # @param [Array] triggers An array of triggers to be fired + def fire(triggers) + # ensure on_error is respected by exiting or continuing + + triggers.each do |trigger| + end + end + + # Prints the given message at info level for a trigger + # + # @param [String] message The string to be printed + def info(message) + @machine_ui.info(message) + end + + # Prints the given message at warn level for a trigger + # + # @param [String] message The string to be printed + def warn(message) + @machine_ui.warn(message) + end + + # Runs a script on a guest + # + # @param [ShellProvisioner/Config] config A Shell provisioner config + def run(config) + end + + # Runs a script on the host + # + # @param [ShellProvisioner/Config] config A Shell provisioner config + def run_remote(config) + end end end end diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 8a9b49cd3..c959dd501 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -176,6 +176,16 @@ module VagrantPlugins {"trigger" => errors} end + # return [Array] + def before_triggers + @_before_triggers + end + + # return [Array] + def after_triggers + @_after_triggers + end + # The String representation of this Trigger. # # @return [String]