diff --git a/lib/vagrant/action/builtin/box_remove.rb b/lib/vagrant/action/builtin/box_remove.rb index cf80542cb..bb5dac1ab 100644 --- a/lib/vagrant/action/builtin/box_remove.rb +++ b/lib/vagrant/action/builtin/box_remove.rb @@ -99,8 +99,11 @@ module Vagrant b.use Confirm, message, force_key end + # Keep used boxes, even if "force" is applied + keep_used_boxes = env[:keep_used_boxes] + result = env[:action_runner].run(stack, env) - if !result[:result] + if !result[:result] || keep_used_boxes # They said "no", so continue with the next box next end diff --git a/plugins/commands/box/command/prune.rb b/plugins/commands/box/command/prune.rb index 6a67b5458..7eb3d7e0f 100644 --- a/plugins/commands/box/command/prune.rb +++ b/plugins/commands/box/command/prune.rb @@ -30,6 +30,10 @@ module VagrantPlugins o.on("-f", "--force", "Destroy without confirmation even when box is in use.") do |f| options[:force] = f end + + o.on("-k", "--keep-used-boxes", "When combined with `--force`, will keep boxes still in use.") do |k| + options[:keep] = k + end end # Parse the options @@ -41,7 +45,7 @@ module VagrantPlugins return @env.ui.warn(I18n.t("vagrant.commands.box.no_installed_boxes"), prefix: false) end - delete_oldest_boxes(boxes, options[:provider], options[:force], options[:name], options[:dry_run]) + delete_oldest_boxes(boxes, options[:provider], options[:force], options[:name], options[:dry_run], options[:keep]) # Success, exit status 0 0 @@ -49,7 +53,7 @@ module VagrantPlugins private - def delete_oldest_boxes(boxes, only_provider, skip_confirm, only_name, dry_run) + def delete_oldest_boxes(boxes, only_provider, skip_confirm, only_name, dry_run, keep_used_boxes) # Find the longest box name longest_box = boxes.max_by { |x| x[0].length } longest_box_length = longest_box[0].length @@ -112,6 +116,7 @@ module VagrantPlugins box_provider: provider, box_version: version, force_confirm_box_remove: skip_confirm, + keep_used_boxes: keep_used_boxes, box_remove_all_versions: false, }) end diff --git a/test/unit/vagrant/action/builtin/box_remove_test.rb b/test/unit/vagrant/action/builtin/box_remove_test.rb index 63637ab84..7309a9b10 100644 --- a/test/unit/vagrant/action/builtin/box_remove_test.rb +++ b/test/unit/vagrant/action/builtin/box_remove_test.rb @@ -151,6 +151,37 @@ describe Vagrant::Action::Builtin::BoxRemove do subject.call(env) end + + it "doesn't delete if the box is in use and keep_used_boxes is set" do + env[:keep_used_boxes] = true + machine_index << new_entry("foo", "virtualbox", "1.0") + + result = { result: true } + expect(action_runner).to receive(:run). + with(anything, env).and_return(result) + + expect(box_collection).to receive(:find).with( + "foo", :virtualbox, "1.0").and_return(box) + expect(box).to receive(:destroy!).never + + subject.call(env) + end + + it "deletes if the box is in use and force is used" do + machine_index << new_entry("foo", "virtualbox", "1.0") + + result = { result: true } + expect(action_runner).to receive(:run). + with(anything, env).and_return(result) + + expect(box_collection).to receive(:find).with( + "foo", :virtualbox, "1.0").and_return(box) + expect(box_collection).to receive(:clean).with(box.name) + .and_return(true) + expect(box).to receive(:destroy!) + + subject.call(env) + end end it "errors if the box doesn't exist" do diff --git a/website/source/docs/cli/box.html.md b/website/source/docs/cli/box.html.md index 8a7f1e320..eade74b19 100644 --- a/website/source/docs/cli/box.html.md +++ b/website/source/docs/cli/box.html.md @@ -142,6 +142,8 @@ This command removes old versions of installed boxes. If the box is currently in * `--force` - Destroy without confirmation even when box is in use. +* `--keep-used-boxes` - When combined with `--force`, will keep boxes still in use. + # Box Remove **Command: `vagrant box remove NAME`**