forked from hashicorp/vagrant
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Build the v2 interface, which is just a copy of V1 for now.
- Loading branch information
Showing
17 changed files
with
1,270 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module Vagrant | ||
module Config | ||
module V2 | ||
autoload :Loader, "vagrant/config/v2/loader" | ||
autoload :Root, "vagrant/config/v2/root" | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
require "vagrant/config/v2/root" | ||
|
||
module Vagrant | ||
module Config | ||
module V2 | ||
# This is the loader that handles configuration loading for V2 | ||
# configurations. | ||
class Loader < VersionBase | ||
# Returns a bare empty configuration object. | ||
# | ||
# @return [V2::Root] | ||
def self.init | ||
new_root_object | ||
end | ||
|
||
# Finalizes the configuration by making sure there is at least | ||
# one VM defined in it. | ||
def self.finalize(config) | ||
# Call the `#finalize` method on each of the configuration keys. | ||
# They're expected to modify themselves in our case. | ||
config.finalize! | ||
|
||
# Return the object | ||
config | ||
end | ||
|
||
# Loads the configuration for the given proc and returns a configuration | ||
# object. | ||
# | ||
# @param [Proc] config_proc | ||
# @return [Object] | ||
def self.load(config_proc) | ||
# Create a root configuration object | ||
root = new_root_object | ||
|
||
# Call the proc with the root | ||
config_proc.call(root) | ||
|
||
# Return the root object, which doubles as the configuration object | ||
# we actually use for accessing as well. | ||
root | ||
end | ||
|
||
# Merges two configuration objects. | ||
# | ||
# @param [V2::Root] old The older root config. | ||
# @param [V2::Root] new The newer root config. | ||
# @return [V2::Root] | ||
def self.merge(old, new) | ||
# Grab the internal states, we use these heavily throughout the process | ||
old_state = old.__internal_state | ||
new_state = new.__internal_state | ||
|
||
# The config map for the new object is the old one merged with the | ||
# new one. | ||
config_map = old_state["config_map"].merge(new_state["config_map"]) | ||
|
||
# Merge the keys. | ||
old_keys = old_state["keys"] | ||
new_keys = new_state["keys"] | ||
keys = {} | ||
old_keys.each do |key, old_value| | ||
if new_keys.has_key?(key) | ||
# We need to do a merge, which we expect to be available | ||
# on the config class itself. | ||
keys[key] = old_value.merge(new_keys[key]) | ||
else | ||
# We just take the old value, but dup it so that we can modify. | ||
keys[key] = old_value.dup | ||
end | ||
end | ||
|
||
new_keys.each do |key, new_value| | ||
# Add in the keys that the new class has that we haven't merged. | ||
if !keys.has_key?(key) | ||
keys[key] = new_value.dup | ||
end | ||
end | ||
|
||
# Return the final root object | ||
V2::Root.new(config_map, keys) | ||
end | ||
|
||
# Upgrade a V1 configuration to a V2 configuration. | ||
# | ||
# @param [V1::Root] old | ||
# @return [Array] A 3-tuple result. | ||
def self.upgrade(old) | ||
# TODO: Actually do an upgrade. For now we just return V1. | ||
[old, [], []] | ||
end | ||
|
||
protected | ||
|
||
def self.new_root_object | ||
# Get all the registered configuration objects and use them. If | ||
# we're currently on version 1, then we load all the config objects, | ||
# otherwise we load only the upgrade safe ones, since we're | ||
# obviously being loaded for an upgrade. | ||
config_map = nil | ||
plugin_manager = Vagrant.plugin("1").manager | ||
if Config::CURRENT_VERSION == "1" | ||
config_map = plugin_manager.config | ||
else | ||
config_map = plugin_manager.config_upgrade_safe | ||
end | ||
|
||
# Create the configuration root object | ||
V2::Root.new(config_map) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
module Vagrant | ||
module Config | ||
module V2 | ||
# This is the root configuration class. An instance of this is what | ||
# is passed into version 1 Vagrant configuration blocks. | ||
class Root | ||
# Initializes a root object that maps the given keys to specific | ||
# configuration classes. | ||
# | ||
# @param [Hash] config_map Map of key to config class. | ||
def initialize(config_map, keys=nil) | ||
@keys = keys || {} | ||
@config_map = config_map | ||
end | ||
|
||
# We use method_missing as a way to get the configuration that is | ||
# used for Vagrant and load the proper configuration classes for | ||
# each. | ||
def method_missing(name, *args) | ||
return @keys[name] if @keys.has_key?(name) | ||
|
||
config_klass = @config_map[name.to_sym] | ||
if config_klass | ||
# Instantiate the class and return the instance | ||
@keys[name] = config_klass.new | ||
return @keys[name] | ||
else | ||
# Super it up to probably raise a NoMethodError | ||
super | ||
end | ||
end | ||
|
||
# Called to finalize this object just prior to it being used by | ||
# the Vagrant system. The "!" signifies that this is expected to | ||
# mutate itself. | ||
def finalize! | ||
@keys.each do |_key, instance| | ||
instance.finalize! | ||
end | ||
end | ||
|
||
# Validates the configuration classes of this instance and raises an | ||
# exception if they are invalid. If you are implementing a custom configuration | ||
# class, the method you want to implement is {Base#validate}. This is | ||
# the method that checks all the validation, not one which defines | ||
# validation rules. | ||
def validate!(env) | ||
# Validate each of the configured classes and store the results into | ||
# a hash. | ||
errors = @keys.inject({}) do |container, data| | ||
key, instance = data | ||
recorder = ErrorRecorder.new | ||
instance.validate(env, recorder) | ||
container[key.to_sym] = recorder if !recorder.errors.empty? | ||
container | ||
end | ||
|
||
return if errors.empty? | ||
raise Errors::ConfigValidationFailed, :messages => Util::TemplateRenderer.render("config/validation_failed", :errors => errors) | ||
end | ||
|
||
# Returns the internal state of the root object. This is used | ||
# by outside classes when merging, and shouldn't be called directly. | ||
# Note the strange method name is to attempt to avoid any name | ||
# clashes with potential configuration keys. | ||
def __internal_state | ||
{ | ||
"config_map" => @config_map, | ||
"keys" => @keys | ||
} | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
module Vagrant | ||
module Plugin | ||
autoload :V1, "vagrant/plugin/v1" | ||
autoload :V2, "vagrant/plugin/v2" | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
require "log4r" | ||
|
||
require "vagrant/plugin/v2/errors" | ||
|
||
module Vagrant | ||
module Plugin | ||
module V2 | ||
autoload :Command, "vagrant/plugin/v2/command" | ||
autoload :Communicator, "vagrant/plugin/v2/communicator" | ||
autoload :Config, "vagrant/plugin/v2/config" | ||
autoload :Guest, "vagrant/plugin/v2/guest" | ||
autoload :Host, "vagrant/plugin/v2/host" | ||
autoload :Manager, "vagrant/plugin/v2/manager" | ||
autoload :Plugin, "vagrant/plugin/v2/plugin" | ||
autoload :Provider, "vagrant/plugin/v2/provider" | ||
autoload :Provisioner, "vagrant/plugin/v2/provisioner" | ||
end | ||
end | ||
end |
Oops, something went wrong.