vagrant/plugins/kernel_v2/config/trigger.rb

212 lines
6.6 KiB
Ruby
Raw Normal View History

2018-03-08 22:20:21 +00:00
require "vagrant"
require File.expand_path("../vm_trigger", __FILE__)
2018-03-08 22:20:21 +00:00
module VagrantPlugins
module Kernel_V2
class TriggerConfig < Vagrant.plugin("2", :config)
# The TriggerConfig class is what gets called when a user
# defines a new trigger in their Vagrantfile. The two entry points are
# either `config.trigger.before` or `config.trigger.after`.
2018-03-08 23:34:39 +00:00
2018-03-08 22:20:21 +00:00
def initialize
@logger = Log4r::Logger.new("vagrant::config::trigger")
# Internal State
2018-03-13 18:33:48 +00:00
@_before_triggers = [] # An array of VagrantConfigTrigger objects
@_after_triggers = [] # An array of VagrantConfigTrigger objects
2018-03-08 22:20:21 +00:00
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"
2018-03-10 00:45:48 +00:00
# Reads in and parses Vagrant command whitelist and settings for a defined
# trigger
#
# @param [Symbol] command Vagrant command to create trigger on
2018-03-10 00:45:48 +00:00
# @param [Block] block The defined before block
def before(*command, &block)
command.flatten!
blk = block
if command.last.is_a?(Hash)
if block_given?
extra_cfg = command.pop
else
# 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
end
elsif !block_given?
raise Vagrant::Errors::TriggersNoBlockGiven,
command: command
2018-03-10 00:45:48 +00:00
end
command.each do |cmd|
trigger = create_trigger(cmd, blk, extra_cfg)
@_before_triggers << trigger
end
2018-03-08 22:20:21 +00:00
end
# Reads in and parses Vagrant command whitelist and settings for a defined
# trigger
#
# @param [Symbol] command Vagrant command to create trigger on
2018-03-13 18:07:41 +00:00
# @param [Block] block The defined after block
def after(*command, &block)
command.flatten!
blk = block
2018-03-30 23:28:23 +00:00
if command.last.is_a?(Hash)
if block_given?
extra_cfg = command.pop
else
# 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
end
elsif !block_given?
raise Vagrant::Errors::TriggersNoBlockGiven,
command: command
2018-03-10 00:45:48 +00:00
end
2018-03-08 22:20:21 +00:00
2018-03-10 00:45:48 +00:00
command.each do |cmd|
trigger = create_trigger(cmd, blk, extra_cfg)
@_after_triggers << trigger
2018-03-10 00:45:48 +00:00
end
end
#-------------------------------------------------------------------
# Internal methods, don't call these.
#-------------------------------------------------------------------
2018-03-10 00:45:48 +00:00
# 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.
#
2018-03-13 18:07:41 +00:00
# @param [Symbol] command Vagrant command to create trigger on
# @param [Block] block The defined config block
# @param [Hash] extra_cfg Extra configurations for a block defined trigger (Optional)
# @return [VagrantConfigTrigger]
def create_trigger(command, block, extra_cfg=nil)
2018-03-13 18:13:25 +00:00
trigger = VagrantConfigTrigger.new(command)
2018-03-13 18:07:41 +00:00
if block.is_a?(Hash)
trigger.set_options(block)
else
block.call(trigger, VagrantConfigTrigger)
trigger.set_options(extra_cfg) if extra_cfg
2018-03-13 18:07:41 +00:00
end
return trigger
end
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)
2018-03-20 22:44:23 +00:00
@_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
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
2018-03-20 22:44:23 +00:00
other_defined_after_triggers.each do |oat|
new_after_triggers << oat.dup
end
2018-03-20 22:44:23 +00:00
result.instance_variable_set(:@_after_triggers, new_after_triggers)
end
end
2018-03-21 17:23:03 +00:00
# Iterates over all defined triggers and finalizes their config objects
2018-03-08 22:20:21 +00:00
def finalize!
if !@_before_triggers.empty?
@_before_triggers.map { |t| t.finalize! }
end
if !@_after_triggers.empty?
@_after_triggers.map { |t| t.finalize! }
end
2018-03-08 22:20:21 +00:00
end
2018-03-15 21:43:39 +00:00
# Validate Trigger Arrays
2018-03-08 22:20:21 +00:00
def validate(machine)
2018-03-09 21:06:26 +00:00
errors = _detected_errors
@_before_triggers.each do |bt|
error = bt.validate(machine)
errors.concat error if !error.empty?
end
@_after_triggers.each do |at|
error = at.validate(machine)
errors.concat error if !error.empty?
end
2018-03-09 21:06:26 +00:00
{"trigger" => errors}
2018-03-08 22:20:21 +00:00
end
2018-03-28 22:02:58 +00:00
# return [Array]
def before_triggers
@_before_triggers
end
# return [Array]
def after_triggers
@_after_triggers
end
2018-03-08 22:20:21 +00:00
# The String representation of this Trigger.
#
# @return [String]
def to_s
"trigger"
2018-03-08 22:20:21 +00:00
end
end
end
end