diff --git a/lib/vagrant/action/general/package.rb b/lib/vagrant/action/general/package.rb index ca1293ad6..b86b19f33 100644 --- a/lib/vagrant/action/general/package.rb +++ b/lib/vagrant/action/general/package.rb @@ -13,6 +13,7 @@ module Vagrant # # * package.output - The filename of the outputted package. # * package.include - An array of files to include in the package. + # * package.info - Path of desired info.json file to include # * package.directory - The directory which contains the contents to # compress into the package. # @@ -63,6 +64,7 @@ module Vagrant @app = app env["package.files"] ||= {} + env["package.info"] ||= "" env["package.output"] ||= "package.box" @fullpath = self.class.fullpath(env["package.output"]) @@ -77,11 +79,14 @@ module Vagrant raise Errors::PackageOutputDirectory if File.directory?(fullpath) + raise Errors::PackageInvalidInfo if invalid_info? + @app.call(env) @env[:ui].info I18n.t("vagrant.actions.general.package.compressing", fullpath: fullpath) copy_include_files + copy_info setup_private_key write_metadata_json compress @@ -137,6 +142,16 @@ module Vagrant raise Errors::PackageIncludeSymlink end + # This method copies the specified info.json file to the temporary directory + # so that it is accessible via the 'box list -i' command + def copy_info + info_path = Pathname.new(@env["package.info"]) + + if info_path.file? + FileUtils.cp(info_path, @env["package.directory"], preserve: true) + end + end + # Compress the exported file into a package def compress # Get the output path. We have to do this up here so that the @@ -216,6 +231,15 @@ module Vagrant f.puts %Q[end] end end + + # Check to see if package.info is a valid file and titled info.json + def invalid_info? + if @env["package.info"] != "" + info_path = Pathname.new(@env["package.info"]) + + return !info_path.file? || File.basename(info_path) != "info.json" + end + end end end end diff --git a/lib/vagrant/errors.rb b/lib/vagrant/errors.rb index 5cb861c06..6b0e26c5a 100644 --- a/lib/vagrant/errors.rb +++ b/lib/vagrant/errors.rb @@ -592,6 +592,10 @@ module Vagrant error_key(:requires_directory, "vagrant.actions.general.package") end + class PackageInvalidInfo < VagrantError + error_key(:package_invalid_info) + end + class PowerShellNotFound < VagrantError error_key(:powershell_not_found) end diff --git a/plugins/commands/box/command/list.rb b/plugins/commands/box/command/list.rb index bee54972f..f2a3fed76 100644 --- a/plugins/commands/box/command/list.rb +++ b/plugins/commands/box/command/list.rb @@ -52,7 +52,7 @@ module VagrantPlugins @env.ui.machine("box-version", version) info_file = @env.boxes.find(name, provider, version). - directory.join("include", "info.json") + directory.join("info.json") if info_file.file? info = JSON.parse(info_file.read) info.each do |k, v| diff --git a/plugins/commands/package/command.rb b/plugins/commands/package/command.rb index 4d468b533..f7b5e49dc 100644 --- a/plugins/commands/package/command.rb +++ b/plugins/commands/package/command.rb @@ -29,6 +29,10 @@ module VagrantPlugins options[:include] = i end + o.on("--info FILE", "Path to a custom info.json file containing additional box information") do |info| + options[:info] = info + end + o.on("--vagrantfile FILE", "Vagrantfile to package with the box") do |v| options[:vagrantfile] = v end diff --git a/templates/locales/en.yml b/templates/locales/en.yml index 8cb1971af..f5cc836ba 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -1293,6 +1293,9 @@ en: A file or directory you're attempting to include with your packaged box has symlinks in it. Vagrant cannot include symlinks in the resulting package. Please remove the symlinks and try again. + package_invalid_info: |- + The information file that you've attempted to include doesn't exist or isn't a valid JSON file. + Please check that the file exists and is titled 'info.json' and try again. provider_cant_install: |- The provider '%{provider}' doesn't support automatic installation. This is a limitation of this provider. Please report this as a feature diff --git a/test/unit/vagrant/action/general/package_test.rb b/test/unit/vagrant/action/general/package_test.rb index 19f334b5b..b5ae4d031 100644 --- a/test/unit/vagrant/action/general/package_test.rb +++ b/test/unit/vagrant/action/general/package_test.rb @@ -183,6 +183,34 @@ describe Vagrant::Action::General::Package do end end + describe "#copy_info" do + let(:package_directory) { @package_directory } + let(:package_info) { File.join(@package_info_directory, "info.json") } + + before do + @package_directory = Dir.mktmpdir + @package_info_directory = Dir.mktmpdir + FileUtils.touch(File.join(@package_info_directory, "info.json")) + env["package.info"] = package_info + env["package.directory"] = package_directory + subject.instance_variable_set(:@env, env) + + allow(ui).to receive(:info) + end + + after do + FileUtils.rm_rf(@package_directory) + FileUtils.rm_rf(@package_info_directory) + end + + it "should copy the specified info.json to package directory" do + subject.copy_info + expected_info = File.join(package_directory, "info.json") + + expect(File.file? expected_info).to be_truthy + end + end + describe "#compress" do let(:package_directory) { @package_directory } let(:fullpath) { "PATH" } diff --git a/website/content/docs/cli/package.mdx b/website/content/docs/cli/package.mdx index ec3285bd5..742d80ec0 100644 --- a/website/content/docs/cli/package.mdx +++ b/website/content/docs/cli/package.mdx @@ -29,6 +29,10 @@ and if the provider supports it. can be used by a packaged Vagrantfile (documented below) to perform additional tasks. +- `--info path/to/info.json` - The package will include a custom JSON file containing + information to be displayed by the [list](/docs/cli/box#box-list) command when invoked + with the `-i` flag + - `--vagrantfile FILE` - Packages a Vagrantfile with the box, that is loaded as part of the [Vagrantfile load order](/docs/vagrantfile/#load-order) when the resulting box is used.