diff --git a/README.md b/README.md new file mode 100644 index 0000000..cef5ff9 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +VirtualBox Plugin +================= + +This plugin manage slaves using VirtualBox vms with its WebServer API. + +Sources +------- + +If you're wanting to make changes, please clone the git repository at [sources] + +git://github.com/jenkinsci/virtualbox-plugin.git + +Documentation +------------- + +Plugin Wiki page [wikipage] + + +[ButlerImage]: http://jenkins-ci.org/sites/default/files/jenkins_logo.png +[website]: http://jenkins-ci.org +[wikipage]: https://wiki.jenkins-ci.org/display/JENKINS/VirtualBox+Plugin +[sources]: https://github.com/jenkinsci/virtualbox-plugin + diff --git a/README.txt b/README.txt index 4e2c2c5..bcb14c9 100644 --- a/README.txt +++ b/README.txt @@ -1,28 +1,5 @@ -This is an experimental branch for Virtualbox Snapshot testing. +git://github.com/jenkinsci/virtualbox-plugin.git +Wiki page at -If you create a snapshot in a virtual machine this snapshot will be listed in the Jenkins node configuration at the Virtual Machine Name as //. It is also possible to create snapshot trees. In this case the Virtual Machine Name is build as ///. - -When the virtualbox-plugin starts and stops the virtual machine the selected snapshot is restored. This allows you to setup a virtual machine in a defined statewith e.g. test data. - -Note: An error will be caused, if the virtual machine is relaunched while it already runs. Therefore the virtual machine has to be stopped (maybe the plugin can do this in one of the next releases). To avoid this, set the Availability in the Jenkins node configuration to 'Take this slave on-line when in demand and off-line when idle', 'In demand delay' and 'Idle delay' to 1, and add a label which is also used for the build job definition. Jenkins will start the virtual machine when the build job is started and stops the virtual machine (the plugin will also restore the virtual machine). - - -Note: Snapshots are implemented for Virtualbox 4.0 and 4.1. Version 3.x isn't supported (at the moment). - - ----- - -Some 'git stuff' for this branch: - - -git clone https://github.com/jenkinsci/virtualbox-plugin.git -## or git pull - -git branch -r -## shows remote branch origin/snap - -git branch --track snap origin/snap -## tracks the (see also ################################################################################) - -git checkout snap +https://wiki.jenkins-ci.org/display/JENKINS/VirtualBox+Plugin diff --git a/client/pom.xml b/client/pom.xml index 3f119c5..c76735b 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -4,7 +4,7 @@ org.jenkins-ci.plugins virtualbox-parent - 0.5-SNAPSHOT + 0.8-SNAPSHOT ../pom.xml diff --git a/lib/org/virtualbox/readme.txt b/lib/org/virtualbox/readme.txt index 958b588..3887465 100644 --- a/lib/org/virtualbox/readme.txt +++ b/lib/org/virtualbox/readme.txt @@ -8,3 +8,26 @@ mvn deploy:deploy-file -Dfile=/PATH_TO_DOWNLOADED_JAR/vboxjws-4.1.8.jar -Durl=file:/PATH_TO_PLUGIN_SOURCES/virtualbox-plugin/plugin/../lib -DrepositoryId=virtualbox-libs + + +Command used to install vboxws.jar version 4.2.0 to local repository: + +mvn deploy:deploy-file + -DgroupId=org.virtualbox + -DartifactId=vboxws-42 + -Dversion=4.2.0 + -Dpackaging=jar + -Dfile=/PATH_TO_DOWNLOADED_JAR/vboxjws-4.2.0.jar + -Durl=file:/PATH_TO_PLUGIN_SOURCES/virtualbox-plugin/plugin/../lib + -DrepositoryId=virtualbox-libs + +Command used to install vboxws.jar version 4.3.0 to local repository: + +mvn deploy:deploy-file + -DgroupId=org.virtualbox + -DartifactId=vboxws-43 + -Dversion=4.3.0 + -Dpackaging=jar + -Dfile=/PATH_TO_DOWNLOADED_JAR/vboxjws-4.3.0.jar + -Durl=file:/PATH_TO_PLUGIN_SOURCES/virtualbox-plugin/plugin/../lib + -DrepositoryId=virtualbox-libs diff --git a/lib/org/virtualbox/vboxws-42/4.2.0/vboxws-42-4.2.0.jar b/lib/org/virtualbox/vboxws-42/4.2.0/vboxws-42-4.2.0.jar new file mode 100644 index 0000000..070e69a Binary files /dev/null and b/lib/org/virtualbox/vboxws-42/4.2.0/vboxws-42-4.2.0.jar differ diff --git a/lib/org/virtualbox/vboxws-42/4.2.0/vboxws-42-4.2.0.jar.md5 b/lib/org/virtualbox/vboxws-42/4.2.0/vboxws-42-4.2.0.jar.md5 new file mode 100644 index 0000000..a096039 --- /dev/null +++ b/lib/org/virtualbox/vboxws-42/4.2.0/vboxws-42-4.2.0.jar.md5 @@ -0,0 +1 @@ +c884629596f4eda162c9f412dadd8321 \ No newline at end of file diff --git a/lib/org/virtualbox/vboxws-42/4.2.0/vboxws-42-4.2.0.jar.sha1 b/lib/org/virtualbox/vboxws-42/4.2.0/vboxws-42-4.2.0.jar.sha1 new file mode 100644 index 0000000..4db2c16 --- /dev/null +++ b/lib/org/virtualbox/vboxws-42/4.2.0/vboxws-42-4.2.0.jar.sha1 @@ -0,0 +1 @@ +24ba74a8b017e479a24cf0a695ec6442be519798 \ No newline at end of file diff --git a/lib/org/virtualbox/vboxws-42/4.2.0/vboxws-42-4.2.0.pom b/lib/org/virtualbox/vboxws-42/4.2.0/vboxws-42-4.2.0.pom new file mode 100644 index 0000000..e38b779 --- /dev/null +++ b/lib/org/virtualbox/vboxws-42/4.2.0/vboxws-42-4.2.0.pom @@ -0,0 +1,8 @@ + + + 4.0.0 + org.virtualbox + vboxws-42 + 4.2.0 + diff --git a/lib/org/virtualbox/vboxws-42/4.2.0/vboxws-42-4.2.0.pom.md5 b/lib/org/virtualbox/vboxws-42/4.2.0/vboxws-42-4.2.0.pom.md5 new file mode 100644 index 0000000..6a96bff --- /dev/null +++ b/lib/org/virtualbox/vboxws-42/4.2.0/vboxws-42-4.2.0.pom.md5 @@ -0,0 +1 @@ +d26aa718e5d01f71fa916af6d7c21b65 \ No newline at end of file diff --git a/lib/org/virtualbox/vboxws-42/4.2.0/vboxws-42-4.2.0.pom.sha1 b/lib/org/virtualbox/vboxws-42/4.2.0/vboxws-42-4.2.0.pom.sha1 new file mode 100644 index 0000000..4727585 --- /dev/null +++ b/lib/org/virtualbox/vboxws-42/4.2.0/vboxws-42-4.2.0.pom.sha1 @@ -0,0 +1 @@ +3dbb8214e83dd58e45a3443c9fab94de3695bc24 \ No newline at end of file diff --git a/lib/org/virtualbox/vboxws-42/maven-metadata.xml b/lib/org/virtualbox/vboxws-42/maven-metadata.xml new file mode 100644 index 0000000..332f0c5 --- /dev/null +++ b/lib/org/virtualbox/vboxws-42/maven-metadata.xml @@ -0,0 +1,12 @@ + + + org.virtualbox + vboxws-42 + + 4.2.0 + + 4.2.0 + + 20120915115604 + + diff --git a/lib/org/virtualbox/vboxws-42/maven-metadata.xml.md5 b/lib/org/virtualbox/vboxws-42/maven-metadata.xml.md5 new file mode 100644 index 0000000..76a0dc6 --- /dev/null +++ b/lib/org/virtualbox/vboxws-42/maven-metadata.xml.md5 @@ -0,0 +1 @@ +799bb16aba4aff40834def6e0933815d \ No newline at end of file diff --git a/lib/org/virtualbox/vboxws-42/maven-metadata.xml.sha1 b/lib/org/virtualbox/vboxws-42/maven-metadata.xml.sha1 new file mode 100644 index 0000000..e341630 --- /dev/null +++ b/lib/org/virtualbox/vboxws-42/maven-metadata.xml.sha1 @@ -0,0 +1 @@ +d347676b8b35c43bf53f7321e4f19f9ce2f95577 \ No newline at end of file diff --git a/lib/org/virtualbox/vboxws-43/4.3.0/vboxws-43-4.3.0.jar b/lib/org/virtualbox/vboxws-43/4.3.0/vboxws-43-4.3.0.jar new file mode 100644 index 0000000..467160e Binary files /dev/null and b/lib/org/virtualbox/vboxws-43/4.3.0/vboxws-43-4.3.0.jar differ diff --git a/lib/org/virtualbox/vboxws-43/4.3.0/vboxws-43-4.3.0.jar.md5 b/lib/org/virtualbox/vboxws-43/4.3.0/vboxws-43-4.3.0.jar.md5 new file mode 100644 index 0000000..e030405 --- /dev/null +++ b/lib/org/virtualbox/vboxws-43/4.3.0/vboxws-43-4.3.0.jar.md5 @@ -0,0 +1 @@ +589d48ae7b4d7e981164ad6de80d456b \ No newline at end of file diff --git a/lib/org/virtualbox/vboxws-43/4.3.0/vboxws-43-4.3.0.jar.sha1 b/lib/org/virtualbox/vboxws-43/4.3.0/vboxws-43-4.3.0.jar.sha1 new file mode 100644 index 0000000..62ecc36 --- /dev/null +++ b/lib/org/virtualbox/vboxws-43/4.3.0/vboxws-43-4.3.0.jar.sha1 @@ -0,0 +1 @@ +4639673004fadf186fa033e01ca662923221d4b0 \ No newline at end of file diff --git a/lib/org/virtualbox/vboxws-43/4.3.0/vboxws-43-4.3.0.pom b/lib/org/virtualbox/vboxws-43/4.3.0/vboxws-43-4.3.0.pom new file mode 100644 index 0000000..6505a19 --- /dev/null +++ b/lib/org/virtualbox/vboxws-43/4.3.0/vboxws-43-4.3.0.pom @@ -0,0 +1,8 @@ + + + 4.0.0 + org.virtualbox + vboxws-43 + 4.3.0 + diff --git a/lib/org/virtualbox/vboxws-43/4.3.0/vboxws-43-4.3.0.pom.md5 b/lib/org/virtualbox/vboxws-43/4.3.0/vboxws-43-4.3.0.pom.md5 new file mode 100644 index 0000000..6dbc53c --- /dev/null +++ b/lib/org/virtualbox/vboxws-43/4.3.0/vboxws-43-4.3.0.pom.md5 @@ -0,0 +1 @@ +8469c434998c1edead34ab7a44dca8f5 \ No newline at end of file diff --git a/lib/org/virtualbox/vboxws-43/4.3.0/vboxws-43-4.3.0.pom.sha1 b/lib/org/virtualbox/vboxws-43/4.3.0/vboxws-43-4.3.0.pom.sha1 new file mode 100644 index 0000000..f7a6b10 --- /dev/null +++ b/lib/org/virtualbox/vboxws-43/4.3.0/vboxws-43-4.3.0.pom.sha1 @@ -0,0 +1 @@ +55747744528d742cefb6b4f623f81220e042f6df \ No newline at end of file diff --git a/lib/org/virtualbox/vboxws-43/maven-metadata.xml b/lib/org/virtualbox/vboxws-43/maven-metadata.xml new file mode 100644 index 0000000..87e5d58 --- /dev/null +++ b/lib/org/virtualbox/vboxws-43/maven-metadata.xml @@ -0,0 +1,12 @@ + + + org.virtualbox + vboxws-43 + + 4.3.0 + + 4.3.0 + + 20131016142905 + + diff --git a/lib/org/virtualbox/vboxws-43/maven-metadata.xml.md5 b/lib/org/virtualbox/vboxws-43/maven-metadata.xml.md5 new file mode 100644 index 0000000..9dd4f29 --- /dev/null +++ b/lib/org/virtualbox/vboxws-43/maven-metadata.xml.md5 @@ -0,0 +1 @@ +f99be82d08cfba9f59c01be24819ecd8 \ No newline at end of file diff --git a/lib/org/virtualbox/vboxws-43/maven-metadata.xml.sha1 b/lib/org/virtualbox/vboxws-43/maven-metadata.xml.sha1 new file mode 100644 index 0000000..18a6976 --- /dev/null +++ b/lib/org/virtualbox/vboxws-43/maven-metadata.xml.sha1 @@ -0,0 +1 @@ +c69fe4411a3198e238e3252fd65c9e55438b812b \ No newline at end of file diff --git a/plugin/pom.xml b/plugin/pom.xml index ffb2f3e..5a05543 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -4,7 +4,7 @@ org.jenkins-ci.plugins virtualbox-parent - 0.5-SNAPSHOT + 0.8-SNAPSHOT ../pom.xml @@ -26,11 +26,21 @@ vboxws-40 4.0.8 - - org.virtualbox - vboxws-41 - 4.1.8 - + + org.virtualbox + vboxws-41 + 4.1.8 + + + org.virtualbox + vboxws-42 + 4.2.0 + + + org.virtualbox + vboxws-43 + 4.3.0 + diff --git a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxBuildWrapper.java b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxBuildWrapper.java index 32db745..650f145 100644 --- a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxBuildWrapper.java +++ b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxBuildWrapper.java @@ -32,7 +32,7 @@ class EnvironmentImpl extends Environment { public boolean tearDown(AbstractBuild build, BuildListener listener) throws IOException, InterruptedException { VirtualBoxMachine machine = VirtualBoxPlugin.getVirtualBoxMachine(getHostName(), getVirtualMachineName()); listener.getLogger().println(Messages.VirtualBoxLauncher_stopVM(machine)); - VirtualBoxUtils.stopVm(machine, new VirtualBoxTaskListenerLog(listener, "[VirtualBox] ")); + VirtualBoxUtils.stopVm(machine, "pause", new VirtualBoxTaskListenerLog(listener, "[VirtualBox] ")); return true; } } diff --git a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxComputerLauncher.java b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxComputerLauncher.java index 2315057..cff91a2 100644 --- a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxComputerLauncher.java +++ b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxComputerLauncher.java @@ -1,9 +1,12 @@ package hudson.plugins.virtualbox; +import org.kohsuke.stapler.DataBoundConstructor; + import hudson.model.Descriptor; import hudson.model.TaskListener; import hudson.slaves.ComputerLauncher; import hudson.slaves.SlaveComputer; + import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; @@ -24,26 +27,36 @@ public class VirtualBoxComputerLauncher extends ComputerLauncher { private ComputerLauncher delegate; - /** - * @param delegate real user-specified {@link ComputerLauncher}. - */ - public VirtualBoxComputerLauncher(ComputerLauncher delegate) { + private String hostName; + + private String virtualMachineName; + + private String virtualMachineType; + + private String virtualMachineStopMode; + + @DataBoundConstructor + public VirtualBoxComputerLauncher(ComputerLauncher delegate, String hostName, String virtualMachineName, + String virtualMachineType, String virtualMachineStopMode) { this.delegate = delegate; + this.hostName = hostName; + this.virtualMachineName = virtualMachineName; + this.virtualMachineType = virtualMachineType; + this.virtualMachineStopMode = virtualMachineStopMode; } @Override public void launch(SlaveComputer computer, TaskListener listener) throws IOException, InterruptedException { - VirtualBoxSlave slave = ((VirtualBoxComputer) computer).getNode(); - log(listener, "Launching node " + slave.getVirtualMachineName()); + log(listener, "Launching node " + virtualMachineName); try { // Connect to VirtualBox host - VirtualBoxMachine machine = VirtualBoxPlugin.getVirtualBoxMachine(slave.getHostName(), slave.getVirtualMachineName()); + VirtualBoxMachine machine = VirtualBoxPlugin.getVirtualBoxMachine(hostName, virtualMachineName); if (machine == null) { listener.fatalError("Unable to find specified machine"); return; } log(listener, Messages.VirtualBoxLauncher_startVM(machine)); - long result = VirtualBoxUtils.startVm(machine, slave.getVirtualMachineType(), new VirtualBoxTaskListenerLog(listener, "[VirtualBox] ")); + long result = VirtualBoxUtils.startVm(machine, virtualMachineType, new VirtualBoxTaskListenerLog(listener, "[VirtualBox] ")); if (result != 0) { listener.fatalError("Unable to launch"); return; @@ -102,7 +115,6 @@ public void beforeDisconnect(SlaveComputer computer, TaskListener listener) { @Override public void afterDisconnect(SlaveComputer computer, TaskListener listener) { - VirtualBoxSlave slave = ((VirtualBoxComputer) computer).getNode(); // Stage 2 of the afterDisconnect log(listener, "Starting stage 2 afterDisconnect"); getCore().afterDisconnect(computer, listener); @@ -110,12 +122,12 @@ public void afterDisconnect(SlaveComputer computer, TaskListener listener) { try { // Connect to VirtualBox host - VirtualBoxMachine machine = VirtualBoxPlugin.getVirtualBoxMachine(slave.getHostName(), slave.getVirtualMachineName()); + VirtualBoxMachine machine = VirtualBoxPlugin.getVirtualBoxMachine(hostName, virtualMachineName); if (machine == null) { listener.fatalError("Unable to find specified machine"); } log(listener, Messages.VirtualBoxLauncher_stopVM(machine)); - long result = VirtualBoxUtils.stopVm(machine, new VirtualBoxTaskListenerLog(listener, "[VirtualBox] ")); + long result = VirtualBoxUtils.stopVm(machine, virtualMachineStopMode, new VirtualBoxTaskListenerLog(listener, "[VirtualBox] ")); if (result != 0) { listener.fatalError("Unable to stop"); } diff --git a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControl.java b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControl.java index 3767cc8..738ef8f 100644 --- a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControl.java +++ b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControl.java @@ -7,7 +7,7 @@ */ public interface VirtualBoxControl { public long startVm(VirtualBoxMachine machine, String virtualMachineType, VirtualBoxLogger log); - public long stopVm(VirtualBoxMachine machine, VirtualBoxLogger log); + public long stopVm(VirtualBoxMachine machine, String virtualMachineStopMode, VirtualBoxLogger log); public List getMachines(VirtualBoxCloud host, VirtualBoxLogger log); public String getMacAddress(VirtualBoxMachine machine, VirtualBoxLogger log); diff --git a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControlV31.java b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControlV31.java index 12f9f0c..b65ea8b 100644 --- a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControlV31.java +++ b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControlV31.java @@ -103,7 +103,7 @@ public synchronized long startVm(VirtualBoxMachine vbMachine, String type, Virtu * @param vbMachine virtual machine to stop * @return result code */ - public synchronized long stopVm(VirtualBoxMachine vbMachine, VirtualBoxLogger log) { + public synchronized long stopVm(VirtualBoxMachine vbMachine, String stopMode, VirtualBoxLogger log) { ConnectionHolder holder = connect(hostUrl, userName, password); IMachine machine = holder.vbox.findMachine(vbMachine.getName()); if (org.virtualbox_3_1.MachineState.RUNNING != machine.getState()) { diff --git a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControlV40.java b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControlV40.java index 2355f81..bc15cf0 100644 --- a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControlV40.java +++ b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControlV40.java @@ -207,7 +207,7 @@ public synchronized long startVm(VirtualBoxMachine vbMachine, String type, Virtu * @param log * @return result code */ - public synchronized long stopVm(VirtualBoxMachine vbMachine, VirtualBoxLogger log) { + public synchronized long stopVm(VirtualBoxMachine vbMachine, String stopMode, VirtualBoxLogger log) { String machineName = vbMachine.getName(); String machineId = vbMachine.getMachineId(); String snapshotId = vbMachine.getSnapshotId(); @@ -252,7 +252,7 @@ public synchronized long stopVm(VirtualBoxMachine vbMachine, VirtualBoxLogger lo return -1; } - if (MachineState.Stuck == state) { + if (MachineState.Stuck == state || "powerdown".equals(stopMode)) { // for Stuck state call powerDown and go to PoweredOff state progress = session.getConsole().powerDown(); } else if (snapshot != null) { diff --git a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControlV41.java b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControlV41.java index 9c82756..3af0856 100644 --- a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControlV41.java +++ b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControlV41.java @@ -207,7 +207,7 @@ public synchronized long startVm(VirtualBoxMachine vbMachine, String type, Virtu * @param log * @return result code */ - public synchronized long stopVm(VirtualBoxMachine vbMachine, VirtualBoxLogger log) { + public synchronized long stopVm(VirtualBoxMachine vbMachine, String stopMode, VirtualBoxLogger log) { String machineName = vbMachine.getName(); String machineId = vbMachine.getMachineId(); String snapshotId = vbMachine.getSnapshotId(); @@ -252,7 +252,7 @@ public synchronized long stopVm(VirtualBoxMachine vbMachine, VirtualBoxLogger lo return -1; } - if (MachineState.Stuck == state) { + if (MachineState.Stuck == state || "powerdown".equals(stopMode)) { // for Stuck state call powerDown and go to PoweredOff state progress = session.getConsole().powerDown(); } else if (snapshot != null) { diff --git a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControlV42.java b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControlV42.java new file mode 100644 index 0000000..07ee695 --- /dev/null +++ b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControlV42.java @@ -0,0 +1,357 @@ +package hudson.plugins.virtualbox; + +import java.util.ArrayList; +import java.util.List; +import org.virtualbox_4_2.*; + + +/** + * @author Mihai Serban, Oscar Carlsson + */ +public final class VirtualBoxControlV42 implements VirtualBoxControl { + + private final VirtualBoxManager manager; + private final IVirtualBox vbox; + + public VirtualBoxControlV42(String hostUrl, String userName, String password) { + manager = VirtualBoxManager.createInstance(null); + manager.connect(hostUrl, userName, password); + vbox = manager.getVBox(); + } + + public synchronized void disconnect() { + try { + manager.disconnect(); + } catch (VBoxException e) {} + } + + public synchronized boolean isConnected() { + try { + vbox.getVersion(); + return true; + } catch (VBoxException e) { + return false; + } + } + + /** + * Get virtual machines installed on specified host. + * + * @param host VirtualBox host + * @return list of virtual machines installed on specified host + */ + public synchronized List getMachines(VirtualBoxCloud host, VirtualBoxLogger log) { + List result = new ArrayList(); + for (IMachine machine : vbox.getMachines()) { + result.add(new VirtualBoxMachine(host, machine.getName(), machine.getId(), null)); //TODO snapshot.id! + if (machine.getSnapshotCount() > 0) { + ISnapshot root = findRootSnapshot(machine); + String machineName = machine.getName(); + + List snapshots = fillSnapshot(new ArrayList(), "", root); + for (SnapshotData snapshot : snapshots){ + result.add(new VirtualBoxMachine(host, machineName + "/" + snapshot.name, machine.getId(), snapshot.id)); + } + } + } + return result; + } + + private class SnapshotData { + String name; + String id; + } + private static ISnapshot findRootSnapshot(IMachine machine){ + ISnapshot root = machine.getCurrentSnapshot(); + if (root.getParent() != null) { + root = root.getParent(); + } + return root; + } + + private List fillSnapshot(List snapshotList, String snapshotPath, ISnapshot snapshot){ + if (snapshot != null){ + SnapshotData snapshotData = new SnapshotData(); + snapshotData.name = snapshot.getName();//snapshotPath + "/" + snapshot.getName(); + snapshotData.id = snapshot.getId(); + snapshotList.add(snapshotData); + + if (snapshot.getChildren() != null){ + for (ISnapshot child : snapshot.getChildren()){ + // call fillSnapshot recursive + snapshotList = fillSnapshot(snapshotList, snapshotData.name, child); + } + } + } + return snapshotList; + } + /** + * Starts specified VirtualBox virtual machine. + * + * @param vbMachine virtual machine to start + * @param type session type (can be headless, vrdp, gui, sdl) + * @param log + * @return result code + */ + public synchronized long startVm(VirtualBoxMachine vbMachine, String type, VirtualBoxLogger log) { + String machineName = vbMachine.getName(); + String machineId = vbMachine.getMachineId(); + String snapshotId = vbMachine.getSnapshotId(); + + IMachine machine = vbox.findMachine(machineId); + if (null == machine) { + log.logFatalError("Cannot find node: " + vbMachine.getName()); + return -1; + } + + ISnapshot snapshot = null; + if (snapshotId != null) { + snapshot = machine.findSnapshot(snapshotId); + } + + // states diagram: https://www.virtualbox.org/sdkref/_virtual_box_8idl.html#80b08f71210afe16038e904a656ed9eb + MachineState state = machine.getState(); + ISession session; + IProgress progress; + + // wait for transient states to finish + while (state.value() >= MachineState.FirstTransient.value() && state.value() <= MachineState.LastTransient.value()) { + log.logInfo("node " + vbMachine.getName() + " in state " + state.toString()); + try { + Thread.sleep(1000); + } catch (InterruptedException e) {} + state = machine.getState(); + } + + if (MachineState.Running == state) { + log.logInfo("node " + vbMachine.getName() + " in state " + state.toString()); + + if (snapshotId != null) { + log.logInfo("node " + machineName + " already started and snapshot could not be restored"); + return -1; + } + log.logInfo("node " + vbMachine.getName() + " started"); + return 0; + } + + if (MachineState.Stuck == state || MachineState.Paused == state) { + log.logInfo("starting node " + vbMachine.getName() + " from state " + state.toString()); + try { + session = getSession(machine); + } catch (Exception e) { + log.logFatalError("node " + vbMachine.getName() + " openMachineSession: " + e.getMessage()); + return -1; + } + + progress = null; + if (MachineState.Stuck == state) { + // for Stuck state call powerDown and go to PoweredOff state + progress = session.getConsole().powerDown(); + } else if (MachineState.Paused == state) { + // from Paused call resume + session.getConsole().resume(); + } + + long result = 0; // success + if (null != progress) { + progress.waitForCompletion(-1); + result = progress.getResultCode(); + } + + releaseSession(session, machine); + if (0 != result) { + log.logFatalError("node " + vbMachine.getName() + " error: " + getVBProcessError(progress)); + return -1; + } + + if (MachineState.Stuck != state) { + log.logInfo("node " + vbMachine.getName() + " started"); + return 0; + } + // continue from PoweredOff state + state = machine.getState(); // update state + } + + log.logInfo("starting node " + vbMachine.getName() + " from state " + state.toString()); + + // powerUp from Saved, Aborted or PoweredOff states + String env = ""; + if (snapshot == null){ + session = getSession(null); + progress = machine.launchVMProcess(session, type, env); + }else { + session = getSession(machine); + progress = session.getConsole().restoreSnapshot(snapshot); + progress.waitForCompletion(-1); + + session.unlockMachine(); + session = getSession(null); + progress = machine.launchVMProcess(session, type, env); + //TODO DUPLICATE + } + + progress.waitForCompletion(-1); + long result = progress.getResultCode(); //TODO: -2312312 + releaseSession(session, machine); + + if (0 != result) { + log.logFatalError("node " + vbMachine.getName() + " error: " + getVBProcessError(progress)); + } else { + log.logInfo("node " + vbMachine.getName() + " started"); + } + + return result; + } + + /** + * Stops specified VirtualBox virtual machine. + * + * @param vbMachine virtual machine to stop + * @param log + * @return result code + */ + public synchronized long stopVm(VirtualBoxMachine vbMachine, String stopMode, VirtualBoxLogger log) { + String machineName = vbMachine.getMachineName(); //TODO replace with these + String machineId = vbMachine.getMachineId(); + String snapshotId = vbMachine.getSnapshotId(); + + IMachine machine = vbox.findMachine(machineId); + + if (null == machine) { + log.logFatalError("Cannot find node: " + vbMachine.getName()); + return -1; + } + + ISnapshot snapshot = null; + if (snapshotId != null) { + snapshot = machine.findSnapshot(snapshotId); + } + + // states diagram: https://www.virtualbox.org/sdkref/_virtual_box_8idl.html#80b08f71210afe16038e904a656ed9eb + MachineState state = machine.getState(); + ISession session; + IProgress progress; + + // wait for transient states to finish + while (state.value() >= MachineState.FirstTransient.value() && state.value() <= MachineState.LastTransient.value()) { + log.logInfo("node " + vbMachine.getName() + " in state " + state.toString()); + try { + Thread.sleep(1000); + } catch (InterruptedException e) {} + state = machine.getState(); + } + + log.logInfo("stopping node " + vbMachine.getName() + " from state " + state.toString()); + + if (MachineState.Aborted == state || MachineState.PoweredOff == state + || MachineState.Saved == state) { + log.logInfo("node " + vbMachine.getName() + " stopped"); + return 0; + } + + try { + session = getSession(machine); + } catch (Exception e) { + log.logFatalError("node " + vbMachine.getName() + " openMachineSession: " + e.getMessage()); + return -1; + } + + if (MachineState.Stuck == state || "powerdown".equals(stopMode)) { + // for Stuck state call powerDown and go to PoweredOff state + progress = session.getConsole().powerDown(); + }else if (snapshot != null) { + progress = session.getConsole().powerDown(); + progress.waitForCompletion(-1); + + session = getSession(machine); + progress = session.getConsole().restoreSnapshot(snapshot); + progress.waitForCompletion(-1); + session.unlockMachine(); + } else { + // Running or Paused + progress = session.getConsole().saveState(); + } + + progress.waitForCompletion(-1); + long result = progress.getResultCode(); + + releaseSession(session, machine); + + if (0 != result) { + log.logFatalError("node " + vbMachine.getName() + " error: " + getVBProcessError(progress)); + } else { + log.logInfo("node " + vbMachine.getName() + " stopped"); + } + + return result; + } + + /** + * MAC Address of specified virtual machine. + * + * @param vbMachine virtual machine + * @return MAC Address of specified virtual machine + */ + public synchronized String getMacAddress(VirtualBoxMachine vbMachine, VirtualBoxLogger log) { + IMachine machine = vbox.findMachine(vbMachine.getName()); + String macAddress = machine.getNetworkAdapter(0L).getMACAddress(); + return macAddress; + } + + private String getVBProcessError(IProgress progress) { + if (0 == progress.getResultCode()) { + return ""; + } + + StringBuilder sb = new StringBuilder(""); + IVirtualBoxErrorInfo errInfo = progress.getErrorInfo(); + while (null != errInfo) { + sb.append(errInfo.getText()); + sb.append("\n"); + errInfo = errInfo.getNext(); + } + return sb.toString(); + } + + private boolean isTransientState(SessionState state) { + return SessionState.Spawning == state || SessionState.Unlocking == state; + } + + private ISession getSession(IMachine machine) { + ISession s = manager.getSessionObject(); + if (null != machine) { + machine.lockMachine(s, LockType.Shared); + while (isTransientState(machine.getSessionState())) { + try { + Thread.sleep(500); + } catch (InterruptedException e) {} + } + } + + while (isTransientState(s.getState())) { + try { + Thread.sleep(500); + } catch (InterruptedException e) {} + } + + return s; + } + + private void releaseSession(ISession s, IMachine machine) { + while (isTransientState(machine.getSessionState()) || isTransientState(s.getState())) { + try { + Thread.sleep(500); + } catch (InterruptedException e) {} + } + + try { + s.unlockMachine(); + } catch (VBoxException e) {} + + while (isTransientState(machine.getSessionState()) || isTransientState(s.getState())) { + try { + Thread.sleep(500); + } catch (InterruptedException e) {} + } + } +} diff --git a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControlV43.java b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControlV43.java new file mode 100644 index 0000000..ce0079a --- /dev/null +++ b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxControlV43.java @@ -0,0 +1,357 @@ +package hudson.plugins.virtualbox; + +import java.util.ArrayList; +import java.util.List; +import org.virtualbox_4_3.*; + + +/** + * @author Mihai Serban, Benjamin Close + */ +public final class VirtualBoxControlV43 implements VirtualBoxControl { + + private final VirtualBoxManager manager; + private final IVirtualBox vbox; + + public VirtualBoxControlV43(String hostUrl, String userName, String password) { + manager = VirtualBoxManager.createInstance(null); + manager.connect(hostUrl, userName, password); + vbox = manager.getVBox(); + } + + public synchronized void disconnect() { + try { + manager.disconnect(); + } catch (VBoxException e) {} + } + + public synchronized boolean isConnected() { + try { + vbox.getVersion(); + return true; + } catch (VBoxException e) { + return false; + } + } + + /** + * Get virtual machines installed on specified host. + * + * @param host VirtualBox host + * @return list of virtual machines installed on specified host + */ + public synchronized List getMachines(VirtualBoxCloud host, VirtualBoxLogger log) { + List result = new ArrayList(); + for (IMachine machine : vbox.getMachines()) { + result.add(new VirtualBoxMachine(host, machine.getName(), machine.getId(), null)); //TODO snapshot.id! + if (machine.getSnapshotCount() > 0) { + ISnapshot root = findRootSnapshot(machine); + String machineName = machine.getName(); + + List snapshots = fillSnapshot(new ArrayList(), "", root); + for (SnapshotData snapshot : snapshots){ + result.add(new VirtualBoxMachine(host, machineName + "/" + snapshot.name, machine.getId(), snapshot.id)); + } + } + } + return result; + } + + private class SnapshotData { + String name; + String id; + } + private static ISnapshot findRootSnapshot(IMachine machine){ + ISnapshot root = machine.getCurrentSnapshot(); + if (root.getParent() != null) { + root = root.getParent(); + } + return root; + } + + private List fillSnapshot(List snapshotList, String snapshotPath, ISnapshot snapshot){ + if (snapshot != null){ + SnapshotData snapshotData = new SnapshotData(); + snapshotData.name = snapshot.getName();//snapshotPath + "/" + snapshot.getName(); + snapshotData.id = snapshot.getId(); + snapshotList.add(snapshotData); + + if (snapshot.getChildren() != null){ + for (ISnapshot child : snapshot.getChildren()){ + // call fillSnapshot recursive + snapshotList = fillSnapshot(snapshotList, snapshotData.name, child); + } + } + } + return snapshotList; + } + /** + * Starts specified VirtualBox virtual machine. + * + * @param vbMachine virtual machine to start + * @param type session type (can be headless, vrdp, gui, sdl) + * @param log + * @return result code + */ + public synchronized long startVm(VirtualBoxMachine vbMachine, String type, VirtualBoxLogger log) { + String machineName = vbMachine.getName(); + String machineId = vbMachine.getMachineId(); + String snapshotId = vbMachine.getSnapshotId(); + + IMachine machine = vbox.findMachine(machineId); + if (null == machine) { + log.logFatalError("Cannot find node: " + vbMachine.getName()); + return -1; + } + + ISnapshot snapshot = null; + if (snapshotId != null) { + snapshot = machine.findSnapshot(snapshotId); + } + + // states diagram: https://www.virtualbox.org/sdkref/_virtual_box_8idl.html#80b08f71210afe16038e904a656ed9eb + MachineState state = machine.getState(); + ISession session; + IProgress progress; + + // wait for transient states to finish + while (state.value() >= MachineState.FirstTransient.value() && state.value() <= MachineState.LastTransient.value()) { + log.logInfo("node " + vbMachine.getName() + " in state " + state.toString()); + try { + Thread.sleep(1000); + } catch (InterruptedException e) {} + state = machine.getState(); + } + + if (MachineState.Running == state) { + log.logInfo("node " + vbMachine.getName() + " in state " + state.toString()); + + if (snapshotId != null) { + log.logInfo("node " + machineName + " already started and snapshot could not be restored"); + return -1; + } + log.logInfo("node " + vbMachine.getName() + " started"); + return 0; + } + + if (MachineState.Stuck == state || MachineState.Paused == state) { + log.logInfo("starting node " + vbMachine.getName() + " from state " + state.toString()); + try { + session = getSession(machine); + } catch (Exception e) { + log.logFatalError("node " + vbMachine.getName() + " openMachineSession: " + e.getMessage()); + return -1; + } + + progress = null; + if (MachineState.Stuck == state) { + // for Stuck state call powerDown and go to PoweredOff state + progress = session.getConsole().powerDown(); + } else if (MachineState.Paused == state) { + // from Paused call resume + session.getConsole().resume(); + } + + long result = 0; // success + if (null != progress) { + progress.waitForCompletion(-1); + result = progress.getResultCode(); + } + + releaseSession(session, machine); + if (0 != result) { + log.logFatalError("node " + vbMachine.getName() + " error: " + getVBProcessError(progress)); + return -1; + } + + if (MachineState.Stuck != state) { + log.logInfo("node " + vbMachine.getName() + " started"); + return 0; + } + // continue from PoweredOff state + state = machine.getState(); // update state + } + + log.logInfo("starting node " + vbMachine.getName() + " from state " + state.toString()); + + // powerUp from Saved, Aborted or PoweredOff states + String env = ""; + if (snapshot == null){ + session = getSession(null); + progress = machine.launchVMProcess(session, type, env); + }else { + session = getSession(machine); + progress = session.getConsole().restoreSnapshot(snapshot); + progress.waitForCompletion(-1); + + session.unlockMachine(); + session = getSession(null); + progress = machine.launchVMProcess(session, type, env); + //TODO DUPLICATE + } + + progress.waitForCompletion(-1); + long result = progress.getResultCode(); //TODO: -2312312 + releaseSession(session, machine); + + if (0 != result) { + log.logFatalError("node " + vbMachine.getName() + " error: " + getVBProcessError(progress)); + } else { + log.logInfo("node " + vbMachine.getName() + " started"); + } + + return result; + } + + /** + * Stops specified VirtualBox virtual machine. + * + * @param vbMachine virtual machine to stop + * @param log + * @return result code + */ + public synchronized long stopVm(VirtualBoxMachine vbMachine, String stopMode, VirtualBoxLogger log) { + String machineName = vbMachine.getMachineName(); //TODO replace with these + String machineId = vbMachine.getMachineId(); + String snapshotId = vbMachine.getSnapshotId(); + + IMachine machine = vbox.findMachine(machineId); + + if (null == machine) { + log.logFatalError("Cannot find node: " + vbMachine.getName()); + return -1; + } + + ISnapshot snapshot = null; + if (snapshotId != null) { + snapshot = machine.findSnapshot(snapshotId); + } + + // states diagram: https://www.virtualbox.org/sdkref/_virtual_box_8idl.html#80b08f71210afe16038e904a656ed9eb + MachineState state = machine.getState(); + ISession session; + IProgress progress; + + // wait for transient states to finish + while (state.value() >= MachineState.FirstTransient.value() && state.value() <= MachineState.LastTransient.value()) { + log.logInfo("node " + vbMachine.getName() + " in state " + state.toString()); + try { + Thread.sleep(1000); + } catch (InterruptedException e) {} + state = machine.getState(); + } + + log.logInfo("stopping node " + vbMachine.getName() + " from state " + state.toString()); + + if (MachineState.Aborted == state || MachineState.PoweredOff == state + || MachineState.Saved == state) { + log.logInfo("node " + vbMachine.getName() + " stopped"); + return 0; + } + + try { + session = getSession(machine); + } catch (Exception e) { + log.logFatalError("node " + vbMachine.getName() + " openMachineSession: " + e.getMessage()); + return -1; + } + + if (MachineState.Stuck == state || "powerdown".equals(stopMode)) { + // for Stuck state call powerDown and go to PoweredOff state + progress = session.getConsole().powerDown(); + }else if (snapshot != null) { + progress = session.getConsole().powerDown(); + progress.waitForCompletion(-1); + + session = getSession(machine); + progress = session.getConsole().restoreSnapshot(snapshot); + progress.waitForCompletion(-1); + session.unlockMachine(); + } else { + // Running or Paused + progress = session.getConsole().saveState(); + } + + progress.waitForCompletion(-1); + long result = progress.getResultCode(); + + releaseSession(session, machine); + + if (0 != result) { + log.logFatalError("node " + vbMachine.getName() + " error: " + getVBProcessError(progress)); + } else { + log.logInfo("node " + vbMachine.getName() + " stopped"); + } + + return result; + } + + /** + * MAC Address of specified virtual machine. + * + * @param vbMachine virtual machine + * @return MAC Address of specified virtual machine + */ + public synchronized String getMacAddress(VirtualBoxMachine vbMachine, VirtualBoxLogger log) { + IMachine machine = vbox.findMachine(vbMachine.getName()); + String macAddress = machine.getNetworkAdapter(0L).getMACAddress(); + return macAddress; + } + + private String getVBProcessError(IProgress progress) { + if (0 == progress.getResultCode()) { + return ""; + } + + StringBuilder sb = new StringBuilder(""); + IVirtualBoxErrorInfo errInfo = progress.getErrorInfo(); + while (null != errInfo) { + sb.append(errInfo.getText()); + sb.append("\n"); + errInfo = errInfo.getNext(); + } + return sb.toString(); + } + + private boolean isTransientState(SessionState state) { + return SessionState.Spawning == state || SessionState.Unlocking == state; + } + + private ISession getSession(IMachine machine) { + ISession s = manager.getSessionObject(); + if (null != machine) { + machine.lockMachine(s, LockType.Shared); + while (isTransientState(machine.getSessionState())) { + try { + Thread.sleep(500); + } catch (InterruptedException e) {} + } + } + + while (isTransientState(s.getState())) { + try { + Thread.sleep(500); + } catch (InterruptedException e) {} + } + + return s; + } + + private void releaseSession(ISession s, IMachine machine) { + while (isTransientState(machine.getSessionState()) || isTransientState(s.getState())) { + try { + Thread.sleep(500); + } catch (InterruptedException e) {} + } + + try { + s.unlockMachine(); + } catch (VBoxException e) {} + + while (isTransientState(machine.getSessionState()) || isTransientState(s.getState())) { + try { + Thread.sleep(500); + } catch (InterruptedException e) {} + } + } +} diff --git a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxListener.java b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxListener.java new file mode 100644 index 0000000..e29dd52 --- /dev/null +++ b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxListener.java @@ -0,0 +1,58 @@ +package hudson.plugins.virtualbox; + +/* CJ: Extensions for RunListener*/ +import hudson.Extension; +import hudson.model.listeners.RunListener; +import hudson.slaves.*; +import hudson.model.Node; + +import java.io.Serializable; +import hudson.model.*; + + +/* CJ: Start normal import*/ +import hudson.Launcher; +import hudson.model.AbstractBuild; +import hudson.model.BuildListener; +import hudson.tasks.BuildWrapper; + +import org.kohsuke.stapler.DataBoundConstructor; + +// http://jenkins.361315.n4.nabble.com/Take-a-slave-off-line-if-a-job-fails-td377500.html + +/** + * @author Christian John + */ +@Extension +public class VirtualBoxListener extends RunListener implements Serializable { + + public VirtualBoxListener() { + super(Run.class); + } + + + /* onCompleted EP: RunListener*/ + @Override + public void onCompleted(Run run, TaskListener listener) { + // Aktuelles Computer-Objekt abgreifen + Computer computer = run.getExecutor().getOwner(); + // Versuchen zu beenden + try{ + // Erst einmal den Build-Server offline-Setzen + computer.setTemporarilyOffline(true,null); + // Und noch mal zur Sicherheit hinterher + computer.cliDisconnect("Sicherheit"); + } catch(Exception e) + { + listener.getLogger().println("Fehler beim Shutdown!"); + } + + + // VirtualBoxMachine machine = VirtualBoxPlugin.getVirtualBoxMachine(super.getHostName(), super.getVirtualMachineName()); + //VirtualBoxUtils.stopVm(run.getExecutor().getOwner().currentComputer(), new VirtualBoxTaskListenerLog(listener, "[VirtualBox] ")); + //slave.getComputer().setTemporarilyOffline(true,null); + listener.getLogger().println("Bye bye VM!"); + + } + +} diff --git a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxSlave.java b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxSlave.java index 31f5c74..a8bfe84 100644 --- a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxSlave.java +++ b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxSlave.java @@ -26,12 +26,13 @@ public class VirtualBoxSlave extends Slave { private final String hostName; private final String virtualMachineName; private final String virtualMachineType; + private final String virtualMachineStopMode; @DataBoundConstructor public VirtualBoxSlave( String name, String nodeDescription, String remoteFS, String numExecutors, Mode mode, String labelString, ComputerLauncher delegateLauncher, RetentionStrategy retentionStrategy, List> nodeProperties, - String hostName, String virtualMachineName, String virtualMachineType + String hostName, String virtualMachineName, String virtualMachineType, String virtualMachineStopMode ) throws Descriptor.FormException, IOException { super( name, @@ -40,13 +41,35 @@ public VirtualBoxSlave( numExecutors, mode, labelString, - new VirtualBoxComputerLauncher(delegateLauncher), + new VirtualBoxComputerLauncher(delegateLauncher, hostName, virtualMachineName, virtualMachineType, virtualMachineStopMode), retentionStrategy, nodeProperties ); this.hostName = hostName; this.virtualMachineName = virtualMachineName; this.virtualMachineType = virtualMachineType; + this.virtualMachineStopMode = virtualMachineStopMode; + } + + public VirtualBoxSlave( + String name, String nodeDescription, String remoteFS, String numExecutors, Mode mode, String labelString, + ComputerLauncher delegateLauncher, RetentionStrategy retentionStrategy, List> nodeProperties, + String hostName, String virtualMachineName, String virtualMachineType + ) throws Descriptor.FormException, IOException { + this( + name, + nodeDescription, + remoteFS, + numExecutors, + mode, + labelString, + delegateLauncher, + retentionStrategy, + nodeProperties, + hostName, + virtualMachineName, + virtualMachineType, + "pause"); } @Override @@ -75,6 +98,13 @@ public String getVirtualMachineType() { return virtualMachineType; } + /** + * @return type of stop mode for virtual machine, can be powerdown or pause + */ + public String getVirtualMachineStopMode() { + return virtualMachineStopMode; + } + @Override public VirtualBoxComputerLauncher getLauncher() { return (VirtualBoxComputerLauncher) super.getLauncher(); @@ -85,7 +115,6 @@ public VirtualBoxComputerLauncher getLauncher() { * * @return original launcher */ - @SuppressWarnings({"UnusedDeclaration"}) public ComputerLauncher getDelegateLauncher() { return getLauncher().getCore(); } @@ -102,7 +131,6 @@ public String getDisplayName() { * * @see VirtualBoxPlugin#getHost(String) */ - @SuppressWarnings({"UnusedDeclaration"}) public List getDefinedVirtualMachines(String hostName) { return VirtualBoxPlugin.getDefinedVirtualMachines(hostName); } @@ -112,7 +140,6 @@ public List getDefinedVirtualMachines(String hostName) { * * @see VirtualBoxPlugin#getHosts() */ - @SuppressWarnings({"UnusedDeclaration"}) public List getHosts() { return VirtualBoxPlugin.getHosts(); } @@ -121,7 +148,6 @@ public List getHosts() { * For UI. * TODO Godin: doesn't work */ - @SuppressWarnings({"UnusedDeclaration"}) public FormValidation doCheckHostName(@QueryParameter String value) { LOG.info("Perform on the fly check - hostName"); if (Util.fixEmptyAndTrim(value) == null) { @@ -134,7 +160,6 @@ public FormValidation doCheckHostName(@QueryParameter String value) { * For UI. * TODO Godin: doesn't work */ - @SuppressWarnings({"UnusedDeclaration"}) public FormValidation doCheckVirtualMachineName(@QueryParameter String value) { LOG.info("Perform on the fly check - virtualMachineName"); if (Util.fixEmptyAndTrim(value) == null) { diff --git a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxUtils.java b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxUtils.java index 6b2b35d..e6fe1b9 100644 --- a/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxUtils.java +++ b/plugin/src/main/java/hudson/plugins/virtualbox/VirtualBoxUtils.java @@ -17,8 +17,8 @@ public static long startVm(VirtualBoxMachine machine, String virtualMachineType, return getVboxControl(machine.getHost(), log).startVm(machine, virtualMachineType, log); } - public static long stopVm(VirtualBoxMachine machine, VirtualBoxLogger log) { - return getVboxControl(machine.getHost(), log).stopVm(machine, log); + public static long stopVm(VirtualBoxMachine machine, String virtualMachineStopMode, VirtualBoxLogger log) { + return getVboxControl(machine.getHost(), log).stopVm(machine, virtualMachineStopMode, log); } public static List getMachines(VirtualBoxCloud host, VirtualBoxLogger log) { @@ -43,23 +43,26 @@ private VirtualBoxUtils() { /** * Cache connections to VirtualBox hosts * TODO: keep the connections alive with a noop + * TODO: rewrite duplicate code */ private static HashMap vboxControls = new HashMap(); private synchronized static VirtualBoxControl getVboxControl(VirtualBoxCloud host, VirtualBoxLogger log) { - VirtualBoxControl vboxControl = (VirtualBoxControl)vboxControls.get(host.toString()); - if (null != vboxControl) { - if (vboxControl.isConnected()) { + VirtualBoxControl vboxControl = (VirtualBoxControl)vboxControls.get(host.toString()); + + if (vboxControl != null && !vboxControl.isConnected()){ + log.logInfo("Lost connection to " + host.getUrl() + ", reconnecting"); + vboxControls.remove(host.toString()); // force a reconnect + } + + if (! (vboxControl != null && vboxControl.isConnected()) ) { + vboxControl = createVboxControl(host, log); + vboxControls.put(host.toString(), vboxControl); + } + return vboxControl; - } - log.logInfo("Lost connection to " + host.getUrl() + ", reconnecting"); - vboxControls.remove(host.toString()); // force a reconnect } - vboxControl = createVboxControl(host, log); - vboxControls.put(host.toString(), vboxControl); - return vboxControl; - } private static VirtualBoxControl createVboxControl(VirtualBoxCloud host, VirtualBoxLogger log) { VirtualBoxControl vboxControl = null; @@ -71,9 +74,13 @@ private static VirtualBoxControl createVboxControl(VirtualBoxCloud host, Virtual manager.disconnect(vbox); log.logInfo("Creating connection to VirtualBox version " + version); - if (version.startsWith("4.1")) { - vboxControl = new VirtualBoxControlV41(host.getUrl(), host.getUsername(), host.getPassword()); - } else if (version.startsWith("4.0")) { + if (version.startsWith("4.3")) { + vboxControl = new VirtualBoxControlV43(host.getUrl(), host.getUsername(), host.getPassword()); + } else if (version.startsWith("4.2")) { + vboxControl = new VirtualBoxControlV42(host.getUrl(), host.getUsername(), host.getPassword()); + } else if (version.startsWith("4.1")) { + vboxControl = new VirtualBoxControlV41(host.getUrl(), host.getUsername(), host.getPassword()); + } else if (version.startsWith("4.0")) { vboxControl = new VirtualBoxControlV40(host.getUrl(), host.getUsername(), host.getPassword()); } else if (version.startsWith("3.")) { vboxControl = new VirtualBoxControlV31(host.getUrl(), host.getUsername(), host.getPassword()); diff --git a/plugin/src/main/resources/hudson/plugins/virtualbox/VirtualBoxSlave/configure-entries.jelly b/plugin/src/main/resources/hudson/plugins/virtualbox/VirtualBoxSlave/configure-entries.jelly index 8036bf9..ea4325c 100644 --- a/plugin/src/main/resources/hudson/plugins/virtualbox/VirtualBoxSlave/configure-entries.jelly +++ b/plugin/src/main/resources/hudson/plugins/virtualbox/VirtualBoxSlave/configure-entries.jelly @@ -35,6 +35,13 @@ + + + + diff --git a/pom.xml b/pom.xml index 2047500..cad03c0 100644 --- a/pom.xml +++ b/pom.xml @@ -3,12 +3,11 @@ org.jenkins-ci.plugins plugin - 1.399 - ../pom.xml + 1.424 virtualbox-parent - 0.5-SNAPSHOT + 0.8-SNAPSHOT pom Jenkins VirtualBox Parent @@ -29,8 +28,18 @@ Developer + + hgomez + Henri Gomez + henri.gomez@gmail.com + +1 + + Developer + + + plugin client @@ -38,17 +47,11 @@ scm:git:git://github.com/jenkinsci/virtualbox-plugin.git - scm:git:https://git@github.com/jenkinsci/virtualbox-plugin.git + scm:git:git@github.com:jenkinsci/virtualbox-plugin.git https://github.com/jenkinsci/virtualbox-plugin + HEAD - - - java.net-m2-repository - http://maven.jenkins-ci.org:8081/content/repositories/releases/ - - - UTF-8 @@ -81,7 +84,7 @@ org.apache.maven.plugins maven-release-plugin - 2.1 + 2.3.2 @@ -90,18 +93,18 @@ org.apache.maven.plugins maven-release-plugin - 2.0 deploy - - - org.apache.maven.scm - maven-scm-provider-gitexe - 1.3 - - - + + + + repo.jenkins-ci.org + http://repo.jenkins-ci.org/public/ + + + + diff --git a/startserver.sh b/startserver.sh new file mode 100755 index 0000000..d247a5b --- /dev/null +++ b/startserver.sh @@ -0,0 +1,8 @@ +#!/bin/bash +sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist +export JAVA_OPTS="$JAVA_OPTS -Xmx1024 -XX:MaxPermSize=512m" +export MAVEN_OPTS="-Xms512m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512m -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000" +cd plugin +mvn clean +mvn install +mvn hpi:run diff --git a/startvm.sh b/startvm.sh new file mode 100755 index 0000000..d9c04fd --- /dev/null +++ b/startvm.sh @@ -0,0 +1,3 @@ +#!/bin/bash +VBoxManage setproperty websrvauthlibrary null +vboxwebsrv