PageRenderTime 75ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/experiment/VirtualboxAdministrationLiveTest.java

https://github.com/edwardt/jclouds
Java | 542 lines | 401 code | 65 blank | 76 comment | 22 complexity | 97c41b831c9a07f6b6bf2f1205bca387 MD5 | raw file
  1. /**
  2. * Licensed to jclouds, Inc. (jclouds) under one or more
  3. * contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. jclouds licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. package org.jclouds.virtualbox.experiment;
  20. import static org.testng.Assert.assertEquals;
  21. import java.io.File;
  22. import java.io.IOException;
  23. import java.io.InputStream;
  24. import java.net.HttpURLConnection;
  25. import java.net.MalformedURLException;
  26. import java.net.Proxy;
  27. import java.net.URL;
  28. import java.rmi.RemoteException;
  29. import java.util.concurrent.TimeUnit;
  30. import org.jclouds.compute.domain.ExecResponse;
  31. import org.jclouds.domain.Credentials;
  32. import org.jclouds.encryption.bouncycastle.config.BouncyCastleCryptoModule;
  33. import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
  34. import org.jclouds.net.IPSocket;
  35. import org.jclouds.predicates.InetSocketAddressConnect;
  36. import org.jclouds.predicates.RetryablePredicate;
  37. import org.jclouds.ssh.SshClient;
  38. import org.jclouds.sshj.config.SshjSshClientModule;
  39. import org.testng.annotations.AfterClass;
  40. import org.testng.annotations.AfterMethod;
  41. import org.testng.annotations.BeforeGroups;
  42. import org.testng.annotations.BeforeMethod;
  43. import org.testng.annotations.Test;
  44. import org.virtualbox_4_1.AccessMode;
  45. import org.virtualbox_4_1.DeviceType;
  46. import org.virtualbox_4_1.IMachine;
  47. import org.virtualbox_4_1.IMedium;
  48. import org.virtualbox_4_1.IProgress;
  49. import org.virtualbox_4_1.ISession;
  50. import org.virtualbox_4_1.IStorageController;
  51. import org.virtualbox_4_1.LockType;
  52. import org.virtualbox_4_1.MachineState;
  53. import org.virtualbox_4_1.NATProtocol;
  54. import org.virtualbox_4_1.SessionState;
  55. import org.virtualbox_4_1.StorageBus;
  56. import org.virtualbox_4_1.VirtualBoxManager;
  57. import org.virtualbox_4_1.jaxws.MediumVariant;
  58. import com.google.common.base.Predicate;
  59. import com.google.common.io.Files;
  60. import com.google.common.io.InputSupplier;
  61. import com.google.inject.Guice;
  62. import com.google.inject.Injector;
  63. @Test(groups = "live", testName = "virtualbox.VirtualboxAdministrationTest")
  64. public class VirtualboxAdministrationLiveTest {
  65. protected String provider = "virtualbox";
  66. protected String identity;
  67. protected String credential;
  68. protected String endpoint;
  69. protected String apiversion;
  70. protected String vmName;
  71. VirtualBoxManager manager = VirtualBoxManager.createInstance("");
  72. protected Injector injector;
  73. protected Predicate<IPSocket> socketTester;
  74. protected SshClient.Factory sshFactory;
  75. protected String settingsFile; // Fully qualified path where the settings
  76. // file should be created, or NULL for a
  77. // default
  78. // folder and file based on the name argument (see composeMachineFilename()).
  79. protected String osTypeId; // Guest OS Type ID.
  80. protected String vmId; // Machine UUID (optional).
  81. protected boolean forceOverwrite; // If true, an existing machine settings
  82. // file will be overwritten.
  83. protected String osUsername;
  84. protected String osPassword;
  85. protected String controller;
  86. protected String diskFormat;
  87. protected String workingDir;
  88. protected String originalDisk;
  89. protected String clonedDisk;
  90. protected String guestAdditionsDvdName;
  91. private String vdiUrl;
  92. private String gaIsoUrl;
  93. private String vboxwebsrvStartCommand;
  94. // private Process pr;
  95. private String vdiName;
  96. private String gaIsoName;
  97. private String admin_pwd;
  98. private String hostUsername;
  99. private String hostPassword;
  100. private String install7zip;
  101. private String run7zip;
  102. private String installVboxOse;
  103. /**
  104. *
  105. *
  106. *
  107. * @param workingDir
  108. * @param vdiUrl
  109. * @param proxy
  110. * Proxy proxy = new Proxy(Proxy.Type.HTTP, new
  111. * InetSocketAddress("localhost", 5865));
  112. * @return
  113. * @throws Exception
  114. */
  115. private File downloadFile(String sourceURL, String destinationDir, String vboxGuestAdditionsName, Proxy proxy)
  116. throws Exception {
  117. String absolutePathName = destinationDir + File.separator + vboxGuestAdditionsName;
  118. File iso = new File(absolutePathName);
  119. final URL isoURL = new URL(sourceURL);
  120. final HttpURLConnection uc = (HttpURLConnection) isoURL.openConnection(); // isoURL.openConnection(proxy);
  121. uc.connect();
  122. if (!iso.exists()) {
  123. System.out.println("Start download " + sourceURL + " to " + absolutePathName);
  124. Files.copy(new InputSupplier<InputStream>() {
  125. @Override
  126. public InputStream getInput() throws IOException {
  127. return uc.getInputStream();
  128. }
  129. }, iso);
  130. }
  131. return iso;
  132. }
  133. protected void setupCredentials() {
  134. identity = System.getProperty("test." + provider + ".identity", "administrator");
  135. credential = System.getProperty("test." + provider + ".credential", "12345");
  136. endpoint = System.getProperty("test." + provider + ".endpoint", "http://localhost:18083/");
  137. apiversion = System.getProperty("test." + provider + ".apiversion");
  138. }
  139. protected void setupConfigurationProperties() {
  140. admin_pwd = System.getProperty("test." + provider + ".admin_pwd", "password");
  141. // OS
  142. osUsername = System.getProperty("test." + provider + ".osusername", "root");
  143. osPassword = System.getProperty("test." + provider + ".ospassword", "toortoor");
  144. controller = System.getProperty("test." + provider + ".controller", "IDE Controller");
  145. // Create disk If the @a format attribute is empty or null then the
  146. // default storage format specified by
  147. // ISystemProperties#defaultHardDiskFormat
  148. diskFormat = System.getProperty("test." + provider + ".diskformat", "");
  149. // VBOX
  150. settingsFile = null; // Fully qualified path where the settings file
  151. // should be created, or NULL for a default
  152. // folder and file based on the name argument (see
  153. // composeMachineFilename()).
  154. osTypeId = System.getProperty("test." + provider + ".osTypeId", ""); // Guest
  155. // OS
  156. // Type
  157. // ID.
  158. vmId = System.getProperty("test." + provider + ".vmId", null); // Machine
  159. // UUID
  160. // (optional).
  161. forceOverwrite = true; // If true, an existing machine settings file will
  162. // be overwritten.
  163. vmName = System.getProperty("test." + provider + ".vmname", "jclouds-virtualbox-admin");
  164. workingDir = System.getProperty("user.home") + File.separator
  165. + System.getProperty("test." + provider + ".workingDir", "jclouds-virtualbox-test");
  166. if (new File(workingDir).mkdir())
  167. ;
  168. vdiName = System.getProperty("test." + provider + ".vdiName", "centos-5.2-x86.7z");
  169. vdiUrl = System.getProperty("test." + provider + ".vdiUrl",
  170. "http://leaseweb.dl.sourceforge.net/project/virtualboximage/CentOS/5.2/centos-5.2-x86.7z");
  171. gaIsoName = System.getProperty("test." + provider + ".gaIsoName", "VBoxGuestAdditions_4.0.2-update-69551.iso");
  172. gaIsoUrl = System.getProperty("test." + provider + ".gaIsoUrl",
  173. "http://download.virtualbox.org/virtualbox/4.0.2/VBoxGuestAdditions_4.0.2-update-69551.iso");
  174. vboxwebsrvStartCommand = System
  175. .getProperty("test." + provider + ".vboxwebsrvStartCommand", "/usr/bin/vboxwebsrv");
  176. originalDisk = workingDir + File.separator + "VDI" + File.separator
  177. + System.getProperty("test." + provider + ".originalDisk", "centos-5.2-x86.vdi");
  178. clonedDisk = workingDir + File.separator + System.getProperty("test." + provider + ".clonedDisk", "template.vdi");
  179. guestAdditionsDvdName = workingDir
  180. + File.separator
  181. + System.getProperty("test." + provider + ".guestAdditionsDvdName",
  182. "VBoxGuestAdditions_4.0.2-update-69551.iso");
  183. install7zip = System.getProperty("test." + provider + ".install7zip", "sudo -S apt-get --yes install p7zip");
  184. run7zip = System.getProperty("test." + provider + ".run7zip", "p7zip -d ");
  185. installVboxOse = System.getProperty("test." + provider + ".installvboxose",
  186. "sudo -S apt-get --yes install virtualbox-ose");
  187. if (!new File(originalDisk).exists()) {
  188. IPSocket socket = new IPSocket("127.0.0.1", 22);
  189. socketTester.apply(socket);
  190. SshClient client = sshFactory.create(socket, new Credentials(hostUsername, hostPassword));
  191. try {
  192. File vdi7z = downloadFile(vdiUrl, workingDir, vdiName, null);
  193. client.connect();
  194. ExecResponse exec = client.exec("echo " + admin_pwd + " | " + install7zip + "; cd " + workingDir + "; "
  195. + run7zip + vdi7z.getName());
  196. System.out.println(exec);
  197. } catch (Exception e) {
  198. e.printStackTrace();
  199. } finally {
  200. if (client != null)
  201. client.disconnect();
  202. }
  203. }
  204. if (!new File(guestAdditionsDvdName).exists()) {
  205. try {
  206. File gaIso = downloadFile(gaIsoUrl, workingDir, gaIsoName, null);
  207. } catch (Exception e) {
  208. e.printStackTrace();
  209. }
  210. }
  211. }
  212. @BeforeGroups(groups = "live")
  213. protected void setupClient() throws IOException, InterruptedException {
  214. hostUsername = System.getProperty("test." + provider + ".hostusername", "toor");
  215. hostPassword = System.getProperty("test." + provider + ".hostpassword", "password");
  216. injector = Guice.createInjector(new SshjSshClientModule(), new SLF4JLoggingModule(),
  217. new BouncyCastleCryptoModule());
  218. sshFactory = injector.getInstance(SshClient.Factory.class);
  219. socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 3600, 1, TimeUnit.SECONDS);
  220. injector.injectMembers(socketTester);
  221. setupCredentials();
  222. setupConfigurationProperties();
  223. installVbox();
  224. // startup vbox web server
  225. startupVboxWebServer(vboxwebsrvStartCommand);
  226. }
  227. private void installVbox() throws IOException, InterruptedException {
  228. IPSocket socket = new IPSocket("127.0.0.1", 22);
  229. socketTester.apply(socket);
  230. SshClient client = sshFactory.create(socket, new Credentials(hostUsername, hostPassword));
  231. try {
  232. client.connect();
  233. ExecResponse exec = client.exec("echo " + hostPassword + " | " + installVboxOse);
  234. System.out.println(exec);
  235. } catch (Exception e) {
  236. e.printStackTrace();
  237. } finally {
  238. if (client != null)
  239. client.disconnect();
  240. }
  241. }
  242. /**
  243. *
  244. * @param command
  245. * absolute path to command. For ubuntu 10.04: /usr/bin/vboxwebsrv
  246. * @throws IOException
  247. * @throws InterruptedException
  248. */
  249. private void startupVboxWebServer(String command) throws IOException, InterruptedException {
  250. // Disable login credential: $
  251. // rt.exec("VBoxManage setproperty websrvauthlibrary null");
  252. IPSocket socket = new IPSocket("127.0.0.1", 22);
  253. socketTester.apply(socket);
  254. SshClient client = sshFactory.create(socket, new Credentials(hostUsername, hostPassword));
  255. try {
  256. client.connect();
  257. ExecResponse exec = client.exec(command + " --timeout 50000 -b");
  258. System.out.println(exec.getOutput());
  259. System.out.println(exec);
  260. } catch (Exception e) {
  261. e.printStackTrace();
  262. } finally {
  263. if (client != null)
  264. client.disconnect();
  265. }
  266. }
  267. @BeforeMethod
  268. protected void setupManager() {
  269. manager.connect(endpoint, identity, credential);
  270. }
  271. @AfterMethod
  272. protected void disconnectAndClenaupManager() throws RemoteException, MalformedURLException {
  273. manager.disconnect();
  274. manager.cleanup();
  275. }
  276. public void testCreateVirtualMachine() {
  277. IMachine newVM = manager.getVBox().createMachine(settingsFile, vmName, osTypeId, vmId, forceOverwrite);
  278. manager.getVBox().registerMachine(newVM);
  279. assertEquals(newVM.getName(), vmName);
  280. }
  281. @Test(dependsOnMethods = "testCreateVirtualMachine")
  282. public void testChangeRAM() {
  283. Long memorySize = new Long(2048);
  284. ISession session = manager.getSessionObject();
  285. IMachine machine = manager.getVBox().findMachine(vmName);
  286. machine.lockMachine(session, LockType.Write);
  287. IMachine mutable = session.getMachine();
  288. mutable.setMemorySize(memorySize);
  289. mutable.saveSettings();
  290. session.unlockMachine();
  291. assertEquals(manager.getVBox().findMachine(vmName).getMemorySize(), memorySize);
  292. }
  293. @Test(dependsOnMethods = "testChangeRAM")
  294. public void testCreateDiskController() {
  295. ISession session = manager.getSessionObject();
  296. IMachine machine = manager.getVBox().findMachine(vmName);
  297. machine.lockMachine(session, LockType.Write);
  298. IMachine mutable = session.getMachine();
  299. mutable.addStorageController(controller, StorageBus.IDE);
  300. mutable.saveSettings();
  301. session.unlockMachine();
  302. assertEquals(manager.getVBox().findMachine(vmName).getStorageControllers().size(), 1);
  303. }
  304. @Test(dependsOnMethods = "testCreateDiskController")
  305. public void testCloneAndAttachHardDisk() {
  306. IMedium hd = manager.getVBox().openMedium(originalDisk, DeviceType.HardDisk, AccessMode.ReadOnly, forceOverwrite);
  307. IMedium clonedHd = null;
  308. if (!new File(clonedDisk).exists()) {
  309. clonedHd = manager.getVBox().createHardDisk(diskFormat, clonedDisk);
  310. IProgress cloning = hd.cloneTo(clonedHd, new Long(MediumVariant.VMDK_SPLIT_2_G.ordinal()), null);
  311. cloning.waitForCompletion(-1);
  312. } else
  313. clonedHd = manager.getVBox().openMedium(clonedDisk, DeviceType.HardDisk, AccessMode.ReadOnly, forceOverwrite);
  314. ISession session = manager.getSessionObject();
  315. IMachine machine = manager.getVBox().findMachine(vmName);
  316. machine.lockMachine(session, LockType.Write);
  317. IMachine mutable = session.getMachine();
  318. mutable.attachDevice(controller, 0, 0, DeviceType.HardDisk, clonedHd);
  319. mutable.saveSettings(); // write settings to xml
  320. session.unlockMachine();
  321. assertEquals(hd.getId().equals(""), false);
  322. }
  323. @Test(dependsOnMethods = "testCloneAndAttachHardDisk")
  324. public void testConfigureNIC() {
  325. ISession session = manager.getSessionObject();
  326. IMachine machine = manager.getVBox().findMachine(vmName);
  327. machine.lockMachine(session, LockType.Write);
  328. IMachine mutable = session.getMachine();
  329. /*
  330. * NAT
  331. */
  332. // mutable.getNetworkAdapter(new Long(0)).attachToNAT(); not in 4.1
  333. mutable.getNetworkAdapter(new Long(0)).setNATNetwork("");
  334. mutable.getNetworkAdapter(new Long(0)).setEnabled(true);
  335. mutable.saveSettings();
  336. session.unlockMachine();
  337. machine.lockMachine(session, LockType.Write);
  338. mutable = session.getMachine();
  339. machine.getNetworkAdapter(new Long(0)).getNatDriver()
  340. .addRedirect("guestssh", NATProtocol.TCP, "127.0.0.1", 2222, "", 22);
  341. mutable.saveSettings();
  342. session.unlockMachine();
  343. }
  344. @Test(dependsOnMethods = "testConfigureNIC")
  345. public void testAttachGuestAdditions() {
  346. ISession session = manager.getSessionObject();
  347. IMachine machine = manager.getVBox().findMachine(vmName);
  348. IMedium guestAdditionsDVD = manager.getVBox().openMedium(guestAdditionsDvdName, DeviceType.DVD,
  349. AccessMode.ReadOnly, forceOverwrite);
  350. for (IStorageController storageController : machine.getStorageControllers()) {
  351. // for DVD we choose IDE
  352. if (storageController.getName().equals(controller)) {
  353. machine.lockMachine(session, LockType.Write);
  354. IMachine mutable = session.getMachine();
  355. // IDE secondary slave [1:1]
  356. mutable.attachDevice(storageController.getName(), new Integer(1), new Integer(1), DeviceType.DVD,
  357. guestAdditionsDVD);
  358. mutable.saveSettings();
  359. session.unlockMachine();
  360. }
  361. }
  362. }
  363. @Test(dependsOnMethods = "testAttachGuestAdditions")
  364. public void testStartVirtualMachine() {
  365. IMachine machine = manager.getVBox().findMachine(vmName);
  366. ISession session = manager.getSessionObject();
  367. launchVMProcess(machine, session);
  368. assertEquals(machine.getState(), MachineState.Running);
  369. }
  370. /**
  371. *
  372. * @param machine
  373. * @param session
  374. */
  375. private void launchVMProcess(IMachine machine, ISession session) {
  376. IProgress prog = machine.launchVMProcess(session, "gui", "");
  377. prog.waitForCompletion(-1);
  378. session.unlockMachine();
  379. }
  380. @Test(dependsOnMethods = "testStartVirtualMachine")
  381. public void testInstallGuestAdditionsThroughNATPortForwarding() {
  382. IPSocket socket = new IPSocket("127.0.0.1", 2222);
  383. socketTester.apply(socket);
  384. SshClient client = sshFactory.create(socket, new Credentials(osUsername, osPassword));
  385. try {
  386. client.connect();
  387. ExecResponse exec = client.exec("yum install gcc kernel kernel-devel -y");
  388. System.out.println(exec);
  389. } finally {
  390. if (client != null)
  391. client.disconnect();
  392. }
  393. // manually restart
  394. IMachine machine = manager.getVBox().findMachine(vmName);
  395. powerDownMachine(machine);
  396. launchVMProcess(machine, manager.getSessionObject());
  397. socketTester.apply(socket);
  398. client = sshFactory.create(socket, new Credentials(osUsername, osPassword));
  399. try {
  400. client.connect();
  401. ExecResponse exec = client
  402. .exec("mkdir -p /media/cdrom; mount /dev/cdrom /media/cdrom; sh /media/cdrom/VBoxLinuxAdditions.run --nox11 force");
  403. System.out.println(exec);
  404. exec = client.exec("echo '/usr/sbin/VBoxService' >> /etc/rc.d/rc.local");
  405. System.out.println(exec);
  406. } finally {
  407. if (client != null)
  408. client.disconnect();
  409. }
  410. }
  411. @Test(dependsOnMethods = "testInstallGuestAdditionsThroughNATPortForwarding")
  412. public void testStopVirtualMachine() {
  413. IMachine machine = manager.getVBox().findMachine(vmName);
  414. powerDownMachine(machine);
  415. assertEquals(machine.getState(), MachineState.PoweredOff);
  416. }
  417. /**
  418. * @param machine
  419. */
  420. private void powerDownMachine(IMachine machine) {
  421. try {
  422. ISession machineSession = manager.openMachineSession(machine);
  423. IProgress progress = machineSession.getConsole().powerDown();
  424. progress.waitForCompletion(-1);
  425. machineSession.unlockMachine();
  426. while (!machine.getSessionState().equals(SessionState.Unlocked)) {
  427. try {
  428. System.out.println("waiting for unlocking session - session state: " + machine.getSessionState());
  429. Thread.sleep(1000);
  430. } catch (InterruptedException e) {
  431. e.printStackTrace();
  432. }
  433. }
  434. } catch (Exception e) {
  435. e.printStackTrace();
  436. }
  437. }
  438. @Test(dependsOnMethods = "testStopVirtualMachine")
  439. public void cleanUp() throws IOException {
  440. ISession session = manager.getSessionObject();
  441. IMachine machine = manager.getVBox().findMachine(vmName);
  442. machine.lockMachine(session, LockType.Write);
  443. IMachine mutable = session.getMachine();
  444. mutable.getNetworkAdapter(new Long(0)).getNatDriver().removeRedirect("guestssh");
  445. // detach disk from controller
  446. mutable.detachDevice(controller, 0, 0);
  447. mutable.saveSettings();
  448. session.unlockMachine();
  449. for (IStorageController storageController : machine.getStorageControllers()) {
  450. if (storageController.getName().equals(controller)) {
  451. session = manager.getSessionObject();
  452. machine.lockMachine(session, LockType.Write);
  453. mutable = session.getMachine();
  454. mutable.detachDevice(storageController.getName(), 1, 1);
  455. mutable.saveSettings();
  456. session.unlockMachine();
  457. }
  458. }
  459. }
  460. @AfterClass
  461. void stopVboxWebServer() throws IOException {
  462. // stop vbox web server
  463. IPSocket socket = new IPSocket("127.0.0.1", 22);
  464. socketTester.apply(socket);
  465. SshClient client = sshFactory.create(socket, new Credentials(hostUsername, hostPassword));
  466. try {
  467. client.connect();
  468. ExecResponse exec = client.exec("pidof vboxwebsrv | xargs kill");
  469. System.out.println(exec.getOutput());
  470. } catch (Exception e) {
  471. e.printStackTrace();
  472. } finally {
  473. if (client != null)
  474. client.disconnect();
  475. }
  476. }
  477. }