diff --git a/lib/vagrant/action.rb b/lib/vagrant/action.rb index 2ec6894ef..508126675 100644 --- a/lib/vagrant/action.rb +++ b/lib/vagrant/action.rb @@ -52,6 +52,7 @@ module Vagrant autoload :ProvisionerCleanup, 'vagrant/action/vm/provisioner_cleanup' autoload :Resume, 'vagrant/action/vm/resume' autoload :ShareFolders, 'vagrant/action/vm/share_folders' + autoload :SetupPackageFiles, 'vagrant/action/vm/setup_package_files' autoload :Suspend, 'vagrant/action/vm/suspend' end end diff --git a/lib/vagrant/action/builtin.rb b/lib/vagrant/action/builtin.rb index d96ee8af1..2acc116e8 100644 --- a/lib/vagrant/action/builtin.rb +++ b/lib/vagrant/action/builtin.rb @@ -106,6 +106,7 @@ module Vagrant registry.register(:package) do Builder.new do use General::Validate + use VM::SetupPackageFiles use VM::CheckAccessible use registry.get(:halt) use VM::ClearForwardedPorts diff --git a/lib/vagrant/action/general/package.rb b/lib/vagrant/action/general/package.rb index 83fcf7c53..e8c768a0e 100644 --- a/lib/vagrant/action/general/package.rb +++ b/lib/vagrant/action/general/package.rb @@ -19,19 +19,15 @@ module Vagrant def initialize(app, env) @app = app - @env = env - @env["package.output"] ||= env["global_config"].package.name - @env["package.include"] ||= [] - @env["package.vagrantfile"] ||= nil + + env["package.files"] ||= {} + env["package.output"] ||= env["global_config"].package.name end def call(env) @env = env raise Errors::PackageOutputExists if File.exist?(tar_path) - raise Errors::PackageRequiresDirectory if !@env["package.directory"] || !File.directory?(@env["package.directory"]) - - verify_files_to_copy compress @app.call(env) @@ -46,30 +42,11 @@ module Vagrant end end - def files_to_copy - package_dir = Pathname.new(@env["package.directory"]).join("include") - - files = @env["package.include"].inject({}) do |acc, file| - source = Pathname.new(file) - acc[file] = source.relative? ? package_dir.join(source) : package_dir.join(source.basename) - acc - end - - files[@env["package.vagrantfile"]] = package_dir.join("_Vagrantfile") if @env["package.vagrantfile"] - files - end - - def verify_files_to_copy - files_to_copy.each do |file, _| - raise Errors::PackageIncludeMissing, :file => file if !File.exist?(file) - end - end - # This method copies the include files (passed in via command line) # to the temporary directory so they are included in a sub-folder within # the actual box def copy_include_files - files_to_copy.each do |from, to| + env["package.files"].each do |from, to| @env[:ui].info I18n.t("vagrant.actions.general.package.packaging", :file => from) FileUtils.mkdir_p(to.parent) diff --git a/lib/vagrant/action/vm/setup_package_files.rb b/lib/vagrant/action/vm/setup_package_files.rb new file mode 100644 index 000000000..9cb5387d5 --- /dev/null +++ b/lib/vagrant/action/vm/setup_package_files.rb @@ -0,0 +1,61 @@ +require 'pathname' + +module Vagrant + module Action + module VM + # Sets up the mapping of files to copy into the package and verifies + # that the files can be properly copied. + class SetupPackageFiles + def initialize(app, env) + @app = app + + env["package.include"] ||= [] + env["package.vagrantfile"] ||= nil + end + + def call(env) + raise Errors::PackageRequiresDirectory if !env["package.directory"] || + !File.directory?(env["package.directory"]) + + # Create a pathname to the directory that will store the files + # we wish to include with the box. + include_directory = Pathname.new(env["package.directory"]).join("include") + + files = {} + env["package.include"].each do |file| + source = Pathname.new(file) + dest = nil + + # If the source is relative then we add the file as-is to the include + # directory. Otherwise, we copy only the file into the root of the + # include directory. Kind of strange, but seems to match what people + # expect based on history. + if source.relative? + dest = include_directory.join(source) + else + dest = include_directory.join(source.basename) + end + + # Assign the mapping + files[file] = dest + end + + if env["package.vagrantfile"] + # Vagrantfiles are treated special and mapped to a specific file + files[env["package.vagrantfile"]] = include_directory.join("_Vagrantfile") + end + + # Verify the mapping + files.each do |from, _| + raise Errors::PackageIncludeMissing, :file => from if !File.exist?(from) + end + + # Save the mapping + env["package.files"] = files + + @app.call(env) + end + end + end + end +end