Riaan's SysAdmin Blog

My tips, howtos, gotchas, snippets and stuff. Use at your own risk!

OVM

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

admin

Bio Info for Riaan