Class: VirtualBox::Snapshot

Inherits:
AbstractModel show all
Defined in:
lib/virtualbox/snapshot.rb

Overview

Represents a virtual machine snapshot. Snapshots allow users of virtual machines to make a lightweight “snapshot” of a virtual machine at any moment. This snapshot can be taken while the virtual machine is running or while its powered off. Snapshotting creates a differencing image for the hard drive which allows a virtual machine to restore itself to the exact state of where it was snapshotted.

# Getting Snapshots

Snapshots are accessed from the ‘current_snapshot` relationship on VM. There is no other way to access snapshots. After getting the current snapshot, you can easily traverse the tree of snapshots by accessing `parent` or `children` on the snapshot. An example follows:

vm = VirtualBox::VM.find("MyWindowsXP")
p vm.current_snapshot # the current snapshot
p vm.current_snapshot.children # The children of the current snapshot
p vm.current_snapshot.parent # The current snapshot's parent
p vm.current_snapshot.parent.parent.children # You get the idea.

# Taking a Snapshot

To take a snapshot, call the VM#take_snapshot method. Please view the documentation on that method for more information.

# Restoring a Snapshot

To restore a snapshot, call the #restore method. A simple example is shown below:

vm = VirtualBox::VM.find("MyWindowsXP")
snapshot = vm.current_snapshot.parent
snapshot.restore

Note: The VM object will not immediately update to reflect any settings changes or current snapshot changes from the restore. To grab the updates, either load a new VM object or call VM#reload.

# Deleting a Snapshot

To delete a snapshot, simply find the snapshot of interest and call it’s #destroy method. A quick example is shown below:

vm = VirtualBox::VM.find("MyWindowsXP")
snapshot = vm.current_snapshot # Grab the current snapshot
snapshot.destroy # Destroy it

Note that this doesn’t actually affect the ‘current_snapshot` relationship on the VM. To update all the proper values, you have to call VM#reload.

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from AbstractModel

#errors, errors_for_relationship, #existing_record!, #inspect, #lazy_attribute?, #lazy_relationship?, #new_record!, #new_record?, #parent_machine, #populate_attributes, #populate_relationship, #populate_relationships, reload!, #reload!, reload?, reloaded!, #save, #save!, #save_attribute, #save_changed_interface_attributes, #save_interface_attribute, #set_relationship, #validate, #write_attribute

Methods included from AbstractModel::Validatable

#__validates_extract_options, #add_error, #clear_errors, #errors, #errors_on, #full_error_messages, #valid?, #validate, #validates_format_of, #validates_inclusion_of, #validates_numericality_of, #validates_presence_of

Methods included from AbstractModel::Relatable

#destroy_relationship, #destroy_relationships, #has_relationship?, included, #lazy_relationship?, #loaded_relationship?, #populate_relationship, #populate_relationships, #read_relationship, #relationship_class, #relationship_data, #save_relationship, #save_relationships, #set_relationship

Methods included from AbstractModel::VersionMatcher

#assert_version_match, #split_version, #version_match?

Methods included from AbstractModel::Dirty

#changed?, #changes, #clear_dirty!, #ignore_dirty, #method_missing, #set_dirty!

Methods included from AbstractModel::InterfaceAttributes

#load_interface_attribute, #load_interface_attributes, #save_interface_attribute, #save_interface_attributes, #spec_to_proc

Methods included from AbstractModel::Attributable

#attributes, #has_attribute?, included, #lazy_attribute?, #loaded_attribute?, #populate_attributes, #read_attribute, #readonly_attribute?, #write_attribute

Methods included from Logger

included, #logger, #logger_output=

Constructor Details

#initialize(snapshot) ⇒ Snapshot

Initializes a new snapshot. This should never be called on its own. Snapshots should be accessed beginning with the ‘current_snapshot` on a VM, and can be further accessed by traversing the parent/child tree of the snapshot.



125
126
127
128
# File 'lib/virtualbox/snapshot.rb', line 125

def initialize(snapshot)
  write_attribute(:interface, snapshot)
  initialize_attributes(snapshot)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class VirtualBox::AbstractModel::Dirty

Class Method Details

.populate_children_relationship(caller, snapshots) ⇒ Array<Snapshot>

Populates the snapshot child tree relationship.

**This method typically won’t be used except internally.**

Returns:



110
111
112
113
114
115
116
117
118
# File 'lib/virtualbox/snapshot.rb', line 110

def populate_children_relationship(caller, snapshots)
  result = Proxies::Collection.new(caller)

  snapshots.each do |snapshot|
    result << new(snapshot)
  end

  result
end

.populate_machine_relationship(caller, machine) ⇒ Snapshot

Populates the VM relationship as the “current snapshot.”

**This method typically won’t be used except internally.**

Returns:



87
88
89
90
91
92
# File 'lib/virtualbox/snapshot.rb', line 87

def populate_machine_relationship(caller, machine)
  # The current snapshot can and will be nil if there are no snapshots
  # taken. In that case, we just return nil.
  snapshot = machine.current_snapshot
  snapshot ? new(machine.current_snapshot) : nil
end

.populate_parent_relationship(caller, parent) ⇒ Snapshot

Populates the VM relationship as the “current snapshot.”

**This method typically won’t be used except internally.**

Returns:



99
100
101
102
103
# File 'lib/virtualbox/snapshot.rb', line 99

def populate_parent_relationship(caller, parent)
  # If the parent is nil then that means the child is the root
  # snapshot
  parent ? new(parent) : nil
end

.populate_relationship(caller, data) ⇒ Object

Populates a relationship with another model. Since a snapshot can be in a relationship with multiple items, this method forwards to other methods such as populate_vm_relationship.

**This method typically won’t be used except internally.**



70
71
72
73
74
75
76
77
78
79
80
# File 'lib/virtualbox/snapshot.rb', line 70

def populate_relationship(caller, data)
  if data.is_a?(COM::Util.versioned_interface(:Machine))
    populate_machine_relationship(caller, data)
  elsif data.is_a?(Array)
    populate_children_relationship(caller, data)
  elsif data.is_a?(COM::Util.versioned_interface(:Snapshot)) || data.nil?
    populate_parent_relationship(caller, data)
  else
    raise Exceptions::Exception.new("Invalid relationship data for Snapshot: #{data}")
  end
end

Instance Method Details

#destroy(&block) ⇒ Object

Destroy a snapshot. This will physically remove the snapshot. Once this method is called, there is no undo. If this snapshot is a parent of other snapshots, the differencing image of this snapshot will be merged with the child snapshots so no data is lost. This process can sometimes take some time. This method will block while this process occurs.

If a block is given to the function, it will be yielded with a progress object which can be used to track the progress of the operation.



179
180
181
182
183
# File 'lib/virtualbox/snapshot.rb', line 179

def destroy(&block)
  machine.with_open_session do |session|
    session.console.delete_snapshot(uuid).wait(&block)
  end
end

#initialize_attributes(snapshot) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
# File 'lib/virtualbox/snapshot.rb', line 130

def initialize_attributes(snapshot)
  # Load the interface attributes
  load_interface_attributes(snapshot)

  # Clear dirtiness, since this should only be called initially and
  # therefore shouldn't affect dirtiness
  clear_dirty!

  # But this is an existing record
  existing_record!
end

#load_relationship(name) ⇒ Object

Loads the lazy relationships.

**This method should only be called internally.**



145
146
147
148
149
# File 'lib/virtualbox/snapshot.rb', line 145

def load_relationship(name)
  populate_relationship(:parent, interface.parent)
  populate_relationship(:machine, interface.machine)
  populate_relationship(:children, interface.children)
end

#restore(&block) ⇒ Object

Restore a snapshot. This will restore this snapshot’s virtual machine to the state that this snapshot represents. This method will block while the restore occurs.

If a block is given to the function, it will be yielded with a progress object which can be used to track the progress of the operation.



165
166
167
168
169
# File 'lib/virtualbox/snapshot.rb', line 165

def restore(&block)
  machine.with_open_session do |session|
    session.console.restore_snapshot(interface).wait(&block)
  end
end

#time_stampObject

Timestamp that the snapshot was taken. This method overwrites the typical attribute so it can return a Time object.



153
154
155
156
157
# File 'lib/virtualbox/snapshot.rb', line 153

def time_stamp
  # Seconds, microseconds, since the time stamp is in milliseconds
  value = read_attribute(:time_stamp)
  Time.at(value / 1000, (value % 1000) * 1000)
end