New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Track downloaded base boxes URLs into a state file and allow hooking into base boxes removal #2327

Merged
merged 13 commits into from Nov 25, 2013
View
@@ -8,7 +8,8 @@ module Action
# Builtin contains middleware classes that are shipped with Vagrant-core
# and are thus available to all plugins as a "standard library" of sorts.
module Builtin
autoload :BoxAdd, "vagrant/action/builtin/box_add"
autoload :BoxAdd, "vagrant/action/builtin/box_add"
autoload :BoxRemove, "vagrant/action/builtin/box_remove"
autoload :Call, "vagrant/action/builtin/call"
autoload :Confirm, "vagrant/action/builtin/confirm"
autoload :ConfigValidate, "vagrant/action/builtin/config_validate"
@@ -41,5 +42,14 @@ def self.action_box_add
b.use Builtin::BoxAdd
end
end
# This is the action that will remove a box given a name (and optionally
# a provider). This middleware sequence is built-in to Vagrant. Plugins
# can hook into this like any other middleware sequence.
def self.action_box_remove
Builder.new.tap do |b|
b.use Builtin::BoxRemove
end
end
end
end
@@ -57,9 +57,9 @@ def call(env)
# Add the box
env[:ui].info I18n.t("vagrant.actions.box.add.adding", :name => env[:box_name])
added_box = nil
box_added = nil
begin
added_box = env[:box_collection].add(
box_added = env[:box_collection].add(
@temp_path, env[:box_name], box_formats, env[:box_force])
rescue Vagrant::Errors::BoxUpgradeRequired
# Upgrade the box
@@ -75,7 +75,13 @@ def call(env)
# Success, we added a box!
env[:ui].success(
I18n.t("vagrant.actions.box.add.added", name: added_box.name, provider: added_box.provider))
I18n.t("vagrant.actions.box.add.added", name: box_added.name, provider: box_added.provider))
# Persists URL used on download and the time it was added
write_extra_info(box_added, url)
# Passes on the newly added box to the rest of the middleware chain
env[:box_added] = box_added
# Carry on!
@app.call(env)
@@ -86,6 +92,13 @@ def recover(env)
File.unlink(@temp_path)
end
end
def write_extra_info(box_added, url)
info = {'url' => url, 'downloaded_at' => Time.now.utc}
box_added.directory.join('info.json').open("w+") do |f|
f.write(JSON.dump(info))
end
end
end
end
end
@@ -0,0 +1,38 @@
require "log4r"
module Vagrant
module Action
module Builtin
# This middleware will remove a box for a given provider.
class BoxRemove
def initialize(app, env)
@app = app
@logger = Log4r::Logger.new("vagrant::action::builtin::box_remove")
end
def call(env)
box_name = env[:box_name]
box_provider = env[:box_provider].to_sym
box = nil
begin
box = env[:box_collection].find(box_name, box_provider)
rescue Vagrant::Errors::BoxUpgradeRequired
@env.boxes.upgrade(box_name)
retry
end
raise Vagrant::Errors::BoxNotFound, :name => box_name, :provider => box_provider if !box
env[:ui].info(I18n.t("vagrant.commands.box.removing",
:name => box_name,
:provider => box_provider))
box.destroy!
# Passes on the removed box to the rest of the middleware chain
env[:box_removed] = box
@app.call(env)
end
end
end
end
end
@@ -39,7 +39,7 @@ def execute
:box_provider => provider,
:box_url => argv[1],
:box_force => options[:force],
:box_download_insecure => options[:insecure],
:box_download_insecure => options[:insecure]
})
# Success, exit status 0
@@ -9,6 +9,11 @@ def execute
opts = OptionParser.new do |opts|
opts.banner = "Usage: vagrant box list"
opts.separator ""
opts.on("-i", "--box-info", "Displays additional information about the boxes.") do |i|
options[:info] = i
end
end
# Parse the options
@@ -20,20 +25,50 @@ def execute
return @env.ui.warn(I18n.t("vagrant.commands.box.no_installed_boxes"), :prefix => false)
end
list_boxes(boxes, options[:info])
# Success, exit status 0
0
end
private
def list_boxes(boxes, extra_info)
# Find the longest box name
longest_box = boxes.max_by { |x| x[0].length }
longest_box_length = longest_box[0].length
# Find the longest provider name
longest_provider = boxes.max_by { |x| x[1].length }
longest_provider_length = longest_provider[1].length
# Go through each box and output the information about it. We
# ignore the "v1" param for now since I'm not yet sure if its
# important for the user to know what boxes need to be upgraded
# and which don't, since we plan on doing that transparently.
boxes.each do |name, provider, _v1|
@env.ui.info("#{name.ljust(longest_box_length)} (#{provider})", :prefix => false)
extra = ''
if extra_info
extra << format_extra_info(name.to_s, provider.to_s)
end
name = name.ljust(longest_box_length)
provider = "(#{provider})".ljust(longest_provider_length + 2) # 2 -> parenthesis
box_info = "#{name} #{provider}#{extra}"
@env.ui.info(box_info, :prefix => false)
end
end
# Success, exit status 0
0
def format_extra_info(name, provider)
info_json = @env.boxes.find(name, provider).directory.join('info.json')
if info_json.file?
info = JSON.parse(info_json.read)
return "\n `- URL: #{info['url']}" +
"\n `- Date: #{info['downloaded_at']}"
else
return ''
end
end
end
end
@@ -34,19 +34,10 @@ def execute
argv[1] = providers[0] || ""
end
b = nil
begin
b = @env.boxes.find(argv[0], argv[1].to_sym)
rescue Vagrant::Errors::BoxUpgradeRequired
@env.boxes.upgrade(argv[0])
retry
end
raise Vagrant::Errors::BoxNotFound, :name => argv[0], :provider => argv[1].to_sym if !b
@env.ui.info(I18n.t("vagrant.commands.box.removing",
:name => argv[0],
:provider => argv[1]))
b.destroy!
@env.action_runner.run(Vagrant::Action.action_box_remove, {
:box_name => argv[0],
:box_provider => argv[1]
})
# Success, exit status 0
0
ProTip! Use n and p to navigate between commits in a pull request.