Merge pull request #11165 from briancain/feature/generic-disk-config-mgmnt
Introduce disk management base config layer to core Vagrant
This commit is contained in:
commit
9fc155bf75
|
@ -15,6 +15,7 @@ module Vagrant
|
||||||
autoload :Confirm, "vagrant/action/builtin/confirm"
|
autoload :Confirm, "vagrant/action/builtin/confirm"
|
||||||
autoload :ConfigValidate, "vagrant/action/builtin/config_validate"
|
autoload :ConfigValidate, "vagrant/action/builtin/config_validate"
|
||||||
autoload :DestroyConfirm, "vagrant/action/builtin/destroy_confirm"
|
autoload :DestroyConfirm, "vagrant/action/builtin/destroy_confirm"
|
||||||
|
autoload :Disk, "vagrant/action/builtin/disk"
|
||||||
autoload :EnvSet, "vagrant/action/builtin/env_set"
|
autoload :EnvSet, "vagrant/action/builtin/env_set"
|
||||||
autoload :GracefulHalt, "vagrant/action/builtin/graceful_halt"
|
autoload :GracefulHalt, "vagrant/action/builtin/graceful_halt"
|
||||||
autoload :HandleBox, "vagrant/action/builtin/handle_box"
|
autoload :HandleBox, "vagrant/action/builtin/handle_box"
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
module Vagrant
|
||||||
|
module Action
|
||||||
|
module Builtin
|
||||||
|
class Disk
|
||||||
|
def initialize(app, env)
|
||||||
|
@app = app
|
||||||
|
@logger = Log4r::Logger.new("vagrant::action::builtin::disk")
|
||||||
|
end
|
||||||
|
|
||||||
|
def call(env)
|
||||||
|
machine = env[:machine]
|
||||||
|
defined_disks = get_disks(machine, env)
|
||||||
|
|
||||||
|
# Call into providers machine implementation for disk management
|
||||||
|
if machine.provider.capability?(:configure_disks)
|
||||||
|
machine.provider.capability(:configure_disks, defined_disks)
|
||||||
|
else
|
||||||
|
env[:ui].warn(I18n.t("vagrant.actions.disk.provider_unsupported",
|
||||||
|
provider: machine.provider_name))
|
||||||
|
end
|
||||||
|
|
||||||
|
# Continue On
|
||||||
|
@app.call(env)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_disks(machine, env)
|
||||||
|
return @_disks if @_disks
|
||||||
|
|
||||||
|
@_disks = []
|
||||||
|
@_disks = machine.config.vm.disks
|
||||||
|
|
||||||
|
@_disks
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,61 @@
|
||||||
|
require "log4r"
|
||||||
|
|
||||||
|
module Vagrant
|
||||||
|
module Util
|
||||||
|
class Numeric
|
||||||
|
|
||||||
|
# Authors Note: This conversion has been borrowed from the ActiveSupport Numeric class
|
||||||
|
# Conversion helper constants
|
||||||
|
KILOBYTE = 1024
|
||||||
|
MEGABYTE = KILOBYTE * 1024
|
||||||
|
GIGABYTE = MEGABYTE * 1024
|
||||||
|
TERABYTE = GIGABYTE * 1024
|
||||||
|
PETABYTE = TERABYTE * 1024
|
||||||
|
EXABYTE = PETABYTE * 1024
|
||||||
|
|
||||||
|
BYTES_CONVERSION_MAP = {KB: KILOBYTE, MB: MEGABYTE, GB: GIGABYTE, TB: TERABYTE,
|
||||||
|
PB: PETABYTE, EB: EXABYTE}
|
||||||
|
|
||||||
|
# Regex borrowed from the vagrant-disksize config class
|
||||||
|
SHORTHAND_MATCH_REGEX = /^(?<number>[0-9]+)\s?(?<unit>KB|MB|GB|TB)?$/
|
||||||
|
|
||||||
|
class << self
|
||||||
|
LOGGER = Log4r::Logger.new("vagrant::util::numeric")
|
||||||
|
|
||||||
|
# A helper that converts a shortcut string to its bytes representation.
|
||||||
|
# The expected format of `str` is essentially: "<Number>XX"
|
||||||
|
# Where `XX` is shorthand for KB, MB, GB, TB, PB, or EB. For example, 50 megabytes:
|
||||||
|
#
|
||||||
|
# str = "50MB"
|
||||||
|
#
|
||||||
|
# @param [String] - str
|
||||||
|
# @return [Integer,nil] - bytes - returns nil if method fails to convert to bytes
|
||||||
|
def string_to_bytes(str)
|
||||||
|
bytes = nil
|
||||||
|
|
||||||
|
str = str.to_s.strip
|
||||||
|
matches = SHORTHAND_MATCH_REGEX.match(str)
|
||||||
|
if matches
|
||||||
|
number = matches[:number].to_i
|
||||||
|
unit = matches[:unit].to_sym
|
||||||
|
|
||||||
|
if BYTES_CONVERSION_MAP.key?(unit)
|
||||||
|
bytes = number * BYTES_CONVERSION_MAP[unit]
|
||||||
|
else
|
||||||
|
LOGGER.error("An invalid unit or format was given, string_to_bytes cannot convert #{str}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
bytes
|
||||||
|
end
|
||||||
|
|
||||||
|
# @private
|
||||||
|
# Reset the cached values for platform. This is not considered a public
|
||||||
|
# API and should only be used for testing.
|
||||||
|
def reset!
|
||||||
|
instance_variables.each(&method(:remove_instance_variable))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,168 @@
|
||||||
|
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
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# 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 = "name_#{@type.to_s}_#{@id.split("-").last}"
|
||||||
|
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 @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
|
||||||
|
|
||||||
|
errors
|
||||||
|
end
|
||||||
|
|
||||||
|
# The String representation of this Disk.
|
||||||
|
#
|
||||||
|
# @return [String]
|
||||||
|
def to_s
|
||||||
|
"disk config"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -11,6 +11,7 @@ require "vagrant/util/experimental"
|
||||||
|
|
||||||
require File.expand_path("../vm_provisioner", __FILE__)
|
require File.expand_path("../vm_provisioner", __FILE__)
|
||||||
require File.expand_path("../vm_subvm", __FILE__)
|
require File.expand_path("../vm_subvm", __FILE__)
|
||||||
|
require File.expand_path("../disk", __FILE__)
|
||||||
|
|
||||||
module VagrantPlugins
|
module VagrantPlugins
|
||||||
module Kernel_V2
|
module Kernel_V2
|
||||||
|
@ -43,6 +44,7 @@ module VagrantPlugins
|
||||||
attr_accessor :post_up_message
|
attr_accessor :post_up_message
|
||||||
attr_accessor :usable_port_range
|
attr_accessor :usable_port_range
|
||||||
attr_reader :provisioners
|
attr_reader :provisioners
|
||||||
|
attr_reader :disks
|
||||||
|
|
||||||
# This is an experimental feature that isn't public yet.
|
# This is an experimental feature that isn't public yet.
|
||||||
attr_accessor :clone
|
attr_accessor :clone
|
||||||
|
@ -73,6 +75,7 @@ module VagrantPlugins
|
||||||
@hostname = UNSET_VALUE
|
@hostname = UNSET_VALUE
|
||||||
@post_up_message = UNSET_VALUE
|
@post_up_message = UNSET_VALUE
|
||||||
@provisioners = []
|
@provisioners = []
|
||||||
|
@disks = []
|
||||||
@usable_port_range = UNSET_VALUE
|
@usable_port_range = UNSET_VALUE
|
||||||
|
|
||||||
# Internal state
|
# Internal state
|
||||||
|
@ -123,6 +126,28 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Merge defined disks
|
||||||
|
other_disks = other.instance_variable_get(:@disks)
|
||||||
|
new_disks = []
|
||||||
|
@disks.each do |p|
|
||||||
|
other_p = other_disks.find { |o| p.id == o.id }
|
||||||
|
if other_p
|
||||||
|
# there is an override. take it.
|
||||||
|
other_p.config = p.config.merge(other_p.config)
|
||||||
|
|
||||||
|
# Remove duplicate disk config from other
|
||||||
|
p = other_p
|
||||||
|
other_disks.delete(other_p)
|
||||||
|
end
|
||||||
|
|
||||||
|
# there is an override, merge it into the
|
||||||
|
new_disks << p.dup
|
||||||
|
end
|
||||||
|
other_disks.each do |p|
|
||||||
|
new_disks << p.dup
|
||||||
|
end
|
||||||
|
result.instance_variable_set(:@disks, new_disks)
|
||||||
|
|
||||||
# Merge the providers by prepending any configuration blocks we
|
# Merge the providers by prepending any configuration blocks we
|
||||||
# have for providers onto the new configuration.
|
# have for providers onto the new configuration.
|
||||||
other_providers = other.instance_variable_get(:@__providers)
|
other_providers = other.instance_variable_get(:@__providers)
|
||||||
|
@ -384,6 +409,38 @@ module VagrantPlugins
|
||||||
@__defined_vms[name].config_procs << [options[:config_version], block] if block
|
@__defined_vms[name].config_procs << [options[:config_version], block] if block
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Stores disk config options from Vagrantfile
|
||||||
|
#
|
||||||
|
# @param [Symbol] type
|
||||||
|
# @param [Hash] options
|
||||||
|
# @param [Block] block
|
||||||
|
def disk(type, **options, &block)
|
||||||
|
disk_config = VagrantConfigDisk.new(type)
|
||||||
|
|
||||||
|
# Remove provider__option options before set_options, otherwise will
|
||||||
|
# show up as missing setting
|
||||||
|
# Extract provider hash options as well
|
||||||
|
provider_options = {}
|
||||||
|
options.delete_if do |p,o|
|
||||||
|
if o.is_a?(Hash) || p.to_s.include?("__")
|
||||||
|
provider_options[p] = o
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
disk_config.set_options(options)
|
||||||
|
|
||||||
|
# Add provider config
|
||||||
|
disk_config.add_provider_config(provider_options, &block)
|
||||||
|
|
||||||
|
if !Vagrant::Util::Experimental.feature_enabled?("disk_base_config")
|
||||||
|
@logger.warn("Disk config defined, but experimental feature is not enabled. To use this feature, enable it with the experimental flag `disk_base_config`. Disk will not be added to internal config, and will be ignored.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
@disks << disk_config
|
||||||
|
end
|
||||||
|
|
||||||
#-------------------------------------------------------------------
|
#-------------------------------------------------------------------
|
||||||
# Internal methods, don't call these.
|
# Internal methods, don't call these.
|
||||||
#-------------------------------------------------------------------
|
#-------------------------------------------------------------------
|
||||||
|
@ -547,6 +604,10 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@disks.each do |d|
|
||||||
|
d.finalize!
|
||||||
|
end
|
||||||
|
|
||||||
if !current_dir_shared && !@__synced_folders["/vagrant"]
|
if !current_dir_shared && !@__synced_folders["/vagrant"]
|
||||||
synced_folder(".", "/vagrant")
|
synced_folder(".", "/vagrant")
|
||||||
end
|
end
|
||||||
|
@ -748,6 +809,26 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Validate disks
|
||||||
|
# Check if there is more than one primrary disk defined and throw an error
|
||||||
|
primary_disks = @disks.select { |d| d.primary && d.type == :disk }
|
||||||
|
if primary_disks.size > 1
|
||||||
|
errors << I18n.t("vagrant.config.vm.multiple_primary_disks_error",
|
||||||
|
name: machine.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
disk_names = @disks.map { |d| d.name }
|
||||||
|
duplicate_names = disk_names.detect{ |d| disk_names.count(d) > 1 }
|
||||||
|
if duplicate_names && duplicate_names.size
|
||||||
|
errors << I18n.t("vagrant.config.vm.multiple_disk_names_error",
|
||||||
|
name: duplicate_names)
|
||||||
|
end
|
||||||
|
|
||||||
|
@disks.each do |d|
|
||||||
|
error = d.validate(machine)
|
||||||
|
errors.concat error if !error.empty?
|
||||||
|
end
|
||||||
|
|
||||||
# We're done with VM level errors so prepare the section
|
# We're done with VM level errors so prepare the section
|
||||||
errors = { "vm" => errors }
|
errors = { "vm" => errors }
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ module VagrantPlugins
|
||||||
b.use ForwardPorts
|
b.use ForwardPorts
|
||||||
b.use SetHostname
|
b.use SetHostname
|
||||||
b.use SaneDefaults
|
b.use SaneDefaults
|
||||||
|
b.use Disk
|
||||||
b.use Customize, "pre-boot"
|
b.use Customize, "pre-boot"
|
||||||
b.use Boot
|
b.use Boot
|
||||||
b.use Customize, "post-boot"
|
b.use Customize, "post-boot"
|
||||||
|
|
|
@ -1792,6 +1792,17 @@ en:
|
||||||
# Translations for config validation errors
|
# Translations for config validation errors
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
config:
|
config:
|
||||||
|
disk:
|
||||||
|
invalid_type: |-
|
||||||
|
Disk type '%{type}' is not a valid type. Please pick one of the following supported disk types: %{types}
|
||||||
|
invalid_size: |-
|
||||||
|
Config option 'size' for disk '%{name}' on guest '%{machine}' is not an integer
|
||||||
|
invalid_file_type: |-
|
||||||
|
Disk config option 'file' for '%{machine}' is not a string.
|
||||||
|
missing_file: |-
|
||||||
|
Disk file '%{file_path}' for disk '%{name}' on machine '%{machine}' does not exist.
|
||||||
|
missing_provider: |-
|
||||||
|
Guest '%{machine}' using provider '%{provider_name}' has provider specific config options for a provider other than '%{provider_name}'. These provider config options will be ignored for this guest
|
||||||
common:
|
common:
|
||||||
bad_field: "The following settings shouldn't exist: %{fields}"
|
bad_field: "The following settings shouldn't exist: %{fields}"
|
||||||
chef:
|
chef:
|
||||||
|
@ -1892,6 +1903,10 @@ en:
|
||||||
hyphens or dots. It cannot start with a hyphen or dot.
|
hyphens or dots. It cannot start with a hyphen or dot.
|
||||||
ignore_provider_config: |-
|
ignore_provider_config: |-
|
||||||
Ignoring provider config for validation...
|
Ignoring provider config for validation...
|
||||||
|
multiple_primary_disks_error: |-
|
||||||
|
There are more than one primary disks defined for guest '%{name}'. Please ensure that only one disk has been defined as a primary disk.
|
||||||
|
multiple_disk_names_error: |-
|
||||||
|
Duplicate disk names defined: '%{name}'. Disk names must be unique.
|
||||||
name_invalid: |-
|
name_invalid: |-
|
||||||
The sub-VM name '%{name}' is invalid. Please don't use special characters.
|
The sub-VM name '%{name}' is invalid. Please don't use special characters.
|
||||||
network_ip_ends_in_one: |-
|
network_ip_ends_in_one: |-
|
||||||
|
@ -2138,6 +2153,9 @@ en:
|
||||||
runner:
|
runner:
|
||||||
waiting_cleanup: "Waiting for cleanup before exiting..."
|
waiting_cleanup: "Waiting for cleanup before exiting..."
|
||||||
exit_immediately: "Exiting immediately, without cleanup!"
|
exit_immediately: "Exiting immediately, without cleanup!"
|
||||||
|
disk:
|
||||||
|
provider_unsupported: |-
|
||||||
|
Guest provider '%{provider}' does not support the disk feature, and will not use the disk configuration defined.
|
||||||
vm:
|
vm:
|
||||||
boot:
|
boot:
|
||||||
booting: Booting VM...
|
booting: Booting VM...
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
require File.expand_path("../../../../base", __FILE__)
|
||||||
|
|
||||||
|
require Vagrant.source_root.join("plugins/kernel_v2/config/disk")
|
||||||
|
|
||||||
|
describe VagrantPlugins::Kernel_V2::VagrantConfigDisk do
|
||||||
|
include_context "unit"
|
||||||
|
|
||||||
|
let(:type) { :disk }
|
||||||
|
|
||||||
|
subject { described_class.new(type) }
|
||||||
|
|
||||||
|
let(:machine) { double("machine") }
|
||||||
|
|
||||||
|
def assert_invalid
|
||||||
|
errors = subject.validate(machine)
|
||||||
|
if !errors.empty? { |v| !v.empty? }
|
||||||
|
raise "No errors: #{errors.inspect}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def assert_valid
|
||||||
|
errors = subject.validate(machine)
|
||||||
|
if !errors.empty? { |v| v.empty? }
|
||||||
|
raise "Errors: #{errors.inspect}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
env = double("env")
|
||||||
|
|
||||||
|
subject.name = "foo"
|
||||||
|
subject.size = 100
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "with defaults" do
|
||||||
|
it "is valid with test defaults" do
|
||||||
|
subject.finalize!
|
||||||
|
assert_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "sets a disk type" do
|
||||||
|
subject.finalize!
|
||||||
|
expect(subject.type).to eq(type)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "defaults to non-primray disk" do
|
||||||
|
subject.finalize!
|
||||||
|
expect(subject.primary).to eq(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "defining a new config that needs to match internal restraints" do
|
||||||
|
before do
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -549,6 +549,58 @@ describe VagrantPlugins::Kernel_V2::VMConfig do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#disk" do
|
||||||
|
before(:each) do
|
||||||
|
allow(Vagrant::Util::Experimental).to receive(:feature_enabled?).
|
||||||
|
with("disk_base_config").and_return("true")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "stores the disks" do
|
||||||
|
subject.disk(:disk, size: 100)
|
||||||
|
subject.disk(:disk, size: 1000, primary: false, name: "storage")
|
||||||
|
subject.finalize!
|
||||||
|
|
||||||
|
assert_valid
|
||||||
|
|
||||||
|
d = subject.disks
|
||||||
|
expect(d.length).to eql(2)
|
||||||
|
expect(d[0].size).to eql(100)
|
||||||
|
expect(d[1].size).to eql(1000)
|
||||||
|
expect(d[1].name).to eql("storage")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises an error with duplicate names" do
|
||||||
|
subject.disk(:disk, size: 100, name: "foo")
|
||||||
|
subject.disk(:disk, size: 1000, name: "foo", primary: false)
|
||||||
|
subject.finalize!
|
||||||
|
assert_invalid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not merge duplicate disks" do
|
||||||
|
subject.disk(:disk, size: 1000, primary: false, name: "storage")
|
||||||
|
subject.disk(:disk, size: 1000, primary: false, name: "backup")
|
||||||
|
|
||||||
|
merged = subject.merge(subject)
|
||||||
|
merged_disks = merged.disks
|
||||||
|
|
||||||
|
expect(merged_disks.length).to eql(2)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "ignores non-overriding runs" do
|
||||||
|
subject.disk(:disk, name: "foo")
|
||||||
|
|
||||||
|
other = described_class.new
|
||||||
|
other.disk(:disk, name: "bar", primary: false)
|
||||||
|
|
||||||
|
merged = subject.merge(other)
|
||||||
|
merged_disks = merged.disks
|
||||||
|
|
||||||
|
expect(merged_disks.length).to eql(2)
|
||||||
|
expect(merged_disks[0].name).to eq("foo")
|
||||||
|
expect(merged_disks[1].name).to eq("bar")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "#synced_folder(s)" do
|
describe "#synced_folder(s)" do
|
||||||
it "defaults to sharing the current directory" do
|
it "defaults to sharing the current directory" do
|
||||||
subject.finalize!
|
subject.finalize!
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
require File.expand_path("../../../base", __FILE__)
|
||||||
|
|
||||||
|
require "vagrant/util/numeric"
|
||||||
|
|
||||||
|
describe Vagrant::Util::Numeric do
|
||||||
|
include_context "unit"
|
||||||
|
before(:each) { described_class.reset! }
|
||||||
|
subject { described_class }
|
||||||
|
|
||||||
|
describe "#string_to_bytes" do
|
||||||
|
it "converts a string to the proper bytes" do
|
||||||
|
bytes = subject.string_to_bytes("10KB")
|
||||||
|
expect(bytes).to eq(10240)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns nil if the given string is the wrong format" do
|
||||||
|
bytes = subject.string_to_bytes("10 Kilobytes")
|
||||||
|
expect(bytes).to eq(nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,76 @@
|
||||||
|
---
|
||||||
|
layout: "docs"
|
||||||
|
page_title: "Vagrant Disks Configuration"
|
||||||
|
sidebar_current: "disks-configuration"
|
||||||
|
description: |-
|
||||||
|
Documentation of various configuration options for Vagrant Disks
|
||||||
|
---
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
<strong>Warning!</strong> This feature is experimental and may break or
|
||||||
|
change in between releases. Use at your own risk. It currently is not officially
|
||||||
|
supported or functional.
|
||||||
|
|
||||||
|
This feature currently reqiures the experimental flag to be used. To explicitly enable this feature, you can set the experimental flag to:
|
||||||
|
|
||||||
|
```
|
||||||
|
VAGRANT_EXPERIMENTAL="disk_base_config"
|
||||||
|
```
|
||||||
|
|
||||||
|
Please note that `VAGRANT_EXPERIMENTAL` is an environment variable. For more
|
||||||
|
information about this flag visit the [Experimental docs page](/docs/experimental/)
|
||||||
|
for more info. Without this flag enabled, triggers with the `:type` option
|
||||||
|
will be ignored.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Vagrant Disks has several options that allow users to define and attach disks to guests.
|
||||||
|
|
||||||
|
## Disk Options
|
||||||
|
|
||||||
|
* `name` (string) - Optional argument to give the disk a name
|
||||||
|
* `type` (symbol) - The type of disk to manage. This option defaults to `:disk`. Please read the provider specific documentation for supported types.
|
||||||
|
* `file` (string) - Optional argument that defines a path on disk pointing to the location of a disk file.
|
||||||
|
* `primary` (boolean) - Optional argument that configures a given disk to be the "primary" disk to manage on the guest. There can only be one `primary` disk per guest.
|
||||||
|
* `provider_config` (hash) - Additional provider specific options for managing a given disk.
|
||||||
|
|
||||||
|
Generally, the disk option accepts two kinds of ways to define a provider config:
|
||||||
|
|
||||||
|
+ `providername__diskoption: value`
|
||||||
|
- The provider name followed by a double underscore, and then the provider specific option for that disk
|
||||||
|
+ `{providername: {diskoption: value}, otherprovidername: {diskoption: value}`
|
||||||
|
- A hash where the top level key(s) are one or more providers, and each provider keys values are a hash of options and their values.
|
||||||
|
|
||||||
|
**Note:** More specific examples of these can be found under the provider specific disk page. The `provider_config` option will depend on the provider you are using. Please read the provider specific documentation for disk management to learn about what options are available to use.
|
||||||
|
|
||||||
|
## Disk Types
|
||||||
|
|
||||||
|
The disk config currently accepts three kinds of disk types:
|
||||||
|
|
||||||
|
* `disk` (symbol)
|
||||||
|
* `dvd` (symbol)
|
||||||
|
* `floppy` (symbol)
|
||||||
|
|
||||||
|
You can set a disk type with the first argument of a disk config in your Vagrantfile:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
config.vm.disk :disk, name: "backup", size: "10GB"
|
||||||
|
config.vm.disk :floppy, name: "cool_files"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Provider Author Guide
|
||||||
|
|
||||||
|
If you are a vagrant plugin author who maintains a provider for Vagrant, this short guide will hopefully give some information on how to use the internal disk config object.
|
||||||
|
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
<strong>Warning!</strong> This guide is still being written as we develop this
|
||||||
|
new feature for Vagrant. Some points below are what we plan on covering once this
|
||||||
|
feature is more fully developed in Vagrant.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
- Entry level builtin action `disk` and how to use it as a provider author
|
||||||
|
- `id` is unique to each disk config object
|
||||||
|
- `provider_config` and how to its structured and how to use/validate it
|
||||||
|
|
||||||
|
More information should be coming once the disk feature is more functional.
|
|
@ -0,0 +1,34 @@
|
||||||
|
---
|
||||||
|
layout: "docs"
|
||||||
|
page_title: "Vagrant Disks"
|
||||||
|
sidebar_current: "disks"
|
||||||
|
description: |-
|
||||||
|
Introduction to Vagrant Disks
|
||||||
|
---
|
||||||
|
|
||||||
|
# Vagrant Disks
|
||||||
|
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
<strong>Warning!</strong> This feature is experimental and may break or
|
||||||
|
change in between releases. Use at your own risk. It currently is not officially
|
||||||
|
supported or functional.
|
||||||
|
|
||||||
|
This feature currently reqiures the experimental flag to be used. To explicitly enable this feature, you can set the experimental flag to:
|
||||||
|
|
||||||
|
```
|
||||||
|
VAGRANT_EXPERIMENTAL="disk_base_config"
|
||||||
|
```
|
||||||
|
|
||||||
|
Please note that `VAGRANT_EXPERIMENTAL` is an environment variable. For more
|
||||||
|
information about this flag visit the [Experimental docs page](/docs/experimental/)
|
||||||
|
for more info. Without this flag enabled, triggers with the `:type` option
|
||||||
|
will be ignored.
|
||||||
|
|
||||||
|
<strong>NOTE:</strong> Vagrant disks is currently a future feature for Vagrant that is not yet supported.
|
||||||
|
Some documentation exists here for future reference, however the Disk feature is
|
||||||
|
not yet functional. Please be patient for us to develop this new feature, and stay
|
||||||
|
tuned for a future release of Vagrant with this new functionality!
|
||||||
|
</div>
|
||||||
|
|
||||||
|
For more information about what options are available for configuring disks, see the
|
||||||
|
[configuration section](/docs/disks/configuration.html).
|
|
@ -0,0 +1,34 @@
|
||||||
|
---
|
||||||
|
layout: "docs"
|
||||||
|
page_title: "Vagrant Disk Usage"
|
||||||
|
sidebar_current: "disks-usage"
|
||||||
|
description: |-
|
||||||
|
Various Vagrant Disk examples
|
||||||
|
---
|
||||||
|
|
||||||
|
# Basic Usage
|
||||||
|
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
<strong>Warning!</strong> This feature is experimental and may break or
|
||||||
|
change in between releases. Use at your own risk. It currently is not officially
|
||||||
|
supported or functional.
|
||||||
|
|
||||||
|
This feature currently reqiures the experimental flag to be used. To explicitly enable this feature, you can set the experimental flag to:
|
||||||
|
|
||||||
|
```
|
||||||
|
VAGRANT_EXPERIMENTAL="disk_base_config"
|
||||||
|
```
|
||||||
|
|
||||||
|
Please note that `VAGRANT_EXPERIMENTAL` is an environment variable. For more
|
||||||
|
information about this flag visit the [Experimental docs page](/docs/experimental/)
|
||||||
|
for more info. Without this flag enabled, triggers with the `:type` option
|
||||||
|
will be ignored.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Below are some very simple examples of how to use Vagrant Disks.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
- Resizing a disk (primary)
|
||||||
|
- Attaching a new disk
|
||||||
|
- Using provider specific options
|
|
@ -128,6 +128,14 @@
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("disks") %>>
|
||||||
|
<a href="/docs/disks/">Disks</a>
|
||||||
|
<ul class="nav">
|
||||||
|
<li<%= sidebar_current("disks-configuration") %>><a href="/docs/disks/configuration.html">Configuration</a></li>
|
||||||
|
<li<%= sidebar_current("disks-usage") %>><a href="/docs/disks/usage.html">Usage</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li<%= sidebar_current("multimachine") %>>
|
<li<%= sidebar_current("multimachine") %>>
|
||||||
<a href="/docs/multi-machine/">Multi-Machine</a>
|
<a href="/docs/multi-machine/">Multi-Machine</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
Loading…
Reference in New Issue