Skip to content

Commit d5e3548

Browse files
committed
Merge pull request #10 from elordahl/snapshot_deletion
Adding snapshot deletion functionality
2 parents 6ec7697 + d76cc36 commit d5e3548

File tree

9 files changed

+234
-8
lines changed

9 files changed

+234
-8
lines changed

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@
6666
<type>jar</type>
6767
</dependency>
6868
<dependency>
69-
<groupId>com.cloudbees.thirdparty</groupId>
69+
<groupId>com.vmware</groupId>
7070
<artifactId>vijava</artifactId>
71-
<version>5.0.0</version>
71+
<version>5.1</version>
7272
</dependency>
7373
</dependencies>
7474
</project>
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/* Copyright 2013, MANDIANT, Eric Lordahl
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
package org.jenkinsci.plugins.vsphere.builders;
16+
17+
import hudson.EnvVars;
18+
import hudson.Extension;
19+
import hudson.Launcher;
20+
import hudson.model.BuildListener;
21+
import hudson.model.AbstractBuild;
22+
import hudson.util.FormValidation;
23+
24+
import java.io.IOException;
25+
import java.io.PrintStream;
26+
27+
import javax.servlet.ServletException;
28+
29+
import org.jenkinsci.plugins.vsphere.VSphereBuildStep;
30+
import org.jenkinsci.plugins.vsphere.tools.VSphere;
31+
import org.jenkinsci.plugins.vsphere.tools.VSphereException;
32+
import org.jenkinsci.plugins.vsphere.tools.VSphereLogger;
33+
import org.kohsuke.stapler.DataBoundConstructor;
34+
import org.kohsuke.stapler.QueryParameter;
35+
36+
import com.vmware.vim25.mo.VirtualMachineSnapshot;
37+
38+
public class DeleteSnapshot extends VSphereBuildStep {
39+
40+
private final String vm;
41+
private final String snapshotName;
42+
private final boolean consolidate;
43+
private final boolean failOnNoExist;
44+
45+
@DataBoundConstructor
46+
public DeleteSnapshot(final String vm, final String snapshotName, final boolean consolidate, final boolean failOnNoExist) throws VSphereException {
47+
this.vm = vm;
48+
this.snapshotName = snapshotName;
49+
this.consolidate = consolidate;
50+
this.failOnNoExist = failOnNoExist;
51+
}
52+
53+
public String getVm() {
54+
return vm;
55+
}
56+
57+
public String getSnapshotName() {
58+
return snapshotName;
59+
}
60+
61+
public boolean isConsolidate() {
62+
return consolidate;
63+
}
64+
65+
public boolean isFailOnNoExist() {
66+
return failOnNoExist;
67+
}
68+
69+
public boolean perform(final AbstractBuild<?, ?> build, Launcher launcher, final BuildListener listener) throws VSphereException {
70+
return deleteSnapshot(build, launcher, listener);
71+
//TODO throw AbortException instead of returning value
72+
}
73+
74+
private boolean deleteSnapshot(final AbstractBuild<?, ?> build, Launcher launcher, final BuildListener listener) throws VSphereException{
75+
PrintStream jLogger = listener.getLogger();
76+
EnvVars env;
77+
try {
78+
env = build.getEnvironment(listener);
79+
} catch (Exception e) {
80+
throw new VSphereException(e);
81+
}
82+
83+
env.overrideAll(build.getBuildVariables()); // Add in matrix axes..
84+
String expandedSnap = env.expand(snapshotName);
85+
String expandedVm = env.expand(vm);
86+
87+
VSphereLogger.vsLogger(jLogger, "Deleting snapshot \""+expandedSnap+"\" of VM "+expandedVm+"...");
88+
vsphere.deleteSnapshot(expandedVm, expandedSnap, consolidate, failOnNoExist);
89+
VSphereLogger.vsLogger(jLogger, "Complete.");
90+
91+
return true;
92+
}
93+
94+
@Extension
95+
public static class DeleteSnapshotDescriptor extends VSphereBuildStepDescriptor {
96+
97+
@Override
98+
public String getDisplayName() {
99+
return Messages.vm_title_DeleteSnapshot();
100+
}
101+
102+
public FormValidation doCheckVm(@QueryParameter String value)
103+
throws IOException, ServletException {
104+
105+
if (value.length() == 0)
106+
return FormValidation.error(Messages.validation_required("the VM name"));
107+
return FormValidation.ok();
108+
}
109+
110+
public FormValidation doCheckSnapshotName(@QueryParameter String value)
111+
throws IOException, ServletException {
112+
113+
if (value.length() == 0)
114+
return FormValidation.error(Messages.validation_required("the snapshot name"));
115+
return FormValidation.ok();
116+
}
117+
118+
public FormValidation doTestData(@QueryParameter String serverName,
119+
@QueryParameter String vm, @QueryParameter String snapshotName) {
120+
try {
121+
122+
if (vm.length() == 0 || serverName.length()==0 || snapshotName.length()==0)
123+
return FormValidation.error(Messages.validation_requiredValues());
124+
125+
VSphere vsphere = getVSphereCloudByName(serverName).vSphereInstance();
126+
127+
if (vm.indexOf('$') >= 0)
128+
return FormValidation.warning(Messages.validation_buildParameter("VM"));
129+
130+
if (vsphere.getVmByName(vm) == null)
131+
return FormValidation.error(Messages.validation_notFound("VM"));
132+
133+
if (snapshotName.indexOf('$') >= 0)
134+
return FormValidation.warning(Messages.validation_buildParameter("Snapshot"));
135+
136+
VirtualMachineSnapshot snap = vsphere.getSnapshotInTree(vsphere.getVmByName(vm), snapshotName);
137+
if (snap==null){
138+
return FormValidation.error(Messages.validation_notFound("Snapshot"));
139+
}
140+
141+
return FormValidation.ok(Messages.validation_success());
142+
} catch (Exception e) {
143+
throw new RuntimeException(e);
144+
}
145+
}
146+
}
147+
}

src/main/java/org/jenkinsci/plugins/vsphere/tools/VSphere.java

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ private ManagedObjectReference findSnapshotInTree(
193193
}
194194

195195
public VirtualMachineSnapshot getSnapshotInTree(
196-
VirtualMachine vm, String snapName) throws VSphereException {
196+
VirtualMachine vm, String snapName) {
197197
if (vm == null || snapName == null) {
198198
return null;
199199
}
@@ -212,10 +212,7 @@ public VirtualMachineSnapshot getSnapshotInTree(
212212
}
213213
}
214214
}
215-
else
216-
{
217-
throw new VSphereException("No snapshots exist or unable to access the snapshot array");
218-
}
215+
219216
return null;
220217
}
221218

@@ -238,6 +235,40 @@ public void revertToSnapshot(String vmName, String snapName) throws VSphereExcep
238235
}
239236
}
240237

238+
public void deleteSnapshot(String vmName, String snapName, boolean consolidate, boolean failOnNoExist) throws VSphereException{
239+
240+
VirtualMachine vm = getVmByName(vmName);
241+
VirtualMachineSnapshot snap = getSnapshotInTree(vm, snapName);
242+
243+
if (snap == null && failOnNoExist) {
244+
throw new VSphereException("Virtual Machine snapshot cannot be found");
245+
}
246+
247+
try{
248+
249+
Task task;
250+
if (snap!=null){
251+
//Does not delete subtree; Implicitly consolidates disk
252+
task = snap.removeSnapshot_Task(false);
253+
if (!task.waitForTask().equals(Task.SUCCESS)) {
254+
throw new VSphereException("Could not delete snapshot");
255+
}
256+
}
257+
258+
if(!consolidate)
259+
return;
260+
261+
//This might be redundant, but I think it consolidates all disks,
262+
//where as the removeSnapshot only consolidates the individual disk
263+
task = vm.consolidateVMDisks_Task();
264+
if (!task.waitForTask().equals(Task.SUCCESS)) {
265+
throw new VSphereException("Could not consolidate VM disks");
266+
}
267+
}catch(Exception e){
268+
throw new VSphereException(e);
269+
}
270+
}
271+
241272
public void takeSnapshot(String vmName, String snapshot, String description, boolean snapMemory) throws VSphereException{
242273

243274
try {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!--
2+
Copyright 2013, MANDIANT, Eric Lordahl
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-->
16+
17+
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
18+
<f:entry title="${%VM}" field="vm">
19+
<f:textbox />
20+
</f:entry>
21+
22+
<f:entry title="${%Snapshot Name}" field="snapshotName">
23+
<f:textbox />
24+
</f:entry>
25+
26+
<f:entry title="${%Consolidate disks?}" field="consolidate">
27+
<f:checkbox />
28+
</f:entry>
29+
30+
<f:entry title="${%Fail on null?}" field="failOnNoExist">
31+
<f:checkbox />
32+
</f:entry>
33+
34+
<f:validateButton title="${%Check Data}" progress="${%Testing...}" method="testData" with="serverName,vm,snapshotName"/>
35+
</j:jelly>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div>
2+
Consolidate all redundant redo logs for this VM?
3+
</div>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div>
2+
If the snapshot you are trying to delete doesnt exist, fail this build step. Sometimes, the job doesnt care if deletion was successful and only wants it gone---if this is the case, leave unchecked.
3+
</div>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div>
2+
The name of the snapshot.
3+
</div>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div>
2+
The name of the VM.
3+
</div>

src/main/resources/org/jenkinsci/plugins/vsphere/builders/Messages.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ vm.title.PowerOn=Power-On/Resume VM
88
vm.title.PowerOff=Power-Off VM
99
vm.title.SuspendVM=Suspend VM
1010
vm.title.RevertToSnapshot=Revert to Snapshot
11-
vm.title.TakeSnapshot=Take snapshot
11+
vm.title.TakeSnapshot=Take Snapshot
12+
vm.title.DeleteSnapshot=Delete a Snapshot
1213

1314
validation.requiredValues=Please enter required values!
1415
validation.required=Please enter {0}!

0 commit comments

Comments
 (0)