Prior to this commit, the default value of disk_ext was set in the finalize! method, and was really only valid for the virtualbox provider. This commit updates that by moving the step into the validate function, which has access to the machines provider.
209 lines
6.0 KiB
Ruby
209 lines
6.0 KiB
Ruby
require "log4r"
|
|
require "securerandom"
|
|
|
|
require "vagrant/util/numeric"
|
|
|
|
module VagrantPlugins
|
|
module Kernel_V2
|
|
class VagrantConfigDisk < Vagrant.plugin("2", :config)
|
|
#-------------------------------------------------------------------
|
|
# Config class for a given Disk
|
|
#-------------------------------------------------------------------
|
|
|
|
DEFAULT_DISK_TYPES = [:disk, :dvd, :floppy].freeze
|
|
|
|
# Note: This value is for internal use only
|
|
#
|
|
# @return [String]
|
|
attr_reader :id
|
|
|
|
# File name for the given disk. Defaults to a generated name that is:
|
|
#
|
|
# vagrant_<disk_type>_<short_uuid>
|
|
#
|
|
# @return [String]
|
|
attr_accessor :name
|
|
|
|
# Type of disk to create. Defaults to `:disk`
|
|
#
|
|
# @return [Symbol]
|
|
attr_accessor :type
|
|
|
|
# Type of disk extension to create. Defaults to `vdi`
|
|
#
|
|
# @return [String]
|
|
attr_accessor :disk_ext
|
|
|
|
# Size of disk to create
|
|
#
|
|
# @return [Integer,String]
|
|
attr_accessor :size
|
|
|
|
# Path to the location of the disk file (Optional)
|
|
#
|
|
# @return [String]
|
|
attr_accessor :file
|
|
|
|
# Determines if this disk is the _main_ disk, or an attachment.
|
|
# Defaults to true.
|
|
#
|
|
# @return [Boolean]
|
|
attr_accessor :primary
|
|
|
|
# Provider specific options
|
|
#
|
|
# @return [Hash]
|
|
attr_accessor :provider_config
|
|
|
|
def initialize(type)
|
|
@logger = Log4r::Logger.new("vagrant::config::vm::disk")
|
|
|
|
@type = type
|
|
@provider_config = {}
|
|
|
|
@name = UNSET_VALUE
|
|
@provider_type = UNSET_VALUE
|
|
@size = UNSET_VALUE
|
|
@primary = UNSET_VALUE
|
|
@file = UNSET_VALUE
|
|
@disk_ext = UNSET_VALUE
|
|
|
|
# Internal options
|
|
@id = SecureRandom.uuid
|
|
end
|
|
|
|
# Helper method for storing provider specific config options
|
|
#
|
|
# Expected format is:
|
|
#
|
|
# - `provider__diskoption: value`
|
|
# - `{provider: {diskoption: value, otherdiskoption: value, ...}`
|
|
#
|
|
# Duplicates will be overriden
|
|
#
|
|
# @param [Hash] options
|
|
def add_provider_config(**options, &block)
|
|
current = {}
|
|
options.each do |k,v|
|
|
opts = k.to_s.split("__")
|
|
|
|
if opts.size == 2
|
|
current[opts[0].to_sym] = {opts[1].to_sym => v}
|
|
elsif v.is_a?(Hash)
|
|
current[k] = v
|
|
else
|
|
@logger.warn("Disk option '#{k}' found that does not match expected provider disk config schema.")
|
|
end
|
|
end
|
|
|
|
current = @provider_config.merge(current) if !@provider_config.empty?
|
|
@provider_config = current
|
|
end
|
|
|
|
def finalize!
|
|
# Ensure all config options are set to nil or default value if untouched
|
|
# by user
|
|
@type = :disk if @type == UNSET_VALUE
|
|
@size = nil if @size == UNSET_VALUE
|
|
@file = nil if @file == UNSET_VALUE
|
|
|
|
if @primary == UNSET_VALUE
|
|
@primary = false
|
|
end
|
|
|
|
if @name == UNSET_VALUE
|
|
if @primary
|
|
@name = "vagrant_primary"
|
|
else
|
|
@name = nil
|
|
end
|
|
end
|
|
|
|
@provider_config = nil if @provider_config == {}
|
|
end
|
|
|
|
# @return [Array] array of strings of error messages from config option validation
|
|
def validate(machine)
|
|
errors = _detected_errors
|
|
|
|
# validate type with list of known disk types
|
|
|
|
if !DEFAULT_DISK_TYPES.include?(@type)
|
|
errors << I18n.t("vagrant.config.disk.invalid_type", type: @type,
|
|
types: DEFAULT_DISK_TYPES.join(', '))
|
|
end
|
|
|
|
if @disk_ext == UNSET_VALUE
|
|
# Work around to finalize disk_ext with a valid default per-provider
|
|
if machine.provider_name == :virtualbox
|
|
@disk_ext = "vdi"
|
|
elsif machine.provider_name == :vmware_desktop
|
|
@disk_ext = nil
|
|
elsif machine.provider_name == :hyperv
|
|
@disk_ext = "vhdx"
|
|
else
|
|
@disk_ext = "vdi"
|
|
end
|
|
elsif @disk_ext
|
|
@disk_ext = @disk_ext.downcase
|
|
|
|
if machine.provider.capability?(:validate_disk_ext)
|
|
if !machine.provider.capability(:validate_disk_ext, @disk_ext)
|
|
if machine.provider.capability?(:get_default_disk_ext)
|
|
disk_exts = machine.provider.capability(:get_default_disk_ext).join(', ')
|
|
else
|
|
disk_exts = "not found"
|
|
end
|
|
errors << I18n.t("vagrant.config.disk.invalid_ext", ext: @disk_ext,
|
|
name: @name,
|
|
exts: disk_exts)
|
|
end
|
|
else
|
|
@logger.warn("No provider capability defined to validate 'disk_ext' type")
|
|
end
|
|
end
|
|
|
|
if @size && !@size.is_a?(Integer)
|
|
if @size.is_a?(String)
|
|
@size = Vagrant::Util::Numeric.string_to_bytes(@size)
|
|
end
|
|
|
|
if !@size
|
|
errors << I18n.t("vagrant.config.disk.invalid_size", name: @name, machine: machine.name)
|
|
end
|
|
end
|
|
|
|
if @file
|
|
if !@file.is_a?(String)
|
|
errors << I18n.t("vagrant.config.disk.invalid_file_type", file: @file, machine: machine.name)
|
|
elsif !File.file?(@file)
|
|
errors << I18n.t("vagrant.config.disk.missing_file", file_path: @file,
|
|
name: @name, machine: machine.name)
|
|
end
|
|
end
|
|
|
|
if @provider_config
|
|
if !@provider_config.keys.include?(machine.provider_name)
|
|
machine.env.ui.warn(I18n.t("vagrant.config.disk.missing_provider",
|
|
machine: machine.name,
|
|
provider_name: machine.provider_name))
|
|
end
|
|
end
|
|
|
|
if !@name
|
|
errors << I18n.t("vagrant.config.disk.no_name_set", machine: machine.name)
|
|
end
|
|
|
|
errors
|
|
end
|
|
|
|
# The String representation of this Disk.
|
|
#
|
|
# @return [String]
|
|
def to_s
|
|
"disk config"
|
|
end
|
|
end
|
|
end
|
|
end
|