Remove all available versions of a box

This patch introduces a new parameter --all for the remove
command of the box plugin. Setting this parameter will remove
all available versions of a specific box.

Example usage:

```
$ vagrant box list
ubuntu/trusty64 (virtualbox, 20150427.0.0)
ubuntu/trusty64 (virtualbox, 20150430.0.0)
ubuntu/trusty64 (virtualbox, 20150506.0.0)
```

```
$ vagrant box remove ubuntu/trusty64
You requested to remove the box 'ubuntu/trusty64' with provider
'virtualbox'. This box has multiple versions. You must
explicitly specify which version you want to remove with
the `--box-version` flag. The available versions for this
box are:

 * 20150427.0.0
 * 20150430.0.0
 * 20150506.0.0
```

With the --all parameter it is possible to remove all versions at once.

```
$ vagrant box remove --all ubuntu/trusty64
Removing box 'ubuntu/trusty64' (v20150506.0.0) with provider 'virtualbox'...
Removing box 'ubuntu/trusty64' (v20150430.0.0) with provider 'virtualbox'...
Removing box 'ubuntu/trusty64' (v20150427.0.0) with provider 'virtualbox'...
```
This commit is contained in:
Christian Berendt 2014-04-13 12:24:22 +02:00 committed by Seth Vargo
parent 4df01da457
commit 3f4a372d57
3 changed files with 51 additions and 37 deletions

View File

@ -15,6 +15,7 @@ module Vagrant
box_provider = env[:box_provider]
box_provider = box_provider.to_sym if box_provider
box_version = env[:box_version]
box_remove_all_versions = env[:box_remove_all_versions]
boxes = {}
env[:box_collection].all.each do |n, v, p|
@ -53,7 +54,7 @@ module Vagrant
if all_versions.length == 1
# There is only one version, just use that.
box_version = all_versions.first
else
elsif not box_remove_all_versions
# There are multiple versions, we can't choose.
raise Errors::BoxRemoveMultiVersion,
name: box_name,
@ -68,48 +69,53 @@ module Vagrant
versions: all_versions.sort.map { |k| " * #{k}" }.join("\n")
end
box = env[:box_collection].find(
box_name, box_provider, box_version)
versions_to_remove = [box_version]
versions_to_remove = all_versions if box_remove_all_versions
# Verify that this box is not in use by an active machine,
# otherwise warn the user.
users = box.in_use?(env[:machine_index]) || []
users = users.find_all { |u| u.valid?(env[:home_path]) }
if !users.empty?
# Build up the output to show the user.
users = users.map do |entry|
"#{entry.name} (ID: #{entry.id})"
end.join("\n")
versions_to_remove.sort.each do |version_to_remove|
box = env[:box_collection].find(
box_name, box_provider, box_version)
force_key = :force_confirm_box_remove
message = I18n.t(
"vagrant.commands.box.remove_in_use_query",
name: box.name,
provider: box.provider,
version: box.version,
users: users) + " "
# Verify that this box is not in use by an active machine,
# otherwise warn the user.
users = box.in_use?(env[:machine_index]) || []
users = users.find_all { |u| u.valid?(env[:home_path]) }
if !users.empty?
# Build up the output to show the user.
users = users.map do |entry|
"#{entry.name} (ID: #{entry.id})"
end.join("\n")
# Ask the user if we should do this
stack = Builder.new.tap do |b|
b.use Confirm, message, force_key
force_key = :force_confirm_box_remove
message = I18n.t(
"vagrant.commands.box.remove_in_use_query",
name: box.name,
provider: box.provider,
version: box.version,
users: users) + " "
# Ask the user if we should do this
stack = Builder.new.tap do |b|
b.use Confirm, message, force_key
end
result = env[:action_runner].run(stack, env)
if !result[:result]
# They said "no", so continue with the next box
next
end
end
result = env[:action_runner].run(stack, env)
if !result[:result]
# They said "no", so just return
return @app.call(env)
end
env[:ui].info(I18n.t("vagrant.commands.box.removing",
name: box.name,
provider: box.provider,
version: box.version))
box.destroy!
# Passes on the removed box to the rest of the middleware chain
env[:box_removed] = box
end
env[:ui].info(I18n.t("vagrant.commands.box.removing",
name: box.name,
provider: box.provider,
version: box.version))
box.destroy!
# Passes on the removed box to the rest of the middleware chain
env[:box_removed] = box
@app.call(env)
end
end

View File

@ -27,6 +27,10 @@ module VagrantPlugins
"The specific version of the box to remove") do |v|
options[:version] = v
end
o.on("--all", "Remove all available versions of the box") do |a|
options[:all] = a
end
end
# Parse the options
@ -50,6 +54,7 @@ module VagrantPlugins
box_provider: options[:provider],
box_version: options[:version],
force_confirm_box_remove: options[:force],
box_remove_all_versions: options[:all],
})
# Success, exit status 0

View File

@ -128,13 +128,16 @@ This command removes a box from Vagrant that matches the given name.
If a box has multiple providers, the exact provider must be specified
with the `--provider` flag. If a box has multiple versions, you can select
what versions to delete with the `--box-version` flag.
what versions to delete with the `--box-version` flag or remove all versions
with the `--all` flag.
## Options
* `--box-version VALUE` - Version of version constraints of the boxes to
remove. See documentation on this flag for `box add` for more details.
* `--all` - Remove all available versions of a box.
* `--force` - Forces removing the box even if an active Vagrant
environment is using it.