From 58ebd52f997ea3cd41d14f4c08eb43fd6055772c Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Fri, 21 Sep 2018 17:08:26 -0700 Subject: [PATCH] Add abort option to core triggers This commit adds a new option `abort`, which when configured, will exit the Vagrant process completely. If set to `true`, it will exit cleanly with exit code 0. Otherwise, the exit code can be configured. --- lib/vagrant/plugin/v2/trigger.rb | 12 ++++++++++++ plugins/kernel_v2/config/vm_trigger.rb | 17 +++++++++++++++++ templates/locales/en.yml | 8 ++++++++ .../plugins/kernel_v2/config/vm_trigger_test.rb | 9 +++++++++ test/unit/vagrant/plugin/v2/trigger_test.rb | 12 ++++++++++++ .../source/docs/triggers/configuration.html.md | 2 ++ 6 files changed, 60 insertions(+) diff --git a/lib/vagrant/plugin/v2/trigger.rb b/lib/vagrant/plugin/v2/trigger.rb index 63b5a9386..73c9a7570 100644 --- a/lib/vagrant/plugin/v2/trigger.rb +++ b/lib/vagrant/plugin/v2/trigger.rb @@ -124,6 +124,10 @@ module Vagrant warn(trigger.warn) end + if trigger.abort + trigger_abort(trigger.abort) + end + if trigger.run run(trigger.run, trigger.on_error, trigger.exit_codes) end @@ -241,6 +245,14 @@ module Vagrant end end end + + # Exits Vagrant immediately + # + # @param [Integer] code Code to exit Vagrant on + def trigger_abort(exit_code) + @machine.ui.warn(I18n.t("vagrant.trigger.abort")) + exit(exit_code) + end end end end diff --git a/plugins/kernel_v2/config/vm_trigger.rb b/plugins/kernel_v2/config/vm_trigger.rb index a8d2ad138..ad856995a 100644 --- a/plugins/kernel_v2/config/vm_trigger.rb +++ b/plugins/kernel_v2/config/vm_trigger.rb @@ -72,6 +72,12 @@ module VagrantPlugins # @return [Integer, Array] attr_accessor :exit_codes + # If set to true, trigger will halt Vagrant immediately and exit 0 + # Can also be configured to have a custom exit code + # + # @return [Integer] + attr_accessor :abort + def initialize(command) @logger = Log4r::Logger.new("vagrant::config::vm::trigger::config") @@ -84,6 +90,7 @@ module VagrantPlugins @run = UNSET_VALUE @run_remote = UNSET_VALUE @exit_codes = UNSET_VALUE + @abort = UNSET_VALUE # Internal options @id = SecureRandom.uuid @@ -104,6 +111,7 @@ module VagrantPlugins @run_remote = nil if @run_remote == UNSET_VALUE @only_on = nil if @only_on == UNSET_VALUE @exit_codes = DEFAULT_EXIT_CODE if @exit_codes == UNSET_VALUE + @abort = nil if @abort == UNSET_VALUE # these values are expected to always be an Array internally, # but can be set as a single String or Symbol @@ -149,6 +157,9 @@ module VagrantPlugins @run_remote = new_run end + if @abort == true + @abort = 1 + end end # @return [Array] array of strings of error messages from config option validation @@ -208,6 +219,12 @@ module VagrantPlugins end end + if @abort && !@abort.is_a?(Integer) + errors << I18n.t("vagrant.config.triggers.abort_bad_type", cmd: @command) + elsif @abort == false + machine.ui.warn(I18n.t("vagrant.config.triggers.abort_false_type")) + end + errors end diff --git a/templates/locales/en.yml b/templates/locales/en.yml index b4f9ea139..8cd72513e 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -287,6 +287,8 @@ en: trigger: on_error_continue: |- Trigger configured to continue on error... + abort: |- + Vagrant has been configured to abort. Terminating now... start: |- Running triggers %{stage} %{action} ... fire_with_name: |- @@ -1768,6 +1770,12 @@ en: on_error_bad_type: |- Invalid type set for `on_error` on trigger for command '%{cmd}'. `on_error` can only be `:halt` (default) or `:continue`. + abort_bad_type: |- + Trigger option `abort` for command '%{cmd}' must be either set to + `true` (defaults to exit code 1) or an integer to use as an exit code. + abort_false_type: |- + `false` is not a valid option for the `abort` option for a trigger. This + will be ignored... exit_codes_bad_type: |- Invalid type set for `exit_codes` on trigger for command '%{cmd}'. `exit_codes` can only be a single integer or an array of integers. 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 a98068d29..a4b28153f 100644 --- a/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb +++ b/test/unit/plugins/kernel_v2/config/vm_trigger_test.rb @@ -66,6 +66,7 @@ describe VagrantPlugins::Kernel_V2::VagrantConfigTrigger do before do cfg.only_on = :guest cfg.ignore = "up" + cfg.abort = true arr_cfg.only_on = ["guest", /other/] arr_cfg.ignore = ["up", "destroy"] end @@ -93,6 +94,12 @@ describe VagrantPlugins::Kernel_V2::VagrantConfigTrigger do expect(a).to be_a(Symbol) end end + + it "converts aborts true to exit code 0" do + cfg.finalize! + + expect(cfg.abort).to eq(1) + end end describe "defining a basic trigger config" do @@ -104,6 +111,7 @@ describe VagrantPlugins::Kernel_V2::VagrantConfigTrigger do cfg.warn = "Warning!!" cfg.on_error = :continue cfg.ignore = :up + cfg.abort = 3 cfg.only_on = "guest" cfg.run = {inline: "apt-get update"} cfg.run_remote = {inline: "apt-get update", env: {"VAR"=>"VAL"}} @@ -118,6 +126,7 @@ describe VagrantPlugins::Kernel_V2::VagrantConfigTrigger do 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) + expect(cfg.abort).to eq(3) end end diff --git a/test/unit/vagrant/plugin/v2/trigger_test.rb b/test/unit/vagrant/plugin/v2/trigger_test.rb index c4023ca88..e413fdb51 100644 --- a/test/unit/vagrant/plugin/v2/trigger_test.rb +++ b/test/unit/vagrant/plugin/v2/trigger_test.rb @@ -373,4 +373,16 @@ describe Vagrant::Plugin::V2::Trigger do to raise_error("Nope!") end end + + context "#trigger_abort" do + + it "system exits when called" do + output = "" + allow(machine.ui).to receive(:warn) do |data| + output << data + end + + expect { subject.send(:trigger_abort, 3) }.to raise_error(SystemExit) + end + end end diff --git a/website/source/docs/triggers/configuration.html.md b/website/source/docs/triggers/configuration.html.md index c7528405b..bd801869c 100644 --- a/website/source/docs/triggers/configuration.html.md +++ b/website/source/docs/triggers/configuration.html.md @@ -44,3 +44,5 @@ The trigger class takes various options. * `warn` (string) - A warning message that will be printed at the beginning of a trigger. * `exit_codes` (integer, array) - A set of acceptable exit codes to continue on. Defaults to `0` if option is absent. For now only valid with the `run` option. + +* `abort` (integer,boolean) - An option that will exit the running Vagrant process once the trigger fires. If set to `true`, Vagrant will use exit code 1. Otherwise, an integer can be provided and Vagrant will it as its exit code when aborting.