mirror of https://github.com/apache/jclouds.git
issue 384: IsoToMachine + Test started
This commit is contained in:
parent
4d624d1d3e
commit
1e2e41f7c1
|
@ -0,0 +1,229 @@
|
||||||
|
/*
|
||||||
|
* *
|
||||||
|
* * 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 static com.google.common.base.Throwables.propagate;
|
||||||
|
import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
|
||||||
|
import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
|
import org.jclouds.compute.domain.ExecResponse;
|
||||||
|
import org.jclouds.compute.options.RunScriptOptions;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
import org.jclouds.virtualbox.config.VirtualBoxConstants;
|
||||||
|
import org.jclouds.virtualbox.experiment.settings.KeyboardScancodes;
|
||||||
|
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.IProgress;
|
||||||
|
import org.virtualbox_4_1.ISession;
|
||||||
|
import org.virtualbox_4_1.LockType;
|
||||||
|
import org.virtualbox_4_1.MachineState;
|
||||||
|
import org.virtualbox_4_1.NATProtocol;
|
||||||
|
import org.virtualbox_4_1.NetworkAttachmentType;
|
||||||
|
import org.virtualbox_4_1.StorageBus;
|
||||||
|
import org.virtualbox_4_1.VirtualBoxManager;
|
||||||
|
import org.virtualbox_4_1.jaxws.MediumVariant;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
public class IsoToIMachine implements Function<String, IMachine> {
|
||||||
|
|
||||||
|
private VirtualBoxManager manager;
|
||||||
|
private String adminDisk;
|
||||||
|
private String diskFormat;
|
||||||
|
private String settingsFile;
|
||||||
|
private String vmName;
|
||||||
|
private String osTypeId;
|
||||||
|
private String vmId;
|
||||||
|
private String controllerIDE;
|
||||||
|
private boolean forceOverwrite;
|
||||||
|
private ComputeServiceContext context;
|
||||||
|
private String hostId;
|
||||||
|
private String guestId;
|
||||||
|
|
||||||
|
@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) {
|
||||||
|
super();
|
||||||
|
this.manager = manager;
|
||||||
|
this.adminDisk = adminDisk;
|
||||||
|
this.diskFormat = diskFormat;
|
||||||
|
this.settingsFile = settingsFile;
|
||||||
|
this.vmName = vmName;
|
||||||
|
this.osTypeId = osTypeId;
|
||||||
|
this.vmId = vmId;
|
||||||
|
this.controllerIDE = controllerIDE;
|
||||||
|
this.forceOverwrite = forceOverwrite;
|
||||||
|
this.context = context;
|
||||||
|
this.hostId = hostId;
|
||||||
|
this.guestId = guestId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IMachine apply(@Nullable String isoName) {
|
||||||
|
IMachine vm = manager.getVBox().createMachine(settingsFile, vmName,
|
||||||
|
osTypeId, vmId, forceOverwrite);
|
||||||
|
assertNotNull(vm.getName());
|
||||||
|
|
||||||
|
IMedium distroMedium = manager.getVBox().openMedium(
|
||||||
|
VirtualBoxConstants.VIRTUALBOX_WORKINGDIR + "/" + isoName,
|
||||||
|
DeviceType.DVD, AccessMode.ReadOnly, forceOverwrite);
|
||||||
|
|
||||||
|
ISession session = manager.getSessionObject();
|
||||||
|
IMachine machine = manager.getVBox().findMachine(vmName);
|
||||||
|
machine.lockMachine(session, LockType.Write);
|
||||||
|
IMachine mutable = session.getMachine();
|
||||||
|
mutable.addStorageController(controllerIDE, StorageBus.IDE);
|
||||||
|
// assertEquals(manager.getVBox().findMachine(vmName).getStorageControllers().size(),
|
||||||
|
// 1);
|
||||||
|
|
||||||
|
mutable.saveSettings();
|
||||||
|
|
||||||
|
// CONTROLLER
|
||||||
|
mutable.attachDevice(controllerIDE, 0, 0, DeviceType.DVD, distroMedium);
|
||||||
|
mutable.saveSettings();
|
||||||
|
|
||||||
|
// DISK
|
||||||
|
IMedium hd = null;
|
||||||
|
if (new File(adminDisk).exists()) {
|
||||||
|
new File(adminDisk).delete();
|
||||||
|
}
|
||||||
|
hd = manager.getVBox().createHardDisk(diskFormat, adminDisk);
|
||||||
|
long size = 4L * 1024L * 1024L * 1024L - 4L;
|
||||||
|
hd.createBaseStorage(new Long(size),
|
||||||
|
new Long(MediumVariant.STANDARD.ordinal()));
|
||||||
|
mutable.attachDevice(controllerIDE, 0, 1, DeviceType.HardDisk, hd);
|
||||||
|
mutable.saveSettings();
|
||||||
|
assertEquals(hd.getId().equals(""), false);
|
||||||
|
|
||||||
|
// NIC
|
||||||
|
mutable.getNetworkAdapter(new Long(0)).setAttachmentType(
|
||||||
|
NetworkAttachmentType.NAT);
|
||||||
|
machine.getNetworkAdapter(new Long(0))
|
||||||
|
.getNatDriver()
|
||||||
|
.addRedirect("guestssh", NATProtocol.TCP, "127.0.0.1", 2222,
|
||||||
|
"", 22);
|
||||||
|
mutable.getNetworkAdapter(new Long(0)).setEnabled(true);
|
||||||
|
mutable.saveSettings();
|
||||||
|
|
||||||
|
launchVMProcess(machine, session);
|
||||||
|
assertEquals(machine.getState(), MachineState.Running);
|
||||||
|
try {
|
||||||
|
Thread.sleep(5000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
propagate(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
sendKeyboardSequence(VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
session.unlockMachine();
|
||||||
|
|
||||||
|
return vm;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void launchVMProcess(IMachine machine, ISession session) {
|
||||||
|
IProgress prog = machine.launchVMProcess(session, "gui", "");
|
||||||
|
prog.waitForCompletion(-1);
|
||||||
|
session.unlockMachine();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendKeyboardSequence(String keyboardSequence)
|
||||||
|
throws InterruptedException {
|
||||||
|
String[] sequenceSplited = keyboardSequence.split(" ");
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (String line : sequenceSplited) {
|
||||||
|
String converted = stringToKeycode(line);
|
||||||
|
for (String word : converted.split(" ")) {
|
||||||
|
sb.append("vboxmanage controlvm " + vmName
|
||||||
|
+ " keyboardputscancode " + word + "; ");
|
||||||
|
if (word.endsWith(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP
|
||||||
|
.get("<Enter>"))) {
|
||||||
|
runScriptOnNode(hostId, sb.toString(), runAsRoot(false)
|
||||||
|
.wrapInInitScript(false));
|
||||||
|
sb.delete(0, sb.length() - 1);
|
||||||
|
}
|
||||||
|
if (word.endsWith(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP
|
||||||
|
.get("<Return>"))) {
|
||||||
|
runScriptOnNode(hostId, sb.toString(), runAsRoot(false)
|
||||||
|
.wrapInInitScript(false));
|
||||||
|
sb.delete(0, sb.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String stringToKeycode(String s) {
|
||||||
|
StringBuilder keycodes = new StringBuilder();
|
||||||
|
if (s.startsWith("<")) {
|
||||||
|
String[] specials = s.split("<");
|
||||||
|
for (int i = 1; i < specials.length; i++) {
|
||||||
|
keycodes.append(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP
|
||||||
|
.get("<" + specials[i]) + " ");
|
||||||
|
}
|
||||||
|
return keycodes.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (i < s.length()) {
|
||||||
|
String digit = s.substring(i, i + 1);
|
||||||
|
String hex = KeyboardScancodes.NORMAL_KEYBOARD_BUTTON_MAP
|
||||||
|
.get(digit);
|
||||||
|
keycodes.append(hex + " ");
|
||||||
|
if (i != 0 && i % 14 == 0)
|
||||||
|
keycodes.append(" ");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
keycodes.append(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP
|
||||||
|
.get("<Spacebar>") + " ");
|
||||||
|
|
||||||
|
return keycodes.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ExecResponse runScriptOnNode(String nodeId, String command,
|
||||||
|
RunScriptOptions options) {
|
||||||
|
ExecResponse toReturn = context.getComputeService().runScriptOnNode(
|
||||||
|
nodeId, command, options);
|
||||||
|
assert toReturn.getExitCode() == 0 : toReturn;
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ExecResponse runScriptOnNode(String nodeId, String command) {
|
||||||
|
return runScriptOnNode(nodeId, command, wrapInInitScript(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* *
|
||||||
|
* * 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrea Turli
|
||||||
|
*/
|
||||||
|
|
||||||
|
import static org.easymock.EasyMock.expect;
|
||||||
|
import static org.easymock.classextension.EasyMock.createNiceMock;
|
||||||
|
import static org.easymock.classextension.EasyMock.replay;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
|
import org.jclouds.virtualbox.config.VirtualBoxConstants;
|
||||||
|
import org.jclouds.virtualbox.experiment.TestUtils;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
import org.virtualbox_4_1.IMachine;
|
||||||
|
import org.virtualbox_4_1.ISession;
|
||||||
|
import org.virtualbox_4_1.IVirtualBox;
|
||||||
|
import org.virtualbox_4_1.VirtualBoxManager;
|
||||||
|
|
||||||
|
//TODO should it be a live test?
|
||||||
|
@Test(groups = "unit")
|
||||||
|
public class IsoToIMachineTest {
|
||||||
|
|
||||||
|
private String settingsFile = "";
|
||||||
|
private boolean forceOverwrite = true;
|
||||||
|
private String vmId = null;
|
||||||
|
private String osTypeId = null;
|
||||||
|
private String controllerIDE = "test-IDE";
|
||||||
|
private String diskFormat = "";
|
||||||
|
private String adminDisk = "testAdmin.vdi";
|
||||||
|
private String guestId = "guestId";
|
||||||
|
private String hostId = "hostId";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConvert() throws Exception {
|
||||||
|
String vmName = "virtualbox-iso-to-machine-test";
|
||||||
|
VirtualBoxManager vbm = createNiceMock(VirtualBoxManager.class);
|
||||||
|
IVirtualBox vBox = createNiceMock(IVirtualBox.class);
|
||||||
|
IMachine vm = createNiceMock(IMachine.class);
|
||||||
|
ISession session = createNiceMock(ISession.class);
|
||||||
|
expect(vbm.getVBox()).andReturn(vBox).anyTimes();
|
||||||
|
expect(vbm.getSessionObject()).andReturn(session).anyTimes();
|
||||||
|
expect(vBox.findMachine(vmName)).andReturn(vm).anyTimes();
|
||||||
|
expect(
|
||||||
|
vBox.createMachine(settingsFile, vmName, osTypeId, vmId,
|
||||||
|
forceOverwrite)).andReturn(vm).anyTimes();
|
||||||
|
expect(vm.getName()).andReturn(vmName).anyTimes();
|
||||||
|
// expect(vm.lockMachine(session, LockType.Write)).and
|
||||||
|
expect(session.getMachine()).andReturn(vm).anyTimes();
|
||||||
|
replay(vbm, vBox, vm, session);
|
||||||
|
|
||||||
|
ComputeServiceContext context = TestUtils
|
||||||
|
.computeServiceForLocalhostAndGuest();
|
||||||
|
IMachine iMachine = new IsoToIMachine(vbm, adminDisk, diskFormat,
|
||||||
|
settingsFile, vmName, osTypeId, vmId, forceOverwrite,
|
||||||
|
controllerIDE, context, hostId, guestId)
|
||||||
|
.apply(VirtualBoxConstants.VIRTUALBOX_DISTRO_ISO_NAME);
|
||||||
|
|
||||||
|
assertEquals(iMachine.getName(), vmName);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue