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; 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.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; 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. * A description of a Virtual Machine in VirtualBox.
@ -39,8 +44,9 @@ public class VmSpec {
private final boolean forceOverwrite; private final boolean forceOverwrite;
private final Map<Long, NatAdapter> natNetworkAdapters; private final Map<Long, NatAdapter> natNetworkAdapters;
private final Set<StorageController> controllers; 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(vmId, "vmId");
checkNotNull(vmName, "vmName"); checkNotNull(vmName, "vmName");
checkArgument(memory > 0, "memory must be > 0"); checkArgument(memory > 0, "memory must be > 0");
@ -53,6 +59,7 @@ public class VmSpec {
this.controllers = controllers; this.controllers = controllers;
this.forceOverwrite = forceOverwrite; this.forceOverwrite = forceOverwrite;
this.natNetworkAdapters = natNetworkAdapters; this.natNetworkAdapters = natNetworkAdapters;
this.cleanupMode = cleanupMode;
} }
public static Builder builder() { public static Builder builder() {
@ -69,6 +76,8 @@ public class VmSpec {
private boolean forceOverwrite; private boolean forceOverwrite;
private Map<Long, NatAdapter> natNetworkAdapters = new HashMap<Long, NatAdapter>(); private Map<Long, NatAdapter> natNetworkAdapters = new HashMap<Long, NatAdapter>();
private long memory; private long memory;
private CleanupMode cleanUpMode;
public Builder controller(StorageController controller) { public Builder controller(StorageController controller) {
controllers.add(controller); controllers.add(controller);
return this; return this;
@ -103,12 +112,17 @@ public class VmSpec {
this.memory = (long) memorySize; this.memory = (long) memorySize;
return this; return this;
} }
public Builder cleanUpMode(CleanupMode cleanupMode) {
this.cleanUpMode = cleanupMode;
return this;
}
public VmSpec build() { public VmSpec build() {
checkNotNull(name, "name"); checkNotNull(name, "name");
checkNotNull(id, "id"); checkNotNull(id, "id");
checkArgument(memory > 0, "Memory must be set"); 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); return Collections.unmodifiableMap(natNetworkAdapters);
} }
public CleanupMode getCleanupMode() {
return cleanupMode;
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;

View File

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

View File

@ -75,14 +75,27 @@ public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest {
private String ideControllerName = "IDE Controller"; private String ideControllerName = "IDE Controller";
private String guestId = "guest"; private String guestId = "guest";
private String hostId = "host"; private String hostId = "host";
private String vmName = "jclouds-image-virtualbox-iso-to-machine-test"; private String vmName = "jclouds-image-virtualbox-iso-to-machine-test";
private StorageController ideController;
private VmSpec vmSpecification;
@BeforeGroups(groups = {"live"}) @BeforeGroups(groups = {"live"})
public void setUp() throws Exception { public void setUp() throws Exception {
identity = "toor"; identity = "toor";
credential = "password"; 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 { public void testCreateImageMachineFromIso() throws Exception {
@ -92,15 +105,6 @@ public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest {
"localhost", new Credentials("toor", "password")); "localhost", new Credentials("toor", "password"));
Predicate<IPSocket> socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 10, 1, TimeUnit.SECONDS); 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, IMachine imageMachine = new CreateAndInstallVm(manager, guestId, localHostContext, hostId,
socketTester, "127.0.0.1", 8080, HEADLESS) socketTester, "127.0.0.1", 8080, HEADLESS)
.apply(vmSpecification); .apply(vmSpecification);

View File

@ -19,15 +19,24 @@
package org.jclouds.virtualbox.functions.admin; package org.jclouds.virtualbox.functions.admin;
import org.testng.annotations.Test; import static org.easymock.EasyMock.expect;
import org.virtualbox_4_1.*; 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.Collections;
import java.util.List; import java.util.List;
import static org.easymock.classextension.EasyMock.createMock; import org.jclouds.virtualbox.domain.VmSpec;
import static org.easymock.classextension.EasyMock.expect; import org.testng.annotations.Test;
import static org.easymock.classextension.EasyMock.*; 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") @Test(groups = "unit", testName = "UnregisterMachineIfExistsTest")
public class UnregisterMachineIfExistsAndDeleteItsMediaTest { public class UnregisterMachineIfExistsAndDeleteItsMediaTest {
@ -37,20 +46,29 @@ public class UnregisterMachineIfExistsAndDeleteItsMediaTest {
VirtualBoxManager manager = createMock(VirtualBoxManager.class); VirtualBoxManager manager = createMock(VirtualBoxManager.class);
IVirtualBox vBox = createMock(IVirtualBox.class); IVirtualBox vBox = createMock(IVirtualBox.class);
IMachine registeredMachine = createMock(IMachine.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; 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(manager.getVBox()).andReturn(vBox).anyTimes();
expect(vBox.findMachine(vmName)).andReturn(registeredMachine); expect(vBox.findMachine(vmName)).andReturn(registeredMachine);
expect(registeredMachine.unregister(mode)).andReturn(mediums); expect(registeredMachine.unregister(mode)).andReturn(mediums);
expectLastCall().anyTimes(); 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);
} }
} }