Merge pull request #290 from andreaturli/islinkedclone

issue 384: add isLinkedClone, modified CloneAndregister and ...
This commit is contained in:
Adrian Cole 2012-01-05 08:38:16 -08:00
commit 0ac7ee69ab
7 changed files with 439 additions and 145 deletions

View File

@ -19,28 +19,31 @@
package org.jclouds.virtualbox.functions;
import com.google.common.base.Function;
import com.google.inject.Inject;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.virtualbox_4_1.*;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import javax.annotation.Resource;
import javax.inject.Named;
import java.util.ArrayList;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.virtualbox.util.MachineUtils.lockMachineAndApply;
import static org.virtualbox_4_1.LockType.Write;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.virtualbox.domain.VmSpec;
import org.jclouds.virtualbox.util.PropertyUtils;
import org.virtualbox_4_1.CloneMode;
import org.virtualbox_4_1.CloneOptions;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.IProgress;
import org.virtualbox_4_1.ISnapshot;
import org.virtualbox_4_1.VBoxException;
import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.base.Function;
import com.google.inject.Inject;
/**
* CloneAndRegisterMachineFromIMachineIfNotAlreadyExists will take care of the
* followings: - cloning the master - register the clone machine -
* ensureBridgedNetworkingIsAppliedToMachine(cloneName, macAddress,
* hostInterface)
*
* @author Andrea Turli
*/
@ -51,45 +54,25 @@ public class CloneAndRegisterMachineFromIMachineIfNotAlreadyExists implements Fu
protected Logger logger = Logger.NULL;
private VirtualBoxManager manager;
private ComputeServiceContext context;
private String settingsFile;
private String osTypeId;
private String vmId;
private boolean forceOverwrite;
private String cloneName;
private String hostId;
private String snapshotName;
private String snapshotDesc;
private String controllerIDE;
private VmSpec vmSpec;
boolean isLinkedClone;
@Inject
public CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(
VirtualBoxManager manager, ComputeServiceContext context,
String settingsFile, String osTypeId, String vmId,
boolean forceOverwrite, String cloneName, String hostId,
String snapshotName, String snapshotDesc, String controllerIDE) {
VirtualBoxManager manager, VmSpec vmSpec, boolean isLinkedClone) {
this.manager = manager;
this.context = context;
this.settingsFile = settingsFile;
this.osTypeId = osTypeId;
this.vmId = vmId;
this.forceOverwrite = forceOverwrite;
this.cloneName = cloneName;
this.hostId = hostId;
this.snapshotName = snapshotName;
this.snapshotDesc = snapshotDesc;
this.controllerIDE = controllerIDE;
this.vmSpec = vmSpec;
this.isLinkedClone = isLinkedClone;
}
@Override
public IMachine apply(@Nullable IMachine master) {
final IVirtualBox vBox = manager.getVBox();
try {
vBox.findMachine(cloneName);
throw new IllegalStateException("Machine " + cloneName + " is already registered.");
manager.getVBox().findMachine(vmSpec.getVmName());
throw new IllegalStateException("Machine " + vmSpec.getVmName() + " is already registered.");
} catch (VBoxException e) {
if (machineNotFoundException(e))
return cloneMachine(cloneName, master);
return cloneMachine(vmSpec, master);
else
throw e;
}
@ -99,13 +82,16 @@ public class CloneAndRegisterMachineFromIMachineIfNotAlreadyExists implements Fu
return e.getMessage().contains("VirtualBox error: Could not find a registered machine named ");
}
private IMachine cloneMachine(String cloneName, IMachine master) {
IMachine clonedMachine = manager.getVBox().createMachine(settingsFile, cloneName, osTypeId, vmId, forceOverwrite);
private IMachine cloneMachine(VmSpec vmSpec, IMachine master) {
String workingDir = PropertyUtils.getWorkingDirFromProperty();
String settingsFile = manager.getVBox().composeMachineFilename(vmSpec.getVmName(), workingDir);
IMachine clonedMachine = manager.getVBox().createMachine(settingsFile, vmSpec.getVmName(), vmSpec.getOsTypeId(), vmSpec.getVmId(), vmSpec.isForceOverwrite());
List<CloneOptions> options = new ArrayList<CloneOptions>();
options.add(CloneOptions.Link);
if(isLinkedClone)
options.add(CloneOptions.Link);
// takeSnapshotIfNotAlreadyExists
ISnapshot currentSnapshot = new TakeSnapshotIfNotAlreadyAttached(manager, snapshotName, snapshotDesc).apply(master);
// TODO snapshot name
ISnapshot currentSnapshot = new TakeSnapshotIfNotAlreadyAttached(manager, "snapshotName", "snapshotDesc").apply(master);
// clone
IProgress progress = currentSnapshot.getMachine().cloneTo(clonedMachine, CloneMode.MachineState, options);
@ -115,32 +101,7 @@ public class CloneAndRegisterMachineFromIMachineIfNotAlreadyExists implements Fu
// registering
manager.getVBox().registerMachine(clonedMachine);
// Bridged Network
List<String> activeBridgedInterfaces = new RetrieveActiveBridgedInterfaces(context).apply(hostId);
checkNotNull(activeBridgedInterfaces);
String macAddress = manager.getVBox().getHost().generateMACAddress();
// TODO this behavior can be improved
String bridgedInterface = activeBridgedInterfaces.get(0);
long adapterSlot = 0l;
ensureBridgedNetworkingIsAppliedToMachine(adapterSlot, cloneName, macAddress, bridgedInterface);
// detach iso
// TODO: also hard-coded values here
int controllerPort = 0;
int device = 0;
ensureMachineHasDistroMediumDetached(cloneName, controllerIDE, controllerPort, device);
return clonedMachine;
}
private void ensureBridgedNetworkingIsAppliedToMachine(long adapterSlot, String vmName, String macAddress, String hostInterface) {
lockMachineAndApply(manager, Write, vmName, new AttachBridgedAdapterToMachine(adapterSlot, macAddress, hostInterface));
}
private void ensureMachineHasDistroMediumDetached(String vmName, String controllerIDE, int controllerPort, int device) {
lockMachineAndApply(manager, Write, vmName, new DetachDistroMediumFromMachine(checkNotNull(controllerIDE, "controllerIDE"), controllerPort, device));
}
}

View File

@ -19,20 +19,45 @@
package org.jclouds.virtualbox.functions;
import com.google.common.base.Function;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.virtualbox.util.MachineUtils.lockMachineAndApply;
import static org.virtualbox_4_1.LockType.Write;
import java.io.File;
import java.util.Map;
import java.util.Set;
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.DeviceDetails;
import org.jclouds.virtualbox.domain.HardDisk;
import org.jclouds.virtualbox.domain.IsoImage;
import org.jclouds.virtualbox.domain.NatAdapter;
import org.jclouds.virtualbox.domain.StorageController;
import org.jclouds.virtualbox.domain.VmSpec;
import org.jclouds.virtualbox.util.PropertyUtils;
import org.virtualbox_4_1.AccessMode;
import org.virtualbox_4_1.DeviceType;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.IMedium;
import org.virtualbox_4_1.IVirtualBox;
import org.virtualbox_4_1.VBoxException;
import org.virtualbox_4_1.VirtualBoxManager;
import javax.annotation.Nullable;
import com.google.common.base.Function;
/**
* @author Mattias Holmqvist
*/
public class CreateAndRegisterMachineFromIsoIfNotAlreadyExists implements Function<VmSpec, IMachine> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private VirtualBoxManager manager;
public CreateAndRegisterMachineFromIsoIfNotAlreadyExists(VirtualBoxManager manager) {
@ -58,12 +83,81 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExists implements Functi
return e.getMessage().contains("VirtualBox error: Could not find a registered machine named ");
}
private IMachine createMachine(IVirtualBox vBox, VmSpec launchSpecification) {
// TODO: add support for settingsfile
String settingsFile1 = null;
IMachine newMachine = vBox.createMachine(settingsFile1, launchSpecification.getVmName(),
launchSpecification.getOsTypeId(), launchSpecification.getVmId(), launchSpecification.isForceOverwrite());
private IMachine createMachine(IVirtualBox vBox, VmSpec vmSpec) {
String workingDir = PropertyUtils.getWorkingDirFromProperty();
String settingsFile = vBox.composeMachineFilename(vmSpec.getVmName() , workingDir);
IMachine newMachine = vBox.createMachine(settingsFile, vmSpec.getVmName(),
vmSpec.getOsTypeId(), vmSpec.getVmId(), vmSpec.isForceOverwrite());
manager.getVBox().registerMachine(newMachine);
String vmName = vmSpec.getVmName();
// Change RAM
ensureMachineHasMemory(vmName, vmSpec.getMemory());
Set<StorageController> controllers = vmSpec.getControllers();
if (controllers.isEmpty()) {
throw new IllegalStateException(missingIDEControllersMessage(vmSpec));
}
StorageController controller = controllers.iterator().next();
ensureMachineHasStorageControllerNamed(vmName, controller);
setupHardDisksForController(vmName, controller);
setupDvdsForController(vmSpec, vmName, controller);
// NAT
Map<Long, NatAdapter> natNetworkAdapters = vmSpec.getNatNetworkAdapters();
for (Map.Entry<Long, NatAdapter> natAdapterAndSlot : natNetworkAdapters.entrySet()) {
long slotId = natAdapterAndSlot.getKey();
NatAdapter natAdapter = natAdapterAndSlot.getValue();
ensureNATNetworkingIsAppliedToMachine(vmName, slotId, natAdapter);
}
return newMachine;
}
private void setupDvdsForController(VmSpec vmSpecification, String vmName, StorageController controller) {
Set<IsoImage> dvds = controller.getIsoImages();
for (IsoImage dvd : dvds) {
String dvdSource = dvd.getSourcePath();
final IMedium dvdMedium = manager.getVBox().openMedium(dvdSource, DeviceType.DVD,
AccessMode.ReadOnly, vmSpecification.isForceOverwrite());
ensureMachineDevicesAttached(vmName, dvdMedium, dvd.getDeviceDetails(), controller.getName());
}
}
private void ensureMachineDevicesAttached(String vmName, IMedium medium, DeviceDetails deviceDetails, String controllerName) {
lockMachineAndApply(manager, Write, vmName, new AttachMediumToMachineIfNotAlreadyAttached(deviceDetails, medium, controllerName));
}
private String missingIDEControllersMessage(VmSpec vmSpecification) {
return String.format("First controller is not an IDE controller. Please verify that the VM spec is a correct master node: %s", vmSpecification);
}
private void setupHardDisksForController(String vmName, StorageController controller) {
Set<HardDisk> hardDisks = controller.getHardDisks();
for (HardDisk hardDisk : hardDisks) {
String sourcePath = hardDisk.getDiskPath();
if (new File(sourcePath).exists()) {
boolean deleted = new File(sourcePath).delete();
if (!deleted) {
logger.error(String.format("File %s could not be deleted.", sourcePath));
}
}
IMedium medium = new CreateMediumIfNotAlreadyExists(manager, true).apply(hardDisk);
ensureMachineDevicesAttached(vmName, medium, hardDisk.getDeviceDetails(), controller.getName());
}
}
private void ensureMachineHasMemory(String vmName, final long memorySize) {
lockMachineAndApply(manager, Write, vmName, new ApplyMemoryToMachine(memorySize));
}
private void ensureNATNetworkingIsAppliedToMachine(String vmName, long slotId, NatAdapter natAdapter) {
lockMachineAndApply(manager, Write, vmName, new AttachNATAdapterToMachine(slotId, natAdapter));
}
public void ensureMachineHasStorageControllerNamed(String vmName, StorageController storageController) {
lockMachineAndApply(manager, Write, checkNotNull(vmName, "vmName"),
new AddIDEControllerIfNotExists(checkNotNull(storageController, "storageController")));
}
}

View File

@ -20,6 +20,8 @@ U * Licensed to jclouds, Inc. (jclouds) under one or more
package org.jclouds.virtualbox.functions.admin;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.transform;
import java.util.Collections;
import java.util.List;
@ -32,6 +34,7 @@ import org.jclouds.logging.Logger;
import org.jclouds.virtualbox.domain.ErrorCode;
import org.jclouds.virtualbox.domain.StorageController;
import org.jclouds.virtualbox.domain.VmSpec;
import org.virtualbox_4_1.DeviceType;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.IMedium;
import org.virtualbox_4_1.IProgress;
@ -41,7 +44,6 @@ import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
public class UnregisterMachineIfExistsAndDeleteItsMedia implements
@ -76,15 +78,15 @@ public class UnregisterMachineIfExistsAndDeleteItsMedia implements
}
}
List<IMedium> filteredMediaToBeDeleted = Lists.newArrayList(Iterables
.filter(mediaToBeDeleted, new AutoDeleteHardDiskPredicate(vmSpec)));
List<IMedium> filteredMediaToBeDeleted = Lists.newArrayList(transform(
filter(mediaToBeDeleted, new AutoDeleteHardDiskPredicate(vmSpec)),
new DeleteChildrenOfMedium()));
checkNotNull(filteredMediaToBeDeleted);
if (!filteredMediaToBeDeleted.isEmpty()) {
try {
IProgress deletion = machine.delete(filteredMediaToBeDeleted);
deletion.waitForCompletion(-1);
} catch (Exception e) {
logger.error(e, "Problem in deleting the media attached to %s",
machine.getName());
@ -113,4 +115,20 @@ public class UnregisterMachineIfExistsAndDeleteItsMedia implements
};
private class DeleteChildrenOfMedium implements Function<IMedium, IMedium> {
@Override
public IMedium apply(IMedium medium) {
checkNotNull(medium.getChildren());
if (medium.getDeviceType().equals(DeviceType.HardDisk)) {
for (IMedium child : medium.getChildren()) {
IProgress deletion = child.deleteStorage();
deletion.waitForCompletion(-1);
}
}
return medium;
}
};
}

View File

@ -0,0 +1,88 @@
/*
* 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.predicates;
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.virtualbox_4_1.DeviceType;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.IMedium;
import org.virtualbox_4_1.IMediumAttachment;
import org.virtualbox_4_1.IStorageController;
import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.base.Predicate;
/**
*
* @author Andrea Turli
*/
public class IsLinkedClone implements Predicate<IMachine> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private VirtualBoxManager manager;
public IsLinkedClone(VirtualBoxManager manager) {
this.manager = manager;
}
@Override
public boolean apply(@Nullable IMachine machine) {
for (IStorageController iStorageController : machine
.getStorageControllers()) {
for (IMediumAttachment iMediumAttachment : machine
.getMediumAttachmentsOfController(iStorageController.getName())) {
IMedium iMedium = iMediumAttachment.getMedium();
if (iMedium.getDeviceType().equals(DeviceType.HardDisk)) {
if (iMedium.getParent() != null) {
// more than one machine is attached to this hd
for (IMedium child : iMedium.getParent().getChildren()) {
for (String machineId : child.getMachineIds()) {
IMachine iMachine = manager.getVBox().findMachine(
machineId);
if (!iMachine.getName().equals(machine.getName())) {
logger.debug("Machine %s is a linked clone",
machine.getName());
return true;
}
}
}
}
}
}
}
return false;
}
@Override
public String toString() {
return "IsLinkedClone()";
}
}

View File

@ -19,22 +19,16 @@
package org.jclouds.virtualbox.functions;
import static org.jclouds.virtualbox.domain.ExecutionType.HEADLESS;
import static org.jclouds.virtualbox.experiment.TestUtils.computeServiceForLocalhostAndGuest;
import static org.testng.Assert.assertEquals;
import static org.virtualbox_4_1.NetworkAttachmentType.Bridged;
import java.util.concurrent.TimeUnit;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.domain.Credentials;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
import org.jclouds.virtualbox.domain.HardDisk;
import org.jclouds.virtualbox.domain.StorageController;
import org.jclouds.virtualbox.domain.VmSpec;
import org.jclouds.virtualbox.functions.admin.UnregisterMachineIfExistsAndDeleteItsMedia;
import org.jclouds.virtualbox.util.PropertyUtils;
import org.testng.annotations.Test;
import org.virtualbox_4_1.CleanupMode;
@ -43,64 +37,72 @@ import org.virtualbox_4_1.ISession;
import org.virtualbox_4_1.StorageBus;
import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.base.Predicate;
/**
* @author Andrea Turli
*/
@Test(groups = "live", singleThreaded = true, testName = "CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest")
public class CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest extends BaseVirtualBoxClientLiveTest {
public class CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest extends
BaseVirtualBoxClientLiveTest {
private String settingsFile = null;
private boolean forceOverwrite = true;
private static final boolean IS_LINKED_CLONE = true;
private String vmId = "jclouds-image-iso-1";
private String osTypeId = "";
private String controllerIDE = "IDE Controller";
private String osTypeId = "DEBIAN";
private String guestId = "guest";
private String hostId = "host";
private String snapshotName = "snap";
private String snapshotDesc = "snapDesc";
private String vmName = "jclouds-image-virtualbox-iso-to-machine-test";
private String cloneName = vmName + "_clone";
private VmSpec clonedVmSpec;
private String ideControllerName = "IDE Controller";
private CleanupMode mode = CleanupMode.Full;
@Test
public void testCloneMachineFromAnotherMachine() throws Exception {
VirtualBoxManager manager = (VirtualBoxManager) context.getProviderSpecificContext().getApi();
ComputeServiceContext localHostContext =
computeServiceForLocalhostAndGuest(hostId, "localhost", guestId, "localhost", new Credentials("toor", "password"));
VirtualBoxManager manager = (VirtualBoxManager) context
.getProviderSpecificContext().getApi();
ComputeServiceContext localHostContext = computeServiceForLocalhostAndGuest(
hostId, "localhost", guestId, "localhost", new Credentials("toor",
"password"));
IMachine master = getMasterNode(manager, localHostContext);
if (master.getCurrentSnapshot() != null) {
ISession session = manager.openMachineSession(master);
session.getConsole().deleteSnapshot(master.getCurrentSnapshot().getId());
session.getConsole().deleteSnapshot(
master.getCurrentSnapshot().getId());
session.unlockMachine();
}
clonedVmSpec = VmSpec.builder().id(cloneName).name(cloneName).memoryMB(512)
.cleanUpMode(mode)
.forceOverwrite(true).build();
IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(
manager, localHostContext, settingsFile, osTypeId, vmId,
forceOverwrite, cloneName, hostId, snapshotName, snapshotDesc,
controllerIDE).apply(master);
assertEquals(clone.getNetworkAdapter(0L).getAttachmentType(), Bridged);
manager, clonedVmSpec, IS_LINKED_CLONE).apply(master);
assertEquals(clone.getName(), clonedVmSpec.getVmName());
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(clonedVmSpec);
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(new IMachineToVmSpec().apply(master));
}
private IMachine getMasterNode(VirtualBoxManager manager, ComputeServiceContext localHostContext) {
private IMachine getMasterNode(VirtualBoxManager manager,
ComputeServiceContext localHostContext) {
try {
Predicate<IPSocket> socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 10, 1, TimeUnit.SECONDS);
String workingDir = PropertyUtils.getWorkingDirFromProperty();
StorageController ideController = StorageController.builder().name(controllerIDE).bus(StorageBus.IDE)
.attachISO(0, 0, workingDir + "/ubuntu-11.04-server-i386.iso")
.attachHardDisk(HardDisk.builder().diskpath(workingDir + "/testadmin.vdi")
.controllerPort(0).deviceSlot(1).build())
.attachISO(1, 1, workingDir + "/VBoxGuestAdditions_4.1.2.iso").build();
VmSpec vmSpecification = VmSpec.builder().id(vmId).name(vmName).osTypeId(osTypeId)
.memoryMB(512)
.cleanUpMode(CleanupMode.Full)
.controller(ideController)
.forceOverwrite(true).build();
return new CreateAndInstallVm(manager, guestId, localHostContext, hostId, socketTester,
"127.0.0.1", 8080, HEADLESS).apply(vmSpecification);
StorageController ideController = StorageController
.builder()
.name(ideControllerName)
.bus(StorageBus.IDE)
.attachISO(0, 0, workingDir + "/ubuntu-11.04-server-i386.iso")
.attachHardDisk(
HardDisk.builder().diskpath(workingDir + "/testadmin.vdi")
.controllerPort(0).deviceSlot(1).build())
.attachISO(1, 1, workingDir + "/VBoxGuestAdditions_4.1.2.iso")
.build();
VmSpec vmSpec = VmSpec.builder().id(vmId).name(vmName)
.osTypeId(osTypeId).memoryMB(512).cleanUpMode(CleanupMode.Full)
.controller(ideController).forceOverwrite(true).build();
return new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(manager).apply(vmSpec);
} catch (IllegalStateException e) {
// already created
return manager.getVBox().findMachine(vmName);

View File

@ -39,45 +39,59 @@ import org.virtualbox_4_1.VBoxException;
/**
* @author Mattias Holmqvist
*/
public class CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest extends BaseVirtualBoxClientLiveTest {
@Test(groups = "live", singleThreaded = true, testName = "CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest")
public class CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest extends
BaseVirtualBoxClientLiveTest {
private String ideControllerName;
private CleanupMode mode;
private StorageController ideController;
@BeforeMethod
public void setUp() {
ideControllerName = "IDE Controller";
mode = CleanupMode.Full;
String workingDir = PropertyUtils.getWorkingDirFromProperty();
ideController = StorageController.builder().name(ideControllerName).bus(StorageBus.IDE)
.attachISO(0, 0, workingDir + "/ubuntu-11.04-server-i386.iso")
.attachHardDisk(HardDisk.builder().diskpath(workingDir + "/testadmin.vdi")
.controllerPort(0).deviceSlot(1).build())
.attachISO(1, 1, workingDir + "/VBoxGuestAdditions_4.1.2.iso").build();
}
private StorageController ideController;
@Test
@BeforeMethod
public void setUp() {
ideControllerName = "IDE Controller";
mode = CleanupMode.Full;
String workingDir = PropertyUtils.getWorkingDirFromProperty();
ideController = StorageController
.builder()
.name(ideControllerName)
.bus(StorageBus.IDE)
.attachISO(0, 0, workingDir + "/ubuntu-11.04-server-i386.iso")
.attachHardDisk(
HardDisk.builder().diskpath(workingDir + "/testadmin.vdi")
.controllerPort(0).deviceSlot(1).build())
.attachISO(1, 1, workingDir + "/VBoxGuestAdditions_4.1.2.iso")
.build();
}
@Test
public void testCreateNewMachine() throws Exception {
String vmName = "jclouds-test-create-1-node";
VmSpec launchSpecification = VmSpec.builder().id(vmName).name(vmName).memoryMB(512).controller(ideController).cleanUpMode(mode)
VmSpec launchSpecification = VmSpec.builder().id(vmName).name(vmName)
.memoryMB(512).controller(ideController).cleanUpMode(mode)
.osTypeId("Debian").forceOverwrite(true).build();
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(launchSpecification);
IMachine debianNode = new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(manager).apply(launchSpecification);
new UnregisterMachineIfExistsAndDeleteItsMedia(manager)
.apply(launchSpecification);
IMachine debianNode = new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(
manager).apply(launchSpecification);
IMachine machine = manager.getVBox().findMachine(vmName);
assertEquals(debianNode.getName(), machine.getName());
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(launchSpecification);
new UnregisterMachineIfExistsAndDeleteItsMedia(manager)
.apply(launchSpecification);
}
@Test
public void testCreateNewMachineWithBadOsType() throws Exception {
String vmName = "jclouds-test-create-2-node";
VmSpec launchSpecification = VmSpec.builder().id(vmName).name(vmName).memoryMB(512).controller(ideController).cleanUpMode(mode)
VmSpec launchSpecification = VmSpec.builder().id(vmName).name(vmName)
.memoryMB(512).controller(ideController).cleanUpMode(mode)
.osTypeId("SomeWeirdUnknownOs").forceOverwrite(true).build();
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(launchSpecification);
new UnregisterMachineIfExistsAndDeleteItsMedia(manager)
.apply(launchSpecification);
try {
new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(manager).apply(launchSpecification);
new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(manager)
.apply(launchSpecification);
fail();
} catch (VBoxException e) {
ErrorCode errorCode = ErrorCode.valueOf(e);

View File

@ -0,0 +1,117 @@
/*
* 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.predicates;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
import org.jclouds.virtualbox.domain.HardDisk;
import org.jclouds.virtualbox.domain.StorageController;
import org.jclouds.virtualbox.domain.VmSpec;
import org.jclouds.virtualbox.functions.CloneAndRegisterMachineFromIMachineIfNotAlreadyExists;
import org.jclouds.virtualbox.functions.CreateAndRegisterMachineFromIsoIfNotAlreadyExists;
import org.jclouds.virtualbox.functions.IMachineToVmSpec;
import org.jclouds.virtualbox.functions.admin.UnregisterMachineIfExistsAndDeleteItsMedia;
import org.jclouds.virtualbox.util.PropertyUtils;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import org.virtualbox_4_1.CleanupMode;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.StorageBus;
import org.virtualbox_4_1.VirtualBoxManager;
/**
*
* @author Andrea Turli
*/
@Test(groups = "live", singleThreaded = true, testName = "IsLinkedClonesLiveTest")
public class IsLinkedClonesLiveTest extends BaseVirtualBoxClientLiveTest {
private static final boolean IS_LINKED_CLONE = true;
private String vmId = "jclouds-image-iso-1";
private String osTypeId = "DEBIAN";
private String ideControllerName = "IDE Controller";
private String cloneId = "jclouds-is-linked-clone-clone";
private String cloneName = "jclouds-is-linked-clone-clone";
private String vmName = "jclouds-is-linked-clone-master";
private StorageController masterStorageController;
private VmSpec masterSpec;
private VmSpec cloneSpec;
@BeforeGroups(groups = { "live" })
public void setUp() throws Exception {
identity = "toor";
credential = "password";
String workingDir = PropertyUtils.getWorkingDirFromProperty();
HardDisk hardDisk = HardDisk.builder()
.diskpath(workingDir + "/testadmin.vdi").autoDelete(true)
.controllerPort(0).deviceSlot(1).build();
masterStorageController = StorageController.builder()
.name(ideControllerName).bus(StorageBus.IDE)
.attachISO(0, 0, workingDir + "/ubuntu-11.04-server-i386.iso")
.attachHardDisk(hardDisk)
.attachISO(1, 1, workingDir + "/VBoxGuestAdditions_4.1.2.iso")
.build();
masterSpec = VmSpec.builder().id(vmId).name(vmName).memoryMB(512)
.osTypeId(osTypeId).controller(masterStorageController)
.forceOverwrite(true).cleanUpMode(CleanupMode.Full).build();
cloneSpec = VmSpec.builder().id(cloneId).name(cloneName).memoryMB(512)
.osTypeId(osTypeId).forceOverwrite(true)
.cleanUpMode(CleanupMode.Full).build();
}
@Test
public void testLinkedClone() {
VirtualBoxManager manager = (VirtualBoxManager) context
.getProviderSpecificContext().getApi();
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(masterSpec);
IMachine master = new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(
manager).apply(masterSpec);
IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(
manager, cloneSpec, IS_LINKED_CLONE).apply(master);
assertTrue(new IsLinkedClone(manager).apply(clone));
new UnregisterMachineIfExistsAndDeleteItsMedia(manager)
.apply(new IMachineToVmSpec().apply(clone));
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(masterSpec);
}
public void testFullClone() {
VirtualBoxManager manager = (VirtualBoxManager) context
.getProviderSpecificContext().getApi();
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(masterSpec);
IMachine master = new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(
manager).apply(masterSpec);
IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(
manager, cloneSpec, !IS_LINKED_CLONE).apply(master);
assertFalse(new IsLinkedClone(manager).apply(clone));
new UnregisterMachineIfExistsAndDeleteItsMedia(manager)
.apply(new IMachineToVmSpec().apply(clone));
new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(masterSpec);
}
}