From df4caf07571f7958616a36954a2c600efed4cffb Mon Sep 17 00:00:00 2001 From: Jon Topper Date: Sat, 5 Mar 2016 16:41:18 +0000 Subject: [PATCH] Add snapshots to Hyper-V driver --- plugins/providers/hyperv/action.rb | 55 +++++++++++++++++++ .../hyperv/action/snapshot_delete.rb | 27 +++++++++ .../hyperv/action/snapshot_restore.rb | 23 ++++++++ .../providers/hyperv/action/snapshot_save.rb | 27 +++++++++ plugins/providers/hyperv/cap/snapshot_list.rb | 11 ++++ plugins/providers/hyperv/driver.rb | 19 ++++++- plugins/providers/hyperv/plugin.rb | 5 ++ .../hyperv/scripts/create_snapshot.ps1 | 8 +++ .../hyperv/scripts/delete_snapshot.ps1 | 8 +++ .../hyperv/scripts/list_snapshots.ps1 | 12 ++++ .../hyperv/scripts/restore_snapshot.ps1 | 8 +++ 11 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 plugins/providers/hyperv/action/snapshot_delete.rb create mode 100644 plugins/providers/hyperv/action/snapshot_restore.rb create mode 100644 plugins/providers/hyperv/action/snapshot_save.rb create mode 100644 plugins/providers/hyperv/cap/snapshot_list.rb create mode 100644 plugins/providers/hyperv/scripts/create_snapshot.ps1 create mode 100644 plugins/providers/hyperv/scripts/delete_snapshot.ps1 create mode 100644 plugins/providers/hyperv/scripts/list_snapshots.ps1 create mode 100644 plugins/providers/hyperv/scripts/restore_snapshot.ps1 diff --git a/plugins/providers/hyperv/action.rb b/plugins/providers/hyperv/action.rb index 61dec2a1a..1e2a19694 100644 --- a/plugins/providers/hyperv/action.rb +++ b/plugins/providers/hyperv/action.rb @@ -207,6 +207,58 @@ module VagrantPlugins end end + def self.action_snapshot_delete + Vagrant::Action::Builder.new.tap do |b| + b.use ConfigValidate + b.use Call, IsState, :not_created do |env, b2| + if env[:result] + b2.use Message, I18n.t("vagrant_hyperv.message_not_created") + next + end + + b2.use SnapshotDelete + + end + end + end + + def self.action_snapshot_restore + Vagrant::Action::Builder.new.tap do |b| + b.use ConfigValidate + b.use Call, IsState, :not_created do |env, b2| + if env[:result] + b2.use Message, I18n.t("vagrant_hyperv.message_not_created") + next + end + + b2.use action_halt + b2.use SnapshotRestore + + b2.use Call, IsEnvSet, :snapshot_delete do |env2, b3| + if env2[:result] + b3.use action_snapshot_delete + end + end + + b2.use action_start + + end + end + end + + def self.action_snapshot_save + Vagrant::Action::Builder.new.tap do |b| + b.use ConfigValidate + b.use Call, IsState, :not_created do |env, b2| + if env[:result] + b2.use Message, I18n.t("vagrant_hyperv.message_not_created") + next + end + b2.use SnapshotSave + end + end + end + # The autoload farm action_root = Pathname.new(File.expand_path("../action", __FILE__)) autoload :CheckEnabled, action_root.join("check_enabled") @@ -222,6 +274,9 @@ module VagrantPlugins autoload :NetSetVLan, action_root.join("net_set_vlan") autoload :NetSetMac, action_root.join("net_set_mac") autoload :MessageWillNotDestroy, action_root.join("message_will_not_destroy") + autoload :SnapshotDelete, action_root.join("snapshot_delete") + autoload :SnapshotRestore, action_root.join("snapshot_restore") + autoload :SnapshotSave, action_root.join("snapshot_save") end end end diff --git a/plugins/providers/hyperv/action/snapshot_delete.rb b/plugins/providers/hyperv/action/snapshot_delete.rb new file mode 100644 index 000000000..2f2492740 --- /dev/null +++ b/plugins/providers/hyperv/action/snapshot_delete.rb @@ -0,0 +1,27 @@ +module VagrantPlugins + module HyperV + module Action + class SnapshotDelete + def initialize(app, env) + @app = app + end + + def call(env) + + env[:ui].info(I18n.t( + "vagrant.actions.vm.snapshot.deleting", + name: env[:snapshot_name])) + + env[:machine].provider.driver.delete_snapshot(env[:snapshot_name]) + + env[:ui].success(I18n.t( + "vagrant.actions.vm.snapshot.deleted", + name: env[:snapshot_name])) + + @app.call(env) + + end + end + end + end +end diff --git a/plugins/providers/hyperv/action/snapshot_restore.rb b/plugins/providers/hyperv/action/snapshot_restore.rb new file mode 100644 index 000000000..cf5f0a9f9 --- /dev/null +++ b/plugins/providers/hyperv/action/snapshot_restore.rb @@ -0,0 +1,23 @@ +module VagrantPlugins + module HyperV + 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[:snapshot_name]) + + @app.call(env) + + end + end + end + end +end diff --git a/plugins/providers/hyperv/action/snapshot_save.rb b/plugins/providers/hyperv/action/snapshot_save.rb new file mode 100644 index 000000000..d81641296 --- /dev/null +++ b/plugins/providers/hyperv/action/snapshot_save.rb @@ -0,0 +1,27 @@ +module VagrantPlugins + module HyperV + module Action + class SnapshotSave + def initialize(app, env) + @app = app + end + + def call(env) + + env[:ui].info(I18n.t( + "vagrant.actions.vm.snapshot.saving", + name: env[:snapshot_name])) + + env[:machine].provider.driver.create_snapshot(env[:snapshot_name]) + + env[:ui].success(I18n.t( + "vagrant.actions.vm.snapshot.saved", + name: env[:snapshot_name])) + + @app.call(env) + + end + end + end + end +end diff --git a/plugins/providers/hyperv/cap/snapshot_list.rb b/plugins/providers/hyperv/cap/snapshot_list.rb new file mode 100644 index 000000000..adafd3514 --- /dev/null +++ b/plugins/providers/hyperv/cap/snapshot_list.rb @@ -0,0 +1,11 @@ +module VagrantPlugins + module HyperV + module Cap + module SnapshotList + def self.snapshot_list(machine) + machine.provider.driver.list_snapshots + end + end + end + end +end diff --git a/plugins/providers/hyperv/driver.rb b/plugins/providers/hyperv/driver.rb index 324599fa1..604c46bbd 100644 --- a/plugins/providers/hyperv/driver.rb +++ b/plugins/providers/hyperv/driver.rb @@ -84,7 +84,24 @@ module VagrantPlugins def net_set_mac(mac_addr) execute("set_network_mac.ps1", { VmId: vm_id, Mac: mac_addr }) end - + + def create_snapshot(snapshot_name) + execute("create_snapshot.ps1", { VmId: vm_id, SnapName: (snapshot_name) } ) + end + + def restore_snapshot(snapshot_name) + execute("restore_snapshot.ps1", { VmId: vm_id, SnapName: (snapshot_name) } ) + end + + def list_snapshots() + snaps = execute("list_snapshots.ps1", { VmID: vm_id } ) + snaps.map { |s| s['Name'] } + end + + def delete_snapshot(snapshot_name) + execute("delete_snapshot.ps1", {VmID: vm_id, SnapName: snapshot_name}) + end + protected def execute_powershell(path, options, &block) diff --git a/plugins/providers/hyperv/plugin.rb b/plugins/providers/hyperv/plugin.rb index 6865f6571..484bf2cae 100644 --- a/plugins/providers/hyperv/plugin.rb +++ b/plugins/providers/hyperv/plugin.rb @@ -27,6 +27,11 @@ module VagrantPlugins Cap::PublicAddress end + provider_capability("hyperv", "snapshot_list") do + require_relative "cap/snapshot_list" + Cap::SnapshotList + end + protected def self.init! diff --git a/plugins/providers/hyperv/scripts/create_snapshot.ps1 b/plugins/providers/hyperv/scripts/create_snapshot.ps1 new file mode 100644 index 000000000..1fa804784 --- /dev/null +++ b/plugins/providers/hyperv/scripts/create_snapshot.ps1 @@ -0,0 +1,8 @@ +Param( + [Parameter(Mandatory=$true)] + [string]$VmId, + [string]$SnapName +) + +$VM = Get-VM -Id $VmId -ErrorAction "Stop" +Checkpoint-VM $VM -SnapshotName $SnapName diff --git a/plugins/providers/hyperv/scripts/delete_snapshot.ps1 b/plugins/providers/hyperv/scripts/delete_snapshot.ps1 new file mode 100644 index 000000000..c05ccbf00 --- /dev/null +++ b/plugins/providers/hyperv/scripts/delete_snapshot.ps1 @@ -0,0 +1,8 @@ +Param( + [Parameter(Mandatory=$true)] + [string]$VmId, + [string]$SnapName +) + +$VM = Get-VM -Id $VmId -ErrorAction "Stop" +Remove-VMSnapshot $VM -Name $SnapName diff --git a/plugins/providers/hyperv/scripts/list_snapshots.ps1 b/plugins/providers/hyperv/scripts/list_snapshots.ps1 new file mode 100644 index 000000000..1a1102edd --- /dev/null +++ b/plugins/providers/hyperv/scripts/list_snapshots.ps1 @@ -0,0 +1,12 @@ +Param( + [Parameter(Mandatory=$true)] + [string]$VmId +) + +$VM = Get-VM -Id $VmId -ErrorAction "Stop" +$Snapshots = @(Get-VMSnapshot $VM | Select-Object Name) +$result = ConvertTo-json $Snapshots + +Write-Host "===Begin-Output===" +Write-Host $result +Write-Host "===End-Output===" diff --git a/plugins/providers/hyperv/scripts/restore_snapshot.ps1 b/plugins/providers/hyperv/scripts/restore_snapshot.ps1 new file mode 100644 index 000000000..d2ed43459 --- /dev/null +++ b/plugins/providers/hyperv/scripts/restore_snapshot.ps1 @@ -0,0 +1,8 @@ +Param( + [Parameter(Mandatory=$true)] + [string]$VmId, + [string]$SnapName +) + +$VM = Get-VM -Id $VmId -ErrorAction "Stop" +Restore-VMSnapshot $VM -Name $SnapName -Confirm:$false