[Kimchi-devel] [PATCH 07/10] snapshot: Revert a domain to a snapshot

Crístian Viana vianac at linux.vnet.ibm.com
Wed Nov 12 13:08:45 UTC 2014


A new command is added to revert a virtual machine to a specified
snapshot:

POST /vms/<vm-name>/snapshots/<snapshot-name>/revert

It changes the specified VM state to the exact same one as it was when
the snapshot was created.

Signed-off-by: Crístian Viana <vianac at linux.vnet.ibm.com>
---
 docs/API.md                        |  5 +++++
 src/kimchi/control/vm/snapshots.py |  1 +
 src/kimchi/i18n.py                 |  1 +
 src/kimchi/mockmodel.py            | 14 ++++++++++++++
 src/kimchi/model/vmsnapshots.py    | 10 ++++++++++
 tests/test_rest.py                 | 14 ++++++++++++++
 6 files changed, 45 insertions(+)

diff --git a/docs/API.md b/docs/API.md
index f4100c0..a918fe5 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -209,6 +209,11 @@ Represents a snapshot of the Virtual Machine's primary monitor.
                 should also be deleted: if true, the snapshot and its children
                 will be deleted; if false, only the snapshot will be deleted
                 (optional, defaults to false).
+* **POST**: See "Snapshot actions (POST)"
+
+**Snapshot Actions (POST):**
+
+* revert: Revert the domain to the given snapshot.
 
 ### Sub-resource: Current snapshot
 **URI:** /vms/*:name*/snapshots/current
diff --git a/src/kimchi/control/vm/snapshots.py b/src/kimchi/control/vm/snapshots.py
index d491015..bbebc9a 100644
--- a/src/kimchi/control/vm/snapshots.py
+++ b/src/kimchi/control/vm/snapshots.py
@@ -39,6 +39,7 @@ class VMSnapshot(Resource):
         self.ident = ident
         self.model_args = [self.vm, self.ident]
         self.uri_fmt = '/vms/%s/snapshots/%s'
+        self.revert = self.generate_action_handler('revert')
 
     @property
     def data(self):
diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py
index b1b8060..b95c707 100644
--- a/src/kimchi/i18n.py
+++ b/src/kimchi/i18n.py
@@ -319,4 +319,5 @@ messages = {
     "KCHSNAP0006E": _("Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %(err)s"),
     "KCHSNAP0007E": _("Virtual machine '%(vm)s' does not have a current snapshot."),
     "KCHSNAP0008E": _("Unable to retrieve current snapshot on virtual machine '%(vm)s'. Details: %(err)s"),
+    "KCHSNAP0009E": _("Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %(err)s"),
 }
diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py
index 33aaa33..0af6056 100644
--- a/src/kimchi/mockmodel.py
+++ b/src/kimchi/mockmodel.py
@@ -1029,6 +1029,20 @@ class MockModel(object):
         except KeyError:
             raise NotFoundError('KCHSNAP0003E', {'vm': vm_name, 'name': name})
 
+    def vmsnapshot_revert(self, vm_name, name):
+        vm = self._get_vm(vm_name)
+
+        try:
+            snap = vm.snapshots[name]
+        except KeyError:
+            raise NotFoundError('KCHSNAP0003E', {'vm': vm_name, 'name': name})
+
+        current_snapshot_name = self.currentvmsnapshot_lookup(vm_name)['name']
+        vm.snapshots[current_snapshot_name].current = False
+        snap.current = True
+
+        vm.info['state'] = snap.info['state']
+
     def tasks_get_list(self):
         with self.objstore as session:
             return session.get_list('task')
diff --git a/src/kimchi/model/vmsnapshots.py b/src/kimchi/model/vmsnapshots.py
index 8d6c296..bbcbf59 100644
--- a/src/kimchi/model/vmsnapshots.py
+++ b/src/kimchi/model/vmsnapshots.py
@@ -142,6 +142,16 @@ class VMSnapshotModel(object):
                                                    'vm': vm_name,
                                                    'err': e.message})
 
+    def revert(self, vm_name, name):
+        try:
+            vir_dom = VMModel.get_vm(vm_name, self.conn)
+            vir_snap = self.get_vmsnapshot(vm_name, name)
+            vir_dom.revertToSnapshot(vir_snap, 0)
+        except libvirt.libvirtError, e:
+            raise OperationFailed('KCHSNAP0009E', {'name': name,
+                                                   'vm': vm_name,
+                                                   'err': e.message})
+
     def get_vmsnapshot(self, vm_name, name):
         vir_dom = VMModel.get_vm(vm_name, self.conn)
 
diff --git a/tests/test_rest.py b/tests/test_rest.py
index 1129aec..b1bfbcc 100644
--- a/tests/test_rest.py
+++ b/tests/test_rest.py
@@ -443,6 +443,20 @@ class RestTests(unittest.TestCase):
         snap = json.loads(resp.read())
         self.assertEquals(snap_name, snap['name'])
 
+        # Revert to snapshot
+        resp = self.request('/vms/test-vm/snapshots/%s/revert' %
+                            params['name'], '{}', 'POST')
+        self.assertEquals(200, resp.status)
+        snap = json.loads(resp.read())
+        resp = self.request('/vms/test-vm', '{}', 'GET')
+        self.assertEquals(200, resp.status)
+        vm = json.loads(resp.read())
+        self.assertEquals(vm['state'], snap['state'])
+        resp = self.request('/vms/test-vm/snapshots/current', '{}', 'GET')
+        self.assertEquals(200, resp.status)
+        current_snap = json.loads(resp.read())
+        self.assertEquals(snap, current_snap)
+
         # Delete a snapshot
         resp = self.request('/vms/test-vm/snapshots/foobar', '{}', 'DELETE')
         self.assertEquals(404, resp.status)
-- 
1.9.3




More information about the Kimchi-devel mailing list