Skip to content
Permalink
Browse files

Implemented JENKINS-16583

  • Loading branch information...
tastybug committed Mar 20, 2013
1 parent eb73184 commit 6b39bca1fa9dd92e023bb2b57db4531ee0417812
@@ -111,7 +111,7 @@
<dependency>
<groupId>org.libvirt</groupId>
<artifactId>libvirt</artifactId>
<version>0.4.2</version>
<version>0.4.7</version>
</dependency>
</dependencies>
</project>
@@ -189,6 +189,32 @@ public String getHypervisorDescription() {
return vmList;
}

/**
* Returns an array of snapshots names/ids of a given VM as found by libvirt.
*
* @param virtualMachineName the name of the vm
* @return the array of snapshot ids (can be empty)
*/
public synchronized String[] getSnapshots (String virtualMachineName) {
try {
LogRecord rec = new LogRecord(Level.INFO, "Searching snapshots for " + virtualMachineName);
LOGGER.log(rec);
for (Domain domain : getDomains().values()) {
if (domain.getName().equals(virtualMachineName)) {
rec = new LogRecord(Level.INFO, "Fetching snapshots for " + virtualMachineName + ": " + domain.snapshotNum());
LOGGER.log(rec);
return domain.snapshotListNames();
}
}
} catch (LibvirtException lve) {
LogRecord rec = new LogRecord(Level.SEVERE, "Failed to fetch snapshot ids for VM {0} at datacenter {1} as {2}/******");
rec.setThrown(lve);
rec.setParameters(new Object[]{virtualMachineName, hypervisorHost, username});
LOGGER.log(rec);
}
return new String[0];
}

public Collection<NodeProvisioner.PlannedNode> provision(Label label, int i) {
return Collections.emptySet();
}
@@ -92,5 +92,23 @@ public void doComputerNameValues(StaplerRequest req, StaplerResponse rsp, @Query
}
m.writeTo(req, rsp);
}

public void doSnapshotNameValues(StaplerRequest req, StaplerResponse rsp, @QueryParameter("vm") String vm, @QueryParameter("hypervisor") String hypervisor) throws IOException, ServletException {
ListBoxModel m = new ListBoxModel();
m.add(new ListBoxModel.Option("", ""));
for (Cloud cloud : Hudson.getInstance().clouds) {
if (cloud instanceof Hypervisor) {
Hypervisor hypHandle = (Hypervisor) cloud;
if (hypervisor != null && hypervisor.equals(hypHandle.getHypervisorURI())) {
String[] ss = hypHandle.getSnapshots(vm);
for (String sshot : ss) {
m.add(new ListBoxModel.Option(sshot, sshot));
}
}
}
}

m.writeTo(req, rsp);
}
}

@@ -45,13 +45,15 @@
private transient VirtualMachine virtualMachine;
private String hypervisorDescription;
private String virtualMachineName;
private String snapshotName;
private final int WAIT_TIME_MS;

@DataBoundConstructor
public VirtualMachineLauncher(ComputerLauncher delegate, String hypervisorDescription, String virtualMachineName, int waitingTimeSecs) {
public VirtualMachineLauncher(ComputerLauncher delegate, String hypervisorDescription, String virtualMachineName, String snapshotName, int waitingTimeSecs) {
super();
this.delegate = delegate;
this.virtualMachineName = virtualMachineName;
this.snapshotName = snapshotName;
this.hypervisorDescription = hypervisorDescription;
this.WAIT_TIME_MS = waitingTimeSecs*1000;
lookupVirtualMachineHandle();
@@ -142,9 +144,13 @@ public synchronized void afterDisconnect(SlaveComputer slaveComputer, TaskListen
if (virtualMachine.getName().equals(domainName)) {
Domain domain = computers.get(domainName);
if (domain.getInfo().state.equals(DomainState.VIR_DOMAIN_RUNNING) || domain.getInfo().state.equals(DomainState.VIR_DOMAIN_BLOCKED)) {
taskListener.getLogger().println("...Virtual machine found, shutting down.");
domain.shutdown();
Thread.sleep(10000); // gi
if (snapshotName != null && snapshotName.length() > 0) {
taskListener.getLogger().println("...Virtual machine found, reverting to " + snapshotName + " and shutting down.");
domain.revertToSnapshot(domain.snapshotLookupByName(snapshotName));
} else {
taskListener.getLogger().println("...Virtual machine found, shutting down.");
domain.shutdown();
}
} else {
taskListener.getLogger().println("...Virtual machine found; it is already suspended, no shutdown required.");
}
@@ -22,7 +22,6 @@
package hudson.plugins.libvirt;

import hudson.Extension;
import hudson.Functions;
import hudson.Util;
import hudson.model.Descriptor;
import hudson.model.Hudson;
@@ -44,21 +43,23 @@

private static final Logger LOGGER = Logger.getLogger(VirtualMachineSlave.class.getName());
private String hypervisorDescription;
private String snapshotName;
private String virtualMachineName;
private int startupWaitingPeriodSeconds;

@DataBoundConstructor
public VirtualMachineSlave(String name, String nodeDescription, String remoteFS, String numExecutors,
Mode mode, String labelString, VirtualMachineLauncher launcher, ComputerLauncher delegateLauncher,
RetentionStrategy retentionStrategy, List<? extends NodeProperty<?>> nodeProperties,
String hypervisorDescription, String virtualMachineName, int startupWaitingPeriodSeconds)
String hypervisorDescription, String virtualMachineName, String snapshotName, int startupWaitingPeriodSeconds)
throws
Descriptor.FormException, IOException {
super(name, nodeDescription, remoteFS, Util.tryParseNumber(numExecutors, 1).intValue(), mode, labelString,
launcher == null ? new VirtualMachineLauncher(delegateLauncher, hypervisorDescription, virtualMachineName, startupWaitingPeriodSeconds) : launcher,
launcher == null ? new VirtualMachineLauncher(delegateLauncher, hypervisorDescription, virtualMachineName, snapshotName, startupWaitingPeriodSeconds) : launcher,
retentionStrategy, nodeProperties);
this.hypervisorDescription = hypervisorDescription;
this.virtualMachineName = virtualMachineName;
this.snapshotName = snapshotName;
this.startupWaitingPeriodSeconds = startupWaitingPeriodSeconds;
}

@@ -70,6 +71,10 @@ public String getVirtualMachineName() {
return virtualMachineName;
}

public String getSnapshotName() {
return snapshotName;
}

public int getStartupWaitingPeriodSeconds() {
return startupWaitingPeriodSeconds;
}
@@ -85,6 +90,7 @@ public ComputerLauncher getDelegateLauncher() {

private String hypervisorDescription;
private String virtualMachineName;
private String snapshotName;

public DescriptorImpl() {
load();
@@ -101,19 +107,21 @@ public boolean isInstantiable() {

public List<VirtualMachine> getDefinedVirtualMachines(String hypervisorDescription) {
List<VirtualMachine> virtualMachinesList = new ArrayList<VirtualMachine>();
if (hypervisorDescription != null && !hypervisorDescription.equals("")) {
Hypervisor hypervisor = null;
for (Cloud cloud : Hudson.getInstance().clouds) {
if (cloud instanceof Hypervisor && ((Hypervisor) cloud).getHypervisorDescription().equals(hypervisorDescription)) {
hypervisor = (Hypervisor) cloud;
break;
}
}
virtualMachinesList.addAll(hypervisor.getVirtualMachines());
}
Hypervisor hypervisor = getHypervisorByDescription(hypervisorDescription);
if (hypervisor != null)
virtualMachinesList.addAll(hypervisor.getVirtualMachines());
return virtualMachinesList;
}

public String[] getDefinedSnapshots(String hypervisorDescription, String virtualMachineName) {
Hypervisor hypervisor = getHypervisorByDescription(hypervisorDescription);
if (hypervisor != null) {
String[] snapS = hypervisor.getSnapshots(virtualMachineName);
return snapS;
}
return new String[0];
}

public ListBoxModel doFillHypervisorDescriptionItems() {
ListBoxModel items = new ListBoxModel();
for (Cloud cloud : Hudson.getInstance().clouds) {
@@ -131,6 +139,20 @@ public String getHypervisorDescription() {
public String getVirtualMachineName() {
return virtualMachineName;
}

public String getSnapshotName() {
return snapshotName;
}

private Hypervisor getHypervisorByDescription (String hypervisorDescription) {
if (hypervisorDescription != null && !hypervisorDescription.equals("")) {
for (Cloud cloud : Hudson.getInstance().clouds) {
if (cloud instanceof Hypervisor && ((Hypervisor) cloud).getHypervisorDescription().equals(hypervisorDescription)) {
return (Hypervisor) cloud;
}
}
}
return null;
}
}
}
@@ -5,7 +5,7 @@
</f:entry>

<f:entry title="${%Virtual Machine}" field="virtualMachineName" help="/plugin/libvirt-slave/help-libvirt-computerName.html">
<select class="setting-input" name="virtualMachineName" value="${instance.virtualMachineName}">
<select class="setting-input" name="virtualMachineName" value="${instance.virtualMachineName}" onchange="updateListBox(document.getElementsByName('snapshotName')[0],'${rootURL}/plugin/libvirt-slave/snapshotNameValues?vm='+encode(this.value)+'&amp;hypervisor='+encode(document.getElementsByName('_.hypervisorDescription')[0].options[document.getElementsByName('_.hypervisorDescription')[0].selectedIndex].text))">
<j:forEach var="vc" items="${descriptor.getDefinedVirtualMachines(it.hypervisorDescription)}" varStatus="loop">
<option selected="${vc.name==it.virtualMachineName?'true':null}">
${vc.name}
@@ -14,6 +14,17 @@
</select>
</f:entry>

<f:entry title="${%Revert Snapshot}" field="snapshotName" help="/plugin/libvirt-slave/help-libvirt-snapshotName.html">
<select class="setting-input" name="snapshotName" value="${instance.snapshotName}">
<option selected="${it.snapshotName == null || it.snapshotName == ''}"></option>
<j:forEach var="sshot" items="${descriptor.getDefinedSnapshots(it.hypervisorDescription, it.virtualMachineName)}" varStatus="loop">
<option selected="${sshot==it.snapshotName?'true':null}">
${sshot}
</option>
</j:forEach>
</select>
</f:entry>

<f:entry title="${%Description}" help="/help/system-config/master-slave/description.html">
<f:textbox field="nodeDescription"/>
</f:entry>
@@ -0,0 +1,5 @@
<div>
<p>
Here you can select a snapshot that your virtual machine is going to be reverted to upon every shutdown.
</p>
</div>

0 comments on commit 6b39bca

Please sign in to comment.
You can’t perform that action at this time.