blob: 153d339fc5bc4e4e7df69fff09c7391890883c02 [file] [log] [blame]
Jiri Broulikf8f96942018-02-15 10:03:42 +01001package com.mirantis.mk
2
3/**
4 *
5 * Virsh functions
6 *
7 */
8
9/**
10 * Ensures that the live snapshot exists
11 *
12 * @param nodeProvider KVM node that hosts the VM
13 * @param target Unique identification of the VM being snapshoted without domain (for ex. ctl01)
14 * @param snapshotName Snapshot name
15 * @param path Path where snapshot image and dumpxml are being put
16 * @param diskName Disk name of the snapshot
17 */
18def liveSnapshotPresent(master, nodeProvider, target, snapshotName, path='/var/lib/libvirt/images', diskName='vda') {
19 def salt = new com.mirantis.mk.Salt()
20 def common = new com.mirantis.mk.Common()
21 def snapshotPresent = ""
22 def domain = salt.getDomainName(master)
23 try {
24 snapshotPresent = salt.getReturnValues(salt.cmdRun(master, "${nodeProvider}*", "virsh snapshot-list ${target}.${domain} | grep ${snapshotName}")).split("\n")[0]
25 } catch (Exception er) {
26 common.infoMsg('snapshot not present')
27 }
28 if (!snapshotPresent.contains(snapshotName)) {
29 def dumpxmlPresent = ''
30 try {
31 dumpxmlPresent = salt.getReturnValues(salt.cmdRun(master, "${nodeProvider}*", "ls -la ${path}/${target}.${domain}.xml")).split("\n")[0]
32 } catch (Exception er) {
33 common.infoMsg('dumpxml file not present')
34 }
35 if (!dumpxmlPresent?.trim()) {
36 salt.cmdRun(master, "${nodeProvider}*", "virsh dumpxml ${target}.${domain} > ${path}/${target}.${domain}.xml")
37 }
38 salt.cmdRun(master, "${nodeProvider}*", "virsh snapshot-create-as --domain ${target}.${domain} ${snapshotName} --diskspec ${diskName},file=${path}/${target}.${domain}.${snapshotName}.qcow2 --disk-only --atomic")
39 }
40}
41
42/**
43 * Ensures that the live snapshot does not exist
44 *
45 * @param nodeProvider KVM node that hosts the VM
46 * @param target Unique identification of the VM being snapshoted without domain (for ex. ctl01)
47 * @param snapshotName Snapshot name
48 * @param path Path where snapshot image and dumpxml are being put
49 */
50def liveSnapshotAbsent(master, nodeProvider, target, snapshotName, path='/var/lib/libvirt/images') {
51 def salt = new com.mirantis.mk.Salt()
52 def common = new com.mirantis.mk.Common()
53 def domain = salt.getDomainName(master)
54 try {
55 salt.cmdRun(master, "${nodeProvider}*", "virsh snapshot-delete ${target}.${domain} --metadata ${snapshotName}")
56 } catch (Exception e) {
57 common.warningMsg('Snapshot ${snapshotName} for ${target}.${domain} does not exist or failed to be removed')
58 }
59 try {
60 salt.runSaltProcessStep(master, "${nodeProvider}*", 'file.remove', ["${path}/${target}.${domain}.${snapshotName}.qcow2"], null, true)
61 } catch (Exception e) {
62 common.warningMsg('Snapshot ${snapshotName} qcow2 file for ${target}.${domain} does not exist or failed to be removed')
63 }
64 try {
65 salt.runSaltProcessStep(master, "${nodeProvider}*", 'file.remove', ["${path}/${target}.${domain}.xml"], null, true)
66 } catch (Exception e) {
67 common.warningMsg('Dumpxml file for ${target}.${domain} does not exist or failed to be removed')
68 }
69}
70
71/**
72 * Rollback
73 *
74 * @param nodeProvider KVM node that hosts the VM
75 * @param target Unique identification of the VM being snapshoted without domain (for ex. ctl01)
76 * @param snapshotName Snapshot name
77 * @param path Path where snapshot image and dumpxml are being put
78 */
79def liveSnapshotRollback(master, nodeProvider, target, snapshotName, path='/var/lib/libvirt/images') {
80 def salt = new com.mirantis.mk.Salt()
81 def common = new com.mirantis.mk.Common()
82 def domain = salt.getDomainName(master)
Jiri Broulik743c0ab2018-02-15 14:32:03 +010083 salt.runSaltProcessStep(master, "${nodeProvider}*", 'virt.destroy', ["${target}.${domain}"], null, true)
84 salt.cmdRun(master, "${nodeProvider}*", "virsh define ${path}/${target}.${domain}.xml")
Jiri Broulikf8f96942018-02-15 10:03:42 +010085 liveSnapshotAbsent(master, nodeProvider, target, snapshotName, path)
Jiri Broulik743c0ab2018-02-15 14:32:03 +010086 salt.runSaltProcessStep(master, "${nodeProvider}*", 'virt.start', ["${target}.${domain}"], null, true)
Jiri Broulikf8f96942018-02-15 10:03:42 +010087}
88
89/**
90 * Merge snapshot while instance is running
91 *
92 * @param nodeProvider KVM node that hosts the VM
93 * @param target Unique identification of the VM being snapshoted without domain (for ex. ctl01)
94 * @param snapshotName Snapshot name
95 * @param path Path where snapshot image and dumpxml are being put
96 * @param diskName Disk name of the snapshot
97 */
98def liveSnapshotMerge(master, nodeProvider, target, snapshotName, path='/var/lib/libvirt/images', diskName='vda') {
99 def salt = new com.mirantis.mk.Salt()
100 def common = new com.mirantis.mk.Common()
101 def domain = salt.getDomainName(master)
102 try {
Jiri Broulik743c0ab2018-02-15 14:32:03 +0100103 salt.cmdRun(master, "${nodeProvider}*", "virsh blockcommit ${target}.${domain} ${diskName} --active --verbose --pivot")
Jiri Broulikf8f96942018-02-15 10:03:42 +0100104 try {
Jiri Broulik743c0ab2018-02-15 14:32:03 +0100105 salt.cmdRun(master, "${nodeProvider}*", "virsh snapshot-delete ${target}.${domain} --metadata ${snapshotName}")
Jiri Broulikf8f96942018-02-15 10:03:42 +0100106 } catch (Exception e) {
107 common.warningMsg('Snapshot ${snapshotName} for ${target}.${domain} does not exist or failed to be removed')
108 }
109 try {
Jiri Broulik743c0ab2018-02-15 14:32:03 +0100110 salt.runSaltProcessStep(master, "${nodeProvider}*", 'file.remove', ["${path}/${target}.${domain}.${snapshotName}.qcow2"], null, true)
Jiri Broulikf8f96942018-02-15 10:03:42 +0100111 } catch (Exception e) {
112 common.warningMsg('Snapshot ${snapshotName} qcow2 file for ${target}.${domain} does not exist or failed to be removed')
113 }
114 try {
Jiri Broulik743c0ab2018-02-15 14:32:03 +0100115 salt.runSaltProcessStep(master, "${nodeProvider}*", 'file.remove', ["${path}/${target}.${domain}.xml"], null, true)
Jiri Broulikf8f96942018-02-15 10:03:42 +0100116 } catch (Exception e) {
117 common.warningMsg('Dumpxml file for ${target}.${domain} does not exist or failed to be removed')
118 }
119 } catch (Exception e) {
120 common.errorMsg("The live snapshoted VM ${target}.${domain} failed to be merged, trying to fix it")
121 checkLiveSnapshotMerge(master, nodeProvider, target, snapshotName, path, diskName)
122 }
123}
124
125
126/**
127 * Check live snapshot merge failure due to known qemu issue not receiving message about merge completion
128 *
129 * @param nodeProvider KVM node that hosts the VM
130 * @param target Unique identification of the VM being snapshoted without domain (for ex. ctl01)
131 * @param snapshotName Snapshot name
132 * @param path Path where snapshot image and dumpxml are being put
133 * @param diskName Disk name of the snapshot
134 */
135def checkLiveSnapshotMerge(master, nodeProvider, target, snapshotName, path='/var/lib/libvirt/images', diskName='vda') {
136 def salt = new com.mirantis.mk.Salt()
137 def domain = salt.getDomainName(master)
Jiri Broulik743c0ab2018-02-15 14:32:03 +0100138 def out = salt.getReturnValues(salt.cmdRun(master, "${nodeProvider}*", "virsh blockjob ${target}.${domain} ${diskName} --info"))
Jiri Broulikf8f96942018-02-15 10:03:42 +0100139 if (out.contains('Block Commit')) {
Jiri Broulik743c0ab2018-02-15 14:32:03 +0100140 def blockJobs = salt.getReturnValues(salt.cmdRun(master, "{nodeProvider}*", "virsh qemu-monitor-command ${target}.${domain} --pretty -- '{ \"execute\": \"query-block-jobs\" }'"))
Jiri Broulikf8f96942018-02-15 10:03:42 +0100141 if (blockJobs.contains('offset')) {
142 // if Block Commit hangs on 100 and check offset - len = 0, then it is safe to merge the image
143 input message: "Please check if offset - len = 0, If so run: virsh qemu-monitor-command ${target}.${domain} --pretty -- '{ \"execute\": \"block-job-complete\", \"arguments\": { \"device\": \"drive-virtio-disk0\" } }', then virsh define ${path}/${target}.${domain}.xml, then virsh snapshot-delete ${target}.${domain} --metadata ${snapshotName} and remove ${path}/${target}.${domain}.${snapshotName}.qcow2 file. When you resolve this issue click on PROCEED."
144 }
145 }
146}
147