Added AttachDistroMediumToMachine and started using it form IsoToIMachine.

This commit is contained in:
Mattias Holmqvist 2011-10-23 11:16:55 +02:00
parent f2d4c58a6a
commit ad8ef18bee
3 changed files with 203 additions and 31 deletions

View File

@ -0,0 +1,63 @@
/*
* *
* * 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.DeviceType;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.IMedium;
import org.virtualbox_4_1.VBoxException;
import javax.annotation.Nullable;
/**
* @author Mattias Holmqvist
*/
public class AttachDistroMediumToMachine implements Function<IMachine, Void> {
private final String controllerIDE;
private final IMedium distroMedium;
public AttachDistroMediumToMachine(String controllerIDE, IMedium distroMedium) {
this.controllerIDE = controllerIDE;
this.distroMedium = distroMedium;
}
@Override
public Void apply(@Nullable IMachine machine) {
try {
int controllerPort = 0;
int device = 0;
machine.attachDevice(controllerIDE, controllerPort, device, DeviceType.DVD, distroMedium);
machine.saveSettings();
} catch (VBoxException e) {
if (!alreadyAttached(e))
throw e;
}
return null;
}
private boolean alreadyAttached(VBoxException e) {
return e.getMessage().indexOf("is already attached to port") != -1;
}
}

View File

@ -87,8 +87,8 @@ public class IsoToIMachine implements Function<String, IMachine> {
@Inject
public IsoToIMachine(VirtualBoxManager manager, String adminDisk, String diskFormat, String settingsFile,
String vmName, String osTypeId, String vmId, boolean forceOverwrite, String controllerIDE,
ComputeServiceContext context, String hostId, String guestId, Credentials credentials) {
String vmName, String osTypeId, String vmId, boolean forceOverwrite, String controllerIDE,
ComputeServiceContext context, String hostId, String guestId, Credentials credentials) {
super();
this.manager = manager;
this.adminDisk = adminDisk;
@ -133,31 +133,15 @@ public class IsoToIMachine implements Function<String, IMachine> {
// IDE Controller
ensureMachineHasIDEControllerNamed(vmName, controllerIDE);
// Distribution medium
ensureMachineHasAttachedDistroMedium(isoName, workingDir, controllerIDE);
// DISK
String adminDiskPath = workingDir + "/" + adminDisk;
if (new File(adminDiskPath).exists()) {
new File(adminDiskPath).delete();
}
final IMedium distroMedium = manager.getVBox().openMedium(workingDir + "/" + isoName, DVD, ReadOnly,
forceOverwrite);
lockMachineAndApply(manager, Write, vmName, new Function<IMachine, Void>() {
@Override
public Void apply(IMachine machine) {
try {
machine.attachDevice(controllerIDE, 0, 0, DeviceType.DVD, distroMedium);
machine.saveSettings();
} catch (VBoxException e) {
if (e.getMessage().indexOf("is already attached to port") == -1)
throw e;
}
return null;
}
});
// Create and attach hard disk
final IMedium hd = manager.getVBox().createHardDisk(diskFormat, adminDiskPath);
long size = 4L * 1024L * 1024L * 1024L - 4L;
@ -190,7 +174,7 @@ public class IsoToIMachine implements Function<String, IMachine> {
String guestAdditionsDvd = workingDir + "/VBoxGuestAdditions_4.1.2.iso";
final IMedium guestAdditionsDvdMedium = manager.getVBox().openMedium(guestAdditionsDvd, DeviceType.DVD,
AccessMode.ReadOnly, forceOverwrite);
AccessMode.ReadOnly, forceOverwrite);
lockMachineAndApply(manager, Write, vmName, new Function<IMachine, Void>() {
@ -246,13 +230,29 @@ public class IsoToIMachine implements Function<String, IMachine> {
return vm;
}
private void ensureMachineHasAttachedDistroMedium(String isoName, String workingDir, String controllerIDE) {
final String pathToIsoFile = checkFileExists(workingDir + "/" + isoName);
final IMedium distroMedium = manager.getVBox().openMedium(pathToIsoFile, DVD, ReadOnly, forceOverwrite);
lockMachineAndApply(manager, Write, vmName,
new AttachDistroMediumToMachine(
checkNotNull(controllerIDE, "controllerIDE"),
checkNotNull(distroMedium, "distroMedium")));
}
public static String checkFileExists(String filePath) {
if (new File(filePath).exists()) {
return filePath;
}
throw new IllegalStateException("File " + filePath + " does not exist.");
}
public void ensureMachineHasIDEControllerNamed(String vmName, String controllerIDE) {
lockMachineAndApply(manager, Write, checkNotNull(vmName, "vmName"),
new AddIDEControllerIfNotExists(checkNotNull(controllerIDE, "controllerIDE")));
new AddIDEControllerIfNotExists(checkNotNull(controllerIDE, "controllerIDE")));
}
public static <T> T lockMachineAndApply(VirtualBoxManager manager, final LockType type, final String machineId,
final Function<IMachine, T> function) {
final Function<IMachine, T> function) {
return lockSessionOnMachineAndApply(manager, type, machineId, new Function<ISession, T>() {
@Override
@ -270,7 +270,7 @@ public class IsoToIMachine implements Function<String, IMachine> {
}
public static <T> T lockSessionOnMachineAndApply(VirtualBoxManager manager, LockType type, String machineId,
Function<ISession, T> function) {
Function<ISession, T> function) {
try {
ISession session = manager.getSessionObject();
IMachine immutableMachine = manager.getVBox().findMachine(machineId);
@ -282,17 +282,17 @@ public class IsoToIMachine implements Function<String, IMachine> {
}
} catch (VBoxException e) {
throw new RuntimeException(String.format("error applying %s to %s with %s lock: %s", function, machineId,
type, e.getMessage()), e);
type, e.getMessage()), e);
}
}
private String defaultInstallSequence() {
return "<Esc><Esc><Enter> "
+ "/install/vmlinuz noapic preseed/url=http://10.0.2.2:8080/src/test/resources/preseed.cfg "
+ "debian-installer=en_US auto locale=en_US kbd-chooser/method=us " + "hostname=" + vmName + " "
+ "fb=false debconf/frontend=noninteractive "
+ "keyboard-configuration/layout=USA keyboard-configuration/variant=USA console-setup/ask_detect=false "
+ "initrd=/install/initrd.gz -- <Enter>";
+ "/install/vmlinuz noapic preseed/url=http://10.0.2.2:8080/src/test/resources/preseed.cfg "
+ "debian-installer=en_US auto locale=en_US kbd-chooser/method=us " + "hostname=" + vmName + " "
+ "fb=false debconf/frontend=noninteractive "
+ "keyboard-configuration/layout=USA keyboard-configuration/variant=USA console-setup/ask_detect=false "
+ "initrd=/install/initrd.gz -- <Enter>";
}
private void sendKeyboardSequence(String keyboardSequence) {

View File

@ -0,0 +1,109 @@
/*
* *
* * 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.testng.annotations.Test;
import org.virtualbox_4_1.DeviceType;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.IMedium;
import org.virtualbox_4_1.VBoxException;
import static org.easymock.classextension.EasyMock.*;
/**
* @author Mattias Holmqvist
*/
@Test(groups = "unit", testName = "AttachDistroMediumToMachineTest")
public class AttachDistroMediumToMachineTest {
@Test
public void testAttachDistroMedium() throws Exception {
String controllerIDE = "IDE Controller";
IMedium distroMedium = createNiceMock(IMedium.class);
IMachine machine = createMock(IMachine.class);
machine.saveSettings();
machine.attachDevice(controllerIDE, 0, 0, DeviceType.DVD, distroMedium);
replay(machine, distroMedium);
new AttachDistroMediumToMachine(controllerIDE, distroMedium).apply(machine);
verify(machine);
}
@Test
public void testAcceptAlreadyAttachedDistroMedium() throws Exception {
String controllerIDE = "IDE Controller";
IMedium distroMedium = createNiceMock(IMedium.class);
IMachine machine = createNiceMock(IMachine.class);
final StringBuilder errorBuilder = new StringBuilder();
errorBuilder.append("VirtualBox error: ");
errorBuilder.append("Medium '/Users/johndoe/jclouds-virtualbox-test/ubuntu-11.04-server-i386.iso' ");
errorBuilder.append("is already attached to port 0, device 0 of controller 'IDE Controller' ");
errorBuilder.append("of this virtual machine (0x80BB000C)");
String isoAlreadyAttachedException = errorBuilder.toString();
VBoxException isoAttachedException = new VBoxException(createNiceMock(Throwable.class), isoAlreadyAttachedException);
machine.attachDevice(controllerIDE, 0, 0, DeviceType.DVD, distroMedium);
expectLastCall().andThrow(isoAttachedException);
replay(machine, distroMedium);
new AttachDistroMediumToMachine(controllerIDE, distroMedium).apply(machine);
verify(machine);
}
@Test(expectedExceptions = VBoxException.class)
public void testFailOnOtherVBoxErrors() throws Exception {
String controllerIDE = "IDE Controller";
IMedium distroMedium = createNiceMock(IMedium.class);
IMachine machine = createNiceMock(IMachine.class);
final StringBuilder errorBuilder = new StringBuilder();
errorBuilder.append("VirtualBox error: ");
errorBuilder.append("Some other VBox error");
String isoAlreadyAttachedException = errorBuilder.toString();
VBoxException isoAttachedException = new VBoxException(createNiceMock(Throwable.class), isoAlreadyAttachedException);
machine.attachDevice(controllerIDE, 0, 0, DeviceType.DVD, distroMedium);
expectLastCall().andThrow(isoAttachedException);
replay(machine, distroMedium);
new AttachDistroMediumToMachine(controllerIDE, distroMedium).apply(machine);
}
}