Skip to content

Commit

Permalink
Merge branch 'machine-abstraction'
Browse files Browse the repository at this point in the history
This branch brings in the "machine abstraction" code. This is a major
milestone in the development of Vagrant as it abstracts all of the
VirtualBox-specific code out into a plugin. There is zero VirtualBox
specific code in the core ("lib/") directory at this point. Read on for
important points.

== Gotchas

White it is technically possible now to write plugins for other
providers, there is still major work to be done to make this feasible.
The plugin interface itself is pretty much done, but there are some
issues:

* ":virtualbox" is the hardcoded provider to be used at the moment.

* There is no way to configure a provider. For example,
  `config.vm.customize` would never work for anything other than
  VirtualBox, so there needs to be a way to have provider-specific
  configuration. This will come soon.

* Shared folders and networking need to be rearchitected to be friendly
  for multiple providers, since it is unrealistic that a provider such as
  EC2 could provide the same level of networking, for example.

* There is no way easy way (like `vagrant package --base`) to create
  boxes for providers other than VirtualBox. This will be addressed in a
  whole new feature of Vagrant probably in a future release after
  provider stuff has shipped.

== Writing a Provider

To write a provider, you create a Vagrant plugin that defines a
"provider". See the "plugins/providers/virtualbox/plugin.rb" for more
details. Providers themselves have an exremely simple API. The burden
for writing providers mostly rests on the fact that you must define
complex middleware sequences.

Lots more work to come in the future, but this is a BIG MILESTONE!
  • Loading branch information
mitchellh committed Aug 20, 2012
2 parents de73b65 + 1cdd69b commit 391dc39
Show file tree
Hide file tree
Showing 122 changed files with 4,156 additions and 2,915 deletions.
25 changes: 10 additions & 15 deletions lib/vagrant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ module Vagrant
autoload :BoxCollection, 'vagrant/box_collection'
autoload :CLI, 'vagrant/cli'
autoload :Command, 'vagrant/command'
autoload :Communication, 'vagrant/communication'
autoload :Config, 'vagrant/config'
autoload :DataStore, 'vagrant/data_store'
autoload :Downloaders, 'vagrant/downloaders'
Expand All @@ -76,27 +75,23 @@ module Vagrant
autoload :Errors, 'vagrant/errors'
autoload :Guest, 'vagrant/guest'
autoload :Hosts, 'vagrant/hosts'
autoload :Machine, 'vagrant/machine'
autoload :Plugin, 'vagrant/plugin'
autoload :SSH, 'vagrant/ssh'
autoload :TestHelpers, 'vagrant/test_helpers'
autoload :UI, 'vagrant/ui'
autoload :Util, 'vagrant/util'
autoload :VM, 'vagrant/vm'

# These are the various plugin versions and their components in
# a lazy loaded Hash-like structure.
c = PLUGIN_COMPONENTS = Registry.new
c.register(:"1") { Plugin::V1::Plugin }
c.register([:"1", :command]) { Plugin::V1::Command }
c.register([:"1", :config]) { Plugin::V1::Config }
c.register([:"1", :guest]) { Plugin::V1::Guest }
c.register([:"1", :host]) { Plugin::V1::Host }
c.register([:"1", :provisioner]) { Plugin::V1::Provisioner }

# Returns a `Vagrant::Registry` object that contains all the built-in
# middleware stacks.
def self.actions
@actions ||= Vagrant::Action::Builtin.new
PLUGIN_COMPONENTS = Registry.new.tap do |c|
c.register(:"1") { Plugin::V1::Plugin }
c.register([:"1", :command]) { Plugin::V1::Command }
c.register([:"1", :communicator]) { Plugin::V1::Communicator }
c.register([:"1", :config]) { Plugin::V1::Config }
c.register([:"1", :guest]) { Plugin::V1::Guest }
c.register([:"1", :host]) { Plugin::V1::Host }
c.register([:"1", :provider]) { Plugin::V1::Provider }
c.register([:"1", :provisioner]) { Plugin::V1::Provisioner }
end

# The source root is the path to the root directory of
Expand Down
61 changes: 18 additions & 43 deletions lib/vagrant/action.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,60 +2,35 @@

module Vagrant
module Action
autoload :Builtin, 'vagrant/action/builtin'
autoload :Environment, 'vagrant/action/environment'
autoload :Runner, 'vagrant/action/runner'
autoload :Warden, 'vagrant/action/warden'

module Box
autoload :Add, 'vagrant/action/box/add'
autoload :Download, 'vagrant/action/box/download'
autoload :Verify, 'vagrant/action/box/verify'
end

module Env
autoload :Set, 'vagrant/action/env/set'
# Builtin contains middleware classes that are shipped with Vagrant-core
# and are thus available to all plugins as a "standard library" of sorts.
module Builtin
autoload :BoxAdd, "vagrant/action/builtin/box_add"
autoload :Call, "vagrant/action/builtin/call"
autoload :Confirm, "vagrant/action/builtin/confirm"
autoload :EnvSet, "vagrant/action/builtin/env_set"
autoload :SSHExec, "vagrant/action/builtin/ssh_exec"
autoload :SSHRun, "vagrant/action/builtin/ssh_run"
end

module General
autoload :CheckVirtualbox, 'vagrant/action/general/check_virtualbox'
autoload :Package, 'vagrant/action/general/package'
autoload :Validate, 'vagrant/action/general/validate'
end

module VM
autoload :Boot, 'vagrant/action/vm/boot'
autoload :CheckAccessible, 'vagrant/action/vm/check_accessible'
autoload :CheckBox, 'vagrant/action/vm/check_box'
autoload :CheckGuestAdditions, 'vagrant/action/vm/check_guest_additions'
autoload :CheckPortCollisions, 'vagrant/action/vm/check_port_collisions'
autoload :CleanMachineFolder, 'vagrant/action/vm/clean_machine_folder'
autoload :ClearForwardedPorts, 'vagrant/action/vm/clear_forwarded_ports'
autoload :ClearNetworkInterfaces, 'vagrant/action/vm/clear_network_interfaces'
autoload :ClearSharedFolders, 'vagrant/action/vm/clear_shared_folders'
autoload :Customize, 'vagrant/action/vm/customize'
autoload :DefaultName, 'vagrant/action/vm/default_name'
autoload :Destroy, 'vagrant/action/vm/destroy'
autoload :DestroyUnusedNetworkInterfaces, 'vagrant/action/vm/destroy_unused_network_interfaces'
autoload :DiscardState, 'vagrant/action/vm/discard_state'
autoload :Export, 'vagrant/action/vm/export'
autoload :ForwardPorts, 'vagrant/action/vm/forward_ports'
autoload :Halt, 'vagrant/action/vm/halt'
autoload :HostName, 'vagrant/action/vm/host_name'
autoload :Import, 'vagrant/action/vm/import'
autoload :MatchMACAddress, 'vagrant/action/vm/match_mac_address'
autoload :Network, 'vagrant/action/vm/network'
autoload :NFS, 'vagrant/action/vm/nfs'
autoload :Package, 'vagrant/action/vm/package'
autoload :PackageVagrantfile, 'vagrant/action/vm/package_vagrantfile'
autoload :Provision, 'vagrant/action/vm/provision'
autoload :ProvisionerCleanup, 'vagrant/action/vm/provisioner_cleanup'
autoload :PruneNFSExports, 'vagrant/action/vm/prune_nfs_exports'
autoload :Resume, 'vagrant/action/vm/resume'
autoload :SaneDefaults, 'vagrant/action/vm/sane_defaults'
autoload :ShareFolders, 'vagrant/action/vm/share_folders'
autoload :SetupPackageFiles, 'vagrant/action/vm/setup_package_files'
autoload :Suspend, 'vagrant/action/vm/suspend'
# This is the action that will add a box from a URL. This middleware
# sequence is built-in to Vagrant. Plugins can hook into this like any
# other middleware sequence. This is particularly useful for provider
# plugins, which can hook in to do things like verification of boxes
# that are downloaded.
def self.action_box_add
Builder.new.tap do |b|
b.use Builtin::BoxAdd
end
end
end
end
31 changes: 0 additions & 31 deletions lib/vagrant/action/box/add.rb

This file was deleted.

84 changes: 0 additions & 84 deletions lib/vagrant/action/box/download.rb

This file was deleted.

24 changes: 0 additions & 24 deletions lib/vagrant/action/box/verify.rb

This file was deleted.

22 changes: 10 additions & 12 deletions lib/vagrant/action/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,21 @@ module Action
#
# Building an action sequence is very easy:
#
# app = Vagrant::Action::Builder.new do
# use MiddlewareA
# use MiddlewareB
# app = Vagrant::Action::Builder.new.tap do |b|
# b.use MiddlewareA
# b.use MiddlewareB
# end
#
# Vagrant::Action.run(app)
#
class Builder
# Initializes the builder. An optional block can be passed which
# will be evaluated in the context of the instance.
def initialize(&block)
instance_eval(&block) if block_given?
# This is a shortcut for a middleware sequence with only one item
# in it. For a description of the arguments and the documentation, please
# see {#use} instead.
#
# @return [Builder]
def self.build(middleware, *args, &block)
new.use(middleware, *args, &block)
end

# Returns a mergeable version of the builder. If `use` is called with
Expand All @@ -38,11 +41,6 @@ def flatten
#
# @param [Class] middleware The middleware class
def use(middleware, *args, &block)
# Prepend with a environment setter if args are given
if !args.empty? && args.first.is_a?(Hash) && middleware != Env::Set
self.use(Env::Set, args.shift, &block)
end

if middleware.kind_of?(Builder)
# Merge in the other builder's stack into our own
self.stack.concat(middleware.stack)
Expand Down
Loading

14 comments on commit 391dc39

@pearkes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

@puffnfresh
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@rick
Copy link

@rick rick commented on 391dc39 Aug 20, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🆒 🤘 🎸 🔥

@auser
Copy link

@auser auser commented on 391dc39 Aug 20, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

YES! CONGRATS!!!!!

@ShepBook
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@myusuf3
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🍰

@kellydunn
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rockin

@dekz
Copy link

@dekz dekz commented on 391dc39 Aug 20, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Congrats on the milestone

@axsuul
Copy link

@axsuul axsuul commented on 391dc39 Aug 20, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Congratulations Mitchell! You're doing great work

@macarthy
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great start, I'll mention that in my vagrant talk next week

@daenney
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Way to go!

@dol
Copy link

@dol dol commented on 391dc39 Aug 20, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@frankscholten
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome!

@martinlauer
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

n1

Please sign in to comment.