Class: Linecook::Commands::Snapshot

Inherits:
VirtualBoxCommand show all
Defined in:
lib/linecook/commands/snapshot.rb

Overview

:startdoc::desc take a vm snapshop

Takes the specified snapshot of one or more VirtualBox virtual machines. By default all virtual machines configured in config/ssh will have a snapshot taken. If the snapshot name is already taken, the previous snapshot will be renamed.

Snapshot can also reset a hierarchy of renamed snapshots using the –reset flag. For example, if there exists a snapshot ‘CURRENT’ then these command will leave you with snapshots CURRENT_0 (the original), CURRENT_1, and CURRENT (the latest):

linecook snapshot CURRENT
linecook snapshot CURRENT

To reset:

linecook snapshot --reset CURRENT

After which there will only be a single ‘CURRENT’ snapshot, which corresponds to the original snapshot.

Constant Summary

Constants inherited from VirtualBoxCommand

VirtualBoxCommand::HOST_REGEXP

Instance Method Summary collapse

Methods inherited from VirtualBoxCommand

#discardstate, #each_host, #each_vm_name, #host_list, #host_map, #load_hosts, #resolve_vm_names, #restore, #running?, #share, #ssh, #ssh!, #ssh_config_file=, #start, #start_ssh_socket, #stop

Methods included from Linecook::CommandUtils

#sh, #sh!

Methods inherited from Linecook::Command

#call, help, #initialize, parse, signature

Constructor Details

This class inherits a constructor from Linecook::Command

Instance Method Details

#parse_snapshots(vm_name) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/linecook/commands/snapshot.rb', line 42

def parse_snapshots(vm_name)
  info = `VBoxManage -q showvminfo #{vm_name}`
  snapshots = {}

  stack = [{}]
  parent  = nil

  info.each_line do |line|
    next unless line =~ /^(\s+)Name\: (.*?) \(/
    depth = $1.length / 3
    name = $2

    if depth > stack.length
      stack.push stack.last[parent]
    elsif depth < stack.length
      stack.pop
    end

    snapshot = {}
    snapshots[name]  = snapshot
    stack.last[name] = snapshot
    parent = name
  end

  snapshots
end

#process(snapshot, *hosts) ⇒ Object



31
32
33
34
35
36
37
38
39
40
# File 'lib/linecook/commands/snapshot.rb', line 31

def process(snapshot, *hosts)
  vm_names = resolve_vm_names(hosts)
  each_vm_name(vm_names) do |vm_name|
    if reset
      reset_snapshot(vm_name, snapshot)
    else
      snapshot(vm_name, snapshot)
    end
  end
end

#reset_snapshot(vm_name, snapshot) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/linecook/commands/snapshot.rb', line 69

def reset_snapshot(vm_name, snapshot)
  stop(vm_name) if running?(vm_name)

  snapshot = snapshot.upcase
  restore(vm_name, snapshot)

  snapshots = parse_snapshots(vm_name)
  parent = snapshots.keys.select {|key| key =~ /\A#{snapshot}(?:_\d+)\z/ }.first
  parent ||= snapshot

  children = snapshots[parent]
  children.each do |key, value|
    inside_out_each(key, value) do |child|
      sh! "VBoxManage -q snapshot #{vm_name} delete #{child}"
    end
  end

  unless parent == snapshot
    sh! "VBoxManage -q snapshot #{vm_name} edit #{parent} --name #{snapshot}"
  end
end

#snapshot(vm_name, snapshot) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
# File 'lib/linecook/commands/snapshot.rb', line 91

def snapshot(vm_name, snapshot)
  snapshot = snapshot.upcase
  snapshots = parse_snapshots(vm_name)

  count = snapshots.keys.grep(/\A#{snapshot}(?:_|\z)/).length
  if count > 0
    sh! "VBoxManage -q snapshot #{vm_name} edit #{snapshot} --name #{snapshot}_#{count - 1}"
  end

  sh! "VBoxManage -q snapshot #{vm_name} take #{snapshot} --pause"
end