From 4fa12d896fb6b64961eaddbe14533d88e499ad6f Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Fri, 4 Oct 2013 11:24:11 -0300 Subject: [PATCH 01/13] core: Pass on the newly added box to the rest of the middleware stack --- lib/vagrant/action/builtin/box_add.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/vagrant/action/builtin/box_add.rb b/lib/vagrant/action/builtin/box_add.rb index 380a2cc39..f05f9a6d4 100644 --- a/lib/vagrant/action/builtin/box_add.rb +++ b/lib/vagrant/action/builtin/box_add.rb @@ -57,9 +57,9 @@ module Vagrant # 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,10 @@ module Vagrant # 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)) + + # Passes on the newly added box to the rest of the middleware chain + env[:box_added] = box_added # Carry on! @app.call(env) From 670a441a997c4e8e126412f84d8e01462a020836 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Fri, 4 Oct 2013 11:24:54 -0300 Subject: [PATCH 02/13] core: Scaffold an action for persisting box information --- lib/vagrant/action.rb | 2 ++ lib/vagrant/action/builtin/write_box_info.rb | 24 ++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 lib/vagrant/action/builtin/write_box_info.rb diff --git a/lib/vagrant/action.rb b/lib/vagrant/action.rb index 52164b462..8c8a241e0 100644 --- a/lib/vagrant/action.rb +++ b/lib/vagrant/action.rb @@ -25,6 +25,7 @@ module Vagrant autoload :SSHExec, "vagrant/action/builtin/ssh_exec" autoload :SSHRun, "vagrant/action/builtin/ssh_run" autoload :WaitForCommunicator, "vagrant/action/builtin/wait_for_communicator" + autoload :WriteBoxInfo, "vagrant/action/builtin/write_box_info" end module General @@ -39,6 +40,7 @@ module Vagrant def self.action_box_add Builder.new.tap do |b| b.use Builtin::BoxAdd + b.use Builtin::WriteBoxInfo end end end diff --git a/lib/vagrant/action/builtin/write_box_info.rb b/lib/vagrant/action/builtin/write_box_info.rb new file mode 100644 index 000000000..ebf11cfb9 --- /dev/null +++ b/lib/vagrant/action/builtin/write_box_info.rb @@ -0,0 +1,24 @@ +require "log4r" + +module Vagrant + module Action + module Builtin + # This middleware will persist some extra information about the base box + class WriteBoxInfo + def initialize(app, env) + @app = app + @logger = Log4r::Logger.new("vagrant::action::builtin::write_box_info") + end + + def call(env) + box_url = env[:box_url] + box_added = env[:box_added] + + # TODO: Persist box_url / provider / datetime + + @app.call(env) + end + end + end + end +end From 17fd5f9e4eb6c0e47e52987e9bdc939b12470e1f Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Fri, 4 Oct 2013 21:28:05 -0300 Subject: [PATCH 03/13] commands/box: Introduce a StateFile for keeping track of downloaded boxes --- plugins/commands/box/command/add.rb | 1 + plugins/commands/box/plugin.rb | 2 ++ plugins/commands/box/state_file.rb | 39 +++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 plugins/commands/box/state_file.rb diff --git a/plugins/commands/box/command/add.rb b/plugins/commands/box/command/add.rb index 7f6829c7d..73511ea99 100644 --- a/plugins/commands/box/command/add.rb +++ b/plugins/commands/box/command/add.rb @@ -40,6 +40,7 @@ module VagrantPlugins :box_url => argv[1], :box_force => options[:force], :box_download_insecure => options[:insecure], + :box_state_file => StateFile.new(@env.home_path.join('boxes.json')) }) # Success, exit status 0 diff --git a/plugins/commands/box/plugin.rb b/plugins/commands/box/plugin.rb index bc19f99f6..58a9ca530 100644 --- a/plugins/commands/box/plugin.rb +++ b/plugins/commands/box/plugin.rb @@ -11,5 +11,7 @@ module VagrantPlugins Command::Root end end + + autoload :StateFile, File.expand_path("../state_file", __FILE__) end end diff --git a/plugins/commands/box/state_file.rb b/plugins/commands/box/state_file.rb new file mode 100644 index 000000000..0fdc0ed48 --- /dev/null +++ b/plugins/commands/box/state_file.rb @@ -0,0 +1,39 @@ +require "json" + +module VagrantPlugins + module CommandBox + # This is a helper to deal with the boxes state file that Vagrant + # uses to track the boxes that have been downloaded. + class StateFile + def initialize(path) + @path = path + + @data = {} + @data = JSON.parse(@path.read) if @path.exist? + @data["boxes"] ||= {} + end + + # Add a downloaded box to the state file. + # + # @param [Box] box The Box object that was added + # @param [String] url The URL from where the box was downloaded + def add_box(box, url) + box_key = "#{box.name}-#{box.provider}" + + @data["boxes"][box_key] = { + "url" => url, + "downloaded_at" => Time.now.utc.to_s + } + + save! + end + + # This saves the state back into the state file. + def save! + @path.open("w+") do |f| + f.write(JSON.dump(@data)) + end + end + end + end +end From 1443d634c7b6ee46b777944da84f58dce787e7e5 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Fri, 4 Oct 2013 21:29:52 -0300 Subject: [PATCH 04/13] core: Write box information after download --- lib/vagrant/action/builtin/write_box_info.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/vagrant/action/builtin/write_box_info.rb b/lib/vagrant/action/builtin/write_box_info.rb index ebf11cfb9..a8bcd30aa 100644 --- a/lib/vagrant/action/builtin/write_box_info.rb +++ b/lib/vagrant/action/builtin/write_box_info.rb @@ -11,10 +11,13 @@ module Vagrant end def call(env) - box_url = env[:box_url] - box_added = env[:box_added] + box_url = env[:box_url] + box_added = env[:box_added] + box_state_file = env[:box_state_file] - # TODO: Persist box_url / provider / datetime + # Mark that we downloaded the box + @logger.info("Adding the box to the state file...") + box_state_file.add_box(box_added, box_url) @app.call(env) end From e4b5db829effc145bd20db2b201735df64fc5701 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Fri, 4 Oct 2013 21:54:21 -0300 Subject: [PATCH 05/13] commands/box: Extract box removal code from `box remove` command into a builtin action --- lib/vagrant/action.rb | 12 +++++++- lib/vagrant/action/builtin/box_remove.rb | 38 ++++++++++++++++++++++++ plugins/commands/box/command/remove.rb | 18 ++++------- 3 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 lib/vagrant/action/builtin/box_remove.rb diff --git a/lib/vagrant/action.rb b/lib/vagrant/action.rb index 8c8a241e0..f2fa0e137 100644 --- a/lib/vagrant/action.rb +++ b/lib/vagrant/action.rb @@ -8,7 +8,8 @@ module Vagrant # 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" @@ -43,5 +44,14 @@ module Vagrant b.use Builtin::WriteBoxInfo 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 diff --git a/lib/vagrant/action/builtin/box_remove.rb b/lib/vagrant/action/builtin/box_remove.rb new file mode 100644 index 000000000..3ae8bc1ac --- /dev/null +++ b/lib/vagrant/action/builtin/box_remove.rb @@ -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 diff --git a/plugins/commands/box/command/remove.rb b/plugins/commands/box/command/remove.rb index 4cdfcdfa4..bea7dd83b 100644 --- a/plugins/commands/box/command/remove.rb +++ b/plugins/commands/box/command/remove.rb @@ -34,19 +34,11 @@ module VagrantPlugins 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], + :box_state_file => StateFile.new(@env.home_path.join('boxes.json')) + }) # Success, exit status 0 0 From 1c689d22114a00aa68cb0b8b3de3e3543ae24290 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Fri, 4 Oct 2013 21:55:27 -0300 Subject: [PATCH 06/13] core: Remove box information from state file after box removal --- lib/vagrant/action.rb | 2 ++ lib/vagrant/action/builtin/remove_box_info.rb | 26 +++++++++++++++++++ plugins/commands/box/state_file.rb | 9 +++++++ 3 files changed, 37 insertions(+) create mode 100644 lib/vagrant/action/builtin/remove_box_info.rb diff --git a/lib/vagrant/action.rb b/lib/vagrant/action.rb index f2fa0e137..b67d5fdb5 100644 --- a/lib/vagrant/action.rb +++ b/lib/vagrant/action.rb @@ -22,6 +22,7 @@ module Vagrant autoload :NFS, "vagrant/action/builtin/nfs" autoload :Provision, "vagrant/action/builtin/provision" autoload :ProvisionerCleanup, "vagrant/action/builtin/provisioner_cleanup" + autoload :RemoveBoxInfo, "vagrant/action/builtin/remove_box_info" autoload :SetHostname, "vagrant/action/builtin/set_hostname" autoload :SSHExec, "vagrant/action/builtin/ssh_exec" autoload :SSHRun, "vagrant/action/builtin/ssh_run" @@ -51,6 +52,7 @@ module Vagrant def self.action_box_remove Builder.new.tap do |b| b.use Builtin::BoxRemove + b.use Builtin::RemoveBoxInfo end end end diff --git a/lib/vagrant/action/builtin/remove_box_info.rb b/lib/vagrant/action/builtin/remove_box_info.rb new file mode 100644 index 000000000..ebf4761b0 --- /dev/null +++ b/lib/vagrant/action/builtin/remove_box_info.rb @@ -0,0 +1,26 @@ +require "log4r" + +module Vagrant + module Action + module Builtin + # This middleware will persist some extra information about the base box + class RemoveBoxInfo + def initialize(app, env) + @app = app + @logger = Log4r::Logger.new("vagrant::action::builtin::remove_box_info") + end + + def call(env) + box_removed = env[:box_removed] + box_state_file = env[:box_state_file] + + # Mark that we removed the box + @logger.info("Removing the box from the state file...") + box_state_file.remove_box(box_removed) + + @app.call(env) + end + end + end + end +end diff --git a/plugins/commands/box/state_file.rb b/plugins/commands/box/state_file.rb index 0fdc0ed48..c0f7c8a1e 100644 --- a/plugins/commands/box/state_file.rb +++ b/plugins/commands/box/state_file.rb @@ -28,6 +28,15 @@ module VagrantPlugins save! end + # Remove a box that has been previously downloaded from the state file. + # + # @param [Box] box The box that was removed. + def remove_box(box) + box_key = "#{box.name}-#{box.provider}" + @data["boxes"].delete(box_key) + save! + end + # This saves the state back into the state file. def save! @path.open("w+") do |f| From 031119a858e961c666dbafabe670db152e1abf9e Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Fri, 4 Oct 2013 22:02:24 -0300 Subject: [PATCH 07/13] commands/box: Extract a base class for dealing with StateFile instantiation --- plugins/commands/box/command/add.rb | 9 +++++---- plugins/commands/box/command/base.rb | 21 +++++++++++++++++++++ plugins/commands/box/command/remove.rb | 9 +++++---- 3 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 plugins/commands/box/command/base.rb diff --git a/plugins/commands/box/command/add.rb b/plugins/commands/box/command/add.rb index 73511ea99..403dddb79 100644 --- a/plugins/commands/box/command/add.rb +++ b/plugins/commands/box/command/add.rb @@ -1,9 +1,11 @@ require 'optparse' +require_relative "base" + module VagrantPlugins module CommandBox module Command - class Add < Vagrant.plugin("2", :command) + class Add < Base def execute options = {} @@ -34,13 +36,12 @@ module VagrantPlugins provider = nil provider = options[:provider].to_sym if options[:provider] - @env.action_runner.run(Vagrant::Action.action_box_add, { + action(Vagrant::Action.action_box_add, { :box_name => argv[0], :box_provider => provider, :box_url => argv[1], :box_force => options[:force], - :box_download_insecure => options[:insecure], - :box_state_file => StateFile.new(@env.home_path.join('boxes.json')) + :box_download_insecure => options[:insecure] }) # Success, exit status 0 diff --git a/plugins/commands/box/command/base.rb b/plugins/commands/box/command/base.rb new file mode 100644 index 000000000..b80b2dcb7 --- /dev/null +++ b/plugins/commands/box/command/base.rb @@ -0,0 +1,21 @@ +module VagrantPlugins + module CommandBox + module Command + class Base < Vagrant.plugin("2", :command) + # This is a helper for executing an action sequence with the proper + # environment hash setup so that the plugin specific helpers are + # in. + # + # @param [Object] callable the Middleware callable + # @param [Hash] env Extra environment hash that is merged in. + def action(callable, env=nil) + env = { + :box_state_file => StateFile.new(@env.home_path.join("boxes.json")) + }.merge(env || {}) + + @env.action_runner.run(callable, env) + end + end + end + end +end diff --git a/plugins/commands/box/command/remove.rb b/plugins/commands/box/command/remove.rb index bea7dd83b..6b52f023f 100644 --- a/plugins/commands/box/command/remove.rb +++ b/plugins/commands/box/command/remove.rb @@ -1,9 +1,11 @@ require 'optparse' +require_relative "base" + module VagrantPlugins module CommandBox module Command - class Remove < Vagrant.plugin("2", :command) + class Remove < Base def execute opts = OptionParser.new do |o| o.banner = "Usage: vagrant box remove " @@ -34,10 +36,9 @@ module VagrantPlugins argv[1] = providers[0] || "" end - @env.action_runner.run(Vagrant::Action.action_box_remove, { + action(Vagrant::Action.action_box_remove, { :box_name => argv[0], - :box_provider => argv[1], - :box_state_file => StateFile.new(@env.home_path.join('boxes.json')) + :box_provider => argv[1] }) # Success, exit status 0 From cbc7e7eedb4dec3ca71f1ab8bea7725b312f265c Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Fri, 4 Oct 2013 22:08:39 -0300 Subject: [PATCH 08/13] commands/box: Preparing to display additional box information on `box list` --- plugins/commands/box/command/list.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/plugins/commands/box/command/list.rb b/plugins/commands/box/command/list.rb index 94a4d3964..2eb4e0790 100644 --- a/plugins/commands/box/command/list.rb +++ b/plugins/commands/box/command/list.rb @@ -24,12 +24,20 @@ module VagrantPlugins 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) + name = name.ljust(longest_box_length) + provider = "(#{provider})".ljust(longest_provider_length + 2) # 2 -> parenthesis + box_info = "#{name} #{provider}" + + @env.ui.info(box_info, :prefix => false) end # Success, exit status 0 From 18cf66e83a37f528af3879962e22da4a57c4c6f5 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Fri, 4 Oct 2013 22:27:30 -0300 Subject: [PATCH 09/13] commands/box: List base box downloaded URL and datetime when `-i` gets provided to `box list` --- plugins/commands/box/command/base.rb | 6 +++++- plugins/commands/box/command/list.rb | 29 +++++++++++++++++++++++----- plugins/commands/box/state_file.rb | 14 ++++++++++++++ 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/plugins/commands/box/command/base.rb b/plugins/commands/box/command/base.rb index b80b2dcb7..9b07cfe4d 100644 --- a/plugins/commands/box/command/base.rb +++ b/plugins/commands/box/command/base.rb @@ -10,11 +10,15 @@ module VagrantPlugins # @param [Hash] env Extra environment hash that is merged in. def action(callable, env=nil) env = { - :box_state_file => StateFile.new(@env.home_path.join("boxes.json")) + :box_state_file => box_state_file }.merge(env || {}) @env.action_runner.run(callable, env) end + + def box_state_file + @box_state_file ||= StateFile.new(@env.home_path.join("boxes.json")) + end end end end diff --git a/plugins/commands/box/command/list.rb b/plugins/commands/box/command/list.rb index 2eb4e0790..ca1b0f3c4 100644 --- a/plugins/commands/box/command/list.rb +++ b/plugins/commands/box/command/list.rb @@ -1,14 +1,21 @@ require 'optparse' +require_relative "base" + module VagrantPlugins module CommandBox module Command - class List < Vagrant.plugin("2", :command) + class List < Base def execute options = {} 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,6 +27,15 @@ module VagrantPlugins 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 @@ -33,15 +49,18 @@ module VagrantPlugins # 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| + extra = '' + if extra_info + extra << "\n `- URL: #{box_state_file.box_url(name, provider)}" + extra << "\n `- Date: #{box_state_file.downloaded_at(name, provider)}" + end + name = name.ljust(longest_box_length) provider = "(#{provider})".ljust(longest_provider_length + 2) # 2 -> parenthesis - box_info = "#{name} #{provider}" + box_info = "#{name} #{provider}#{extra}" @env.ui.info(box_info, :prefix => false) end - - # Success, exit status 0 - 0 end end end diff --git a/plugins/commands/box/state_file.rb b/plugins/commands/box/state_file.rb index c0f7c8a1e..0ea690da9 100644 --- a/plugins/commands/box/state_file.rb +++ b/plugins/commands/box/state_file.rb @@ -28,6 +28,20 @@ module VagrantPlugins save! end + def box_url(name, provider) + box_key = "#{name}-#{provider}" + + box_info = @data["boxes"].fetch(box_key, {}) + box_info['url'] || 'Unknown' + end + + def downloaded_at(name, provider) + box_key = "#{name}-#{provider}" + + box_info = @data["boxes"].fetch(box_key, {}) + box_info['downloaded_at'] || 'Unknown' + end + # Remove a box that has been previously downloaded from the state file. # # @param [Box] box The box that was removed. From fcfb431362db62d1c2848130ae936d4ccfb3ef2c Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Fri, 4 Oct 2013 22:31:43 -0300 Subject: [PATCH 10/13] core: Improve RemoveBoxInfo and WriteBoxInfo docs a bit --- lib/vagrant/action/builtin/remove_box_info.rb | 3 ++- lib/vagrant/action/builtin/write_box_info.rb | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/vagrant/action/builtin/remove_box_info.rb b/lib/vagrant/action/builtin/remove_box_info.rb index ebf4761b0..c0a8d8fba 100644 --- a/lib/vagrant/action/builtin/remove_box_info.rb +++ b/lib/vagrant/action/builtin/remove_box_info.rb @@ -3,7 +3,8 @@ require "log4r" module Vagrant module Action module Builtin - # This middleware will persist some extra information about the base box + # This middleware will remove additional information about the base box + # from state file class RemoveBoxInfo def initialize(app, env) @app = app diff --git a/lib/vagrant/action/builtin/write_box_info.rb b/lib/vagrant/action/builtin/write_box_info.rb index a8bcd30aa..e8c55989b 100644 --- a/lib/vagrant/action/builtin/write_box_info.rb +++ b/lib/vagrant/action/builtin/write_box_info.rb @@ -4,6 +4,7 @@ module Vagrant module Action module Builtin # This middleware will persist some extra information about the base box + # on a state file class WriteBoxInfo def initialize(app, env) @app = app From 05a8cf523ac4eacc8b48b522dc8bf73dd14391e8 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Wed, 16 Oct 2013 10:58:11 -0300 Subject: [PATCH 11/13] core: Get rid of code that deals with box info on a separate statefile --- lib/vagrant/action.rb | 4 -- lib/vagrant/action/builtin/remove_box_info.rb | 27 -------- lib/vagrant/action/builtin/write_box_info.rb | 28 --------- plugins/commands/box/command/add.rb | 6 +- plugins/commands/box/command/base.rb | 25 -------- plugins/commands/box/command/list.rb | 8 +-- plugins/commands/box/command/remove.rb | 6 +- plugins/commands/box/plugin.rb | 2 - plugins/commands/box/state_file.rb | 62 ------------------- 9 files changed, 7 insertions(+), 161 deletions(-) delete mode 100644 lib/vagrant/action/builtin/remove_box_info.rb delete mode 100644 lib/vagrant/action/builtin/write_box_info.rb delete mode 100644 plugins/commands/box/command/base.rb delete mode 100644 plugins/commands/box/state_file.rb diff --git a/lib/vagrant/action.rb b/lib/vagrant/action.rb index b67d5fdb5..03ce5a358 100644 --- a/lib/vagrant/action.rb +++ b/lib/vagrant/action.rb @@ -22,12 +22,10 @@ module Vagrant autoload :NFS, "vagrant/action/builtin/nfs" autoload :Provision, "vagrant/action/builtin/provision" autoload :ProvisionerCleanup, "vagrant/action/builtin/provisioner_cleanup" - autoload :RemoveBoxInfo, "vagrant/action/builtin/remove_box_info" autoload :SetHostname, "vagrant/action/builtin/set_hostname" autoload :SSHExec, "vagrant/action/builtin/ssh_exec" autoload :SSHRun, "vagrant/action/builtin/ssh_run" autoload :WaitForCommunicator, "vagrant/action/builtin/wait_for_communicator" - autoload :WriteBoxInfo, "vagrant/action/builtin/write_box_info" end module General @@ -42,7 +40,6 @@ module Vagrant def self.action_box_add Builder.new.tap do |b| b.use Builtin::BoxAdd - b.use Builtin::WriteBoxInfo end end @@ -52,7 +49,6 @@ module Vagrant def self.action_box_remove Builder.new.tap do |b| b.use Builtin::BoxRemove - b.use Builtin::RemoveBoxInfo end end end diff --git a/lib/vagrant/action/builtin/remove_box_info.rb b/lib/vagrant/action/builtin/remove_box_info.rb deleted file mode 100644 index c0a8d8fba..000000000 --- a/lib/vagrant/action/builtin/remove_box_info.rb +++ /dev/null @@ -1,27 +0,0 @@ -require "log4r" - -module Vagrant - module Action - module Builtin - # This middleware will remove additional information about the base box - # from state file - class RemoveBoxInfo - def initialize(app, env) - @app = app - @logger = Log4r::Logger.new("vagrant::action::builtin::remove_box_info") - end - - def call(env) - box_removed = env[:box_removed] - box_state_file = env[:box_state_file] - - # Mark that we removed the box - @logger.info("Removing the box from the state file...") - box_state_file.remove_box(box_removed) - - @app.call(env) - end - end - end - end -end diff --git a/lib/vagrant/action/builtin/write_box_info.rb b/lib/vagrant/action/builtin/write_box_info.rb deleted file mode 100644 index e8c55989b..000000000 --- a/lib/vagrant/action/builtin/write_box_info.rb +++ /dev/null @@ -1,28 +0,0 @@ -require "log4r" - -module Vagrant - module Action - module Builtin - # This middleware will persist some extra information about the base box - # on a state file - class WriteBoxInfo - def initialize(app, env) - @app = app - @logger = Log4r::Logger.new("vagrant::action::builtin::write_box_info") - end - - def call(env) - box_url = env[:box_url] - box_added = env[:box_added] - box_state_file = env[:box_state_file] - - # Mark that we downloaded the box - @logger.info("Adding the box to the state file...") - box_state_file.add_box(box_added, box_url) - - @app.call(env) - end - end - end - end -end diff --git a/plugins/commands/box/command/add.rb b/plugins/commands/box/command/add.rb index 403dddb79..5a2ff0187 100644 --- a/plugins/commands/box/command/add.rb +++ b/plugins/commands/box/command/add.rb @@ -1,11 +1,9 @@ require 'optparse' -require_relative "base" - module VagrantPlugins module CommandBox module Command - class Add < Base + class Add < Vagrant.plugin("2", :command) def execute options = {} @@ -36,7 +34,7 @@ module VagrantPlugins provider = nil provider = options[:provider].to_sym if options[:provider] - action(Vagrant::Action.action_box_add, { + @env.action_runner.run(Vagrant::Action.action_box_add, { :box_name => argv[0], :box_provider => provider, :box_url => argv[1], diff --git a/plugins/commands/box/command/base.rb b/plugins/commands/box/command/base.rb deleted file mode 100644 index 9b07cfe4d..000000000 --- a/plugins/commands/box/command/base.rb +++ /dev/null @@ -1,25 +0,0 @@ -module VagrantPlugins - module CommandBox - module Command - class Base < Vagrant.plugin("2", :command) - # This is a helper for executing an action sequence with the proper - # environment hash setup so that the plugin specific helpers are - # in. - # - # @param [Object] callable the Middleware callable - # @param [Hash] env Extra environment hash that is merged in. - def action(callable, env=nil) - env = { - :box_state_file => box_state_file - }.merge(env || {}) - - @env.action_runner.run(callable, env) - end - - def box_state_file - @box_state_file ||= StateFile.new(@env.home_path.join("boxes.json")) - end - end - end - end -end diff --git a/plugins/commands/box/command/list.rb b/plugins/commands/box/command/list.rb index ca1b0f3c4..97782d026 100644 --- a/plugins/commands/box/command/list.rb +++ b/plugins/commands/box/command/list.rb @@ -1,11 +1,9 @@ require 'optparse' -require_relative "base" - module VagrantPlugins module CommandBox module Command - class List < Base + class List < Vagrant.plugin("2", :command) def execute options = {} @@ -51,8 +49,8 @@ module VagrantPlugins boxes.each do |name, provider, _v1| extra = '' if extra_info - extra << "\n `- URL: #{box_state_file.box_url(name, provider)}" - extra << "\n `- Date: #{box_state_file.downloaded_at(name, provider)}" + extra << "\n `- URL: TODO" + extra << "\n `- Date: TODO" end name = name.ljust(longest_box_length) diff --git a/plugins/commands/box/command/remove.rb b/plugins/commands/box/command/remove.rb index 6b52f023f..d58f5bcec 100644 --- a/plugins/commands/box/command/remove.rb +++ b/plugins/commands/box/command/remove.rb @@ -1,11 +1,9 @@ require 'optparse' -require_relative "base" - module VagrantPlugins module CommandBox module Command - class Remove < Base + class Remove < Vagrant.plugin("2", :command) def execute opts = OptionParser.new do |o| o.banner = "Usage: vagrant box remove " @@ -36,7 +34,7 @@ module VagrantPlugins argv[1] = providers[0] || "" end - action(Vagrant::Action.action_box_remove, { + @env.action_runner.run(Vagrant::Action.action_box_remove, { :box_name => argv[0], :box_provider => argv[1] }) diff --git a/plugins/commands/box/plugin.rb b/plugins/commands/box/plugin.rb index 58a9ca530..bc19f99f6 100644 --- a/plugins/commands/box/plugin.rb +++ b/plugins/commands/box/plugin.rb @@ -11,7 +11,5 @@ module VagrantPlugins Command::Root end end - - autoload :StateFile, File.expand_path("../state_file", __FILE__) end end diff --git a/plugins/commands/box/state_file.rb b/plugins/commands/box/state_file.rb deleted file mode 100644 index 0ea690da9..000000000 --- a/plugins/commands/box/state_file.rb +++ /dev/null @@ -1,62 +0,0 @@ -require "json" - -module VagrantPlugins - module CommandBox - # This is a helper to deal with the boxes state file that Vagrant - # uses to track the boxes that have been downloaded. - class StateFile - def initialize(path) - @path = path - - @data = {} - @data = JSON.parse(@path.read) if @path.exist? - @data["boxes"] ||= {} - end - - # Add a downloaded box to the state file. - # - # @param [Box] box The Box object that was added - # @param [String] url The URL from where the box was downloaded - def add_box(box, url) - box_key = "#{box.name}-#{box.provider}" - - @data["boxes"][box_key] = { - "url" => url, - "downloaded_at" => Time.now.utc.to_s - } - - save! - end - - def box_url(name, provider) - box_key = "#{name}-#{provider}" - - box_info = @data["boxes"].fetch(box_key, {}) - box_info['url'] || 'Unknown' - end - - def downloaded_at(name, provider) - box_key = "#{name}-#{provider}" - - box_info = @data["boxes"].fetch(box_key, {}) - box_info['downloaded_at'] || 'Unknown' - end - - # Remove a box that has been previously downloaded from the state file. - # - # @param [Box] box The box that was removed. - def remove_box(box) - box_key = "#{box.name}-#{box.provider}" - @data["boxes"].delete(box_key) - save! - end - - # This saves the state back into the state file. - def save! - @path.open("w+") do |f| - f.write(JSON.dump(@data)) - end - end - end - end -end From 500deb5138ecab6c9165bb174e8c2f88b2b63e05 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Fri, 18 Oct 2013 17:56:51 -0300 Subject: [PATCH 12/13] core: Persist box URL and download date into a JSON file under boxes directory --- lib/vagrant/action/builtin/box_add.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/vagrant/action/builtin/box_add.rb b/lib/vagrant/action/builtin/box_add.rb index f05f9a6d4..d1523c408 100644 --- a/lib/vagrant/action/builtin/box_add.rb +++ b/lib/vagrant/action/builtin/box_add.rb @@ -77,6 +77,9 @@ module Vagrant env[:ui].success( 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 @@ -89,6 +92,13 @@ module Vagrant 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 From 48875124b9aaa1ea998da8de1c04653ff6bff99f Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Fri, 18 Oct 2013 17:57:24 -0300 Subject: [PATCH 13/13] commands/box: Read box URL and downloaded date from JSON --- plugins/commands/box/command/list.rb | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/plugins/commands/box/command/list.rb b/plugins/commands/box/command/list.rb index 97782d026..85166cd5c 100644 --- a/plugins/commands/box/command/list.rb +++ b/plugins/commands/box/command/list.rb @@ -49,8 +49,7 @@ module VagrantPlugins boxes.each do |name, provider, _v1| extra = '' if extra_info - extra << "\n `- URL: TODO" - extra << "\n `- Date: TODO" + extra << format_extra_info(name.to_s, provider.to_s) end name = name.ljust(longest_box_length) @@ -60,6 +59,17 @@ module VagrantPlugins @env.ui.info(box_info, :prefix => false) end end + + 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 end