Merge branch 'synced-folders'

This introduces the foundation for a new abstraction for shared folders
called "synced folders." At this point there isn't much difference
except the nomenclature for configuration purposes. In the future, this
will be a new subsystem
This commit is contained in:
Mitchell Hashimoto 2013-01-23 09:46:13 -08:00
commit 37adb10a67
8 changed files with 63 additions and 55 deletions

View File

@ -24,7 +24,7 @@ Vagrant.configure("2") do |config|
# Share the root folder. This can then be overridden by # Share the root folder. This can then be overridden by
# other Vagrantfiles, if they wish. # other Vagrantfiles, if they wish.
config.vm.share_folder("v-root", "/vagrant", ".") config.vm.synced_folder(".", "/vagrant", :id => "vagrant-root")
config.nfs.map_uid = :auto config.nfs.map_uid = :auto
config.nfs.map_gid = :auto config.nfs.map_gid = :auto

View File

@ -122,10 +122,11 @@ module VagrantPlugins
# Shared folders # Shared folders
self.shared_folders.each do |name, sf| self.shared_folders.each do |name, sf|
options = sf.dup options = sf.dup
options[:id] = name
guestpath = options.delete(:guestpath) guestpath = options.delete(:guestpath)
hostpath = options.delete(:hostpath) hostpath = options.delete(:hostpath)
new.vm.share_folder(name, guestpath, hostpath, options) new.vm.synced_folder(hostpath, guestpath, options)
end end
# Defined sub-VMs # Defined sub-VMs

View File

@ -21,7 +21,7 @@ module VagrantPlugins
attr_accessor :host_name attr_accessor :host_name
attr_accessor :usable_port_range attr_accessor :usable_port_range
attr_reader :forwarded_ports attr_reader :forwarded_ports
attr_reader :shared_folders attr_reader :synced_folders
attr_reader :networks attr_reader :networks
attr_reader :providers attr_reader :providers
attr_reader :provisioners attr_reader :provisioners
@ -30,7 +30,7 @@ module VagrantPlugins
@forwarded_ports = [] @forwarded_ports = []
@graceful_halt_retry_count = UNSET_VALUE @graceful_halt_retry_count = UNSET_VALUE
@graceful_halt_retry_interval = UNSET_VALUE @graceful_halt_retry_interval = UNSET_VALUE
@shared_folders = {} @synced_folders = {}
@networks = [] @networks = []
@provisioners = [] @provisioners = []
@ -44,23 +44,31 @@ module VagrantPlugins
def merge(other) def merge(other)
result = super result = super
result.instance_variable_set(:@forwarded_ports, @forwarded_ports + other.forwarded_ports) result.instance_variable_set(:@forwarded_ports, @forwarded_ports + other.forwarded_ports)
result.instance_variable_set(:@shared_folders, @shared_folders.merge(other.shared_folders)) result.instance_variable_set(:@synced_folders, @synced_folders.merge(other.synced_folders))
result.instance_variable_set(:@networks, @networks + other.networks) result.instance_variable_set(:@networks, @networks + other.networks)
result.instance_variable_set(:@provisioners, @provisioners + other.provisioners) result.instance_variable_set(:@provisioners, @provisioners + other.provisioners)
result result
end end
def share_folder(name, guestpath, hostpath, opts=nil) # Defines a synced folder pair. This pair of folders will be synced
@shared_folders[name] = { # to/from the machine. Note that if the machine you're using doesn't
:guestpath => guestpath.to_s, # support multi-directional syncing (perhaps an rsync backed synced
:hostpath => hostpath.to_s, # folder) then the host is always synced to the guest but guest data
:create => false, # may not be synced back to the host.
:owner => nil, #
:group => nil, # @param [String] hostpath Path to the host folder to share. If this
:nfs => false, # is a relative path, it is relative to the location of the
:transient => false, # Vagrantfile.
:extra => nil # @param [String] guestpath Path on the guest to mount the shared
}.merge(opts || {}) # folder.
# @param [Hash] options Additional options.
def synced_folder(hostpath, guestpath, options=nil)
options ||= {}
options[:id] ||= guestpah
options[:guestpath] = guestpath
options[:hostpath] = hostpath
@synced_folders[options[:id]] = options
end end
# Define a way to access the machine via a network. This exposes a # Define a way to access the machine via a network. This exposes a
@ -133,19 +141,18 @@ module VagrantPlugins
errors << I18n.t("vagrant.config.vm.box_not_found", :name => box) if \ errors << I18n.t("vagrant.config.vm.box_not_found", :name => box) if \
box && !box_url && !machine.box box && !box_url && !machine.box
shared_folders.each do |name, options| @synced_folders.each do |id, options|
hostpath = Pathname.new(options[:hostpath]).expand_path(machine.env.root_path) hostpath = Pathname.new(options[:hostpath]).expand_path(machine.env.root_path)
if !hostpath.directory? && !options[:create] if !hostpath.directory? && !options[:create]
errors << I18n.t("vagrant.config.vm.shared_folder_hostpath_missing", errors << I18n.t("vagrant.config.vm.shared_folder_hostpath_missing",
:name => name,
:path => options[:hostpath]) :path => options[:hostpath])
end end
if options[:nfs] && (options[:owner] || options[:group]) if options[:nfs] && (options[:owner] || options[:group])
# Owner/group don't work with NFS # Owner/group don't work with NFS
errors << I18n.t("vagrant.config.vm.shared_folder_nfs_owner_group", errors << I18n.t("vagrant.config.vm.shared_folder_nfs_owner_group",
:name => name) :path => options[:hostpath])
end end
end end

View File

@ -42,7 +42,7 @@ module VagrantPlugins
def extract_folders def extract_folders
# Load the NFS enabled shared folders # Load the NFS enabled shared folders
@folders = {} @folders = {}
@env[:machine].config.vm.shared_folders.each do |key, opts| @env[:machine].config.vm.synced_folders.each do |id, opts|
if opts[:nfs] if opts[:nfs]
# Duplicate the options, set the hostpath, and set disabled on the original # Duplicate the options, set the hostpath, and set disabled on the original
# options so the ShareFolders middleware doesn't try to mount it. # options so the ShareFolders middleware doesn't try to mount it.
@ -65,7 +65,7 @@ module VagrantPlugins
folder[:hostpath] = hostpath.to_s folder[:hostpath] = hostpath.to_s
# Assign the folder to our instance variable for later use # Assign the folder to our instance variable for later use
@folders[key] = folder @folders[id] = folder
# Disable the folder so that regular shared folders don't try to # Disable the folder so that regular shared folders don't try to
# mount it. # mount it.
@ -78,7 +78,7 @@ module VagrantPlugins
# options on the NFS folders. # options on the NFS folders.
def prepare_folders def prepare_folders
@folders = @folders.inject({}) do |acc, data| @folders = @folders.inject({}) do |acc, data|
key, opts = data id, opts = data
opts[:map_uid] = prepare_permission(:uid, opts) opts[:map_uid] = prepare_permission(:uid, opts)
opts[:map_gid] = prepare_permission(:gid, opts) opts[:map_gid] = prepare_permission(:gid, opts)
opts[:nfs_version] ||= 3 opts[:nfs_version] ||= 3
@ -89,7 +89,7 @@ module VagrantPlugins
# the same host path will hash to the same fsid. # the same host path will hash to the same fsid.
opts[:uuid] = Digest::MD5.hexdigest(opts[:hostpath]) opts[:uuid] = Digest::MD5.hexdigest(opts[:hostpath])
acc[key] = opts acc[id] = opts
acc acc
end end
end end
@ -166,8 +166,8 @@ module VagrantPlugins
# Checks if there are any NFS enabled shared folders. # Checks if there are any NFS enabled shared folders.
def nfs_enabled? def nfs_enabled?
@env[:machine].config.vm.shared_folders.each do |key, opts| @env[:machine].config.vm.synced_folders.each do |id, options|
return true if opts[:nfs] return true if options[:nfs]
end end
false false

View File

@ -25,22 +25,20 @@ module VagrantPlugins
# This method returns an actual list of VirtualBox shared # This method returns an actual list of VirtualBox shared
# folders to create and their proper path. # folders to create and their proper path.
def shared_folders def shared_folders
@env[:machine].config.vm.shared_folders.inject({}) do |acc, data| {}.tap do |result|
key, value = data @env[:machine].config.vm.synced_folders.each do |id, data|
next if data[:disabled]
next acc if value[:disabled]
# This to prevent overwriting the actual shared folders data # This to prevent overwriting the actual shared folders data
value = value.dup result[id] = data.dup
acc[key] = value end
acc
end end
end end
# Prepares the shared folders by verifying they exist and creating them # Prepares the shared folders by verifying they exist and creating them
# if they don't. # if they don't.
def prepare_folders def prepare_folders
shared_folders.each do |name, options| shared_folders.each do |id, options|
hostpath = Pathname.new(options[:hostpath]).expand_path(@env[:root_path]) hostpath = Pathname.new(options[:hostpath]).expand_path(@env[:root_path])
if !hostpath.directory? && options[:create] if !hostpath.directory? && options[:create]
@ -61,9 +59,9 @@ module VagrantPlugins
@env[:ui].info I18n.t("vagrant.actions.vm.share_folders.creating") @env[:ui].info I18n.t("vagrant.actions.vm.share_folders.creating")
folders = [] folders = []
shared_folders.each do |name, data| shared_folders.each do |id, data|
folders << { folders << {
:name => name, :name => id,
:hostpath => File.expand_path(data[:hostpath], @env[:root_path]), :hostpath => File.expand_path(data[:hostpath], @env[:root_path]),
:transient => data[:transient] :transient => data[:transient]
} }
@ -76,7 +74,7 @@ module VagrantPlugins
@env[:ui].info I18n.t("vagrant.actions.vm.share_folders.mounting") @env[:ui].info I18n.t("vagrant.actions.vm.share_folders.mounting")
# short guestpaths first, so we don't step on ourselves # short guestpaths first, so we don't step on ourselves
folders = shared_folders.sort_by do |name, data| folders = shared_folders.sort_by do |id, data|
if data[:guestpath] if data[:guestpath]
data[:guestpath].length data[:guestpath].length
else else
@ -86,11 +84,10 @@ module VagrantPlugins
end end
# Go through each folder and mount # Go through each folder and mount
folders.each do |name, data| folders.each do |id, data|
if data[:guestpath] if data[:guestpath]
# Guest path specified, so mount the folder to specified point # Guest path specified, so mount the folder to specified point
@env[:ui].info(I18n.t("vagrant.actions.vm.share_folders.mounting_entry", @env[:ui].info(I18n.t("vagrant.actions.vm.share_folders.mounting_entry",
:name => name,
:guest_path => data[:guestpath])) :guest_path => data[:guestpath]))
# Dup the data so we can pass it to the guest API # Dup the data so we can pass it to the guest API
@ -101,11 +98,11 @@ module VagrantPlugins
data[:group] ||= @env[:machine].config.ssh.username data[:group] ||= @env[:machine].config.ssh.username
# Mount the actual folder # Mount the actual folder
@env[:machine].guest.mount_shared_folder(name, data[:guestpath], data) @env[:machine].guest.mount_shared_folder(id, data[:guestpath], data)
else else
# If no guest path is specified, then automounting is disabled # If no guest path is specified, then automounting is disabled
@env[:ui].info(I18n.t("vagrant.actions.vm.share_folders.nomount_entry", @env[:ui].info(I18n.t("vagrant.actions.vm.share_folders.nomount_entry",
:name => name)) :host_path => data[:hostpath]))
end end
end end
end end

View File

@ -111,9 +111,10 @@ module VagrantPlugins
def share_folders(root_config, prefix, folders) def share_folders(root_config, prefix, folders)
folders.each do |type, local_path, remote_path| folders.each do |type, local_path, remote_path|
if type == :host if type == :host
root_config.vm.share_folder( root_config.vm.synced_folder(
"v-#{prefix}-#{self.class.get_and_update_counter(:shared_folder)}", local_path, remote_path,
remote_path, local_path, :nfs => @config.nfs) :id => "v-#{prefix}-#{self.class.get_and_update_counter(:shared_folder)}",
:nfs => @config.nfs)
end end
end end
end end

View File

@ -28,15 +28,15 @@ module VagrantPlugins
end end
# Share the manifests directory with the guest # Share the manifests directory with the guest
root_config.vm.share_folder( root_config.vm.synced_folder(
"manifests", manifests_guest_path, @expanded_manifests_path) @expanded_manifests_path, manifests_guest_path)
# Share the module paths # Share the module paths
count = 0 count = 0
@module_paths.each do |from, to| @module_paths.each do |from, to|
# Sorry for the cryptic key here, but VirtualBox has a strange limit on # Sorry for the cryptic key here, but VirtualBox has a strange limit on
# maximum size for it and its something small (around 10) # maximum size for it and its something small (around 10)
root_config.vm.share_folder("v-pp-m#{count}", to, from) root_config.vm.synced_folder(from, to)
count += 1 count += 1
end end
end end

View File

@ -351,9 +351,11 @@ en:
network_ip_ends_one: |- network_ip_ends_one: |-
The host only network IP '%{ip}' must not end in a 1, as this The host only network IP '%{ip}' must not end in a 1, as this
is reserved for the host machine. is reserved for the host machine.
shared_folder_hostpath_missing: "Shared folder host path for '%{name}' doesn't exist: %{path}" shared_folder_hostpath_missing: |-
The host path of the shared folder is missing: %{path}
shared_folder_nfs_owner_group: |- shared_folder_nfs_owner_group: |-
Shared folder '%{name}': NFS does not support the owner/group settings. Shared folder that have NFS enabled do no support owner/group
attributes. Host path: %{path}
provisioner_not_found: "The provisioner '%{shortcut}' doesn't exist." provisioner_not_found: "The provisioner '%{shortcut}' doesn't exist."
provisioner_invalid_class: |- provisioner_invalid_class: |-
The provisioner '%{shortcut}' must inherit from The provisioner '%{shortcut}' must inherit from
@ -659,8 +661,8 @@ en:
share_folders: share_folders:
creating: Creating shared folders metadata... creating: Creating shared folders metadata...
mounting: Mounting shared folders... mounting: Mounting shared folders...
mounting_entry: "-- %{name}: %{guest_path}" mounting_entry: "-- %{guest_path}"
nomount_entry: "-- %{name}: Automounting disabled." nomount_entry: "-- Automounting disabled: %{host_path}"
suspend: suspend:
suspending: Saving VM state and suspending execution... suspending: Saving VM state and suspending execution...