commands/box: update command can update a specific box now
This commit is contained in:
parent
386938f0b1
commit
7a6d1a3ff1
|
@ -27,6 +27,7 @@ module Vagrant
|
|||
error: e.to_s
|
||||
end
|
||||
|
||||
@raw ||= {}
|
||||
@name = @raw["name"]
|
||||
@description = @raw["description"]
|
||||
@version_map = (@raw["versions"] || []).map do |v|
|
||||
|
|
|
@ -172,6 +172,14 @@ module Vagrant
|
|||
error_key(:box_metadata_malformed)
|
||||
end
|
||||
|
||||
class BoxNotFound < VagrantError
|
||||
error_key(:box_not_found)
|
||||
end
|
||||
|
||||
class BoxNotFoundWithProvider < VagrantError
|
||||
error_key(:box_not_found_with_provider)
|
||||
end
|
||||
|
||||
class BoxOutdatedNoBox < VagrantError
|
||||
error_key(:box_outdated_no_box)
|
||||
end
|
||||
|
@ -200,6 +208,10 @@ module Vagrant
|
|||
error_key(:untar_failure, "vagrant.actions.box.unpackage")
|
||||
end
|
||||
|
||||
class BoxUpdateMultiProvider < VagrantError
|
||||
error_key(:box_update_multi_provider)
|
||||
end
|
||||
|
||||
class BoxUpdateNoMetadata < VagrantError
|
||||
error_key(:box_update_no_metadata)
|
||||
end
|
||||
|
|
|
@ -23,11 +23,62 @@ module VagrantPlugins
|
|||
o.on("--box VALUE", String, "Update a specific box") do |b|
|
||||
options[:box] = b
|
||||
end
|
||||
|
||||
o.on("--provider VALUE", String, "Update box with specific provider.") do |p|
|
||||
options[:provider] = p.to_sym
|
||||
end
|
||||
end
|
||||
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
|
||||
if options[:box]
|
||||
update_specific(options[:box], options[:provider])
|
||||
else
|
||||
update_vms(argv)
|
||||
end
|
||||
|
||||
0
|
||||
end
|
||||
|
||||
def update_specific(name, provider)
|
||||
boxes = {}
|
||||
@env.boxes.all.each do |n, v, p|
|
||||
boxes[n] ||= {}
|
||||
boxes[n][p] ||= []
|
||||
boxes[n][p] << v
|
||||
end
|
||||
|
||||
if !boxes[name]
|
||||
raise Vagrant::Errors::BoxNotFound, name: name.to_s
|
||||
end
|
||||
|
||||
if !provider
|
||||
if boxes[name].length > 1
|
||||
raise Vagrant::Errors::BoxUpdateMultiProvider,
|
||||
name: name.to_s,
|
||||
providers: boxes[name].keys.map(&:to_s).sort.join(", ")
|
||||
end
|
||||
|
||||
provider = boxes[name].keys.first
|
||||
elsif !boxes[name][provider]
|
||||
raise Vagrant::Errors::BoxNotFoundWithProvider,
|
||||
name: name.to_s,
|
||||
provider: provider.to_s,
|
||||
providers: boxes[name].keys.map(&:to_s).sort.join(", ")
|
||||
end
|
||||
|
||||
to_update = [
|
||||
[name, provider, boxes[name][provider].last],
|
||||
]
|
||||
|
||||
to_update.each do |n, p, v|
|
||||
box = @env.boxes.find(n, p, v)
|
||||
box_update(box, "> #{v}", @env.ui)
|
||||
end
|
||||
end
|
||||
|
||||
def update_vms(argv)
|
||||
with_target_vms(argv) do |machine|
|
||||
if !machine.box
|
||||
machine.ui.output(I18n.t(
|
||||
|
@ -38,33 +89,36 @@ module VagrantPlugins
|
|||
|
||||
box = machine.box
|
||||
version = machine.config.vm.box_version
|
||||
|
||||
machine.ui.output(I18n.t("vagrant.box_update_checking", name: box.name))
|
||||
machine.ui.detail("Version constraints: #{version}")
|
||||
machine.ui.detail("Provider: #{box.provider}")
|
||||
|
||||
update = box.has_update?(version)
|
||||
if !update
|
||||
machine.ui.success(I18n.t(
|
||||
"vagrant.box_up_to_date_single",
|
||||
name: box.name, version: box.version))
|
||||
next
|
||||
end
|
||||
|
||||
machine.ui.output(I18n.t(
|
||||
"vagrant.box_updating",
|
||||
name: update[0].name,
|
||||
provider: update[2].name,
|
||||
old: box.version,
|
||||
new: update[1].version))
|
||||
@env.action_runner.run(Vagrant::Action.action_box_add, {
|
||||
box_url: box.metadata_url,
|
||||
box_provider: update[2].name,
|
||||
box_version: update[1].version,
|
||||
ui: machine.ui,
|
||||
})
|
||||
box_update(box, version, machine.ui)
|
||||
end
|
||||
end
|
||||
|
||||
def box_update(box, version, ui)
|
||||
ui.output(I18n.t("vagrant.box_update_checking", name: box.name))
|
||||
ui.detail("Version constraints: #{version}")
|
||||
ui.detail("Provider: #{box.provider}")
|
||||
|
||||
update = box.has_update?(version)
|
||||
if !update
|
||||
ui.success(I18n.t(
|
||||
"vagrant.box_up_to_date_single",
|
||||
name: box.name, version: box.version))
|
||||
return
|
||||
end
|
||||
|
||||
ui.output(I18n.t(
|
||||
"vagrant.box_updating",
|
||||
name: update[0].name,
|
||||
provider: update[2].name,
|
||||
old: box.version,
|
||||
new: update[1].version))
|
||||
@env.action_runner.run(Vagrant::Action.action_box_add, {
|
||||
box_url: box.metadata_url,
|
||||
box_provider: update[2].name,
|
||||
box_version: update[1].version,
|
||||
ui: ui,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -378,6 +378,16 @@ en:
|
|||
that this issue can be fixed.
|
||||
|
||||
%{error}
|
||||
box_not_found: |-
|
||||
The box '%{name}' does not exist. Please double check and
|
||||
try again. You can see the boxes that are installed with
|
||||
`vagrant box list`.
|
||||
box_not_found_with_provider: |-
|
||||
The box '%{name}' isn't installed for the provider '%{provider}'.
|
||||
Please double-check and try again. The installed providers for
|
||||
the box are shown below:
|
||||
|
||||
%{providers}
|
||||
box_outdated_no_box: |-
|
||||
The box '%{name}' isn't downloaded or added yet, so we can't
|
||||
check if it is outdated. Run a `vagrant up` or add the box
|
||||
|
@ -409,6 +419,12 @@ en:
|
|||
the provider specified. Please double-check and try again.
|
||||
|
||||
The providers for this are: %{providers}
|
||||
box_update_multi_provider: |-
|
||||
You requested to update the box '%{name}'. This box has
|
||||
multiple providers. You must explicitly select a single
|
||||
provider to remove with `--provider`.
|
||||
|
||||
Available providers: %{providers}
|
||||
box_update_no_metadata: |-
|
||||
The box '%{name}' is not a versioned box. The box was added
|
||||
directly instead of from a box catalog. Vagrant can only
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
require "pathname"
|
||||
require "tmpdir"
|
||||
|
||||
require File.expand_path("../../../../../base", __FILE__)
|
||||
|
||||
require Vagrant.source_root.join("plugins/commands/box/command/update")
|
||||
|
@ -23,6 +26,126 @@ describe VagrantPlugins::CommandBox::Command::Update do
|
|||
end
|
||||
|
||||
describe "execute" do
|
||||
context "updating specific box" do
|
||||
let(:argv) { ["--box", "foo"] }
|
||||
|
||||
let(:metadata_url) { Pathname.new(Dir.mktmpdir).join("metadata.json") }
|
||||
|
||||
before do
|
||||
metadata_url.open("w") do |f|
|
||||
f.write("")
|
||||
end
|
||||
|
||||
test_iso_env.box3(
|
||||
"foo", "1.0", :virtualbox, metadata_url: metadata_url.to_s)
|
||||
end
|
||||
|
||||
it "doesn't update if they're up to date" do
|
||||
action_runner.should_receive(:run).never
|
||||
|
||||
subject.execute
|
||||
end
|
||||
|
||||
it "does update if there is an update" do
|
||||
metadata_url.open("w") do |f|
|
||||
f.write(<<-RAW)
|
||||
{
|
||||
"name": "foo",
|
||||
"versions": [
|
||||
{
|
||||
"version": "1.0"
|
||||
},
|
||||
{
|
||||
"version": "1.1",
|
||||
"providers": [
|
||||
{
|
||||
"name": "virtualbox",
|
||||
"url": "bar"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
RAW
|
||||
end
|
||||
|
||||
action_runner.should_receive(:run).with do |action, opts|
|
||||
expect(opts[:box_url]).to eq(metadata_url.to_s)
|
||||
expect(opts[:box_provider]).to eq("virtualbox")
|
||||
expect(opts[:box_version]).to eq("1.1")
|
||||
true
|
||||
end
|
||||
|
||||
subject.execute
|
||||
end
|
||||
|
||||
it "raises an error if there are multiple providers" do
|
||||
test_iso_env.box3("foo", "1.0", :vmware)
|
||||
|
||||
action_runner.should_receive(:run).never
|
||||
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::BoxUpdateMultiProvider)
|
||||
end
|
||||
|
||||
context "with multiple providers and specifying the provider" do
|
||||
let(:argv) { ["--box", "foo", "--provider", "vmware"] }
|
||||
|
||||
it "updates the proper box" do
|
||||
metadata_url.open("w") do |f|
|
||||
f.write(<<-RAW)
|
||||
{
|
||||
"name": "foo",
|
||||
"versions": [
|
||||
{
|
||||
"version": "1.0"
|
||||
},
|
||||
{
|
||||
"version": "1.1",
|
||||
"providers": [
|
||||
{
|
||||
"name": "vmware",
|
||||
"url": "bar"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
RAW
|
||||
end
|
||||
|
||||
test_iso_env.box3("foo", "1.0", :vmware)
|
||||
|
||||
action_runner.should_receive(:run).with do |action, opts|
|
||||
expect(opts[:box_url]).to eq(metadata_url.to_s)
|
||||
expect(opts[:box_provider]).to eq("vmware")
|
||||
expect(opts[:box_version]).to eq("1.1")
|
||||
true
|
||||
end
|
||||
|
||||
subject.execute
|
||||
end
|
||||
|
||||
it "raises an error if that provider doesn't exist" do
|
||||
action_runner.should_receive(:run).never
|
||||
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::BoxNotFoundWithProvider)
|
||||
end
|
||||
end
|
||||
|
||||
context "with a box that doesn't exist" do
|
||||
let(:argv) { ["--box", "nope"] }
|
||||
|
||||
it "raises an exception" do
|
||||
action_runner.should_receive(:run).never
|
||||
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::BoxNotFound)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "updating environment machines" do
|
||||
before do
|
||||
subject.stub(:with_target_vms) { |&block| block.call machine }
|
||||
|
|
|
@ -117,6 +117,13 @@ module Unit
|
|||
end
|
||||
end
|
||||
|
||||
# Create the metadata URL
|
||||
if opts[:metadata_url]
|
||||
boxes_dir.join(name, "metadata_url").open("w") do |f|
|
||||
f.write(opts[:metadata_url])
|
||||
end
|
||||
end
|
||||
|
||||
box_dir
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue