plugins/kernel_v2/config/vm_provisioner.rb in vagrant-unbundled-2.2.5.0 vs plugins/kernel_v2/config/vm_provisioner.rb in vagrant-unbundled-2.2.6.0

- old
+ new

@@ -1,11 +1,14 @@ require 'log4r' module VagrantPlugins module Kernel_V2 # Represents a single configured provisioner for a VM. - class VagrantConfigProvisioner + class VagrantConfigProvisioner < Vagrant.plugin("2", :config) + # Defaults + VALID_BEFORE_AFTER_TYPES = [:each, :all].freeze + # Unique name for this provisioner # # @return [String] attr_reader :name @@ -27,32 +30,44 @@ # The configuration associated with the provisioner, if there is any. # # @return [Object] attr_accessor :config - # When to run this provisioner. Either "once" or "always" + # When to run this provisioner. Either "once", "always", or "never" # # @return [String] attr_accessor :run # Whether or not to preserve the order when merging this with a # parent scope. # # @return [Boolean] attr_accessor :preserve_order - def initialize(name, type) + # The name of a provisioner to run before it has started + # + # @return [String, Symbol] + attr_accessor :before + + # The name of a provisioner to run after it is finished + # + # @return [String, Symbol] + attr_accessor :after + + def initialize(name, type, **options) @logger = Log4r::Logger.new("vagrant::config::vm::provisioner") @logger.debug("Provisioner defined: #{name}") @id = name || SecureRandom.uuid @config = nil @invalid = false @name = name @preserve_order = false @run = nil @type = type + @before = options[:before] + @after = options[:after] # Attempt to find the provisioner... if !Vagrant.plugin("2").manager.provisioners[type] @logger.warn("Provisioner '#{type}' not found.") @invalid = true @@ -86,9 +101,78 @@ def finalize! return if invalid? @config.finalize! + end + + # Validates the before/after options + # + # @param [Vagrant::Machine] machine - machine to validate against + # @param [Array] provisioners - Array of defined provisioners for the guest machine + # @return [Array] array of strings of error messages from config option validation + def validate(machine, provisioners) + errors = _detected_errors + + provisioner_names = provisioners.map { |i| i.name.to_s if i.name != name }.compact + + if @before && @after + errors << I18n.t("vagrant.provisioners.base.both_before_after_set") + end + + if @before + if !VALID_BEFORE_AFTER_TYPES.include?(@before) + if @before.is_a?(Symbol) && !VALID_BEFORE_AFTER_TYPES.include?(@before) + errors << I18n.t("vagrant.provisioners.base.invalid_alias_value", opt: "before", alias: VALID_BEFORE_AFTER_TYPES.join(", ")) + elsif !@before.is_a?(String) && !VALID_BEFORE_AFTER_TYPES.include?(@before) + errors << I18n.t("vagrant.provisioners.base.wrong_type", opt: "before") + end + + if !provisioner_names.include?(@before) + errors << I18n.t("vagrant.provisioners.base.missing_provisioner_name", + name: @before, + machine_name: machine.name, + action: "before", + provisioner_name: @name) + end + + dep_prov = provisioners.find_all { |i| i.name.to_s == @before && (i.before || i.after) } + + if !dep_prov.empty? + errors << I18n.t("vagrant.provisioners.base.dependency_provisioner_dependency", + name: @name, + dep_name: dep_prov.first.name.to_s) + end + end + end + + if @after + if !VALID_BEFORE_AFTER_TYPES.include?(@after) + if @after.is_a?(Symbol) + errors << I18n.t("vagrant.provisioners.base.invalid_alias_value", opt: "after", alias: VALID_BEFORE_AFTER_TYPES.join(", ")) + elsif !@after.is_a?(String) + errors << I18n.t("vagrant.provisioners.base.wrong_type", opt: "after") + end + + if !provisioner_names.include?(@after) + errors << I18n.t("vagrant.provisioners.base.missing_provisioner_name", + name: @after, + machine_name: machine.name, + action: "after", + provisioner_name: @name) + end + + dep_prov = provisioners.find_all { |i| i.name.to_s == @after && (i.before || i.after) } + + if !dep_prov.empty? + errors << I18n.t("vagrant.provisioners.base.dependency_provisioner_dependency", + name: @name, + dep_name: dep_prov.first.name.to_s) + end + end + end + + {"provisioner" => errors} end # Returns whether the provisioner used was invalid or not. A provisioner # is invalid if it can't be found. #