improved nat rules to survive existing sets, and also made sure we lock machines before attempting to delete them

This commit is contained in:
Adrian Cole 2012-01-06 12:31:49 -08:00
parent 1255d91eef
commit dec63d7cbe
11 changed files with 119 additions and 49 deletions

View File

@ -27,18 +27,19 @@ import org.jclouds.virtualbox.domain.NatAdapter;
import org.jclouds.virtualbox.domain.RedirectRule; import org.jclouds.virtualbox.domain.RedirectRule;
import org.virtualbox_4_1.IMachine; import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.INetworkAdapter; import org.virtualbox_4_1.INetworkAdapter;
import org.virtualbox_4_1.VBoxException;
import com.google.common.base.Function; import com.google.common.base.Function;
/** /**
* @author Mattias Holmqvist * @author Mattias Holmqvist
*/ */
public class AttachNATAdapterToMachine implements Function<IMachine, Void> { public class AttachNATAdapterToMachineIfNotAlreadyExists implements Function<IMachine, Void> {
private long adapterSlot; private long adapterSlot;
private NatAdapter natAdapter; private NatAdapter natAdapter;
public AttachNATAdapterToMachine(long adapterSlot, NatAdapter natAdapter) { public AttachNATAdapterToMachineIfNotAlreadyExists(long adapterSlot, NatAdapter natAdapter) {
this.adapterSlot = adapterSlot; this.adapterSlot = adapterSlot;
this.natAdapter = natAdapter; this.natAdapter = natAdapter;
} }
@ -48,12 +49,15 @@ public class AttachNATAdapterToMachine implements Function<IMachine, Void> {
INetworkAdapter networkAdapter = machine.getNetworkAdapter(adapterSlot); INetworkAdapter networkAdapter = machine.getNetworkAdapter(adapterSlot);
networkAdapter.setAttachmentType(NAT); networkAdapter.setAttachmentType(NAT);
for (RedirectRule rule : natAdapter.getRedirectRules()) { for (RedirectRule rule : natAdapter.getRedirectRules()) {
networkAdapter.getNatDriver().addRedirect("guestssh", try {
rule.getProtocol(), String ruleName = String.format("%s@%s:%s->%s:%s",rule.getProtocol(), rule.getHost(), rule.getHostPort(),
rule.getHost(), rule.getGuest(), rule.getGuestPort());
rule.getHostPort(), networkAdapter.getNatDriver().addRedirect(ruleName, rule.getProtocol(), rule.getHost(), rule.getHostPort(),
rule.getGuest(), rule.getGuest(), rule.getGuestPort());
rule.getGuestPort()); } catch (VBoxException e) {
if (e.getMessage().indexOf("already exists") == -1)
throw e;
}
} }
networkAdapter.setEnabled(true); networkAdapter.setEnabled(true);
machine.saveSettings(); machine.saveSettings();

View File

@ -207,7 +207,7 @@ public class CreateAndInstallVm implements Function<VmSpec, IMachine> {
} }
private void ensureNATNetworkingIsAppliedToMachine(String vmName, long slotId, NatAdapter natAdapter) { private void ensureNATNetworkingIsAppliedToMachine(String vmName, long slotId, NatAdapter natAdapter) {
lockMachineAndApply(manager, Write, vmName, new AttachNATAdapterToMachine(slotId, natAdapter)); lockMachineAndApply(manager, Write, vmName, new AttachNATAdapterToMachineIfNotAlreadyExists(slotId, natAdapter));
} }
public void ensureMachineHasIDEControllerNamed(String vmName, StorageController storageController) { public void ensureMachineHasIDEControllerNamed(String vmName, StorageController storageController) {

View File

@ -161,7 +161,7 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExists implements Functi
} }
private void ensureNATNetworkingIsAppliedToMachine(String vmName, long slotId, NatAdapter natAdapter) { private void ensureNATNetworkingIsAppliedToMachine(String vmName, long slotId, NatAdapter natAdapter) {
lockMachineAndApply(manager, Write, vmName, new AttachNATAdapterToMachine(slotId, natAdapter)); lockMachineAndApply(manager, Write, vmName, new AttachNATAdapterToMachineIfNotAlreadyExists(slotId, natAdapter));
} }
public void ensureMachineHasStorageControllerNamed(String vmName, StorageController storageController) { public void ensureMachineHasStorageControllerNamed(String vmName, StorageController storageController) {

View File

@ -39,7 +39,6 @@ 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;
import org.virtualbox_4_1.VBoxException; import org.virtualbox_4_1.VBoxException;
import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
@ -47,24 +46,22 @@ import com.google.common.base.Throwables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
public class UnregisterMachineIfExistsAndDeleteItsMedia implements public class UnregisterMachineIfExistsAndDeleteItsMedia implements
Function<VmSpec, Void> { Function<IMachine, 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 final VmSpec vmSpec;
public UnregisterMachineIfExistsAndDeleteItsMedia(VirtualBoxManager manager) { public UnregisterMachineIfExistsAndDeleteItsMedia(VmSpec vmSpec) {
this.manager = manager; this.vmSpec = vmSpec;
} }
@Override @Override
public Void apply(VmSpec vmSpec) { public Void apply(IMachine machine) {
List<IMedium> mediaToBeDeleted = Collections.emptyList(); List<IMedium> mediaToBeDeleted = Collections.emptyList();
IMachine machine = null;
try { try {
machine = manager.getVBox().findMachine(vmSpec.getVmName());
mediaToBeDeleted = machine.unregister(vmSpec.getCleanupMode()); mediaToBeDeleted = machine.unregister(vmSpec.getCleanupMode());
} catch (VBoxException e) { } catch (VBoxException e) {
ErrorCode errorCode = ErrorCode.valueOf(e); ErrorCode errorCode = ErrorCode.valueOf(e);

View File

@ -19,8 +19,14 @@
package org.jclouds.virtualbox.util; package org.jclouds.virtualbox.util;
import org.jclouds.util.Throwables2;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.ISession;
import org.virtualbox_4_1.LockType;
import org.virtualbox_4_1.VBoxException;
import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.base.Function; import com.google.common.base.Function;
import org.virtualbox_4_1.*;
/** /**
* Utilities for executing functions on a VirtualBox machine. * Utilities for executing functions on a VirtualBox machine.
@ -101,4 +107,28 @@ public class MachineUtils {
type, e.getMessage()), e); type, e.getMessage()), e);
} }
} }
/**
* Locks the machine and executes the given function using the current session, if the machine is registered.
* Since the machine is locked it is possible to perform some modifications to the IMachine.
* <p/>
* Unlocks the machine before returning.
*
* @param manager the VirtualBoxManager
* @param type the kind of lock to use when initially locking the machine.
* @param machineId the id of the machine
* @param function the function to execute
* @return the result from applying the function to the session.
*/
public static <T> T lockMachineAndApplyOrReturnNullIfNotRegistered(VirtualBoxManager manager, LockType type, String machineId,
Function<IMachine, T> function) {
try {
return lockMachineAndApply(manager, type, machineId, function);
} catch (RuntimeException e) {
VBoxException vbex = Throwables2.getFirstThrowableOfType(e, VBoxException.class);
if (vbex != null && vbex.getMessage().indexOf("not find a registered") == -1)
throw e;
return null;
}
}
} }

View File

@ -19,6 +19,14 @@
package org.jclouds.virtualbox.functions; package org.jclouds.virtualbox.functions;
import static org.easymock.EasyMock.*;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.createNiceMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.easymock.classextension.EasyMock.verify;
import static org.virtualbox_4_1.NATProtocol.TCP;
import static org.virtualbox_4_1.NetworkAttachmentType.NAT;
import org.jclouds.virtualbox.domain.NatAdapter; import org.jclouds.virtualbox.domain.NatAdapter;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import org.virtualbox_4_1.IMachine; import org.virtualbox_4_1.IMachine;
@ -26,16 +34,11 @@ import org.virtualbox_4_1.INATEngine;
import org.virtualbox_4_1.INetworkAdapter; import org.virtualbox_4_1.INetworkAdapter;
import org.virtualbox_4_1.VBoxException; import org.virtualbox_4_1.VBoxException;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.*;
import static org.virtualbox_4_1.NATProtocol.TCP;
import static org.virtualbox_4_1.NetworkAttachmentType.NAT;
/** /**
* @author Mattias Holmqvist * @author Mattias Holmqvist
*/ */
@Test(groups = "unit", testName = "AttachNATAdapterToMachineTest") @Test(groups = "unit", testName = "AttachNATAdapterToMachineIfNotAlreadyExistsTest")
public class AttachNATAdapterToMachineTest { public class AttachNATAdapterToMachineIfNotAlreadyExistsTest {
@Test @Test
public void testApplyNetworkingToNonExistingAdapter() throws Exception { public void testApplyNetworkingToNonExistingAdapter() throws Exception {
@ -47,13 +50,39 @@ public class AttachNATAdapterToMachineTest {
expect(machine.getNetworkAdapter(slotId)).andReturn(networkAdapter); expect(machine.getNetworkAdapter(slotId)).andReturn(networkAdapter);
networkAdapter.setAttachmentType(NAT); networkAdapter.setAttachmentType(NAT);
expect(networkAdapter.getNatDriver()).andReturn(natEngine); expect(networkAdapter.getNatDriver()).andReturn(natEngine);
natEngine.addRedirect("guestssh", TCP, "127.0.0.1", 2222, "", 22);
natEngine.addRedirect("TCP@127.0.0.1:2222->guest:22", TCP, "127.0.0.1", 2222, "guest", 22);
networkAdapter.setEnabled(true); networkAdapter.setEnabled(true);
machine.saveSettings(); machine.saveSettings();
replay(machine, networkAdapter, natEngine); replay(machine, networkAdapter, natEngine);
NatAdapter natAdapter = NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "", 22).build(); NatAdapter natAdapter = NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "guest", 22).build();
new AttachNATAdapterToMachine(slotId, natAdapter).apply(machine); new AttachNATAdapterToMachineIfNotAlreadyExists(slotId, natAdapter).apply(machine);
verify(machine, networkAdapter, natEngine);
}
@Test
public void testApplySkipsWhenAlreadyExists() throws Exception {
Long slotId = 0l;
IMachine machine = createMock(IMachine.class);
INetworkAdapter networkAdapter = createMock(INetworkAdapter.class);
INATEngine natEngine = createMock(INATEngine.class);
expect(machine.getNetworkAdapter(slotId)).andReturn(networkAdapter);
networkAdapter.setAttachmentType(NAT);
expect(networkAdapter.getNatDriver()).andReturn(natEngine);
natEngine.addRedirect("TCP@127.0.0.1:2222->guest:22", TCP, "127.0.0.1", 2222, "guest", 22);
expectLastCall().andThrow(
new VBoxException(null, "VirtualBox error: A NAT rule of this name already exists (0x80070057)"));
networkAdapter.setEnabled(true);
machine.saveSettings();
replay(machine, networkAdapter, natEngine);
NatAdapter natAdapter = NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "guest", 22).build();
new AttachNATAdapterToMachineIfNotAlreadyExists(slotId, natAdapter).apply(machine);
verify(machine, networkAdapter, natEngine); verify(machine, networkAdapter, natEngine);
} }
@ -73,8 +102,8 @@ public class AttachNATAdapterToMachineTest {
replay(machine, networkAdapter, natEngine); replay(machine, networkAdapter, natEngine);
NatAdapter natAdapter = NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "", 22).build(); NatAdapter natAdapter = NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "guest", 22).build();
new AttachNATAdapterToMachine(slotId, natAdapter).apply(machine); new AttachNATAdapterToMachineIfNotAlreadyExists(slotId, natAdapter).apply(machine);
verify(machine, networkAdapter, natEngine); verify(machine, networkAdapter, natEngine);
} }

View File

@ -20,7 +20,9 @@
package org.jclouds.virtualbox.functions; package org.jclouds.virtualbox.functions;
import static org.jclouds.virtualbox.experiment.TestUtils.computeServiceForLocalhostAndGuest; import static org.jclouds.virtualbox.experiment.TestUtils.computeServiceForLocalhostAndGuest;
import static org.jclouds.virtualbox.util.MachineUtils.lockMachineAndApplyOrReturnNullIfNotRegistered;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.virtualbox_4_1.LockType.Write;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
@ -36,6 +38,8 @@ import org.virtualbox_4_1.ISession;
import org.virtualbox_4_1.StorageBus; import org.virtualbox_4_1.StorageBus;
import org.virtualbox_4_1.VirtualBoxManager; import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.collect.ImmutableSet;
/** /**
* @author Andrea Turli * @author Andrea Turli
*/ */
@ -79,8 +83,8 @@ public class CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest extends
IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists( IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(
manager, workingDir, clonedVmSpec, IS_LINKED_CLONE).apply(master); manager, workingDir, clonedVmSpec, IS_LINKED_CLONE).apply(master);
assertEquals(clone.getName(), clonedVmSpec.getVmName()); assertEquals(clone.getName(), clonedVmSpec.getVmName());
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(clonedVmSpec); for (VmSpec spec : ImmutableSet.of(clonedVmSpec, new IMachineToVmSpec().apply(master)))
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(new IMachineToVmSpec().apply(master)); lockMachineAndApplyOrReturnNullIfNotRegistered(manager, Write, spec.getVmName(), new UnregisterMachineIfExistsAndDeleteItsMedia(spec));
} }
private IMachine getMasterNode(VirtualBoxManager manager, private IMachine getMasterNode(VirtualBoxManager manager,

View File

@ -24,7 +24,9 @@ import static com.google.common.collect.Iterables.any;
import static com.google.common.collect.Iterables.transform; import static com.google.common.collect.Iterables.transform;
import static org.jclouds.virtualbox.domain.ExecutionType.HEADLESS; import static org.jclouds.virtualbox.domain.ExecutionType.HEADLESS;
import static org.jclouds.virtualbox.experiment.TestUtils.computeServiceForLocalhostAndGuest; import static org.jclouds.virtualbox.experiment.TestUtils.computeServiceForLocalhostAndGuest;
import static org.jclouds.virtualbox.util.MachineUtils.lockMachineAndApplyOrReturnNullIfNotRegistered;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
import static org.virtualbox_4_1.LockType.Write;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -94,8 +96,7 @@ public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest {
.forceOverwrite(true) .forceOverwrite(true)
.cleanUpMode(CleanupMode.Full) .cleanUpMode(CleanupMode.Full)
.natNetworkAdapter(0, NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "", 22).build()).build(); .natNetworkAdapter(0, NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "", 22).build()).build();
lockMachineAndApplyOrReturnNullIfNotRegistered(manager, Write, vmName, new UnregisterMachineIfExistsAndDeleteItsMedia(vmSpecification));
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(vmSpecification);
} }
public void testCreateImageMachineFromIso() throws Exception { public void testCreateImageMachineFromIso() throws Exception {

View File

@ -19,8 +19,10 @@
package org.jclouds.virtualbox.functions; package org.jclouds.virtualbox.functions;
import static org.jclouds.virtualbox.util.MachineUtils.lockMachineAndApplyOrReturnNullIfNotRegistered;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail; import static org.testng.Assert.fail;
import static org.virtualbox_4_1.LockType.Write;
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest; import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
import org.jclouds.virtualbox.domain.ErrorCode; import org.jclouds.virtualbox.domain.ErrorCode;
@ -68,14 +70,14 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest extends
VmSpec launchSpecification = VmSpec.builder().id(vmName).name(vmName) VmSpec launchSpecification = VmSpec.builder().id(vmName).name(vmName)
.memoryMB(512).controller(ideController).cleanUpMode(mode) .memoryMB(512).controller(ideController).cleanUpMode(mode)
.osTypeId("Debian").forceOverwrite(true).build(); .osTypeId("Debian").forceOverwrite(true).build();
new UnregisterMachineIfExistsAndDeleteItsMedia(manager) lockMachineAndApplyOrReturnNullIfNotRegistered(manager, Write, launchSpecification.getVmName(), new UnregisterMachineIfExistsAndDeleteItsMedia(launchSpecification));
.apply(launchSpecification);
IMachine debianNode = new CreateAndRegisterMachineFromIsoIfNotAlreadyExists( IMachine debianNode = new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(
manager, workingDir).apply(launchSpecification); manager, workingDir).apply(launchSpecification);
IMachine machine = manager.getVBox().findMachine(vmName); IMachine machine = manager.getVBox().findMachine(vmName);
assertEquals(debianNode.getName(), machine.getName()); assertEquals(debianNode.getName(), machine.getName());
new UnregisterMachineIfExistsAndDeleteItsMedia(manager) lockMachineAndApplyOrReturnNullIfNotRegistered(manager, Write, launchSpecification.getVmName(), new UnregisterMachineIfExistsAndDeleteItsMedia(launchSpecification));
.apply(launchSpecification);
} }
@Test @Test
@ -84,8 +86,7 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest extends
VmSpec launchSpecification = VmSpec.builder().id(vmName).name(vmName) VmSpec launchSpecification = VmSpec.builder().id(vmName).name(vmName)
.memoryMB(512).controller(ideController).cleanUpMode(mode) .memoryMB(512).controller(ideController).cleanUpMode(mode)
.osTypeId("SomeWeirdUnknownOs").forceOverwrite(true).build(); .osTypeId("SomeWeirdUnknownOs").forceOverwrite(true).build();
new UnregisterMachineIfExistsAndDeleteItsMedia(manager) lockMachineAndApplyOrReturnNullIfNotRegistered(manager, Write, launchSpecification.getVmName(), new UnregisterMachineIfExistsAndDeleteItsMedia(launchSpecification));
.apply(launchSpecification);
try { try {
new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(manager, workingDir) new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(manager, workingDir)

View File

@ -81,7 +81,7 @@ public class UnregisterMachineIfExistsAndDeleteItsMediaTest {
replay(manager, vBox, registeredMachine, progress); replay(manager, vBox, registeredMachine, progress);
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(vmSpecification); new UnregisterMachineIfExistsAndDeleteItsMedia(vmSpecification).apply(registeredMachine);
} }
} }

View File

@ -19,8 +19,10 @@
package org.jclouds.virtualbox.predicates; package org.jclouds.virtualbox.predicates;
import static org.jclouds.virtualbox.util.MachineUtils.lockMachineAndApplyOrReturnNullIfNotRegistered;
import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
import static org.virtualbox_4_1.LockType.Write;
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest; import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
import org.jclouds.virtualbox.domain.HardDisk; import org.jclouds.virtualbox.domain.HardDisk;
@ -37,6 +39,8 @@ import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.StorageBus; import org.virtualbox_4_1.StorageBus;
import org.virtualbox_4_1.VirtualBoxManager; import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.collect.ImmutableSet;
/** /**
* *
* @author Andrea Turli * @author Andrea Turli
@ -75,28 +79,28 @@ public class IsLinkedClonesLiveTest extends BaseVirtualBoxClientLiveTest {
public void testLinkedClone() { public void testLinkedClone() {
VirtualBoxManager manager = (VirtualBoxManager) context.getProviderSpecificContext().getApi(); VirtualBoxManager manager = (VirtualBoxManager) context.getProviderSpecificContext().getApi();
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(masterSpec); lockMachineAndApplyOrReturnNullIfNotRegistered(manager, Write, masterSpec.getVmName(), new UnregisterMachineIfExistsAndDeleteItsMedia(masterSpec));
IMachine master = new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(manager, workingDir).apply(masterSpec); IMachine master = new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(manager, workingDir).apply(masterSpec);
IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(manager, workingDir, cloneSpec, IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(manager, workingDir, cloneSpec,
IS_LINKED_CLONE).apply(master); IS_LINKED_CLONE).apply(master);
assertTrue(new IsLinkedClone(manager).apply(clone)); assertTrue(new IsLinkedClone(manager).apply(clone));
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(new IMachineToVmSpec().apply(clone)); for (VmSpec spec : ImmutableSet.of(new IMachineToVmSpec().apply(clone), masterSpec))
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(masterSpec); lockMachineAndApplyOrReturnNullIfNotRegistered(manager, Write, spec.getVmName(), new UnregisterMachineIfExistsAndDeleteItsMedia(spec));
} }
public void testFullClone() { public void testFullClone() {
VirtualBoxManager manager = (VirtualBoxManager) context.getProviderSpecificContext().getApi(); VirtualBoxManager manager = (VirtualBoxManager) context.getProviderSpecificContext().getApi();
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(masterSpec); lockMachineAndApplyOrReturnNullIfNotRegistered(manager, Write, masterSpec.getVmName(), new UnregisterMachineIfExistsAndDeleteItsMedia(masterSpec));
IMachine master = new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(manager, workingDir).apply(masterSpec); IMachine master = new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(manager, workingDir).apply(masterSpec);
IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(manager, workingDir, cloneSpec, IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(manager, workingDir, cloneSpec,
!IS_LINKED_CLONE).apply(master); !IS_LINKED_CLONE).apply(master);
assertFalse(new IsLinkedClone(manager).apply(clone)); assertFalse(new IsLinkedClone(manager).apply(clone));
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(new IMachineToVmSpec().apply(clone)); for (VmSpec spec : ImmutableSet.of(new IMachineToVmSpec().apply(clone), masterSpec))
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(masterSpec); lockMachineAndApplyOrReturnNullIfNotRegistered(manager, Write, spec.getVmName(), new UnregisterMachineIfExistsAndDeleteItsMedia(spec));
} }
} }