Oracle VM SDK Create VM
I am playing with the java SOAP API to test creating a VM and since it took me a while to get it working I am jotting down my recipe for future refining. This is rough and needs a rewrite. Currently it is just a gutted version of the Sample that comes with the OVMM ISO.
Note I ran this on the OVMM server at first and using localhost for connecting. That worked but to run this code from a different server I copied java from the OVMM server. Newer java just gave me too much SSL issues.
Also I would prefer using REST/JSON but that is not working yet. REST/JSON gave me a NullPointerException which may provide me a clue as to why I could not get POST to work from my Python tests in a prior article. Which is actually the reason I am testing the Java code.
You are WARNED this code is rough. For example it will create duplicate VM's with the same name. Also checkign the SERverPool is not safe it needs more logic. It will just grab the last one if you have more than one.
You will need jersey for this code to work. Also as I mentioned this needs a lot of cleanup. I had some dependency issues so I copied a lot of classes from the SDK into my tree $APPROOT/lib/com/oracle/ovm/mgr/ws/
rrosso@BL:~/src/ovm_java_api$ ls lib/ com jersey-bundle-1.19.1.jar OvmWsClient.jar
Little BASH script to show compile and run.
rrosso@BL:~/src/ovm_java_api$ cat buildrun.sh # Script to build and run OVM 3.3.3 specifc SDK API # Run with two parms example: ./buildrun.sh vmname=vm1 server=ovs333 # JAVA ENV #export JAVA_HOME=/home/rrosso/jdk1.8.0_121 export JAVA_HOME=/home/rrosso/java export PATH=$JAVA_HOME/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/rrosso/bin #java -version APPROOT=/home/rrosso/src/ovm_java_api BUILDROOT=com/oracle/ovm/mgr/ws/sample/ OVMLIB=$APPROOT/lib # APP ROOT cd $APPROOT # BUILD cd $BUILDROOT rm WsDevClient*.class javac -cp $OVMLIB/OvmWsClient.jar:. WsDevClient.java # RUN cd $APPROOT #java -Djavax.net.debug=ssl -cp .:$OVMLIB com.oracle.ovm.mgr.ws.sample.WsDevClient #echo "Trying to create $1 on $2" java -cp .:$OVMLIB com.oracle.ovm.mgr.ws.sample.WsDevClient $1 $2
Example run working:
rrosso@BL:~/src/ovm_java_api$ ./buildrun.sh vmname=vm4.3 server=ovs333 Starting Ovm Api Test Using SOAP Implementation Starting VM create of: vm4.3 create vm job id: Create Vm: vm4.3 on Server Pool: pool1(1487049718384) Uri: https://localhost:7002/ovm/core/wsapi/rest/Job/1487049718384
Client Source:
rrosso@BL:~/src/ovm_java_api$ cat com/oracle/ovm/mgr/ws/sample/WsDevClient.java package com.oracle.ovm.mgr.ws.sample; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.List; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.KeyManager; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import com.oracle.ovm.mgr.ws.client.OvmWsClient; import com.oracle.ovm.mgr.ws.client.OvmWsClientFactory; import com.oracle.ovm.mgr.ws.model.BaseObject; import com.oracle.ovm.mgr.ws.model.Id; import com.oracle.ovm.mgr.ws.model.Job; import com.oracle.ovm.mgr.ws.model.Job.JobRunState; import com.oracle.ovm.mgr.ws.model.JobError; import com.oracle.ovm.mgr.ws.model.Repository; import com.oracle.ovm.mgr.ws.model.Server; import com.oracle.ovm.mgr.ws.model.ServerPool; //import com.oracle.ovm.mgr.ws.model.StorageElement; import com.oracle.ovm.mgr.ws.model.Vm; import com.oracle.ovm.mgr.ws.model.Vm.VmDomainType; import com.oracle.ovm.mgr.ws.model.VmDiskMapping; import com.oracle.ovm.mgr.ws.model.WsException; /** * A simple web services create vm client. * . * BEFORE RUNNING THIS you should first override the WsDevClient_<username>.properties file with your own values. See that * file for details. */ public class WsDevClient { private OvmWsClient api; private Id<Vm> testVmId; private Id<ServerPool> testPoolId; private Id<Server> testServerId; private Id<Repository> testRepoId; private Id<Vm> importedAssemblyVmId; private Job repoPresentJob; public static void main(final String args[]) { int index; String vmname=""; String server=""; for (index = 0; index < args.length; ++index) { //System.out.println("args[" + index + "]: " + args[index]); String[] splitted=args[index].split("="); if ( splitted[0].equals("vmname") ) { vmname=splitted[1]; //System.out.println(vmname); } if ( splitted[0].equals("server") ) { server=splitted[1]; //System.out.println(server); } } //String[] vmname=args[0].split("=");; //String[] server=args[1].split("=");; final WsDevClient wsClient = new WsDevClient(); wsClient.run(vmname,server); } public void run(final String testVmName,final String testServerName) { try { // Configure the SSLContext with an insecure TrustManager // This is done to avoid the need to use valid certificates in the development environment. // This should not be done in a real / secure environment. final SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(new KeyManager[0], new TrustManager[] { new InsecureTrustManager() }, new SecureRandom()); SSLContext.setDefault(ctx); // Configure the HostnameVerifier to trust host names that do // not match the name on the server certificate. // This should not be done in real / secure environments. final HostnameVerifier hv = new HostnameVerifier() { public boolean verify(final String arg0, final SSLSession arg1) { return true; } }; HttpsURLConnection.setDefaultHostnameVerifier(hv); final ResourceBundle rootProps = ResourceBundle.getBundle("com.oracle.ovm.mgr.ws.sample.WsDevClient"); ResourceBundle userProps = null; try { userProps = ResourceBundle.getBundle("com.oracle.ovm.mgr.ws.sample.WsDevClient_" + System.getProperty("user.name")); } catch (final MissingResourceException ex) { System.out.println(ex); System.out.println("Warning: No user-overridden properties found. Using default values. This is unlikely to work and is not recommended!"); } // Load the properties. An exception will be thrown if any of these properties are not found. final String wsimpl = getProperty("wsimpl", rootProps, userProps); final String dialect = getProperty("dialect", rootProps, userProps); final String hostname = getProperty("hostname", rootProps, userProps); final String port = getProperty("port", rootProps, userProps); final String username = getProperty("username", rootProps, userProps); final String password = getProperty("password", rootProps, userProps); final String testRepo = getProperty("testRepo", rootProps, userProps); //final String testVmName = getProperty("testVmName", rootProps, userProps); final String debugStr = getProperty("debugHttpTraffic", rootProps, userProps); //final String testServerName = getProperty("testServerName", rootProps, userProps); final String testServerPoolName = getProperty("testServerPoolName", rootProps, userProps); final String assemblyUrl = getProperty("assemblyUrl", rootProps, userProps); final boolean debug = debugStr.equalsIgnoreCase("true"); api = OvmWsClientFactory.getOvmWsClient(wsimpl); api.setDebug(debug); api.setDialect(dialect); api.initialize(hostname, port, true); // Authenticate with the OvmApi Service api.login(username, password, Locale.getDefault()); System.out.println("Starting Ovm Api Test Using " + wsimpl + " Implementation\n"); final List<Repository> repos = api.repositoryGetAll(); for (final Repository repo : repos) { //printRepository(repo); if (repo.getId().getValue().equals(testRepo)) { testRepoId = repo.getId(); } } // Get a list of all Server Pools final List<Id<ServerPool>> serverPoolIds = api.serverPoolGetIds(); for (final Id<ServerPool> serverPoolId : serverPoolIds) { //printId("ServerPool", serverPoolId); // need better checking than just picking one testPoolId = serverPoolId; } // Run checks to make sure we can proceed. if (testRepoId == null) { throw new Exception("Repository for VM creation (with id " + testRepo + ") not found. Exiting."); } System.out.println("Starting VM create of: " + testVmName); Vm testVm = new Vm(); testVm.setVmDomainType(VmDomainType.XEN_HVM); testVm.setName(testVmName); testVm.setRepositoryId(testRepoId); //final ServerPool serverPool = api.serverPoolGetById(testPoolId); final Job vmCreateJob = api.vmCreate(testVm, testPoolId); System.out.println("create vm job id: " + vmCreateJob.getId()); testVmId = waitForJobComplete(api, vmCreateJob, Vm.class); // fetch vm create result object to fully populate the object (including the id and default values) // in preparation for the modify test testVm = api.vmGetById(testVmId); } catch (final Exception e) { e.printStackTrace(); System.out.println("\nException occurred during processing. Calling cleanup routine."); } finally { try { api.logout(); } catch (final WsException e) { e.printStackTrace(); } } } /** * @param string * @param rootProps * @param userProps * @return */ private String getProperty(final String key, final ResourceBundle... bundles) { String value = null; MissingResourceException missingResourceEx = null; for (final ResourceBundle bundle : bundles) { if (bundle != null) { try { value = bundle.getString(key); } catch (final MissingResourceException ex) { missingResourceEx = ex; } } } if (value == null) { throw missingResourceEx; } return value; } /** * @param group */ private void printJob(final Job job) { System.out.println("Job Id: " + job.getId()); System.out.println("\tUser: " + job.getUser()); System.out.println("\tStart Time: " + job.getStartTime()); System.out.println("\tEnd Time: " + job.getEndTime()); System.out.println("\tRun State: " + job.getJobRunState()); System.out.println("\tGroup: " + job.isJobGroup()); System.out.println("\tResult Id: " + job.getResultId()); try { final String transcript = api.jobGetDebugTranscript(job.getId()); System.out.println(transcript); } catch (final Exception e) { e.printStackTrace(); } final List<Id<Job>> jobChildren = job.getChildJobIds(); if (jobChildren != null) { for (final Id<Job> childJob : jobChildren) { System.out.println("\tChildJob: " + childJob); } } final JobError error = job.getError(); if (error != null) { System.out.println("\tError Type: " + error.getType()); System.out.println("\tError Message: " + error.getMessage()); } System.out.println(); } public void waitForJobComplete(final OvmWsClient api, final Job job) throws WsException { waitForJobComplete(api, job, null); } @SuppressWarnings("unchecked") public <T> Id<T> waitForJobComplete(final OvmWsClient api, Job job, final Class<T> type) throws WsException { while (job.isSummaryDone() == false) { try { Thread.sleep(1000); } catch (final Exception e) { } job = api.jobGetById(job.getId()); if (job.getJobRunState().equals(JobRunState.FAILURE)) { final JobError error = job.getError(); if (error != null) { System.out.println(" error type: " + error.getType()); System.out.println(" error message: " + error.getMessage()); } System.out.println(" transcript: " + api.jobGetDebugTranscript(job.getId())); } } @SuppressWarnings("rawtypes") final Id resultId = job.getResultId(); if (type == null) { return resultId; } else { final Id<T> typedResultId = resultId; return typedResultId; } } private static class InsecureTrustManager implements X509TrustManager { @Override public void checkClientTrusted(final X509Certificate[] arg0, final String arg1) throws CertificateException { } @Override public void checkServerTrusted(final X509Certificate[] arg0, final String arg1) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } } }
Properties file. I will work more of this into command line parms later.
rrosso@BL:~/src/ovm_java_api$ cat com//oracle/ovm/mgr/ws/sample/WsDevClient_rrosso.properties wsimpl=SOAP dialect=XML hostname=192.168.1.231 port=7002 username=admin password=myAdminPassW testRepo=0004fb00000300002e4e288cfa06e535 testServerPoolName=repo1 debugHttpTraffic=false assemblyUrl=http://install-vi.us.oracle.com/tests/assemblies/virtual-appliance-simple/package.ovf