diff --git a/CHANGELOG.md b/CHANGELOG.md index d38bdba0f..212c3527e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ ## 1.2.4 (unreleased) +BUG FIXES: + - core/nfs: Exporting sub-directories of other exported folders now + works properly. [GH-785] ## 1.2.3 (July 9, 2013) diff --git a/plugins/hosts/bsd/host.rb b/plugins/hosts/bsd/host.rb index 0aee78f48..e51878ade 100644 --- a/plugins/hosts/bsd/host.rb +++ b/plugins/hosts/bsd/host.rb @@ -35,10 +35,55 @@ module VagrantPlugins end def nfs_export(id, ip, folders) + # We need to build up mapping of directories that are enclosed + # within each other because the exports file has to have subdirectories + # of an exported directory on the same line. e.g.: + # + # "/foo" "/foo/bar" ... + # "/bar" + # + # We build up this mapping within the following hash. + @logger.debug("Compiling map of sub-directories for NFS exports...") + dirmap = {} + folders.each do |_, opts| + hostpath = opts[:hostpath] + + found = false + dirmap.each do |dirs, diropts| + dirs.each do |dir| + if dir.start_with?(hostpath) || hostpath.start_with?(dir) + # TODO: verify opts and diropts are _identical_, raise an error + # if not. NFS mandates subdirectories have identical options. + dirs << hostpath + found = true + break + end + end + + break if found + end + + if !found + dirmap[[hostpath]] = opts.dup + end + end + + # Sort all the keys by length so that the directory closest to + # the root is exported first. + dirmap.each do |dirs, _| + dirs.sort_by! { |d| d.length } + end + + @logger.info("Exporting the following for NFS...") + dirmap.each do |dirs, opts| + @logger.info("NFS DIR: #{dirs.inspect}") + @logger.info("NFS OPTS: #{opts.inspect}") + end + output = TemplateRenderer.render(@nfs_exports_template, :uuid => id, :ip => ip, - :folders => folders) + :folders => dirmap) # The sleep ensures that the output is truly flushed before any `sudo` # commands are issued. diff --git a/templates/nfs/exports.erb b/templates/nfs/exports.erb index 5bc241f5b..5b437cbfd 100644 --- a/templates/nfs/exports.erb +++ b/templates/nfs/exports.erb @@ -1,5 +1,5 @@ # VAGRANT-BEGIN: <%= uuid %> -<% folders.each do |name, opts| %> -"<%= opts[:hostpath] %>" <%= ip %><% if opts[:map_uid] -%> -mapall=<%= [opts[:map_uid],opts[:map_gid]].compact.join(":") %><% end -%> +<% folders.each do |dirs, opts| %> +<%= dirs.map { |d| "\"#{d}\"" }.join(" ") %> <%= ip %><% if opts[:map_uid] -%> -mapall=<%= [opts[:map_uid],opts[:map_gid]].compact.join(":") %><% end -%> <% end %> # VAGRANT-END: <%= uuid %> diff --git a/templates/nfs/exports_freebsd.erb b/templates/nfs/exports_freebsd.erb index 59dbd83be..e421ab394 100644 --- a/templates/nfs/exports_freebsd.erb +++ b/templates/nfs/exports_freebsd.erb @@ -1,5 +1,5 @@ # VAGRANT-BEGIN: <%= uuid %> -<% folders.each do |name, opts| %> -<%= opts[:hostpath] %> <%= ip %><% if opts[:map_uid] -%> -alldirs -mapall=<%= [opts[:map_uid],opts[:map_gid]].compact.join(":") %><% end -%> +<% folders.each do |dirs, opts| %> +<%= dirs.map { |d| "\"#{d}\"" }.join(" ") %> <%= ip %><% if opts[:map_uid] -%> -alldirs -mapall=<%= [opts[:map_uid],opts[:map_gid]].compact.join(":") %><% end -%> <% end %> # VAGRANT-END: <%= uuid %>