From c635352b898b42c4ff7ede683dc527a3dfa5d395 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 7 Oct 2015 16:41:58 -0400 Subject: [PATCH] providers/virtualbox: list snapshots, progress for delete --- plugins/providers/virtualbox/action.rb | 15 +++++++ .../virtualbox/action/snapshot_delete.rb | 9 +++- .../virtualbox/action/snapshot_list.rb | 22 ++++++++++ .../virtualbox/action/snapshot_restore.rb | 21 ++++++++++ plugins/providers/virtualbox/driver/meta.rb | 1 + .../virtualbox/driver/version_5_0.rb | 41 ++++++++++++++++++- 6 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 plugins/providers/virtualbox/action/snapshot_list.rb create mode 100644 plugins/providers/virtualbox/action/snapshot_restore.rb diff --git a/plugins/providers/virtualbox/action.rb b/plugins/providers/virtualbox/action.rb index 96cd2373d..d355b8a69 100644 --- a/plugins/providers/virtualbox/action.rb +++ b/plugins/providers/virtualbox/action.rb @@ -43,6 +43,8 @@ module VagrantPlugins autoload :SetName, File.expand_path("../action/set_name", __FILE__) autoload :SetupPackageFiles, File.expand_path("../action/setup_package_files", __FILE__) autoload :SnapshotDelete, File.expand_path("../action/snapshot_delete", __FILE__) + autoload :SnapshotList, File.expand_path("../action/snapshot_list", __FILE__) + autoload :SnapshotRestore, File.expand_path("../action/snapshot_restore", __FILE__) autoload :SnapshotSave, File.expand_path("../action/snapshot_save", __FILE__) autoload :Suspend, File.expand_path("../action/suspend", __FILE__) @@ -237,6 +239,19 @@ module VagrantPlugins end end + def self.action_snapshot_list + Vagrant::Action::Builder.new.tap do |b| + b.use CheckVirtualbox + b.use Call, Created do |env, b2| + if env[:result] + b2.use SnapshotList + else + b2.use MessageNotCreated + end + end + end + end + # This is the action that is primarily responsible for saving a snapshot def self.action_snapshot_save Vagrant::Action::Builder.new.tap do |b| diff --git a/plugins/providers/virtualbox/action/snapshot_delete.rb b/plugins/providers/virtualbox/action/snapshot_delete.rb index 2efc8eae2..1d8cecc73 100644 --- a/plugins/providers/virtualbox/action/snapshot_delete.rb +++ b/plugins/providers/virtualbox/action/snapshot_delete.rb @@ -11,7 +11,14 @@ module VagrantPlugins "vagrant.actions.vm.snapshot.deleting", name: env[:snapshot_name])) env[:machine].provider.driver.delete_snapshot( - env[:machine].id, env[:snapshot_name]) + env[:machine].id, env[:snapshot_name]) do |progress| + env[:ui].clear_line + env[:ui].report_progress(progress, 100, false) + end + + # Clear the line one last time since the progress meter doesn't disappear + # immediately. + env[:ui].clear_line env[:ui].success(I18n.t( "vagrant.actions.vm.snapshot.deleted", diff --git a/plugins/providers/virtualbox/action/snapshot_list.rb b/plugins/providers/virtualbox/action/snapshot_list.rb new file mode 100644 index 000000000..e909c5e87 --- /dev/null +++ b/plugins/providers/virtualbox/action/snapshot_list.rb @@ -0,0 +1,22 @@ +module VagrantPlugins + module ProviderVirtualBox + module Action + class SnapshotList + def initialize(app, env) + @app = app + end + + def call(env) + snapshots = env[:machine].provider.driver.list_snapshots( + env[:machine].id) + + snapshots.each do |snapshot| + env[:machine].ui.output(snapshot, prefix: false) + end + + @app.call(env) + end + end + end + end +end diff --git a/plugins/providers/virtualbox/action/snapshot_restore.rb b/plugins/providers/virtualbox/action/snapshot_restore.rb new file mode 100644 index 000000000..c05480261 --- /dev/null +++ b/plugins/providers/virtualbox/action/snapshot_restore.rb @@ -0,0 +1,21 @@ +module VagrantPlugins + module ProviderVirtualBox + module Action + class SnapshotRestore + def initialize(app, env) + @app = app + end + + def call(env) + env[:ui].info(I18n.t( + "vagrant.actions.vm.snapshot.restoring", + name: env[:snapshot_name])) + env[:machine].provider.driver.restore_snapshot( + env[:machine].id, env[:snapshot_name]) + + @app.call(env) + end + end + end + end +end diff --git a/plugins/providers/virtualbox/driver/meta.rb b/plugins/providers/virtualbox/driver/meta.rb index a4246ba78..136ab196a 100644 --- a/plugins/providers/virtualbox/driver/meta.rb +++ b/plugins/providers/virtualbox/driver/meta.rb @@ -98,6 +98,7 @@ module VagrantPlugins :forward_ports, :halt, :import, + :list_snapshots, :read_forwarded_ports, :read_bridged_interfaces, :read_dhcp_servers, diff --git a/plugins/providers/virtualbox/driver/version_5_0.rb b/plugins/providers/virtualbox/driver/version_5_0.rb index b7e186538..2a0f3ea3d 100644 --- a/plugins/providers/virtualbox/driver/version_5_0.rb +++ b/plugins/providers/virtualbox/driver/version_5_0.rb @@ -87,7 +87,46 @@ module VagrantPlugins end def delete_snapshot(machine_id, snapshot_name) - execute("snapshot", machine_id, "delete", snapshot_name) + # Start with 0% + last = 0 + total = "" + yield 0 if block_given? + + # Snapshot and report the % progress + execute("snapshot", machine_id, "delete", snapshot_name) do |type, data| + if type == :stderr + # Append the data so we can see the full view + total << data.gsub("\r", "") + + # Break up the lines. We can't get the progress until we see an "OK" + lines = total.split("\n") + + # The progress of the import will be in the last line. Do a greedy + # regular expression to find what we're looking for. + match = /.+(\d{2})%/.match(lines.last) + if match + current = match[1].to_i + if current > last + last = current + yield current if block_given? + end + end + end + end + end + + def list_snapshots(machine_id) + result = [] + output = execute( + "snapshot", machine_id, "list", "--machinereadable", + retryable: true) + output.split("\n").each do |line| + if line =~ /^SnapshotName.*?="(.+?)"$/i + result << $1.to_s + end + end + + result.sort end def restore_snapshot(machine_id, snapshot_name)