issue 384: improve UnregisterMachineIfExistsAndDeleteItsMedia + Test

This commit is contained in:
andreaturli 2011-12-19 23:47:10 +00:00
parent 57c3c81139
commit 3f559bf0c5
4 changed files with 89 additions and 46 deletions

View File

@ -19,13 +19,18 @@
package org.jclouds.virtualbox.domain;
import com.google.common.base.Objects;
import java.util.*;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.virtualbox_4_1.CleanupMode;
import com.google.common.base.Objects;
/**
* A description of a Virtual Machine in VirtualBox.
@ -39,8 +44,9 @@ public class VmSpec {
private final boolean forceOverwrite;
private final Map<Long, NatAdapter> natNetworkAdapters;
private final Set<StorageController> controllers;
private final CleanupMode cleanupMode;
public VmSpec(String vmId, String vmName, String osTypeId, long memory, boolean forceOverwrite, Set<StorageController> controllers, Map<Long, NatAdapter> natNetworkAdapters) {
public VmSpec(String vmId, String vmName, String osTypeId, long memory, boolean forceOverwrite, Set<StorageController> controllers, Map<Long, NatAdapter> natNetworkAdapters, CleanupMode cleanupMode) {
checkNotNull(vmId, "vmId");
checkNotNull(vmName, "vmName");
checkArgument(memory > 0, "memory must be > 0");
@ -53,6 +59,7 @@ public class VmSpec {
this.controllers = controllers;
this.forceOverwrite = forceOverwrite;
this.natNetworkAdapters = natNetworkAdapters;
this.cleanupMode = cleanupMode;
}
public static Builder builder() {
@ -69,6 +76,8 @@ public class VmSpec {
private boolean forceOverwrite;
private Map<Long, NatAdapter> natNetworkAdapters = new HashMap<Long, NatAdapter>();
private long memory;
private CleanupMode cleanUpMode;
public Builder controller(StorageController controller) {
controllers.add(controller);
return this;
@ -103,12 +112,17 @@ public class VmSpec {
this.memory = (long) memorySize;
return this;
}
public Builder cleanUpMode(CleanupMode cleanupMode) {
this.cleanUpMode = cleanupMode;
return this;
}
public VmSpec build() {
checkNotNull(name, "name");
checkNotNull(id, "id");
checkArgument(memory > 0, "Memory must be set");
return new VmSpec(id, name, osTypeId, memory, forceOverwrite, controllers, natNetworkAdapters);
return new VmSpec(id, name, osTypeId, memory, forceOverwrite, controllers, natNetworkAdapters, cleanUpMode);
}
@ -141,6 +155,10 @@ public class VmSpec {
return Collections.unmodifiableMap(natNetworkAdapters);
}
public CleanupMode getCleanupMode() {
return cleanupMode;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;

View File

@ -19,16 +19,18 @@
package org.jclouds.virtualbox.functions.admin;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import javax.annotation.Resource;
import javax.inject.Named;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.virtualbox.domain.ErrorCode;
import org.jclouds.virtualbox.domain.VmSpec;
import org.virtualbox_4_1.CleanupMode;
import org.virtualbox_4_1.DeviceType;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.IMedium;
import org.virtualbox_4_1.IProgress;
@ -38,48 +40,49 @@ import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.base.Function;
import com.google.common.base.Throwables;
public class UnregisterMachineIfExistsAndDeleteItsMedia implements Function<String, Void> {
public class UnregisterMachineIfExistsAndDeleteItsMedia implements Function<VmSpec, Void> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private VirtualBoxManager manager;
private CleanupMode mode;
public UnregisterMachineIfExistsAndDeleteItsMedia(VirtualBoxManager manager, CleanupMode mode) {
this.manager = manager;
this.mode = mode;
}
@Override
public Void apply(@Nullable String vmName) {
List<IMedium> mediaToBeDeleted = null;
public Void apply(VmSpec vmSpec) {
List<IMedium> mediaToBeDeleted = Collections.emptyList();
IMachine machine = null;
try {
machine = manager.getVBox().findMachine(vmName);
mediaToBeDeleted = machine.unregister(mode);
machine = manager.getVBox().findMachine(vmSpec.getVmName());
mediaToBeDeleted = machine.unregister(vmSpec.getCleanupMode());
} catch (VBoxException e) {
ErrorCode errorCode = ErrorCode.valueOf(e);
switch (errorCode) {
case VBOX_E_OBJECT_NOT_FOUND:
logger.debug("Machine %s does not exists, cannot unregister",
vmName);
vmSpec.getVmName());
break;
default:
throw e;
}
}
/**
* deletion of all files is currently disabled on Windows/x64 to prevent a
* crash
*/
try {
IProgress deletion = machine.delete(mediaToBeDeleted);
deletion.waitForCompletion(-1);
} catch (Exception e) {
logger.error(e, "Problem in deleting the media attached to %s", machine.getName());
propagate(e);
if(!mediaToBeDeleted.isEmpty()) {
try {
for (IMedium iMedium : mediaToBeDeleted) {
if(iMedium.getDeviceType().equals(DeviceType.HardDisk)) {
IProgress deletion = machine.delete(mediaToBeDeleted);
deletion.waitForCompletion(-1);
}
}
} catch (Exception e) {
logger.error(e, "Problem in deleting the media attached to %s", machine.getName());
propagate(e);
}
}
return null;
}

View File

@ -75,14 +75,27 @@ public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest {
private String ideControllerName = "IDE Controller";
private String guestId = "guest";
private String hostId = "host";
private String vmName = "jclouds-image-virtualbox-iso-to-machine-test";
private StorageController ideController;
private VmSpec vmSpecification;
@BeforeGroups(groups = {"live"})
public void setUp() throws Exception {
identity = "toor";
credential = "password";
new UnregisterMachineIfExistsAndDeleteItsMedia(manager, CleanupMode.Full).apply(vmName);
String workingDir = PropertyUtils.getWorkingDirFromProperty();
ideController = StorageController.builder().name(ideControllerName).bus(StorageBus.IDE)
.attachISO(0, 0, workingDir + "/ubuntu-11.04-server-i386.iso")
.attachHardDisk(0, 1, workingDir + "/testadmin.vdi")
.attachISO(1, 1, workingDir + "/VBoxGuestAdditions_4.1.2.iso").build();
vmSpecification = VmSpec.builder().id(vmId).name(vmName).memoryMB(512).osTypeId(osTypeId)
.controller(ideController)
.forceOverwrite(true)
.cleanUpMode(CleanupMode.DetachAllReturnHardDisksOnly)
.natNetworkAdapter(0, NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "", 22).build()).build();
new UnregisterMachineIfExistsAndDeleteItsMedia(manager, CleanupMode.Full).apply(vmSpecification);
}
public void testCreateImageMachineFromIso() throws Exception {
@ -92,15 +105,6 @@ public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest {
"localhost", new Credentials("toor", "password"));
Predicate<IPSocket> socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 10, 1, TimeUnit.SECONDS);
String workingDir = PropertyUtils.getWorkingDirFromProperty();
StorageController ideController = StorageController.builder().name(ideControllerName).bus(StorageBus.IDE)
.attachISO(0, 0, workingDir + "/ubuntu-11.04-server-i386.iso")
.attachHardDisk(0, 1, workingDir + "/testadmin.vdi")
.attachISO(1, 1, workingDir + "/VBoxGuestAdditions_4.1.2.iso").build();
VmSpec vmSpecification = VmSpec.builder().id(vmId).name(vmName).memoryMB(512).osTypeId(osTypeId)
.controller(ideController)
.forceOverwrite(true)
.natNetworkAdapter(0, NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "", 22).build()).build();
IMachine imageMachine = new CreateAndInstallVm(manager, guestId, localHostContext, hostId,
socketTester, "127.0.0.1", 8080, HEADLESS)
.apply(vmSpecification);

View File

@ -19,15 +19,24 @@
package org.jclouds.virtualbox.functions.admin;
import org.testng.annotations.Test;
import org.virtualbox_4_1.*;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.createNiceMock;
import static org.easymock.classextension.EasyMock.replay;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.expect;
import static org.easymock.classextension.EasyMock.*;
import org.jclouds.virtualbox.domain.VmSpec;
import org.testng.annotations.Test;
import org.virtualbox_4_1.CleanupMode;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.IMedium;
import org.virtualbox_4_1.IProgress;
import org.virtualbox_4_1.IVirtualBox;
import org.virtualbox_4_1.VirtualBoxManager;
@Test(groups = "unit", testName = "UnregisterMachineIfExistsTest")
public class UnregisterMachineIfExistsAndDeleteItsMediaTest {
@ -37,20 +46,29 @@ public class UnregisterMachineIfExistsAndDeleteItsMediaTest {
VirtualBoxManager manager = createMock(VirtualBoxManager.class);
IVirtualBox vBox = createMock(IVirtualBox.class);
IMachine registeredMachine = createMock(IMachine.class);
List<IMedium> mediums = Collections.emptyList();
IProgress progress = createNiceMock(IProgress.class);
List<IMedium> media = new ArrayList<IMedium>();
List<IMedium> mediums = Collections.unmodifiableList(media);
CleanupMode mode = CleanupMode.Full;
String vmName = "jclouds-image-example-machine";
String vmName = "jclouds-image-example-machine-to-be-destroyed";
String vmId = "jclouds-image-iso-unregister";
VmSpec vmSpecification = VmSpec.builder().id(vmId).name(vmName).memoryMB(512) .cleanUpMode(mode)
.build();
expect(manager.getVBox()).andReturn(vBox).anyTimes();
expect(vBox.findMachine(vmName)).andReturn(registeredMachine);
expect(registeredMachine.unregister(mode)).andReturn(mediums);
expectLastCall().anyTimes();
expect(registeredMachine.delete(mediums)).andReturn(progress);
expectLastCall().anyTimes();
replay(manager, vBox, registeredMachine);
replay(manager, vBox, registeredMachine, progress);
new UnregisterMachineIfExistsAndDeleteItsMedia(manager, mode).apply(vmName);
new UnregisterMachineIfExistsAndDeleteItsMedia(manager, mode).apply(vmSpecification);
}
}