From a194057fc04f6c8e1a66e0a2eb14aa537622e86f Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 8 Mar 2018 14:20:21 -0800 Subject: [PATCH 01/95] Add trigger config plugin --- plugins/kernel_v2/config/trigger.rb | 46 +++++++++++++++++++++++++++++ plugins/kernel_v2/plugin.rb | 5 ++++ 2 files changed, 51 insertions(+) create mode 100644 plugins/kernel_v2/config/trigger.rb diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb new file mode 100644 index 000000000..7e23ee8c8 --- /dev/null +++ b/plugins/kernel_v2/config/trigger.rb @@ -0,0 +1,46 @@ +require "vagrant" + +module VagrantPlugins + module Kernel_V2 + class TriggerConfig < Vagrant.plugin("2", :config) + + attr_accessor :name + + def initialize + @logger = Log4r::Logger.new("vagrant::config::trigger") + + # Internal state + @name = UNSET_VALUE + end + + # @param [Symbol] command Vagrant command to create trigger on + # @param [Block] block The defined after block + def before(command, &block) + end + + # @param [Symbol] command Vagrant command to create trigger on + # @param [Block] block The defined after block + def after(command, &block) + end + + #------------------------------------------------------------------- + # Internal methods, don't call these. + #------------------------------------------------------------------- + + def finalize! + @name = nil if @name == UNSET_VALUE + end + + # Validate all pushes + def validate(machine) + end + + # The String representation of this Trigger. + # + # @return [String] + def to_s + "Trigger" + end + end + end +end diff --git a/plugins/kernel_v2/plugin.rb b/plugins/kernel_v2/plugin.rb index 27737854f..4c836424f 100644 --- a/plugins/kernel_v2/plugin.rb +++ b/plugins/kernel_v2/plugin.rb @@ -39,6 +39,11 @@ module VagrantPlugins require File.expand_path("../config/vm", __FILE__) VMConfig end + + config("trigger") do + require File.expand_path("../config/trigger", __FILE__) + TriggerConfig + end end end end From 813ffd06ec7abfe3e63d73d09a7a719a58068eaa Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 8 Mar 2018 15:31:58 -0800 Subject: [PATCH 02/95] Add more trigger config options --- plugins/kernel_v2/config/trigger.rb | 56 ++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 7e23ee8c8..32946629b 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -3,24 +3,65 @@ require "vagrant" module VagrantPlugins module Kernel_V2 class TriggerConfig < Vagrant.plugin("2", :config) + DEFAULT_ON_ERROR = :halt + # Name for the given Trigger. Defaults to nil. + # + # @return [String] attr_accessor :name + # A string to print at the WARN level + # + # @return [String] + attr_accessor :info + + # A string to print at the WARN level + # + # @return [String] + attr_accessor :warn + + # Determines what how a Trigger should behave if it runs into an error. + # Defaults to :halt, otherwise can only be set to :continue. + # + # @return [Symbol] + attr_accessor :on_error + + # If set, will not run trigger for the configured Vagrant commands. + # + # @return [String, Array] + attr_accessor :ignore + + + # If set, will only run trigger for guests that match keys for this parameter. + # + # @return [String, Array] + attr_accessor :only_on + def initialize @logger = Log4r::Logger.new("vagrant::config::trigger") # Internal state @name = UNSET_VALUE + @info = UNSET_VALUE + @warn = UNSET_VALUE + @on_error = UNSET_VALUE + @ignore = UNSET_VALUE + @only_on = UNSET_VALUE end - # @param [Symbol] command Vagrant command to create trigger on + # @param [Array, Symbol] command Vagrant command to create trigger on # @param [Block] block The defined after block - def before(command, &block) + def before(**command, &block) end - # @param [Symbol] command Vagrant command to create trigger on + # @param [Array, Symbol] command Vagrant command to create trigger on # @param [Block] block The defined after block - def after(command, &block) + def after(**command, &block) + end + + # @param [Array, Symbol] command Vagrant command to create trigger on + # @return [ActionHook] returns action hook? + def parse_trigger_block(**command) end #------------------------------------------------------------------- @@ -29,9 +70,14 @@ module VagrantPlugins def finalize! @name = nil if @name == UNSET_VALUE + @info = nil if @info == UNSET_VALUE + @warn = nil if @warn == UNSET_VALUE + @on_error = DEFAULT_ON_ERROR if @on_error == UNSET_VALUE + @ignore = nil if @ignore == UNSET_VALUE + @only_on = :halt if @only_on == UNSET_VALUE end - # Validate all pushes + # Validate Trigger settings def validate(machine) end From 0142722787a6f947146efed71a746c40b6f0dd4c Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 8 Mar 2018 15:34:39 -0800 Subject: [PATCH 03/95] Add run and run_remote scaffolding --- plugins/kernel_v2/config/trigger.rb | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 32946629b..acf779644 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -37,6 +37,16 @@ module VagrantPlugins # @return [String, Array] attr_accessor :only_on + # A local inline or file script to execute for the trigger + # + # @return [???] + attr_accessor :run + + # A remote inline or file script to execute for the trigger + # + # @return [???] + attr_accessor :run_remote + def initialize @logger = Log4r::Logger.new("vagrant::config::trigger") @@ -47,6 +57,8 @@ module VagrantPlugins @on_error = UNSET_VALUE @ignore = UNSET_VALUE @only_on = UNSET_VALUE + @run = UNSET_VALUE + @run_remote = UNSET_VALUE end # @param [Array, Symbol] command Vagrant command to create trigger on @@ -74,7 +86,9 @@ module VagrantPlugins @warn = nil if @warn == UNSET_VALUE @on_error = DEFAULT_ON_ERROR if @on_error == UNSET_VALUE @ignore = nil if @ignore == UNSET_VALUE - @only_on = :halt if @only_on == UNSET_VALUE + @only_on = nil if @only_on == UNSET_VALUE + @run = nil if @run == UNSET_VALUE + @run_remote = nil if @run_remote == UNSET_VALUE end # Validate Trigger settings From 01b904061d8da1cddc7b6da1bb26759153fea295 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 8 Mar 2018 16:00:51 -0800 Subject: [PATCH 04/95] Use proper command reference for command whitelist params --- plugins/kernel_v2/config/trigger.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index acf779644..f83323e6f 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -63,12 +63,12 @@ module VagrantPlugins # @param [Array, Symbol] command Vagrant command to create trigger on # @param [Block] block The defined after block - def before(**command, &block) + def before(*command, &block) end # @param [Array, Symbol] command Vagrant command to create trigger on # @param [Block] block The defined after block - def after(**command, &block) + def after(*command, &block) end # @param [Array, Symbol] command Vagrant command to create trigger on From 7cccddc009dde3ca2eeb7851e7abb6e9281e1f67 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 8 Mar 2018 16:12:36 -0800 Subject: [PATCH 05/95] Add basic scaffolding for command parsing --- plugins/kernel_v2/config/trigger.rb | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index f83323e6f..1e6d39e06 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -39,18 +39,21 @@ module VagrantPlugins # A local inline or file script to execute for the trigger # - # @return [???] + # @return [Hash] attr_accessor :run # A remote inline or file script to execute for the trigger # - # @return [???] + # @return [Hash] attr_accessor :run_remote def initialize @logger = Log4r::Logger.new("vagrant::config::trigger") # Internal state + @_commands = [] + + # Trigger config options @name = UNSET_VALUE @info = UNSET_VALUE @warn = UNSET_VALUE @@ -71,9 +74,10 @@ module VagrantPlugins def after(*command, &block) end - # @param [Array, Symbol] command Vagrant command to create trigger on - # @return [ActionHook] returns action hook? - def parse_trigger_block(**command) + # Sets the internal Trigger state for which commands the Trigger will run on + # + # @param [Array, Symbol, Args] command Vagrant command to create trigger on + def parse_command_whitelist(*command) end #------------------------------------------------------------------- @@ -93,6 +97,15 @@ module VagrantPlugins # Validate Trigger settings def validate(machine) + if !@run.nil? + # validate proper keys + # WARN if invalid keys are used? + end + + if !@run_remote.nil? + # validate proper keys + # WARN if invalid keys are used? + end end # The String representation of this Trigger. From bb2f3b35b9c1dd042208e14fa5e6afb11ca0d05b Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Fri, 9 Mar 2018 13:06:26 -0800 Subject: [PATCH 06/95] Add basic unit test --- plugins/kernel_v2/config/trigger.rb | 4 ++ .../plugins/kernel_v2/config/trigger_test.rb | 40 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 test/unit/plugins/kernel_v2/config/trigger_test.rb diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 1e6d39e06..882953154 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -97,6 +97,8 @@ module VagrantPlugins # Validate Trigger settings def validate(machine) + errors = _detected_errors + if !@run.nil? # validate proper keys # WARN if invalid keys are used? @@ -106,6 +108,8 @@ module VagrantPlugins # validate proper keys # WARN if invalid keys are used? end + + {"triggers" => errors} end # The String representation of this Trigger. diff --git a/test/unit/plugins/kernel_v2/config/trigger_test.rb b/test/unit/plugins/kernel_v2/config/trigger_test.rb new file mode 100644 index 000000000..be7d1a6c1 --- /dev/null +++ b/test/unit/plugins/kernel_v2/config/trigger_test.rb @@ -0,0 +1,40 @@ +require File.expand_path("../../../../base", __FILE__) + +require Vagrant.source_root.join("plugins/kernel_v2/config/trigger") + +describe VagrantPlugins::Kernel_V2::TriggerConfig do + include_context "unit" + + subject { described_class.new } + + let(:machine) { double("machine") } + + def assert_invalid + errors = subject.validate(machine) + if !errors.values.any? { |v| !v.empty? } + raise "No errors: #{errors.inspect}" + end + end + + def assert_valid + errors = subject.validate(machine) + if !errors.values.all? { |v| v.empty? } + raise "Errors: #{errors.inspect}" + end + end + + before do + env = double("env") + allow(env).to receive(:root_path).and_return(nil) + allow(machine).to receive(:env).and_return(env) + allow(machine).to receive(:provider_config).and_return(nil) + allow(machine).to receive(:provider_options).and_return({}) + + subject.name = "foo" + end + + it "is valid with test defaults" do + subject.finalize! + assert_valid + end +end From fdf1b5857035f42f40a6f4e5a52c776c9d758d27 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Fri, 9 Mar 2018 16:45:48 -0800 Subject: [PATCH 07/95] Introduce ids for trigger blocks --- plugins/kernel_v2/config/trigger.rb | 75 ++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 18 deletions(-) diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 882953154..22f462872 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -10,6 +10,15 @@ module VagrantPlugins # @return [String] attr_accessor :name + # Internal unique name for this provisioner + # Set to the given :name if exists, otherwise + # it's set as a UUID. + # + # Note: This is for internal use only. + # + # @return [String] + attr_reader :id + # A string to print at the WARN level # # @return [String] @@ -51,7 +60,13 @@ module VagrantPlugins @logger = Log4r::Logger.new("vagrant::config::trigger") # Internal state - @_commands = [] + @id = SecureRandom.uuid + # Expected to store state like: + # {@id=>{"command" => [Triggers],"command2"=>[Triggers]}} + # finalize will take this data structure and construct action hooks + # Does this make sense + @_before_triggers = {} # A hash of all before triggers and their settings + @_after_triggers = {} # A hash of all after triggers and their settings # Trigger config options @name = UNSET_VALUE @@ -64,27 +79,61 @@ module VagrantPlugins @run_remote = UNSET_VALUE end + # Reads in and parses Vagrant command whitelist and settings for a defined + # trigger + # # @param [Array, Symbol] command Vagrant command to create trigger on - # @param [Block] block The defined after block + # @param [Block] block The defined before block def before(*command, &block) + if block_given? + puts "the command: #{command}" + puts "the block: #{block}" + command.each do |cmd| + @_before_triggers[@id] = {cmd=>block} + end + puts @_before_triggers + elsif command.last.is_a?(Hash) + blck = command.pop + command.each do |cmd| + @_before_triggers[@id] = {cmd=>blck} + end + else + # No config block given at all, validation step should throw error? + end + puts "The trigger: #{@_before_triggers}" end # @param [Array, Symbol] command Vagrant command to create trigger on # @param [Block] block The defined after block def after(*command, &block) - end - - # Sets the internal Trigger state for which commands the Trigger will run on - # - # @param [Array, Symbol, Args] command Vagrant command to create trigger on - def parse_command_whitelist(*command) + if block_given? + store_after_trigger(command, block) + elsif command.last.is_a?(Hash) + blck = command.pop + store_after_trigger(command, blck) + else + # No config block given at all, validation step should throw error? + end end #------------------------------------------------------------------- # Internal methods, don't call these. #------------------------------------------------------------------- + def store_before_trigger(*command, block) + command.each do |cmd| + @_before_triggers[@id] = {cmd=>block} + end + end + + def store_after_trigger(*command, block) + command.each do |cmd| + @_after_triggers[@id] = {cmd=>block} + end + end + def finalize! + # Ensure all config options are set to nil if untouched by user @name = nil if @name == UNSET_VALUE @info = nil if @info == UNSET_VALUE @warn = nil if @warn == UNSET_VALUE @@ -99,16 +148,6 @@ module VagrantPlugins def validate(machine) errors = _detected_errors - if !@run.nil? - # validate proper keys - # WARN if invalid keys are used? - end - - if !@run_remote.nil? - # validate proper keys - # WARN if invalid keys are used? - end - {"triggers" => errors} end From 6f00eb56797acec91362925f846de48113ab0a2b Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Fri, 9 Mar 2018 16:46:29 -0800 Subject: [PATCH 08/95] Move trigger options into own plugin class --- plugins/kernel_v2/config/trigger.rb | 167 ++++++------------ plugins/kernel_v2/config/vm_trigger.rb | 112 ++++++++++++ .../plugins/kernel_v2/config/trigger_test.rb | 2 - .../kernel_v2/config/vm_trigger_test.rb | 40 +++++ 4 files changed, 207 insertions(+), 114 deletions(-) create mode 100644 plugins/kernel_v2/config/vm_trigger.rb create mode 100644 test/unit/plugins/kernel_v2/config/vm_trigger_test.rb diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 22f462872..6216fc4a4 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -1,152 +1,95 @@ require "vagrant" +require 'pry' + +require File.expand_path("../vm_trigger", __FILE__) module VagrantPlugins module Kernel_V2 class TriggerConfig < Vagrant.plugin("2", :config) - DEFAULT_ON_ERROR = :halt - - # Name for the given Trigger. Defaults to nil. - # - # @return [String] - attr_accessor :name - - # Internal unique name for this provisioner - # Set to the given :name if exists, otherwise - # it's set as a UUID. - # - # Note: This is for internal use only. - # - # @return [String] - attr_reader :id - - # A string to print at the WARN level - # - # @return [String] - attr_accessor :info - - # A string to print at the WARN level - # - # @return [String] - attr_accessor :warn - - # Determines what how a Trigger should behave if it runs into an error. - # Defaults to :halt, otherwise can only be set to :continue. - # - # @return [Symbol] - attr_accessor :on_error - - # If set, will not run trigger for the configured Vagrant commands. - # - # @return [String, Array] - attr_accessor :ignore - - - # If set, will only run trigger for guests that match keys for this parameter. - # - # @return [String, Array] - attr_accessor :only_on - - # A local inline or file script to execute for the trigger - # - # @return [Hash] - attr_accessor :run - - # A remote inline or file script to execute for the trigger - # - # @return [Hash] - attr_accessor :run_remote def initialize @logger = Log4r::Logger.new("vagrant::config::trigger") - # Internal state - @id = SecureRandom.uuid - # Expected to store state like: - # {@id=>{"command" => [Triggers],"command2"=>[Triggers]}} - # finalize will take this data structure and construct action hooks - # Does this make sense - @_before_triggers = {} # A hash of all before triggers and their settings - @_after_triggers = {} # A hash of all after triggers and their settings - - # Trigger config options - @name = UNSET_VALUE - @info = UNSET_VALUE - @warn = UNSET_VALUE - @on_error = UNSET_VALUE - @ignore = UNSET_VALUE - @only_on = UNSET_VALUE - @run = UNSET_VALUE - @run_remote = UNSET_VALUE + # Internal State + @_before_triggers = [] # An array of VagrantConfigTrigger objectrs + @_after_triggers = [] # An array of VagrantConfigTrigger objectrs end # Reads in and parses Vagrant command whitelist and settings for a defined # trigger # - # @param [Array, Symbol] command Vagrant command to create trigger on + # @param [Symbol] command Vagrant command to create trigger on # @param [Block] block The defined before block def before(*command, &block) - if block_given? - puts "the command: #{command}" - puts "the block: #{block}" - command.each do |cmd| - @_before_triggers[@id] = {cmd=>block} - end - puts @_before_triggers - elsif command.last.is_a?(Hash) - blck = command.pop - command.each do |cmd| - @_before_triggers[@id] = {cmd=>blck} - end + blk = block + if !block_given? && command.last.is_a?(Hash) + # We were given a hash rather than a block, + # so the last element should be the "config block" + # and the rest are commands for the trigger + blk = command.pop else # No config block given at all, validation step should throw error? end - puts "The trigger: #{@_before_triggers}" + + command.each do |cmd| + trigger = VagrantConfigTrigger.new(cmd) + trigger.add_config(blk) + @_before_triggers << trigger + end end - # @param [Array, Symbol] command Vagrant command to create trigger on - # @param [Block] block The defined after block + # Reads in and parses Vagrant command whitelist and settings for a defined + # trigger + # + # @param [Symbol] command Vagrant command to create trigger on + # @param [Block] block The defined before block def after(*command, &block) - if block_given? - store_after_trigger(command, block) - elsif command.last.is_a?(Hash) - blck = command.pop - store_after_trigger(command, blck) + blk = block + if !block_given? && command.last.is_a?(Hash) + # We were given a hash rather than a block, + # so the last element should be the "config block" + # and the rest are commands for the trigger + blk = command.pop else # No config block given at all, validation step should throw error? end + + command.each do |cmd| + trigger = VagrantConfigTrigger.new(cmd) + trigger.add_config(blk) + @_after_triggers << trigger + end end #------------------------------------------------------------------- # Internal methods, don't call these. #------------------------------------------------------------------- - def store_before_trigger(*command, block) - command.each do |cmd| - @_before_triggers[@id] = {cmd=>block} - end - end - - def store_after_trigger(*command, block) - command.each do |cmd| - @_after_triggers[@id] = {cmd=>block} - end - end - def finalize! - # Ensure all config options are set to nil if untouched by user - @name = nil if @name == UNSET_VALUE - @info = nil if @info == UNSET_VALUE - @warn = nil if @warn == UNSET_VALUE - @on_error = DEFAULT_ON_ERROR if @on_error == UNSET_VALUE - @ignore = nil if @ignore == UNSET_VALUE - @only_on = nil if @only_on == UNSET_VALUE - @run = nil if @run == UNSET_VALUE - @run_remote = nil if @run_remote == UNSET_VALUE + # read through configured settings blocks and set their values + # and then set up action hooks here? + # for some reason not all triggers are showing up here + #puts @_before_triggers if !@_before_triggers.empty? + #puts @_after_triggers if !@_after_triggers.empty? + if !@_before_triggers.empty? + binding.pry + end end # Validate Trigger settings def validate(machine) + if !@_before_triggers.empty? + binding.pry + end + errors = _detected_errors + @_before_triggers.each do |bt| + errors << bt.validate(machine) + end + + @_after_triggers.each do |at| + errors << at.validate(machine) + end {"triggers" => errors} end diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb new file mode 100644 index 000000000..59871339a --- /dev/null +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -0,0 +1,112 @@ +require 'log4r' +require 'pry' + +module VagrantPlugins + module Kernel_V2 + # Represents a single configured provisioner for a VM. + class VagrantConfigTrigger < Vagrant.plugin("2", :config) + DEFAULT_ON_ERROR = :halt + + # Internal unique name for this trigger + # + # Note: This is for internal use only. + # + # @return [String] + attr_reader :id + + # Name for the given Trigger. Defaults to nil. + # + # @return [String] + attr_accessor :name + + # Command to fire the trigger on + # + # @return [Symbol] + attr_reader :command + + # A string to print at the WARN level + # + # @return [String] + attr_accessor :info + + # A string to print at the WARN level + # + # @return [String] + attr_accessor :warn + + # Determines what how a Trigger should behave if it runs into an error. + # Defaults to :halt, otherwise can only be set to :continue. + # + # @return [Symbol] + attr_accessor :on_error + + # If set, will not run trigger for the configured Vagrant commands. + # + # @return [String, Array] + attr_accessor :ignore + + + # If set, will only run trigger for guests that match keys for this parameter. + # + # @return [String, Array] + attr_accessor :only_on + + # A local inline or file script to execute for the trigger + # + # @return [Hash] + attr_accessor :run + + # A remote inline or file script to execute for the trigger + # + # @return [Hash] + attr_accessor :run_remote + + def initialize(command) + @logger = Log4r::Logger.new("vagrant::config::vm::trigger::config") + #@logger.debug("Trigger defined: #{name}") + + @name = UNSET_VALUE + @info = UNSET_VALUE + @warn = UNSET_VALUE + @on_error = UNSET_VALUE + @ignore = UNSET_VALUE + @only_on = UNSET_VALUE + @run = UNSET_VALUE + @run_remote = UNSET_VALUE + + # Internal options + @id = SecureRandom.uuid + @command = command.to_sym + end + + # Expecting a ruby block of a trigger config + def add_config(config_block) + if config_block.is_a?(Hash) + # We have a ruby hash + self.set_options(config_block) + else + # We have a ruby block + end + end + + def finalize! + # Ensure all config options are set to nil if untouched by user + @name = nil if @name == UNSET_VALUE + @info = nil if @info == UNSET_VALUE + @warn = nil if @warn == UNSET_VALUE + @on_error = DEFAULT_ON_ERROR if @on_error == UNSET_VALUE + @ignore = nil if @ignore == UNSET_VALUE + @only_on = nil if @only_on == UNSET_VALUE + @run = nil if @run == UNSET_VALUE + @run_remote = nil if @run_remote == UNSET_VALUE + end + + def validate(machine) + binding.pry + errors = _detected_errors + # Validate that each config option has the right values and is the right type + {"triggers" => errors} + end + end + end +end diff --git a/test/unit/plugins/kernel_v2/config/trigger_test.rb b/test/unit/plugins/kernel_v2/config/trigger_test.rb index be7d1a6c1..79199bd84 100644 --- a/test/unit/plugins/kernel_v2/config/trigger_test.rb +++ b/test/unit/plugins/kernel_v2/config/trigger_test.rb @@ -29,8 +29,6 @@ describe VagrantPlugins::Kernel_V2::TriggerConfig do allow(machine).to receive(:env).and_return(env) allow(machine).to receive(:provider_config).and_return(nil) allow(machine).to receive(:provider_options).and_return({}) - - subject.name = "foo" end it "is valid with test defaults" do diff --git a/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb b/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb new file mode 100644 index 000000000..245fab5bf --- /dev/null +++ b/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb @@ -0,0 +1,40 @@ +require File.expand_path("../../../../base", __FILE__) + +require Vagrant.source_root.join("plugins/kernel_v2/config/vm_trigger") + +describe VagrantPlugins::Kernel_V2::VagrantConfigTrigger do + include_context "unit" + + subject { described_class.new } + + let(:machine) { double("machine") } + + def assert_invalid + errors = subject.validate(machine) + if !errors.values.any? { |v| !v.empty? } + raise "No errors: #{errors.inspect}" + end + end + + def assert_valid + errors = subject.validate(machine) + if !errors.values.all? { |v| v.empty? } + raise "Errors: #{errors.inspect}" + end + end + + before do + env = double("env") + allow(env).to receive(:root_path).and_return(nil) + allow(machine).to receive(:env).and_return(env) + allow(machine).to receive(:provider_config).and_return(nil) + allow(machine).to receive(:provider_options).and_return({}) + + subject.name = "foo" + end + + it "is valid with test defaults" do + subject.finalize! + assert_valid + end +end From e0a5b1d64787d4b55560c7bd022f50652176a028 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 13 Mar 2018 11:07:41 -0700 Subject: [PATCH 09/95] Parse block trigger configs --- plugins/kernel_v2/config/trigger.rb | 21 ++++++++++++++++----- plugins/kernel_v2/config/vm_trigger.rb | 12 +++--------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 6216fc4a4..01a4e6b3f 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -32,8 +32,7 @@ module VagrantPlugins end command.each do |cmd| - trigger = VagrantConfigTrigger.new(cmd) - trigger.add_config(blk) + trigger = create_trigger(cmd, blk) @_before_triggers << trigger end end @@ -42,7 +41,7 @@ module VagrantPlugins # trigger # # @param [Symbol] command Vagrant command to create trigger on - # @param [Block] block The defined before block + # @param [Block] block The defined after block def after(*command, &block) blk = block if !block_given? && command.last.is_a?(Hash) @@ -55,8 +54,7 @@ module VagrantPlugins end command.each do |cmd| - trigger = VagrantConfigTrigger.new(cmd) - trigger.add_config(blk) + trigger = create_trigger(cmd, blk) @_after_triggers << trigger end end @@ -65,6 +63,19 @@ module VagrantPlugins # Internal methods, don't call these. #------------------------------------------------------------------- + # @param [Symbol] command Vagrant command to create trigger on + # @param [Block] block The defined config block + def create_trigger(command, block) + trigger = VagrantConfigTrigger.new(cmd) + if block.is_a?(Hash) + trigger.set_options(block) + else + block.call(trigger, VagrantConfigTrigger) + end + trigger.finalize! + return trigger + end + def finalize! # read through configured settings blocks and set their values # and then set up action hooks here? diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb index 59871339a..7afedb080 100644 --- a/plugins/kernel_v2/config/vm_trigger.rb +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -79,15 +79,9 @@ module VagrantPlugins @command = command.to_sym end - # Expecting a ruby block of a trigger config - def add_config(config_block) - if config_block.is_a?(Hash) - # We have a ruby hash - self.set_options(config_block) - else - # We have a ruby block - end - end + #------------------------------------------------------------------- + # Internal methods, don't call these. + #------------------------------------------------------------------- def finalize! # Ensure all config options are set to nil if untouched by user From c10ae070b66c77956ae1d7b7a183d0d7b17ec1bb Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 13 Mar 2018 11:13:25 -0700 Subject: [PATCH 10/95] Store correct command for trigger --- plugins/kernel_v2/config/trigger.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 01a4e6b3f..674c5537c 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -66,7 +66,7 @@ module VagrantPlugins # @param [Symbol] command Vagrant command to create trigger on # @param [Block] block The defined config block def create_trigger(command, block) - trigger = VagrantConfigTrigger.new(cmd) + trigger = VagrantConfigTrigger.new(command) if block.is_a?(Hash) trigger.set_options(block) else From 50ecf45d505f88b91f81ac7452f1d80729fdf1ce Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 13 Mar 2018 11:25:35 -0700 Subject: [PATCH 11/95] Add more doc to create_trigger function --- plugins/kernel_v2/config/trigger.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 674c5537c..1dd38d017 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -63,8 +63,13 @@ module VagrantPlugins # Internal methods, don't call these. #------------------------------------------------------------------- + # Creates a new trigger config. If a block is given, parse that block + # by calling it with the created trigger. Otherwise set the options if it's + # a hash. + # # @param [Symbol] command Vagrant command to create trigger on # @param [Block] block The defined config block + # @return [VagrantConfigTrigger] def create_trigger(command, block) trigger = VagrantConfigTrigger.new(command) if block.is_a?(Hash) From 3c5e4b2464715f6d1ed99e46e5c36d27f0732d7e Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 13 Mar 2018 11:33:48 -0700 Subject: [PATCH 12/95] Fix variable doc --- plugins/kernel_v2/config/trigger.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 1dd38d017..6a06bdc3e 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -11,8 +11,8 @@ module VagrantPlugins @logger = Log4r::Logger.new("vagrant::config::trigger") # Internal State - @_before_triggers = [] # An array of VagrantConfigTrigger objectrs - @_after_triggers = [] # An array of VagrantConfigTrigger objectrs + @_before_triggers = [] # An array of VagrantConfigTrigger objects + @_after_triggers = [] # An array of VagrantConfigTrigger objects end # Reads in and parses Vagrant command whitelist and settings for a defined From 375e8d71532a1d86f2a5dddbe0a75b1eff3b7dde Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 13 Mar 2018 11:36:25 -0700 Subject: [PATCH 13/95] Remove old comments --- plugins/kernel_v2/config/trigger.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 6a06bdc3e..3a6049917 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -84,9 +84,6 @@ module VagrantPlugins def finalize! # read through configured settings blocks and set their values # and then set up action hooks here? - # for some reason not all triggers are showing up here - #puts @_before_triggers if !@_before_triggers.empty? - #puts @_after_triggers if !@_after_triggers.empty? if !@_before_triggers.empty? binding.pry end From 8e72ae5bd65d85c2f37805806a66c9bbf425697c Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 13 Mar 2018 14:35:24 -0700 Subject: [PATCH 14/95] Add basic validation for trigger config objects --- plugins/kernel_v2/config/trigger.rb | 18 +++---- plugins/kernel_v2/config/vm_trigger.rb | 68 ++++++++++++++++++++++++-- templates/locales/en.yml | 21 ++++++++ 3 files changed, 93 insertions(+), 14 deletions(-) diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 3a6049917..b486aaf55 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -84,27 +84,25 @@ module VagrantPlugins def finalize! # read through configured settings blocks and set their values # and then set up action hooks here? - if !@_before_triggers.empty? - binding.pry - end + #if !@_before_triggers.empty? + # binding.pry + #end end # Validate Trigger settings def validate(machine) - if !@_before_triggers.empty? - binding.pry - end - errors = _detected_errors @_before_triggers.each do |bt| - errors << bt.validate(machine) + error = bt.validate(machine) + errors.concat error if !error.empty? end @_after_triggers.each do |at| - errors << at.validate(machine) + error = at.validate(machine) + errors.concat error if !error.empty? end - {"triggers" => errors} + {"trigger" => errors} end # The String representation of this Trigger. diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb index 7afedb080..03c070fc8 100644 --- a/plugins/kernel_v2/config/vm_trigger.rb +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -90,16 +90,76 @@ module VagrantPlugins @warn = nil if @warn == UNSET_VALUE @on_error = DEFAULT_ON_ERROR if @on_error == UNSET_VALUE @ignore = nil if @ignore == UNSET_VALUE - @only_on = nil if @only_on == UNSET_VALUE @run = nil if @run == UNSET_VALUE @run_remote = nil if @run_remote == UNSET_VALUE + @only_on = nil if @only_on == UNSET_VALUE + + # these values are expected to always be an Array internally, + # but can be set as a single String or Symbol + if @only_on.is_a?(String) + @logger.debug("Updating @only_on variable to be an Array") + @only_on = Array(@only_on) + end + + if @ignore.is_a?(String) + @logger.debug("Updating @ignore variable to be an Array and Symbol") + @ignore = Array(@ignore.to_sym) + elsif @ignore.is_a?(Symbol) + @logger.debug("Updating @ignore variable to be an Array") + @ignore = Array(@ignore) + end end def validate(machine) - binding.pry errors = _detected_errors - # Validate that each config option has the right values and is the right type - {"triggers" => errors} + + if !@run.nil? + if !@run.is_a?(Hash) + # Run must be a hash + errors << I18n.t("vagrant.config.triggers.run.bad_type", cmd: @command) + end + + if !@run.key?(:inline) && !@run.key?(:file) + errors << I18n.t("vagrant.config.triggers.run.missing_context", cmd: @command) + end + end + + if !@run_remote.nil? + if !@run_remote.is_a?(Hash) + errors << I18n.t("vagrant.config.triggers.run_remote.bad_type", cmd: @command) + end + end + + if !@name.nil? && !@name.is_a?(String) + errors << I18n.t("vagrant.config.triggers.name_bad_type", cmd: @command) + end + + if !@info.nil? && !@info.is_a?(String) + errors << I18n.t("vagrant.config.triggers.info_bad_type", cmd: @command) + end + + if !@warn.nil? && !@warn.is_a?(String) + errors << I18n.t("vagrant.config.triggers.warn_bad_type", cmd: @command) + end + + if @on_error != :halt + if @on_error != :continue + # must be :halt or :continue + errors << I18n.t("vagrant.config.triggers.on_error_bad_type", cmd: @command) + end + end + + # @ignore validations? + # @only_on validations? + + errors + end + + # The String representation of this Trigger. + # + # @return [String] + def to_s + "Trigger Config" end end end diff --git a/templates/locales/en.yml b/templates/locales/en.yml index c0897632b..e663515f0 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -1677,6 +1677,27 @@ en: paranoid_deprecated: |- The key `paranoid` is deprecated. Please use `verify_host_key`. Supported values are exactly the same, only the name of the option has changed. + triggers: + name_bad_type: |- + Invalid type set for `name` on trigger for command '%{cmd}'. `name` should be a String. + on_error_bad_type: |- + Invalid type set for `on_error` on trigger for command '%{cmd}'. `on_error` can + only be `:halt` (default) or `:continue`. + run: + bad_type: |- + Invalid type set for `run` on trigger for command '%{cmd}'. `run` must be a + Hash with either key `:inline` or `:file` + missing_context: |- + Missing key for trigger config setting `run` for command '%{cmd}'. `run` is expected + to be given either an `:inline` or `:file` setting. + run_remote: + bad_type: |- + Invalid type set for `run_remote` on trigger for command '%{cmd}'. `run` must be a + Hash with either key `:inline` or `:file` + missing_context: |- + Missing key for trigger config setting `run` for command '%{cmd}'. `run_remote` is expected + to be given either an `:inline` or `:file` setting. + vm: bad_version: |- Invalid box version constraints: %{version} From 60ff2489c4030a158769077bc78a6f5ea5256fc0 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 13 Mar 2018 15:14:18 -0700 Subject: [PATCH 15/95] Display warning if vagrant command for trigger is not found --- plugins/kernel_v2/config/vm_trigger.rb | 11 +++++++++++ templates/locales/en.yml | 2 ++ 2 files changed, 13 insertions(+) diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb index 03c070fc8..7211bca88 100644 --- a/plugins/kernel_v2/config/vm_trigger.rb +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -113,6 +113,17 @@ module VagrantPlugins def validate(machine) errors = _detected_errors + commands = [] + # TODO: Should this be cached...? + Vagrant.plugin("2").manager.commands.each do |key,data| + commands.push(key) + end + + if !commands.include?(@command) + machine.ui.warn(I18n.t("vagrant.config.triggers.bad_command_warning", + cmd: @command)) + end + if !@run.nil? if !@run.is_a?(Hash) # Run must be a hash diff --git a/templates/locales/en.yml b/templates/locales/en.yml index e663515f0..06a50ef95 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -1678,6 +1678,8 @@ en: The key `paranoid` is deprecated. Please use `verify_host_key`. Supported values are exactly the same, only the name of the option has changed. triggers: + bad_command_warning: |- + The command '%{cmd}' was not found for this trigger. name_bad_type: |- Invalid type set for `name` on trigger for command '%{cmd}'. `name` should be a String. on_error_bad_type: |- From a96baad0d7008b8c47bb26cdd17d20aeb470e239 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 13 Mar 2018 16:24:46 -0700 Subject: [PATCH 16/95] Add comments for later dev --- plugins/kernel_v2/config/trigger.rb | 1 + plugins/kernel_v2/config/vm_trigger.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index b486aaf55..6e77f225f 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -90,6 +90,7 @@ module VagrantPlugins end # Validate Trigger settings + # TODO: Validate not called if there are providers defined in vagrantfile def validate(machine) errors = _detected_errors @_before_triggers.each do |bt| diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb index 7211bca88..72bccdd3a 100644 --- a/plugins/kernel_v2/config/vm_trigger.rb +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -114,12 +114,12 @@ module VagrantPlugins errors = _detected_errors commands = [] - # TODO: Should this be cached...? Vagrant.plugin("2").manager.commands.each do |key,data| commands.push(key) end if !commands.include?(@command) + # does this make sense to print on this machine? machine.ui.warn(I18n.t("vagrant.config.triggers.bad_command_warning", cmd: @command)) end From b04f13657b906df90ae65e0dcd4892862a1725ac Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 14 Mar 2018 10:08:41 -0700 Subject: [PATCH 17/95] Move warning to logger rather than guest --- plugins/kernel_v2/config/vm_trigger.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb index 72bccdd3a..2e45236ca 100644 --- a/plugins/kernel_v2/config/vm_trigger.rb +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -119,8 +119,7 @@ module VagrantPlugins end if !commands.include?(@command) - # does this make sense to print on this machine? - machine.ui.warn(I18n.t("vagrant.config.triggers.bad_command_warning", + @logger.warn(I18n.t("vagrant.config.triggers.bad_command_warning", cmd: @command)) end From 5ca1d1ab64ea2ff58d33d4da5cedb6897b4ebf41 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 14 Mar 2018 13:43:50 -0700 Subject: [PATCH 18/95] Finalize config in plugins finalize, improve docs --- plugins/kernel_v2/config/trigger.rb | 37 +++++++++++++++++++++----- plugins/kernel_v2/config/vm_trigger.rb | 27 ++++++++++++------- 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 6e77f225f..62754eea7 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -15,13 +15,34 @@ module VagrantPlugins @_after_triggers = [] # An array of VagrantConfigTrigger objects end + #------------------------------------------------------------------- + # Trigger before/after functions + #------------------------------------------------------------------- + # + # Commands are expected to be ether: + # - splat + # + config.trigger.before :up, :destroy, :halt do |trigger|.... + # - array + # + config.trigger.before [:up, :destroy, :halt] do |trigger|.... + # + # Config is expected to be given as a block, or the last parameter as a hash + # + # - block + # + config.trigger.before :up, :destroy, :halt do |trigger| + # trigger.option = "option" + # end + # - hash + # + config.trigger.before :up, :destroy, :halt, options: "option" + # Reads in and parses Vagrant command whitelist and settings for a defined # trigger # # @param [Symbol] command Vagrant command to create trigger on # @param [Block] block The defined before block def before(*command, &block) + command.flatten! blk = block + if !block_given? && command.last.is_a?(Hash) # We were given a hash rather than a block, # so the last element should be the "config block" @@ -43,6 +64,7 @@ module VagrantPlugins # @param [Symbol] command Vagrant command to create trigger on # @param [Block] block The defined after block def after(*command, &block) + command.flatten! blk = block if !block_given? && command.last.is_a?(Hash) # We were given a hash rather than a block, @@ -77,20 +99,23 @@ module VagrantPlugins else block.call(trigger, VagrantConfigTrigger) end - trigger.finalize! return trigger end def finalize! # read through configured settings blocks and set their values # and then set up action hooks here? - #if !@_before_triggers.empty? - # binding.pry - #end + if !@_before_triggers.empty? + @_before_triggers.map { |t| t.finalize! } + end + + if !@_after_triggers.empty? + @_after_triggers.map { |t| t.finalize! } + end end # Validate Trigger settings - # TODO: Validate not called if there are providers defined in vagrantfile + # TODO: Validate not called if there are guests defined in vagrantfile def validate(machine) errors = _detected_errors @_before_triggers.each do |bt| @@ -110,7 +135,7 @@ module VagrantPlugins # # @return [String] def to_s - "Trigger" + "trigger" end end end diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb index 2e45236ca..e9030c362 100644 --- a/plugins/kernel_v2/config/vm_trigger.rb +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -12,7 +12,7 @@ module VagrantPlugins # Note: This is for internal use only. # # @return [String] - attr_reader :id + attr_accessor :id # Name for the given Trigger. Defaults to nil. # @@ -96,18 +96,23 @@ module VagrantPlugins # these values are expected to always be an Array internally, # but can be set as a single String or Symbol - if @only_on.is_a?(String) - @logger.debug("Updating @only_on variable to be an Array") + # + # map to all be strings + if !@only_on.nil? @only_on = Array(@only_on) end - if @ignore.is_a?(String) - @logger.debug("Updating @ignore variable to be an Array and Symbol") + if !@ignore.nil? @ignore = Array(@ignore.to_sym) - elsif @ignore.is_a?(Symbol) - @logger.debug("Updating @ignore variable to be an Array") - @ignore = Array(@ignore) end + + # Convert @run and @run_remote to be a "Shell provisioner" + if @run + end + + if @run_remote + end + end def validate(machine) @@ -119,7 +124,7 @@ module VagrantPlugins end if !commands.include?(@command) - @logger.warn(I18n.t("vagrant.config.triggers.bad_command_warning", + machine.ui.warn(I18n.t("vagrant.config.triggers.bad_command_warning", cmd: @command)) end @@ -138,6 +143,10 @@ module VagrantPlugins if !@run_remote.is_a?(Hash) errors << I18n.t("vagrant.config.triggers.run_remote.bad_type", cmd: @command) end + + if !@run_remote.key?(:inline) && !@run_remote.key?(:file) + errors << I18n.t("vagrant.config.triggers.run_remote.missing_context", cmd: @command) + end end if !@name.nil? && !@name.is_a?(String) From d26a925bd7b3f5baea5dae787b7daa3fcac364fd Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 14 Mar 2018 13:47:01 -0700 Subject: [PATCH 19/95] Update variable doc --- plugins/kernel_v2/config/vm_trigger.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb index e9030c362..870d17e0a 100644 --- a/plugins/kernel_v2/config/vm_trigger.rb +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -42,7 +42,7 @@ module VagrantPlugins # If set, will not run trigger for the configured Vagrant commands. # - # @return [String, Array] + # @return [Symbol, Array] attr_accessor :ignore From 607368a66cba897e9add4d6c5d6132b60b54a506 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 14 Mar 2018 15:54:38 -0700 Subject: [PATCH 20/95] Introduce merge function to preserve internal state --- plugins/kernel_v2/config/trigger.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 62754eea7..1cbd88a25 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -102,6 +102,19 @@ module VagrantPlugins return trigger end + # Solve the mystery of disappearing state?? + def merge(other) + super.tap do |result| + other_defined_before_triggers = other.instance_variable_get(:@_before_triggers) + other_defined_after_triggers = other.instance_variable_get(:@_after_triggers) + + #overrides??? + + result.instance_variable_set(:@_before_triggers, other_defined_before_triggers) + result.instance_variable_set(:@_after_triggers, other_defined_after_triggers) + end + end + def finalize! # read through configured settings blocks and set their values # and then set up action hooks here? From 0cbf6970fc683297777d16321fe34f9971ef446b Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 14 Mar 2018 15:57:21 -0700 Subject: [PATCH 21/95] Update config class setting --- plugins/kernel_v2/config/vm_trigger.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb index 870d17e0a..2570a4392 100644 --- a/plugins/kernel_v2/config/vm_trigger.rb +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -7,6 +7,10 @@ module VagrantPlugins class VagrantConfigTrigger < Vagrant.plugin("2", :config) DEFAULT_ON_ERROR = :halt + #------------------------------------------------------------------- + # Config class for a given Trigger + #------------------------------------------------------------------- + # Internal unique name for this trigger # # Note: This is for internal use only. @@ -79,10 +83,6 @@ module VagrantPlugins @command = command.to_sym end - #------------------------------------------------------------------- - # Internal methods, don't call these. - #------------------------------------------------------------------- - def finalize! # Ensure all config options are set to nil if untouched by user @name = nil if @name == UNSET_VALUE @@ -103,7 +103,8 @@ module VagrantPlugins end if !@ignore.nil? - @ignore = Array(@ignore.to_sym) + @ignore = @ignore.to_sym if @ignore.is_a?(String) + @ignore = Array(@ignore) end # Convert @run and @run_remote to be a "Shell provisioner" From 51e4118cc271dba2993894d6cd9154daee2461bc Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 14 Mar 2018 15:57:48 -0700 Subject: [PATCH 22/95] Debug commit --- lib/vagrant/config/v2/root.rb | 2 ++ plugins/kernel_v2/config/ssh.rb | 1 + plugins/kernel_v2/config/trigger.rb | 1 + 3 files changed, 4 insertions(+) diff --git a/lib/vagrant/config/v2/root.rb b/lib/vagrant/config/v2/root.rb index b41e5c031..e2d33fd42 100644 --- a/lib/vagrant/config/v2/root.rb +++ b/lib/vagrant/config/v2/root.rb @@ -1,4 +1,5 @@ require "set" +require 'pry' require "vagrant/config/v2/util" @@ -63,6 +64,7 @@ module Vagrant def validate(machine) # Go through each of the configuration keys and validate errors = {} + binding.pry @keys.each do |_key, instance| if instance.respond_to?(:validate) # Validate this single item, and if we have errors then diff --git a/plugins/kernel_v2/config/ssh.rb b/plugins/kernel_v2/config/ssh.rb index 1dc3d51c9..4efd89951 100644 --- a/plugins/kernel_v2/config/ssh.rb +++ b/plugins/kernel_v2/config/ssh.rb @@ -1,4 +1,5 @@ require "vagrant" +require 'pry' require_relative "ssh_connect" diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 1cbd88a25..25d63c7a3 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -130,6 +130,7 @@ module VagrantPlugins # Validate Trigger settings # TODO: Validate not called if there are guests defined in vagrantfile def validate(machine) + binding.pry errors = _detected_errors @_before_triggers.each do |bt| error = bt.validate(machine) From f0ec7c750bab2245470da13566c138880afbe4e3 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 15 Mar 2018 12:21:14 -0700 Subject: [PATCH 23/95] Potential solution for trigger validation when guest is defined Send the defined before and or after triggers in the merge function if triggers exist already --- lib/vagrant/config/v2/root.rb | 1 - plugins/kernel_v2/config/trigger.rb | 16 ++++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/vagrant/config/v2/root.rb b/lib/vagrant/config/v2/root.rb index e2d33fd42..8fde6f267 100644 --- a/lib/vagrant/config/v2/root.rb +++ b/lib/vagrant/config/v2/root.rb @@ -64,7 +64,6 @@ module Vagrant def validate(machine) # Go through each of the configuration keys and validate errors = {} - binding.pry @keys.each do |_key, instance| if instance.respond_to?(:validate) # Validate this single item, and if we have errors then diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 25d63c7a3..4e99a2163 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -105,13 +105,22 @@ module VagrantPlugins # Solve the mystery of disappearing state?? def merge(other) super.tap do |result| + new_before_triggers = [] + new_after_triggers = [] other_defined_before_triggers = other.instance_variable_get(:@_before_triggers) other_defined_after_triggers = other.instance_variable_get(:@_after_triggers) - #overrides??? + # TODO: Is this the right solution? + # If a guest in a Vagrantfile exists beyond the default, this check + # will properly set up the defined triggers and validate them. + # overrides??? check for duplicate ids? + if other_defined_before_triggers.empty? && !@_before_triggers.empty? + result.instance_variable_set(:@_before_triggers, @_before_triggers) + end - result.instance_variable_set(:@_before_triggers, other_defined_before_triggers) - result.instance_variable_set(:@_after_triggers, other_defined_after_triggers) + if other_defined_before_triggers.empty? && !@_after_triggers.empty? + result.instance_variable_set(:@_after_triggers, @_after_triggers) + end end end @@ -130,7 +139,6 @@ module VagrantPlugins # Validate Trigger settings # TODO: Validate not called if there are guests defined in vagrantfile def validate(machine) - binding.pry errors = _detected_errors @_before_triggers.each do |bt| error = bt.validate(machine) From 1591ae99169ddb6356afa8aa933d6321e2e72920 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 15 Mar 2018 14:42:59 -0700 Subject: [PATCH 24/95] Make run and run_remote settings shell provisioner configs --- plugins/kernel_v2/config/vm_trigger.rb | 30 ++++++++------------------ templates/locales/en.yml | 14 ++++-------- 2 files changed, 13 insertions(+), 31 deletions(-) diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb index 2570a4392..cde23e34c 100644 --- a/plugins/kernel_v2/config/vm_trigger.rb +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -1,5 +1,6 @@ require 'log4r' require 'pry' +require Vagrant.source_root.join('plugins/provisioners/shell/config') module VagrantPlugins module Kernel_V2 @@ -109,9 +110,17 @@ module VagrantPlugins # Convert @run and @run_remote to be a "Shell provisioner" if @run + new_run = VagrantPlugins::Shell::Config.new() + new_run.set_options(@run) + new_run.finalize! + @run = new_run end if @run_remote + new_run = VagrantPlugins::Shell::Config.new() + new_run.set_options(@run_remote) + new_run.finalize! + @run_remote = new_run end end @@ -129,27 +138,6 @@ module VagrantPlugins cmd: @command)) end - if !@run.nil? - if !@run.is_a?(Hash) - # Run must be a hash - errors << I18n.t("vagrant.config.triggers.run.bad_type", cmd: @command) - end - - if !@run.key?(:inline) && !@run.key?(:file) - errors << I18n.t("vagrant.config.triggers.run.missing_context", cmd: @command) - end - end - - if !@run_remote.nil? - if !@run_remote.is_a?(Hash) - errors << I18n.t("vagrant.config.triggers.run_remote.bad_type", cmd: @command) - end - - if !@run_remote.key?(:inline) && !@run_remote.key?(:file) - errors << I18n.t("vagrant.config.triggers.run_remote.missing_context", cmd: @command) - end - end - if !@name.nil? && !@name.is_a?(String) errors << I18n.t("vagrant.config.triggers.name_bad_type", cmd: @command) end diff --git a/templates/locales/en.yml b/templates/locales/en.yml index 06a50ef95..8f8706f1f 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -1687,18 +1687,12 @@ en: only be `:halt` (default) or `:continue`. run: bad_type: |- - Invalid type set for `run` on trigger for command '%{cmd}'. `run` must be a - Hash with either key `:inline` or `:file` - missing_context: |- - Missing key for trigger config setting `run` for command '%{cmd}'. `run` is expected - to be given either an `:inline` or `:file` setting. + Invalid type set for `run` on trigger for command '%{cmd}'. `run` + must be a Hash. run_remote: bad_type: |- - Invalid type set for `run_remote` on trigger for command '%{cmd}'. `run` must be a - Hash with either key `:inline` or `:file` - missing_context: |- - Missing key for trigger config setting `run` for command '%{cmd}'. `run_remote` is expected - to be given either an `:inline` or `:file` setting. + Invalid type set for `run` on trigger for command '%{cmd}'. `run` + must be a Hash. vm: bad_version: |- From d3dde739fe1821f442f3d4a75d2f038caef9cdb6 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 15 Mar 2018 14:43:39 -0700 Subject: [PATCH 25/95] Update trigger code docs --- plugins/kernel_v2/config/trigger.rb | 3 +-- plugins/kernel_v2/config/vm_trigger.rb | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 4e99a2163..41e9bf641 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -136,8 +136,7 @@ module VagrantPlugins end end - # Validate Trigger settings - # TODO: Validate not called if there are guests defined in vagrantfile + # Validate Trigger Arrays def validate(machine) errors = _detected_errors @_before_triggers.each do |bt| diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb index cde23e34c..5d7b3481b 100644 --- a/plugins/kernel_v2/config/vm_trigger.rb +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -53,7 +53,7 @@ module VagrantPlugins # If set, will only run trigger for guests that match keys for this parameter. # - # @return [String, Array] + # @return [String, Regex, Array] attr_accessor :only_on # A local inline or file script to execute for the trigger @@ -167,7 +167,7 @@ module VagrantPlugins # # @return [String] def to_s - "Trigger Config" + "trigger config" end end end From e752878de93b6967fd8aa0fd322af12aa7a2cbb8 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Fri, 16 Mar 2018 14:06:39 -0700 Subject: [PATCH 26/95] Update finalize method for run and run_remote objects --- plugins/kernel_v2/config/vm_trigger.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb index 5d7b3481b..9c45fbf8a 100644 --- a/plugins/kernel_v2/config/vm_trigger.rb +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -98,17 +98,19 @@ module VagrantPlugins # these values are expected to always be an Array internally, # but can be set as a single String or Symbol # - # map to all be strings + # Guests are stored internally as strings if !@only_on.nil? @only_on = Array(@only_on) + @only_on.map { |o| o.to_s } end + # Commands must be stored internally as symbols if !@ignore.nil? - @ignore = @ignore.to_sym if @ignore.is_a?(String) @ignore = Array(@ignore) + @ignore.map { |i| i.to_sym } end - # Convert @run and @run_remote to be a "Shell provisioner" + # Convert @run and @run_remote to be a "Shell provisioner" config if @run new_run = VagrantPlugins::Shell::Config.new() new_run.set_options(@run) From 60c4ffa8a618f200a7ce93529a7aafb52df49320 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Fri, 16 Mar 2018 14:38:11 -0700 Subject: [PATCH 27/95] Ensure run & run_remote are Hashes before updating to shell config --- plugins/kernel_v2/config/vm_trigger.rb | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb index 9c45fbf8a..2e95c496a 100644 --- a/plugins/kernel_v2/config/vm_trigger.rb +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -111,14 +111,14 @@ module VagrantPlugins end # Convert @run and @run_remote to be a "Shell provisioner" config - if @run + if @run && @run.is_a?(Hash) new_run = VagrantPlugins::Shell::Config.new() new_run.set_options(@run) new_run.finalize! @run = new_run end - if @run_remote + if @run_remote && @run_remote.is_a?(Hash) new_run = VagrantPlugins::Shell::Config.new() new_run.set_options(@run_remote) new_run.finalize! @@ -135,6 +135,18 @@ module VagrantPlugins commands.push(key) end + # TODO: Does it make sense to strip out the "shell provisioner" error key here? + # We could add more context around triggers? + if @run + errorz = @run.validate(machine) + errors.concat errorz["shell provisioner"] if !errorz.empty? + end + + if @run_remote + errorz = @run_remote.validate(machine) + errors.concat errorz["shell provisioner"] if !errorz.empty? + end + if !commands.include?(@command) machine.ui.warn(I18n.t("vagrant.config.triggers.bad_command_warning", cmd: @command)) From d0d69e59c9739abeed53535af4a18e84e9777fe5 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Fri, 16 Mar 2018 15:39:38 -0700 Subject: [PATCH 28/95] Update return doc string on validate --- plugins/kernel_v2/config/vm_trigger.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb index 2e95c496a..cdbf6a6dd 100644 --- a/plugins/kernel_v2/config/vm_trigger.rb +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -127,6 +127,7 @@ module VagrantPlugins end + # @return [Array] array of strings of error messages from config option validation def validate(machine) errors = _detected_errors From 42419bbd4945e21950f3764756e669f622be5af3 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Mon, 19 Mar 2018 10:56:09 -0700 Subject: [PATCH 29/95] Fix rspec tests --- lib/vagrant/config/v2/root.rb | 1 - plugins/kernel_v2/config/ssh.rb | 1 - plugins/kernel_v2/config/trigger.rb | 1 - plugins/kernel_v2/config/vm_trigger.rb | 2 +- test/unit/plugins/kernel_v2/config/vm_trigger_test.rb | 8 +++++--- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/vagrant/config/v2/root.rb b/lib/vagrant/config/v2/root.rb index 8fde6f267..b41e5c031 100644 --- a/lib/vagrant/config/v2/root.rb +++ b/lib/vagrant/config/v2/root.rb @@ -1,5 +1,4 @@ require "set" -require 'pry' require "vagrant/config/v2/util" diff --git a/plugins/kernel_v2/config/ssh.rb b/plugins/kernel_v2/config/ssh.rb index 4efd89951..1dc3d51c9 100644 --- a/plugins/kernel_v2/config/ssh.rb +++ b/plugins/kernel_v2/config/ssh.rb @@ -1,5 +1,4 @@ require "vagrant" -require 'pry' require_relative "ssh_connect" diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 41e9bf641..0b24b450c 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -1,5 +1,4 @@ require "vagrant" -require 'pry' require File.expand_path("../vm_trigger", __FILE__) diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb index cdbf6a6dd..edee528ba 100644 --- a/plugins/kernel_v2/config/vm_trigger.rb +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -1,5 +1,5 @@ require 'log4r' -require 'pry' + require Vagrant.source_root.join('plugins/provisioners/shell/config') module VagrantPlugins diff --git a/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb b/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb index 245fab5bf..c7b7fb139 100644 --- a/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb +++ b/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb @@ -5,20 +5,22 @@ require Vagrant.source_root.join("plugins/kernel_v2/config/vm_trigger") describe VagrantPlugins::Kernel_V2::VagrantConfigTrigger do include_context "unit" - subject { described_class.new } + let(:command) { :up } + + subject { described_class.new(command) } let(:machine) { double("machine") } def assert_invalid errors = subject.validate(machine) - if !errors.values.any? { |v| !v.empty? } + if !errors.empty? { |v| !v.empty? } raise "No errors: #{errors.inspect}" end end def assert_valid errors = subject.validate(machine) - if !errors.values.all? { |v| v.empty? } + if !errors.empty? { |v| v.empty? } raise "Errors: #{errors.inspect}" end end From 3dec6869bb18826edd31d44937f7666dbe581fed Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Mon, 19 Mar 2018 15:02:51 -0700 Subject: [PATCH 30/95] Update trigger unit tests --- .../plugins/kernel_v2/config/trigger_test.rb | 100 ++++++++++++++++++ .../kernel_v2/config/vm_trigger_test.rb | 13 ++- 2 files changed, 110 insertions(+), 3 deletions(-) diff --git a/test/unit/plugins/kernel_v2/config/trigger_test.rb b/test/unit/plugins/kernel_v2/config/trigger_test.rb index 79199bd84..a14f2a1ad 100644 --- a/test/unit/plugins/kernel_v2/config/trigger_test.rb +++ b/test/unit/plugins/kernel_v2/config/trigger_test.rb @@ -35,4 +35,104 @@ describe VagrantPlugins::Kernel_V2::TriggerConfig do subject.finalize! assert_valid end + + let (:hash_block) { {info: "hi", run: {inline: "echo 'hi'"}} } + let (:splat) { [:up, :destroy, :halt] } + let (:arr) { [[:up, :destroy, :halt]] } + + describe "creating a before trigger" do + it "creates a trigger with the splat syntax" do + allow(subject).to receive(:create_trigger).and_return([:foo]) + subject.before(:up, hash_block) + bf_trigger = subject.instance_variable_get(:@_before_triggers) + expect(bf_trigger.size).to eq(1) + end + + it "creates a trigger with the array syntax" do + allow(subject).to receive(:create_trigger).and_return([:foo]) + subject.before([:up], hash_block) + bf_trigger = subject.instance_variable_get(:@_before_triggers) + expect(bf_trigger.size).to eq(1) + end + + it "creates a trigger with the block syntax" do + allow(subject).to receive(:create_trigger).and_return([:foo]) + subject.before :up do |trigger| + trigger.name = "rspec" + end + bf_trigger = subject.instance_variable_get(:@_before_triggers) + expect(bf_trigger.size).to eq(1) + end + + it "creates multiple triggers with the splat syntax" do + allow(subject).to receive(:create_trigger).and_return([:foo]) + subject.before(splat, hash_block) + bf_trigger = subject.instance_variable_get(:@_before_triggers) + expect(bf_trigger.size).to eq(3) + end + + it "creates multiple triggers with the block syntax" do + allow(subject).to receive(:create_trigger).and_return([:foo]) + subject.before splat do |trigger| + trigger.name = "rspec" + end + bf_trigger = subject.instance_variable_get(:@_before_triggers) + expect(bf_trigger.size).to eq(3) + end + + it "creates multiple triggers with the array syntax" do + allow(subject).to receive(:create_trigger).and_return([:foo]) + subject.before(arr, hash_block) + bf_trigger = subject.instance_variable_get(:@_before_triggers) + expect(bf_trigger.size).to eq(3) + end + end + + describe "creating an after trigger" do + it "creates a trigger with the splat syntax" do + allow(subject).to receive(:create_trigger).and_return([:foo]) + subject.after(:up, hash_block) + af_trigger = subject.instance_variable_get(:@_after_triggers) + expect(af_trigger.size).to eq(1) + end + + it "creates a trigger with the array syntax" do + allow(subject).to receive(:create_trigger).and_return([:foo]) + subject.after([:up], hash_block) + af_trigger = subject.instance_variable_get(:@_after_triggers) + expect(af_trigger.size).to eq(1) + end + + it "creates a trigger with the block syntax" do + allow(subject).to receive(:create_trigger).and_return([:foo]) + subject.after :up do |trigger| + trigger.name = "rspec" + end + af_trigger = subject.instance_variable_get(:@_after_triggers) + expect(af_trigger.size).to eq(1) + end + + it "creates multiple triggers with the splat syntax" do + allow(subject).to receive(:create_trigger).and_return([:foo]) + subject.after(splat, hash_block) + af_trigger = subject.instance_variable_get(:@_after_triggers) + expect(af_trigger.size).to eq(3) + end + + it "creates multiple triggers with the block syntax" do + allow(subject).to receive(:create_trigger).and_return([:foo]) + subject.after splat do |trigger| + trigger.name = "rspec" + end + af_trigger = subject.instance_variable_get(:@_after_triggers) + expect(af_trigger.size).to eq(3) + end + + it "creates multiple triggers with the array syntax" do + allow(subject).to receive(:create_trigger).and_return([:foo]) + subject.after(arr, hash_block) + af_trigger = subject.instance_variable_get(:@_after_triggers) + expect(af_trigger.size).to eq(3) + end + end end diff --git a/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb b/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb index c7b7fb139..71a04bb4b 100644 --- a/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb +++ b/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb @@ -35,8 +35,15 @@ describe VagrantPlugins::Kernel_V2::VagrantConfigTrigger do subject.name = "foo" end - it "is valid with test defaults" do - subject.finalize! - assert_valid + describe "with defaults" do + it "is valid with test defaults" do + subject.finalize! + assert_valid + end + + it "sets a command" do + expect(subject.command).to eq(command) + end end + end From 6cbb5d8e5d46cc5971d64484219704a9e71d13f3 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Mon, 19 Mar 2018 15:29:58 -0700 Subject: [PATCH 31/95] Add unit tests for config, fix type change bug with map! --- plugins/kernel_v2/config/vm_trigger.rb | 4 +- .../kernel_v2/config/vm_trigger_test.rb | 67 +++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb index edee528ba..c0220f4ea 100644 --- a/plugins/kernel_v2/config/vm_trigger.rb +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -101,13 +101,13 @@ module VagrantPlugins # Guests are stored internally as strings if !@only_on.nil? @only_on = Array(@only_on) - @only_on.map { |o| o.to_s } + @only_on.map! { |o| o.to_s } end # Commands must be stored internally as symbols if !@ignore.nil? @ignore = Array(@ignore) - @ignore.map { |i| i.to_sym } + @ignore.map! { |i| i.to_sym } end # Convert @run and @run_remote to be a "Shell provisioner" config diff --git a/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb b/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb index 71a04bb4b..da4b7f108 100644 --- a/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb +++ b/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb @@ -46,4 +46,71 @@ describe VagrantPlugins::Kernel_V2::VagrantConfigTrigger do end end + describe "defining a new config that needs to match internal restraints" do + let(:cmd) { :destroy } + let(:cfg) { described_class.new(cmd) } + let(:arr_cfg) { described_class.new(cmd) } + + before do + cfg.only_on = :guest + cfg.ignore = "up" + arr_cfg.only_on = [:guest, :other] + arr_cfg.ignore = ["up", "destroy"] + end + + it "ensures only_on is an array of strings" do + cfg.finalize! + arr_cfg.finalize! + + expect(cfg.only_on).to be_a(Array) + expect(arr_cfg.only_on).to be_a(Array) + + cfg.only_on.each do |a| + expect(a).to be_a(String) + end + + arr_cfg.only_on.each do |a| + expect(a).to be_a(String) + end + end + + it "ensures ignore is an array of symbols" do + cfg.finalize! + arr_cfg.finalize! + + expect(cfg.ignore).to be_a(Array) + expect(arr_cfg.ignore).to be_a(Array) + + cfg.ignore.each do |a| + expect(a).to be_a(Symbol) + end + + arr_cfg.ignore.each do |a| + expect(a).to be_a(Symbol) + end + end + end + + describe "defining a basic trigger config" do + let(:cmd) { :up } + let(:cfg) { described_class.new(cmd) } + + before do + cfg.info = "Hello there" + cfg.warn = "Warning!!" + cfg.on_error = :continue + cfg.ignore = :up + cfg.only_on = "guest" + end + + it "sets the options" do + cfg.finalize! + expect(cfg.info).to eq("Hello there") + expect(cfg.warn).to eq("Warning!!") + expect(cfg.on_error).to eq(:continue) + expect(cfg.ignore).to eq([:up]) + expect(cfg.only_on).to eq(["guest"]) + end + end + end From abb6d77442d68a6d1f278f5300f65273a5d5c2df Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Mon, 19 Mar 2018 15:34:35 -0700 Subject: [PATCH 32/95] Move location of command validator --- plugins/kernel_v2/config/vm_trigger.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb index c0220f4ea..5ce358431 100644 --- a/plugins/kernel_v2/config/vm_trigger.rb +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -136,6 +136,11 @@ module VagrantPlugins commands.push(key) end + if !commands.include?(@command) + machine.ui.warn(I18n.t("vagrant.config.triggers.bad_command_warning", + cmd: @command)) + end + # TODO: Does it make sense to strip out the "shell provisioner" error key here? # We could add more context around triggers? if @run @@ -148,11 +153,6 @@ module VagrantPlugins errors.concat errorz["shell provisioner"] if !errorz.empty? end - if !commands.include?(@command) - machine.ui.warn(I18n.t("vagrant.config.triggers.bad_command_warning", - cmd: @command)) - end - if !@name.nil? && !@name.is_a?(String) errors << I18n.t("vagrant.config.triggers.name_bad_type", cmd: @command) end From 7b1b044e7245a5d50d26e61bb4b07d5b2bad1336 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Mon, 19 Mar 2018 15:39:15 -0700 Subject: [PATCH 33/95] Check for default on_error behavior setting --- test/unit/plugins/kernel_v2/config/vm_trigger_test.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb b/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb index da4b7f108..3619cefe9 100644 --- a/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb +++ b/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb @@ -42,8 +42,14 @@ describe VagrantPlugins::Kernel_V2::VagrantConfigTrigger do end it "sets a command" do + subject.finalize! expect(subject.command).to eq(command) end + + it "uses default error behavior" do + subject.finalize! + expect(subject.on_error).to eq(:halt) + end end describe "defining a new config that needs to match internal restraints" do From e157362ace882a3a8751537ca4906c9260a5aeac Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Mon, 19 Mar 2018 16:16:33 -0700 Subject: [PATCH 34/95] Add run and run_remote expectations --- test/unit/plugins/kernel_v2/config/vm_trigger_test.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb b/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb index 3619cefe9..a7f064f4f 100644 --- a/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb +++ b/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb @@ -107,6 +107,8 @@ describe VagrantPlugins::Kernel_V2::VagrantConfigTrigger do cfg.on_error = :continue cfg.ignore = :up cfg.only_on = "guest" + cfg.run = {inline: "apt-get update"} + cfg.run_remote = {inline: "apt-get update", env: {"VAR"=>"VAL"}} end it "sets the options" do @@ -116,6 +118,8 @@ describe VagrantPlugins::Kernel_V2::VagrantConfigTrigger do expect(cfg.on_error).to eq(:continue) expect(cfg.ignore).to eq([:up]) expect(cfg.only_on).to eq(["guest"]) + expect(cfg.run).to be_a(VagrantPlugins::Shell::Config) + expect(cfg.run_remote).to be_a(VagrantPlugins::Shell::Config) end end From fc526a164aab2ba948da7da1b30fe943e0bf529c Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Mon, 19 Mar 2018 16:33:06 -0700 Subject: [PATCH 35/95] Add basic create_trigger rspec test --- .../plugins/kernel_v2/config/trigger_test.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/unit/plugins/kernel_v2/config/trigger_test.rb b/test/unit/plugins/kernel_v2/config/trigger_test.rb index a14f2a1ad..a044eff0b 100644 --- a/test/unit/plugins/kernel_v2/config/trigger_test.rb +++ b/test/unit/plugins/kernel_v2/config/trigger_test.rb @@ -135,4 +135,21 @@ describe VagrantPlugins::Kernel_V2::TriggerConfig do expect(af_trigger.size).to eq(3) end end + + describe "#create_trigger" do + let(:command) { :up } + let(:hash_block) { {info: "hi", run: {inline: "echo 'hi'"}} } + + it "returns a new VagrantConfigTrigger object if given a hash" do + trigger = subject.create_trigger(command, hash_block) + expect(trigger).to be_a(VagrantPlugins::Kernel_V2::VagrantConfigTrigger) + end + + it "returns a new VagrantConfigTrigger object if given a block" do + block = Proc.new { |b| b.info = "test"} + + trigger = subject.create_trigger(command, block) + expect(trigger).to be_a(VagrantPlugins::Kernel_V2::VagrantConfigTrigger) + end + end end From 7dae1acd21b58f740bc8a938137a4531833c2e68 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 20 Mar 2018 11:14:19 -0700 Subject: [PATCH 36/95] Add some "default" options to be validated --- test/unit/plugins/kernel_v2/config/vm_trigger_test.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb b/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb index a7f064f4f..9edae20ea 100644 --- a/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb +++ b/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb @@ -33,6 +33,12 @@ describe VagrantPlugins::Kernel_V2::VagrantConfigTrigger do allow(machine).to receive(:provider_options).and_return({}) subject.name = "foo" + subject.info = "Hello there" + subject.warn = "Warning!!" + subject.ignore = :up + subject.only_on = "guest" + subject.run = {inline: "apt-get update"} + subject.run_remote = {inline: "apt-get update", env: {"VAR"=>"VAL"}} end describe "with defaults" do From 956ed004bbfb7f2bb182282b70686b3ab243e156 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 20 Mar 2018 15:44:23 -0700 Subject: [PATCH 37/95] Update trigger config merge function --- plugins/kernel_v2/config/trigger.rb | 43 +++++++++++++++---- .../plugins/kernel_v2/config/trigger_test.rb | 39 +++++++++++++++++ 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 0b24b450c..0535e0565 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -101,7 +101,6 @@ module VagrantPlugins return trigger end - # Solve the mystery of disappearing state?? def merge(other) super.tap do |result| new_before_triggers = [] @@ -109,17 +108,43 @@ module VagrantPlugins other_defined_before_triggers = other.instance_variable_get(:@_before_triggers) other_defined_after_triggers = other.instance_variable_get(:@_after_triggers) - # TODO: Is this the right solution? - # If a guest in a Vagrantfile exists beyond the default, this check - # will properly set up the defined triggers and validate them. - # overrides??? check for duplicate ids? - if other_defined_before_triggers.empty? && !@_before_triggers.empty? - result.instance_variable_set(:@_before_triggers, @_before_triggers) + @_before_triggers.each do |bt| + other_bft = other_defined_before_triggers.find { |o| bt.id == o.id } + if other_bft + # Override, take it + other_bft = bt.merge(other_bft) + + # Preserve order, always + bt = other_bft + other_defined_before_triggers.delete(other_bft) + end + + new_before_triggers << bt.dup end - if other_defined_before_triggers.empty? && !@_after_triggers.empty? - result.instance_variable_set(:@_after_triggers, @_after_triggers) + other_defined_before_triggers.each do |obt| + new_before_triggers << obt.dup end + result.instance_variable_set(:@_before_triggers, new_before_triggers) + + @_after_triggers.each do |at| + other_aft = other_defined_after_triggers.find { |o| at.id == o.id } + if other_aft + # Override, take it + other_aft = at.merge(other_aft) + + # Preserve order, always + at = other_aft + other_defined_after_triggers.delete(other_aft) + end + + new_after_triggers << at.dup + end + + other_defined_after_triggers.each do |oat| + new_after_triggers << oat.dup + end + result.instance_variable_set(:@_after_triggers, new_after_triggers) end end diff --git a/test/unit/plugins/kernel_v2/config/trigger_test.rb b/test/unit/plugins/kernel_v2/config/trigger_test.rb index a044eff0b..4b5e1ed1f 100644 --- a/test/unit/plugins/kernel_v2/config/trigger_test.rb +++ b/test/unit/plugins/kernel_v2/config/trigger_test.rb @@ -152,4 +152,43 @@ describe VagrantPlugins::Kernel_V2::TriggerConfig do expect(trigger).to be_a(VagrantPlugins::Kernel_V2::VagrantConfigTrigger) end end + + describe "#merge" do + it "merges defined triggers" do + a = described_class.new() + b = described_class.new() + + a.before(splat, hash_block) + a.after(arr, hash_block) + b.before(splat, hash_block) + b.after(arr, hash_block) + + result = a.merge(b) + bf_trigger = result.instance_variable_get(:@_before_triggers) + af_trigger = result.instance_variable_get(:@_after_triggers) + + expect(bf_trigger).to be_a(Array) + expect(af_trigger).to be_a(Array) + expect(bf_trigger.size).to eq(6) + expect(af_trigger.size).to eq(6) + end + + it "merges the other triggers if a class is empty" do + a = described_class.new() + b = described_class.new() + + a.before(splat, hash_block) + a.after(arr, hash_block) + + b_bf_trigger = b.instance_variable_get(:@_before_triggers) + b_af_trigger = b.instance_variable_get(:@_after_triggers) + + result = a.merge(b) + bf_trigger = result.instance_variable_get(:@_before_triggers) + af_trigger = result.instance_variable_get(:@_after_triggers) + + expect(bf_trigger.size).to eq(3) + expect(af_trigger.size).to eq(3) + end + end end From e7274f1b6ced09ad2bd923ee4368d49446fd2094 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 20 Mar 2018 15:44:38 -0700 Subject: [PATCH 38/95] Improve config rspec tests --- .../plugins/kernel_v2/config/trigger_test.rb | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/unit/plugins/kernel_v2/config/trigger_test.rb b/test/unit/plugins/kernel_v2/config/trigger_test.rb index 4b5e1ed1f..a9bf3bbc2 100644 --- a/test/unit/plugins/kernel_v2/config/trigger_test.rb +++ b/test/unit/plugins/kernel_v2/config/trigger_test.rb @@ -42,97 +42,97 @@ describe VagrantPlugins::Kernel_V2::TriggerConfig do describe "creating a before trigger" do it "creates a trigger with the splat syntax" do - allow(subject).to receive(:create_trigger).and_return([:foo]) subject.before(:up, hash_block) bf_trigger = subject.instance_variable_get(:@_before_triggers) expect(bf_trigger.size).to eq(1) + expect(bf_trigger.first).to be_a(VagrantPlugins::Kernel_V2::VagrantConfigTrigger) end it "creates a trigger with the array syntax" do - allow(subject).to receive(:create_trigger).and_return([:foo]) subject.before([:up], hash_block) bf_trigger = subject.instance_variable_get(:@_before_triggers) expect(bf_trigger.size).to eq(1) + expect(bf_trigger.first).to be_a(VagrantPlugins::Kernel_V2::VagrantConfigTrigger) end it "creates a trigger with the block syntax" do - allow(subject).to receive(:create_trigger).and_return([:foo]) subject.before :up do |trigger| trigger.name = "rspec" end bf_trigger = subject.instance_variable_get(:@_before_triggers) expect(bf_trigger.size).to eq(1) + expect(bf_trigger.first).to be_a(VagrantPlugins::Kernel_V2::VagrantConfigTrigger) end it "creates multiple triggers with the splat syntax" do - allow(subject).to receive(:create_trigger).and_return([:foo]) subject.before(splat, hash_block) bf_trigger = subject.instance_variable_get(:@_before_triggers) expect(bf_trigger.size).to eq(3) + bf_trigger.map { |t| expect(t).to be_a(VagrantPlugins::Kernel_V2::VagrantConfigTrigger) } end it "creates multiple triggers with the block syntax" do - allow(subject).to receive(:create_trigger).and_return([:foo]) subject.before splat do |trigger| trigger.name = "rspec" end bf_trigger = subject.instance_variable_get(:@_before_triggers) expect(bf_trigger.size).to eq(3) + bf_trigger.map { |t| expect(t).to be_a(VagrantPlugins::Kernel_V2::VagrantConfigTrigger) } end it "creates multiple triggers with the array syntax" do - allow(subject).to receive(:create_trigger).and_return([:foo]) subject.before(arr, hash_block) bf_trigger = subject.instance_variable_get(:@_before_triggers) expect(bf_trigger.size).to eq(3) + bf_trigger.map { |t| expect(t).to be_a(VagrantPlugins::Kernel_V2::VagrantConfigTrigger) } end end describe "creating an after trigger" do it "creates a trigger with the splat syntax" do - allow(subject).to receive(:create_trigger).and_return([:foo]) subject.after(:up, hash_block) af_trigger = subject.instance_variable_get(:@_after_triggers) expect(af_trigger.size).to eq(1) + expect(af_trigger.first).to be_a(VagrantPlugins::Kernel_V2::VagrantConfigTrigger) end it "creates a trigger with the array syntax" do - allow(subject).to receive(:create_trigger).and_return([:foo]) subject.after([:up], hash_block) af_trigger = subject.instance_variable_get(:@_after_triggers) expect(af_trigger.size).to eq(1) + expect(af_trigger.first).to be_a(VagrantPlugins::Kernel_V2::VagrantConfigTrigger) end it "creates a trigger with the block syntax" do - allow(subject).to receive(:create_trigger).and_return([:foo]) subject.after :up do |trigger| trigger.name = "rspec" end af_trigger = subject.instance_variable_get(:@_after_triggers) expect(af_trigger.size).to eq(1) + expect(af_trigger.first).to be_a(VagrantPlugins::Kernel_V2::VagrantConfigTrigger) end it "creates multiple triggers with the splat syntax" do - allow(subject).to receive(:create_trigger).and_return([:foo]) subject.after(splat, hash_block) af_trigger = subject.instance_variable_get(:@_after_triggers) expect(af_trigger.size).to eq(3) + af_trigger.map { |t| expect(t).to be_a(VagrantPlugins::Kernel_V2::VagrantConfigTrigger) } end it "creates multiple triggers with the block syntax" do - allow(subject).to receive(:create_trigger).and_return([:foo]) subject.after splat do |trigger| trigger.name = "rspec" end af_trigger = subject.instance_variable_get(:@_after_triggers) expect(af_trigger.size).to eq(3) + af_trigger.map { |t| expect(t).to be_a(VagrantPlugins::Kernel_V2::VagrantConfigTrigger) } end it "creates multiple triggers with the array syntax" do - allow(subject).to receive(:create_trigger).and_return([:foo]) subject.after(arr, hash_block) af_trigger = subject.instance_variable_get(:@_after_triggers) expect(af_trigger.size).to eq(3) + af_trigger.map { |t| expect(t).to be_a(VagrantPlugins::Kernel_V2::VagrantConfigTrigger) } end end From a5d8cc1caa52e3bd86a760a3cfef7731036279d6 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 21 Mar 2018 10:23:03 -0700 Subject: [PATCH 39/95] Update trigger classes with comments --- plugins/kernel_v2/config/trigger.rb | 6 +++--- plugins/kernel_v2/config/vm_trigger.rb | 8 +++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/plugins/kernel_v2/config/trigger.rb b/plugins/kernel_v2/config/trigger.rb index 0535e0565..8a9b49cd3 100644 --- a/plugins/kernel_v2/config/trigger.rb +++ b/plugins/kernel_v2/config/trigger.rb @@ -1,5 +1,4 @@ require "vagrant" - require File.expand_path("../vm_trigger", __FILE__) module VagrantPlugins @@ -48,6 +47,7 @@ module VagrantPlugins # and the rest are commands for the trigger blk = command.pop else + # TODO: # No config block given at all, validation step should throw error? end @@ -71,6 +71,7 @@ module VagrantPlugins # and the rest are commands for the trigger blk = command.pop else + # TODO: # No config block given at all, validation step should throw error? end @@ -148,9 +149,8 @@ module VagrantPlugins end end + # Iterates over all defined triggers and finalizes their config objects def finalize! - # read through configured settings blocks and set their values - # and then set up action hooks here? if !@_before_triggers.empty? @_before_triggers.map { |t| t.finalize! } end diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb index 5ce358431..ed09d8900 100644 --- a/plugins/kernel_v2/config/vm_trigger.rb +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -1,11 +1,11 @@ require 'log4r' - require Vagrant.source_root.join('plugins/provisioners/shell/config') module VagrantPlugins module Kernel_V2 # Represents a single configured provisioner for a VM. class VagrantConfigTrigger < Vagrant.plugin("2", :config) + # Defaults DEFAULT_ON_ERROR = :halt #------------------------------------------------------------------- @@ -68,7 +68,6 @@ module VagrantPlugins def initialize(command) @logger = Log4r::Logger.new("vagrant::config::vm::trigger::config") - #@logger.debug("Trigger defined: #{name}") @name = UNSET_VALUE @info = UNSET_VALUE @@ -82,10 +81,13 @@ module VagrantPlugins # Internal options @id = SecureRandom.uuid @command = command.to_sym + + @logger.debug("Trigger defined for command: #{command}") end def finalize! - # Ensure all config options are set to nil if untouched by user + # Ensure all config options are set to nil or default value if untouched + # by user @name = nil if @name == UNSET_VALUE @info = nil if @info == UNSET_VALUE @warn = nil if @warn == UNSET_VALUE From 4ecf6822659dd0d0936958f083a60b5994138eda Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 22 Mar 2018 15:40:17 -0700 Subject: [PATCH 40/95] Add basic trigger plugin scaffold --- lib/vagrant/plugin/v2.rb | 1 + lib/vagrant/plugin/v2/trigger.rb | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 lib/vagrant/plugin/v2/trigger.rb diff --git a/lib/vagrant/plugin/v2.rb b/lib/vagrant/plugin/v2.rb index 953f73ff6..5bf2cdd41 100644 --- a/lib/vagrant/plugin/v2.rb +++ b/lib/vagrant/plugin/v2.rb @@ -19,6 +19,7 @@ module Vagrant autoload :Push, "vagrant/plugin/v2/push" autoload :Provisioner, "vagrant/plugin/v2/provisioner" autoload :SyncedFolder, "vagrant/plugin/v2/synced_folder" + autoload :Trigger, "vagrant/plugin/v2/trigger" end end end diff --git a/lib/vagrant/plugin/v2/trigger.rb b/lib/vagrant/plugin/v2/trigger.rb new file mode 100644 index 000000000..175529e48 --- /dev/null +++ b/lib/vagrant/plugin/v2/trigger.rb @@ -0,0 +1,23 @@ +require 'log4r' + +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 + attr_reader :config + + # Trigger + # + # @param [Object] env Vagrant environment + # @param [Object] config Trigger configuration + def initialize(env, config) + @env = env + @config = config + @logger = Log4r::Logger.new("vagrant::trigger::#{self.class.to_s.downcase}") + end + end + end + end +end From 372a6a7911d48e10a3bbce67b0acd3e77a103d09 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 28 Mar 2018 15:02:58 -0700 Subject: [PATCH 41/95] Initial trigger plugin scaffolding --- lib/vagrant/machine.rb | 4 ++ lib/vagrant/plugin/v2/command.rb | 2 +- lib/vagrant/plugin/v2/trigger.rb | 108 ++++++++++++++++++++++++++-- plugins/kernel_v2/config/trigger.rb | 10 +++ 4 files changed, 119 insertions(+), 5 deletions(-) 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] From 1462b3f71800839c6c73f4f27911776de62e9ca4 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 28 Mar 2018 15:34:16 -0700 Subject: [PATCH 42/95] Simplify trigger command filtering --- lib/vagrant/plugin/v2/trigger.rb | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/vagrant/plugin/v2/trigger.rb b/lib/vagrant/plugin/v2/trigger.rb index d30326d17..373b506a1 100644 --- a/lib/vagrant/plugin/v2/trigger.rb +++ b/lib/vagrant/plugin/v2/trigger.rb @@ -30,11 +30,9 @@ module Vagrant # @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 = config.before_triggers.select do |trigger| + trigger.command == action + end triggers = filter_triggers(triggers, guest_name) binding.pry @@ -51,12 +49,10 @@ module Vagrant # @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 = config.after_triggers.select do |trigger| + trigger.command == action + end triggers = filter_triggers(triggers, guest_name) binding.pry @@ -110,12 +106,15 @@ module Vagrant # # @param [ShellProvisioner/Config] config A Shell provisioner config def run(config) + @logger.info("Running script on the host...") end # Runs a script on the host # # @param [ShellProvisioner/Config] config A Shell provisioner config def run_remote(config) + @logger.info("Running script on the guest...") + # make sure guest actually exists, if not, display a WARNING end end end From 0e5cd900f8b8f650a1a80c0284c00b8e55591372 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 28 Mar 2018 15:38:08 -0700 Subject: [PATCH 43/95] Add missing param --- lib/vagrant/plugin/v2/trigger.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vagrant/plugin/v2/trigger.rb b/lib/vagrant/plugin/v2/trigger.rb index 373b506a1..639b1af8c 100644 --- a/lib/vagrant/plugin/v2/trigger.rb +++ b/lib/vagrant/plugin/v2/trigger.rb @@ -81,7 +81,7 @@ module Vagrant # Fires off all triggers in the given array # # @param [Array] triggers An array of triggers to be fired - def fire(triggers) + def fire(triggers, guest_name) # ensure on_error is respected by exiting or continuing triggers.each do |trigger| From 76418b9fcd954647627eab24ca850ae52db5150a Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 28 Mar 2018 16:22:50 -0700 Subject: [PATCH 44/95] Simplify trigger selection --- lib/vagrant/plugin/v2/trigger.rb | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/vagrant/plugin/v2/trigger.rb b/lib/vagrant/plugin/v2/trigger.rb index 639b1af8c..39644725d 100644 --- a/lib/vagrant/plugin/v2/trigger.rb +++ b/lib/vagrant/plugin/v2/trigger.rb @@ -30,9 +30,7 @@ module Vagrant # @param [String] guest_name The guest that invoked firing the triggers def fire_before_triggers(action, guest_name) # get all triggers matching action - triggers = config.before_triggers.select do |trigger| - trigger.command == action - end + triggers = config.before_triggers.select { |t| t.command == action } triggers = filter_triggers(triggers, guest_name) binding.pry @@ -49,10 +47,8 @@ module Vagrant # @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) - triggers = [] - triggers = config.after_triggers.select do |trigger| - trigger.command == action - end + # get all triggers matching action + triggers = config.after_triggers.select { |t| t.command == action } triggers = filter_triggers(triggers, guest_name) binding.pry From 6373441ab21da5b57b71ce2001c9fabb7dfd6285 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 28 Mar 2018 16:59:41 -0700 Subject: [PATCH 45/95] Ensure guest name is a string --- lib/vagrant/machine.rb | 4 ++-- lib/vagrant/plugin/v2/trigger.rb | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/vagrant/machine.rb b/lib/vagrant/machine.rb index 7dd643434..ce2278b3b 100644 --- a/lib/vagrant/machine.rb +++ b/lib/vagrant/machine.rb @@ -160,7 +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) + @triggers.fire_before_triggers(name, @name.to_s) @logger.info("Calling action: #{name} on provider #{@provider}") opts ||= {} @@ -206,7 +206,7 @@ module Vagrant action_result end - @triggers.fire_after_triggers(name, @name) + @triggers.fire_after_triggers(name, @name.to_s) rescue Errors::EnvironmentLockedError raise Errors::MachineActionLockedError, action: name, diff --git a/lib/vagrant/plugin/v2/trigger.rb b/lib/vagrant/plugin/v2/trigger.rb index 39644725d..e6e73f528 100644 --- a/lib/vagrant/plugin/v2/trigger.rb +++ b/lib/vagrant/plugin/v2/trigger.rb @@ -71,6 +71,8 @@ module Vagrant # @param [Array] triggers An array of triggers to be filtered # @return [Array] The filtered array of triggers def filter_triggers(triggers, guest_name) + binding.pry + # look for only_on triggers and if it doesn't match guest name, throw it away return triggers end From 09bb98679cf1d372d9d6b31984a3ac247bd1e07c Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 29 Mar 2018 09:08:25 -0700 Subject: [PATCH 46/95] Add basic website pages for triggers --- website/source/docs/triggers/configuration.html.md | 10 ++++++++++ website/source/docs/triggers/index.html.md | 10 ++++++++++ website/source/docs/triggers/usage.html.md | 10 ++++++++++ website/source/layouts/docs.erb | 8 ++++++++ 4 files changed, 38 insertions(+) create mode 100644 website/source/docs/triggers/configuration.html.md create mode 100644 website/source/docs/triggers/index.html.md create mode 100644 website/source/docs/triggers/usage.html.md diff --git a/website/source/docs/triggers/configuration.html.md b/website/source/docs/triggers/configuration.html.md new file mode 100644 index 000000000..5e26d0e11 --- /dev/null +++ b/website/source/docs/triggers/configuration.html.md @@ -0,0 +1,10 @@ +--- +layout: "docs" +page_title: "Vagrant Triggers Configuration" +sidebar_current: "triggers-configuration" +description: |- + Description goes here +--- + +# Vagrant Triggers Configuration + diff --git a/website/source/docs/triggers/index.html.md b/website/source/docs/triggers/index.html.md new file mode 100644 index 000000000..394695d9d --- /dev/null +++ b/website/source/docs/triggers/index.html.md @@ -0,0 +1,10 @@ +--- +layout: "docs" +page_title: "Vagrant Triggers" +sidebar_current: "triggers" +description: |- + Description goes here +--- + +# Vagrant Triggers + diff --git a/website/source/docs/triggers/usage.html.md b/website/source/docs/triggers/usage.html.md new file mode 100644 index 000000000..3b8d86d7c --- /dev/null +++ b/website/source/docs/triggers/usage.html.md @@ -0,0 +1,10 @@ +--- +layout: "docs" +page_title: "Vagrant Triggers Usage" +sidebar_current: "triggers-usage" +description: |- + Description goes here +--- + +# Vagrant Triggers Usage + diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index 984887372..de509850c 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -207,6 +207,14 @@ + > + Triggers + + + > Other