diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExists.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExists.java new file mode 100644 index 0000000000..921b50bf0e --- /dev/null +++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExists.java @@ -0,0 +1,73 @@ +/* + * * + * * Licensed to jclouds, Inc. (jclouds) under one or more + * * contributor license agreements. See the NOTICE file + * * distributed with this work for additional information + * * regarding copyright ownership. jclouds licenses this file + * * to you under the Apache License, Version 2.0 (the + * * "License"); you may not use this file except in compliance + * * with the License. You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, + * * software distributed under the License is distributed on an + * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * * KIND, either express or implied. See the License for the + * * specific language governing permissions and limitations + * * under the License. + * + */ + +package org.jclouds.virtualbox.functions; + + +import com.google.common.base.Function; +import org.virtualbox_4_1.IMachine; +import org.virtualbox_4_1.IVirtualBox; +import org.virtualbox_4_1.VBoxException; +import org.virtualbox_4_1.VirtualBoxManager; + +import javax.annotation.Nullable; + +public class CreateAndRegisterMachineFromIsoIfNotAlreadyExists implements Function { + + private String settingsFile; + private String osTypeId; + private String vmId; + private boolean forceOverwrite; + private VirtualBoxManager manager; + + public CreateAndRegisterMachineFromIsoIfNotAlreadyExists(String settingsFile, String osTypeId, String vmId, + boolean forceOverwrite, VirtualBoxManager manager) { + this.settingsFile = settingsFile; + this.osTypeId = osTypeId; + this.vmId = vmId; + this.forceOverwrite = forceOverwrite; + this.manager = manager; + } + + @Override + public IMachine apply(@Nullable String vmName) { + + final IVirtualBox vBox = manager.getVBox(); + try { + throw new IllegalStateException("Machine " + vmName + " is already registered."); + } catch (VBoxException e) { + if (machineNotFoundException(e)) + return createMachine(vBox, vmName); + else + throw e; + } + } + + private boolean machineNotFoundException(VBoxException e) { + return e.getMessage().indexOf("VirtualBox error: Could not find a registered machine named ") != -1; + } + + private IMachine createMachine(IVirtualBox vBox, String vmName) { + IMachine newMachine = vBox.createMachine(settingsFile, vmName, osTypeId, vmId, forceOverwrite); + manager.getVBox().registerMachine(newMachine); + return newMachine; + } +} diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IsoToIMachine.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IsoToIMachine.java index c0ed17c3a0..ff844ab625 100644 --- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IsoToIMachine.java +++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IsoToIMachine.java @@ -112,8 +112,7 @@ public class IsoToIMachine implements Function { String baseResource = "."; Server server = new StartJettyIfNotAlreadyRunning(port).apply(baseResource); - IMachine vm = manager.getVBox().createMachine(settingsFile, vmName, osTypeId, vmId, forceOverwrite); - manager.getVBox().registerMachine(vm); + IMachine vm = new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(settingsFile, osTypeId, vmId, forceOverwrite, manager).apply(vmName); String defaultWorkingDir = System.getProperty("user.home") + "/jclouds-virtualbox-test"; String workingDir = System.getProperty(VIRTUALBOX_WORKINGDIR, defaultWorkingDir); diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsTest.java new file mode 100644 index 0000000000..3a2f705dfe --- /dev/null +++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsTest.java @@ -0,0 +1,89 @@ +/* + * * + * * Licensed to jclouds, Inc. (jclouds) under one or more + * * contributor license agreements. See the NOTICE file + * * distributed with this work for additional information + * * regarding copyright ownership. jclouds licenses this file + * * to you under the Apache License, Version 2.0 (the + * * "License"); you may not use this file except in compliance + * * with the License. You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, + * * software distributed under the License is distributed on an + * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * * KIND, either express or implied. See the License for the + * * specific language governing permissions and limitations + * * under the License. + * + */ + +package org.jclouds.virtualbox.functions; + +import org.easymock.EasyMock; +import org.testng.annotations.Test; +import org.virtualbox_4_1.IMachine; +import org.virtualbox_4_1.IVirtualBox; +import org.virtualbox_4_1.VBoxException; +import org.virtualbox_4_1.VirtualBoxManager; + +import static org.easymock.EasyMock.anyBoolean; +import static org.easymock.EasyMock.expect; +import static org.easymock.classextension.EasyMock.*; + +@Test(groups = "unit", testName = "CreateAndRegisterMachineFromIsoIfNotAlreadyExistsTest") +public class CreateAndRegisterMachineFromIsoIfNotAlreadyExistsTest { + + @Test + public void testCreateIfNotAlreadyExists() throws Exception { + + VirtualBoxManager manager = createNiceMock(VirtualBoxManager.class); + IVirtualBox vBox = createMock(IVirtualBox.class); + String vmName = "jclouds-image-my-ubuntu-image"; + + IMachine createdMachine = createMock(IMachine.class); + + expect(manager.getVBox()).andReturn(vBox).anyTimes(); + + StringBuilder errorMessageBuilder = new StringBuilder(); + errorMessageBuilder.append("VirtualBox error: Could not find a registered machine named "); + errorMessageBuilder.append("'jclouds-image-virtualbox-iso-to-machine-test' (0x80BB0001)"); + String errorMessage = errorMessageBuilder.toString(); + VBoxException vBoxException = new VBoxException(createNiceMock(Throwable.class), errorMessage); + + vBox.findMachine(vmName); + expectLastCall().andThrow(vBoxException); + + expect(vBox.createMachine(anyString(), eq(vmName), anyString(), anyString(), anyBoolean())).andReturn(createdMachine).anyTimes(); + + vBox.registerMachine(createdMachine); + + replay(manager, vBox); + + new CreateAndRegisterMachineFromIsoIfNotAlreadyExists("", "", "", false, manager).apply(vmName); + + verify(manager, vBox); + } + + @Test(expectedExceptions = IllegalStateException.class) + public void testFailIfMachineIsAlreadyRegistered() throws Exception { + + VirtualBoxManager manager = createNiceMock(VirtualBoxManager.class); + IVirtualBox vBox = createNiceMock(IVirtualBox.class); + String vmName = "jclouds-image-my-ubuntu-image"; + + IMachine registeredMachine = createMock(IMachine.class); + + expect(manager.getVBox()).andReturn(vBox).anyTimes(); + expect(vBox.findMachine(vmName)).andReturn(registeredMachine).anyTimes(); + + replay(manager, vBox); + + new CreateAndRegisterMachineFromIsoIfNotAlreadyExists("", "", "", false, manager).apply(vmName); + } + + private String anyString() { + return EasyMock.anyObject(); + } +}