vagrant-zz-multiprovider-snap 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md ADDED
@@ -0,0 +1,78 @@
1
+ Vagrant Multi-Provder Snap
2
+ ==========================
3
+
4
+ Description
5
+ -----------
6
+
7
+ This Vagrant plugin provides a consistent interface to taking snapshots of
8
+ running Vagrant boxes. It currently supports the following providers:
9
+
10
+ * VirtualBox
11
+ * VMWare Fusion (via the commercial VMWare plugin)
12
+
13
+
14
+ Installation
15
+ ------------
16
+
17
+ The easiest way to install this plugin is via the published gem.
18
+
19
+ ```
20
+ vagrant plugin install vagrant-zz-multiprovider-snap
21
+ ```
22
+
23
+ (The 'zz' in the gem name is a workaround for a bug in Vagrant plugin loading
24
+ which prevents the mixins in this module from working correctly - we need to
25
+ force this plugin to be loaded after the vmware plugin otherwise this fails)
26
+
27
+
28
+ Usage
29
+ -----
30
+
31
+ Typical usage:
32
+
33
+ * Take a new snapshot
34
+ ```vagrant snap take [vm]```
35
+
36
+ * Roll back to the last snapshot
37
+ ```vagrant snap rollback [vm]```
38
+
39
+ * List snapshots
40
+ ```vagrant snap list [vm]```
41
+
42
+ Limitations
43
+ -----------
44
+
45
+ It's currently not possible to do any of the following:
46
+
47
+ * Give a custom snapshot name
48
+ * Roll back to a specific named snapshot
49
+ * Disable snapshotting
50
+
51
+ My own requirements don't include these features, but I could be tempted to
52
+ add them if anyone would find them useful.
53
+
54
+
55
+ Hacking
56
+ -------
57
+
58
+ Working on this module is a little tricky because of the obfuscation used by
59
+ the commercial VMWare module. The following approach should get you up and
60
+ running - although it's a bundler environment, you'll also need a packaged
61
+ Vagrant install in order to get access to the rgloader libraries.
62
+
63
+ ```
64
+ git@github.com:scalefactory/vagrant-multiprovider-snap.git
65
+ cd vagrant-multiprovider-snap
66
+ cp ~/.vagrant.d/license-vagrant-vmware-fusion.lic .
67
+ bundle install
68
+ bundle install --deployment
69
+ ```
70
+
71
+ You should now find that ```bundle exec vagrant status``` returns correctly,
72
+ and you can hack on the code from there.
73
+
74
+ Once you've made changes that you're happy with, I'd recommend using
75
+ ```rake build``` to create a gem, then installing that into your packaged
76
+ Vagrant install since some things which work in the bundler environment might
77
+ not work as expected in the packaged copy due to differences in how the plugins
78
+ are handled.
@@ -0,0 +1,54 @@
1
+ require 'optparse'
2
+ require 'vagrant'
3
+
4
+ module VagrantSnap
5
+
6
+ module Command
7
+
8
+ class List < Vagrant.plugin("2", :command)
9
+
10
+ def execute
11
+
12
+ options = {}
13
+
14
+ opts = OptionParser.new do |o|
15
+ o.banner = "Usage: vagrant snap list [vm-name]"
16
+ o.separator ""
17
+ end
18
+
19
+ argv = parse_options(opts)
20
+ return if !argv
21
+
22
+ results = []
23
+
24
+ with_target_vms(argv) do |machine|
25
+
26
+ results << "#{machine.name.to_s}"
27
+
28
+ snaps = machine.provider.driver.snapshot_list
29
+
30
+ if snaps.length == 0
31
+ results << " (none)"
32
+ else
33
+ snaps.each do |snap|
34
+ results << " + #{snap}"
35
+ end
36
+ end
37
+
38
+ results << "\n"
39
+
40
+ end
41
+
42
+ @env.ui.info(I18n.t("vagrant_snap.commands.list.output",
43
+ :snapshots => results.join("\n")),
44
+ :prefix => false)
45
+
46
+ 0
47
+
48
+ end
49
+
50
+ end
51
+
52
+ end
53
+
54
+ end
@@ -0,0 +1,36 @@
1
+ require 'optparse'
2
+ require 'vagrant'
3
+
4
+ module VagrantSnap
5
+
6
+ module Command
7
+
8
+ class Rollback < Vagrant.plugin("2", :command)
9
+
10
+ def execute
11
+
12
+ options = {}
13
+
14
+ opts = OptionParser.new do |o|
15
+ o.banner = "Usage: vagrant snap rollback [vm-name]"
16
+ o.separator ""
17
+ end
18
+
19
+ argv = parse_options(opts)
20
+ return if !argv
21
+
22
+ with_target_vms(argv) do |vm|
23
+
24
+ vm.action(:snapshot_rollback)
25
+
26
+ end
27
+
28
+ 0
29
+
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,73 @@
1
+ require 'optparse'
2
+
3
+ module VagrantSnap
4
+
5
+ module Command
6
+
7
+ class Root < Vagrant.plugin("2", :command)
8
+
9
+ def initialize(argv, env)
10
+
11
+ super
12
+
13
+ @main_args, @sub_command, @sub_args = split_main_and_subcommand(argv)
14
+
15
+ @subcommands = Vagrant::Registry.new
16
+
17
+ @subcommands.register(:take) do
18
+ require_relative "take"
19
+ Take
20
+ end
21
+
22
+ @subcommands.register(:rollback) do
23
+ require_relative "rollback"
24
+ Rollback
25
+ end
26
+
27
+ @subcommands.register(:list) do
28
+ require_relative "list"
29
+ List
30
+ end
31
+
32
+
33
+ end
34
+
35
+ def execute
36
+
37
+ if @main_args.include?("-h") || @main_args.include?("--help")
38
+ return help
39
+ end
40
+
41
+ command_class = @subcommands.get(@sub_command.to_sym) if @sub_command
42
+ return help if !command_class || !@sub_command
43
+
44
+ # Initialize and execute the command class
45
+ command_class.new(@sub_args, @env).execute
46
+
47
+ end
48
+
49
+ def help
50
+ opts = OptionParser.new do |opts|
51
+ opts.banner = 'Usage: vagrant snap <command> [<args>]'
52
+ opts.separator ""
53
+ opts.separator "Available subcommands:"
54
+
55
+ keys = []
56
+ @subcommands.each { |key, value| keys << key.to_s }
57
+
58
+ keys.sort.each do |key|
59
+ opts.separator " #{key}"
60
+ end
61
+
62
+ opts.separator ""
63
+ opts.separator "For help on any individual command run 'vagrant snap COMMAND -h'"
64
+ end
65
+
66
+ @env.ui.info(opts.help, :prefix => false)
67
+ end
68
+
69
+ end
70
+
71
+ end
72
+
73
+ end
@@ -0,0 +1,36 @@
1
+ require 'optparse'
2
+ require 'vagrant'
3
+
4
+ module VagrantSnap
5
+
6
+ module Command
7
+
8
+ class Take < Vagrant.plugin("2", :command)
9
+
10
+ def execute
11
+
12
+ options = {}
13
+
14
+ opts = OptionParser.new do |o|
15
+ o.banner = "Usage: vagrant snap take [vm-name]"
16
+ o.separator ""
17
+ end
18
+
19
+ argv = parse_options(opts)
20
+ return if !argv
21
+
22
+ with_target_vms(argv) do |vm|
23
+
24
+ vm.action(:snapshot_take)
25
+
26
+ end
27
+
28
+ 0
29
+
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,30 @@
1
+ require 'vagrant'
2
+
3
+ module VagrantSnap
4
+ class Plugin < Vagrant.plugin("2")
5
+
6
+ require_relative "command/root"
7
+ require_relative "providers/virtualbox/action"
8
+ require_relative "providers/virtualbox/driver/base"
9
+ require_relative "providers/vmware_fusion/action"
10
+ require_relative "providers/vmware_fusion/driver/base"
11
+
12
+ name "snap command"
13
+
14
+ description <<-DESC
15
+ This command provides snapshot features across multiple
16
+ Vagrant providers
17
+ DESC
18
+
19
+ command("snap") do
20
+ setup_i18n
21
+ Command::Root
22
+ end
23
+
24
+ def self.setup_i18n
25
+ I18n.load_path << File.expand_path("locales/en.yml", VagrantSnap.source_root)
26
+ I18n.reload!
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,33 @@
1
+ module VagrantPlugins
2
+
3
+ module ProviderVirtualBox
4
+
5
+ module Action
6
+
7
+ class SnapshotRollback
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+
15
+ env[:ui].info I18n.t("vagrant_snap.actions.vm.snapshot_rollback.rolling_back")
16
+
17
+ # Snapshot rollback involves powering off and on the VM
18
+ # so we need to find the gui state
19
+ boot_mode = env[:machine].provider_config.gui ? "gui" : "headless"
20
+
21
+ env[:machine].provider.driver.snapshot_rollback(boot_mode)
22
+
23
+ @app.call(env)
24
+
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,28 @@
1
+ module VagrantPlugins
2
+
3
+ module ProviderVirtualBox
4
+
5
+ module Action
6
+
7
+ class SnapshotTake
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+
15
+ env[:ui].info I18n.t("vagrant_snap.actions.vm.snapshot_take.taking")
16
+ env[:machine].provider.driver.snapshot_take
17
+
18
+ @app.call(env)
19
+
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,46 @@
1
+ require "vagrant/action/builder"
2
+
3
+ module VagrantPlugins
4
+
5
+ module ProviderVirtualBox
6
+
7
+ module Action
8
+
9
+ autoload :SnapshotTake, File.expand_path("../action/snapshot_take.rb", __FILE__)
10
+ autoload :SnapshotRollback, File.expand_path("../action/snapshot_rollback.rb", __FILE__)
11
+
12
+ def self.action_snapshot_take
13
+ Vagrant::Action::Builder.new.tap do |b|
14
+ b.use CheckVirtualbox
15
+ b.use Call, Created do |env, b2|
16
+ if env[:result]
17
+ b2.use CheckAccessible
18
+ b2.use SnapshotTake
19
+ else
20
+ b2.use MessageNotCreated
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ def self.action_snapshot_rollback
27
+ Vagrant::Action::Builder.new.tap do |b|
28
+ b.use CheckVirtualbox
29
+ b.use Call, Created do |env, b2|
30
+ if env[:result]
31
+ b2.use CheckAccessible
32
+ b2.use SnapshotRollback
33
+ else
34
+ b2.use MessageNotCreated
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
44
+ end
45
+
46
+
@@ -0,0 +1,38 @@
1
+ module VagrantPlugins
2
+
3
+ module ProviderVirtualBox
4
+
5
+ module Driver
6
+
7
+ class Base
8
+
9
+ def snapshot_take
10
+ execute("snapshot", @uuid, "take", "vagrant-snap-#{Time.now.to_i}", "--pause")
11
+ end
12
+
13
+ def snapshot_rollback(bootmode)
14
+ halt
15
+ sleep 2 # race condition on locked VMs otherwise?
16
+ execute("snapshot", @uuid, "restore", snapshot_list.first)
17
+ start(bootmode)
18
+ end
19
+
20
+ def snapshot_list
21
+ # XXX blows up if no snapshots on the VM - how to prevent this?
22
+ info = execute("showvminfo", @uuid, "--machinereadable")
23
+ snapshots = []
24
+ info.split("\n").each do |line|
25
+ if line =~ /^SnapshotName="(.+?)"$/
26
+ snapshots << $1.to_s
27
+ end
28
+ end
29
+ snapshots
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -0,0 +1,33 @@
1
+ module HashiCorp
2
+
3
+ module VagrantVMwarefusion
4
+
5
+ module Action
6
+
7
+ class SnapshotRollback
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+
15
+ env[:ui].info I18n.t("vagrant_snap.actions.vm.snapshot_rollback.rolling_back")
16
+
17
+ # Snapshot rollback involves powering off and on the VM
18
+ # so we need to find the gui state
19
+ boot_mode = env[:machine].provider_config.gui ? "gui" : "headless"
20
+
21
+ env[:machine].provider.driver.snapshot_rollback(boot_mode)
22
+
23
+ @app.call(env)
24
+
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,28 @@
1
+ module HashiCorp
2
+
3
+ module VagrantVMwarefusion
4
+
5
+ module Action
6
+
7
+ class SnapshotTake
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+
15
+ env[:ui].info I18n.t("vagrant_snap.actions.vm.snapshot_take.taking")
16
+ env[:machine].provider.driver.snapshot_take
17
+
18
+ @app.call(env)
19
+
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,44 @@
1
+ require "vagrant/action/builder"
2
+
3
+ module HashiCorp
4
+
5
+ module VagrantVMwarefusion
6
+
7
+ module Action
8
+
9
+ autoload :SnapshotTake, File.expand_path("../action/snapshot_take.rb", __FILE__)
10
+ autoload :SnapshotRollback, File.expand_path("../action/snapshot_rollback.rb", __FILE__)
11
+
12
+ def self.action_snapshot_take
13
+ Vagrant::Action::Builder.new.tap do |b|
14
+ b.use CheckVMware
15
+ b.use Call, Created do |env, b2|
16
+ if env[:result]
17
+ b2.use SnapshotTake
18
+ else
19
+ b2.use MessageNotCreated
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ def self.action_snapshot_rollback
26
+ Vagrant::Action::Builder.new.tap do |b|
27
+ b.use CheckVMware
28
+ b.use Call, Created do |env, b2|
29
+ if env[:result]
30
+ b2.use SnapshotRollback
31
+ else
32
+ b2.use MessageNotCreated
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
44
+
@@ -0,0 +1,34 @@
1
+ module HashiCorp
2
+
3
+ module VagrantVMwarefusion
4
+
5
+ module Driver
6
+
7
+ class Fusion
8
+
9
+ def snapshot_take
10
+ vmrun("snapshot", "#{vmx_path}", "vagrant-snap-#{Time.now.to_i}")
11
+ end
12
+
13
+ def snapshot_rollback(bootmode)
14
+ vmrun("revertToSnapshot", "#{vmx_path}", snapshot_list.first)
15
+ start
16
+ end
17
+
18
+ def snapshot_list
19
+ snapshots = []
20
+ vmrun("listSnapshots", "#{vmx_path}").stdout.split("\n").each do |line|
21
+ if line =~ /^vagrant-snap-/
22
+ snapshots << line
23
+ end
24
+ end
25
+ snapshots.sort
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,5 @@
1
+ module Vagrant
2
+ module Snap
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ require "vagrant-multiprovider-snap/version"
2
+ require "vagrant-multiprovider-snap/plugin"
3
+
4
+ module VagrantSnap
5
+ def self.source_root
6
+ @source_root ||= Pathname.new(File.expand_path("../../", __FILE__))
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require "vagrant-multiprovider-snap/version"
2
+ require "vagrant-multiprovider-snap/plugin"
3
+
4
+ module VagrantSnap
5
+ def self.source_root
6
+ @source_root ||= Pathname.new(File.expand_path("../../", __FILE__))
7
+ end
8
+ end
data/locales/en.yml ADDED
@@ -0,0 +1,19 @@
1
+ en:
2
+ vagrant_snap:
3
+ commands:
4
+ list:
5
+ output: |-
6
+ Current available snapshots by VM:
7
+
8
+ %{snapshots}
9
+
10
+ actions:
11
+ vm:
12
+ snapshot_take:
13
+ taking: |-
14
+ Taking snapshot.
15
+ snapshot_rollback:
16
+ rolling_back: |-
17
+ Rolling back to previous snapshot
18
+
19
+
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "vagrant-multiprovider-snap/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "vagrant-zz-multiprovider-snap"
7
+ s.version = Vagrant::Snap::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Jon Topper"]
10
+ s.email = ["jon@scalefactory.com"]
11
+ s.homepage = "http://github.com/scalefactory/vagrant-multiprovider-snap"
12
+
13
+ s.summary = %q{Multi-provider snapshots for Vagrant}
14
+ s.description = %q{Multi-provider snapshots for Vagrant}
15
+
16
+ s.rubyforge_project = "vagrant-multiprovider-snap"
17
+
18
+ files = `git ls-files`.split("\n")
19
+ ignore = %w{rgloader/* Gemfile Rakefile Vagrantfile .gitignore}
20
+
21
+ files.delete_if do |f|
22
+ ignore.any? do |i|
23
+ File.fnmatch(i, f, File::FNM_PATHNAME) ||
24
+ File.fnmatch(i, File.basename(f), File::FNM_PATHNAME)
25
+ end
26
+ end
27
+
28
+ s.files = files
29
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
30
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
31
+ s.require_paths = ["lib"]
32
+
33
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vagrant-zz-multiprovider-snap
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jon Topper
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-06-12 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Multi-provider snapshots for Vagrant
15
+ email:
16
+ - jon@scalefactory.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - README.md
22
+ - lib/vagrant-multiprovider-snap.rb
23
+ - lib/vagrant-multiprovider-snap/command/list.rb
24
+ - lib/vagrant-multiprovider-snap/command/rollback.rb
25
+ - lib/vagrant-multiprovider-snap/command/root.rb
26
+ - lib/vagrant-multiprovider-snap/command/take.rb
27
+ - lib/vagrant-multiprovider-snap/plugin.rb
28
+ - lib/vagrant-multiprovider-snap/providers/virtualbox/action.rb
29
+ - lib/vagrant-multiprovider-snap/providers/virtualbox/action/snapshot_rollback.rb
30
+ - lib/vagrant-multiprovider-snap/providers/virtualbox/action/snapshot_take.rb
31
+ - lib/vagrant-multiprovider-snap/providers/virtualbox/driver/base.rb
32
+ - lib/vagrant-multiprovider-snap/providers/vmware_fusion/action.rb
33
+ - lib/vagrant-multiprovider-snap/providers/vmware_fusion/action/snapshot_rollback.rb
34
+ - lib/vagrant-multiprovider-snap/providers/vmware_fusion/action/snapshot_take.rb
35
+ - lib/vagrant-multiprovider-snap/providers/vmware_fusion/driver/base.rb
36
+ - lib/vagrant-multiprovider-snap/version.rb
37
+ - lib/vagrant-zz-multiprovider-snap.rb
38
+ - locales/en.yml
39
+ - vagrant-multiprovider-snap.gemspec
40
+ homepage: http://github.com/scalefactory/vagrant-multiprovider-snap
41
+ licenses: []
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ! '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubyforge_project: vagrant-multiprovider-snap
60
+ rubygems_version: 1.8.11
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: Multi-provider snapshots for Vagrant
64
+ test_files: []