diff --git a/plugins/hypervisors/ovm3 b/plugins/hypervisors/ovm3
deleted file mode 160000
index bd64f2d..0000000
--- a/plugins/hypervisors/ovm3
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit bd64f2dbf461847a3f7056693bf34e80e4f7af73
diff --git a/plugins/hypervisors/ovm3/pom.xml b/plugins/hypervisors/ovm3/pom.xml
new file mode 100644
index 0000000..22c9fe0
--- /dev/null
+++ b/plugins/hypervisors/ovm3/pom.xml
@@ -0,0 +1,36 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>cloud-plugin-hypervisor-ovm3</artifactId>
+  <name>Apache CloudStack Plugin - Hypervisor OracleVM3</name>
+  <parent>
+    <groupId>org.apache.cloudstack</groupId>
+    <artifactId>cloudstack-plugins</artifactId>
+    <version>4.4.0-SNAPSHOT</version>
+    <relativePath>../../pom.xml</relativePath>
+  </parent>
+   <dependencies>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>xapi</artifactId>
+      <version>${cs.xapi.version}</version>
+    </dependency>    
+  </dependencies>
+</project>
diff --git a/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-compute/module.properties b/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-compute/module.properties
new file mode 100644
index 0000000..69e6469
--- /dev/null
+++ b/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-compute/module.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF 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.
+name=ovm3-compute
+parent=compute
diff --git a/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-compute/spring-ovm3-compute-context.xml b/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-compute/spring-ovm3-compute-context.xml
new file mode 100644
index 0000000..42230c9
--- /dev/null
+++ b/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-compute/spring-ovm3-compute-context.xml
@@ -0,0 +1,39 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF 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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+                      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
+                      http://www.springframework.org/schema/context
+                      http://www.springframework.org/schema/context/spring-context-3.0.xsd"
+                      >
+
+    <bean id="Ovm3Fencer" class="com.cloud.hypervisor.ovm3.hypervisor.Ovm3Fencer">
+        <property name="name" value="Ovm3FenceBuilder" />
+    </bean>
+
+    <bean id="Ovm3Guru" class="com.cloud.hypervisor.ovm3.hypervisor.Ovm3Guru">
+        <property name="name" value="Ovm3Guru" />
+    </bean>
+
+    
+</beans>
diff --git a/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-discoverer/module.properties b/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-discoverer/module.properties
new file mode 100644
index 0000000..025d4cf
--- /dev/null
+++ b/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-discoverer/module.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF 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.
+name=ovm3-discoverer
+parent=discoverer
diff --git a/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-discoverer/spring-ovm3-discoverer-context.xml b/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-discoverer/spring-ovm3-discoverer-context.xml
new file mode 100644
index 0000000..aa76271
--- /dev/null
+++ b/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-discoverer/spring-ovm3-discoverer-context.xml
@@ -0,0 +1,34 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF 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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+                      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
+                      http://www.springframework.org/schema/context
+                      http://www.springframework.org/schema/context/spring-context-3.0.xsd"
+                      >
+
+    <bean id="Ovm3Discoverer" class="com.cloud.hypervisor.ovm3.hypervisor.Ovm3Discoverer">
+        <property name="name" value="Ovm3Discover" />
+    </bean>
+    
+</beans>
diff --git a/plugins/hypervisors/ovm3/scripts/clean_master.sh b/plugins/hypervisors/ovm3/scripts/clean_master.sh
new file mode 100755
index 0000000..bbf1cd0
--- /dev/null
+++ b/plugins/hypervisors/ovm3/scripts/clean_master.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF 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.
+#
+for i in `xm list | awk '{ print $1 }' | egrep -v "Name|Domain-0"`
+do
+    xm destroy $i
+done
+rm /etc/ovs-agent/db/server
+rm /etc/ovs-agent/db/repository
+rm /etc/ocfs2/cluster.conf
+rm /nfsmnt/*/*.img
+rm /nfsmnt/*/.ovspoolfs
+rm /nfsmnt/*/.generic_fs_stamp
+rm /OVS/Repositories/*/.generic_fs_stamp
+rm /OVS/Repositories/*/.ovsrepo
+/etc/init.d/ovs-agent restart
+/etc/init.d/ocfs2 restart
+for i in `mount | grep cs-mgmt | awk '{ print $1 }'`
+do
+    umount $i
+done
+rm -rf /OVS/Repositories/*
+rm -rf /nfsmnt/*
+ip addr del 192.168.1.230 dev c0a80100
+ip addr del 192.168.1.161 dev c0a80100
+rm /etc/sysconfig/network-scripts/ifcfg-control0
+reboot
diff --git a/plugins/hypervisors/ovm3/scripts/clean_slave.sh b/plugins/hypervisors/ovm3/scripts/clean_slave.sh
new file mode 100755
index 0000000..6d46859
--- /dev/null
+++ b/plugins/hypervisors/ovm3/scripts/clean_slave.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF 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.
+#
+for i in `xm list | awk '{ print $1 }' | egrep -v "Name|Domain-0"`
+do
+    xm destroy $i
+done
+rm /etc/ovs-agent/db/server
+rm /etc/ovs-agent/db/repository
+rm /etc/ocfs2/cluster.conf
+/etc/init.d/ovs-agent restart
+/etc/init.d/ocfs2 restart
+for i in `mount | grep cs-mgmt | awk '{ print $1 }'`
+do
+    umount $i
+done
+
diff --git a/plugins/hypervisors/ovm3/scripts/create_pool_cluster.py b/plugins/hypervisors/ovm3/scripts/create_pool_cluster.py
new file mode 100755
index 0000000..15c9a97
--- /dev/null
+++ b/plugins/hypervisors/ovm3/scripts/create_pool_cluster.py
@@ -0,0 +1,271 @@
+#!/usr/bin/python
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF 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.
+#
+import os, sys, subprocess
+from xml.dom.minidom import parseString
+
+from xmlrpclib import ServerProxy, Error
+
+server = ServerProxy("http://localhost:8899")
+
+pooledFs = 1
+normalRepo = 0
+
+try:
+  if normalRepo:
+    print "normal repo"
+    # this litterally throws EVERYTHING away on the repo
+    repoDom = parseString(server.discover_repository_db())
+    for node in repoDom.getElementsByTagName('Repository'):
+        repoUuid = node.attributes['Uuid']
+        remoteMount = node.getElementsByTagName('Fs_location')[0].firstChild.nodeValue
+        localMount = node.getElementsByTagName('Mount_point')[0].firstChild.nodeValue
+
+        # there is a "strong" relation between repo's and VMs
+        # onfortunately there is no reference in the vm.cfg
+        # or any known info in the configuration of the VM
+        # in which repo it lives....
+        for dirname, dirnames, filenames in os.walk('%s/VirtualMachines/' % localMount):
+            for vm in dirnames:
+                print "Destroying vm: %s on repo %s" % (vm, repoUuid.value)
+                try:
+                    mVm = server.list_vm(repoUuid.value, vm)
+                    if mVm != None:
+                        print server.stop_vm(repoUuid.value, vm)
+                        print server.delete_vm(repoUuid.value, vm)
+                    else:
+                        print "%s already not in repo %s" % (repoUuid.value, vm)
+                except Error, v:
+                    print "Unable to destroy: %s" % (v)
+                    continue
+
+        # VMs = server.list_vms() 
+        # for vm in VMs:
+        #    if vm['domid'] != '0':
+        #        print vm
+        #        print server.delete_vm(repoUuid.value, vm['uuid'])
+
+        rc = server.delete_repository(repoUuid.value, True)
+        # Set to false if you want to keep data:      ^^^^
+        print "Repository: %s" % repoUuid.value
+        if (rc == None):
+            print "Ok repo: %s destroyed!" % repoUuid.value
+            # now unmount the FS
+            # print server.unmount_repository_fs(localMount)
+        else:
+            print "Failed repo: %s not destroyed!" % repoUuid.value
+
+    # for now only treat NFS stuff as we're testing with that..
+    nfsHost='cs-mgmt'
+    nfsDom = server.storage_plugin_listMountPoints(
+        'oracle.generic.NFSPlugin.GenericNFSPlugin', 
+            { 'status': '', 
+                'admin_user': '', 
+                'admin_host': '', 
+                'uuid': '', 
+                'total_sz': 0, 
+                'admin_passwd': '',
+                'free_sz': 0, 
+                'name': '', 
+                'access_host': nfsHost, 
+                'storage_type': 'FileSys', 
+                'alloc_sz': 0, 
+                'access_grps': [], 
+                'used_sz': 0, 
+                'storage_desc': ''
+            })
+    for node in nfsDom:
+        props = {'status': node['status'], 
+            'uuid': '', 
+            'access_host': nfsHost, 
+            'storage_type': 'FileSys', 
+            'name': '' }
+        extprops = {'status': node['status'], 
+            'uuid': node['fs_uuid'], 
+            'ss_uuid': '', 
+            'size': 0, 
+            'free_sz': '', 
+            'state': 1, 
+            'access_grp_names': [], 
+            'access_path': nfsHost + ':' + '/volumes/cs-data/secondary', 
+            'name': ''}
+        # rc = server.storage_plugin_unmount('oracle.generic.NFSPlugin.GenericNFSPlugin', props, extprops, nfsMnt, True)
+        # print rc
+
+    nfsDom = parseString(server.discover_mounted_file_systems('nfs'))
+    for node in nfsDom.getElementsByTagName('Mount'):
+        nfsMnt = node.attributes['Dir'].value
+        print 'Mountpoint: %s' % (nfsMnt)
+        fsStamp = '%s/.generic_fs_stamp' % nfsMnt
+        # remove this so we don't cock up next run
+        if os.path.isfile(fsStamp):
+            print "Stamp found: %s" % fsStamp
+            os.unlink(fsStamp)
+
+        rc = server.storage_plugin_unmount('oracle.generic.NFSPlugin.GenericNFSPlugin', props, extprops, nfsMnt, True)
+        print rc
+
+
+  if pooledFs:
+    print "pooling"
+    # pool stuff 
+    poolalias="ItsMyPool"
+    poolmvip="192.168.1.161"
+    poolfirsthost = {
+        'ip': "192.168.1.64",
+        'hn': "ovm-1",
+        'id': 0,
+        'role': 'utility,xen'
+    }
+    fstype="nfs"
+    fstarget="cs-mgmt:/volumes/cs-data/primary"
+    poolid="0004fb0000020000ba9aaf00ae5e2d73"
+    clusterid="ba9aaf00ae5e2d72"
+    poolfsuuid="0004fb0000050000e70fbddeb802208f"
+    poolfsnfsbaseuuid="b8ca41cb-3469-4f74-a086-dddffe37dc2d"
+    manageruuid="0004fb00000100000af70d20dcce7d65"
+    pooluuid="0004fb0000020000ba9aaf00ae5e2d73"
+    blocksize=""
+    clustersize=""
+    journalesize=""
+
+    # o2cb is the problem.... /etc/init.d/o2cb
+    #   sets it's config in /etc/sysconfig/o2cb (can be removed)
+    #   dmsetup requires the stopping of o2cb first,
+    #   then the removal of the config, after which dmsetup
+    #   can remove the device from /dev/mapper/
+    # eventually cluster cleanup can be done by removing
+    #   stuff from /etc/ovs-agent/db 
+    #   also clean /etc/ocfs2/cluster.conf
+    print server.create_pool_filesystem(
+        fstype,
+        fstarget,
+        clusterid,
+        poolfsuuid,
+        poolfsnfsbaseuuid,
+        manageruuid,
+        pooluuid
+    )
+
+    # poolDom = server.discover_server_pool()
+    # print poolDom
+    # poolDom = parseString(server.discover_server_pool()) 
+    # if poolDom.getElementsByTagName('Server_Pool'):
+    # get unique id
+    cluster = server.is_cluster_online()
+    if cluster == True:
+        print "clean up pool"
+        # print server.destroy_cluster(poolfsuuid)
+        # deconfigure cluster
+        # print server.destroy_server_pool(poolid)
+        
+    if cluster == False:
+        print "create_server_pool"
+        # first take ownership. without an owner nothing happens
+        print server.take_ownership(manageruuid, "")
+        # we need to add the first host first to the pool....
+        poolDom = server.discover_server_pool()
+        print poolDom
+        poolDom = parseString(server.discover_server_pool())
+        if poolDom.getElementsByTagName('Server_Pool'):
+            print server.destroy_server_pool(pooluuid)
+
+        print server.create_pool_filesystem(
+            fstype,
+            fstarget,
+            clusterid,
+            poolfsuuid,
+            poolfsnfsbaseuuid,
+            manageruuid,
+            pooluuid
+        )
+        print server.create_server_pool(poolalias, 
+            pooluuid, 
+            poolmvip, 
+            poolfirsthost['id'], 
+            poolfirsthost['hn'], 
+            poolfirsthost['ip'], 
+            poolfirsthost['role'])
+        
+        print "configure_virtual_ip"
+        server.configure_virtual_ip(poolmvip, poolfirsthost['ip'])
+        server.set_pool_member_ip_list(['192.168.1.64','192.168.1.65'],)
+        print "configure for cluster"
+        server.configure_server_for_cluster(
+            {
+                'O2CB_HEARTBEAT_THRESHOLD': '61', 
+                'O2CB_RECONNECT_DELAY_MS': '2000', 
+                'O2CB_KEEPALIVE_DELAY_MS': '2000', 
+                'O2CB_BOOTCLUSTER': clusterid, 
+                'O2CB_IDLE_TIMEOUT_MS': '60000', 
+                'O2CB_ENABLED': 'true', 
+                'O2CB_STACK': 'o2cb'
+            }, 
+            {
+                'node': [
+                    {
+                        'ip_port': 7777, 
+                        'cluster': clusterid, 
+                        'ip_address': poolfirsthost['ip'], 
+                        'name': poolfirsthost['hn'], 
+                        'number': poolfirsthost['id']
+                    }
+                ], 
+                'heartbeat': [
+                    {
+                        'cluster': clusterid, 
+                        # uppercase poolfsuuid
+                        'region': '0004FB0000050000E70FBDDEB802208F'
+                    }
+                ], 
+                'cluster': [
+                    {
+                        'heartbeat_mode': 'global', 
+                        'node_count': 1, 
+                        'name': clusterid
+                    }
+                ]
+            }, 
+            'nfs', 
+            'cs-mgmt:/volumes/cs-data/primary', 
+            poolfsuuid, 
+            poolfsnfsbaseuuid
+        )
+        print "create cluster"
+        server.create_cluster(poolfsuuid,)
+
+    poolDom = parseString(server.discover_server_pool())
+    for node in poolDom.getElementsByTagName('Server_Pool'):
+        id = node.getElementsByTagName('Unique_Id')[0].firstChild.nodeValue
+        alias = node.getElementsByTagName('Pool_Alias')[0].firstChild.nodeValue
+        mvip = node.getElementsByTagName('Master_Virtual_Ip')[0].firstChild.nodeValue
+        print "pool: %s, %s, %s" % (id, mvip, alias)
+        members = node.getElementsByTagName('Member')
+        for member in members:
+            mip = member.getElementsByTagName('Registered_IP')[0].firstChild.nodeValue
+            print "member: %s" % (mip)
+
+    print server.is_cluster_online()
+    print server.discover_cluster()
+    print server.discover_pool_filesystem()
+    print server.discover_server_pool()
+    # server.destroy_server_pool(pooluuid)
+
+except Error, v:
+    print "ERROR", v
diff --git a/plugins/hypervisors/ovm3/scripts/info.py b/plugins/hypervisors/ovm3/scripts/info.py
new file mode 100755
index 0000000..518aaf1
--- /dev/null
+++ b/plugins/hypervisors/ovm3/scripts/info.py
@@ -0,0 +1,111 @@
+#!/usr/bin/python
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF 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.
+#
+import os, sys, subprocess, socket,fcntl, struct
+from socket import gethostname
+import errno
+from socket import error as socket_error
+from xml.dom.minidom import parseString
+
+from xmlrpclib import ServerProxy, Error
+
+def spCon(proto, auth, host, port):
+    print "trying %s on %s@%s:%s" % (proto, auth, host, port)
+    try:
+        x=ServerProxy("%s://%s@%s:%s" % (proto, auth, host, port))
+        x.echo(proto)
+        return x
+    except Error, v:
+        return
+    except socket_error, serr:
+        return
+
+def getCon(auth, host, port):
+    try:    
+        server = spCon("http", auth, host, port)
+        if server:
+            return server
+        else:
+            server = spCon("https", auth, host, port)
+    except Error, v:
+        print "ERROR", v
+    return server
+
+def get_ip_address(ifname):
+    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    return socket.inet_ntoa(fcntl.ioctl(
+        s.fileno(),
+        0x8915,  # SIOCGIFADDR
+        struct.pack('256s', ifname[:15])
+    )[20:24])
+
+def is_it_up(host, port):
+    try:
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        s.settimeout(1)
+        s.connect((host, port))
+        s.close()
+    except:
+        print "host: %s:%s DOWN" % (host, port)
+        return False
+
+    print "host: %s:%s UP" % (host, port)
+    return True
+
+# hmm master actions don't apply to a slave
+master="192.168.1.161"
+port=8899
+user = "oracle"
+password = "test123"
+auth = "%s:%s" % (user, password)
+server = getCon(auth, 'localhost', port)
+mserver = getCon(auth, master, port)
+poolNode=True
+interface = "c0a80100"
+role='xen,utility'
+hostname=gethostname()
+ip = get_ip_address(interface)
+poolMembers = []
+xserver = server
+poolCount = 0
+
+try:
+    print server.discover_pool_filesystem()
+    print
+    print server.discover_server_pool()
+    poolDom = parseString(server.discover_server_pool())
+    for node in poolDom.getElementsByTagName('Server_Pool'):
+        id = node.getElementsByTagName('Unique_Id')[0].firstChild.nodeValue
+        alias = node.getElementsByTagName('Pool_Alias')[0].firstChild.nodeValue
+        mvip = node.getElementsByTagName('Master_Virtual_Ip')[0].firstChild.nodeValue
+        print "pool: %s, %s, %s" % (id, mvip, alias)
+        members = node.getElementsByTagName('Member')
+        for member in members:
+            poolCount = poolCount + 1
+            mip = member.getElementsByTagName('Registered_IP')[0].firstChild.nodeValue
+            print "member: %s" % (mip)
+            if mip == ip:
+               pooled = True
+            else:
+               poolMembers.append(mip)
+            
+    # print server.discover_server()
+
+except Error, v:
+    print "ERROR", v
diff --git a/plugins/hypervisors/ovm3/scripts/ovs_agent_plugin/cloudstack.py b/plugins/hypervisors/ovm3/scripts/ovs_agent_plugin/cloudstack.py
new file mode 100644
index 0000000..f655760
--- /dev/null
+++ b/plugins/hypervisors/ovm3/scripts/ovs_agent_plugin/cloudstack.py
@@ -0,0 +1,344 @@
+#!/usr/bin/python
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF 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.
+#
+import logging
+import time
+import re
+import os.path
+import paramiko
+import subprocess
+import socket
+
+from xen.util.xmlrpcclient import ServerProxy
+from xmlrpclib import Error
+from xen.xend import XendClient
+from agent.api.base import Agent
+from agent.lib.settings import get_api_version
+from xen.xend import sxp
+
+class CloudStack(Agent):
+    """
+    Cloudstack plugin for OVM3.2.x.
+    """
+
+    # exposed services
+    def get_services(self, version=None):
+        return {
+            'call': call,
+            'get_vncport': getVncPort,
+            'exec_domr': domrExec,
+            'check_domr_port': domrCheckPort,
+            'check_domr_ssh': domrCheckSsh,
+            'ovs_control_interface': ovsControlInterface,
+            'ovs_mkdir': ovsMkdir,
+            'ovs_check_file': ovsCheckFile,
+            'ovs_upload_ssh_key': ovsUploadSshKey,
+            'ovs_dom0_stats': ovsDom0Stats,
+            'ovs_domU_stats': ovsDomUStats,
+            'get_module_version': getModuleVersion,
+            'ping': ping,
+#            'ovs_agent_set_ssl': ovsAgentSetSsl,
+#            'ovs_agent_set_port': ovsAgentSetPort,
+#            'ovs_restart_agent': ovsRestartAgent,
+        }
+
+    def getName(self):
+        return self.__class__.__name__
+
+# which version are we intended for?
+def getModuleVersion():
+    return "0.1"
+
+# call test
+def call(msg):
+    return msg
+
+# execute something on domr
+def domrExec(ip, cmd, timeout=10, username="root", port=3922, keyfile="~/.ssh/id_rsa.cloud"):
+    ssh = paramiko.SSHClient()
+    ssh.load_system_host_keys()
+    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+    privatekeyfile = os.path.expanduser(keyfile)
+    key = paramiko.RSAKey.from_private_key_file(privatekeyfile)
+    ssh.connect(ip, port, username, pkey=key, timeout=timeout)
+    ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(cmd)
+    exit_status = ssh_stdout.channel.recv_exit_status()
+    ssh.close()
+    return { "rc": exit_status,
+        "out": ''.join(ssh_stdout.readlines()),
+        "err": ''.join(ssh_stderr.readlines()) };
+
+# check a port on domr
+def domrPort(ip, port=3922, timeout=3):
+    return domrCheckPort(ip, port, timeout=timeout)
+
+# check a port on domr
+def domrCheckPort(ip, port=3922, timeout=3):
+    try:
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        s.settimeout(timeout)
+        s.connect((ip, port))
+        s.close()
+        return True
+    except:
+        return False
+
+# check ssh
+def domrCheckSsh(ip, port=3922, timeout=10):
+    x = domrExec(ip, "", port=port, timeout=timeout)
+    if (x.get("rc") == 0):
+        return True
+    return False
+
+def _ovsIni(setting, set):
+    ini="/etc/ovs-agent/agent.ini"
+    replaced=False
+    if os.path.isfile(ini):
+        import fileinput
+        for line in fileinput.FileInput(ini, inplace=1):
+                line=line.rstrip('\n')
+                if re.search("%s=" % setting, line):
+                    line="%s=%s" % (setting, set)
+                    replaced=True
+                print line
+    return replaced
+
+# enable/disable ssl for the agent
+def ovsAgentSetSsl(state):
+    ena="disable"
+    if state and state != "disable" and state.lower() != "false":
+        ena="enable"
+    return _ovsIni("ssl", ena)
+
+def ovsAgentSetPort(port):
+    return _ovsIni("port", port)
+
+def ovsRestartAgent():
+    return restartService("ovs-agent")
+
+# replace with popen
+def restartService(service):
+    command = ['service', service, 'restart'];
+    subprocess.call(command, shell=False)
+    return True
+
+# sets the control interface and removes the route net entry
+def ovsControlInterface(dev, ipmask):
+    command = ['route', 'del', '-net', ipmask];
+    subprocess.call(command, shell=False)
+    command = ['ifconfig', dev, 'arp']
+    subprocess.call(command, shell=False)
+    return True
+
+# create a dir if we need it
+def ovsMkdir(dir, mode=0700):
+    if not os.path.exists(dir):
+        return os.makedirs(dir, mode)
+    return True
+
+# if a file exists, easy
+def ovsCheckFile(file):
+    if os.path.isfile(file):
+        return True
+    return False
+
+# upload keys
+def ovsUploadSshKey(keyfile, content):
+    keydir=os.path.expanduser("~/.ssh")
+    key="%s/%s" % (keydir, keyfile)
+    try:
+        ovsMkdir(os.path.expanduser(keydir))
+    except Error, v:
+        print "was already there %s" % keydir
+
+    try:
+        text_file = open("%s" % key, "w")
+        text_file.write("%s" % content)
+        text_file.close()
+    except Error, v:
+        print "something went wrong %s" % v
+        return False
+    return True
+
+
+# older python,
+def ovsDom0Stats(bridge):
+    stats={}
+    stats['cpu'] = "%s" % (100 - float(os.popen("top -b -n 1 | grep Cpu\(s\): | cut -d% -f4|cut -d, -f2").read()))
+    stats['free'] = "%s" % (1048576 * int(os.popen("xm info | grep free_memory | awk '{ print $3 }'").read()))
+    stats['total'] = "%s" % (1048576 * int(os.popen("xm info | grep total_memory | awk '{ print $3 }'").read()))
+    stats['tx'] = os.popen("netstat -in | grep %s | head -1 | awk '{print $4 }'" % bridge).read()
+    stats['rx'] = os.popen("netstat -in | grep %s | head -1 | awk '{print $8 }'" % bridge).read()
+    return stats
+
+def getVncPort(domain):
+    port = "0"
+    if re.search("\w-(\d+-)?\d+-VM", domain):
+        server=ServerProxy(XendClient.uri)
+        dom=server.xend.domain(domain, 1)
+        devices = [child for child in sxp.children(dom)
+            if len(child) > 0 and child[0] == "device"]
+        vfbs_sxp = map(lambda x: x[1], [device for device in devices 
+            if device[1][0] == "vfb"])[0]
+        loc=[child for child in vfbs_sxp
+            if child[0] == "location"][0][1]
+        listner, port = loc.split(":")
+    else:
+        print "no valid domain: %s" % domain
+    return port
+
+def get_child_by_name(exp, childname, default = None):
+    try:
+        return [child for child in sxp.children(exp)
+                if child[0] == childname][0][1]
+    except:
+        return default
+
+def ovsDomUStats(domain):
+    _rd_bytes=0
+    _wr_bytes=0
+    _rd_ops=0
+    _wr_ops=0
+    _tx_bytes=0
+    _rx_bytes=0
+    stats={}
+    server=ServerProxy(XendClient.uri)
+    dominfo=server.xend.domain(domain, 1)
+    domid=get_child_by_name(dominfo, "domid")
+
+    # vbds
+    devs = server.xend.domain.getDeviceSxprs(domain, 'vbd')
+    devids = [dev[0] for dev in devs]
+    for dev in devids:
+        sys_path="/sys/devices/%s-%s-%s/statistics" % ("vbd", domid, dev)
+        _rd_bytes += long(open("%s/rd_sect" % sys_path).readline().strip())
+        _wr_bytes += long(open("%s/wr_sect" % sys_path).readline().strip())
+        _rd_ops += long(open("%s/rd_req" % sys_path).readline().strip())
+        _wr_ops += long(open("%s/wr_req" % sys_path).readline().strip())
+
+    # vifs
+    devs = server.xend.domain.getDeviceSxprs(domain, 'vif')
+    devids = [dev[0] for dev in devs]
+    for dev in devids:
+        vif="vif%s.%s" % (domid, dev)
+        sys_path="/sys/devices/%s-%s-%s/net/%s/statistics" % ("vif", domid, dev, vif)
+        _tx_bytes += long(open("%s/tx_bytes" % sys_path).readline().strip())
+        _rx_bytes += long(open("%s/rx_bytes" % sys_path).readline().strip())
+
+    epoch=time.time()
+    stats['rd_bytes'] = "%s" % (_rd_bytes * 512)
+    stats['wr_bytes'] = "%s" % (_wr_bytes * 512)
+    stats['rd_ops'] = "%s" % (_rd_ops)
+    stats['wr_ops'] = "%s" % (_wr_ops)
+    stats['tx_bytes'] = "%s" % (_tx_bytes)
+    stats['rx_bytes'] = "%s" % (_rx_bytes)
+    stats['cputime']= "%s" % get_child_by_name(dominfo, "cpu_time")
+    stats['uptime']= "%s" % (epoch - get_child_by_name(dominfo, "start_time"))
+    stats['vcpus']= "%s" % get_child_by_name(dominfo, "online_vcpus")
+    return stats
+
+def ping(host, count=3):
+    if os.system("ping -c %s %s " % (count, host)) == 0:
+        return True
+    return False
+
+# add SystemVM stuff here....
+#
+
+#
+# Self deploy and integration, not de-integration 
+# should return False if fails
+#
+# install us if we are missing in: 
+# /usr/lib64/python2.4/site-packages/agent/api
+# and add our hooks in:
+# /usr/lib64/python2.4/site-packages/agent/target/api.py
+if __name__ == '__main__':
+    from distutils.sysconfig import get_python_lib
+    from agent.target.api import MODULES
+    from shutil import copyfile
+    import inspect, os, hashlib, getopt, sys
+
+    # default vars
+    exist=False
+    agentpath="%s/agent" % (get_python_lib(1))
+    api="%s/target/api.py" % (agentpath)
+    modpath="%s/api" % (agentpath)
+    ssl="disable"
+    port=0
+
+    # get options
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "sp::", 
+            [ 'port=','ssl='])
+    except getopt.GetoptError:
+        print "Available Options: --port=, --ssl="
+        sys.exit()
+
+    for o, a in opts:
+        if o in ('-s', '--ssl'):
+            ssl = a
+        if o in ('-p', '--port'):
+            port = int(a)
+
+    # check if we're in the modules already
+    cs = CloudStack()
+    for mod in MODULES:
+        if re.search(cs.getName(), "%s" % (mod)):
+            exist=True
+
+    # if we're not:
+    if not exist:
+        if os.path.isfile(api):
+            import fileinput
+            for line in fileinput.FileInput(api, inplace=1):
+                line=line.rstrip('\n')
+                if re.search("import common", line):
+                    line="%s, cloudstack" % (line)
+                if re.search("MODULES", line):
+                    n=cs.getName()
+                    line="%s\n\t%s.%s," % (line, n.lower(), n)
+                print line
+            print "Api inserted, %s in %s" % (cs.getName(), api)
+        else:
+            print "Api missing, %s" % (api)
+    else:
+        print "Api present, %s in %s" % (cs.getName(), api)
+
+    # either way check our version and install if checksum differs
+    modfile="%s/%s.py" % (modpath, cs.getName().lower())
+    me=os.path.abspath(__file__)
+    if os.path.isfile(modfile):
+        if hashlib.md5(open(me).read()).hexdigest() != hashlib.md5(open(modfile).read()).hexdigest():
+            print "Module copy, %s" % (modfile)
+            copyfile(me, modfile)
+        else:
+            print "Module correct, %s" % (modfile)
+    else:
+        print "Module copy, %s" % (modfile)
+        copyfile(me, modfile)
+    
+    # setup ssl and port
+    if ssl:
+        ovsAgentSetSsl(ssl)
+    if port > 1024:
+        ovsAgentSetPort(port)
+
+    # restart either way
+    ovsRestartAgent()
diff --git a/plugins/hypervisors/ovm3/scripts/password.py b/plugins/hypervisors/ovm3/scripts/password.py
new file mode 100755
index 0000000..25404a9
--- /dev/null
+++ b/plugins/hypervisors/ovm3/scripts/password.py
@@ -0,0 +1,57 @@
+#!/usr/bin/python
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF 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.
+#
+import os, sys, subprocess, socket,fcntl, struct
+from socket import gethostname
+from xml.dom.minidom import parseString
+
+from xmlrpclib import ServerProxy, Error
+
+def spCon(proto, host, port):
+    print "trying %s on %s:%s" % (proto, host, port)
+    try:
+        x=ServerProxy("%s://%s:%s" % (proto, host, port))
+        x.echo(proto)
+        return x
+    except Error, v:
+        print "ERROR", v
+        return
+
+def getCon(host, port):
+    try:
+        server = spCon("http", host, port)
+    except Error, v:
+        print "ERROR", v
+        server = spCon("https", host, port)
+
+    return server
+
+# hmm master actions don't apply to a slave
+port=8899
+user = "oracle"
+password = "test123"
+auth = "%s:%s" % (user, password)
+host = "localhost"
+
+print "setting up password"
+try:
+    con = getCon(host, port)
+    print con.update_agent_password(user, password)
+except Error, v:
+    print "ERROR", v
diff --git a/plugins/hypervisors/ovm3/scripts/repo_pool.py b/plugins/hypervisors/ovm3/scripts/repo_pool.py
new file mode 100755
index 0000000..71feca8
--- /dev/null
+++ b/plugins/hypervisors/ovm3/scripts/repo_pool.py
@@ -0,0 +1,186 @@
+#!/usr/bin/python
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF 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.
+#
+import os, sys, subprocess, socket,fcntl, struct
+from socket import gethostname
+from xml.dom.minidom import parseString
+
+from xmlrpclib import ServerProxy, Error
+
+def get_ip_address(ifname):
+    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    return socket.inet_ntoa(fcntl.ioctl(
+        s.fileno(),
+        0x8915,  # SIOCGIFADDR
+        struct.pack('256s', ifname[:15])
+    )[20:24])
+
+def is_it_up(host, port):
+    try:
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        s.settimeout(1)
+        s.connect((host, port))
+        s.close()
+    except:
+        print "host: %s:%s DOWN" % (host, port)
+        return False
+
+    print "host: %s:%s UP" % (host, port)
+    return True
+
+# hmm master actions don't apply to a slave
+master="192.168.1.161"
+port=8899
+user = "oracle"
+password = "*******"
+auth = "%s:%s" % (user, password)
+server = ServerProxy("http://%s:%s" % ("localhost", port))
+mserver = ServerProxy("http://%s@%s:%s" % (auth, master, port))
+poolNode=True
+interface = "c0a80100"
+role='xen,utility'
+hostname=gethostname()
+ip = get_ip_address(interface)
+poolMembers = []
+xserver = server
+
+print "setting up password"
+server.update_agent_password(user, password)
+
+if (is_it_up(master, port)):
+    print "master seems to be up, slaving"
+    xserver = mserver
+else:
+    print "no master yet, will become master"
+
+# other mechanism must be used to make interfaces equal...
+try:
+    # pooling related same as primary storage!
+    poolalias="Pool 0"
+    poolid="0004fb0000020000ba9aaf00ae5e2d73"
+    poolfsnfsbaseuuid="7718562d-872f-47a7-b454-8f9cac4ffa3a"
+    pooluuid=poolid
+    poolfsuuid=poolid
+    clusterid="ba9aaf00ae5e2d72"
+    mgr="d1a749d4295041fb99854f52ea4dea97"
+    poolmvip=master
+
+    poolfsnfsbaseuuid="6824e646-5908-48c9-ba44-bb1a8a778084"
+    repoid="6824e646590848c9ba44bb1a8a778084"
+    poolid=repoid
+    repo="/OVS/Repositories/%s" % (repoid)
+    repomount="cs-mgmt:/volumes/cs-data/secondary"
+
+    # primary
+    primuuid="7718562d872f47a7b4548f9cac4ffa3a"
+    ssuuid="7718562d-872f-47a7-b454-8f9cac4ffa3a"
+    fshost="cs-mgmt"
+    fstarget="/volumes/cs-data/primary"
+    fstype="nfs"
+    fsname="Primary storage"
+    fsmntpoint="%s:%s" % (fshost, fstarget)
+    fsmnt="/nfsmnt/%s" % (ssuuid)
+    fsplugin="oracle.generic.NFSPlugin.GenericNFSPlugin"
+
+    # set the basics we require to "operate"
+    print server.take_ownership(mgr, '')
+    print server.update_server_roles(role,)
+
+    # if we're pooling pool...
+    if (poolNode == True):
+        poolCount = 0
+        pooled = False
+
+        # check pooling
+        try:
+            poolDom = parseString(xserver.discover_server_pool())
+            print xserver.discover_server_pool()
+            for node in poolDom.getElementsByTagName('Server_Pool'):
+                id = node.getElementsByTagName('Unique_Id')[0].firstChild.nodeValue
+                alias = node.getElementsByTagName('Pool_Alias')[0].firstChild.nodeValue
+                mvip = node.getElementsByTagName('Master_Virtual_Ip')[0].firstChild.nodeValue
+                print "pool: %s, %s, %s" % (id, mvip, alias)
+                members = node.getElementsByTagName('Member')
+                for member in members:
+                    poolCount = poolCount + 1
+                    mip = member.getElementsByTagName('Registered_IP')[0].firstChild.nodeValue
+                    print "member: %s" % (mip)
+                    if mip == ip:
+                        pooled = True
+                    else:
+                        poolMembers.append(mip)
+
+        except Error,v:
+            print "no master will become master, %s" % v
+            
+        if (pooled == False):
+            # setup the repository
+            print "setup repo"
+            print server.mount_repository_fs(repomount, repo)
+            try:    
+                print "adding repo"
+                print server.add_repository(repomount, repo)
+            except Error, v:
+                print "will create the repo, as it's not there", v
+                print server.create_repository(repomount, repo, repoid, "repo") 
+
+            print "not pooled!"
+            if (poolCount == 0):
+                print "no pool yet, create it"
+                # check if a pool exists already if not create 
+                # pool if so add us to the pool
+                print "create pool fs"
+                print server.create_pool_filesystem(
+                    fstype, 
+                    "%s/VirtualMachines/" % repomount,
+                    clusterid,
+                    poolfsuuid,
+                    poolfsnfsbaseuuid,
+                    mgr,
+                    pooluuid
+                )
+                print "create pool"      
+                print server.create_server_pool(poolalias, 
+                    pooluuid, 
+                    poolmvip, 
+                    poolCount, 
+                    hostname, 
+                    ip, 
+                    role
+                )
+            else:
+                print "join the pool"
+                print server.join_server_pool(poolalias,
+                    pooluuid,
+                    poolmvip,
+                    poolCount,
+                    hostname,
+                    ip,
+                    role
+                )
+
+        # add member to ip list ?
+        poolMembers.append(ip)
+        print "mambers for pool: %s" % poolMembers
+        print xserver.set_pool_member_ip_list(poolMembers)
+
+    print server.discover_server_pool()
+
+except Error, v:
+    print "ERROR", v
diff --git a/plugins/hypervisors/ovm3/scripts/simple_pool.py b/plugins/hypervisors/ovm3/scripts/simple_pool.py
new file mode 100755
index 0000000..756de93
--- /dev/null
+++ b/plugins/hypervisors/ovm3/scripts/simple_pool.py
@@ -0,0 +1,209 @@
+#!/usr/bin/python
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF 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.
+#
+import os, sys, subprocess, socket,fcntl, struct
+from socket import gethostname
+from xml.dom.minidom import parseString
+import errno
+from socket import error as socket_error
+
+from xmlrpclib import ServerProxy, Error
+
+def spCon(proto, auth, host, port):
+    print "trying %s on %s@%s:%s" % (proto, auth, host, port)
+    try:
+        x=ServerProxy("%s://%s@%s:%s" % (proto, auth, host, port))
+        x.echo(proto)
+        return x
+    except Error, v:
+        return
+    except socket_error, serr:
+        return
+
+def getCon(auth, host, port):
+    try:    
+        server = spCon("http", auth, host, port)
+        if server:
+            return server
+        else:
+            server = spCon("https", auth, host, port)
+    except Error, v:
+        print "ERROR", v
+    return server
+
+def get_ip_address(ifname):
+    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    return socket.inet_ntoa(fcntl.ioctl(
+        s.fileno(),
+        0x8915,  # SIOCGIFADDR
+        struct.pack('256s', ifname[:15])
+    )[20:24])
+
+# hmm master actions don't apply to a slave
+master="192.168.1.161"
+port=8899
+passw='test123'
+user='oracle'
+auth="%s:%s" % (user, passw)
+server = getCon(auth, "localhost", port)
+mserver = getCon(auth, master, port)
+try:
+    mserver.echo("test")
+except AttributeError, v:
+    print "no mserver, becoming mserver"
+    mserver=server
+
+poolNode=True
+interface = "c0a80100"
+role='xen,utility'
+hostname=gethostname()
+ip = get_ip_address(interface)
+nodes=[]
+
+try:
+    # pooling related same as primary storage!
+    poolalias="Pool 0"
+    clusterid="ba9aaf00ae5e2d72"
+    mgr="d1a749d4295041fb99854f52ea4dea97"
+    poolmvip=master
+
+    # primary
+    primuuid="7718562d872f47a7b4548f9cac4ffa3a"
+    ssuuid="7718562d-872f-47a7-b454-8f9cac4ffa3a"
+    fshost="cs-mgmt"
+    fstarget="/volumes/cs-data/primary/ovm"
+    fstype="nfs"
+    fsname="Primary storage"
+    fsmntpoint="%s:%s" % (fshost, fstarget)
+    fsmntpoint2="%s:%s" % (fshost, "/volumes/cs-data/secondary")
+    fsmntpoint="%s/VirtualMachines" % (fsmntpoint2)
+    fsmnt="/nfsmnt/%s" % (ssuuid)
+    fsplugin="oracle.generic.NFSPlugin.GenericNFSPlugin"
+    repo="/OVS/Repositories/%s" % (primuuid)
+
+    # set the basics we require to "operate"
+    print server.take_ownership(mgr, '')
+    print server.update_server_roles(role,)
+
+    # setup the repository
+    print server.mount_repository_fs(fsmntpoint2, repo)
+    try:
+        print server.add_repository(fsmntpoint2, repo)
+    except Error, v:
+        print "will create the repo, as it's not there", v
+        print server.create_repository(fsmntpoint2, repo, primuuid, "A repository")
+    
+    # if we're pooling pool...
+    if (poolNode == True):
+        poolCount = 0
+        pooled = False
+
+        # check pooling
+       	poolDom = parseString(mserver.discover_server_pool())
+        for node in poolDom.getElementsByTagName('Server_Pool'):
+            id = node.getElementsByTagName('Unique_Id')[0].firstChild.nodeValue
+            alias = node.getElementsByTagName('Pool_Alias')[0].firstChild.nodeValue
+            mvip = node.getElementsByTagName('Master_Virtual_Ip')[0].firstChild.nodeValue
+            print "pool: %s, %s, %s" % (id, mvip, alias)
+            members = node.getElementsByTagName('Member')
+            for member in members:
+                poolCount = poolCount + 1
+                mip = member.getElementsByTagName('Registered_IP')[0].firstChild.nodeValue
+                if (mip == ip):
+                    pooled = True
+                else:
+                    nodes.append(mip)
+                print "member: %s" % (mip)
+
+        # if (pooled == False):
+        try:
+            if (poolCount == 0):
+                print "master"
+                # check if a pool exists already if not create 
+                # pool if so add us to the pool
+                print server.configure_virtual_ip(master, ip)
+                print server.create_pool_filesystem(
+                    fstype, 
+                    fsmntpoint,
+                    clusterid,
+                    primuuid,
+                    ssuuid,
+                    mgr,
+                    primuuid
+                )       
+                print server.create_server_pool(poolalias, 
+                    primuuid, 
+                    poolmvip, 
+                    poolCount, 
+                    hostname, 
+                    ip, 
+                    role
+                )
+            else:
+                try:
+                    print "slave"
+                    print server.join_server_pool(poolalias,
+                        primuuid,
+                        poolmvip,
+                        poolCount,
+                        hostname,
+                        ip,
+                        role
+                    )
+                except Error, v:
+                    print "host already part of pool?: %s" % (v)
+                    
+            nodes.append(ip)
+            for node in nodes:
+                # con = getCon(auth, node, port)
+                # print con.set_pool_member_ip_list(nodes);
+                print mserver.dispatch("http://%s@%s:%s/api/3" % (auth, node, port), "set_pool_member_ip_list", nodes)
+            # print server.configure_virtual_ip(master, ip)
+        except Error, e:
+            print "something went wrong: %s" % (e)
+
+    # sys.exit()
+    # mount the primary fs
+    print server.storage_plugin_mount(
+        fsplugin, 
+        {
+            'uuid': primuuid, 
+            'storage_desc': fsname, 
+            'access_host': fshost, 
+            'storage_type': 'FileSys', 
+            'name':primuuid 
+       }, 
+        {
+            'status': '', 
+            'uuid': ssuuid,
+            'ss_uuid': primuuid, 
+            'size': 0, 
+            'state': 1, 
+            'access_grp_names': [], 
+            'access_path': fsmntpoint,
+            'name': fsname
+        },
+        fsmnt,
+        '', 
+        True, 
+        []
+    )
+
+except Error, v:
+    print "ERROR", v
diff --git a/plugins/hypervisors/ovm3/scripts/socat.sh b/plugins/hypervisors/ovm3/scripts/socat.sh
new file mode 100755
index 0000000..c3fbc44
--- /dev/null
+++ b/plugins/hypervisors/ovm3/scripts/socat.sh
@@ -0,0 +1,2 @@
+CERT="/etc/ovs-agent/cert"
+socat OPENSSL-LISTEN:8899,reuseaddr,fork,verify=0,key=$CERT/key.pem,cert=$CERT/certificate.pem TCP:localhost:8898 &
diff --git a/plugins/hypervisors/ovm3/scripts/tail.sh b/plugins/hypervisors/ovm3/scripts/tail.sh
new file mode 100755
index 0000000..fe88bc0
--- /dev/null
+++ b/plugins/hypervisors/ovm3/scripts/tail.sh
@@ -0,0 +1,2 @@
+cd /var/log 
+tail -f ovm-consoled.log devmon.log messages ovs-agent.log ovmwatch.log
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/ha/Ovm3Investigator.java b/plugins/hypervisors/ovm3/src/com/cloud/ha/Ovm3Investigator.java
new file mode 100644
index 0000000..980fa1f
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/ha/Ovm3Investigator.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF 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 com.cloud.ha;
+
+import java.util.List;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckOnHostCommand;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.resource.ResourceManager;
+import com.cloud.utils.component.AdapterBase;
+
+@Local(value = Investigator.class)
+public class Ovm3Investigator extends AdapterBase implements Investigator {
+    private final static Logger s_logger = Logger.getLogger(Ovm3Investigator.class);
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    ResourceManager _resourceMgr;
+
+    @Override
+    public Boolean isVmAlive(com.cloud.vm.VirtualMachine vm, Host host) {
+        Status status = isAgentAlive(host);
+        if (status == null) {
+            return null;
+        }
+        return status == Status.Up ? true : null;
+    }
+
+    @Override
+    public Status isAgentAlive(Host agent) {
+        if (agent.getHypervisorType() != Hypervisor.HypervisorType.Ovm3) {
+            return null;
+        }
+        CheckOnHostCommand cmd = new CheckOnHostCommand(agent);
+        List<HostVO> neighbors = _resourceMgr.listHostsInClusterByStatus(agent.getClusterId(), Status.Up);
+        for (HostVO neighbor : neighbors) {
+            if (neighbor.getId() == agent.getId() || neighbor.getHypervisorType() != Hypervisor.HypervisorType.Ovm3) {
+                continue;
+            }
+            try {
+                Answer answer = _agentMgr.easySend(neighbor.getId(), cmd);
+                if (answer != null) {
+                    return answer.getResult() ? Status.Down : Status.Up;
+                }
+            } catch (Exception e) {
+                s_logger.debug("Failed to send command to host: " + neighbor.getId());
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Discoverer.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Discoverer.java
new file mode 100755
index 0000000..bd1d90d
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Discoverer.java
@@ -0,0 +1,411 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF 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 com.cloud.hypervisor.ovm3.hypervisor;
+
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.UnknownHostException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+
+import com.cloud.agent.Listener;
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.AgentControlAnswer;
+import com.cloud.agent.api.AgentControlCommand;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.host.Status;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.configuration.Config;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.ClusterDetailsDao;
+// import com.cloud.exception.DiscoveryException;
+import com.cloud.host.HostInfo;
+import com.cloud.host.HostVO;
+import com.cloud.host.Host;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.ovm3.object.Linux;
+import com.cloud.hypervisor.ovm3.object.Connection;
+import com.cloud.resource.Discoverer;
+import com.cloud.resource.DiscovererBase;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.utils.db.QueryBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.ssh.SSHCmdHelper;
+
+@Local(value = Discoverer.class)
+public class Ovm3Discoverer extends DiscovererBase implements Discoverer,
+        Listener, ResourceStateAdapter {
+    private static final Logger s_logger = Logger
+            .getLogger(Ovm3Discoverer.class);
+    protected String _publicNetworkDevice;
+    protected String _privateNetworkDevice;
+    protected String _guestNetworkDevice;
+    protected String _storageNetworkDevice;
+    private String _ovsAgentPath = "/etc/ovs-agent/agent.ini";
+
+    @Inject
+    ClusterDao _clusterDao;
+    @Inject
+    ClusterDetailsDao _clusterDetailsDao;
+    @Inject
+    ResourceManager _resourceMgr;
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    HostDao _hostDao = null;
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params)
+            throws ConfigurationException {
+        super.configure(name, params);
+        /* these are in Config.java */
+        _publicNetworkDevice = _params.get(Config.Ovm3PublicNetwork.key());
+        _privateNetworkDevice = _params.get(Config.Ovm3PrivateNetwork.key());
+        _guestNetworkDevice = _params.get(Config.Ovm3GuestNetwork.key());
+        _storageNetworkDevice = _params.get(Config.Ovm3StorageNetwork.key());
+        _resourceMgr.registerResourceStateAdapter(this.getClass()
+                .getSimpleName(), this);
+        return true;
+    }
+
+    protected Ovm3Discoverer() {
+    }
+
+    @Override
+    public boolean stop() {
+        _resourceMgr.unregisterResourceStateAdapter(this.getClass()
+                .getSimpleName());
+        return super.stop();
+    }
+
+    private boolean checkIfExisted(String guid) {
+        QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        sc.and(sc.entity().getGuid(), SearchCriteria.Op.EQ, guid);
+        sc.and(sc.entity().getHypervisorType(), SearchCriteria.Op.EQ,
+                HypervisorType.Ovm3);
+        List<HostVO> hosts = sc.list();
+        return !hosts.isEmpty();
+    }
+
+    @Override
+    public Map<? extends ServerResource, Map<String, String>> find(long dcId,
+            Long podId, Long clusterId, URI url, String username,
+            String password, List<String> hostTags)
+            throws CloudRuntimeException {
+        Connection c = null;
+
+        if (url.getScheme().equals("http") || url.getScheme().equals("https")) {
+            String msg = "Discovering " + url
+                + ": " + _params;
+            s_logger.debug(msg);
+        } else {
+            String msg = "urlString is not http(s) so we're not taking care of the discovery for this: "
+                    + url;
+            s_logger.debug(msg);
+            throw new CloudRuntimeException(msg);
+        }
+
+        if (clusterId == null) {
+            String msg = "must specify cluster Id when add host";
+            s_logger.debug(msg);
+            throw new CloudRuntimeException(msg);
+        }
+
+        if (podId == null) {
+            String msg = "must specify pod Id when add host";
+            s_logger.debug(msg);
+            throw new CloudRuntimeException(msg);
+        }
+
+        ClusterVO cluster = _clusterDao.findById(clusterId);
+        if (cluster == null
+                || (cluster.getHypervisorType() != HypervisorType.Ovm3)) {
+            String msg = "invalid cluster id or cluster is not for Ovm3 hypervisors";
+            s_logger.info(msg);
+            throw new CloudRuntimeException(msg);
+        } else {
+            s_logger.info("cluster: " + cluster);
+        }
+
+        String agentUsername = _params.get("agentusername");
+        if (agentUsername == null) {
+            String msg = "Agent user name must be specified";
+            s_logger.info(msg);
+            throw new CloudRuntimeException(msg);
+        }
+
+        String agentPassword = _params.get("agentpassword");
+        if (agentPassword == null) {
+            String msg = "Agent password must be specified";
+            s_logger.info(msg);
+            throw new CloudRuntimeException(msg);
+        }
+
+        String agentPort = _params.get("agentport");
+        if (agentPort == null) {
+            String msg = "Agent port must be specified";
+            s_logger.info(msg);
+            throw new CloudRuntimeException(msg);
+        }
+
+        try {
+            String hostname = url.getHost();
+            /* port = url.getPort(); */
+
+            InetAddress ia = InetAddress.getByName(hostname);
+            String hostIp = ia.getHostAddress();
+            String guid = UUID.nameUUIDFromBytes(hostIp.getBytes()).toString();
+
+            if (checkIfExisted(guid)) {
+                String msg = "The host " + hostIp + " has been added before";
+                s_logger.debug(msg);
+                throw new CloudRuntimeException(msg);
+            }
+
+            s_logger.debug("Ovm3 discover is going to disover host having guid "
+                    + guid);
+
+            ClusterVO clu = _clusterDao.findById(clusterId);
+            if (clu.getGuid() == null) {
+                clu.setGuid(UUID.randomUUID().toString());
+            }
+            _clusterDao.update(clusterId, clu);
+            Map<String, String> clusterDetails = _clusterDetailsDao
+                    .findDetails(clusterId);
+            String ovm3vip = (clusterDetails.get("ovm3vip") == null) ? ""
+                    : clusterDetails.get("ovm3vip");
+            String ovm3pool = (clusterDetails.get("ovm3pool") == null) ? "false"
+                    : clusterDetails.get("ovm3pool");
+            String ovm3cluster = (clusterDetails.get("ovm3cluster") == null) ? "false"
+                    : clusterDetails.get("ovm3cluster");
+
+            /* should perhaps only make this connect to the agent port ? */
+            com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(
+                    hostIp, 22);
+            sshConnection.connect(null, 60000, 60000);
+            sshConnection = SSHCmdHelper.acquireAuthorizedConnection(hostIp,
+                    username, password);
+            if (sshConnection == null) {
+                String msg = String.format("Cannot connect to Ovm3 host(IP=%1$s, username=%2$s, password=*******), discovery failed",
+                        hostIp, username);
+                s_logger.warn(msg);
+                throw new CloudRuntimeException(msg);
+            }
+
+            Map<String, String> details = new HashMap<String, String>();
+            Ovm3ResourceBase ovmResource = new Ovm3ResourceBase();
+            details.put("ip", hostIp);
+            details.put("host", hostname);
+            details.put("username", username);
+            details.put("password", password);
+            details.put("zone", Long.toString(dcId));
+            details.put("guid", guid);
+            details.put("pod", Long.toString(podId));
+            details.put("cluster", Long.toString(clusterId));
+            details.put("agentusername", agentUsername);
+            details.put("agentpassword", agentPassword);
+            details.put("agentport", agentPort.toString());
+            details.put("ovm3vip", ovm3vip);
+            details.put("ovm3pool", ovm3pool);
+            details.put("ovm3cluster", ovm3cluster);
+
+            if (_publicNetworkDevice != null) {
+                details.put("public.network.device", _publicNetworkDevice);
+            }
+            if (_privateNetworkDevice != null) {
+                details.put("private.network.device", _privateNetworkDevice);
+            }
+            if (_guestNetworkDevice != null) {
+                details.put("guest.network.device", _guestNetworkDevice);
+            }
+            if (_storageNetworkDevice != null) {
+                details.put("storage.network.device", _storageNetworkDevice);
+            }
+            s_logger.warn("network devices: " + _guestNetworkDevice + " "
+                    + _privateNetworkDevice + " " + _publicNetworkDevice + " "
+                    + _storageNetworkDevice);
+
+            Map<String, Object> params = new HashMap<String, Object>();
+            params.putAll(details);
+
+            ovmResource.configure(hostname, params);
+            ovmResource.start();
+
+            try {
+                c = new Connection(hostIp, Integer.parseInt(agentPort), agentUsername, agentPassword);
+            } catch (Exception e) {
+                String msg = String.format("Cannot connect to Ovm3 agent(IP=%1$s, Port=%1$, username=%3$s, password=*******), discovery failed",
+                        hostIp, agentPort, agentUsername);
+                s_logger.warn(msg);
+                throw new CloudRuntimeException(msg);
+            }
+            /* After resource start, we are able to execute our agent api */
+            Linux host = new Linux(c);
+            details.put("agentVersion", host.getAgentVersion());
+            details.put(HostInfo.HOST_OS_KERNEL_VERSION,
+                    host.getHostKernelRelease());
+            details.put(HostInfo.HOST_OS, host.getHostOs());
+            details.put(HostInfo.HOST_OS_VERSION, host.getHostOsVersion());
+            details.put(HostInfo.HYPERVISOR_VERSION,
+                    host.getHypervisorVersion());
+
+            Map<Ovm3ResourceBase, Map<String, String>> resources = new HashMap<Ovm3ResourceBase, Map<String, String>>();
+            resources.put(ovmResource, details);
+            return resources;
+        } catch (XmlRpcException e) {
+            s_logger.debug("XmlRpc exception, Unable to discover Ovm3 host: " + url.getHost(),
+                    e);
+            return null;
+        } catch (UnknownHostException e) {
+            s_logger.debug(
+                    "Host name resolve failed exception, Unable to discover Ovm3 host: "
+                            + url.getHost(), e);
+            return null;
+        } catch (ConfigurationException e) {
+            s_logger.debug(
+                    "Configure resource failed, Unable to discover Ovm3 host: " + url.getHost(),
+                    e);
+            return null;
+        } catch (Exception e) {
+            s_logger.debug("Unable to discover Ovm3 host: " + url.getHost(), e);
+            return null;
+        }
+    }
+
+    @Override
+    public void postDiscovery(List<HostVO> hosts, long msId)
+            throws CloudRuntimeException {
+        // TODO Auto-generated method stub
+        s_logger.debug("postDiscovery" + hosts);
+    }
+
+    @Override
+    public boolean matchHypervisor(String hypervisor) {
+        return HypervisorType.Ovm3.toString().equalsIgnoreCase(hypervisor);
+    }
+
+    @Override
+    public HypervisorType getHypervisorType() {
+        return HypervisorType.Ovm3;
+    }
+
+    @Override
+    public HostVO createHostVOForConnectedAgent(HostVO host,
+            StartupCommand[] cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean processAnswers(long agentId, long seq, Answer[] answers) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean processCommands(long agentId, long seq, Command[] commands) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public AgentControlAnswer processControlCommand(long agentId,
+            AgentControlCommand cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* for reconnecting */
+    @Override
+    public void processConnect(Host host, StartupCommand cmd,
+            boolean forRebalance) {
+    }
+
+    @Override
+    public boolean processDisconnect(long agentId, Status state) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isRecurring() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public int getTimeout() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public boolean processTimeout(long agentId, long seq) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public HostVO createHostVOForDirectConnectAgent(HostVO host,
+            StartupCommand[] startup, ServerResource resource,
+            Map<String, String> details, List<String> hostTags) {
+        StartupCommand firstCmd = startup[0];
+        if (!(firstCmd instanceof StartupRoutingCommand)) {
+            return null;
+        }
+
+        StartupRoutingCommand ssCmd = ((StartupRoutingCommand) firstCmd);
+        if (ssCmd.getHypervisorType() != HypervisorType.Ovm3) {
+            return null;
+        }
+
+        // TODO: Double check this
+        return _resourceMgr.fillRoutingHostVO(host, ssCmd, HypervisorType.Ovm3,
+                details, hostTags);
+    }
+
+    // TODO: Make sure that we cleanup when the host is removed
+    @Override
+    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced,
+            boolean isForceDeleteStorage) throws UnableDeleteHostException {
+        if (host.getType() != com.cloud.host.Host.Type.Routing
+                || host.getHypervisorType() != HypervisorType.Ovm3) {
+            return null;
+        }
+
+        _resourceMgr.deleteRoutingHost(host, isForced, isForceDeleteStorage);
+        return new DeleteHostAnswer(true);
+    }
+
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Fencer.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Fencer.java
new file mode 100755
index 0000000..30db663
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Fencer.java
@@ -0,0 +1,133 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF 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 com.cloud.hypervisor.ovm3.hypervisor;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.FenceAnswer;
+import com.cloud.agent.api.FenceCommand;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.ha.FenceBuilder;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.resource.ResourceManager;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.vm.VirtualMachine;
+
+@Local(value = FenceBuilder.class)
+public class Ovm3Fencer extends AdapterBase implements FenceBuilder {
+    Map<String, Object> _params;
+    private static final Logger s_logger = Logger.getLogger(Ovm3Fencer.class);
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    ResourceManager _resourceMgr;
+
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params)
+            throws ConfigurationException {
+        _params = params;
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    public Ovm3Fencer() {
+        super();
+    }
+
+    @Override
+    public Boolean fenceOff(VirtualMachine vm, Host host) {
+        if (host.getHypervisorType() != HypervisorType.Ovm3) {
+            s_logger.debug("Don't know how to fence non Ovm3 hosts "
+                    + host.getHypervisorType());
+            return null;
+        } else {
+            s_logger.debug("Fencing " + vm + " on host " + host
+                    + " with params: "+ _params );
+        }
+
+        List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(host
+                .getClusterId());
+        FenceCommand fence = new FenceCommand(vm, host);
+
+        for (HostVO h : hosts) {
+            if (h.getHypervisorType() != HypervisorType.Ovm3) {
+                continue;
+            }
+
+            if (h.getStatus() != Status.Up) {
+                continue;
+            }
+
+            if (h.getId() == host.getId()) {
+                continue;
+            }
+
+            FenceAnswer answer;
+            try {
+                answer = (FenceAnswer) _agentMgr.send(h.getId(), fence);
+            } catch (AgentUnavailableException e) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Moving on to the next host because "
+                            + h.toString() + " is unavailable");
+                }
+                continue;
+            } catch (OperationTimedoutException e) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Moving on to the next host because "
+                            + h.toString() + " is unavailable");
+                }
+                continue;
+            }
+
+            if (answer != null && answer.getResult()) {
+                return true;
+            }
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Unable to fence off " + vm.toString() + " on "
+                    + host.toString());
+        }
+
+        return false;
+    }
+
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Guru.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Guru.java
new file mode 100755
index 0000000..08aac30
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Guru.java
@@ -0,0 +1,65 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF 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.
+
+/* shameless rip from original ovm guru */
+package com.cloud.hypervisor.ovm3.hypervisor;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.HypervisorGuru;
+import com.cloud.hypervisor.HypervisorGuruBase;
+import com.cloud.storage.GuestOSVO;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Local(value = HypervisorGuru.class)
+public class Ovm3Guru extends HypervisorGuruBase implements HypervisorGuru {
+    // private static final Logger s_logger = Logger.getLogger(VMwareGuru.class);
+
+    @Inject
+    GuestOSDao _guestOsDao;
+
+    protected Ovm3Guru() {
+        super();
+    }
+
+    @Override
+    public HypervisorType getHypervisorType() {
+        return HypervisorType.Ovm3;
+    }
+
+    @Override
+    public VirtualMachineTO implement(VirtualMachineProfile vm) {
+        VirtualMachineTO to = toVirtualMachineTO(vm);
+        to.setBootloader(vm.getBootLoaderType());
+
+        // Determine the VM's OS description
+        GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine()
+                .getGuestOSId());
+        to.setOs(guestOS.getDisplayName());
+
+        return to;
+    }
+
+    @Override
+    public boolean trackVmHostChange() {
+        return true;
+    }
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Helper.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Helper.java
new file mode 100755
index 0000000..8b0b1b5
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Helper.java
@@ -0,0 +1,82 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF 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 com.cloud.hypervisor.ovm3.hypervisor;
+
+import java.util.HashMap;
+
+public class Ovm3Helper {
+    /* /usr/lib64/python2.4/site-packages/agent/lib/assembly */
+    private static final HashMap<String, String> s_ovmMap = new HashMap<String, String>();
+
+    public static final String HVM = "hvm";
+    public static final String PV = "xen_pvm";
+    public static final String DOMSOL = "ldoms_pvm";
+    public static final String DEFAULT = "default";
+
+    static {
+        s_ovmMap.put("Oracle Enterprise Linux 6.0 (32-bit)", PV);
+        s_ovmMap.put("Oracle Enterprise Linux 6.0 (64-bit)", PV);
+        s_ovmMap.put("Oracle Enterprise Linux 5.0 (32-bit)", PV);
+        s_ovmMap.put("Oracle Enterprise Linux 5.0 (64-bit)", PV);
+        s_ovmMap.put("Oracle Enterprise Linux 5.1 (32-bit)", PV);
+        s_ovmMap.put("Oracle Enterprise Linux 5.1 (64-bit)", PV);
+        s_ovmMap.put("Oracle Enterprise Linux 5.2 (32-bit)", PV);
+        s_ovmMap.put("Oracle Enterprise Linux 5.2 (64-bit)", PV);
+        s_ovmMap.put("Oracle Enterprise Linux 5.3 (32-bit)", PV);
+        s_ovmMap.put("Oracle Enterprise Linux 5.3 (64-bit)", PV);
+        s_ovmMap.put("Oracle Enterprise Linux 5.4 (32-bit)", PV);
+        s_ovmMap.put("Oracle Enterprise Linux 5.4 (64-bit)", PV);
+        s_ovmMap.put("Oracle Enterprise Linux 5.5 (32-bit)", PV);
+        s_ovmMap.put("Oracle Enterprise Linux 5.5 (64-bit)", PV);
+        s_ovmMap.put("Other Linux (32-bit)", PV);
+        s_ovmMap.put("Other Linux (64-bit)", PV);
+        s_ovmMap.put("Other PV (32-bit)", PV);
+        s_ovmMap.put("Other PV (64-bit)", PV);
+        s_ovmMap.put("Debian GNU/Linux 7(32-bit)", PV);
+        s_ovmMap.put("Debian GNU/Linux 7(64-bit)", PV);
+        s_ovmMap.put("Linux HVM (32-bit)", HVM);
+        s_ovmMap.put("Linux HVM (64-bit)", HVM);
+        s_ovmMap.put("Dos", HVM);
+        s_ovmMap.put("Windows 7 (32-bit)", HVM);
+        s_ovmMap.put("Windows 7 (64-bit)", HVM);
+        s_ovmMap.put("Windows 8 (64-bit)", HVM);
+        s_ovmMap.put("Windows Server 2003 (32-bit)", HVM);
+        s_ovmMap.put("Windows Server 2003 (64-bit)", HVM);
+        s_ovmMap.put("Windows Server 2008 (32-bit)", HVM);
+        s_ovmMap.put("Windows Server 2008 (64-bit)", HVM);
+        s_ovmMap.put("Windows Server 2008 R2 (64-bit)", HVM);
+        s_ovmMap.put("Windows Server 2012 (64-bit)", HVM);
+        s_ovmMap.put("Windows 2000 SP4 (32-bit)", HVM);
+        s_ovmMap.put("Windows Vista (32-bit)", HVM);
+        s_ovmMap.put("Windows XP SP2 (32-bit)", HVM);
+        s_ovmMap.put("Windows XP SP3 (32-bit)", HVM);
+        s_ovmMap.put("Sun Solaris 10(32-bit)", HVM);
+        s_ovmMap.put("Sun Solaris 10(64-bit)", HVM);
+        s_ovmMap.put("Sun Solaris 9(Experimental)", HVM);
+        s_ovmMap.put("Sun Solaris 8(Experimental)", HVM);
+        s_ovmMap.put("Sun Solaris 11 (32-bit)", HVM);
+        s_ovmMap.put("Sun Solaris 11 (64-bit)", HVM);
+        s_ovmMap.put("Sun Solaris PV (32-bit)", PV);
+        s_ovmMap.put("Sun Solaris PV (64-bit)", PV);
+        s_ovmMap.put("Sun Solaris Sparc (32-bit)", DOMSOL);
+        s_ovmMap.put("Sun Solaris Sparc (64-bit)", DOMSOL);
+    }
+
+    public static String getOvm3GuestType(String stdType) {
+        return s_ovmMap.get(stdType);
+    }
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3ResourceBase.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3ResourceBase.java
new file mode 100755
index 0000000..6b563d5
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3ResourceBase.java
@@ -0,0 +1,3211 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF 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 com.cloud.hypervisor.ovm3.hypervisor;
+
+import java.io.File;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.net.URI;
+import java.util.ArrayList;
+// import java.net.URISyntaxException;
+/*
+ * import java.util.ArrayList;
+ */
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.net.URL;
+
+import org.apache.commons.lang.BooleanUtils;
+
+import com.google.gson.Gson;
+
+import org.apache.commons.codec.binary.Base64;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+
+
+
+
+// import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
+// import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AttachIsoCommand;
+import com.cloud.agent.api.AttachVolumeAnswer;
+import com.cloud.agent.api.AttachVolumeCommand;
+import com.cloud.agent.api.CheckNetworkAnswer;
+import com.cloud.agent.api.CheckNetworkCommand;
+import com.cloud.agent.api.CheckVirtualMachineAnswer;
+import com.cloud.agent.api.CheckVirtualMachineCommand;
+// import com.cloud.agent.api.CleanupNetworkRulesCmd;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
+import com.cloud.agent.api.CreateStoragePoolCommand;
+import com.cloud.agent.api.DeleteStoragePoolCommand;
+import com.cloud.agent.api.FenceAnswer;
+import com.cloud.agent.api.FenceCommand;
+import com.cloud.agent.api.GetHostStatsAnswer;
+import com.cloud.agent.api.GetHostStatsCommand;
+import com.cloud.agent.api.GetStorageStatsAnswer;
+import com.cloud.agent.api.GetStorageStatsCommand;
+import com.cloud.agent.api.GetVmStatsAnswer;
+import com.cloud.agent.api.GetVmStatsCommand;
+import com.cloud.agent.api.GetVncPortAnswer;
+import com.cloud.agent.api.GetVncPortCommand;
+import com.cloud.agent.api.GetDomRVersionAnswer;
+import com.cloud.agent.api.GetDomRVersionCmd;
+import com.cloud.agent.api.NetworkRulesSystemVmCommand;
+import com.cloud.agent.api.routing.DhcpEntryCommand;
+import com.cloud.agent.api.routing.SavePasswordCommand;
+import com.cloud.agent.api.routing.VmDataCommand;
+// import com.cloud.agent.api.routing.DhcpEntryAnswer;
+import com.cloud.agent.api.HostStatsEntry;
+import com.cloud.agent.api.HostVmStateReportEntry;
+import com.cloud.agent.api.MaintainAnswer;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.MigrateAnswer;
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.agent.api.ModifyStoragePoolAnswer;
+import com.cloud.agent.api.ModifyStoragePoolCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingRoutingCommand;
+import com.cloud.agent.api.PingTestCommand;
+import com.cloud.agent.api.PrepareForMigrationAnswer;
+import com.cloud.agent.api.PrepareForMigrationCommand;
+// import com.cloud.agent.api.PrepareOCFS2NodesCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.RebootAnswer;
+import com.cloud.agent.api.RebootCommand;
+/*
+ * import com.cloud.agent.api.SecurityGroupRuleAnswer;
+ * import com.cloud.agent.api.SecurityGroupRulesCmd;
+ */
+import com.cloud.agent.api.StartAnswer;
+import com.cloud.agent.api.StartCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.StartupStorageCommand;
+import com.cloud.agent.api.StopAnswer;
+import com.cloud.agent.api.StopCommand;
+import com.cloud.agent.api.VmStatsEntry;
+import com.cloud.agent.api.storage.CopyVolumeAnswer;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.storage.CreateAnswer;
+import com.cloud.agent.api.storage.CreateCommand;
+import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
+import com.cloud.agent.api.storage.DestroyCommand;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.StorageFilerTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.api.to.VolumeTO;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.host.Host.Type;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetworkSetupInfo;
+// import com.cloud.network.NetworkModel;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.hypervisor.HypervisorResource;
+// import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.Volume;
+import com.cloud.storage.template.TemplateProp;
+import com.cloud.template.VirtualMachineTemplate.BootloaderType;
+// import com.cloud.utils.Pair;
+// import com.cloud.utils.Ternary;
+import com.cloud.utils.exception.CloudRuntimeException;
+// import com.cloud.utils.script.Script;
+import com.cloud.utils.ssh.SshHelper;
+import com.trilead.ssh2.SCPClient;
+import com.cloud.utils.ssh.SSHCmdHelper;
+import com.cloud.agent.api.check.CheckSshAnswer;
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineName;
+import com.cloud.vm.VirtualMachine.PowerState;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.hypervisor.ovm3.object.Common;
+import com.cloud.hypervisor.ovm3.object.Connection;
+import com.cloud.hypervisor.ovm3.object.Linux;
+import com.cloud.hypervisor.ovm3.object.Network;
+import com.cloud.hypervisor.ovm3.object.OvmObject;
+import com.cloud.hypervisor.ovm3.object.Pool;
+import com.cloud.hypervisor.ovm3.object.PoolOCFS2;
+import com.cloud.hypervisor.ovm3.object.Repository;
+import com.cloud.hypervisor.ovm3.object.StoragePlugin;
+import com.cloud.hypervisor.ovm3.object.Xen;
+import com.cloud.hypervisor.ovm3.object.CloudStackPlugin;
+
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.DeleteCommand;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CreateObjectAnswer;
+import org.apache.cloudstack.storage.command.CreateObjectCommand;
+
+import com.cloud.storage.resource.StorageProcessor;
+
+import org.apache.cloudstack.storage.command.ForgetObjectCmd;
+import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
+import org.apache.cloudstack.storage.command.DettachCommand;
+// import org.apache.cloudstack.storage.command.DettachAnswer;
+import org.apache.cloudstack.storage.command.AttachCommand;
+
+
+
+// import org.apache.cloudstack.storage.command.AttachAnswer;
+import com.cloud.storage.Storage.ImageFormat;
+/* do we need this ? */
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.resource.ResourceManager;
+import com.cloud.utils.script.Script;
+
+import org.apache.commons.io.FileUtils;
+
+import javax.inject.Inject;
+
+/* TODO: Seperate these out */
+public class Ovm3ResourceBase implements ServerResource, HypervisorResource,
+        StorageProcessor {
+    private static final Logger s_logger = Logger
+            .getLogger(Ovm3ResourceBase.class);
+    private Connection c;
+    private Connection m;
+    private String _name;
+    private String _ip;
+    Long _zoneId;
+    Long _podId;
+    Long _poolId;
+    Long _clusterId;
+    String _host;
+    String _guid;
+    String _username = "root";
+    String _password;
+    String _agentUserName = "oracle";
+    String _agentPassword;
+    Integer _agentPort = 8899;
+    Boolean _agentSsl = false;
+    String _ovmSshKey = "id_rsa.cloud";
+    String _masterUuid = "d1a749d4295041fb99854f52ea4dea97";
+    Boolean _isMaster = false;
+    Boolean _hasMaster = false;
+    Boolean _ovm3pool = false;
+    Boolean _ovm3cluster = false;
+    String _ovm3vip = "";
+    protected boolean _checkHvm = false;
+    /* _clusterDetailsDao.findDetail(clusterId, getVagKey(storagePoolId)); */
+    String _privateNetworkName;
+    String _publicNetworkName;
+    String _guestNetworkName;
+    String _storageNetworkName;
+    String _controlNetworkName = "control0";
+    String _controlNetworkIp = "169.254.0.1";
+    // String _controlNetworkMask = "255.255.0.0";
+    boolean _canBridgeFirewall = false;
+    String _ovmRepo = "/OVS/Repositories";
+    String _ovmSec = "/nfsmnt";
+    OvmObject _ovmObject = new OvmObject();
+    static boolean s_isHeartBeat = false;
+    protected final int DefaultDomRSshPort = 3922;
+    String DefaultDomRPath = "/opt/cloud/bin/";
+    private Map<String, Network.Interface> _interfaces = null;
+    /* switch to concurrenthasmaps all over the place ? */
+    private final ConcurrentHashMap<String,
+        Map<String, String>> _vmStats =
+            new ConcurrentHashMap<String,
+                Map<String, String>>();
+
+    // TODO vmsync {
+    /* This is replaced by the vmList in getall VMs, and operate on that */
+    // protected HashMap<String, State> _vms = new HashMap<String, State>(250);
+    protected Map<String, Xen.Vm> _vms = new HashMap<String, Xen.Vm>();
+    protected Map<String, State> _vmstates = new HashMap<String, State>();
+
+    static HashMap<String, State> s_stateMaps;
+    static {
+        s_stateMaps = new HashMap<String, State>();
+        s_stateMaps.put("Stopping", State.Stopping);
+        s_stateMaps.put("Running", State.Running);
+        s_stateMaps.put("Stopped", State.Stopped);
+        s_stateMaps.put("Error", State.Error);
+        s_stateMaps.put("Suspended", State.Running);
+        s_stateMaps.put("Paused", State.Running);
+        s_stateMaps.put("Migrating", State.Migrating);
+    }
+
+    static HashMap<String, PowerState> s_powerStateMaps;
+    static {
+        s_powerStateMaps = new HashMap<String, PowerState>();
+        s_powerStateMaps.put("Stopping", PowerState.PowerOn);
+        s_powerStateMaps.put("Running", PowerState.PowerOn);
+        s_powerStateMaps.put("Stopped", PowerState.PowerOff);
+        s_powerStateMaps.put("Error", PowerState.PowerUnknown);
+        s_powerStateMaps.put("Suspended", PowerState.PowerOn);
+        s_powerStateMaps.put("Paused", PowerState.PowerOn);
+        /* unknown ? */
+        s_powerStateMaps.put("Migrating", PowerState.PowerOn);
+    }
+
+    @Inject
+    PrimaryDataStoreDao _storagePoolDao;
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    ResourceManager _resourceMgr;
+
+    GlobalLock _exclusiveOpLock = GlobalLock.getInternLock("ovm3.exclusive.op");
+
+    /* return params we want to add, damnit */
+    @Override
+    public boolean configure(String name, Map<String, Object> params)
+            throws ConfigurationException {
+        _name = name;
+        s_logger.debug("configure " + name + " with params: " + params);
+        /* do we have enough ? */
+        try {
+            _zoneId = Long.parseLong((String) params.get("zone"));
+            _podId = Long.parseLong((String) params.get("pod"));
+            _clusterId = Long.parseLong((String) params.get("cluster"));
+            _ovm3vip = String.valueOf(params.get("ovm3vip"));
+            _ovm3pool = BooleanUtils.toBoolean((String) params.get("ovm3pool"));
+            _ovm3cluster = BooleanUtils.toBoolean((String) params
+                    .get("ovm3cluster"));
+            _host = (String) params.get("host");
+            _ip = (String) params.get("ip");
+            _username = (String) params.get("username");
+            _password = (String) params.get("password");
+            _guid = (String) params.get("guid");
+            _agentUserName = (String) params.get("agentusername");
+            _agentPassword = (String) params.get("agentpassword");
+            _privateNetworkName = (String) params.get("private.network.device");
+            _publicNetworkName = (String) params.get("public.network.device");
+            _guestNetworkName = (String) params.get("guest.network.device");
+            _storageNetworkName = (String) params.get("storage.network.device");
+
+            if (params.get("agentport") != null)
+                _agentPort = Integer.parseInt((String) params.get("agentport"));
+
+            // Add later
+            // _agentSsl = (Boolean)params.get("agentssl");
+        } catch (Exception e) {
+            s_logger.debug("Configure " + _host + " failed", e);
+            throw new ConfigurationException("Configure " + _host + " failed, "
+                    + e.toString());
+        }
+
+        if (_podId == null) {
+            String msg = "Unable to get the pod";
+            s_logger.debug(msg);
+            throw new ConfigurationException(msg);
+        }
+
+        if (_host == null) {
+            String msg = "Unable to get the host";
+            s_logger.debug(msg);
+            throw new ConfigurationException(msg);
+        }
+
+        if (_username == null) {
+            String msg = "Unable to get the username";
+            s_logger.debug(msg);
+            throw new ConfigurationException(msg);
+        }
+
+        if (_password == null) {
+            String msg = "Unable to get the password";
+            s_logger.debug(msg);
+            throw new ConfigurationException(msg);
+        }
+
+        if (_guid == null) {
+            String msg = "Unable to get the guid";
+            s_logger.debug(msg);
+            throw new ConfigurationException(msg);
+        }
+
+        if (_agentUserName == null) {
+            String msg = "Unable to get the agent username";
+            s_logger.debug(msg);
+            throw new ConfigurationException(msg);
+        }
+
+        if (_agentPassword == null) {
+            String msg = "Unable to get the agent password";
+            s_logger.debug(msg);
+            throw new ConfigurationException(msg);
+        }
+
+        if (_agentPort == null) {
+            String msg = "Unable to get the agent port";
+            s_logger.debug(msg);
+            throw new ConfigurationException(msg);
+        }
+
+        /* TODO: Needs to be relocated */
+        if (_ovm3vip.equals("")) {
+            s_logger.debug("No VIP, Setting ovm3pool and ovm3cluster to false");
+            this._ovm3pool = false;
+            this._ovm3cluster = false;
+            this._ovm3vip = "";
+        }
+        /* if we're a cluster we have to be a pool ? */
+        if (_ovm3cluster) {
+            this._ovm3pool = true;
+        }
+
+        /* check if we're master or not and if we can connect */
+        try {
+            try {
+                c = new Connection(_host, _agentPort, _agentUserName,
+                        _agentPassword);
+            } catch (XmlRpcException ex) {
+                String msg = "Unable to connect to " + _host;
+                s_logger.warn(msg + ": " + ex.getMessage());
+                throw new Exception(msg, ex);
+            }
+            this._isMaster = masterCheck();
+        } catch (Exception e) {
+            String msg = "Base checks failed for " + _host;
+            s_logger.debug(msg, e);
+            throw new ConfigurationException(msg);
+        }
+        /* setup ovm3 plugin */
+        try {
+            installOvsPlugin();
+            CloudStackPlugin cSp = new CloudStackPlugin(c);
+            cSp.ovsUploadSshKey(this._ovmSshKey,
+                    FileUtils.readFileToString(getSystemVMKeyFile()));
+        } catch (Exception e) {
+            String msg = "Failed to setup server: " + _host;
+            s_logger.error(msg + ": " + e.getMessage());
+            throw new ConfigurationException(msg + ", " + e);
+        }
+
+        try {
+            try {
+                /*
+                 * TODO: setup meta tags for the management interface (probably
+                 * required with multiple interfaces)?
+                 */
+                Network net = new Network(c);
+                _interfaces = net.getInterfaceList();
+                s_logger.debug("all interfaces: " + _interfaces);
+                if (_controlNetworkName != null
+                        && !_interfaces.containsKey(_controlNetworkName)) {
+                    /*
+                     * TODO: find a more elegant way to do this
+                     * for now we need the route del and ifconfig
+                     * as loopback bridges have arp disabled by default,
+                     * and zeroconf configures a route on the main bridge...
+                     */
+                    try {
+                        net.startOvsLocalConfig(_controlNetworkName);
+                    } catch (Exception e) {
+                        s_logger.debug("Unable to configure"
+                                + _controlNetworkName + ":" + e.getMessage());
+                    }
+                    /* ovs replies too "fast" so the bridge can be "busy" */
+                    while (!_interfaces.containsKey(_controlNetworkName)) {
+                        s_logger.debug("waiting for " + _controlNetworkName);
+                        _interfaces = net.getInterfaceList();
+                         Thread.sleep(1 * 1000);
+                    }
+                }
+                /* The bridge is remembered upon reboot, but not the IP */
+                net.ovsIpConfig(_controlNetworkName,
+                        "static",
+                        _controlNetworkIp,
+                        "255.255.0.0");
+                CloudStackPlugin cSp = new CloudStackPlugin(c);
+                cSp.ovsControlInterface(_controlNetworkName,
+                        _controlNetworkIp + "/16");
+
+                // Missing netM = new Missing(c);
+                /* build ovs_if_meta in Net based on the following */
+                if (_privateNetworkName != null
+                        && net.getBridgeByName(_privateNetworkName).getName() == null) {
+                    throw new ConfigurationException(
+                            "Cannot find private bridge "
+                                    + _privateNetworkName
+                                    + " on host "
+                                    + _host
+                                    + " - "
+                                    + net.getBridgeByName(_privateNetworkName)
+                                            .getName());
+                }
+                if (_publicNetworkName != null
+                        && net.getBridgeByName(_publicNetworkName).getName() == null) {
+                    throw new ConfigurationException(
+                            "Cannot find private bridge "
+                                    + _publicNetworkName
+                                    + " on host "
+                                    + _host
+                                    + " - "
+                                    + net.getBridgeByName(_publicNetworkName)
+                                            .getName());
+                }
+                if (_guestNetworkName != null
+                        && net.getBridgeByName(_guestNetworkName).getName() == null) {
+                    throw new ConfigurationException(
+                            "Cannot find private bridge "
+                                    + _guestNetworkName
+                                    + " on host "
+                                    + _host
+                                    + " - "
+                                    + net.getBridgeByName(_guestNetworkName)
+                                            .getName());
+                }
+                if (_storageNetworkName != null
+                        && net.getBridgeByName(_storageNetworkName).getName() == null) {
+                    throw new ConfigurationException(
+                            "Cannot find private bridge "
+                                    + _storageNetworkName
+                                    + " on host "
+                                    + _host
+                                    + " - "
+                                    + net.getBridgeByName(_storageNetworkName)
+                                            .getName());
+                }
+            } catch (Exception e) {
+                s_logger.debug("Get bridges failed on host " + _host + ", ", e);
+                throw new ConfigurationException("Cannot get bridges on host "
+                        + _host + ", " + e);
+            }
+            try {
+                prepareForPool();
+            } catch (Exception e) {
+                throw new ConfigurationException("Failed to prepare for pool "
+                        + _host + ", " + e);
+            }
+
+            /*
+             * set to false so each time ModifyStoragePoolCommand will re-setup
+             * heartbeat
+             */
+            /*
+             * only required if we do cluster and then o2cb will take care of it
+             * s_isHeartBeat = false;
+             */
+
+            /*
+             * - uses iptables in XenServer, but not agent accessible for agent
+             * *should make module*
+             */
+            try {
+                _canBridgeFirewall = canBridgeFirewall();
+            } catch (XmlRpcException e) {
+                s_logger.error("Failed to detect whether the host supports security groups.",
+                        e);
+                _canBridgeFirewall = false;
+            }
+
+            s_logger.debug(_canBridgeFirewall ? "OVM3 host supports security groups."
+                    : "OVM3 host doesn't support security groups.");
+            /*
+             * } catch (XmlRpcException e) {
+             * String msg = "XML RPC Exception, unable to setup host: " + _host
+             * + " " + e;
+             * s_logger.debug(msg);
+             * throw new ConfigurationException(msg);
+             */
+        } catch (Exception e) {
+            String msg = "Generic Exception, failed to setup host: " + _host;
+            s_logger.debug(msg + ": " + e.getMessage());
+            throw new ConfigurationException(msg + ":" + e.getMessage());
+        } /*
+           * catch (IOException e) { s_logger.debug("Failed to setup host " +
+           * _host, e); throw new
+           * ConfigurationException("Unable to setup host"); }
+           */
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public String getName() {
+        return _name;
+    }
+
+    @Override
+    public Type getType() {
+        return Type.Routing;
+    }
+
+    protected void fillHostInfo(StartupRoutingCommand cmd) {
+        try {
+            /* get data we need from parts */
+            Linux host = new Linux(c);
+            if (!host.getOvmVersion().startsWith("3.2.")) {
+                throw new CloudRuntimeException(
+                        "OVM 3.2.X is only supported, not "
+                                + host.getOvmVersion());
+            }
+            Xen vms = new Xen(c);
+            vms.listVms();
+            Xen.Vm dom0 = vms.getRunningVmConfig("Domain-0");
+
+            cmd.setName(host.getHostName());
+            cmd.setSpeed(host.getCpuKhz());
+            cmd.setCpus(host.getTotalThreads());
+            cmd.setCpuSockets(host.getCpuSockets());
+            cmd.setMemory(host.getMemory().longValue());
+            /*
+             * TODO: Convert Bigint to long in Linux
+             */
+            BigInteger totalmem = BigInteger.valueOf(host.getMemory()
+                    .longValue());
+            BigInteger freemem = BigInteger.valueOf(host.getFreeMemory()
+                    .longValue());
+            cmd.setDom0MinMemory(totalmem.subtract(freemem).longValue());
+            // setPoolSync and setCaps.
+            cmd.setGuid(_guid);
+            cmd.setDataCenter(_zoneId.toString());
+            cmd.setPod(_podId.toString());
+            // also set uuid for ownership, or else pooling/clustering will not
+            // work
+            // cmd.setOwner(host.getManagerUuid());
+            cmd.setCluster(_clusterId.toString());
+            cmd.setHypervisorVersion(host.getOvmVersion());
+            cmd.setVersion(host.getAgentVersion());
+            cmd.setHypervisorType(HypervisorType.Ovm3);
+            /* is this true ? */
+            cmd.setCaps(host.getCapabilities());
+            // TODO: Control ip, for now cheat ?
+            cmd.setPrivateIpAddress(_ip);
+            cmd.setStorageIpAddress(_ip);
+            cmd.setHostVmStateReport(HostVmStateReport());
+
+            Network net = new Network(c);
+            /* more detail -- fix -- and shouldn't matter */
+            /* should this be the bond before the bridge ?*/
+            String defaultBridge = net.getBridgeByIp(_ip).getName();
+            if (defaultBridge == null) {
+                throw new CloudRuntimeException(
+                        "Unable to obtain valid bridge with " + _ip);
+            }
+
+            /* TODO: cleanup network section, this is not right */
+            if (_publicNetworkName == null) {
+                _publicNetworkName = defaultBridge;
+            }
+            if (_privateNetworkName == null) {
+                _privateNetworkName = _publicNetworkName;
+            }
+            if (_guestNetworkName == null) {
+                _guestNetworkName = _publicNetworkName;
+            }
+            /*
+             * if (_storageNetworkName == null) {
+             * _storageNetworkName = _privateNetworkName;
+             * }
+             */
+            Map<String, String> d = cmd.getHostDetails();
+            d.put("public.network.device", _publicNetworkName);
+            if (_privateNetworkName != null)
+                d.put("private.network.device", _privateNetworkName);
+            if (_guestNetworkName != null)
+                d.put("guest.network.device", _guestNetworkName);
+            if (_storageNetworkName != null)
+                d.put("storage.network.device", _storageNetworkName);
+            d.put("ismaster", this._isMaster.toString());
+            cmd.setHostDetails(d);
+            s_logger.debug("Add an Ovm3 host " + _name + ":"
+                    + cmd.getHostDetails());
+        } catch (XmlRpcException e) {
+            s_logger.debug("XML RPC Exception" + e.getMessage(), e);
+            throw new CloudRuntimeException("XML RPC Exception"
+                    + e.getMessage(), e);
+        } catch (Exception e) {
+            s_logger.debug("Exception " + e.getMessage(), e);
+            throw new CloudRuntimeException("Exception" + e.getMessage(), e);
+        }
+    }
+
+    /*
+     * plugs the ovm module into the ovs-agent
+     */
+    protected void installOvsPlugin() throws IOException {
+        /* ssh-copy-id anyone ? */
+        try {
+            com.trilead.ssh2.Connection sshConnection =
+                    SSHCmdHelper.acquireAuthorizedConnection(_ip,
+                            _username,
+                            _password);
+            if (sshConnection == null) {
+                throw new ConfigurationException(String.format("Unable to "
+                        + "connect to server(IP=%1$s, username=%2$s, "
+                        + "password=%3$s", _ip, _username, _password));
+            }
+            SCPClient scp = new SCPClient(sshConnection);
+            String userDataScript = "scripts/vm/hypervisor/ovm3/cloudstack.py";
+            String userDataScriptPath = Script.findScript("", userDataScript);
+            if (userDataScriptPath == null) {
+                throw new ConfigurationException("Can not find "
+                        + userDataScript);
+            }
+            scp.put(userDataScriptPath, "", "0755");
+            String prepareCmd = String.format("./cloudstack.py "
+                    + "--ssl=" + this._agentSsl + " "
+                    + "--port=" + this._agentPort);
+            if (!SSHCmdHelper.sshExecuteCmd(sshConnection, prepareCmd)) {
+                throw new ConfigurationException("Module insertion at "
+                        + _host + " failed");
+            }
+        } catch (Exception es) {
+            s_logger.error("Unexpected exception ", es);
+            String msg = "Unable to install module in agent";
+            s_logger.error(msg);
+            throw new CloudRuntimeException(msg);
+        }
+    }
+
+    /* startup */
+    @Override
+    public StartupCommand[] initialize() {
+        s_logger.debug("Ovm3 resource intializing");
+        try {
+            StartupRoutingCommand srCmd = new StartupRoutingCommand();
+
+            StartupStorageCommand ssCmd = new StartupStorageCommand();
+            fillHostInfo(srCmd);
+            String pool = srCmd.getPool();
+            s_logger.debug("Ovm3 pool " + ssCmd + " " + srCmd);
+
+            Map<String, State> changes = null;
+            synchronized (_vmstates) {
+                _vmstates.clear();
+                changes = sync();
+            }
+            srCmd.setStateChanges(changes);
+            /* should not force HVM */
+            // cmd.setCaps("hvm");
+            return new StartupCommand[] { srCmd, ssCmd };
+        } catch (Exception e) {
+            s_logger.debug("Ovm3 resource initializes failed", e);
+            return null;
+        }
+    }
+
+    /* See if the agent is still up on the host */
+    @Override
+    public PingCommand getCurrentStatus(long id) {
+        try {
+            /* feels useless somehow */
+            Common test = new Common(c);
+            String ping = "put";
+            String pong = test.echo(ping);
+            if (pong.contains(ping)) {
+                HashMap<String, State> newStates = sync();
+                return new PingRoutingCommand(getType(), id, newStates,
+                        HostVmStateReport());
+            }
+        } catch (XmlRpcException e) {
+            s_logger.debug("Check agent status failed", e);
+            return null;
+        } catch (Exception e) {
+            s_logger.debug("Check agent status failed", e);
+            return null;
+        }
+        return null;
+    }
+
+    /* Check if the host is in ready state for CS */
+    protected ReadyAnswer execute(ReadyCommand cmd) {
+        try {
+            Linux host = new Linux(c);
+            Pool pool = new Pool(c);
+
+            /* only interesting when doing cluster */
+            if (!host.getIsMaster() && _ovm3cluster) {
+                if (pool.getPoolMasterVip().equalsIgnoreCase(_ip)) {
+                    /* check pool state here */
+                    return new ReadyAnswer(cmd);
+                } else {
+                    s_logger.debug("Master IP changes to "
+                            + pool.getPoolMasterVip() + ", it should be " + _ip);
+                    return new ReadyAnswer(cmd, "I am not the master server");
+                }
+            } else if (host.getIsMaster()) {
+                s_logger.debug("Master, not clustered " + _host);
+                return new ReadyAnswer(cmd);
+            } else {
+                s_logger.debug("No master, not clustered " + _host);
+                return new ReadyAnswer(cmd);
+            }
+        } catch (XmlRpcException e) {
+            s_logger.debug("XML RPC Exception" + e.getMessage(), e);
+            throw new CloudRuntimeException("XML RPC Exception"
+                    + e.getMessage(), e);
+        } catch (Exception e) {
+            s_logger.debug("Exception" + e.getMessage(), e);
+            throw new CloudRuntimeException("Exception" + e.getMessage(), e);
+        }
+
+    }
+
+    /*
+     * Primary storage, will throw an error if ownership does not match!
+     * Pooling is a part of this, for now
+     */
+    protected boolean createRepo(StorageFilerTO cmd) throws XmlRpcException {
+        String basePath = this._ovmRepo;
+        Repository repo = new Repository(c);
+        String primUuid = repo.deDash(cmd.getUuid());
+        String ovsRepo = basePath + "/" + primUuid;
+        /* should add port ? */
+        String mountPoint = String.format("%1$s:%2$s",
+                cmd.getHost(),
+                cmd.getPath());
+
+        String msg;
+        if (cmd.getType() == StoragePoolType.NetworkFilesystem) {
+            /* base repo first */
+
+            repo.mountRepoFs(mountPoint, ovsRepo);
+            s_logger.debug("NFS repository " + mountPoint + " on " + ovsRepo
+                    + " requested for " + _host);
+            try {
+                repo.addRepo(mountPoint, ovsRepo);
+            } catch (Exception e) {
+                s_logger.debug("NFS repository " + mountPoint + " on "
+                        + ovsRepo + " not found creating!");
+                try {
+                    repo.createRepo(mountPoint,
+                            ovsRepo,
+                            primUuid,
+                            "OVS Reposutory");
+                } catch (Exception es) {
+                    msg = "NFS repository " + mountPoint + " on "
+                            + ovsRepo + " create failed!";
+                    s_logger.debug(msg);
+                    throw new CloudRuntimeException(
+                            msg + " " + es.getMessage(), es);
+                }
+            }
+            /* add base pooling first */
+            if (this._ovm3pool) {
+                try {
+                    msg = "Configuring host for pool";
+                    s_logger.debug(msg);
+                    setupPool(cmd);
+                    msg = "Configured host for pool";
+                    /* add clustering after pooling */
+                    if (this._ovm3cluster) {
+                        msg = "Configuring host for cluster";
+                        s_logger.debug(msg);
+                        /* setup cluster */
+                        /*
+                         * From cluster.java
+                         * configure_server_for_cluster(cluster conf, fs, mount,
+                         * fsuuid, poolfsbaseuuid)
+                         */
+                        /* create_cluster(poolfsuuid,) */
+                        msg = "Configuring host for cluster";
+                    }
+                } catch (Exception e) {
+                    msg = "Unable to setup pool on " + ovsRepo;
+                    s_logger.debug(msg);
+                    throw new CloudRuntimeException(msg + " " + e.getMessage(), e);
+                }
+            } else {
+                msg = "no way dude I can't stand for this";
+                s_logger.debug(msg);
+            }
+            /*
+             * this is to create the .generic_fs_stamp else we're not allowed
+             * to create any data\disks on this thing
+             */
+            try {
+                URI uri = new URI(cmd.getType() + "://" + cmd.getHost() + ":"
+                        + +cmd.getPort() + cmd.getPath() + "/VirtualMachines");
+                this.setupNfsStorage(uri, cmd.getUuid());
+            } catch (Exception e) {
+                msg = "NFS mount " + mountPoint + " on " + _ovmSec + "/"
+                        + cmd.getUuid() + " create failed!";
+                s_logger.debug(msg);
+                throw new CloudRuntimeException(msg + " " + e.getMessage(), e);
+            }
+        } else {
+            msg = "NFS repository " + mountPoint + " on " + ovsRepo
+                    + " create failed, was type " + cmd.getType();
+            s_logger.debug(msg);
+            return false;
+        }
+
+        try {
+            /* systemvm iso is imported here */
+            prepareSecondaryStorageStore(ovsRepo);
+        } catch (Exception e) {
+            msg = "systemvm.iso copy failed to " + ovsRepo;
+            s_logger.debug(msg);
+            return false;
+        }
+        return true;
+    }
+
+    /*  */
+    public void prepareSecondaryStorageStore(String storageUrl) {
+        String mountPoint = storageUrl;
+
+        GlobalLock lock = GlobalLock.getInternLock("prepare.systemvm");
+        try {
+            /* double check */
+            if (this._hasMaster && this._ovm3pool) {
+                s_logger.debug("Skip systemvm iso copy, leave it to the master");
+                return;
+            }
+            if (lock.lock(3600)) {
+                try {
+                    File srcIso = getSystemVMPatchIsoFile();
+                    String destPath = mountPoint + "/ISOs/";
+                    String repoPath[] = mountPoint.split(File.separator);
+                    String destIso = destPath + "/"
+                            + getSystemVMIsoFileNameOnDatastore();
+                    String result = "";
+                    try {
+                        StoragePlugin sp = new StoragePlugin(c);
+                        // sp.storagePluginGetFileInfo(repoPath[repoPath.length],
+                        // destIso);
+                        if (sp.getFileSize() > 0) {
+                            s_logger.info(" System VM patch ISO file already exists: "
+                                + srcIso.getAbsolutePath().toString()
+                                + ", destination: " + destIso);
+                        }
+                    } catch (Exception e) {
+                        /*
+                         * Cloudstack already does this at boot time:
+                         * s_logger.info(
+                         * "Inject SSH key pairs before copying systemvm.iso into secondary storage"
+                         * );
+                         */
+                        s_logger.info("Copy System VM patch ISO file to secondary storage. source ISO: "
+                                + srcIso.getAbsolutePath()
+                                + ", destination: "
+                                + destIso);
+                        try {
+                            /*
+                             * should actualy come from importIso in
+                             * Storageplugin, so craft a url that can be used
+                             * for that.
+                             */
+                            SshHelper.scpTo(this._host,
+                                    22,
+                                    this._username,
+                                    null,
+                                    this._password,
+                                    destPath,
+                                    srcIso.getAbsolutePath().toString(),
+                                    "0644");
+                        } catch (Exception es) {
+                            s_logger.error("Unexpected exception ", es);
+                            String msg = "Unable to copy systemvm ISO on secondary storage. src location: "
+                                    + srcIso.toString()
+                                    + ", dest location: "
+                                    + destIso;
+                            s_logger.error(msg);
+                            throw new CloudRuntimeException(msg);
+                        }
+                    }
+                } finally {
+                    lock.unlock();
+                }
+            }
+        } finally {
+            lock.releaseRef();
+        }
+    }
+
+    /* stolen from vmware impl */
+    public String getSystemVMIsoFileNameOnDatastore() {
+        String version = this.getClass().getPackage()
+                .getImplementationVersion();
+        String fileName = "systemvm-" + version + ".iso";
+        return fileName.replace(':', '-');
+    }
+
+    /* stolen from vmware impl */
+    private File getSystemVMPatchIsoFile() {
+        // locate systemvm.iso
+        String svmName = getSystemVMIsoFileNameOnDatastore();
+        URL url = this.getClass().getClassLoader()
+                .getResource("vms/" + svmName);
+        s_logger.debug(url);
+        File isoFile = null;
+        if (url != null) {
+            isoFile = new File(url.getPath());
+        }
+        if (isoFile == null || !isoFile.exists()) {
+            isoFile = new File("/usr/share/cloudstack-common/vms/" + svmName);
+        }
+
+        assert (isoFile != null);
+        if (!isoFile.exists()) {
+            s_logger.error("Unable to locate " + svmName + " in your setup at "
+                    + isoFile.toString());
+        }
+        return isoFile;
+    }
+
+    /* get the key */
+    public File getSystemVMKeyFile() {
+        URL url = this.getClass().getClassLoader()
+                .getResource("scripts/vm/systemvm/" + this._ovmSshKey);
+        File keyFile = null;
+        if (url != null) {
+            keyFile = new File(url.getPath());
+        }
+        if (keyFile == null || !keyFile.exists()) {
+            keyFile = new File(
+                    "/usr/share/cloudstack-common/scripts/vm/systemvm/"
+                            + _ovmSshKey);
+        }
+        assert (keyFile != null);
+        if (!keyFile.exists()) {
+            s_logger.error("Unable to locate " + _ovmSshKey
+                    + " in your setup at " + keyFile.toString());
+        }
+        return keyFile;
+    }
+
+    /*
+     * TODO: local OCFS2? or iSCSI OCFS2
+     */
+    protected Boolean createOCFS2Sr(StorageFilerTO pool) throws XmlRpcException {
+        /*
+         * Ovm3StoragePool.Details d = new Ovm3StoragePool.Details(); d.path =
+         * pool.getPath(); d.type = Ovm3StoragePool.OCFS2; d.uuid =
+         * pool.getUuid(); Ovm3StoragePool.create(_conn, d);
+         * s_logger.debug(String.format("Created SR (mount point:%1$s)",
+         * d.path));
+         */
+        s_logger.debug("OCFS2 Not implemented yet");
+        return false;
+    }
+
+    /* TODO: heartbeats are done by the oracle cluster when clustering */
+    private void setupHeartBeat(String poolUuid) {
+        try {
+            if (!s_isHeartBeat) {
+                // Ovm3Host.setupHeartBeat(_conn, poolUuid, _ip);
+                s_isHeartBeat = true;
+            }
+        } catch (Exception e) {
+            s_logger.debug("setup heart beat for " + _host + " failed", e);
+            s_isHeartBeat = false;
+        }
+    }
+
+    /* Setup a storage pool and also get the size */
+    protected Answer execute(ModifyStoragePoolCommand cmd) {
+        StorageFilerTO pool = cmd.getPool();
+        s_logger.debug("modifying pool " + pool);
+        try {
+            if (pool.getType() == StoragePoolType.NetworkFilesystem) {
+                /* this should actually not be here */
+                createRepo(pool);
+            } else if (pool.getType() == StoragePoolType.OCFS2) {
+                createOCFS2Sr(pool);
+            } else {
+                return new Answer(cmd, false, "The pool type: "
+                        + pool.getType().name() + " is not supported.");
+            }
+
+            if (this._ovm3cluster) {
+                // setupHeartBeat(pool.getUuid());
+            }
+            /* TODO: needs to be in network fs above */
+            StoragePlugin store = new StoragePlugin(c);
+            String propUuid = store.deDash(pool.getUuid());
+            String mntUuid = pool.getUuid();
+            String nfsHost = pool.getHost();
+            String nfsPath = pool.getPath();
+            store.setUuid(propUuid);
+            store.setSsUuid(propUuid);
+            store.setMntUuid(mntUuid);
+            store.setFsHost(nfsHost);
+            store.setFsSourcePath(nfsHost + ":" + nfsPath);
+            store.storagePluginGetFileSystemInfo();
+
+            Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
+            ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd,
+                    Long.parseLong(store.getTotalSize()), Long.parseLong(store
+                            .getFreeSize()), tInfo);
+            return answer;
+        } catch (Exception e) {
+            s_logger.debug("ModifyStoragePoolCommand failed", e);
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
+    /* TODO: add iSCSI */
+    protected Answer execute(CreateStoragePoolCommand cmd) {
+        StorageFilerTO pool = cmd.getPool();
+        s_logger.debug("creating pool " + pool);
+        try {
+            if (pool.getType() == StoragePoolType.NetworkFilesystem) {
+                createRepo(pool);
+            } else if (pool.getType() == StoragePoolType.IscsiLUN) {
+                return new Answer(cmd, false,
+                        "iSCSI is unsupported at the moment");
+                // getIscsiSR(conn, pool.getUuid(), pool.getHost(),
+                // pool.getPath(), null, null, false);
+            } else if (pool.getType() == StoragePoolType.OCFS2) {
+                return new Answer(cmd, false,
+                        "OCFS2 is unsupported at the moment");
+            } else if (pool.getType() == StoragePoolType.PreSetup) {
+                s_logger.warn("pre setup for pool " + pool);
+            } else {
+                return new Answer(cmd, false, "The pool type: "
+                        + pool.getType().name() + " is not supported.");
+            }
+        } catch (Exception e) {
+            String msg = "Catch Exception " + e.getClass().getName()
+                    + ", create StoragePool failed due to " + e.toString()
+                    + " on host:" + _host + " pool: " + pool.getHost()
+                    + pool.getPath();
+            s_logger.warn(msg, e);
+            return new Answer(cmd, false, msg);
+        }
+        return new Answer(cmd, true, "success");
+    }
+
+    /*
+     * Download some primary storage into the repository, we need the repoid to
+     * do that, but also have a uuid for the disk...
+     * TODO: check disk
+     * TODO: looks like we don't need this for now! (dead code)
+     */
+    protected PrimaryStorageDownloadAnswer execute(
+            final PrimaryStorageDownloadCommand cmd) {
+        try {
+            Repository repo = new Repository(c);
+            String tmplturl = cmd.getUrl();
+            String poolName = cmd.getPoolUuid();
+            String image = repo.deDash(repo.newUuid()) + ".raw";
+
+            /* url to download from, image name, and repo to copy it to */
+            repo.importVirtualDisk(tmplturl, image, poolName);
+
+            /* TODO: return uuid and size */
+            return new PrimaryStorageDownloadAnswer(image);
+        } catch (Exception e) {
+            s_logger.debug("PrimaryStorageDownloadCommand failed", e);
+            return new PrimaryStorageDownloadAnswer(e.getMessage());
+        }
+    }
+
+    /*
+     * TODO: Split out in Sec to prim and prim to prim and types ?
+     * Storage mount also goes in here for secstorage
+     */
+    protected final Answer execute(final CopyCommand cmd) {
+        DataTO srcData = cmd.getSrcTO();
+        DataStoreTO srcStore = srcData.getDataStore();
+        DataTO destData = cmd.getDestTO();
+        DataStoreTO destStore = destData.getDataStore();
+
+        try {
+            /* target and source are NFS and TEMPLATE */
+            if ((srcStore instanceof NfsTO)
+                    && (srcData.getObjectType() == DataObjectType.TEMPLATE)
+                    && (destData.getObjectType() == DataObjectType.TEMPLATE)) {
+                NfsTO srcImageStore = (NfsTO) srcStore;
+                TemplateObjectTO srcTemplate = (TemplateObjectTO) srcData;
+                String storeUrl = srcImageStore.getUrl();
+
+                URI uri = new URI(storeUrl);
+                String secPoolUuid = setupSecondaryStorage(storeUrl);
+                String primaryPoolUuid = destData.getDataStore().getUuid();
+                String destPath = this._ovmRepo + "/"
+                        + _ovmObject.deDash(primaryPoolUuid) + "/"
+                        + "Templates";
+                String sourcePath = this._ovmSec + "/" + secPoolUuid;
+
+                Linux host = new Linux(c);
+                String destUuid = srcTemplate.getUuid();
+                /*
+                 * TODO: add dynamic formats (tolower), it also supports VHD and
+                 * QCOW2, although Ovm3.2 does not have tapdisk2 anymore so we
+                 * can forget about that.
+                 */
+                /* TODO: add checksumming */
+                String srcFile = sourcePath + "/" + srcData.getPath();
+                if (srcData.getPath().endsWith("/")) {
+                    srcFile = sourcePath + "/" + srcData.getPath() + "/"
+                            + destUuid + ".raw";
+                }
+                String destFile = destPath + "/" + destUuid + ".raw";
+                s_logger.debug("CopyFrom: " + srcData.getObjectType() + ","
+                        + srcFile + " to " + destData.getObjectType() + ","
+                        + destFile);
+                host.copyFile(srcFile, destFile);
+
+                TemplateObjectTO newVol = new TemplateObjectTO();
+                newVol.setUuid(destUuid);
+                newVol.setPath(destPath);
+                newVol.setFormat(ImageFormat.RAW);
+                return new CopyCmdAnswer(newVol);
+                /* we assume the cache for templates is local */
+            } else if ((srcData.getObjectType() == DataObjectType.TEMPLATE)
+                    && (destData.getObjectType() == DataObjectType.VOLUME)) {
+                if (srcStore.getUrl().equals(destStore.getUrl())) {
+                    TemplateObjectTO srcTemplate = (TemplateObjectTO) srcData;
+                    VolumeObjectTO dstVolume = (VolumeObjectTO) destData;
+
+                    String srcFile = srcTemplate.getPath() + "/"
+                            + srcTemplate.getUuid() + ".raw";
+                    String vDisksPath = srcTemplate.getPath()
+                            .replace("Templates", "VirtualDisks");
+                    String destFile = vDisksPath + "/" + dstVolume.getUuid()
+                            + ".raw";
+
+                    Linux host = new Linux(c);
+                    s_logger.debug("CopyFrom: " + srcData.getObjectType() + ","
+                            + srcFile + " to " + destData.getObjectType() + ","
+                            + destFile);
+                    host.copyFile(srcFile, destFile);
+                    VolumeObjectTO newVol = new VolumeObjectTO();
+                    newVol.setUuid(dstVolume.getUuid());
+                    newVol.setPath(vDisksPath);
+                    newVol.setFormat(ImageFormat.RAW);
+                    return new CopyCmdAnswer(newVol);
+                } else {
+                    s_logger.debug("Primary to Primary doesn't match");
+                }
+            } else {
+                String msg = "Unable to do stuff for " + srcStore.getClass()
+                        + ":" + srcData.getObjectType() + " to "
+                        + destStore.getClass() + ":" + destData.getObjectType();
+                s_logger.debug(msg);
+            }
+        } catch (Exception e) {
+            String msg = "Catch Exception " + e.getClass().getName()
+                    + " for template due to " + e.toString();
+            s_logger.warn(msg, e);
+            return new CopyCmdAnswer(msg);
+        }
+        return new CopyCmdAnswer("not implemented yet");
+    }
+
+    protected Answer execute(DeleteCommand cmd) {
+        DataTO data = cmd.getData();
+        s_logger.debug("Deleting object: " + data.getObjectType());
+        if (data.getObjectType() == DataObjectType.VOLUME) {
+            return deleteVolume(cmd);
+        } else if (data.getObjectType() == DataObjectType.SNAPSHOT) {
+
+        } else if (data.getObjectType() == DataObjectType.TEMPLATE) {
+
+        } else {
+
+        }
+        String msg = "Delete not implemented yet for this object";
+        s_logger.debug(msg);
+        return new Answer(cmd);
+    }
+
+    /* TODO: Create a Disk from a template needs cleaning */
+    protected CreateAnswer execute(CreateCommand cmd) {
+        StorageFilerTO primaryStorage = cmd.getPool();
+        DiskProfile disk = cmd.getDiskCharacteristics();
+
+        /* disk should have a uuid */
+        String fileName = UUID.randomUUID().toString() + ".img";
+        String dst = primaryStorage.getPath() + "/" + primaryStorage.getUuid()
+                + "/" + fileName;
+
+        try {
+            StoragePlugin store = new StoragePlugin(c);
+            store.setUuid(primaryStorage.getUuid());
+            store.setName(primaryStorage.getUserInfo());
+            store.setSsUuid(primaryStorage.getUserInfo());
+            if (cmd.getTemplateUrl() != null) {
+                s_logger.debug("CreateCommand " + cmd.getTemplateUrl() + " "
+                        + dst);
+                Linux host = new Linux(c);
+                host.copyFile(cmd.getTemplateUrl(), dst);
+            } else {
+                /* this is a dup with the createVolume ? */
+                s_logger.debug("CreateCommand " + dst);
+                store.storagePluginCreate(primaryStorage.getUuid(),
+                        primaryStorage.getHost(),
+                        dst,
+                        disk.getSize());
+            }
+
+            store.storagePluginGetFileInfo(dst);
+            VolumeTO volume = new VolumeTO(cmd.getVolumeId(), disk.getType(),
+                    primaryStorage.getType(), primaryStorage.getUuid(),
+                    primaryStorage.getPath(), fileName, store.getFileName(),
+                    store.getFileSize(), null);
+            return new CreateAnswer(cmd, volume);
+        } catch (Exception e) {
+            s_logger.debug("CreateCommand failed", e);
+            return new CreateAnswer(cmd, e.getMessage());
+        }
+    }
+
+    /*
+     * Add rootdisk, datadisk and iso's
+     */
+    protected Boolean createVbds(Xen.Vm vm, VirtualMachineTO spec) {
+        for (DiskTO volume : spec.getDisks()) {
+            try {
+                if (volume.getType() == Volume.Type.ROOT) {
+                    VolumeObjectTO vol = (VolumeObjectTO) volume.getData();
+                    DataStoreTO ds = (DataStoreTO) vol.getDataStore();
+                    String dsk = vol.getPath() + "/" + vol.getUuid() + ".raw";
+                    vm.addRootDisk(dsk);
+                    /* TODO: needs to be replaced by rootdiskuuid? */
+                    vm.setPrimaryPoolUuid(ds.getUuid());
+                    s_logger.debug("Adding root disk: " + dsk);
+                } else if (volume.getType() == Volume.Type.ISO) {
+                    DataTO isoTO = volume.getData();
+                    if (isoTO.getPath() != null) {
+                        TemplateObjectTO template = (TemplateObjectTO) isoTO;
+                        DataStoreTO store = template.getDataStore();
+                        if (!(store instanceof NfsTO)) {
+                            throw new CloudRuntimeException(
+                                    "unsupported protocol");
+                        }
+                        NfsTO nfsStore = (NfsTO) store;
+                        String secPoolUuid = setupSecondaryStorage(nfsStore
+                                .getUrl());
+                        String isoPath = this._ovmSec + File.separator
+                                + secPoolUuid + File.separator
+                                + template.getPath();
+                        // + template.getUuid() + ".iso";
+                        vm.addIso(isoPath);
+                        /* check if secondary storage is mounted */
+                        s_logger.debug("Adding ISO: " + isoPath);
+                    }
+                } else if (volume.getType() == Volume.Type.DATADISK) {
+                    vm.addDataDisk(volume.getData().getPath());
+                    s_logger.debug("Adding data disk: "
+                            + volume.getData().getPath());
+                } else {
+                    throw new CloudRuntimeException("Unknown volume type: "
+                            + volume.getType());
+                }
+            } catch (Exception e) {
+                s_logger.debug("CreateVbds failed", e);
+                throw new CloudRuntimeException("Exception" + e.getMessage(), e);
+            }
+        }
+        return true;
+    }
+
+    /* TODO: iptables/etables logic in the supporting libs ? */
+    protected Boolean createVifs(Xen.Vm vm, VirtualMachineTO spec) {
+        NicTO[] nics = spec.getNics();
+        for (NicTO nic : nics) {
+            if (nic.isSecurityGroupEnabled()) {
+                if (spec.getType().equals(VirtualMachine.Type.User)) {
+                    /*
+                     * defaultNetworkRulesForUserVm(vmName, vmSpec.getId(),
+                     * nic);
+                     */
+                }
+            }
+            try {
+                if (getNetwork(nic) != null)
+                    vm.addVif(nic.getDeviceId(), getNetwork(nic), nic.getMac());
+            } catch (Exception e) {
+                String msg = "Unable to add vif " + nic.getType() + " for "
+                        + spec.getName() + " " + e.getMessage();
+                s_logger.debug(msg);
+                throw new CloudRuntimeException(msg);
+            }
+        }
+        vm.setupVifs();
+        return true;
+    }
+
+    /*
+     * TODO: ovs calls ? depending on the type of network
+     * TODO: get the bridge on a per VM base so we can throw it away?
+     */
+    private String createVlanBridge(String networkName, Integer vlanId)
+            throws XmlRpcException {
+        if (vlanId < 2 || vlanId > 4094) {
+            throw new CloudRuntimeException("Vlan " + vlanId
+                    + " needs to be between 1-4095");
+        }
+        Network net = new Network(c);
+        /* figure out if our bridged vlan exists, if not then create */
+        String brName = networkName + "." + vlanId.toString();
+        try {
+            String physInterface = net.getPhysicalByBridgeName(networkName);
+            String physVlanInt = physInterface + "." + vlanId;
+
+            if (net.getInterfaceByName(physVlanInt) == null)
+                net.startOvsVlanConfig(physInterface, vlanId);
+
+            if (net.getInterfaceByName(brName) == null)
+                net.startOvsBrConfig(brName, physVlanInt);
+        } catch (Exception e) {
+            throw new CloudRuntimeException("Unable to create vlan "
+                    + vlanId.toString() + " bridge for " + networkName
+                    + e.getMessage());
+        }
+        return brName;
+    }
+
+    // TODO: complete all network support
+    protected String getNetwork(NicTO nic) throws XmlRpcException {
+        String vlanId = null;
+        String bridgeName = null;
+        if (nic.getBroadcastType() == BroadcastDomainType.Vlan) {
+            vlanId = BroadcastDomainType.getValue(nic.getBroadcastUri());
+        }
+
+        if (nic.getType() == TrafficType.Guest) {
+            if (nic.getBroadcastType() == BroadcastDomainType.Vlan
+                    && !vlanId.equalsIgnoreCase("untagged")) {
+                bridgeName = createVlanBridge(_guestNetworkName,
+                        Integer.valueOf(vlanId));
+            } else {
+                bridgeName = _guestNetworkName;
+            }
+        } else if (nic.getType() == TrafficType.Control) {
+            bridgeName = _controlNetworkName;
+        } else if (nic.getType() == TrafficType.Public) {
+            bridgeName = _publicNetworkName;
+        } else if (nic.getType() == TrafficType.Management) {
+            bridgeName = _privateNetworkName;
+        } else if (nic.getType() == TrafficType.Storage) {
+            /* TODO: Add storage network */
+            bridgeName = _storageNetworkName;
+        } else {
+            throw new CloudRuntimeException("Unknown network traffic type:"
+                    + nic.getType());
+        }
+        return bridgeName;
+    }
+
+    /* This is not create for us, but really start */
+    protected boolean startVm(String repoId, String vmId)
+            throws XmlRpcException {
+        Xen host = new Xen(c);
+        try {
+            if (host.getRunningVmConfig(vmId) == null) {
+                s_logger.error("Create VM " + vmId + " first on " + c.getIp());
+                return false;
+            } else {
+                s_logger.info("VM " + vmId + " exists on " + c.getIp());
+            }
+            host.startVm(repoId, vmId);
+        } catch (Exception e) {
+            s_logger.error("Failed to start VM " + vmId + " on " + c.getIp()
+                    + " " + e.getMessage());
+            return false;
+        }
+        return true;
+    }
+
+    /*
+     * TODO: OVM already cleans stuff up, just not the extra bridges which we
+     * don't want right now, as we'd have to keep a state table of which vlans
+     * need to stay on the host!?
+     * A map with vlanid -> list-o-hosts
+     */
+    private void cleanupNetwork(List<String> vifs) throws XmlRpcException {
+        /* peel out vif info for vlan stuff */
+        /*
+         * for (String vif : vifs) { if (vif.bridge.startsWith("vlan")) {
+         * Network net = new Network(c); net.ovsVlanBridgeStop(br, net, vlan);
+         * // Ovm3Bridge.deleteVlanBridge(_conn, vif.bridge); } }
+         */
+    }
+
+    protected void cleanup(Xen.Vm vm) {
+        try {
+            cleanupNetwork(vm.getVmVifs());
+        } catch (XmlRpcException e) {
+            s_logger.debug("Clean up network for " + vm.getVmName() + " failed",
+                    e);
+        }
+        String vmName = vm.getVmName();
+        /* should become a single entity */
+        this._vmStats.remove(vmName);
+    }
+
+    /*
+     * TODO: The actual VM provisioning start to end, we can rip this from our
+     * simple stuff
+     */
+    @Override
+    public synchronized StartAnswer execute(StartCommand cmd) {
+        VirtualMachineTO vmSpec = cmd.getVirtualMachine();
+        String vmName = vmSpec.getName();
+        State state = State.Stopped;
+        Xen xen = new Xen(c);
+
+        try {
+            synchronized (this._vmstates) {
+                this._vmstates.put(vmName, State.Starting);
+            }
+            Xen.Vm vm = xen.getVmConfig();
+            /* max and min ? */
+            vm.setVmCpus(vmSpec.getCpus());
+            /* in mb not in bytes */
+            vm.setVmMemory(vmSpec.getMinRam() / 1024 / 1024);
+            vm.setVmUuid(UUID.nameUUIDFromBytes(vmSpec.getName().getBytes())
+                    .toString());
+            vm.setVmName(vmName);
+            String domType = Ovm3Helper.getOvm3GuestType(vmSpec.getOs());
+            if (domType == null || domType.equals("")) {
+                domType = "default";
+                s_logger.debug("VM Virt type missing setting to: " + domType);
+            } else {
+                s_logger.debug("VM Virt type set to " + domType + " for "
+                        + vmSpec.getOs());
+            }
+            vm.setVmDomainType(domType);
+            /* only for none user VMs? */
+            vm.setVmExtra(vmSpec.getBootArgs().replace(" ", "%"));
+
+            /* TODO: booting from CD... */
+            if (vmSpec.getBootloader() == BootloaderType.CD) {
+                // do something with this please...
+            }
+            /*
+             * officially CD boot is only supported on HVM, although there is a
+             * simple way around it..
+             */
+            /* TODO: pool uuid now comes from here should change! */
+            createVbds(vm, vmSpec);
+
+            if (vmSpec.getType() != VirtualMachine.Type.User) {
+                String svmPath = _ovmRepo + "/"
+                        + _ovmObject.deDash(vm.getPrimaryPoolUuid()) + "/ISOs";
+                String svmIso = svmPath + "/"
+                        + getSystemVMIsoFileNameOnDatastore();
+                vm.addIso(svmIso);
+            }
+            /* TODO: OVS should go here! */
+            createVifs(vm, vmSpec);
+
+            /* vm migration requires a 0.0.0.0 bind */
+            vm.setVncPassword(vmSpec.getVncPassword());
+            vm.setVncAddress("0.0.0.0");
+            vm.setVnc();
+
+            /* this should be getVmRootDiskPoolId ? */
+            xen.createVm(_ovmObject.deDash(vm.getPrimaryPoolUuid()),
+                    vm.getVmUuid());
+            xen.startVm(_ovmObject.deDash(vm.getPrimaryPoolUuid()),
+                    vm.getVmUuid());
+            state = State.Running;
+
+            if (vmSpec.getType() != VirtualMachine.Type.User) {
+                String controlIp = null;
+                for (NicTO nic : vmSpec.getNics()) {
+                    if (nic.getType() == TrafficType.Control) {
+                        controlIp = nic.getIp();
+                    }
+                }
+
+                try {
+                    CloudStackPlugin cSp = new CloudStackPlugin(c);
+                    for (int count = 0; count < 60; count++) {
+                        Boolean res = cSp.domrCheckSsh(controlIp);
+                        s_logger.debug("connected to " + controlIp
+                                + " on attempt " + count + " result: " + res);
+                        Thread.sleep(5000);
+                        if (res) {
+                            break;
+                        }
+                        /*
+                         * Older xend issues in, took me a while to figure this
+                         * out:
+                         * ../xen/xend/XendConstants.py
+                         * """Minimum time between domain restarts in seconds."""
+                         * MINIMUM_RESTART_TIME = 60
+                         * this does NOT work!!!--^^ as we respawn within 30
+                         * seconds easily.
+                         * return state stopped.
+                         */
+                        if (_vmstates.get(vmName) == null) {
+                            String msg = "VM " + vmName + " went missing on "
+                                    + _host + ", returning stopped";
+                                    s_logger.debug(msg);
+                            state = State.Stopped;
+                            return new StartAnswer(cmd, msg);
+                        }
+                    }
+                } catch (Exception x) {
+                    s_logger.debug("unable to connect to " + controlIp + " "
+                            + x.getMessage());
+                }
+            }
+            /*
+             * TODO: Can't remember if HA worked if we were only a pool ?
+             */
+            if (_ovm3pool && _ovm3cluster) {
+                xen.configureVmHa(_ovmObject.deDash(vm.getPrimaryPoolUuid()),
+                        vm.getVmUuid(),
+                        true);
+            }
+            /* should be starting no ? */
+            state = State.Running;
+            return new StartAnswer(cmd);
+        } catch (Exception e) {
+            s_logger.debug("Start vm " + vmName + " failed", e);
+            state = State.Stopped;
+            // cleanup(vmDetails);
+            return new StartAnswer(cmd, e.getMessage());
+        } finally {
+            synchronized (this._vmstates) {
+                // FIXME: where to come to Stopped???
+                this._vmstates.put(vmName, state);
+            }
+        }
+    }
+
+    /* split out domr stuff later */
+    private GetDomRVersionAnswer execute(GetDomRVersionCmd cmd) {
+        String args = this.DefaultDomRPath + "get_template_version.sh";
+        String ip = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        try {
+            CloudStackPlugin cSp = new CloudStackPlugin(c);
+            CloudStackPlugin.ReturnCode result;
+            result = cSp.domrExec(ip, args);
+            if (!result.getRc() || result.getStdOut().isEmpty()) {
+                return new GetDomRVersionAnswer(cmd, "getDomRVersionCmd failed");
+            }
+            String domResp = result.getStdOut();
+            String[] lines = domResp.split("&");
+            if (lines.length != 2) {
+                return new GetDomRVersionAnswer(cmd, domResp);
+            }
+            return new GetDomRVersionAnswer(cmd, domResp, lines[0], lines[1]);
+        } catch (Exception e) {
+            return new GetDomRVersionAnswer(cmd, "getDomRVersionCmd "
+                    + e.getMessage());
+        }
+    }
+
+    private Answer giveDomRAns(Command cmd, String ip, String args, String resp) {
+        CloudStackPlugin cSp = new CloudStackPlugin(c);
+        try {
+            CloudStackPlugin.ReturnCode result = cSp.domrExec(ip, args);
+            if (!result.getRc()) {
+                return new Answer(cmd, false, result.getStdOut());
+            }
+        } catch (Exception e) {
+            return new Answer(cmd, false, e.getMessage());
+        }
+        return new Answer(cmd);
+    }
+
+    protected synchronized Answer execute(final DhcpEntryCommand cmd) {
+        String args = this.DefaultDomRPath + "edithosts.sh";
+        String ip = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        if (cmd.getVmIpAddress() != null) {
+            args += " -4 " + cmd.getVmIpAddress();
+        }
+        args += " -m " + cmd.getVmMac();
+        args += " -n " + cmd.getVmName();
+        if (cmd.getDefaultRouter() != null) {
+            args += " -d " + cmd.getDefaultRouter();
+        }
+        if (cmd.getStaticRoutes() != null) {
+            args += " -s " + cmd.getStaticRoutes();
+        }
+
+        if (cmd.getDefaultDns() != null) {
+            args += " -N " + cmd.getDefaultDns();
+        }
+
+        if (cmd.getVmIp6Address() != null) {
+            args += " -6 " + cmd.getVmIp6Address();
+            args += " -u " + cmd.getDuid();
+        }
+
+        if (!cmd.isDefault()) {
+            args += " -z";
+        }
+
+        return giveDomRAns(cmd, ip, args, "DhcpEntry failed");
+    }
+
+    protected Answer execute(final SavePasswordCommand cmd) {
+        final String password = cmd.getPassword();
+        final String ip = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        final String vmIpAddress = cmd.getVmIpAddress();
+        String args = this.DefaultDomRPath + "savepassword.sh ";
+        args += " -v " + vmIpAddress;
+        args += " -p " + password;
+        return giveDomRAns(cmd, ip, args, "SavePassword failed");
+    }
+
+    protected Answer execute(final VmDataCommand cmd) {
+        String ip = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        Map<String, List<String[]>> data = new HashMap<String, List<String[]>>();
+        data.put(cmd.getVmIpAddress(), cmd.getVmData());
+        String json = new Gson().toJson(data);
+        json = Base64.encodeBase64String(json.getBytes());
+        String args = this.DefaultDomRPath + "vmdata.py -d " + json;
+        return giveDomRAns(cmd, ip, args, "Set vm_data failed");
+    }
+
+    /*
+     * we don't for now, gave an error on migration though....
+     */
+    private Answer execute(NetworkRulesSystemVmCommand cmd) {
+        boolean success = true;
+        if (_canBridgeFirewall) {
+            // meh
+        }
+        return new Answer(cmd, success, "");
+    }
+
+    public CheckSshAnswer execute(CheckSshCommand cmd) {
+        String vmName = cmd.getName();
+        String privateIp = cmd.getIp();
+        int cmdPort = cmd.getPort();
+        int interval = cmd.getInterval();
+        int retries = cmd.getRetries();
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Trying port " + privateIp + ":" + cmdPort);
+        }
+        try {
+            CloudStackPlugin cSp = new CloudStackPlugin(c);
+            if (!cSp.domrCheckPort(privateIp, cmdPort, retries, interval)) {
+                s_logger.info(vmName + ":" + cmdPort + " nok");
+                return new CheckSshAnswer(cmd, "unable to connect");
+            }
+            s_logger.info(vmName + ":" + cmdPort + " ok");
+        } catch (Exception e) {
+            s_logger.error("Can not reach port on System vm " + vmName
+                    + " due to exception", e);
+            return new CheckSshAnswer(cmd, e);
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Ping command port succeeded for vm " + vmName + " "
+                    + cmd);
+        }
+        if (VirtualMachineName.isValidRouterName(vmName)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Execute network usage setup command on "
+                        + vmName);
+            }
+            // TODO: check this one out...
+        }
+        return new CheckSshAnswer(cmd);
+    }
+
+    protected Answer execute(GetHostStatsCommand cmd) {
+        try {
+            CloudStackPlugin cSp = new CloudStackPlugin(c);
+            Map<String, String> stats = cSp.ovsDom0Stats(this._publicNetworkName);
+            Double cpuUtil = Double.parseDouble(stats.get("cpu"));
+            Double rxBytes = Double.parseDouble(stats.get("rx"));
+            Double txBytes = Double.parseDouble(stats.get("tx"));
+            Double totalMemory = Double.parseDouble(stats.get("total"));
+            Double freeMemory = Double.parseDouble(stats.get("free"));
+            HostStatsEntry hostStats = new HostStatsEntry(cmd.getHostId(),
+                    cpuUtil, rxBytes, txBytes, "host", totalMemory, freeMemory,
+                    0, 0);
+            return new GetHostStatsAnswer(cmd, hostStats);
+        } catch (Exception e) {
+            s_logger.debug("Get host stats of " + cmd.getHostName() + " failed",
+                    e);
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
+    /* TODO: Stop the VM, this means cleanup too, should this be destroy ? */
+    @Override
+    public StopAnswer execute(StopCommand cmd) {
+        String vmName = cmd.getVmName();
+        State state = State.Error;
+        synchronized (this._vmstates) {
+            state = _vmstates.get(vmName);
+            this._vmstates.put(vmName, State.Stopping);
+        }
+
+        try {
+            Xen vms = new Xen(c);
+            Xen.Vm vm = null;
+            vm = vms.getRunningVmConfig(vmName);
+
+            if (vm == null) {
+                state = State.Stopping;
+                s_logger.debug("Unable to get details of vm: " + vmName
+                        + ", treating it as Stopping");
+                return new StopAnswer(cmd, "success", true);
+            }
+            String repoId = _ovmObject.deDash(vm.getVmRootDiskPoolId());
+            String vmId = vm.getVmUuid();
+
+            /* can we do without the poolId ? */
+            vms.stopVm(repoId, vmId);
+            int tries = 30;
+            while (vms.getRunningVmConfig(vmName) != null && tries > 0) {
+                String msg = "Waiting for " + vmName + " to stop";
+                s_logger.debug(msg);
+                tries--;
+                Thread.sleep(10 * 1000);
+            }
+            vms.deleteVm(repoId, vmId);
+            /* TODO: Check cleanup */
+            this.cleanup(vm);
+
+            if (vms.getRunningVmConfig(vmName) != null) {
+                String msg = "Stop " + vmName + " failed ";
+                s_logger.debug(msg);
+                return new StopAnswer(cmd, msg, false);
+            }
+            state = State.Stopped;
+            return new StopAnswer(cmd, "success", true);
+        } catch (Exception e) {
+            /* TODO: check output of message, might be that it did get removed */
+            s_logger.debug("Stop " + vmName + " failed ", e);
+            return new StopAnswer(cmd, e.getMessage(), false);
+        } finally {
+            synchronized (this._vmstates) {
+                if (state != null) {
+                    this._vmstates.put(vmName, state);
+                } else {
+                    this._vmstates.remove(vmName);
+                }
+            }
+        }
+    }
+
+    /* Reboot the VM and destroy should call the same method in here ? */
+    @Override
+    public RebootAnswer execute(RebootCommand cmd) {
+        String vmName = cmd.getVmName();
+
+        synchronized (this._vmstates) {
+            this._vmstates.put(vmName, State.Starting);
+        }
+
+        try {
+            Xen xen = new Xen(c);
+            Xen.Vm vm = xen.getRunningVmConfig(vmName);
+            /* TODO: stop, start or reboot, reboot for now ? */
+            xen.rebootVm(_ovmObject.deDash(vm.getVmRootDiskPoolId()),
+                    vm.getVmUuid());
+            vm = xen.getRunningVmConfig(vmName);
+            /* erh but this don't work, should point at cloudstackplugin */
+            Integer vncPort = vm.getVncPort();
+            return new RebootAnswer(cmd, null, vncPort);
+        } catch (Exception e) {
+            s_logger.debug("Reboot " + vmName + " failed", e);
+            return new RebootAnswer(cmd, e.getMessage(), false);
+        } finally {
+            synchronized (this._vmstates) {
+                this._vmstates.put(cmd.getVmName(), State.Running);
+            }
+        }
+    }
+
+    protected State convertPowerToState(PowerState ps) {
+        final State state = s_stateMaps.get(ps.toString());
+        return state == null ? State.Unknown : state;
+    }
+
+    private static PowerState convertStateToPower(State s) {
+        final PowerState state = s_powerStateMaps.get(s.toString());
+        return state == null ? PowerState.PowerUnknown : state;
+    }
+
+    /* State to power in the states */
+    protected Map<String, HostVmStateReportEntry> HostVmStateReport()
+            throws XmlRpcException {
+        final HashMap<String, HostVmStateReportEntry> vmStates = new HashMap<String, HostVmStateReportEntry>();
+        Map<String, State> vms = sync();
+        for (final Map.Entry<String, State> vm : vms.entrySet()) {
+            /* TODO: Figure out how to get xentools version in here */
+            s_logger.debug("VM " + vm.getKey() + " state: " + vm.getValue()
+                    + ":" + convertStateToPower(vm.getValue()));
+            vmStates.put(vm.getKey(), new HostVmStateReportEntry(
+                    convertStateToPower(vm.getValue()), c.getIp(), null));
+        }
+        return vmStates;
+    }
+
+    /* uses the running configuration, not the vm.cfg configuration */
+    protected Map<String, Xen.Vm> getAllVms() throws XmlRpcException {
+        try {
+            Xen vms = new Xen(c);
+            return vms.getRunningVmConfigs();
+        } catch (Exception e) {
+            s_logger.debug("getting VM list from " + _host + " failed", e);
+            throw new CloudRuntimeException("Exception on getting VMs from "
+                    + _host + ":" + e.getMessage(), e);
+        }
+    }
+
+    /*
+     * Get all the states and set them up according to xm(1)
+     * TODO: check migrating ?
+     */
+    protected HashMap<String, State> getAllVmStates() throws XmlRpcException {
+        Map<String, Xen.Vm> vms = getAllVms();
+        final HashMap<String, State> states = new HashMap<String, State>();
+        for (final Map.Entry<String, Xen.Vm> entry : vms.entrySet()) {
+            Xen.Vm vm = entry.getValue();
+            if (vm.isControlDomain()) {
+                continue;
+            }
+            State ns = State.Running;
+            String as = vm.getVmState();
+            /* missing VM is stopped */
+            if (as == null) {
+                ns = State.Stopped;
+                continue;
+            }
+            /* The domain is currently running on a CPU */
+            /* need a more exact match! */
+            if (as.contains("r")) {
+                ns = State.Running;
+                /* The domain is blocked, and not running or runnable. */
+            } else if (as.contains("b")) {
+                ns = State.Running;
+                /* The domain has been paused */
+            } else if (as.contains("p")) {
+                ns = State.Running;
+                /* The guest has requested to be shutdown, still migrating... */
+            } else if (as.contains("s")) {
+                if (this._vmstates.get(vm.getVmName()) == State.Migrating)
+                    ns = State.Migrating;
+                ns = State.Stopped;
+                /* The domain has crashed */
+            } else if (as.contains("c")) {
+                ns = State.Error;
+                /*
+                 * The domain is in process of dying (if we see this twice we
+                 * have a problem ?)
+                 */
+            } else if (as.contains("d")) {
+                ns = State.Stopping;
+            } else {
+                ns = State.Unknown;
+            }
+            s_logger.debug("state " + ns + " for " + vm.getVmName()
+                    + " based on " + as);
+            states.put(vm.getVmName(), ns);
+        }
+        return states;
+    }
+
+    /* sync the state we know of with reality */
+    protected HashMap<String, State> sync() {
+        HashMap<String, State> newStates;
+        HashMap<String, State> oldStates = null;
+
+        try {
+            final HashMap<String, State> changes = new HashMap<String, State>();
+            newStates = getAllVmStates();
+            if (newStates == null) {
+                s_logger.debug("Unable to get the vm states so no state sync at this point.");
+                return null;
+            }
+
+            synchronized (_vmstates) {
+                oldStates = new HashMap<String, State>(_vmstates.size());
+                oldStates.putAll(_vmstates);
+
+                for (final Map.Entry<String, State> entry : newStates
+                        .entrySet()) {
+                    final String vmName = entry.getKey();
+                    State newState = entry.getValue();
+                    final State oldState = oldStates.remove(vmName);
+                    s_logger.debug("state for " + vmName + ", old: " + oldState
+                            + ", new: " + newState);
+
+                    /* eurh ? */
+                    if (newState == State.Stopped && oldState != State.Stopping
+                            && oldState != null && oldState != State.Stopped) {
+                        s_logger.debug("Getting power state....");
+                        newState = State.Running;
+                    }
+
+                    if (s_logger.isTraceEnabled()) {
+                        s_logger.trace("VM "
+                                + vmName
+                                + ": ovm has state "
+                                + newState
+                                + " and we have state "
+                                + (oldState != null ? oldState.toString()
+                                        : "null"));
+                    }
+
+                    /* TODO: is this really true ? should be right ? */
+                    if (newState == State.Migrating) {
+                        s_logger.debug(vmName
+                                + " is migrating, skipping state check");
+                        continue;
+                    }
+
+                    if (oldState == null) {
+                        _vmstates.put(vmName, newState);
+                        s_logger.debug("New state without old state: " + vmName);
+                        changes.put(vmName, newState);
+                    } else if (oldState == State.Starting) {
+                        if (newState == State.Running) {
+                            _vmstates.put(vmName, newState);
+                        } else if (newState == State.Stopped) {
+                            s_logger.debug("Ignoring vm " + vmName
+                                    + " because of a lag in starting the vm.");
+                        }
+                    } else if (oldState == State.Migrating) {
+                        if (newState == State.Running) {
+                            s_logger.debug("Detected that a migrating VM is now running: "
+                                    + vmName);
+                            _vmstates.put(vmName, newState);
+                        }
+                    } else if (oldState == State.Stopping) {
+                        if (newState == State.Stopped) {
+                            _vmstates.put(vmName, newState);
+                        } else if (newState == State.Running) {
+                            s_logger.debug("Ignoring vm " + vmName
+                                    + " because of a lag in stopping the vm. ");
+                        }
+                    } else if (oldState != newState) {
+                        _vmstates.put(vmName, newState);
+                        if (newState == State.Stopped) {
+                            // TODO: need to state.error here ?
+                        }
+                        changes.put(vmName, newState);
+                    }
+                }
+
+                for (final Map.Entry<String, State> entry : oldStates
+                        .entrySet()) {
+                    final String vmName = entry.getKey();
+                    final State oldState = entry.getValue();
+
+                    if (oldState == State.Stopping) {
+                        s_logger.debug("Removing VM " + vmName
+                                + " in transition state stopping.");
+                        _vmstates.remove(vmName);
+                    } else if (oldState == State.Starting) {
+                        s_logger.debug("Removing VM " + vmName
+                                + " in transition state starting.");
+                        _vmstates.remove(vmName);
+                    } else if (oldState == State.Stopped) {
+                        s_logger.debug("Stopped VM " + vmName + " removing.");
+                        _vmstates.remove(vmName);
+                    } else if (oldState == State.Migrating) {
+                        /*
+                         * do something smarter here.. newstate should
+                         * say stopping already
+                         */
+                        s_logger.debug("Ignoring VM " + vmName
+                                + " in migrating state.");
+                    } else {
+                        /* if it's not there name it stopping */
+                        _vmstates.remove(vmName);
+                        State state = State.Stopping;
+                        s_logger.debug("VM "
+                                + vmName
+                                + " is now missing from ovm3 server so removing it");
+                        /* TODO: something about killed/halted VM's in here ? */
+                        changes.put(vmName, state);
+                    }
+                }
+            }
+
+            return changes;
+        } catch (Exception e) {
+            s_logger.debug("Ovm3 full sync failed", e);
+            return null;
+        }
+    }
+
+    /* cleanup the storageplugin so we can use an object here */
+    protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
+        // cmd.getStorageId();
+        s_logger.debug("Getting stats for: " + cmd.getStorageId());
+        try {
+            Linux host = new Linux(c);
+            /* TODO: NFS only for now */
+            Map<String, Linux.FileSystem> fsList = host
+                    .getFileSystemList("nfs");
+            Linux.FileSystem fs = fsList.get(cmd.getStorageId());
+            StoragePlugin store = new StoragePlugin(c);
+            /*
+             * TODO: something odd here where do I get which Storage I need to
+             * look at ?
+             */
+            String propUuid = store.deDash(cmd.getStorageId());
+            String mntUuid = cmd.getStorageId();
+            store.setUuid(propUuid);
+            store.setSsUuid(propUuid);
+            store.setMntUuid(mntUuid);
+            store.setFsHost(fs.getHost());
+            store.setFsSourcePath(fs.getDevice());
+            store.storagePluginGetFileSystemInfo();
+            long total = Long.parseLong(store.getTotalSize());
+            long used = total - Long.parseLong(store.getFreeSize());
+            return new GetStorageStatsAnswer(cmd, total, used);
+        } catch (Exception e) {
+            s_logger.debug("GetStorageStatsCommand on pool "
+                    + cmd.getStorageId() + " failed",
+                    e);
+            return new GetStorageStatsAnswer(cmd, e.getMessage());
+        }
+    }
+
+    private VmStatsEntry getVmStat(String vmName) throws XmlRpcException {
+        CloudStackPlugin cSp = new CloudStackPlugin(c);
+        Map<String, String> stats = cSp.ovsDomUStats(vmName);
+        Map<String, String> o_stats = this._vmStats.get(vmName);
+        VmStatsEntry e = new VmStatsEntry();
+        if (o_stats == null) {
+            e.setNumCPUs(1);
+            e.setNetworkReadKBs(0);
+            e.setNetworkWriteKBs(0);
+            e.setDiskReadKBs(0);
+            e.setDiskWriteKBs(0);
+            e.setDiskReadIOs(0);
+            e.setDiskWriteIOs(0);
+            e.setCPUUtilization(0);
+            e.setEntityType("vm");
+        } else {
+            /* beware of negatives ? */
+            Integer cpus = Integer.parseInt(stats.get("vcpus"));
+            e.setNumCPUs(Integer.parseInt(stats.get(cpus)));
+            e.setNetworkReadKBs(Double.parseDouble(stats.get("rx_bytes"))
+                    - Double.parseDouble(o_stats.get("rx_bytes")));
+            e.setNetworkWriteKBs(Double.parseDouble(stats.get("tx_bytes"))
+                    - Double.parseDouble(o_stats.get("tx_bytes")));;
+            e.setDiskReadKBs(Double.parseDouble(stats.get("rd_bytes"))
+                    - Double.parseDouble(o_stats.get("rd_bytes")));;
+            e.setDiskWriteKBs(Double.parseDouble(stats.get("rw_bytes"))
+                    - Double.parseDouble(o_stats.get("rw_bytes")));
+            e.setDiskReadIOs(Double.parseDouble(stats.get("rd_ops"))
+                    - Double.parseDouble(o_stats.get("rd_ops")));
+            e.setDiskWriteIOs(Double.parseDouble(stats.get("rw_ops"))
+                    - Double.parseDouble(o_stats.get("rw_ops")));
+
+            Double d_cpu = Double.parseDouble(stats.get("cputime"))
+                    - Double.parseDouble(o_stats.get("cputime"));
+            Double d_time = Double.parseDouble(stats.get("uptime"))
+                    - Double.parseDouble(o_stats.get("uptime"));
+            Double cpupct = d_cpu/d_time * 100 * cpus;
+            e.setCPUUtilization(cpupct);
+            e.setEntityType("vm");
+        }
+        this._vmStats.replace(vmName, stats);
+        return e;
+    }
+
+    /* TODO: The main caller for vm statstics */
+    protected GetVmStatsAnswer execute(GetVmStatsCommand cmd) {
+        List<String> vmNames = cmd.getVmNames();
+        HashMap<String, VmStatsEntry> vmStatsNameMap = new HashMap<String, VmStatsEntry>();
+        for (String vmName : vmNames) {
+            try {
+                VmStatsEntry e = getVmStat(vmName);
+                vmStatsNameMap.put(vmName, e);
+            } catch (XmlRpcException e) {
+                s_logger.debug("Get vm stat for " + vmName + " failed", e);
+                continue;
+            }
+        }
+        return new GetVmStatsAnswer(cmd, vmStatsNameMap);
+    }
+
+    /* TODO: Hot plugging harddisks... */
+    protected AttachVolumeAnswer execute(AttachVolumeCommand cmd) {
+        return new AttachVolumeAnswer(cmd, "You must stop " + cmd.getVmName()
+                + " first, OVM doesn't support hotplug datadisk");
+    }
+
+    /* Destroy a volume (image) */
+    public Answer execute(DestroyCommand cmd) {
+        VolumeTO vol = cmd.getVolume();
+        String vmName = cmd.getVmName();
+        try {
+            StoragePlugin store = new StoragePlugin(c);
+            // TODO: check if path is correct...
+            store.storagePluginDestroy(vol.getPoolUuid(), vol.getPath());
+            return new Answer(cmd, true, "Success");
+        } catch (Exception e) {
+            s_logger.debug("Destroy volume " + vol.getName() + " failed for "
+                    + vmName + " ", e);
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
+    /* Migration should make sure both HVs are the same ? */
+    protected PrepareForMigrationAnswer execute(PrepareForMigrationCommand cmd) {
+        VirtualMachineTO vm = cmd.getVirtualMachine();
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Preparing host for migrating " + vm.getName());
+        }
+        /* securitygroups */
+        try {
+            synchronized (_vmstates) {
+                _vmstates.put(vm.getName(), State.Migrating);
+            }
+            return new PrepareForMigrationAnswer(cmd);
+        } catch (Exception e) {
+            s_logger.warn("Catch Exception " + e.getClass().getName()
+                    + " prepare for migration failed due to " + e.toString(), e);
+            return new PrepareForMigrationAnswer(cmd, e);
+        }
+    }
+
+    /* do migrations of VMs in a simple way just inside a cluster for now */
+    protected MigrateAnswer execute(final MigrateCommand cmd) {
+        final String vmName = cmd.getVmName();
+        String destUuid = cmd.getHostGuid();
+        String destIp = cmd.getDestinationIp();
+        State state = State.Error;
+        /*
+         * TODO: figure out non pooled migration, works from CLI but not from
+         * the agent... perhaps pause the VM and then migrate it ? for now
+         * just stop the VM.
+         */
+        String msg = "Migrating " + vmName + " to " + destIp;
+        s_logger.info(msg);
+        if (!this._ovm3cluster && !this._ovm3pool) {
+            try {
+                Xen xen = new Xen(c);
+                Xen.Vm vm = xen.getRunningVmConfig(vmName);
+                HostVO destHost = _resourceMgr.findHostByGuid(destUuid);
+                if (destHost == null) {
+                    msg = "Unable to find migration target host in DB "
+                            + destUuid + " with ip " + destIp;
+                    s_logger.info(msg);
+                    return new MigrateAnswer(cmd, false, msg, null);
+                }
+                xen.stopVm(_ovmObject.deDash(vm.getVmRootDiskPoolId()),
+                        vm.getVmUuid());
+                msg = destHost.toString();
+                state = State.Stopping;
+                return new MigrateAnswer(cmd, false, msg, null);
+            } catch (Exception e) {
+                msg = "Unpooled VM Migrate of " + vmName + " to " + destUuid
+                        + " failed due to: " + e.getMessage();
+                s_logger.debug(msg, e);
+                return new MigrateAnswer(cmd, false, msg, null);
+            } finally {
+                /* shouldn't we just reinitialize completely as a last resort ? */
+                synchronized (_vmstates) {
+                    _vmstates.put(vmName, state);
+                }
+            }
+        } else {
+            try {
+                Xen xen = new Xen(c);
+                Xen.Vm vm = xen.getRunningVmConfig(vmName);
+                if (vm == null) {
+                    state = State.Stopped;
+                    msg = vmName + " is no running on " + _host;
+                    return new MigrateAnswer(cmd, false, msg, null);
+                }
+                /* not a storage migration!!! */
+                xen.migrateVm(_ovmObject.deDash(vm.getVmRootDiskPoolId()),
+                        vm.getVmUuid(),
+                        destIp);
+                state = State.Stopping;
+                msg = "Migration of " + vmName + " successfull";
+                return new MigrateAnswer(cmd, true, msg, null);
+            } catch (Exception e) {
+                msg = "Pooled VM Migrate" + ": Migration of " + vmName + " to "
+                        + destIp + " failed due to " + e.getMessage();
+                s_logger.debug(msg, e);
+                return new MigrateAnswer(cmd, false, msg, null);
+            } finally {
+                /* if (state != state.Stopped) { */
+                synchronized (_vmstates) {
+                    _vmstates.put(vmName, state);
+                }
+            }
+        }
+    }
+
+    /* hHeck "the" virtual machine */
+    protected CheckVirtualMachineAnswer execute(
+            final CheckVirtualMachineCommand cmd) {
+        String vmName = cmd.getVmName();
+        try {
+            // if state migrating skip ?
+            Xen vms = new Xen(c);
+            Xen.Vm vm = vms.getRunningVmConfig(vmName);
+            /* check if there is a VM */
+
+            CloudStackPlugin plug = new CloudStackPlugin(c);
+            Integer vncPort = Integer.valueOf(plug.getVncPort(vmName));
+            if (vncPort == 0) {
+                s_logger.warn("No VNC port for " + vmName);
+            }
+            /* we already have the state ftw */
+            Map<String, State> states = getAllVmStates();
+            State vmState = states.get(vmName);
+            if (vmState == null) {
+                s_logger.warn("Check state of " + vmName
+                        + " return null in CheckVirtualMachineCommand");
+                vmState = State.Stopped;
+            }
+            synchronized (_vmstates) {
+                _vmstates.put(vmName, State.Running);
+            }
+            return new CheckVirtualMachineAnswer(cmd, vmState, vncPort);
+        } catch (Exception e) {
+            s_logger.debug("Check migration for " + vmName + " failed", e);
+            return new CheckVirtualMachineAnswer(cmd, State.Stopped, null);
+        }
+    }
+
+    /* TODO: fill this one, for maintenance */
+    protected MaintainAnswer execute(MaintainCommand cmd) {
+        /* leave cluster, leave pool, release ownership ? */
+        try {
+            Network net = new Network(c);
+            Pool pool = new Pool(c);
+            // pool.leaveServerPool();
+            net.stopOvsLocalConfig(_controlNetworkName);
+        } catch (Exception e) {
+            s_logger.debug("unable to disable " + _controlNetworkName);
+        }
+        return new MaintainAnswer(cmd);
+    }
+
+    /*
+     */
+    protected GetVncPortAnswer execute(GetVncPortCommand cmd) {
+        try {
+            Xen host = new Xen(c);
+            Xen.Vm vm = host.getRunningVmConfig(cmd.getName());
+            Integer vncPort = vm.getVncPort();
+            s_logger.debug("get vnc port for " + cmd.getName() + ": " + vncPort);
+            return new GetVncPortAnswer(cmd, _ip, vncPort);
+        } catch (Exception e) {
+            s_logger.debug("get vnc port for " + cmd.getName() + " failed", e);
+            return new GetVncPortAnswer(cmd, e.getMessage());
+        }
+    }
+
+    protected Answer execute(PingTestCommand cmd) {
+        try {
+            if (cmd.getComputingHostIp() != null) {
+                CloudStackPlugin cSp = new CloudStackPlugin(c);
+                if (!cSp.ping(cmd.getComputingHostIp())) {
+                    return new Answer(cmd, false, "ping failed");
+                }
+            } else {
+                return new Answer(cmd, false, "why asks me to ping router???");
+            }
+            return new Answer(cmd, true, "success");
+        } catch (Exception e) {
+            s_logger.debug("Ping " + cmd.getComputingHostIp() + " failed", e);
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
+    /*
+     * TODO: no heartbeat if no cluster, should we add a heartbeat ?
+     * cloudstack/plugins
+     * /hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmHostModule.py contains
+     * fence
+     */
+    protected FenceAnswer execute(FenceCommand cmd) {
+        try {
+            Boolean res = false;
+            return new FenceAnswer(cmd, res, res.toString());
+        } catch (Exception e) {
+            s_logger.debug("fence " + cmd.getHostIp() + " failed", e);
+            return new FenceAnswer(cmd, false, e.getMessage());
+        }
+    }
+
+    /* TODO: nothing yet */
+    protected boolean canBridgeFirewall() throws XmlRpcException {
+        return false;
+    }
+
+    protected boolean prepareForPool() throws ConfigurationException {
+        /* need single master uuid */
+        try {
+            Linux host = new Linux(c);
+            Pool pool = new Pool(c);
+
+            /* setup pool and role, needs utility to be able to do things */
+            if (host.getServerRoles().contentEquals(pool.getValidRoles()
+                    .toString())) {
+                s_logger.debug("Server role for host " + _host + " is ok");
+            } else {
+                try {
+                    pool.setServerRoles(pool.getValidRoles());
+                } catch (Exception e) {
+                    s_logger.debug("Failed to set server role for host "
+                            + _host, e);
+                    throw new ConfigurationException(
+                            "Unable to set server role for host");
+                }
+            }
+            if (host.getMembershipState().contentEquals("Unowned")) {
+                try {
+                    s_logger.debug("Take ownership of host " + _host);
+                    pool.takeOwnership(_masterUuid, "");
+                } catch (Exception e) {
+                    String msg = "Failed to take ownership of host " + _host;
+                    s_logger.debug(msg, e);
+                    throw new ConfigurationException(msg);
+                }
+            } else {
+                /* TODO: check if it's part of our pool, give ok if it is */
+                if (host.getManagerUuid().equals(_masterUuid)) {
+                    String msg = "Host " + _host + " owned by us";
+                    s_logger.debug(msg);
+                    return true;
+                } else {
+                    String msg = "Host " + _host
+                            + " already part of a pool, and not owned by us";
+                    s_logger.debug(msg);
+                    throw new ConfigurationException(msg);
+                }
+            }
+        } catch (Exception es) {
+            String msg = "Failed to prepare " + _host + " for pool";
+            s_logger.debug(msg, es);
+            throw new ConfigurationException(msg + ": " + es.getMessage());
+        }
+        return true;
+    }
+
+    /*
+     * TODO: redo this, it's a mess now.
+     */
+    protected Boolean setupPool(StorageFilerTO cmd)
+            throws ConfigurationException, XmlRpcException, Exception {
+        String primUuid = cmd.getUuid();
+        String ssUuid = _ovmObject.deDash(primUuid);
+        String ovsRepo = this._ovmRepo + "/" + _ovmObject.deDash(primUuid);
+        String fsType = "nfs";
+        /* TODO: 16, need to get this from the cluster id actually */
+        String clusterUuid = _masterUuid.substring(0, 15);
+        String managerId = _masterUuid;
+        String poolAlias = cmd.getHost() + ":" + cmd.getPath();
+        String mountPoint = String.format("%1$s:%2$s",
+                cmd.getHost(),
+                cmd.getPath()) +
+                "/VirtualMachines";
+        List<String> members = new ArrayList<String>();
+        _isMaster = masterCheck();
+        Integer poolSize = 0;
+        String msg = "";
+
+        try {
+            Pool poolHost = new Pool(c);
+            if (_isMaster && !poolHost.getPoolId().contentEquals(primUuid)
+                    && !_hasMaster) {
+                PoolOCFS2 poolFs = new PoolOCFS2(c);
+                try {
+                    try {
+                        msg = "Create poolfs on " + _host + " for repo "
+                                + primUuid;
+                        s_logger.debug(msg);
+                        poolFs.createPoolFs(fsType,
+                                mountPoint,
+                                clusterUuid,
+                                primUuid,
+                                ssUuid,
+                                managerId,
+                                primUuid);
+                    } catch (Exception e) {
+                        msg = "Poolfs already exists on " + _host
+                                + " for repo " + primUuid;
+                        s_logger.debug(msg);
+                    }
+                    try {
+                        poolHost.createServerPool(poolAlias,
+                                primUuid,
+                                _ovm3vip,
+                                poolSize + 1,
+                                _host,
+                                _ip);
+                    } catch (Exception e) {
+                        msg = "Server pool with id " + clusterUuid + " on "
+                                + _host;
+                        s_logger.debug(msg);
+                    }
+                } catch (Exception e) {
+                    msg = "Failed to create pool on " + _host + " for repo "
+                            + primUuid;
+                    s_logger.debug(msg, e);
+                    throw new Exception(msg);
+                }
+            } else if (!_isMaster || _hasMaster) {
+                Pool poolMaster = new Pool(m);
+                poolSize = poolMaster.getPoolMemberIpList().size() + 1;
+                members.addAll(poolMaster.getPoolMemberIpList());
+
+                poolHost = new Pool(c);
+                if (!poolHost.getPoolId().contentEquals(primUuid)) {
+
+                    /* get all the details from the master */
+                    try {
+                        /* why does it call bloody M here???!?!?!! */
+                        poolHost.joinServerPool(poolAlias,
+                                primUuid,
+                                _ovm3vip,
+                                poolSize,
+                                _host,
+                                _ip);
+                    } catch (Exception e) {
+                        msg = "Failed to join server pool "
+                                + poolMaster.getPoolAlias() + " on " + _host
+                                + " for pool " + primUuid;
+                        s_logger.debug(msg, e);
+                        throw new Exception(msg);
+                    }
+                }
+            } else {
+                s_logger.debug("Pool " + primUuid + " already configured on "
+                        + _host);
+            }
+            if (!members.contains(_ip)) {
+                members.add(_ip);
+            }
+            for (String member : members) {
+                /* easy way out for now..., should get this from hostVO */
+                String url = "http://" + this._agentUserName + ":"
+                        + this._agentPassword + "@" + member + ":" + _agentPort
+                        + "/api/3";
+                /*
+                 * Common comCall = new Common(c);
+                 * comCall.dispatch(url,
+                 * "set_pool_member_ip_list",
+                 * StringUtils.join(members, ","));
+                 */
+                Connection x = new Connection(member, _agentPort,
+                        _agentUserName, _agentPassword);
+                Pool xpool = new Pool(x);
+                xpool.setPoolIps(members);
+                xpool.setPoolMemberIpList();
+                msg = "Added " + member + " to pool " + primUuid;
+                s_logger.debug(msg);
+            }
+        } catch (Exception e) {
+            msg = "Failed to setup server pool on " + _host;
+            s_logger.debug(msg, e);
+            throw new Exception(msg);
+        }
+        return true;
+    }
+
+    /* the storage url combination of host and path is unique */
+    protected String setupSecondaryStorage(String url) throws Exception {
+        URI uri = URI.create(url);
+        String uuid = _ovmObject.newUuid(uri.getHost() + ":" + uri.getPath());
+        s_logger.info("Secondary storage with uuid: " + uuid);
+        return setupNfsStorage(uri, uuid);
+    }
+
+    protected String setupNfsStorage(URI uri, String uuid) throws Exception {
+        String fsUri = "nfs";
+        String fsType = "FileSys";
+        String msg = "";
+        String mountPoint = this._ovmSec + "/" + uuid;
+        Linux host = new Linux(c);
+        try {
+            Map<String, Linux.FileSystem> fsList = host
+                    .getFileSystemList(fsUri);
+            Linux.FileSystem fs = fsList.get(uuid);
+            if (fs == null || !fs.getMountPoint().equals(mountPoint)) {
+                try {
+                    StoragePlugin sp = new StoragePlugin(c);
+                    sp.storagePluginMount(uri.getHost(),
+                            uri.getPath(),
+                            uuid,
+                            mountPoint);
+                    msg = "Nfs storage " + uri + " mounted on " + mountPoint;
+                    return uuid;
+                } catch (Exception ec) {
+                    msg = "Nfs storage " + uri + " mount on " + mountPoint
+                            + " FAILED " + ec.getMessage();
+                    throw new Exception(msg, ec);
+                }
+            } else {
+                msg = "NFS storage " + uri + " already mounted on "
+                        + mountPoint;
+                return uuid;
+            }
+        } finally {
+            s_logger.debug(msg);
+        }
+    }
+
+    /* TODO: move the connection elsewhere.... */
+    protected boolean masterCheck() throws ConfigurationException, Exception {
+        if (_ovm3vip.equals("")) {
+            s_logger.debug("No cluster vip, not checking for master");
+            return false;
+        }
+        try {
+            /* should get the details of that host hmmz */
+            m = new Connection(_ovm3vip, _agentPort, _agentUserName,
+                    _agentPassword);
+            Linux master = new Linux(m);
+            if (master.getHostName().equals(_host)) {
+                s_logger.debug("Host " + _host + " is master");
+                this._isMaster = true;
+            } else {
+                s_logger.debug("Host " + _host + " has master "
+                        + master.getHostName());
+                _hasMaster = true;
+            }
+        } catch (Exception e) {
+            this._isMaster = true;
+            s_logger.debug("Unable to connect to master, we are master");
+        } finally {
+            if (!this._isMaster) {
+                if (this._hasMaster) {
+                    s_logger.debug("Host " + _host + " will become a slave "
+                            + _ovm3vip);
+                    return this._isMaster;
+                } else {
+                    this._isMaster = true;
+                    s_logger.debug("Host " + _host + " will become a master "
+                            + _ovm3vip);
+                    return this._isMaster;
+                }
+            }
+        }
+        return this._isMaster;
+    }
+
+    /* check if a VM is running should be added */
+    protected CreatePrivateTemplateAnswer execute(
+            final CreatePrivateTemplateFromVolumeCommand cmd) {
+        String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+        String volumePath = cmd.getVolumePath();
+        Long accountId = cmd.getAccountId();
+        Long templateId = cmd.getTemplateId();
+        int wait = cmd.getWait();
+        if (wait == 0) {
+            /* Defaut timeout 2 hours */
+            wait = 7200;
+        }
+
+        try {
+            URI uri;
+            uri = new URI(secondaryStorageUrl);
+            String secondaryStorageMountPath = uri.getHost() + ":"
+                    + uri.getPath();
+            /* missing uuid */
+            String installPath = _ovmRepo + "/Templates/" + accountId + "/"
+                    + templateId;
+            String templateLoc = installPath;
+            Linux host = new Linux(c);
+            /* check if VM is running or thrown an error, or pause it :P */
+            host.copyFile(volumePath, installPath);
+            /* TODO: look at the original */
+            return new CreatePrivateTemplateAnswer(cmd, true, installPath);
+            /*
+             * res.get("installPath"), Long.valueOf(res.get("virtualSize")),
+             * Long.valueOf(res.get("physicalSize")),
+             * res.get("templateFileName"), ImageFormat.RAW);
+             */
+        } catch (Exception e) {
+            s_logger.debug("Create template failed", e);
+            return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage());
+        }
+    }
+
+    /*
+     * Might have some logic errors that's what debugging is for...
+     */
+    protected CopyVolumeAnswer execute(CopyVolumeCommand cmd) {
+        String volumePath = cmd.getVolumePath();
+        /* is a repository */
+        String secondaryStorageURL = cmd.getSecondaryStorageURL();
+        int wait = cmd.getWait();
+        if (wait == 0) {
+            wait = 7200;
+        }
+
+        /* TODO: we need to figure out what sec and prim really is */
+        try {
+            Linux host = new Linux(c);
+
+            /* to secondary storage */
+            if (cmd.toSecondaryStorage()) {
+                s_logger.debug("Copy to  secondary storage " + volumePath
+                        + " to " + secondaryStorageURL);
+                host.copyFile(volumePath, secondaryStorageURL);
+                /* from secondary storage */
+            } else {
+                s_logger.debug("Copy from secondary storage "
+                        + secondaryStorageURL + " to " + volumePath);
+                host.copyFile(secondaryStorageURL, volumePath);
+            }
+            /* check the truth of this */
+            return new CopyVolumeAnswer(cmd, true, null, null, null);
+        } catch (Exception e) {
+            s_logger.debug("Copy volume failed", e);
+            return new CopyVolumeAnswer(cmd, false, e.getMessage(), null, null);
+        }
+    }
+
+    /*
+     * TODO: this ties into if we're in a cluster or just a pool, leaving a pool
+     * means just leaving the pool and getting rid of the pooled fs, different a
+     * repo though
+     */
+    protected Answer execute(DeleteStoragePoolCommand cmd) {
+        try {
+            Pool pool = new Pool(c);
+            pool.leaveServerPool(cmd.getPool().getUuid());
+            /* also connect to the master and update the pool list ? */
+        } catch (Exception e) {
+            s_logger.debug("Delete storage pool on host "
+                    + _host
+                    + " failed, however, we leave to user for cleanup and tell managment server it succeeded",
+                    e);
+        }
+
+        return new Answer(cmd);
+    }
+
+    /* TODO: check getPhysicalNetworkInfoList */
+    /*
+     * need to refactor this bit, networksetupbyname makes no sense, and neither
+     * does the physical bit
+     */
+    protected CheckNetworkAnswer execute(CheckNetworkCommand cmd) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Checking if network name setup is done on " + _host);
+        }
+
+        List<PhysicalNetworkSetupInfo> infoList = cmd
+                .getPhysicalNetworkInfoList();
+        boolean errorout = false;
+        String msg = "";
+        /* here we assume all networks are set */
+        for (PhysicalNetworkSetupInfo info : infoList) {
+            if (info.getGuestNetworkName() == null)
+                info.setGuestNetworkName(this._guestNetworkName);
+            if (info.getPublicNetworkName() == null)
+                info.setPublicNetworkName(this._publicNetworkName);
+            if (info.getPrivateNetworkName() == null)
+                info.setPrivateNetworkName(this._privateNetworkName);
+            if (info.getStorageNetworkName() == null)
+                info.setStorageNetworkName(this._storageNetworkName);
+
+            if (!isNetworkSetupByName(info.getGuestNetworkName())) {
+                msg = "For Physical Network id:"
+                        + info.getPhysicalNetworkId()
+                        + ", Guest Network is not configured on the backend by name "
+                        + info.getGuestNetworkName();
+                errorout = true;
+                break;
+            }
+            if (!isNetworkSetupByName(info.getPrivateNetworkName())) {
+                msg = "For Physical Network id:"
+                        + info.getPhysicalNetworkId()
+                        + ", Private Network is not configured on the backend by name "
+                        + info.getPrivateNetworkName();
+                errorout = true;
+                break;
+            }
+            if (!isNetworkSetupByName(info.getPublicNetworkName())) {
+                msg = "For Physical Network id:"
+                        + info.getPhysicalNetworkId()
+                        + ", Public Network is not configured on the backend by name "
+                        + info.getPublicNetworkName();
+                errorout = true;
+                break;
+            }
+            /* Storage network is optional, will revert to private otherwise */
+        }
+
+        if (errorout) {
+            s_logger.error(msg);
+            return new CheckNetworkAnswer(cmd, false, msg);
+        } else {
+            return new CheckNetworkAnswer(cmd, true,
+                    "Network Setup check by names is done");
+        }
+    }
+
+    private boolean isNetworkSetupByName(String nameTag) {
+        s_logger.debug("known networks: " + this._guestNetworkName + " "
+                + this._publicNetworkName + " " + this._privateNetworkName);
+        if (nameTag != null) {
+            s_logger.debug("Looking for network setup by name " + nameTag);
+
+            try {
+                Network net = new Network(c);
+                net.setBridgeList(_interfaces);
+                if (net.getBridgeByName(nameTag) != null) {
+                    s_logger.debug("Found bridge with name: " + nameTag);
+                    return true;
+                }
+            } catch (Exception e) {
+                s_logger.debug("Unxpected error looking for name: " + nameTag);
+                return false;
+            }
+        }
+        s_logger.debug("No bridge with name: " + nameTag);
+        return false;
+    }
+
+    @Override
+    public Answer executeRequest(Command cmd) {
+        Class<? extends Command> clazz = cmd.getClass();
+        if (clazz == ReadyCommand.class) {
+            return execute((ReadyCommand) cmd);
+        } else if (clazz == CopyCommand.class) {
+            return execute((CopyCommand) cmd);
+        } else if (clazz == DeleteCommand.class) {
+            return execute((DeleteCommand) cmd);
+        } else if (clazz == CreateStoragePoolCommand.class) {
+            return execute((CreateStoragePoolCommand) cmd);
+        } else if (clazz == ModifyStoragePoolCommand.class) {
+            return execute((ModifyStoragePoolCommand) cmd);
+        } else if (clazz == PrimaryStorageDownloadCommand.class) {
+            return execute((PrimaryStorageDownloadCommand) cmd);
+        } else if (clazz == CreateCommand.class) {
+            return execute((CreateCommand) cmd);
+        } else if (clazz == GetHostStatsCommand.class) {
+            return execute((GetHostStatsCommand) cmd);
+        } else if (clazz == StopCommand.class) {
+            return execute((StopCommand) cmd);
+        } else if (clazz == RebootCommand.class) {
+            return execute((RebootCommand) cmd);
+        } else if (clazz == GetStorageStatsCommand.class) {
+            return execute((GetStorageStatsCommand) cmd);
+        } else if (clazz == GetVmStatsCommand.class) {
+            return execute((GetVmStatsCommand) cmd);
+        } else if (clazz == AttachVolumeCommand.class) {
+            return execute((AttachVolumeCommand) cmd);
+        } else if (clazz == DestroyCommand.class) {
+            return execute((DestroyCommand) cmd);
+        } else if (clazz == PrepareForMigrationCommand.class) {
+            return execute((PrepareForMigrationCommand) cmd);
+        } else if (clazz == MigrateCommand.class) {
+            return execute((MigrateCommand) cmd);
+        } else if (clazz == CheckVirtualMachineCommand.class) {
+            return execute((CheckVirtualMachineCommand) cmd);
+        } else if (clazz == MaintainCommand.class) {
+            return execute((MaintainCommand) cmd);
+        } else if (clazz == StartCommand.class) {
+            return execute((StartCommand) cmd);
+        } else if (clazz == GetVncPortCommand.class) {
+            return execute((GetVncPortCommand) cmd);
+        } else if (clazz == PingTestCommand.class) {
+            return execute((PingTestCommand) cmd);
+        } else if (clazz == FenceCommand.class) {
+            return execute((FenceCommand) cmd);
+        } else if (clazz == AttachIsoCommand.class) {
+            return execute((AttachIsoCommand) cmd);
+        } else if (clazz == DettachCommand.class) {
+            return execute((DettachCommand) cmd);
+        } else if (clazz == AttachCommand.class) {
+            return execute((AttachCommand) cmd);
+        } else if (clazz == NetworkRulesSystemVmCommand.class) {
+            return execute((NetworkRulesSystemVmCommand) cmd);
+            /*
+             * } else if (clazz == SecurityGroupRulesCmd.class) { return
+             * execute((SecurityGroupRulesCmd) cmd); } else if (clazz ==
+             * CleanupNetworkRulesCmd.class) { return
+             * execute((CleanupNetworkRulesCmd) cmd); } else if (clazz ==
+             * PrepareOCFS2NodesCommand.class) { return
+             * execute((PrepareOCFS2NodesCommand) cmd);
+             */
+        } else if (clazz == CreatePrivateTemplateFromVolumeCommand.class) {
+            return execute((CreatePrivateTemplateFromVolumeCommand) cmd);
+        } else if (clazz == CopyVolumeCommand.class) {
+            return execute((CopyVolumeCommand) cmd);
+        } else if (clazz == DeleteStoragePoolCommand.class) {
+            return execute((DeleteStoragePoolCommand) cmd);
+        } else if (clazz == CheckNetworkCommand.class) {
+            return execute((CheckNetworkCommand) cmd);
+        } else if (clazz == CheckSshCommand.class) {
+            return execute((CheckSshCommand) cmd);
+        } else if (clazz == GetDomRVersionCmd.class) {
+            return execute((GetDomRVersionCmd) cmd);
+        } else if (clazz == DhcpEntryCommand.class) {
+            return execute((DhcpEntryCommand) cmd);
+        } else if (clazz == SavePasswordCommand.class) {
+            return execute((SavePasswordCommand) cmd);
+        } else if (clazz == VmDataCommand.class) {
+            return execute((VmDataCommand) cmd);
+        } else if (clazz == CreateObjectCommand.class) {
+            return execute((CreateObjectCommand) cmd);
+        } else {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+    }
+
+    @Override
+    public void disconnected() {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public IAgentControl getAgentControl() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void setAgentControl(IAgentControl agentControl) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setName(String name) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setConfigParams(Map<String, Object> params) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public Map<String, Object> getConfigParams() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getRunLevel() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public void setRunLevel(int level) {
+        // TODO Auto-generated method stub
+
+    }
+
+    /* TODO: move to the StoragPprocessor */
+    @Override
+    public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    @Override
+    public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    @Override
+    public Answer cloneVolumeFromBaseTemplate(CopyCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    @Override
+    public Answer createTemplateFromVolume(CopyCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    @Override
+    public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    @Override
+    public Answer createTemplateFromSnapshot(CopyCommand cmd) {
+        return null;  // To change body of implemented methods use File |
+                     // Settings | File Templates.
+    }
+
+    @Override
+    public Answer backupSnapshot(CopyCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    /*
+     * TODO: Add iso and update config of the VM is done from set_disk in
+     * lib/xenxm.py (Example found in Xen.java)
+     * Iso first needs to be copied over to the primary storage where the ISOs
+     * reside, or just mount secondary storage, feh!
+     */
+    protected Answer execute(AttachIsoCommand cmd) {
+        try {
+            URI iso = new URI(cmd.getIsoPath());
+            String isoPath = iso.getHost() + ":" + iso.getPath();
+            /*
+             * Ovm3Vm.detachOrAttachIso(_conn, cmd.getVmName(), isoPath,
+             * cmd.isAttach());
+             */
+            // setupSecStorage()
+            s_logger.debug(cmd.getStoreUrl() + " " + cmd.getIsoPath());
+            return new Answer(cmd);
+        } catch (Exception e) {
+            s_logger.debug("Attach or detach ISO " + cmd.getIsoPath() + " for "
+                    + cmd.getVmName() + " attach:" + cmd.isAttach() + " failed",
+                    e);
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
+    @Override
+    public Answer attachIso(AttachCommand cmd) {
+        s_logger.debug("attachIso not implemented yet");
+        return new Answer(cmd);
+    }
+
+    @Override
+    public Answer dettachIso(DettachCommand cmd) {
+        s_logger.debug("detachIso not implemented yet");
+        return new Answer(cmd);
+    }
+
+    public String isoAttachDetach(String vmName, DiskTO disk, boolean isAttach) {
+        Xen xen = new Xen(c);
+        String doThis = (isAttach) ? "AttachIso" : "DettachIso";
+        String msg = null;
+        try {
+            Xen.Vm vm = xen.getVmConfig(vmName);
+            /* check running */
+            if (vm == null) {
+                msg = doThis + " can't find VM " + vmName;
+                return msg;
+            }
+            TemplateObjectTO isoTO = (TemplateObjectTO) disk.getData();
+            DataStoreTO store = isoTO.getDataStore();
+            if (!(store instanceof NfsTO)) {
+                msg = doThis + " unsupported protocol";
+                return msg;
+            }
+            NfsTO nfsStore = (NfsTO) store;
+            String secPoolUuid = setupSecondaryStorage(nfsStore.getUrl());
+            String isoPath = _ovmSec + File.separator + secPoolUuid
+                    + File.separator + isoTO.getPath();
+            s_logger.debug(doThis + " " + isoPath);
+            if (isAttach) {
+                /* check if iso is not already there ? */
+                vm.addIso(isoPath);
+            } else {
+                if (!vm.removeDisk(isoPath)) {
+                    msg = doThis + " failed for "
+                            + vmName + " iso was not attached " + isoPath;
+                    return msg;
+                }
+            }
+            xen.configureVm(_ovmObject.deDash(vm.getPrimaryPoolUuid()),
+                    vm.getVmUuid());
+            return msg;
+        } catch (Exception e) {
+            msg = doThis + " failed for " + vmName + " " + e.getMessage();
+            return msg;
+        } finally {
+            if (msg == null) {
+                msg = "success";
+            }
+            s_logger.debug(msg);
+        }
+    }
+
+    public Answer execute(AttachCommand cmd) {
+        String vmName = cmd.getVmName();
+        DiskTO disk = cmd.getDisk();
+        Boolean success = false;
+        String answer = "";
+        if (cmd.getDisk().getType() == Volume.Type.ISO) {
+            answer = isoAttachDetach(vmName, disk, true);
+        }
+
+        if (answer == null) {
+            success = true;
+        }
+        return new Answer(cmd, success, answer);
+    }
+
+    public Answer execute(DettachCommand cmd) {
+        String vmName = cmd.getVmName();
+        DiskTO disk = cmd.getDisk();
+        Boolean success = false;
+        String answer = "";
+        if (cmd.getDisk().getType() == Volume.Type.ISO) {
+            answer = isoAttachDetach(vmName, disk, false);
+        }
+
+        if (answer == null) {
+            success = true;
+        }
+        return new Answer(cmd, success, answer);
+        /*
+         * s_logger.debug("dettaching object: " + cmd.getDisk().getType());
+         * if (this._vmstates.get(vmName) == State.Running) {
+         * return new DettachAnswer("Dettach unsupported on running VM "
+         * + vmName);
+         */
+    }
+
+    /*
+     * for now we assume that the datastore is there or else we
+     * never came this far
+     */
+    public Answer execute(CreateObjectCommand cmd) {
+        // public Answer execute(CreateObjectCommand cmd) {
+        DataTO data = cmd.getData();
+        s_logger.debug("creating new object: " + data.getObjectType());
+        if (data.getObjectType() == DataObjectType.VOLUME) {
+            return createVolume(cmd);
+        } else if (data.getObjectType() == DataObjectType.SNAPSHOT) {
+            /*
+             * if stopped yes, if runniing ... no, unless we have ocfs2
+             * when using raw partitions (file:) if using tap:aio we cloud...
+             */
+            /* if (_vmstates(get)) { */
+        } else if (data.getObjectType() == DataObjectType.TEMPLATE) {
+            /* aaalwaaays */
+        } else {
+
+        }
+        return new CreateObjectAnswer("Create unsupported object type: "
+                + data.getObjectType());
+    }
+
+    @Override
+    public Answer createVolume(CreateObjectCommand cmd) {
+        DataTO data = cmd.getData();
+        VolumeObjectTO volume = (VolumeObjectTO) data;
+        try {
+            /*
+             * public Boolean storagePluginCreate(String uuid, String ssuuid,
+             * String
+             * host, String file, Integer size)
+             */
+            String poolUuid = data.getDataStore().getUuid();
+            String storeUrl = data.getDataStore().getUrl();
+            URI uri = new URI(storeUrl);
+            String host = uri.getHost();
+            String file = this._ovmRepo + "/" + _ovmObject.deDash(poolUuid)
+                    + "/VirtualDisks/"
+                    + volume.getUuid() + ".raw";
+            Long size = volume.getSize();
+            StoragePlugin sp = new StoragePlugin(c);
+            sp.storagePluginCreate(poolUuid, host, file, size);
+            sp.storagePluginGetFileInfo(file);
+            VolumeObjectTO newVol = new VolumeObjectTO();
+            newVol.setName(volume.getName());
+            newVol.setSize(sp.getFileSize());
+            newVol.setPath(file);
+            return new CreateObjectAnswer(newVol);
+        } catch (Exception e) {
+            s_logger.debug("create volume failed: " + e.toString());
+            return new CreateObjectAnswer(e.toString());
+        }
+    }
+
+    /* volumes are created on primary storage, ehm they should be ... */
+    @Override
+    public Answer attachVolume(AttachCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    /* stub */
+    @Override
+    public Answer dettachVolume(DettachCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    /* is it supported? */
+    @Override
+    public Answer createSnapshot(CreateObjectCommand cmd) {
+        /* createsnap, but should be implemented */
+        return new Answer(cmd);
+    }
+
+    @Override
+    public Answer deleteVolume(DeleteCommand cmd) {
+        /* storagePluginDestroy(String ssuuid, String file) */
+        DataTO data = cmd.getData();
+        VolumeObjectTO volume = (VolumeObjectTO) data;
+        try {
+            String poolUuid = data.getDataStore().getUuid();
+            /* needs the file attached too please... */
+            String file = volume.getPath();
+            if (file.endsWith("/")) {
+                file = volume.getPath() + "/" + volume.getUuid() + ".raw";
+            }
+            StoragePlugin sp = new StoragePlugin(c);
+            sp.storagePluginDestroy(poolUuid, file);
+            s_logger.debug("delete volume success: " + file);
+        } catch (Exception e) {
+            s_logger.debug("delete volume failed: " + e.toString());
+            return new CreateObjectAnswer(e.toString());
+        }
+        return new Answer(cmd);
+    }
+
+    /* copies it from secondary to primary ? */
+    @Override
+    public Answer createVolumeFromSnapshot(CopyCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    @Override
+    public Answer deleteSnapshot(DeleteCommand cmd) {
+        /* storagePluginDestroy(String ssuuid, String file) */
+        return new Answer(cmd);
+    }
+
+    @Override
+    public Answer introduceObject(IntroduceObjectCmd cmd) {
+        return new Answer(cmd, false, "not implememented yet");
+    }
+
+    @Override
+    public Answer forgetObject(ForgetObjectCmd cmd) {
+        return new Answer(cmd, false, "not implememented yet");
+    }
+
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/CloudStackPlugin.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/CloudStackPlugin.java
new file mode 100644
index 0000000..94275f4
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/CloudStackPlugin.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Licensed 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 com.cloud.hypervisor.ovm3.object;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.xmlrpc.XmlRpcException;
+
+public class CloudStackPlugin extends OvmObject {
+
+    public CloudStackPlugin(Connection c) {
+        client = c;
+    }
+
+    public String getVncPort(String vmName) throws XmlRpcException {
+        String x = (String) callWrapper("get_vncport", vmName);
+        return x;
+    }
+
+    public boolean ovsUploadSshKey(String key, String content)
+            throws XmlRpcException {
+        Object x = callWrapper("ovs_upload_ssh_key", key, content);
+        if (x==null) {
+            return false;
+        }
+        return true;
+    }
+
+    public class ReturnCode {
+        private Map<String, Object> _rc = new HashMap<String, Object>() {
+            {
+                put("rc", null);
+                put("exit", null);
+                put("err", null);
+                put("out", null);
+            }
+        };
+        public void setValues(Map<String, String> m) {
+            this._rc.putAll(m);
+        }
+        public Boolean getRc() {
+            try {
+                Long rc = (Long) _rc.get("rc");
+                _rc.put("exit", rc);
+                if (rc != 0)
+                    return false;
+                return true;
+            } catch (Exception e) {
+
+            }
+            return false;
+        }
+        public String getStdOut() {
+            return (String) _rc.get("out");
+        }
+        public String getStdErr() {
+            return (String) _rc.get("err");
+        }
+        public Integer getExit() {
+            if (_rc.get("exit") == null)
+                _rc.put("exit", _rc.get("rc"));
+            return Integer.valueOf((String) _rc.get("exit"));
+        }
+    }
+    public ReturnCode domrExec(String ip, String cmd) throws XmlRpcException {
+        ReturnCode rc = new ReturnCode();
+        rc.setValues((Map<String, String>) callWrapper("exec_domr", ip, cmd));
+        return rc;
+    }
+
+    public boolean domrCheckPort(String ip, Integer port, Integer retries, Integer interval)
+                throws XmlRpcException, InterruptedException {
+        Boolean x= false;
+        /* should deduct the interval from the timeout and sleep on it */
+        Integer sleep=interval;
+        while(x == false && retries > 0) {
+            x = (Boolean) callWrapper("check_domr_port", ip, port, interval);
+            retries--;
+            Thread.sleep(sleep * 1000);
+        }
+        return x;
+    }
+
+    public Map<String, String> ovsDom0Stats(String bridge) throws XmlRpcException {
+        Map<String, String> stats  = (Map<String, String>)
+                callWrapper("ovs_dom0_stats", bridge);
+        return stats;
+    }
+
+
+    public Map<String, String> ovsDomUStats(String domain) throws XmlRpcException {
+        Map<String, String> stats  = (Map<String, String>)
+                callWrapper("ovs_domU_stats", domain);
+        return stats;
+    }
+    public boolean domrCheckPort(String ip, Integer port) throws XmlRpcException {
+        Object x = callWrapper("check_domr_port", ip, port);
+        return (Boolean) x;
+    }
+
+    public boolean domrCheckSsh(String ip) throws XmlRpcException {
+        Object x = callWrapper("check_domr_ssh", ip);
+        return (Boolean) x;
+    }
+
+    public boolean ovsControlInterface(String dev, String ipmask) throws XmlRpcException {
+        Object x = callWrapper("ovs_control_interface", dev, ipmask);
+        return (Boolean) x;
+    }
+
+    public boolean ping(String host) throws XmlRpcException {
+        Object x = callWrapper("ping", host);
+        return (Boolean) x;
+    }
+
+    public boolean ovsCheckFile(String file) throws XmlRpcException {
+        Object x = callWrapper("ovs_check_file", file);
+        return (Boolean) x;
+    }
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Cluster.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Cluster.java
new file mode 100644
index 0000000..703f8a2
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Cluster.java
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * Licensed 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 com.cloud.hypervisor.ovm3.object;
+
+import org.apache.xmlrpc.XmlRpcException;
+
+/*
+ * should become an interface implementation
+ */
+public class Cluster extends OvmObject {
+
+    public Cluster(Connection c) {
+        client = c;
+    }
+
+    /*
+     * leave_cluster, <class 'agent.api.cluster.o2cb.ClusterO2CB'> argument:
+     * self - default: None argument: poolfsUuid - default: None
+     */
+    public Boolean leaveCluster(String poolfsUuid) throws XmlRpcException {
+        Object x = callWrapper("leave_cluster", poolfsUuid);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * configure_server_for_cluster, <class
+     * 'agent.api.cluster.o2cb.ClusterO2CB'> argument: self - default: None <( ?
+     * argument: o2cb_conf - default: None <( ? argument: clusterConf -
+     * default: None <( ? argument: poolfs_type - default: None argument:
+     * poolfs_target - default: None argument: poolfsUuid - default: None
+     * argument: poolfs_nfsbase_uuid - default: None
+     */
+    public Boolean configureServerForCluster(String poolfsUuid)
+            throws XmlRpcException {
+        Object x = callWrapper("configure_server_for_cluster", poolfsUuid);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * deconfigure_server_for_cluster, <class
+     * 'agent.api.cluster.o2cb.ClusterO2CB'> argument: self - default: None
+     * argument: poolfsUuid - default: None
+     */
+    public Boolean deconfigureServerForCluster(String poolfsUuid)
+            throws XmlRpcException {
+        Object x = callWrapper("deconfigure_server_for_cluster", poolfsUuid);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * join_cluster, <class 'agent.api.cluster.o2cb.ClusterO2CB'> argument: self
+     * - default: None argument: poolfsUuid - default: None
+     */
+    public Boolean joinCLuster(String poolfsUuid) throws XmlRpcException {
+        Object x = callWrapper("join_cluster", poolfsUuid);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * discover_cluster, <class 'agent.api.cluster.o2cb.ClusterO2CB'> argument:
+     * self - default: None
+     */
+    /*
+     * <Discover_Cluster_Result>< <O2CB_Config>
+     * <O2CB_HEARTBEAT_THRESHOLD>61</O2CB_HEARTBEAT_THRESHOLD>
+     * <O2CB_RECONNECT_DELAY_MS>2000</O2CB_RECONNECT_DELAY_MS>
+     * <O2CB_KEEPALIVE_DELAY_MS>2000</O2CB_KEEPALIVE_DELAY_MS>
+     * <O2CB_BOOTCLUSTER>ba9aaf00ae5e2d73</O2CB_BOOTCLUSTER>
+     * <O2CB_IDLE_TIMEOUT_MS>60000</O2CB_IDLE_TIMEOUT_MS>
+     * <O2CB_ENABLED>true</O2CB_ENABLED> <O2CB_STACK>o2cb</O2CB_STACK>
+     * </O2CB_Config> <Cluster_Information> <Stored> <Clusters> <Cluster>
+     * <Name>ba9aaf00ae5e2d73</Name> <Node_Count>1</Node_Count>
+     * <Heartbeat_Mode>global</Heartbeat_Mode> </Cluster> </Clusters>
+     * <Heartbeats> <Heartbeat>
+     * <Region>0004FB0000050000E70FBDDEB802208F</Region>
+     * <Cluster>ba9aaf00ae5e2d73</Cluster> </Heartbeat> </Heartbeats> <Nodes>
+     * <Node> <Number>0</Number> <IP_Port>7777</IP_Port>
+     * <IP_Address>192.168.1.64</IP_Address> <Name>ovm-1</Name>
+     * <Cluster_Name>ba9aaf00ae5e2d73</Cluster_Name> </Node> </Nodes> </Stored>
+     * </Cluster_Information> </Discover_Cluster_Result>
+     */
+    /* returns xml - sigh */
+    public Boolean discoverCluster() throws XmlRpcException {
+        Object x = callWrapper("discover_cluster");
+        // System.out.println(x);
+
+        return false;
+    }
+
+    /*
+     * update_clusterConfiguration, <class
+     * 'agent.api.cluster.o2cb.ClusterO2CB'> argument: self - default: None
+     * argument: cluster_conf - default: None <( ? cluster_conf can be a "dict"
+     * or a plain file: print master.update_clusterConfiguration(
+     * "heartbeat:\n\tregion = 0004FB0000050000E70FBDDEB802208F\n\tcluster = ba9aaf00ae5e2d72\n\nnode:\n\tip_port = 7777\n\tip_address = 192.168.1.64\n\tnumber = 0\n\tname = ovm-1\n\tcluster = ba9aaf00ae5e2d72\n\nnode:\n\tip_port = 7777\n\tip_address = 192.168.1.65\n\tnumber = 1\n\tname = ovm-2\n\tcluster = ba9aaf00ae5e2d72\n\ncluster:\n\tnode_count = 2\n\theartbeat_mode = global\n\tname = ba9aaf00ae5e2d72\n"
+     * )
+     */
+    public Boolean updateClusterConfiguration(String clusterConf)
+            throws XmlRpcException {
+        Object x = callWrapper("update_clusterConfiguration", clusterConf);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * destroy_cluster, <class 'agent.api.cluster.o2cb.ClusterO2CB'> argument:
+     * self - default: None argument: poolfsUuid - default: None
+     */
+    public Boolean destroyCluster(String poolfsUuid) throws XmlRpcException {
+        Object x = callWrapper("destroy_cluster", poolfsUuid);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * is_cluster_online, <class 'agent.api.cluster.o2cb.ClusterO2CB'> argument:
+     * self - default: None
+     */
+    public Boolean isClusterOnline() throws XmlRpcException {
+        Object x = callWrapper("is_cluster_online");
+        return Boolean.valueOf(x.toString());
+    }
+
+    /*
+     * create_cluster, <class 'agent.api.cluster.o2cb.ClusterO2CB'> argument:
+     * self - default: None argument: poolfsUuid - default: None
+     */
+    public Boolean createCluster(String poolfsUuid) throws XmlRpcException {
+        Object x = callWrapper("create_cluster", poolfsUuid);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Common.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Common.java
new file mode 100644
index 0000000..ca24748
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Common.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Licensed 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 com.cloud.hypervisor.ovm3.object;
+
+import org.apache.xmlrpc.XmlRpcException;
+
+/*
+ * should become an interface implementation
+ */
+public class Common extends OvmObject {
+    public String apiVersion;
+
+    public Common(Connection c) {
+        client = c;
+    }
+
+    /*
+     * get_api_version, <class 'agent.api.common.Common'>
+     */
+    public String getApiVersion() throws XmlRpcException {
+        return callString("get_api_version");
+
+    }
+
+    /*
+     * sleep, <class 'agent.api.common.Common'> argument: secs - default: None
+     */
+    public String sleep(int seconds) throws XmlRpcException {
+        return callString("sleep", seconds);
+    }
+
+    /*
+     * dispatch, <class 'agent.api.common.Common'> argument: uri - default: None
+     * argument: func - default: None
+     */
+    /*
+     * normally used to push commands to other hosts in a cluster: *
+     * dispatch function join_server_pool
+     * to server https://oracle:******@192.168.1.67:8899/api/3/
+     */
+    public <T> String dispatch(String url, String function, T... args)
+            throws XmlRpcException {
+        return callString("dispatch", url, function, args);
+    }
+
+    /*
+     * echo, <class 'agent.api.common.Common'> argument: msg - default: None
+     */
+    public String echo(String msg) throws XmlRpcException {
+        return callString("echo", msg);
+    }
+
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Connection.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Connection.java
new file mode 100644
index 0000000..53a8e10
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Connection.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Licensed 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 com.cloud.hypervisor.ovm3.object;
+import java.net.URL;
+import java.util.TimeZone;
+import java.util.Vector;
+
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+import org.apache.xmlrpc.client.TimingOutCallback;
+import org.apache.xmlrpc.client.XmlRpcClient;
+import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
+
+public class Connection extends XmlRpcClient {
+    private static final Logger s_logger = Logger.getLogger(Connection.class);
+    private final XmlRpcClientConfigImpl _config = new XmlRpcClientConfigImpl();
+    private XmlRpcClient _client;
+    private String _username;
+    private String _password;
+    private String _ip;
+    private Integer _port = 8898;
+    private Boolean _isSsl = false;
+    private String cert = "";
+    private String key = "";
+    private Integer timeout = 1200; /* seconds */
+    private Integer _timeout = timeout * 1000; /* native is ms */
+
+    private XmlRpcClient getXmlClient() throws XmlRpcException {
+        // check ssl boolean
+        final XmlRpcClient client = new XmlRpcClient();
+
+        URL url;
+        try {
+            // here too
+            url = new URL("http://" + _ip + ":" + _port.toString());
+            _config.setTimeZone(TimeZone.getTimeZone("UTC"));
+            _config.setServerURL(url);
+            _config.setReplyTimeout(0); // disable, we use asyncexecute to
+                                        // control timeout
+            _config.setConnectionTimeout(60000);
+            _config.setReplyTimeout(60 * 15000);
+            _config.setBasicUserName(_username);
+            _config.setBasicPassword(_password);
+            _config.setXmlRpcServer(null);
+            // _config.setEnabledForExtensions(true);
+            client.setConfig(_config);
+            client.setTypeFactory(new RpcTypeFactory(client));
+        } catch (Throwable e) {
+            throw new XmlRpcException(e.getMessage());
+        }
+        return client;
+    }
+
+    public Connection(String ip, Integer port, String username, String password)
+            throws XmlRpcException {
+        _ip = ip;
+        _port = port;
+        _username = username;
+        _password = password;
+        _client = getXmlClient();
+    }
+
+    public Connection(String ip, String username, String password)
+            throws XmlRpcException {
+        _ip = ip;
+        _username = username;
+        _password = password;
+        _client = getXmlClient();
+    }
+
+    public Object call(String method, Vector<?> params) throws XmlRpcException {
+        /* default timeout is 10 mins */
+        return callTimeoutInSec(method, params, this._timeout);
+    }
+
+    public Object call(String method, Vector<?> params, boolean debug)
+            throws XmlRpcException {
+        /* default timeout is 10 mins */
+        return callTimeoutInSec(method, params, this._timeout, debug);
+    }
+
+    public Object callTimeoutInSec(String method, Vector<?> params,
+            int timeout, boolean debug) throws XmlRpcException {
+        TimingOutCallback callback = new TimingOutCallback(timeout * 1000);
+        if (debug) {
+            /*
+             * some parameters including user password should not be printed in
+             * log
+             */
+            s_logger.debug("Call Ovm3 agent: " + method + " with " + params);
+        }
+
+        long startTime = System.currentTimeMillis();
+        _client.executeAsync(method, params, callback);
+        try {
+            return callback.waitForResponse();
+        } catch (TimingOutCallback.TimeoutException to) {
+            throw to;
+        } catch (Throwable e) {
+            throw new XmlRpcException(-2, e.getMessage());
+        } finally {
+            long endTime = System.currentTimeMillis();
+            float during = (endTime - startTime) / 1000; // in secs
+            s_logger.debug("Ovm3 call " + method + " finished in " + during
+                    + " secs, on " + _ip + ":" + _port);
+        }
+    }
+
+    public Object callTimeoutInSec(String method, Vector<?> params, int timeout)
+            throws XmlRpcException {
+        return callTimeoutInSec(method, params, timeout, true);
+    }
+
+    public String getIp() {
+        return _ip;
+    }
+
+    public Integer getPort() {
+        return _port;
+    }
+
+    public String getUserName() {
+        return _username;
+    }
+
+    public String getPassword() {
+        return _password;
+    }
+
+    public Boolean getIsSsl() {
+        return _isSsl;
+    }
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Linux.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Linux.java
new file mode 100644
index 0000000..3be9feb
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Linux.java
@@ -0,0 +1,612 @@
+/*******************************************************************************
+ * Licensed 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 com.cloud.hypervisor.ovm3.object;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.w3c.dom.Document;
+
+/*
+ * should become an interface implementation
+ */
+public class Linux extends OvmObject {
+    private Integer _init = 0;
+
+    /*
+     * use capabilities to match things later, perhaps also hardware discovery ?
+     * wrap getters and setters.... for Mapps...
+     */
+    public Map<String, String> Capabilities = new HashMap<String, String>();
+    /*
+     * MAX_CONCURRENT_MIGRATION_IN=1, ALL_VM_CPU_OVERSUBSCRIBE=True,
+     * HIGH_AVAILABILITY=True, LOCAL_STORAGE_ELEMENT=True, NFS=True,
+     * MTU_CONFIGURATION=True, CONCURRENT_MIGRATION=False,
+     * VM_MEMORY_ALIGNMENT=1048576, CLUSTERS=True, VM_SUSPEND=True,
+     * BOND_MODE_LINK_AGGREGATION=True, YUM_PACKAGE_MANAGEMENT=True,
+     * VM_VNC_CONSOLE=True, BOND_MODE_ACTIVE_BACKUP=True,
+     * MAX_CONCURRENT_MIGRATION_OUT=1, MIGRATION_SETUP=False,
+     * PER_VM_CPU_OVERSUBSCRIBE=True, POWER_ON_WOL=True, FIBRE_CHANNEL=True,
+     * ISCSI=True, HVM_MAX_VNICS=8}
+     */
+    public Map<String, String> VMM = new HashMap<String, String>();
+    public Map<String, String> VMMc = new HashMap<String, String>();
+    public Map<String, String> NTP = new HashMap<String, String>();
+    public Map<String, String> DateTime = new HashMap<String, String>();
+    public Map<String, String> Generic = new HashMap<String, String>();
+    /*
+     * {OS_Major_Version=5, Statistic=20, Membership_State=Unowned,
+     * OVM_Version=3.2.1-517, OS_Type=Linux, Hypervisor_Name=Xen,
+     * CPU_Type=x86_64, Manager_Core_API_Version=3.2.1.516,
+     * Is_Current_Master=false, OS_Name=Oracle VM Server,
+     * Server_Roles=xen,utility, Pool_Unique_Id=none,
+     * Host_Kernel_Release=2.6.39-300.22.2.el5uek, OS_Minor_Version=7,
+     * Agent_Version=3.2.1-183, Boot_Time=1392366638, RPM_Version=3.2.1-183,
+     * Exports=, Hypervisor_Type=xen, Host_Kernel_Version=#1 SMP Fri Jan 4
+     * 12:40:29 PST 2013,
+     * Unique_Id=1d:d5:e8:91:d9:d0:ed:bd:81:c2:a6:9a:b3:d1:b7:ea,
+     * Manager_Unique_Id=none, Cluster_State=Offline, Hostname=ovm-1}
+     */
+    public Map<String, String> hwVMM = new HashMap<String, String>();
+    public Map<String, String> hwSystem = new HashMap<String, String>();
+    public int localTime;
+    public int lastBootTime;
+    public String timeZone;
+    public String timeUTC;
+    public List<String> _mounts = null;
+
+    // public Map<String, Map> Settings = new HashMap<String, Map>();
+
+    public Linux(Connection c) {
+        client = c;
+    }
+
+    /*
+     * discover_server, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None
+     */
+    public Boolean discoverServer() throws Exception {
+        String cmd = "discover_server";
+        Object result = callWrapper(cmd);
+        if (result == null) {
+            return false;
+        }
+
+        Document xmlDocument = prepParse((String) result);
+        /* System.out.println(result); */
+        /* could be more subtle */
+        String path = "//Discover_Server_Result/Server";
+        Capabilities = xmlToMap(path + "/Capabilities", xmlDocument);
+        VMM = xmlToMap(path + "/VMM/Version", xmlDocument);
+        VMMc = xmlToMap(path + "/VMM", xmlDocument);
+        NTP = xmlToMap(path + "/NTP", xmlDocument);
+        DateTime = xmlToMap(path + "/Date_Time", xmlDocument);
+        Generic = xmlToMap(path, xmlDocument);
+
+        // System.out.println(Get("Agent_Version"));
+
+        // System.out.println(Generic.toString());
+        return true;
+    }
+
+    public String getAgentVersion() throws ParserConfigurationException, IOException, Exception {
+        return this.Get("Agent_Version");
+    }
+    public String getHostKernelRelease() throws ParserConfigurationException, IOException, Exception {
+        return this.Get("Host_Kernel_Release");
+    }
+    public String getHostOs() throws ParserConfigurationException, IOException,
+            Exception {
+        return this.Get("OS_Name");
+    }
+    public String getHostOsVersion() throws ParserConfigurationException,
+            IOException, Exception {
+        String ver = this.Get("OS_Major_Version") + "."
+                + this.Get("OS_Minor_Version");
+        return ver;
+    }
+    public String getHypervisorName() throws ParserConfigurationException, IOException, Exception {
+        return this.Get("Hypervisor_Name");
+    }
+    public String getHypervisorVersion() throws ParserConfigurationException, IOException, Exception {
+        String ver = this.getHypervisorMajor() + "."
+                + this.getHypervisorMinor() + "." + this.getHypervisorExtra();
+        return ver;
+    }
+    public String getCapabilities() throws ParserConfigurationException,
+            IOException, Exception {
+        return this.Get("Capabilities");
+    }
+    public String getHypervisorMajor() throws ParserConfigurationException, IOException, Exception {
+        return this.Get("Major");
+    }
+    public String getHypervisorMinor() throws ParserConfigurationException, IOException, Exception {
+        return this.Get("Minor");
+    }
+    public String getHypervisorExtra() throws ParserConfigurationException,
+            IOException, Exception {
+        return this.Get("Extra").replace(".", "");
+    }
+    public String getManagerUuid() throws ParserConfigurationException, IOException, Exception {
+        return this.Get("Manager_Unique_Id");
+    }
+
+    public String getMembershipState() throws ParserConfigurationException,
+            IOException, Exception {
+        return this.Get("Membership_State");
+    }
+
+    public String getServerRoles() throws ParserConfigurationException,
+            IOException, Exception {
+        return this.Get("Server_Roles");
+    }
+    public boolean getIsMaster() throws ParserConfigurationException,
+            IOException, Exception {
+        return Boolean.parseBoolean(this.Get("Is_Current_Master"));
+    }
+    public String getOvmVersion() throws ParserConfigurationException, IOException, Exception {
+        return this.Get("OVM_Version");
+    }
+    public String getHostName() throws ParserConfigurationException, IOException, Exception {
+        return this.Get("Hostname");
+    }
+    public Integer getCpuKhz() throws NumberFormatException, ParserConfigurationException, IOException, Exception {
+        return Integer.valueOf(this.Get("CPUKHz"));
+    }
+    public Integer getCpuSockets() throws NumberFormatException, ParserConfigurationException, IOException, Exception {
+        return Integer.valueOf(this.Get("SocketsPerNode"));
+    }
+    public Integer getCpuThreads() throws NumberFormatException, ParserConfigurationException, IOException, Exception {
+        return Integer.valueOf(this.Get("ThreadsPerCore"));
+    }
+    public Integer getCpuCores() throws NumberFormatException, ParserConfigurationException, IOException, Exception {
+        return Integer.valueOf(this.Get("CoresPerSocket"));
+    }
+    public Integer getTotalThreads() throws NumberFormatException, ParserConfigurationException, IOException, Exception {
+        return this.getCpuSockets() * this.getCpuCores() * this.getCpuThreads();
+    }
+
+    public Double getMemory() throws NumberFormatException,
+            ParserConfigurationException, IOException, Exception {
+        return Double.valueOf(this.Get("TotalPages")) * 4096;
+    }
+
+    public Double getFreeMemory() throws NumberFormatException,
+            ParserConfigurationException, IOException, Exception {
+        return Double.valueOf(this.Get("FreePages")) * 4096;
+    }
+    public String getUuid() throws NumberFormatException,
+            ParserConfigurationException, IOException, Exception {
+        return this.Get("Unique_Id");
+    }
+
+    public String Get(String element) throws ParserConfigurationException, IOException, Exception {
+        if (this._init == 0) {
+            this.discoverHardware();
+            this.discoverServer();
+            this._init = 1;
+        }
+        if (Generic.containsKey(element))
+            return Generic.get(element);
+        if (VMMc.containsKey(element))
+            return VMMc.get(element);
+        if (VMM.containsKey(element))
+            return VMM.get(element);
+        if (hwVMM.containsKey(element))
+            return hwVMM.get(element);
+        if (hwSystem.containsKey(element))
+            return hwSystem.get(element);
+        if (Capabilities.containsKey(element))
+            return Capabilities.get(element);
+        return "";
+    }
+
+    /*
+     * unexport_fs, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None argument: export_uuid - default: None
+     */
+
+    /*
+     * get_last_boot_time, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None
+     */
+    public Integer getLastBootTime() throws XmlRpcException {
+        HashMap<String, Long> result = callMap("get_last_boot_time");
+        if (result == null)
+            return null;
+        this.lastBootTime = result.get("last_boot_time").intValue();
+        this.localTime = result.get("local_time").intValue();
+        return lastBootTime;
+    }
+
+    /*
+     * delete_yum_repo, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None argument: repo_id - default: None
+     */
+
+    /*
+     * notify_manager, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None argument: notification - default: None argument: data -
+     * default: None
+     */
+
+    /*
+     * update_core_api_bindings, <class 'agent.api.host.linux.Linux'> argument:
+     * self - default: None argument: url - default: None argument: option -
+     * default: None
+     */
+
+    /*
+     * set_datetime, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None argument: year - default: None argument: month - default:
+     * None argument: day - default: None argument: hour - default: None
+     * argument: min - default: None argument: sec - default: None
+     */
+    public Boolean setDateTime(int year, int month, int day, int hour, int min,
+            int sec) throws XmlRpcException {
+        Object x = callWrapper("set_datetime", year, month, day, hour, min, sec);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * list_package, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None argument: name - default: None
+     */
+
+    /*
+     * discover_physical_luns, <class 'agent.api.host.linux.Linux'> argument:
+     * self - default: None argument: args - default: None
+     */
+    public String discoverPhysicalLuns() throws XmlRpcException {
+        String x = (String) callWrapper("discover_physical_luns", "");
+        return x;
+    }
+
+    /*
+     * ovs_download_file, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None argument: url - default: None argument: filename - default:
+     * None argument: option - default: None argument: obj - default: None
+     * argument: obj_current - default: None argument: obj_total - default: None
+     * argument: update_period - default: None
+     */
+
+    /*
+     * install_package, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None argument: pkg_data - default: None argument: option -
+     * default: None
+     */
+
+    /*
+     * get_support_files, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None
+     */
+
+    /*
+     * export_fs, <class 'agent.api.host.linux.Linux'> argument: self - default:
+     * None argument: export_uuid - default: None argument: export_type -
+     * default: None argument: client - default: None argument: path - default:
+     * None argument: options - default: None
+     */
+
+    /*
+     * ovs_async_proc_status, <class 'agent.api.host.linux.Linux'> argument:
+     * self - default: None argument: pid - default: None
+     */
+
+    /*
+     * set_timezone, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None argument: timezone - default: None argument: utc - default:
+     * None
+     */
+    public Boolean setTimeZone(String tz, Boolean utc) throws XmlRpcException {
+        Object x = callWrapper("set_timezone", tz, utc);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * copy_file, <class 'agent.api.host.linux.Linux'> argument: self - default:
+     * None argument: src - default: None argument: dst - default: None
+     * argument: sparse - default: None argument: update_period - default: None
+     */
+    public Boolean copyFile(String src, String dst) throws XmlRpcException {
+        Object x = callWrapper("copy_file", src, dst, false);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    public Boolean copyFile(String src, String dst, Boolean sparse)
+            throws XmlRpcException {
+        Object x = callWrapper("copy_file", src, dst, sparse);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * discover_mounted_file_systems, <class 'agent.api.host.linux.Linux'>
+     * argument: self - default: None argument: args - default: None
+     */
+    /*
+     * <Discover_Mounted_File_Systems_Result> <Filesystem Type="nfs"> <Mount
+     * Dir="/nfsmnt/e080e318-91c2-47e5-a5ab-f3ab53790162">
+     * <Device>cs-mgmt:/volumes/cs-data/secondary/</Device>
+     * <Mount_Options>rw,relatime
+     * ,vers=3,rsize=524288,wsize=524288,namlen=255,hard
+     * ,proto=tcp,port=65535,timeo
+     * =600,retrans=2,sec=sys,local_lock=none,addr=192.168.1.61</Mount_Options>
+     * </Mount> </Filesystem> ... </Discover_Mounted_File_Systems_Result>
+     */
+
+    public Boolean discoverMountedFs() throws XmlRpcException {
+        Object x = callWrapper("discover_mounted_file_systems");
+        // System.out.println(x);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /* Filesystem bits and bobs */
+    private Map<String, FileSystem> fsList = null;
+
+    public Map<String, FileSystem> getFileSystemList(String type)
+            throws ParserConfigurationException, IOException, Exception {
+        if (fsList == null)
+            this.discoverMountedFs(type);
+
+        return fsList;
+    }
+
+    public void setFileSystemList(Map<String, FileSystem> list) {
+        fsList = list;
+    }
+    public class FileSystem {
+        public Map<String, Object> _fs = new HashMap<String, Object>() {
+            {
+                put("Mount_Options", null);
+                put("Name", null);
+                put("Device", null);
+                put("Host", null);
+                put("Dir", null);
+                put("Mount_Point", null);
+                put("Uuid", null);
+            }
+        };
+
+        public String getUuid() {
+            return (String) _fs.get("Uuid");
+        }
+
+        public String setUuid(String uuid) {
+            return (String) _fs.put("Uuid", uuid);
+        }
+        public String getName() {
+            return (String) _fs.get("Name");
+        }
+
+        public String setName(String name) {
+                return (String) _fs.put("Name", name);
+        }
+
+        public String getDevice() {
+                return (String) _fs.get("Device");
+        }
+
+        public String setDevice(String dev) {
+                return (String) _fs.put("Device", dev);
+        }
+
+        public String getHost() {
+                if (getDevice() != null && getDevice().contains(":")) {
+                    String spl[] = getDevice().split(":");
+                    setHost(spl[0]);
+                    setMountPoint(spl[1]);
+                } else {
+                    return null;
+                }
+                return (String) _fs.get("Host");
+        }
+
+        public String setHost(String host) {
+                return (String) _fs.put("Host", host);
+        }
+
+        public String getDir() {
+                return (String) _fs.get("Dir");
+        }
+
+        public String setDir(String dir) {
+            return (String) _fs.put("Dir", dir);
+        }
+
+        public String getMountPoint() {
+            if (getHost() != null) {
+                return (String) _fs.get("Mount_Point");
+            }
+            return null;
+        }
+        public String setMountPoint(String pnt) {
+            return (String) _fs.put("Mount_Point", pnt);
+        }
+    };
+
+    /* should actually be called "getMountedsFsDevice" or something */
+    public Map<String, FileSystem> discoverMountedFs(String type)
+            throws ParserConfigurationException, IOException, Exception {
+        // if (postDiscovery == null) {
+        //    postDiscovery = callWrapper("discover_network");
+        this.fsList = new HashMap<String, FileSystem>();
+        //}
+        Object x = callWrapper("discover_mounted_file_systems", type);
+        Document xmlDocument = prepParse((String) x);
+        // List<String> list = new ArrayList<String>();
+        String bpath = "//Discover_Mounted_File_Systems_Result/Filesystem";
+        String mpath = bpath + "/Mount/@Dir";
+        _mounts = xmlToList(mpath, xmlDocument);
+        for (String mnt : _mounts) {
+            String dpath = bpath + "/Mount[@Dir='" + mnt + "']";
+            Map<String, Object> fs = xmlToMap(dpath, xmlDocument);
+            FileSystem f = new FileSystem();
+            f._fs = fs;
+            String[] spl = mnt.split("/");
+            String uuid = spl[spl.length - 1];
+            // System.out.println(uuid + " " + mnt);
+            f.setUuid(uuid);
+            f.setDir(mnt);
+            fsList.put(uuid, f);
+        }
+        setFileSystemList(fsList);
+        if (x == null) {
+            return this.fsList;
+        }
+
+        return this.fsList;
+    }
+
+    /*
+     * ovs_async_proc, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None argument: func - default: None
+     */
+
+    /*
+     * get_log, <class 'agent.api.host.linux.Linux'> argument: self - default:
+     * None argument: loglist - default: None
+     */
+
+    /*
+     * update_agent_password, <class 'agent.api.host.linux.Linux'> argument:
+     * self - default: None argument: username - default: None argument:
+     * password - default: None
+     */
+    public Boolean updateAgentPassword(String user, String pass)
+            throws XmlRpcException {
+        Object x = callWrapper("update_agent_password", user, pass);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * yum_update, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None argument: option - default: None
+     */
+
+    /*
+     * discover_hardware, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None
+     */
+    public Boolean discoverHardware()
+            throws ParserConfigurationException, IOException, Exception {
+        Object result = callWrapper("discover_hardware");
+
+        Document xmlDocument = prepParse((String) result);
+        /* could be more subtle */
+        String path = "//Discover_Hardware_Result/NodeInformation";
+        hwVMM = xmlToMap(path + "/VMM/PhysicalInfo", xmlDocument);
+        hwSystem = xmlToMap(path + "/DMTF/System", xmlDocument);
+
+        if (result == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * uninstall_package, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None argument: pkg_list - default: None argument: option -
+     * default: None
+     */
+
+    /*
+     * get_datetime, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None
+     */
+    public Integer getDateTime() throws XmlRpcException {
+        this.getLastBootTime();
+        return this.localTime;
+    }
+
+    /*
+     * configure_yum, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None argument: section - default: None argument: params -
+     * default: None
+     */
+
+    /*
+     * get_yum_config, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None
+     */
+    public Boolean getYumConfig() throws XmlRpcException {
+        Object x = callWrapper("get_yum_config");
+        // System.out.println(x);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * ovs_async_proc_stop, <class 'agent.api.host.linux.Linux'> argument: self
+     * - default: None argument: pid - default: None
+     */
+
+    /*
+     * set_statistic_interval, <class 'agent.api.host.linux.Linux'> argument:
+     * interval - default: None
+     */
+    public Boolean setStatisticsInterval(int val) throws XmlRpcException {
+        Object x = callWrapper("set_statistics_interval", val);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * yum_list_package, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None argument: pkgnarrow - default: None argument: patterns -
+     * default: None argument: showdups - default: None argument: ignore_case -
+     * default: None
+     */
+
+    /*
+     * get_timezone, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None
+     */
+    public Boolean getTimeZone() throws XmlRpcException {
+        Object[] result = (Object[]) callWrapper("get_timezone");
+        if (result != null) {
+            this.timeZone = result[0].toString();
+            this.timeUTC = result[1].toString();
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Network.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Network.java
new file mode 100644
index 0000000..0ae9d84
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Network.java
@@ -0,0 +1,628 @@
+/*******************************************************************************
+ * Licensed 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 com.cloud.hypervisor.ovm3.object;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+// import java.util.Map;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.w3c.dom.Document;
+// import java.util.HashMap;
+
+/*
+ * should become an interface implementation
+ */
+public class Network extends OvmObject {
+
+    public Network(Connection c) {
+        client = c;
+    }
+
+    private Map<String, Interface> interfaceList = null;
+
+    public Map<String, Interface> getInterfaceList()
+            throws ParserConfigurationException, IOException, Exception {
+        try {
+            this.discoverNetwork();
+        } catch (Exception e) {
+            throw new Exception(e.getMessage());
+        }
+        return interfaceList;
+    }
+
+    public void setBridgeList(Map<String, Interface> list) {
+        interfaceList = list;
+    }
+
+    public class Interface {
+        private Map<String, String> _interface = new HashMap<String, String>() {
+            {
+                put("Type", null);
+                put("Physical", null);
+                put("Name", null);
+                put("Address", null);
+                put("Broadcast", null);
+                put("MAC", null);
+                put("Vlan", null);
+            }
+        };
+
+        public void setIfType(String t) {
+            this._interface.put("Type", t);
+        }
+        public String getIfType() {
+            return this._interface.get("Type");
+        }
+        public void setInterface(Map<String, String> itf) {
+            this._interface.putAll(itf);
+        }
+
+        public String getName() {
+            return _interface.get("Name");
+        }
+
+        public String getPhysical() {
+            return _interface.get("Physical");
+        }
+
+        public String getAddress() {
+            return _interface.get("Address");
+        }
+
+        public String getBroadcast() {
+            return _interface.get("Broadcast");
+        }
+
+        public String getMac() {
+            return _interface.get("MAC");
+        }
+
+        public String setName(String name) {
+            return _interface.put("Name", name);
+        }
+
+        public String setPhysical(String ph) {
+            return _interface.put("Physical", ph);
+        }
+        public String setAddress(String addr) {
+            return _interface.put("Address", addr);
+        }
+
+        public String setBroadcast(String bcast) {
+            return _interface.put("Broadcast", bcast);
+        }
+
+        public String setMac(String mac) {
+            return _interface.put("MAC", mac);
+        }
+    }
+
+    private Network.Interface _getInterface(String key, String val)
+            throws ParserConfigurationException, IOException, Exception {
+        HashMap<String, Network.Interface> ifaces = new HashMap<String, Network.Interface>();
+        ifaces = (HashMap<String, Interface>) this.getInterfaceList();
+        for (final Entry<String, Interface> iface : ifaces.entrySet()) {
+            String match = "default";
+            if (key.equals("Address"))
+                match = iface.getValue().getAddress();
+            if (key.equals("Name"))
+                match = iface.getKey();
+            // .getName();
+            if (match != null && match.equals(val))
+                return iface.getValue();
+        }
+        return null;
+    }
+
+    public Network.Interface getInterfaceByIp(String ip)
+            throws ParserConfigurationException, IOException, Exception {
+        return _getInterface("Address", ip);
+    }
+
+    public Network.Interface getInterfaceByName(String name)
+            throws ParserConfigurationException, IOException, Exception {
+        return _getInterface("Name", name);
+    }
+    /* check if it is a BRIDGE */
+    public String getPhysicalByBridgeName(String name)
+            throws ParserConfigurationException, IOException, Exception {
+        return getInterfaceByName(name).getPhysical();
+    }
+
+    public Network.Interface getBridgeByName(String name)
+            throws ParserConfigurationException, IOException, Exception {
+        if (_getInterface("Name", name).getIfType().contentEquals("Bridge")) {
+              return _getInterface("Name", name);
+        }
+        return null;
+    }
+    public Network.Interface getBridgeByIp(String ip)
+            throws ParserConfigurationException, IOException, Exception {
+        if (_getInterface("Address", ip).getIfType().contentEquals("Bridge")) {
+              return _getInterface("Address", ip);
+        }
+        return null;
+    }
+    private Object postDiscovery = null;
+
+    private List<String> netInterfaces = new ArrayList<String>();
+
+    /*
+     * ovs_bond_mode, <class 'agent.api.network.linux_network.LinuxNetwork'>
+        Change Bond mode.
+
+        @param bond   One of the logical channel bonds (bond0, bond1 ...etc)
+        @mode         Current supported bonding modes (1 = active-backup, 4 = 802.3ad
+                      6 = balance-alb).
+        @return       If successful, returns bond's names and its new mode
+                      Raises an exception on failure
+        Restriction:
+        -bond     must be one of the logical channel bonds (bond0, bond1 ...etc)
+
+     */
+    public Boolean ovsBondMode(String bond, String mode) throws XmlRpcException {
+        Object x = callWrapper("ovs_bond_mode", bond, mode);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * ovs_change_mtu, <class 'agent.api.network.linux_network.LinuxNetwork'>
+        Changes MTU on a physical,vlan,bond,and bridge interface.
+        Changing a bond MTU will also change the MTU of its slaves.
+        Changing the MTU of an interface that is part of a bridge,
+        will cause the bridge MTU and all of the interfaces change.
+        When a Guest VIF attach to a bridge,the VIF MTU will be set
+        to the bridge MTU
+
+
+        @param   interface    Physical,bond,vlan, and a bridge
+        @param   MTU          Values are 1500 to 64000
+
+        @return  If successful, returns the interface, and the new MTU
+                 Raises an exception on failure
+
+        Restriction:
+        -Can not change the MTU of a bridge without interfaces.
+        -VLAN MTU must less or equal to the MTU of the underlying
+         physical interface.
+     */
+    public Boolean ovsChangeMtu(String net, int mtu) throws XmlRpcException {
+        Object x = callWrapper("ovs_change_mtu", net, mtu);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * ovs_async_bridge, <class 'agent.api.network.linux_network.LinuxNetwork'>
+     * argument: self - default: None argument: action - default: None argument:
+     * br_name - default: None argument: net_dev - default: None
+     */
+    public Boolean ovsAsyncBridge(String action, String bridge, String netdev)
+            throws XmlRpcException {
+        Object x = callWrapper("ovs_async_bridge", action, bridge, netdev);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * ovs_bond_op, <class 'agent.api.network.linux_network.LinuxNetwork'>
+     * argument: self - default: None argument: action - default: None argument:
+     * bond - default: None argument: backup - default: None
+     */
+    public Boolean ovsBondOp(String action, String bond, String backup)
+            throws XmlRpcException {
+        Object x = callWrapper("ovs_bond_op", action, bond, backup);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * configure_virtual_ip, <class
+     * 'agent.api.network.linux_network.LinuxNetwork'> argument: self - default:
+     * None argument: virtual_ip - default: None argument: base_ip - default:
+     * None
+     */
+    public Boolean configureVip(String vip, String baseip)
+            throws XmlRpcException {
+        Object x = callWrapper("configure_virtual_ip", vip, baseip);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * ovs_ip_config, <class 'agent.api.network.linux_network.LinuxNetwork'>
+        Assigns/flushes IP, netmask address to a physical,VLAN, and bond interfaces.
+
+        @param  interface    The interface on which to assign
+        @param  optype (static|dynamic|flush)
+            static:  Assigns the given IP, and netmask to the interface, and
+                         saves the config file to /etc/sysconfig/network-scripts.
+            dynamic: Flushes current address, and creats and save the config
+                         file to /etc/sysconfig/network-scripts, (BOOTPROTO=dhcp)
+            flush:   flushes the interface address,routes, removes the current
+                         config file from /etc/sysconfig/network-scripts.
+                         Creats a new one with BOOTPROTO=static
+
+        @args   Required for the static option, otherwise it is ignored
+            IP address:  IPv4 address in decimal notation (101.230.112)
+            netmask:     Standard netmask in a decimal notation,NOT CIDR.
+                             example(255.255.255.0)
+
+        @return  If successful, returns the interface, and addresses added/flushed
+                 Raises an exception on failure
+
+        Restriction:
+        -Interface must be physical, VLAN, or a Bond
+        -Interface must not be a bridge port, or slave to a bond
+        -Addresses must be valid in a decimal notation
+
+     */
+    public Boolean ovsIpConfig(String net, String optype, String ip,
+            String netmask)
+            throws XmlRpcException {
+        Object x = callWrapper("ovs_ip_config", net, optype, ip, netmask);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * ovs_if_meta, <class 'agent.api.network.linux_network.LinuxNetwork'>
+        This function creates meta data file meta-interface, and write the string
+        (METADATA=data) to it.  This string is used by the manager to identify
+        networks that interfaces belong to. Dom0 does not make used of this string,
+        it just saves it and returns it during running, saved network discovery.
+
+         - If an interface already has a meta data string, then it gets
+           replace by the new one
+         - An empty meta data string, indicates to remove the existing string
+           (remove the meta-interface) file
+
+        @param  interface    physical,VLAN, bond ...etc interfaces
+        @param  data         meta data to save
+
+        @return  If successful, returns the interface, and meta data
+                 Raises an exception on failure
+
+        Restriction:
+        - data string that starts with leading spaces will be rejected
+     * ovs_if_meta('bond0',
+     * 'ethernet:c0a80100{192.168.1.0}:MANAGEMENT,CLUSTER_HEARTBEAT,LIVE_MIGRATE,VIRTUAL_MACHINE,STORAGE')
+     */
+    public Boolean ovsIfMeta(String net, String data) throws XmlRpcException {
+        Object x = callWrapper("ovs_if_meta", net, data);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+
+    /*
+     * ovs_bond_config, <class 'agent.api.network.linux_network.LinuxNetwork'>
+     * argument: self - default: None argument: action - default: None argument:
+     * bond - default: None
+     */
+    public Boolean ovsBondConfig(String action, String bond)
+            throws XmlRpcException {
+        Object x = callWrapper("ovs_bond_config", action, bond);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * discover_network, <class 'agent.api.network.linux_network.LinuxNetwork'>
+        Discover information about the current network configuration.
+        This includes the state of physical NICs, bonds, and bridges.  Also return
+        information stored for this server that is needed to configure
+        the network when the OVM Manager is not available.
+
+        Discovery of the current network configuration is handled by invoking
+        a python extension that calls legacy C code from the VI agent.
+
+        @param None
+
+        @return    Returns the discovery data as an XML document.
+                   Raises an exception on failure.
+     * <?xml version="1.0" ?> <Discover_Network_Result>
+     * <Network><Active><Network> <Device Name="eth0">
+     * <MAC>52:54:00:24:47:70</MAC> <Flags>(0x1843) IFF_UP IFF_BROADCAST
+     * IFF_RUNNING IFF_SLAVE IFF_MULTICAST</Flags> <ETHTOOL> <Autonegotiate>
+     * <State>Complete</State> <Speed>1000baseT-FD</Speed> </Autonegotiate>
+     * <Link>ok</Link> <Capabilities>10baseT-HD 10baseT-FD 100baseT-HD
+     * 100baseT-FD 1000baseT-FD</Capabilities> <Advertising>10baseT-HD
+     * 10baseT-FD 100baseT-HD 100baseT-FD 1000baseT-FD</Advertising> </ETHTOOL>
+     * <WOL> <WakeOnLan>disabled</WakeOnLan> </WOL> <SysFS>
+     * <uevent>INTERFACE=eth0 IFINDEX=2</uevent>
+     * <addr_assign_type>0</addr_assign_type> <addr_len>6</addr_len>
+     * <dev_id>0x0</dev_id> <ifalias/> <iflink>2</iflink> <ifindex>2</ifindex>
+     * <features>0x40014ba9</features> <type>1</type> <link_mode>0</link_mode>
+     * <carrier>1</carrier> <speed>1000</speed> <duplex>full</duplex>
+     * <dormant>0</dormant> <operstate>up</operstate> <mtu>1500</mtu>
+     * <flags>0x1903</flags> <tx_queue_len>1000</tx_queue_len>
+     * <netdev_group>0</netdev_group> <SysFSDev> <vendor>0x8086</vendor>
+     * <device>0x100e</device> <subsystem_vendor>0x1af4</subsystem_vendor>
+     * <subsystem_device>0x1100</subsystem_device> <class>0x020000</class>
+     * </SysFSDev> </SysFS> <BootProto>none</BootProto> </Device> ....
+     * </Network> <Bonding> <Device Name="bond0">
+     * <Bonding_Mode>active-backup</Bonding_Mode> <Primary_Slave>eth0
+     * (primary_reselect always)</Primary_Slave>
+     * <Currently_Active_Slave>eth0</Currently_Active_Slave>
+     * <MII_Status>up</MII_Status>
+     * <MII_Polling_Interval>250</MII_Polling_Interval> <Up_Delay>500</Up_Delay>
+     * <Down_Delay>500</Down_Delay> <Slave_Interface Name="eth0">
+     * <MII_Status>up</MII_Status> <Speed>1000 Mbps</Speed>
+     * <Duplex>full</Duplex> <Link_Failure_Count>0</Link_Failure_Count>
+     * <Permanent_HW_addr>52:54:00:24:47:70</Permanent_HW_addr>
+     * </Slave_Interface> <Family Type="AF_INET"> <MAC>52:54:00:24:47:70</MAC>
+     * <mtu>1500</mtu> </Family> <BootProto>none</BootProto>
+     * <MetaData>ethernet:c0a80100
+     * {192.168.1.0}:MANAGEMENT,CLUSTER_HEARTBEAT,LIVE_MIGRATE
+     * ,VIRTUAL_MACHINE,STORAGE</MetaData> </Device> </Bonding> <Bridges>
+     * <Device Name="c0a80100"> <Family Type="AF_INET">
+     * <MAC>52:54:00:24:47:70</MAC> <Address>192.168.1.64</Address>
+     * <Netmask>255.255.255.0</Netmask> <Broadcast>192.168.1.255</Broadcast>
+     * </Family> <Interfaces> <PhyInterface>bond0</PhyInterface> </Interfaces>
+     * <BootProto>static</BootProto></Device> </Bridges> <Infiniband>
+     * </Infiniband> </Active></Network></Discover_Network_Result>
+     */
+    /* put more in when required, for now ok */
+    public Boolean discoverNetwork() throws ParserConfigurationException,
+            IOException, Exception {
+        // if (postDiscovery == null) {
+            postDiscovery = callWrapper("discover_network");
+            this.interfaceList = new HashMap<String, Interface>();
+        // }
+        // System.out.println(postDiscovery);
+        Document xmlDocument = prepParse((String) postDiscovery);
+        String path = "//Discover_Network_Result/Network/Active";
+        String bpath = path + "/Bridges/Device";
+
+        netInterfaces = new ArrayList<String>();
+        netInterfaces.addAll(xmlToList(bpath + "/@Name",
+                xmlDocument));
+        for (String b : netInterfaces) {
+            Map<String, String> br = xmlToMap(bpath + "[@Name='" + b
+                    + "']/Family", xmlDocument);
+            /* vifs are here too */
+            String phyInt = (String) this.xmlToMap(bpath + "[@Name='" + b
+                    + "']/Interfaces", xmlDocument).get("PhyInterface");
+            Interface iface = new Interface();
+            iface.setInterface(br);
+            iface.setName(b);
+            iface.setIfType("Bridge");
+            if (phyInt == null) {
+                iface.setIfType("Local");
+            }
+            iface.setPhysical(phyInt);
+            interfaceList.put(b, iface);
+        }
+        /* add "physical" interfaces */
+        bpath =  path + "/Network/Device";
+        netInterfaces = new ArrayList<String>();
+        netInterfaces.addAll(xmlToList(bpath + "/@Name", xmlDocument));
+        for (String p : netInterfaces) {
+            Map<String, String> nf = xmlToMap("//Device[@Name='" + p
+                    + "']", xmlDocument);
+            Interface iface = new Interface();
+            iface.setPhysical(nf.get("Basename"));
+            iface.setName(p);
+            iface.setMac(nf.get("MAC"));
+            iface.setIfType("Physical");
+            interfaceList.put(p, iface);
+        }
+        /* add virtual interfaces ? */
+        if (postDiscovery == null)
+            return false;
+
+        return true;
+    }
+
+    /*
+     * ovs_local_config, <class 'agent.api.network.linux_network.LinuxNetwork'>
+        Configure a Local Bridge ((NIC-less bridge)
+
+        @param action (start | stop)
+             start: Creates local bridge without a physical interface, and saves bridge config
+                    file in /etc/sysconfig/network-scripts
+             stop:  Deletes local bridge, removes bridge config file from
+                    /etc/sysconfig/network-scripts
+
+        @param br_name       The bridge name to add
+
+        @return       If successful, returns the name of the bridge
+                      Raises an exception on failure
+
+     */
+    public Boolean startOvsLocalConfig(String br)
+            throws XmlRpcException {
+        return ovsLocalConfig("start", br);
+    }
+
+    public Boolean stopOvsLocalConfig(String br)
+            throws XmlRpcException {
+        return ovsLocalConfig("stop", br);
+    }
+
+    public Boolean ovsLocalConfig(String action, String br)
+            throws XmlRpcException {
+        Object x = callWrapper("ovs_local_config", action, br);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * ovs_vlan_config, <class 'agent.api.network.linux_network.LinuxNetwork'>
+        Creates a VLAN interface on a physical, or a bond interface.
+
+        @param  action (add|remove)
+              add:    Creates a VLAN on an interface,saves the VLAN config file in
+                      /etc/sysconfig/network-scripts
+              remove: Removes a VLAN from an interfacei,removes its config file from
+                      /etc/sysconfig/network-scripts
+
+        @param   interface    The interface on which to create a VLAN
+        @param   vlanid       VLAN ID (2-4095)
+
+        @return  If successful, returns the interface, and VLAN created
+                 Raises an exception on failure
+
+        Restriction:
+        -Interface  must be physical, or bond
+        -Interface must not be member of a bridge, or slave to a bond
+        -VLAN ID must not exist on the same interface
+
+     */
+    public Boolean startOvsVlanConfig(String dev, int vlan)
+            throws XmlRpcException {
+        return ovsVlanConfig("add", dev, vlan);
+    }
+
+    public Boolean stopOvsVlanConfig(String dev, int vlan)
+            throws XmlRpcException {
+        return ovsVlanConfig("del", dev, vlan);
+    }
+    public Boolean ovsVlanConfig(String action, String net, int vlan)
+            throws XmlRpcException {
+        Object x = callWrapper("ovs_vlan_config", action, net, vlan);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * ovs_br_config, <class 'agent.api.network.linux_network.LinuxNetwork'>
+        Configure a Standard Bridge.
+
+        @param action (start | stop)
+              start: Creates the bridge, Copies the IP and MAC addresses from netdev to bridge,
+                     enslaves net_dev to bridge, and saves bridge config files in
+                     /etc/sysconfig/network-scripts
+              stop:  Removes net_dev from the bridge,transfers addresses, routes from bridge to
+                     net_dev, deletes the bridge, and revomes bridge config files from
+                     /etc/sysconfig/network-scripts
+
+        @param br_name       The bridge name to add
+        @param net_dev       The physical interface to add to the bridge
+
+        @return    If successful, returns the names of the bridge and it's physical interface.
+                   Raises an exception on failure
+        Restriction:
+        -net_dev  must be physical, or bond
+        -net_dev  must not be member of a bridge, or slave to a bond
+     */
+    public Boolean startOvsBrConfig(String br, String dev)
+            throws XmlRpcException {
+        return ovsBrConfig("start", br, dev);
+    }
+
+    public Boolean stopOvsBrConfig(String br, String dev)
+            throws XmlRpcException {
+        return ovsBrConfig("stop", br, dev);
+    }
+
+    public Boolean ovsBrConfig(String action, String br, String net)
+            throws XmlRpcException {
+        Object x = callWrapper("ovs_br_config", action, br, net);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * ovs_vlan_bridge, <class 'agent.api.network.linux_network.LinuxNetwork'>
+         @param action (start | stop)
+              start: Creates the bridge, creats VLAN on net_dev,enslaves
+                     the VLAN to the bridge, and saves VLAN bridge config
+                     files in /etc/sysconfig/network-scripts
+              stop:  Removes the VLAN from the bridge, removes the VLAN,
+                     deletes the bridge, and removes VLAN bridge config files
+                     from /etc/sysconfig/network-scripts
+
+        @param br_name       The bridge name to add
+        @param net_dev       The physical interface on which to create a VLAN.
+        @param vlan_id       VLAN ID (1-4095). VLAN ID of 1 is the untagged VLAN.
+
+        @return       If successful, returns the names of the bridge and it's VLAN interface
+                      Raises an exception on failure
+     */
+    public Boolean stopOvsVlanBridge(String br, String net, int vlan) throws XmlRpcException {
+        return ovsVlanBridge("stop", br, net, vlan);
+    }
+
+    public Boolean startOvsVlanBridge(String br, String net, int vlan) throws XmlRpcException {
+        return ovsVlanBridge("start", br, net, vlan);
+    }
+
+    public Boolean ovsVlanBridge(String action, String br, String net, int vlan)
+            throws XmlRpcException {
+        Object x = callWrapper("ovs_vlan_bridge", action, br, net, vlan);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * deconfigure_virtual_ip, <class
+     * 'agent.api.network.linux_network.LinuxNetwork'> argument: self - default:
+     * None argument: virtual_ip - default: None
+     */
+    public Boolean deconfigureVip(String vip) throws XmlRpcException {
+        Object x = callWrapper("deconfigure_virtual_ip", vip);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * ovs_async_bond, <class 'agent.api.network.linux_network.LinuxNetwork'>
+     * argument: self - default: None argument: action - default: None argument:
+     * bond - default: None
+     */
+    public Boolean ovsAsyncBond(String action, String bond)
+            throws XmlRpcException {
+        Object x = callWrapper("ovs_async_bond", action, bond);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Ntp.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Ntp.java
new file mode 100644
index 0000000..96b1b4e
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Ntp.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Licensed 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 com.cloud.hypervisor.ovm3.object;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.xmlrpc.XmlRpcException;
+
+/*
+ * should become an interface implementation
+ */
+public class Ntp extends OvmObject {
+    private List<String> Servers = new ArrayList<String>();
+    private Boolean isServer = null;
+    private Boolean isRunning = null;
+
+    public Ntp(Connection c) {
+        client = c;
+    }
+
+    public List<String> addServer(String server) {
+        if (Servers.contains(server) == false)
+            Servers.add(server);
+
+        return Servers;
+    }
+
+    public List<String> removeServer(String server) {
+        if (Servers.contains(server))
+            Servers.remove(server);
+
+        return Servers;
+    }
+
+    public List<String> servers() {
+        return Servers;
+    }
+
+    public Boolean isRunning() {
+        return isRunning;
+    }
+
+    public Boolean isServer() {
+        return isServer;
+    }
+
+    public Boolean getDetails() throws XmlRpcException {
+        return this.getNtp();
+    }
+
+    /*
+     * get_ntp, <class 'agent.api.host.linux.Linux'> argument: self - default:
+     * None
+     */
+    public Boolean getNtp() throws XmlRpcException {
+        Object[] v = (Object[]) callWrapper("get_ntp");
+        int c = 0;
+        for (Object o : v) {
+            // System.out.println(o.getClass());
+            if (o instanceof java.lang.Boolean) {
+                if (c == 0)
+                    this.isServer = (Boolean) o;
+
+                if (c == 1)
+                    this.isRunning = (Boolean) o;
+
+                // should not get here
+                if (c > 1)
+                    return false;
+
+                c += 1;
+            } else if (o instanceof java.lang.Object) {
+                Object[] S = (Object[]) o;
+                for (Object m : S) {
+                    this.addServer((String) m);
+                }
+            }
+        }
+        return true;
+    }
+
+    /*
+     * set_ntp, <class 'agent.api.host.linux.Linux'> argument: self - default:
+     * None argument: servers - default: None argument: local_time_source -
+     * default: None argument: allow_query - default: None // right, can't be
+     * set eh
+     */
+    public Boolean setNtp(List<String> servers, Boolean running)
+            throws XmlRpcException {
+        if (callWrapper("set_ntp", servers, running) == null) {
+            return this.getNtp();
+        } else {
+            return false;
+        }
+    }
+
+    /* also cleans the vector */
+    public Boolean setNtp(String server, Boolean running)
+            throws XmlRpcException {
+        this.Servers = new ArrayList<String>();
+        this.Servers.add(server);
+        return setNtp(this.Servers, running);
+    }
+
+    public Boolean setNtp(Boolean running) throws XmlRpcException {
+        return setNtp(this.Servers, running);
+    }
+
+    /*
+     * disable_ntp, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None
+     */
+    public Boolean disableNtp() throws XmlRpcException {
+        if (callWrapper("disable_ntp") == null)
+            return true;
+        return false;
+    }
+
+    /*
+     * enable_ntp, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None
+     */
+    public Boolean enableNtp() throws XmlRpcException {
+        if (callWrapper("enable_ntp") == null)
+            return true;
+        return false;
+    }
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/OvmObject.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/OvmObject.java
new file mode 100644
index 0000000..4dba83c
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/OvmObject.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Licensed 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 com.cloud.hypervisor.ovm3.object;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.Vector;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+public class OvmObject {
+    public static Connection client = null;
+    public static Vector<?> emptyParams = new Vector<Object>();
+
+    /* remove dashes from uuids */
+    public String deDash(String str) {
+        final String x = str.replaceAll("-", "");
+        return x;
+    }
+
+    /* generate a uuid */
+    public String newUuid() {
+        final String uuid = UUID.randomUUID().toString();
+        return uuid;
+    }
+
+    /* generate a uuid */
+    public String newUuid(String str) {
+        final String uuid = UUID.nameUUIDFromBytes(str.getBytes()).toString();
+        return uuid;
+    }
+
+    /* capture most of the calls here */
+    public static Object callWrapper(String call) throws XmlRpcException {
+        try {
+            Object res = client.call(call, emptyParams);
+            return res;
+        } catch (XmlRpcException e) {
+            throw new XmlRpcException(e.getMessage());
+        }
+    }
+
+    /* nice try but doesn't work like that .. */
+    @SafeVarargs
+    public static <T> Object callWrapper(String call, T... args)
+            throws XmlRpcException {
+        Vector<T> params = new Vector<T>();
+        for (T param : args) {
+            params.add(param);
+        }
+        // return
+        Object res = client.call(call, params);
+        return res;
+    }
+
+    /* returns a single string */
+    public HashMap<String, Long> callMap(String call) throws XmlRpcException {
+        HashMap<String, Long> result = (HashMap<String, Long>) callWrapper(call);
+        return result;
+    }
+
+    public <T> String callString(String call, T... args) throws XmlRpcException {
+        Object result = callWrapper(call, args);
+        if (result == null) {
+            return null;
+        }
+        if (result instanceof String)
+            return result.toString();
+        if (result instanceof Integer)
+            return result.toString();
+        if (result instanceof Long)
+            return result.toString();
+        if (result instanceof HashMap)
+            return result.toString();
+
+        Object[] results = (Object[]) result;
+
+        if (results.length == 0)
+            // return results[0].toString();
+            return null;
+
+        if (results.length == 1)
+            return results[0].toString();
+
+        return null;
+    }
+
+    /* was String, Object before */
+    public <E> Map<String, E> xmlToMap(String path, Document xmlDocument)
+            throws XPathExpressionException {
+        XPathFactory factory = javax.xml.xpath.XPathFactory.newInstance();
+        XPath xPath = factory.newXPath();
+        // capabilities, date_time etc
+        XPathExpression xPathExpression = xPath.compile(path);
+        NodeList nodeList = (NodeList) xPathExpression.evaluate(xmlDocument,
+                XPathConstants.NODESET);
+
+        Map<String, E> myMap = new HashMap<String, E>();
+        for (int ind = 0; ind < nodeList.getLength(); ind++) {
+            NodeList nodeListFor = nodeList.item(ind).getChildNodes();
+            for (int index = 0; index < nodeListFor.getLength(); index++) {
+                String rnode = nodeListFor.item(index).getNodeName();
+                NodeList nodeListFor2 = nodeListFor.item(index).getChildNodes();
+                if (nodeListFor2.getLength() > 1) {
+                    // System.out.println("multiball");
+                    /*
+                     * for (int i = 0; i < nodeListFor2.getLength(); i++) {
+                     * String node = nodeListFor2.item(i).getNodeName(); String
+                     * element = nodeListFor2.item(i).getTextContent();
+                     * System.out.println("rnode: " + rnode + " -> node " + node
+                     * + " ---> " + element); myMap.put(node, element); }
+                     */
+                } else {
+                    String element = nodeListFor.item(index).getTextContent();
+                    // System.out.println("rnode " + rnode + " ---> " +
+                    // element);
+                    myMap.put(rnode, (E) element);
+                }
+            }
+        }
+        return myMap;
+    }
+
+    public List<String> xmlToList(String path, Document xmlDocument)
+            throws XPathExpressionException {
+        List<String> list = new ArrayList<String>();
+        XPathFactory factory = javax.xml.xpath.XPathFactory.newInstance();
+        XPath xPath = factory.newXPath();
+
+        XPathExpression xPathExpression = xPath.compile(path);
+        NodeList nodeList = (NodeList) xPathExpression.evaluate(xmlDocument,
+                XPathConstants.NODESET);
+
+        for (int ind = 0; ind < nodeList.getLength(); ind++) {
+            // System.out.println(nodeList.item(ind).getTextContent());
+            if (!nodeList.item(ind).getTextContent().isEmpty()) {
+                list.add("" + nodeList.item(ind).getTextContent());
+            } else {
+                list.add("" + nodeList.item(ind).getNodeValue());
+            }
+        }
+        return list;
+    }
+
+    public String xmlToString(String path, Document xmlDocument)
+            throws XPathExpressionException {
+
+        XPathFactory factory = javax.xml.xpath.XPathFactory.newInstance();
+        XPath xPath = factory.newXPath();
+
+        XPathExpression xPathExpression = xPath.compile(path);
+        NodeList nodeList = (NodeList) xPathExpression.evaluate(xmlDocument,
+                XPathConstants.NODESET);
+        // put a try in here too, so we can get the subbies
+        String x = nodeList.item(0).getTextContent();
+        return x;
+    }
+
+    public Document prepParse(String input)
+            throws ParserConfigurationException, Exception, IOException {
+        DocumentBuilderFactory builderfactory = DocumentBuilderFactory
+                .newInstance();
+        builderfactory.setNamespaceAware(true);
+
+        DocumentBuilder builder = builderfactory.newDocumentBuilder();
+        Document xmlDocument = builder.parse(new InputSource(new StringReader(
+                (String) input)));
+        return xmlDocument;
+    }
+    /*
+     * returns a list of strings public <T> ArrayList<String> call(String call,
+     * T... args) throws XmlRpcException { ArrayList<String> data = new
+     * ArrayList<String>(); Object[] result = (Object[]) callWrapper(call,
+     * args);
+     *
+     * if (result[result.length] != null) return null;
+     *
+     * for(Object x : result) { data.add(x.toString()); } return data; }
+     */
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Pool.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Pool.java
new file mode 100644
index 0000000..2b87c70
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Pool.java
@@ -0,0 +1,362 @@
+/*******************************************************************************
+ * Licensed 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 com.cloud.hypervisor.ovm3.object;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.apache.commons.lang.StringUtils;
+import org.apache.xmlrpc.XmlRpcException;
+
+/*
+ * synonym to the pool python lib in the ovs-agent
+ */
+public class Pool extends OvmObject {
+    /*
+     * {Pool_Filesystem_Target=cs-mgmt:/volumes/cs-data/secondary,
+     * Pool_Filesystem_Type=nfs,
+     * Pool_Filesystem_Nfsbase_Uuid=b8ca41cb-3469-4f74-a086-dddffe37dc2d,
+     * Pool_Filesystem_Uuid=0004fb0000050000e70fbddeb802208f}
+     */
+    private List<String> validRoles = new ArrayList<String>() {
+        {
+            add("utility");
+            add("xen");
+        }
+    };
+    private Boolean _poolDisc = false;
+    public Map<String, String> poolFileSystem = new HashMap<String, String>();
+    public List<String> poolIps = new ArrayList<String>();
+    private List<String> poolRoles = new ArrayList<String>();
+    public List<String> poolMembers = new ArrayList<String>();
+    public String poolMasterVip;
+    public String poolAlias;
+    public String poolId = "";
+
+    public Pool(Connection c) throws ParserConfigurationException, IOException,
+            Exception {
+        client = c;
+        discoverServerPool();
+    }
+
+    public String getPoolMasterVip() {
+        return this.poolMasterVip;
+    }
+
+    public String getPoolAlias() {
+        return this.poolAlias;
+    }
+
+    public String getPoolId() {
+        return this.poolId;
+    }
+
+    /* TODO: check the toString for the list x,x */
+    public List<String> getValidRoles() {
+        return this.validRoles;
+    }
+
+    public void setPoolIps(List<String> ips) {
+        this.poolIps = new ArrayList<String>();
+        this.poolIps.addAll(ips);
+    }
+
+    /*
+     * create_server_pool, <class 'agent.api.serverpool.ServerPool'> argument:
+     * self - default: None argument: pool_alias - default: None argument:
+     * pool_uuid - default: None argument: pool_virtual_ip - default: None
+     * argument: node_number - default: None argument: server_hostname -
+     * default: None argument: server_ip - default: None argument: roles -
+     * default: None
+     */
+    public Boolean createServerPool(String alias, String id, String vip,
+            int num, String name, String ip, List<String> roles)
+            throws XmlRpcException {
+        String role = roles.toString();
+        role = "xen,utility";
+        Object x = callWrapper("create_server_pool", alias, id, vip, num, name,
+                ip,
+                role);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    public Boolean createServerPool(String alias, String id, String vip,
+            int num, String name, String ip) throws XmlRpcException {
+        return this.createServerPool(alias,
+                id,
+                vip,
+                num,
+                name,
+                ip,
+                getValidRoles());
+    }
+    public Boolean createServerPool(int num, String name, String ip)
+            throws XmlRpcException {
+        return createServerPool(poolAlias, poolId, poolMasterVip, num, name,
+                ip, poolRoles);
+    }
+
+    /*
+     * update_pool_virtual_ip, <class 'agent.api.serverpool.ServerPool'>
+     * argument: self - default: None argument: new_pool_vip - default: None
+     */
+    public Boolean updatePoolVirtualIp(String ip) throws XmlRpcException {
+        Object x = callWrapper("update_pool_virtual_ip", ip);
+        if (x == null) {
+            this.poolMasterVip = ip;
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * leave_server_pool, <class 'agent.api.serverpool.ServerPool'> argument:
+     * self - default: None argument: pool_uuid - default: None
+     */
+    public Boolean leaveServerPool(String uuid) throws XmlRpcException {
+        Object x = callWrapper("leave_server_pool", uuid);
+        if (x == null)
+            return true;
+        return false;
+    }
+
+    /*
+     * set_server_pool_alias, <class 'agent.api.serverpool.ServerPool'>
+     * argument: self - default: None argument: pool_alias - default: None
+     */
+    public Boolean setServerPoolAlias(String alias) throws XmlRpcException {
+        Object x = callWrapper("set_server_pool_alias", alias);
+        if (x == null) {
+            this.poolAlias = alias;
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * take_ownership, <class 'agent.api.serverpool.ServerPool'> argument: self
+     * - default: None argument: manager_uuid - default: None argument:
+     * manager_core_api_url - default: None
+     * take_ownership('0004fb00000100000af70d20dcce7d65',
+     * 'https://2f55e3b9efa6f067ad54a7b144bb6f2e:
+     * ******@0.0.0.0:7002/ovm/core/OVMManagerCoreServlet')
+     */
+    public Boolean takeOwnership(String uuid, String apiurl)
+            throws XmlRpcException {
+        Object x = callWrapper("take_ownership", uuid, apiurl);
+        if (x == null) {
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * destroy_server_pool, <class 'agent.api.serverpool.ServerPool'> argument:
+     * self - default: None argument: pool_uuid - default: None
+     */
+    public Boolean destroyServerPool(String uuid) throws XmlRpcException {
+        Object x = callWrapper("destroy_server_pool", uuid);
+        if (x == null) {
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * release_ownership, <class 'agent.api.serverpool.ServerPool'> argument:
+     * self - default: None argument: manager_uuid - default: None
+     */
+    public Boolean releaseOwnership(String uuid) throws XmlRpcException {
+        Object x = callWrapper("release_ownership", uuid);
+        if (x == null) {
+            return true;
+        }
+        return false;
+    }
+
+    /* server.discover_pool_filesystem */
+    /*
+     * discover_server_pool, <class 'agent.api.serverpool.ServerPool'> argument:
+     * self - default: None
+     */
+    public Boolean discoverServerPool() throws ParserConfigurationException,
+            IOException, Exception {
+        /* forcefull rediscover for now */
+        if (this._poolDisc) {
+            return true;
+        }
+        Object x = callWrapper("discover_server_pool");
+        if (x == null) {
+            return false;
+        }
+
+        try {
+            Document xmlDocument = prepParse((String) x);
+            String path = "//Discover_Server_Pool_Result/Server_Pool";
+            this.poolId = xmlToString(path + "/Unique_Id", xmlDocument);
+            this.poolAlias = xmlToString(path + "/Pool_Alias", xmlDocument);
+            this.poolMasterVip = xmlToString(path + "/Master_Virtual_Ip",
+                    xmlDocument);
+            this.poolMembers = xmlToList(path + "/Member_List", xmlDocument);
+            this.poolIps
+                    .addAll(xmlToList(path + "//Registered_IP", xmlDocument));
+            this._poolDisc = true;
+        } catch (Exception e) {
+            if (e.getMessage() == null) {
+                System.err.println("No pool to discover: " + e.getMessage());
+            } else {
+                System.err.println("Error in pooldiscovery: " + e.getMessage());
+            }
+        }
+
+        return true;
+    }
+
+    /*
+     * update_server_roles, <class 'agent.api.serverpool.ServerPool'> argument:
+     * self - default: None argument: roles - default: None ?> list or sring
+     */
+    private Boolean validPoolRole(String role) throws Exception {
+        for (String r : this.validRoles) {
+            if (r.contentEquals(role)) {
+                return true;
+            }
+        }
+        throw new Exception("Illegal role: " + role);
+    }
+
+    private Boolean validPoolRole(List<String> roles) throws Exception {
+        for (String r : roles) {
+            return validPoolRole(r);
+        }
+        return false;
+    }
+
+    public Boolean setServerRoles() throws XmlRpcException, Exception {
+        validPoolRole(this.poolRoles);
+        String roles = StringUtils.join(this.poolRoles.toArray(), ",");
+        Object x = callWrapper("update_server_roles", roles);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /* do some sanity check on the valid poolroles */
+    public Boolean setServerRoles(List<String> roles) throws Exception {
+        this.poolRoles.addAll(roles);
+        return setServerRoles();
+    }
+
+
+    public void addServerRole(String role) throws Exception {
+        validPoolRole(role);
+        this.poolRoles.add(role);
+    }
+
+    public void removeServerRole(String role) {
+        this.poolRoles.remove(role);
+    }
+
+    public boolean serverHasRole(String role) {
+        for (String r : this.poolRoles) {
+            if (r.contentEquals(role)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /*
+     * join_server_pool, <class 'agent.api.serverpool.ServerPool'> argument:
+     * self - default: None argument: pool_alias - default: None argument:
+     * pool_uuid - default: None argument: pool_virtual_ip - default: None
+     * argument: node_number - default: None argument: server_hostname -
+     * default: None argument: server_ip - default: None argument: roles -
+     * default: None
+     */
+    /* allow these to be set before ? */
+    public Boolean joinServerPool(String alias, String id, String vip, int num,
+            String name, String ip, List<String> roles) throws XmlRpcException {
+        String role = StringUtils.join(roles.toArray(), ",");
+        Object x = callWrapper("join_server_pool", alias, id, vip, num, name,
+                ip,
+                role);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    public Boolean joinServerPool(String alias, String id, String vip, int num,
+            String name, String ip) throws XmlRpcException {
+        return joinServerPool(alias, id, vip, num, name, ip, getValidRoles());
+    }
+
+    public Boolean joinServerPool(int num, String name, String ip)
+            throws XmlRpcException {
+        return joinServerPool(poolAlias, poolId, poolMasterVip, num, name, ip,
+                poolRoles);
+    }
+
+    /*
+     * set_pool_member_ip_list, <class 'agent.api.serverpool.ServerPool'>
+     * argument: self - default: None argument: ip_list - default: None
+     */
+    public Boolean setPoolMemberIpList() throws XmlRpcException {
+        // should throw exception if no poolIps set
+        Object x = callWrapper("set_pool_member_ip_list", this.poolIps);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    public List getPoolMemberIpList() throws XmlRpcException, Exception {
+        if (poolIps.size() == 0) {
+            this.discoverServerPool();
+        }
+        return poolIps;
+    }
+
+    /* TODO: need to change the logic here */
+    public Boolean setPoolMemberIpList(String ip) throws XmlRpcException {
+        this.poolIps = new ArrayList<String>();
+        this.poolIps.add(ip);
+        return setPoolMemberIpList();
+    }
+
+    public Boolean addPoolMemberIp(String ip) throws XmlRpcException, Exception {
+        this.getPoolMemberIpList();
+        this.poolIps.add(ip);
+        return setPoolMemberIpList();
+    }
+
+    /* meh */
+    public Boolean removePoolMemberIp(String ip) throws XmlRpcException,
+            Exception {
+        this.getPoolMemberIpList();
+        this.poolIps.remove(ip);
+        return setPoolMemberIpList();
+    }
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/PoolOCFS2.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/PoolOCFS2.java
new file mode 100644
index 0000000..1759224
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/PoolOCFS2.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Licensed 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 com.cloud.hypervisor.ovm3.object;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.w3c.dom.Document;
+
+/* should ingest this into Pool */
+public class PoolOCFS2 extends OvmObject {
+    public Map<String, String> poolFileSystem = new HashMap<String, String>();
+    public String poolFsTarget;
+    public String poolFsType;
+    public String poolFsNFSBaseId;
+    public String poolFsId;
+
+    public String poolFsNFSBaseId() {
+        return this.poolFsNFSBaseId;
+    }
+
+    public String poolFsId() {
+        return this.poolFsId;
+    }
+
+    public String poolFsUuid() {
+        return this.poolFsId;
+    }
+
+    public String poolFsTarget() {
+        return this.poolFsTarget;
+    }
+
+    public PoolOCFS2(Connection c) {
+        client = c;
+    }
+
+    /*
+     * destroy_pool_filesystem, <class 'agent.api.poolfs.ocfs2.PoolOCFS2'>
+     * argument: self - default: None argument: poolfs_type - default: None
+     * argument: poolfs_target - default: None argument: poolfs_uuid - default:
+     * None argument: poolfs_nfsbase_uuid - default: None
+     */
+    public Boolean destroyPoolFs(String type, String target, String uuid,
+            String nfsbaseuuid) throws ParserConfigurationException,
+            IOException, Exception {
+        // should throw exception if no poolIps set
+        Object x = callWrapper("destroy_pool_filesystem", type, target, uuid,
+                nfsbaseuuid);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    public Boolean destroyPoolFs() throws ParserConfigurationException,
+            IOException, Exception {
+        // should throw exception if no poolIps set
+        Object x = callWrapper("destroy_pool_filesystem", poolFsType,
+                poolFsTarget, poolFsId, poolFsNFSBaseId);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * create_pool_filesystem, <class 'agent.api.poolfs.ocfs2.PoolOCFS2'>
+     * argument: self - default: None argument: poolfs_type - default: None
+     * argument: poolfs_target - default: None argument: cluster_name - default:
+     * None argument: poolfs_uuid - default: None argument: poolfs_nfsbase_uuid
+     * - default: None argument: manager_uuid - default: None argument:
+     * pool_uuid - default: None argument: block_size - default: None argument:
+     * cluster_size - default: None argument: journal_size - default: None
+     */
+    /*
+     * create_pool_filesystem('nfs', 'cs-mgmt:/volumes/cs-data/secondary',
+     * 'ba9aaf00ae5e2d73', '0004fb0000050000e70fbddeb802208f',
+     * 'b8ca41cb-3469-4f74-a086-dddffe37dc2d',
+     * '0004fb00000100000af70d20dcce7d65', '0004fb0000020000ba9aaf00ae5e2d73')
+     */
+    public Boolean createPoolFs(String type, String target, String clustername,
+            String fsid, String nfsbaseid, String managerid, String id)
+            throws XmlRpcException {
+        Object x = callWrapper("create_pool_filesystem", type, target,
+                clustername, fsid, nfsbaseid, managerid, id);
+        // System.out.println(x);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    public Boolean createPoolFs(String type, String target, String clustername,
+            String fsid, String nfsbaseid, String managerid, String id,
+            int blocksize, int clustersize, int journalsize)
+            throws XmlRpcException {
+        Object x = callWrapper("create_pool_filesystem", type, target,
+                clustername, fsid, nfsbaseid, managerid, id, blocksize,
+                clustersize, journalsize);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * discover_pool_filesystem, <class 'agent.api.poolfs.ocfs2.PoolOCFS2'>
+     * argument: self - default: None
+     */
+    public Boolean discoverPoolFs() throws ParserConfigurationException,
+            IOException, Exception {
+        // should throw exception if no poolIps set
+        Object x = callWrapper("discover_pool_filesystem");
+        Document xmlDocument = prepParse((String) x);
+        String path = "//Discover_Pool_Filesystem_Result";
+        poolFileSystem = xmlToMap(path + "/Pool_Filesystem", xmlDocument);
+        poolFsTarget = poolFileSystem.get("Pool_Filesystem_Target");
+        poolFsType = poolFileSystem.get("Pool_Filesystem_Type");
+        poolFsNFSBaseId = poolFileSystem.get("Pool_Filesystem_Nfsbase_Uuid");
+        poolFsId = poolFileSystem.get("Pool_Filesystem_Uuid");
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * ocfs2_get_meta_data, <class 'agent.api.poolfs.ocfs2.PoolOCFS2'> argument:
+     * self - default: None argument: device - default: None argument: filename
+     * - default: None
+     */
+    public Boolean ocfs2GetMetaData(String device, String filename)
+            throws XmlRpcException {
+        Object x = callWrapper("ocfs2_get_meta_data", device, filename);
+        // System.out.println(x);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Remote.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Remote.java
new file mode 100644
index 0000000..a2ae0a4
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Remote.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Licensed 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 com.cloud.hypervisor.ovm3.object;
+
+import org.apache.xmlrpc.XmlRpcException;
+
+/*
+ * should become an interface implementation
+ */
+public class Remote extends OvmObject {
+
+    public Remote(Connection c) {
+        client = c;
+    }
+
+    /*
+     * sys_shutdown, <class
+     * 'agent.api.remote.linux_remote.LinuxRemoteManagement'> argument: self -
+     * default: None
+     */
+    public Boolean sysShutdown() throws XmlRpcException {
+        Object x = callWrapper("sys_shutdown");
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * remote_power_off, <class
+     * 'agent.api.remote.linux_remote.LinuxRemoteManagement'> argument: self -
+     * default: None argument: controller_type - default: None ?> figure this
+     * one out in the source argument: tgt_host - default: None argument:
+     * bmc_username - default: None argument: bmc_password - default: None
+     */
+
+    /*
+     * sys_reboot, <class 'agent.api.remote.linux_remote.LinuxRemoteManagement'>
+     * argument: self - default: None
+     */
+    public Boolean sysReboot() throws XmlRpcException {
+        Object x = callWrapper("sys_reboot");
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * remote_power_on, <class
+     * 'agent.api.remote.linux_remote.LinuxRemoteManagement'> argument: self -
+     * default: None argument: controller_type - default: None ?> same here
+     * argument: tgt - default: None argument: arg1 - default: None argument:
+     * arg2 - default: None
+     */
+
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Repository.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Repository.java
new file mode 100644
index 0000000..d45f198
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Repository.java
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * Licensed 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 com.cloud.hypervisor.ovm3.object;
+
+import java.util.Map;
+
+import org.apache.xmlrpc.XmlRpcException;
+
+/*
+ * should become an interface implementation
+ */
+public class Repository extends OvmObject {
+
+    public Repository(Connection c) {
+        client = c;
+    }
+
+    /*
+     * delete_repository, <class 'agent.api.repository.Repository'> argument:
+     * repo_uuid - default: None argument: erase - default: None
+     */
+    public Boolean deleteRepo(String id, Boolean erase) throws XmlRpcException {
+        Object x = callWrapper("delete_repository", id, erase);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * import_virtual_disk, <class 'agent.api.repository.Repository'> argument:
+     * url - default: None argument: virtual_disk_id - default: None argument:
+     * repo_uuid - default: None argument: option - default: None
+     */
+    /* should add timeout ? */
+    public Boolean importVirtualDisk(String url, String vdiskid, String repoid,
+            String option) throws XmlRpcException {
+        Object x = callWrapper("import_virtual_disk", url, vdiskid, repoid, option);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+    public Boolean importVirtualDisk(String url, String vdiskid, String repoid) throws XmlRpcException {
+        Object x = callWrapper("import_virtual_disk", url, vdiskid, repoid);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * discover_repositories, <class 'agent.api.repository.Repository'>
+     * argument: args - default: None
+     */
+    /*
+     * args are repo ids <Discover_Repositories_Result> <RepositoryList/>
+     * </Discover_Repositories_Result>
+     */
+    public Boolean discoverRepo(Map<String, String> args)
+            throws XmlRpcException {
+        Object x = callWrapper("discover_repositories", args);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    public Boolean discoverRepo(String id) throws XmlRpcException {
+        Object x = callWrapper("discover_repositories", id);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * add_repository, <class 'agent.api.repository.Repository'> argument:
+     * fs_location - default: None argument: mount_point - default: None
+     */
+    public Boolean addRepo(String remote, String local) throws XmlRpcException {
+        Object x = callWrapper("add_repository", remote, local);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * get_repository_meta_data, <class 'agent.api.repository.Repository'>
+     * argument: repo_mount_point - default: None
+     */
+    public Boolean getRepoMetaData(String local) throws XmlRpcException {
+        Object x = callWrapper("get_repository_meta_data", local);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * mount_repository_fs, <class 'agent.api.repository.Repository'> argument:
+     * fs_location - default: None argument: mount_point - default: None
+     */
+    public Boolean mountRepoFs(String remote, String local)
+            throws XmlRpcException {
+        Object x = callWrapper("mount_repository_fs", remote, local);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * unmount_repository_fs, <class 'agent.api.repository.Repository'>
+     * argument: mount_point - default: None
+     */
+    public Boolean unmountRepoFs(String local) throws XmlRpcException {
+        Object x = callWrapper("unmount_repository_fs", local);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * create_repository, <class 'agent.api.repository.Repository'> argument:
+     * fs_location - default: None argument: mount_point - default: None
+     * argument: repo_uuid - default: None argument: repo_alias - default: None
+     */
+    public Boolean createRepo(String remote, String local, String repoid,
+            String repoalias) throws XmlRpcException {
+        Object x = callWrapper("create_repository", remote, local, repoid,
+                repoalias);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * discover_repository_db, <class 'agent.api.repository.Repository'>
+     * <Discover_Repository_Db_Result> <RepositoryDbList> <Repository
+     * Uuid="0004fb0000030000aeaca859e4a8f8c0">
+     * <Fs_location>cs-mgmt:/volumes/cs-data/primary</Fs_location>
+     * <Mount_point>/
+     * OVS/Repositories/0004fb0000030000aeaca859e4a8f8c0</Mount_point>
+     * <Filesystem_type>nfs</Filesystem_type> <Version>3.0</Version>
+     * <Alias>MyRepo</Alias>
+     * <Manager_uuid>0004fb00000100000af70d20dcce7d65</Manager_uuid>
+     * <Status>Unmounted</Status> </Repository> <Repository> ... </Repository>
+     * </RepositoryDbList> </Discover_Repository_Db_Result>
+     */
+    public Boolean discoverRepoDb() throws XmlRpcException {
+        Object x = callWrapper("discover_repository_db");
+        // System.out.println(x);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * edit_repository_db, <class 'agent.api.repository.Repository'> argument:
+     * repo_uuid - default: None argument: db_changes - default: None
+     */
+    public Boolean editRepoDb(String repoId, Map<String, String> changes)
+            throws XmlRpcException {
+        Object x = callWrapper("edit_repository_db", repoId, changes);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * import_ISO, <class 'agent.api.repository.Repository'> argument: url -
+     * default: None argument: iso_id - default: None argument: repo_uuid -
+     * default: None argument: option - default: None ?> it throws an error when
+     * you add this...
+     */
+    /*
+     * is async, need to find a way to do something with that.... add timeout
+     * too
+     */
+    public Boolean importIso(String url, String isoId, String repoId,
+            String option) throws XmlRpcException {
+        Object x = callWrapper("import_ISO", url, isoId, repoId);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/RpcTypeFactory.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/RpcTypeFactory.java
new file mode 100644
index 0000000..240efef
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/RpcTypeFactory.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Licensed 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.
+ ******************************************************************************/
+/*
+ * Dealing with nil..... -sigh-
+ * http://libjack.com/2009/03/26/java-magento-xmlrpc-api-nil-issue/
+ *
+ * i8 - aka long
+ */
+
+package com.cloud.hypervisor.ovm3.object;
+
+import org.apache.ws.commons.util.NamespaceContextImpl;
+import org.apache.xmlrpc.common.TypeFactoryImpl;
+import org.apache.xmlrpc.common.XmlRpcController;
+import org.apache.xmlrpc.common.XmlRpcStreamConfig;
+import org.apache.xmlrpc.parser.NullParser;
+import org.apache.xmlrpc.parser.TypeParser;
+import org.apache.xmlrpc.parser.AtomicParser;
+import org.apache.xmlrpc.serializer.NullSerializer;
+import org.apache.xmlrpc.serializer.TypeSerializer;
+import org.apache.xmlrpc.serializer.TypeSerializerImpl;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.ContentHandler;
+
+public class RpcTypeFactory extends TypeFactoryImpl {
+
+    public RpcTypeFactory(XmlRpcController pController) {
+        super(pController);
+    }
+
+    @Override
+    public TypeParser getParser(XmlRpcStreamConfig pConfig,
+            NamespaceContextImpl pContext, String pURI, String pLocalName) {
+        if ("".equals(pURI) && NullSerializer.NIL_TAG.equals(pLocalName)) {
+            return new NullParser();
+        } else if (pLocalName.equals("i8")) {
+            return new LongTypeParser();
+        } else {
+            return super.getParser(pConfig, pContext, pURI, pLocalName);
+        }
+    }
+
+    public TypeSerializer getSerializer(XmlRpcStreamConfig pConfig,
+            Object pObject) throws SAXException {
+        if (pObject instanceof Long) {
+            return new LongTypeSerializer();
+        } else {
+            return super.getSerializer(pConfig, pObject);
+        }
+    }
+
+    private class LongTypeSerializer extends TypeSerializerImpl {
+        /*
+         * Tag name of an i8 value.
+         */
+        public static final String I8_TAG = "i8";
+
+        /*
+         * Fully qualified name of an i8 value.
+         */
+        public static final String EX_I8_TAG = "i8";
+
+        @Override
+        public void write(ContentHandler pHandler, Object pObject)
+                throws SAXException {
+            write(pHandler, I8_TAG, EX_I8_TAG, pObject.toString());
+        }
+    }
+
+    private class LongTypeParser extends AtomicParser {
+        protected void setResult(String pResult) throws SAXException {
+            try {
+                super.setResult(new Long(pResult.trim()));
+            } catch (NumberFormatException e) {
+                throw new SAXParseException("Failed to parse long value: "
+                        + pResult, getDocumentLocator());
+            }
+        }
+    }
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/StoragePlugin.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/StoragePlugin.java
new file mode 100644
index 0000000..c311523
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/StoragePlugin.java
@@ -0,0 +1,876 @@
+/*******************************************************************************
+ * Licensed 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 com.cloud.hypervisor.ovm3.object;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.w3c.dom.Document;
+
+/*
+ * should become an interface implementation
+ */
+public class StoragePlugin extends OvmObject {
+    /* nfs or iscsi should be an "enabled" flag */
+    /*
+     * storage_plugin_mount('oracle.generic.NFSPlugin.GenericNFSPlugin', {
+     * 'status': '', 'admin_user': '', 'admin_host': '', 'uuid':
+     * '0004fb00000900000c2461c2f62ba43e', 'total_sz': 0, 'admin_passwd':
+     * '******', 'storage_desc': '', 'free_sz': 0, 'access_host': 'cs-mgmt',
+     * 'storage_type': 'FileSys', 'alloc_sz': 0, 'access_grps': [], 'used_sz':
+     * 0, 'name': '0004fb00000900000c2461c2f62ba43e'}, { 'status': '', 'uuid':
+     * 'b8ca41cb-3469-4f74-a086-dddffe37dc2d', 'ss_uuid':
+     * '0004fb00000900000c2461c2f62ba43e', 'size': '263166853120', 'free_sz':
+     * '259377299456', 'state': 1, 'access_grp_names': [], 'access_path':
+     * 'cs-mgmt:/volumes/cs-data/secondary', 'name':
+     * 'nfs:/volumes/cs-data/secondary'},
+     * '/nfsmnt/b8ca41cb-3469-4f74-a086-dddffe37dc2d', '', True, [])
+     */
+    private String pluginType = "oracle.generic.NFSPlugin.GenericNFSPlugin";
+
+    /* TODO: subclass */
+    /*
+     * Json, but then it's xml... {'status': '', 'admin_user': '', 'admin_host':
+     * '', 'uuid': '0004fb00000900000c2461c2f62ba43e', 'total_sz': 0,
+     * 'admin_passwd': '******', 'storage_desc': '', 'free_sz': 0,
+     * 'access_host': 'cs-mgmt', 'storage_type': 'FileSys', 'alloc_sz': 0,
+     * 'access_grps': [], 'used_sz': 0, 'name':
+     * '0004fb00000900000c2461c2f62ba43e'}
+     */
+    private Map<String, Object> baseProps = new HashMap<String, Object>() {
+        {
+            put("status", ""); /* empty */
+            put("admin_user", ""); /* auth */
+            put("admin_host", ""); /* auth host */
+            put("uuid", ""); /* no dash uuid */
+            put("total_sz", "");
+            put("admin_passwd", ""); /* iscsi or fc */
+            put("storage_desc", ""); /* description */
+            put("free_sz", 0);
+            put("access_host", ""); /* remote host for fs */
+            put("storage_type", "FileSys"); /* type, guess lun ? */
+            put("alloc_size", 0);
+            put("access_groups", new ArrayList<String>());
+            put("sed_size", 0);
+            put("name", ""); /* uuid no dashes */
+        };
+    };
+
+    public String setUuid(String val) {
+        this.baseProps.put("uuid", val);
+        return val;
+    }
+
+    public String getUuid() {
+        return (String) this.baseProps.get("uuid");
+    }
+
+    public String setName(String val) {
+        this.baseProps.put("name", val);
+        return val;
+    }
+
+    public String getName() {
+        return (String) this.baseProps.get("name");
+    }
+
+    public String setFsType(String val) {
+        this.baseProps.put("storage_type", val);
+        return val;
+    }
+
+    public String getFsType() {
+        return (String) this.baseProps.get("storage_type");
+    }
+
+    public String setFsHost(String val) {
+        this.baseProps.put("access_host", val);
+        return val;
+    }
+
+    public String getFsHost() {
+        return (String) this.baseProps.get("access_host");
+    }
+
+    public String setFsServer(String val) {
+        return this.setFsHost(val);
+    }
+
+    public String getFsServer() {
+        return this.getFsHost();
+    }
+
+    /* TODO: subclass */
+    /*
+     * Meh {'status': '', 'uuid': 'b8ca41cb-3469-4f74-a086-dddffe37dc2d',
+     * 'ss_uuid': '0004fb00000900000c2461c2f62ba43e', 'size': '263166853120',
+     * 'free_sz': '259377299456', 'state': 1, 'access_grp_names': [],
+     * 'access_path': 'cs-mgmt:/volumes/cs-data/secondary', 'name':
+     * 'nfs:/volumes/cs-data/secondary'}
+     */
+    private Map<String, Object> ssProps = new HashMap<String, Object>() {
+        {
+            put("status", ""); /* empty */
+            put("uuid", ""); /* with dashes */
+            put("ss_uuid", ""); /* no dashes */
+            put("size", "");
+            put("free_sz", "");
+            put("state", 1); /* guess this is active ? */
+            put("access_grp_names", new ArrayList<String>());
+            put("access_path", ""); /* remote path */
+            put("name", ""); /* just a name */
+            put("mount_options", new ArrayList<String>()); /*
+                                                            * array of values
+                                                            * which match normal
+                                                            * mount options
+                                                            */
+        };
+    };
+
+    public String setFsSourcePath(String val) {
+        this.ssProps.put("access_path", val);
+        return val;
+    }
+
+    public String getFsSourcePath() {
+        return (String) this.ssProps.get("access_path");
+    }
+
+    public String setMntUuid(String val) {
+        this.ssProps.put("uuid", val);
+        return val;
+    }
+
+    public String getMntUuid() {
+        return (String) this.ssProps.get("uuid");
+    }
+
+    public String setSsUuid(String val) {
+        this.ssProps.put("ss_uuid", val);
+        return val;
+    }
+
+    public String getSsUuid() {
+        return (String) this.ssProps.get("ss_uuid");
+    }
+
+    public String setSsName(String val) {
+        this.ssProps.put("name", val);
+        return val;
+    }
+
+    public String getSsName() {
+        return (String) this.ssProps.get("ss_uuid");
+    }
+
+    public String getFreeSize() {
+        return this.ssProps.get("free_sz").toString();
+    }
+
+    public String getTotalSize() {
+        return this.ssProps.get("size").toString();
+    }
+
+    public String getSize() {
+        return this.ssProps.get("size").toString();
+    }
+
+    /* TODO: subclass */
+    /* {'fr_type': 'File',
+        'ondisk_sz': '48193536',
+        'fs_uuid': '7718562d-872f-47a7-b454-8f9cac4ffa3a',
+        'file_path': '/nfsmnt/7718562d-872f-47a7-b454-8f9cac4ffa3a/0004fb0000060000d4a1d2ec05a5e799.img',
+        'file_sz': '52380672'}
+     */
+    private Map<String, Object> fileProps = new HashMap<String, Object>() {
+        {
+            put("fr_type", "");
+            put("ondisk_sz", "");
+            put("fs_uuid", "");
+            put("file_path", "");
+            put("file_sz", "");
+        }
+    };
+
+    public String getFileName() {
+        return (String) this.fileProps.get("file_path");
+    }
+    public long getFileSize() {
+        return Long.parseLong((String) this.fileProps.get("file_sz"));
+    }
+    private String mountPoint = "";
+
+    public String setFsMountPoint(String val) {
+        this.mountPoint = val;
+        return val;
+    }
+
+    public String getFsMountPoint() {
+        return mountPoint;
+    }
+
+    public String unknown = ""; /* empty */
+    public Boolean active = true;
+    public List<String> someList = new ArrayList<String>(); /* empty */
+
+    public StoragePlugin(Connection c) {
+        client = c;
+    }
+
+    /*
+     * storage_plugin_resizeFileSystem, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_getStatus, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     * meh ?
+     */
+
+    /*
+     * storage_plugin_validate, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_setQoS, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /* TODO: make more generic now only for files
+     * storage_plugin_create, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     * - calls resize secretly.. after "create"
+     */
+    public Boolean storagePluginCreate(String poolUuid, String host,
+            String file, Long size) throws XmlRpcException {
+        /* this is correct ordering stuff */
+        String uuid = this.deDash(poolUuid);
+        ssProps.put("uuid", uuid);
+        ssProps.put("access_host", host);
+        ssProps.put("storage_type", "FileSys");
+        ssProps.put("name", "");
+        ssProps.put("status", "");
+        ssProps.put("admin_user", "");
+        ssProps.put("admin_passwd", "");
+        ssProps.put("admin_host", "");
+        ssProps.put("total_sz", "");
+        ssProps.put("free_sz", "");
+        ssProps.put("used_sz", "");
+        ssProps.put("access_grps", "");
+        ssProps.put("storage_desc", "");
+
+        baseProps.put("ss_uuid", uuid);
+        baseProps.put("state", 2);
+        baseProps.put("uuid", poolUuid);
+        /* some more bogus values */
+        baseProps.put("status", "");
+        baseProps.put("access_path", "");
+        baseProps.put("access_grp_names", "");
+        baseProps.put("name", "");
+        baseProps.put("size", "");
+
+        /*
+         * fileProps.put("fr_type", "File");
+         * fileProps.put("fs_uuid", ssuuid);
+         * fileProps.put("file_path", file);
+         * fileProps.put("file_sz", "");
+         * fileProps.put("ondisk_sz", "");
+         */
+        Object x = (HashMap<String, Object>)callWrapper("storage_plugin_create",
+                this.pluginType, this.ssProps, this.baseProps, file, "File", size);
+
+        if (x == null)
+            return true;
+
+        return true;
+    }
+
+    /*
+     * storage_plugin_createAccessGroups, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_deviceTeardown, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_startPresent, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_listFileSystems, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+    public Boolean storagePluginListFs(String type) throws XmlRpcException {
+        this.pluginType = type;
+        return storagePluginListFs();
+    }
+
+    public Boolean storagePluginListFs() throws XmlRpcException {
+        Map<String, String> y = new HashMap<String, String>();
+        Object x = callWrapper("storage_plugin_listFileSystems",
+                this.pluginType, y);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * storage_plugin_getFileSystemCloneLimits, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_getQoSList, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_stopPresent, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_isCloneable, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /**
+     * .
+     * storage_plugin_mount, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+    public final Boolean storagePluginMount(String nfsHost, String nfsPath,
+            String mntUuid, String mountPoint) throws XmlRpcException {
+        String propUuid = this.deDash(mntUuid);
+        this.setUuid(propUuid);
+        this.setName(propUuid);
+        this.setFsServer(nfsHost);
+        this.setFsSourcePath(nfsHost + ":" + nfsPath);
+        this.setMntUuid(mntUuid);
+        this.setSsUuid(propUuid);
+        this.setSsName("nfs:" + nfsPath);
+        this.setFsMountPoint(mountPoint);
+        this.storagePluginMount();
+        Map<String, Object> x = (Map<String, Object>) callWrapper(
+                "storage_plugin_mount", this.pluginType, this.baseProps,
+                this.ssProps, this.mountPoint, this.unknown, this.active,
+                this.someList);
+        // System.out.println(x);
+        if (x == null) {
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * {ss_uuid=eb1dbafadee9450d876239bb5e3b7f4a,
+     * mount_options=[Ljava.lang.Object;@2d8dea20, status=,
+     * name=nfs:/volumes/cs-data/secondary, state=1,
+     * access_path=cs-mgmt:/volumes/cs-data/secondary,
+     * uuid=6ab917b0-a070-4254-8fe2-e2163ee0e885,
+     * access_grp_names=[Ljava.lang.Object;@4005f23d, free_sz=, size=}
+     */
+    public Boolean storagePluginMount() throws XmlRpcException {
+        Map<String, Object> x = (Map<String, Object>) callWrapper(
+                "storage_plugin_mount", this.pluginType, this.baseProps,
+                this.ssProps, this.mountPoint, this.unknown, this.active,
+                this.someList);
+        // System.out.println(x);
+        if (x == null) {
+            return true;
+        }
+        // System.out.println(x);
+        /*
+         * {ss_uuid=1b8685bf625642cb92ddd4c0d7b18620,
+         * mount_options=[Ljava.lang.Object;@6f479e5f, status=,
+         * name=nfs:/volumes/cs-data/secondary, state=1,
+         * access_path=cs-mgmt:/volumes/cs-data/secondary,
+         * uuid=54d78233-508f-4632-92a6-97fc1311ca23,
+         * access_grp_names=[Ljava.lang.Object;@46eea80c, free_sz=, size=}
+         */
+
+        /*
+         * if (!x.get("ss_uuid").equals(this.ssProps.get("ss_uuid"))) { return
+         * false; } this.ssProps.put("mount_options", x.get("mount_options"));
+         * this.ssProps.put("access_grp_names", x.get("access_grp_names"));
+         */
+        return false;
+    }
+
+    /**
+     * .
+     * storage_plugin_unmount, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     * @return boolean
+     * @throws XmlRpcException
+     */
+    public final Boolean storagePluginUnmount() throws XmlRpcException {
+        Object x = callWrapper("storage_plugin_unmount", this.pluginType,
+                this.baseProps, this.ssProps, this.mountPoint, this.active);
+        if (x == null) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /*
+     * storage_plugin_resize, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_deviceSizeRefresh, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+    /*
+     * storage_plugin_getStorageNames, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_splitClone, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_destroyFileSystem, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_snapRestore, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_updateSERecords, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_getSnapLimits, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * discover_storage_plugins, <class 'agent.api.storageplugin.StoragePlugin'>
+     */
+    /*
+     * <Discover_Storage_Plugins_Result> <storage_plugin_info_list>
+     * <storage_plugin_info plugin_impl_name="oracle.ocfs2.OCFS2.OCFS2Plugin">
+     * <fs_api_version>1,2,7</fs_api_version>
+     * <generic_plugin>False</generic_plugin>
+     * <plugin_version>0.1.0-38</plugin_version>
+     * <filesys_type>LocalFS</filesys_type>
+     * <extended_api_version>None</extended_api_version> <plugin_desc>Oracle
+     * OCFS2 File system Storage Connect Plugin</plugin_desc>
+     * <cluster_required>True</cluster_required> <plugin_name>Oracle OCFS2 File
+     * system</plugin_name> <fs_extra_info_help>None</fs_extra_info_help>
+     * <required_api_vers>1,2,7</required_api_vers>
+     * <file_extra_info_help>None</file_extra_info_help>
+     * <ss_extra_info_help>None</ss_extra_info_help>
+     * <filesys_name>ocfs2</filesys_name> <vendor_name>Oracle</vendor_name>
+     * <plugin_type>ifs</plugin_type> <abilities>
+     * <resize_is_sync>YES</resize_is_sync> <clone_is_sync>YES</clone_is_sync>
+     * <access_control>NO</access_control>
+     * <custom_clone_name>YES</custom_clone_name>
+     * <require_storage_name>NO</require_storage_name>
+     * <backing_device_type>DEVICE_SINGLE</backing_device_type>
+     * <splitclone_while_open>NO</splitclone_while_open>
+     * <custom_snap_name>YES</custom_snap_name> <snapshot>ONLINE</snapshot>
+     * <splitclone>UNSUPPORTED</splitclone> <snap_is_sync>YES</snap_is_sync>
+     * <snapclone>ONLINE</snapclone> <splitclone_is_sync>NO</splitclone_is_sync>
+     * <clone>ONLINE</clone> <resize>ONLINE</resize>
+     * <snapclone_is_sync>YES</snapclone_is_sync> </abilities>
+     * </storage_plugin_info> <storage_plugin_info
+     * plugin_impl_name="oracle.generic.SCSIPlugin.GenericPlugin"> ....
+     */
+    public Boolean discoverStoragePlugins()
+            throws ParserConfigurationException, IOException, Exception {
+        Object result = callWrapper("discover_storage_plugins");
+        // System.out.println(result);
+        Document xmlDocument = prepParse((String) result);
+        /* could be more subtle */
+        String path = "//Discover_Storage_Plugins_Result/storage_plugin_info_list";
+        /*
+         * Capabilities = xmlToMap(path+"/Capabilities", xmlDocument); VMM =
+         * xmlToMap(path+"/VMM", xmlDocument); NTP = xmlToMap(path+"/NTP",
+         * xmlDocument); Date_Time = xmlToMap(path+"/Date_Time", xmlDocument);
+         * Generic = xmlToMap(path, xmlDocument);
+         */
+        if (result != null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * storage_plugin_deviceResize, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_getCloneLimits, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /* TODO: is used for files and dirs..., we only implement files for now...
+     * storage_plugin_destroy, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+    public Boolean storagePluginDestroy(String poolUuid, String file) throws XmlRpcException {
+        /* clean the props, the empty ones are checked, but not for content... */
+        // String uuid = this.deDash(poolUuid);
+        baseProps.put("uuid", "");
+        baseProps.put("access_host", "");
+        baseProps.put("storage_type", "FileSys");
+        ssProps.put("ss_uuid", "");
+        ssProps.put("access_path", "");
+        ssProps.put("uuid", poolUuid);
+        fileProps.put("fr_type", "File");
+        fileProps.put("fs_uuid", poolUuid);
+        fileProps.put("file_path", file);
+        fileProps.put("file_sz", "");
+        fileProps.put("ondisk_sz", "");
+        Object x = (HashMap<String, Object>) callWrapper(
+                "storage_plugin_destroy", this.pluginType, this.baseProps,
+                this.ssProps, this.fileProps);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    public Boolean storagePluginDestroy() throws XmlRpcException {
+        /* clean the props */
+        Object x = (HashMap<String, Object>) callWrapper(
+                "storage_plugin_destroy", this.pluginType, this.baseProps,
+                this.ssProps, this.fileProps);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * storage_plugin_isSnapable, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_getStorageServerInfo, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_removeFromAccessGroup, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_renameAccessGroup, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_stop, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_createMultiSnap, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_getCurrentSnaps, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_getFileInfo, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+    public Boolean storagePluginGetFileInfo() throws XmlRpcException {
+        fileProps = (HashMap<String, Object>)callWrapper("storage_plugin_getFileInfo",
+                this.pluginType, this.baseProps, this.fileProps);
+        if (fileProps == null)
+            return true;
+
+        return false;
+    }
+
+    public Boolean storagePluginGetFileInfo(String file) throws XmlRpcException {
+        fileProps.put("file_path", file);
+        fileProps = (HashMap<String, Object>)callWrapper("storage_plugin_getFileInfo",
+                this.pluginType,
+                this.ssProps,
+                this.baseProps,
+                this.fileProps);
+        if (fileProps == null)
+            return true;
+
+        return false;
+    }
+
+    public Boolean storagePluginGetFileInfo(String poolUuid, String host,
+            String file) throws XmlRpcException {
+        /* file path is the full path */
+        String uuid = this.deDash(poolUuid);
+        baseProps.put("uuid", poolUuid);
+        baseProps.put("access_host", host);
+        ssProps.put("access_path", "");
+        ssProps.put("uuid", uuid);
+        ssProps.put("state", 1);
+        ssProps.put("ss_uuid", poolUuid);
+        ssProps.put("name", "");
+        fileProps.put("file_path", file);
+        fileProps = (HashMap<String, Object>)callWrapper("storage_plugin_getFileInfo",
+                this.pluginType,
+                this.ssProps,
+                this.baseProps,
+                this.fileProps);
+        if (fileProps == null)
+            return true;
+
+        return false;
+    }
+
+    /* TODO: input checking of ss and base
+    /*
+     * storage_plugin_getFileSystemInfo, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     * requires a minumum of uuid, access_host, storage_type
+     *   ss_uuid, access_path, uuid (the ss
+     */
+    public Boolean storagePluginGetFileSystemInfo(String propUuid,
+            String mntUuid, String nfsHost, String nfsPath)
+            throws XmlRpcException {
+        /* clean the props */
+        this.setUuid(propUuid);
+        this.setSsUuid(propUuid);
+        this.setMntUuid(mntUuid);
+        this.setFsHost(nfsHost);
+        this.setFsSourcePath(nfsHost + ":" + nfsPath);
+        this.setFsType("FileSys");
+        Map<String, Object> props = (HashMap<String, Object>) callWrapper(
+                "storage_plugin_getFileSystemInfo", this.pluginType,
+                this.baseProps, this.ssProps);
+        this.ssProps = props;
+        if (props == null)
+            return false;
+
+        return true;
+    }
+
+    /* TODO: double check base and ss ordering!!!! */
+    public Boolean storagePluginGetFileSystemInfo() throws XmlRpcException {
+        HashMap<String, Object> props = (HashMap<String, Object>) callWrapper(
+                "storage_plugin_getFileSystemInfo", this.pluginType,
+                this.baseProps, this.ssProps);
+        this.ssProps = props;
+        // System.out.println(props);
+        if (props == null)
+            return false;
+
+        return true;
+    }
+
+    /*
+     * storage_plugin_clone, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_list, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_getInfo, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_snapRemove, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_getCapabilities, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_createSnap, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_getFileSystemSnapLimits, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_remove, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_getCurrentClones, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_online, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_isRestorable, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_iSCSI_logoutTarget, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: target - default: None
+     * argument: portal - default: None
+     */
+
+    /*
+     * storage_plugin_discover, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_start, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_removeAccessGroups, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_refresh, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_getAccessGroups, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_iSCSI_deletePortal, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: portal - default: None
+     */
+
+    /*
+     * storage_plugin_createFileSystem, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_cloneFromSnap, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_addToAccessGroup, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_offline, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_listMountPoints, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+    /* should really make that stuff a class as this is weird now... */
+    public Boolean storagePluginListMounts() throws XmlRpcException {
+        Object x = callWrapper("storage_plugin_listMountPoints",
+                this.pluginType, this.baseProps);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    public Boolean storagePluginListMounts(String uuid) throws XmlRpcException {
+        /* should allow for putting in the uuid */
+        Object x = callWrapper("storage_plugin_listMountPoints",
+                this.pluginType, this.baseProps);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Test.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Test.java
new file mode 100644
index 0000000..850daf8
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Test.java
@@ -0,0 +1,546 @@
+/*******************************************************************************
+ * Licensed 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 com.cloud.hypervisor.ovm3.object;
+
+// import java.io.File;
+import java.math.BigInteger;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+
+import java.util.Map.Entry;
+
+// mport org.apache.commons.io.FileUtils;
+import org.apache.xmlrpc.XmlRpcException;
+
+import com.cloud.hypervisor.ovm3.object.Linux.FileSystem;
+
+public class Test {
+    // private static Sanitize _insane = new Sanitize();
+    /*
+     * Other trinket
+     * https://192.168.1.51:7002/ovm/core/OVMManagerCoreServlet&c=1
+     * &s=-1&lb=p&t=2
+     * &p=1dd5e891d9d0edbd81c2a69ab3d1b7ea%2C2f3b7fca202045058ae388d22f21f508'
+     */
+    public static void main(final String[] args) throws Exception {
+        boolean CheckNet = false;
+        boolean CheckNtp = false;
+        boolean CheckLinux = false;
+        boolean CheckCommon = false;
+        boolean CheckCluster = false;
+        boolean CheckRepo = false;
+        boolean CheckPool = false;
+        boolean CheckOcfs2 = false;
+        boolean CheckNFSPlugin = false;
+        boolean CheckXen = false;
+        boolean CheckVnc = false;
+
+        boolean CheckCombine = false;
+        boolean CheckVmInfo = false;
+        boolean CheckUuid = false;
+        boolean CheckBridge = false;
+        boolean CheckFs = false;
+        boolean CheckPlugin = true;
+
+
+        try {
+            Connection c;
+            Socket client;
+            String hostname = "ovm-2";
+            try{
+                client = new Socket(hostname, 8899);
+            } catch (Exception e) {
+                hostname = "localhost";
+                client = new Socket(hostname, 8899);
+            }
+            if (!client.isConnected()) {
+                System.out.println("No connection");
+            } else {
+                System.out.println("connected to: " + hostname);
+            }
+            client.close();
+            try {
+                System.out.println("trying to connect to " + hostname);
+                c = new Connection(hostname, 8899, "oracle", "test123");
+            } catch (Exception e) {
+                throw new Exception("Unable to connect to " + hostname
+                       + " port seemed to listen...");
+            }
+            /*
+             * needs to be finished and implement ovs + bridge, or do we count
+             * on chef ?
+             */
+            if (CheckPlugin) {
+                CloudStackPlugin csp = new CloudStackPlugin(c);
+                try {
+                    System.out.println(csp.ovsUploadSshKey("test", "testing 123"));
+//                            FileUtils.readFileToString(new File(""))));
+                    String ip = "169.254.1.202";
+                    String domain = "i-2-29-VM";
+                    String pubnic = "bond0";
+                    // System.out.println(csp.ovsDom0Stats(pubnic));
+                    // System.out.println(csp.domrCheckPort(ip, 3922, 3, 3));
+                    // System.out.println(csp.domrCheckSsh(ip));
+                    System.out.println("vnc Port: "+ csp.getVncPort(domain));
+                    // System.out.println(csp.domrExec(ip, "ls -l").getStdOut());
+                    Map<String, String> stats = csp.ovsDomUStats(domain);
+                    /* for (final Entry<String, String> stat : stats.entrySet()) {
+                        System.out.println(stat.getKey() + " "
+                                + Double.parseDouble(stat.getValue()));
+                    } */
+                    Thread.sleep(1000);
+                    Map<String, String> stats2 = csp.ovsDomUStats(domain);
+                    for (final Entry<String, String> stat : stats2.entrySet()) {
+                        String key = stat.getKey();
+                        Double delta = Double.parseDouble(stat.getValue())
+                                - Double.parseDouble(stats.get(key));
+                        System.out.println(stat.getKey() + ": " + delta);
+                    }
+                    Integer cpus = Integer.parseInt(stats.get("vcpus"));
+                    Double d_cpu = Double.parseDouble(stats.get("cputime"))
+                            - Double.parseDouble(stats2.get("cputime"));
+                    Double d_time = Double.parseDouble(stats.get("uptime"))
+                            - Double.parseDouble(stats2.get("uptime"));
+                    Double cpupct = d_cpu/d_time * 100 * cpus;
+                    System.out.println(cpupct);
+                } catch (Exception e) {
+                    System.out.println("nooooo!!!" + e.getMessage());
+                    throw new Exception(e.getMessage());
+                }
+            }
+            if (CheckFs) {
+                Linux host = new Linux(c);
+
+                Map<String, Linux.FileSystem> fsList = host
+                        .getFileSystemList("nfs");
+                Linux.FileSystem fs = fsList.get("nfs");
+                System.out.println(fs + " " + fsList);
+            }
+            if (CheckUuid) {
+                System.out.println(UUID.nameUUIDFromBytes(("test@test-test")
+                        .getBytes()));
+            }
+            if (CheckNet) {
+                Network net = new Network(c);
+                System.out.println(net.getInterfaceByName("c0a80100"));
+                // net.discoverNetwork();
+                System.out
+                        .println(net.getInterfaceByName("c0a80100").getAddress());
+                System.out.println(net.getInterfaceByIp("192.168.1.65").getName());
+                // System.out.println(bridge.getMac());
+            }
+            if (CheckCommon == true) {
+                Common Com = new Common(c);
+                String x = Com.getApiVersion();
+                System.out.println("Api Version: " + x);
+                String y = Com.sleep(1);
+                System.out.println("Sleep: " + y);
+                String msg = Com.echo("testing 1 2 3");
+                System.out.println("Echo: " + msg);
+                /*
+                 * String disp = Com.dispatch ("192.168.1.60", "hoeleboele");
+                 * System.out. println("dispatch" + disp);
+                 */
+            }
+            /* check stuff */
+            if (CheckLinux == true) {
+                Linux Host = new Linux(c);
+                Host.discoverHardware();
+                Host.discoverServer();
+                System.out.println("hwVMM: " + Host.hwVMM.toString());
+                System.out.println("hwSystem: " + Host.hwSystem.toString());
+                System.out.println("Cap: " + Host.Capabilities.toString());
+                System.out.println("VMM: " + Host.VMM.toString());
+                System.out.println("NTP: " + Host.NTP.toString());
+                System.out.println("DT: " + Host.DateTime.toString());
+                System.out.println("Gen: " + Host.Generic.toString());
+                System.out.println("time; " + Host.getDateTime());
+                // needs to be within bounds of 1970... *grin*
+                System.out.println("update time to 1999: "
+                        + Host.setDateTime(1999, 12, 31, 12, 0, 0));
+                System.out.println("lastboot: " + Host.getLastBootTime());
+                System.out.println("time: " + Host.localTime);
+                Calendar now = Calendar.getInstance();
+                int year = now.get(Calendar.YEAR);
+                int month = now.get(Calendar.MONTH); // Note: zero based!
+                int day = now.get(Calendar.DAY_OF_MONTH);
+                int hour = now.get(Calendar.HOUR_OF_DAY);
+                int minute = now.get(Calendar.MINUTE);
+                int second = now.get(Calendar.SECOND);
+                int millis = now.get(Calendar.MILLISECOND);
+                System.out.println("set time to now: "
+                        + Host.setDateTime(year, month, day, hour, minute,
+                                second));
+                System.out.println("lastboot: " + Host.getLastBootTime());
+                System.out.println("time: " + Host.localTime);
+                System.out.println("update password: "
+                        + Host.updateAgentPassword("oracle", "test123"));
+                System.out.println("set time zone: "
+                        + Host.setTimeZone("Europe/London", false));
+                System.out.println("time zone: " + Host.getTimeZone() + ", "
+                        + Host.timeZone + ", " + Host.timeUTC);
+                System.out.println("set time zone: "
+                        + Host.setTimeZone("Europe/Amsterdam", true));
+                System.out.println("time zone: " + Host.getTimeZone() + ", "
+                        + Host.timeZone + ", " + Host.timeUTC);
+                // System.out.println("Luns: " + Host.discoverPhysicalLuns());
+
+            }
+
+            /* setting up ntp */
+            if (CheckNtp == true) {
+                Ntp ntp = new Ntp(c);
+                ntp.getDetails();
+                System.out.println("ntp isServer: " + ntp.isServer());
+                System.out.println("ntp isRunning: " + ntp.isRunning());
+                System.out.println("ntp Servers: " + ntp.servers());
+                ntp.addServer("192.168.1.1");
+                ntp.addServer("192.168.1.61");
+                System.out.println("ntp set: " + ntp.setNtp(true));
+                System.out.println("ntp enable: " + ntp.enableNtp());
+                ntp.getDetails();
+                System.out.println("ntp isServer: " + ntp.isServer());
+                System.out.println("ntp isRunning: " + ntp.isRunning());
+                System.out.println("ntp Servers: " + ntp.servers());
+                System.out.println("ntp disable: " + ntp.disableNtp());
+                System.out.println("ntp reset: " + ntp.setNtp("", false));
+            }
+
+            if (CheckNFSPlugin == true) {
+                Linux lin = new Linux(c);
+                lin.discoverServer();
+                System.out.println(lin.getCapabilities());
+                Map<String, FileSystem> fsList = lin.getFileSystemList("nfs");
+                System.out.println(fsList);
+                System.out.println(BigInteger.valueOf(lin.getMemory()
+                        .longValue()));
+                System.out.println(lin.getFreeMemory());
+                BigInteger totalmem = BigInteger.valueOf(lin.getMemory()
+                        .longValue());
+                BigInteger freemem = BigInteger.valueOf(lin.getFreeMemory()
+                        .longValue());
+                System.out.println(totalmem.subtract(freemem));
+                /*
+                 * for (final Map.Entry<String, Linux.FileSystem> entry : fsList
+                 * .entrySet()) {
+                 * Linux.FileSystem fs = entry.getValue();
+                 * StoragePlugin sp = new StoragePlugin(c);
+                 * String propUuid = sp.deDash(fs.getUuid());
+                 * String mntUuid = fs.getUuid();
+                 * String fsType = "FileSys";
+                 * sp.setUuid(propUuid);
+                 * sp.setSsUuid(propUuid);
+                 * sp.setName(propUuid);
+                 * sp.setFsType(fsType);
+                 * sp.setFsServer(fs.getHost());
+                 * sp.setFsSourcePath(fs.getDevice());
+                 * sp.storagePluginGetFileSystemInfo();
+                 * }
+                 */
+                /*
+                 * StoragePlugin sp = new StoragePlugin(c);
+                 * String propUuid = sp.deDash(sp.newUuid());
+                 * String mntUuid = sp.newUuid();
+                 * String nfsHost = "cs-mgmt";
+                 * String nfsPath = "/volumes/cs-data/primary";
+                 * String fsType = "FileSys";
+                 * sp.setUuid(propUuid);
+                 * sp.setName(propUuid);
+                 * sp.setFsType(fsType);
+                 * sp.setFsServer(nfsHost);
+                 * sp.setFsSourcePath(nfsHost + ":" + nfsPath);
+                 * // sp.fsTarget("/nfsmnt/" + mntUuid);
+                 * sp.setFsMountPoint("/nfsmnt/" + mntUuid);
+                 * sp.setMntUuid(mntUuid);
+                 * sp.setSsUuid(propUuid);
+                 * sp.setSsName("nfs:" + nfsPath);
+                 * if (sp.storagePluginMount() != null) {
+                 * lin.discoverMountedFs("nfs");
+                 * // System.out.println(sp.extprops);
+                 * StoragePlugin store = new StoragePlugin(c);
+                 * store.setUuid(propUuid);
+                 * store.setSsUuid(propUuid);
+                 * store.setMntUuid(mntUuid);
+                 * store.setFsHost(nfsHost);
+                 * store.setFsSourcePath(nfsHost + ":" + nfsPath);
+                 * // store.setFsMountPoint(pool.getPath());
+                 * store.storagePluginGetFileSystemInfo();
+                 * System.out.println(store.getTotalSize());
+                 * sp.setFsSourcePath(nfsHost + ":" + nfsPath);
+                 * sp.storagePluginUnmount();
+                 * }
+                 */
+            }
+
+            /* still needs to be finished! */
+            if (CheckRepo == true) {
+                Repository repo = new Repository(c);
+                String repouuid = repo.deDash(repo.newUuid());
+                String remote = "cs-mgmt:/volumes/cs-data/secondary";
+                String local = "/OVS/Repositories/" + repouuid;
+                String url = "http://nibbler/~funs/iso";
+                String iso = url + "/gentoo.iso";
+                String vhd = url + "/ovm.raw";
+                String isouuid = repo.deDash(repo.newUuid());
+                String vmuuid = repo.deDash(repo.newUuid());
+
+                repo.mountRepoFs(remote, local);
+                repo.createRepo(remote, repouuid, repouuid, "My Comment");
+                repo.discoverRepoDb();
+                // repo.discoverRepo(repouuid);
+                repo.importIso(iso, isouuid + ".iso", repouuid, "");
+                repo.importVirtualDisk(vhd, vmuuid + ".img", repouuid, "");
+                repo.deleteRepo(repouuid, true);
+                repo.unmountRepoFs(local);
+                repo.discoverRepoDb();
+                repo.discoverRepo(repouuid);
+            }
+
+            if (CheckPool == true) {
+                System.out.println("checking pool");
+                Pool pool = new Pool(c);
+                pool.discoverServerPool();
+                System.out.println(pool.getPoolAlias());
+                System.out.println(pool.getPoolId());
+                if (pool.getPoolId().contentEquals("TEST")) {
+                    System.out.println("pool equals test");
+                } else {
+                    System.out.println("pool" + pool.getPoolId());
+                }
+                List<String> ips = new ArrayList<String>();
+                ips.add("192.168.1.64");
+                ips.add("192.168.1.65");
+                /*
+                 * pool.setPoolIps(ips);
+                 * pool.setPoolMemberIpList();
+                 */
+                /*
+                 * if (pool.poolFsId != null) {
+                 * pool.leaveServerPool(pool.poolFsId);
+                 * }
+                 */
+                System.out.println("pool members: "
+                        + pool.getPoolMemberIpList());
+            }
+
+            if (CheckOcfs2 == true) {
+                PoolOCFS2 poolocfs = new PoolOCFS2(c);
+                poolocfs.discoverPoolFs();
+                // poolocfs.ocfs2GetMetaData();
+            }
+
+            if (CheckCluster == true) {
+                Pool pool = new Pool(c);
+                pool.discoverServerPool();
+                Cluster Clos = new Cluster(c);
+                // Clos.destroyCluster(pool.poolFsId);
+                if (pool.getPoolId() != null) {
+                    // Clos.deconfigureServerForCluster(pool.poolId);
+                }
+                System.out.println("Cluster online: " + Clos.isClusterOnline());
+                System.out.println("Cluster discover: "
+                        + Clos.discoverCluster());
+
+            }
+
+            if (CheckXen == true) {
+                Xen xen = new Xen(c);
+                xen.listVms();
+                xen.createVm("xx", "xx");
+                /* xen.deleteVm(repoId, vmId); */
+            }
+
+            /* check the combination of stuff */
+            if (CheckCombine == true) {
+                /* prepare host, mgr should have "steady uuid" */
+                OvmObject Go = new OvmObject();
+                String masterUuid = Go.deDash(Go.newUuid());
+
+                /* check capabilities */
+                Linux Host = new Linux(c);
+                Host.discoverServer();
+                /* setup pool and role, needs utility to be able to do shit */
+                Pool pool = new Pool(c);
+
+                /* Info comes from Linux, not the pool, but needs to be set in the pool -sigh- */
+                if (Host.Get("Server_Roles").contentEquals(
+                        pool.getValidRoles().toString())) {
+                    pool.setServerRoles(pool.getValidRoles());
+                }
+                if (Host.Get("Membership_State").contentEquals("Unowned")) {
+                    pool.takeOwnership(masterUuid, "");
+                }
+                /* get primary storage mounted and registered */
+
+                StoragePlugin sp = new StoragePlugin(c);
+                String propUuid = sp.deDash(sp.newUuid());
+                String mntUuid = sp.newUuid();
+                String nfsHost = "cs-mgmt";
+                String nfsPath = "/volumes/cs-data/primary";
+                String fsType = "FileSys";
+                sp.setUuid(propUuid);
+                sp.setName(propUuid);
+                sp.setFsType(fsType);
+                sp.setFsServer(nfsHost);
+                sp.setFsSourcePath(nfsHost + ":" + nfsPath);
+                sp.setMntUuid(mntUuid);
+                sp.setSsUuid(propUuid);
+                sp.setSsName("nfs:" + nfsPath);
+                sp.setFsMountPoint("/nfsmnt/" + mntUuid);
+
+                /* setup a repo */
+                Repository repo = new Repository(c);
+                String repouuid = repo.deDash(repo.newUuid());
+                String remote = "cs-mgmt:/volumes/cs-data/secondary";
+                String repopath = "/OVS/Repositories/" + repouuid;
+                String url = "http://nibbler/~funs/iso";
+                String iso = url + "/gentoo.iso";
+                String vhd = url + "/ovm.raw";
+                String isouuid = repo.deDash(repo.newUuid());
+                String vmuuid = repo.deDash(repo.newUuid());
+
+                repo.discoverRepoDb();
+
+                repo.mountRepoFs(remote, repopath);
+                repo.createRepo(remote, repouuid, repouuid, "My Comment");
+                repo.discoverRepoDb();
+                // repo.discoverRepo(repouuid);
+                String isoname = isouuid + ".iso";
+                String imgname = vmuuid + ".img";
+                repo.importIso(iso, isoname, repouuid, "");
+                repo.importVirtualDisk(vhd, imgname, repouuid, "");
+
+                if (sp.storagePluginMount() != null) {
+                    /* prep the VM disk to go to primary storage */
+                    Linux vmDisk = new Linux(c);
+                    String srcvmimg = repopath + "/VirtualDisks/" + imgname;
+                    String dstvmimg = sp.getFsMountPoint() + "/" + imgname;
+                    /* the "solving" of no real primary and secondary storage in OVS */
+                    vmDisk.copyFile(srcvmimg, dstvmimg);
+                    Xen xen = new Xen(c);
+
+                    /*
+                     * 'vfb':
+                     * ['type=vnc,vncunused=1,vnclisten=127.0.0.1,keymap=en-us']
+                     */
+                    /*
+                     * 'disk': [
+                     * 'file:/OVS/Repositories/0004fb0000030000aeaca859e4a8f8c0/VirtualDisks/0004fb0000120000c444117fd87ea251.img,xvda,w']
+                     */
+                    /* 'vif': ['mac=00:21:f6:00:00:00,bridge=c0a80100'] */
+                    String vmName = Go.deDash(Go.newUuid());
+
+                    Xen.Vm vm = xen.getVmConfig();
+                    vm.setVmName(vmName);
+                    vm.setVmUuid(vmName);
+
+                    vm.addRootDisk(dstvmimg);
+
+                    vm.addVif(0, "c0a80100", "00:21:f6:00:00:02");
+                    vm.setVnc("0.0.0.0");
+                    xen.createVm(repouuid, vm.vmName);
+                    xen.startVm(repouuid, vm.vmName);
+                    /*
+                     * vm.stopVm(repouuid, vm.vmUuid); vm.deleteVm(repouuid,
+                     * vm.vmUuid);
+                     */
+                    System.out.println("Created VM with: " + vmName);
+                    System.out.println("repo: " + repouuid);
+                    System.out.println("image: " + imgname);
+                    System.out.println("disk: " + dstvmimg);
+                    System.out.println("master: " + masterUuid);
+                }
+            }
+            if (CheckVmInfo == true) {
+                Xen host = new Xen(c);
+                /* make an itterator */
+                // String vmId = "14fc3846-45e5-3c08-ad23-432ceb07407b";
+                // String repoId = "f12842eb-f5ed-3fe7-8da1-eb0e17f5ede8";
+                String vmName = "s-1-VM";
+                Xen.Vm vm = null;
+                Xen.Vm ovm = null;
+                try {
+                    /* backwards for now: */
+                    ovm = host.getRunningVmConfig(vmName);
+                    System.out.println(ovm.getVmRootDiskPoolId());
+                    /* new style */
+                    vm = host.getVmConfig(vmName);
+                    vm.addIso("test.iso");
+                    if (vm.getVmUuid().equals("")) {
+                        System.out.println("no vm found");
+                    } else {
+                        System.out.println(vm.getVmParams());
+                        System.out.println(vm.getVmDisks());
+                        System.out.println(vm.getVmUuid());
+                        System.out.println(vm.getPrimaryPoolUuid());
+                        vm.removeDisk("test.iso");
+                        System.out.println(vm.getVmParams().get("disk"));
+                    }
+
+                } catch (XmlRpcException e) {
+                    System.out.println("Failed to get VM details for " + vmName
+                            + " on " + c.getIp());
+                }
+            }
+            if (CheckVnc == true) {
+                Xen vms = new Xen(c);
+                Xen.Vm vm = vms.listVms().get("Domain-0");
+                vm.setVncAddress("0.0.0.0");
+                vm.setVncPassword("testikkel");
+                vm.setVnc();
+                System.out.println(vm._vmVnc + " " + vm.vmVnc);
+            }
+            if (CheckBridge) {
+                Network net = new Network(c);
+                for (final Map.Entry<String, Network.Interface> entry : net.getInterfaceList().entrySet()) {
+                    Network.Interface iface = entry.getValue();
+                    System.out.println("interface: " + iface.getName() + ", phys: " + iface.getPhysical() + ", type: " + iface.getIfType());
+                }
+                String physInterface = "bond0";
+                Integer vlanId = 2;
+                String physVlanInt = physInterface + "." + vlanId.toString();
+                String brName = "c0a80100" + "." + vlanId.toString();
+                System.out.println(net.getInterfaceByName(physVlanInt)
+                        + " " + net.getInterfaceByName(brName));
+
+                if (net.getInterfaceByName(physVlanInt) == null)
+                    net.startOvsVlanConfig(physInterface, vlanId);
+
+                if (net.getInterfaceByName(brName) == null)
+                    net.startOvsBrConfig(brName, physVlanInt);
+
+                // net.startOvsLocalConfig("control0");
+                // net.ovsBrConfig("start", "control0", "lo");
+                // net.ovsIpConfig("control0", "static", "169.254.0.1",
+                // "255.255.0.0");
+                // execOverSsh("route del -net 169.254.0.0/16");
+            }
+                /* cleanup */
+                /*
+                 * repo.deleteRepo(repouuid, true);
+                 * repo.unmountRepoFs(repopath); repo.discoverRepoDb();
+                 * repo.discoverRepo(repouuid); sp.storagePluginUnmount();
+                 */
+
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.getMessage();
+        }
+    }
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Xen.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Xen.java
new file mode 100644
index 0000000..7d30cab
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Xen.java
@@ -0,0 +1,1169 @@
+/*******************************************************************************
+ * Licensed 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.
+ ******************************************************************************/
+/* contains VM related stuff too */
+
+package com.cloud.hypervisor.ovm3.object;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.xmlrpc.XmlRpcException;
+// import org.w3c.dom.Document;
+
+/*
+ * should become an interface implementation
+ */
+public class Xen extends OvmObject {
+    public Xen(Connection c) {
+        client = c;
+    }
+
+    private Map<String, Vm> vmList = null;
+
+    /*
+     * ugly for now, but just insert a "default" VM in the Xen class will strip
+     * it out later if we need to
+     */
+    private Vm vm = new Vm();
+
+    /* a vm class....
+     * Setting up a VM is different than retrieving one from OVM.
+     * retrieve with list:
+     * {state=-b----, vcpus=1, on_poweroff=destroy, cpu_weight=27500, cpus=[Ljava.lang.Object;@4239410a, cpu_cap=0, on_xend_start=ignore, description=, name=0d87b9506da945fd98fb979bb345c187, features=, bootloader_args=-q, shadow_memory=0, domid=7, pool_name=Pool-0, maxmem=256, store_mfn=873241, console_mfn=873240, status=2, builder=linux, image={pci=[Ljava.lang.Object;@3cdd197d, device_model=/usr/lib/xen/bin/qemu-dm, superpages=0, videoram=4, tsc_mode=0, nomigrate=0, notes=[Ljava.lang.Object;@57b47cc2, kernel=, expose_host_uuid=0}, bootloader=/usr/bin/pygrub, cpu_time=1.328733473, memory=256, on_crash=restart, online_vcpus=1, on_reboot=restart, device={console=[Ljava.lang.Object;@a6ad18a, vbd=[Ljava.lang.Object;@6ae2c05d, vkbd=[Ljava.lang.Object;@4cc3507d, vfb=[Ljava.lang.Object;@2ad965ea, vif=[Ljava.lang.Object;@26b1fba0}, start_time=1390033675.38, uuid=0d87b950-6da9-45fd-98fb-979bb345c187, on_xend_stop=ignore}
+     * while setting one up goes according to vmParams, boggle me.
+     * According to the python agent it should be this:
+     * (/usr/lib64/python2.4/site-packages/agent/lib/xenxm.py)
+     * VM_PARAMS =  {
+            # option: setter
+            'cpu_cap': set_cpu_cap,
+            'cpus': set_cpus,
+            'cpu_weight': set_cpu_weight,
+            'disk_other_config': set_disk_other_config,
+            'disk': set_disk,
+            'maxmem': set_maxmem,
+            'memory': set_memory,
+            'name': set_name,
+            'vcpus': set_vcpus,
+            'vif_other_config': set_vif_other_config,
+            'vif': set_vif
+        }
+     * or:
+     * (/usr/lib64/python2.4/site-packages/agent/lib/xenvm.py)
+       VM_CFG =  {
+            # option: checker,
+            'access_control': check_list,
+            'acpi': check_int,
+            'apic': check_int,
+            'blkif': check_int,
+            'bootargs': check_str,
+            'bootloader': check_str,
+            'boot': check_str,
+            'builder': check_str,
+            'console_autoconnect': check_int,
+            'cpu_cap': check_int,
+            'cpuid_check': check_list,
+            'cpuid': check_list,
+            'cpus': check_str_or_list,
+            'cpu': check_int,
+            'cpu_weight': check_int,
+            'device_model': check_str,
+            'dhcp': check_str,
+            'disk_other_config': check_list,
+            'disk': check_list,
+            'display': check_int,
+            'expose_host_uuid': check_int,
+            'extra': check_str,
+            'fda': check_str,
+            'fdb': check_str,
+            'features': check_str,
+            'gateway': check_str,
+            'guest_os_type': check_str,
+            'hap': check_int,
+            'hostname': check_str,
+            'hpet': check_int,
+            'interface': check_str,
+            'ioports': check_list,
+            'ip': check_str,
+            'irq': check_list,
+            'isa': check_int,
+            'kernel': check_str,
+            'keymap': check_str,
+            'loader': check_str,
+            'localtime': check_int,
+            'machine_address_size': check_int,
+            'maxmem': check_int,
+            'maxvcpus': check_int,
+            'memory': check_int,
+            'monitor_path': check_str,
+            'monitor': check_int,
+            'name': check_str,
+            'netif': check_int,
+            'netmask': check_str,
+            'nfs_root': check_str,
+            'nfs_server': check_str,
+            'nographic': check_int,
+            'nomigrate': check_int,
+            'on_crash': check_str,
+            'on_poweroff': check_str,
+            'on_reboot': check_str,
+            'on_xend_start': check_str,
+            'on_xend_stop': check_str,
+            'opengl': check_int,
+            'pae': check_int,
+            'pasued': check_int,
+            'pci_msitranslate': check_int,
+            'pci_power_mgmt': check_int,
+            'pci': check_list,
+            'ramdisk': check_str,
+            'root': check_str,
+            'rtc_timeoffset': check_int,
+            's3_integrity': check_int,
+            'sdl': check_int,
+            'serial': check_str,
+            'shadow_memory': check_int,
+            'soundhw': check_str,
+            'stdvga': check_int,
+            'superpages': check_int,
+            'suppress_spurious_page_faults': check_int,
+            'target': check_int,
+            'timer_mode': check_int,
+            'tpmif': check_int,
+            'tsc_mode': check_int,
+            'usbdevice': check_str,
+            'usb': check_int,
+            'uuid': check_str,
+            'vcpus': check_int,
+            'vfb': check_list,
+            'vhpt': check_int,
+            'videoram': check_int,
+            'vif2': check_list,
+            'vif_other_config': check_list,
+            'vif': check_list,
+            'viridian': check_int,
+            'vncconsole': check_int,
+            'vncdisplay': check_int,
+            'vnclisten': check_str,
+            'vncpasswd': check_str,
+            'vncunused': check_int,
+            'vnc': check_int,
+            'vpt_align': check_int,
+            'vscsi': check_list,
+            'vtpm': check_list,
+            'xauthority': check_str,
+            'xen_platform_pci': check_int,
+        }
+     */
+    public class Vm {
+        /* vm attributes */
+        public ArrayList<String> _vmVnc = new ArrayList<String>();
+        public Map<String, String> vmVnc = new HashMap<String, String>() {
+            {
+                put(new String("type"), "vnc");
+                put(new String("vncunused"), "1");
+                put(new String("vnclisten"), "127.0.0.1");
+                put(new String("keymap"), "en-us");
+            }
+        };
+        /*
+         * 'vfb': [ 'type=vnc,vncunused=1,vnclisten=127.0.0.1,keymap=en-us']
+         */
+        public List<String> _vmDisks = new ArrayList<String>();
+        public Map<String, String> vmDisk = new HashMap<String, String>() {
+            {
+                put(new String("id"), "");
+                put(new String("uuid"), "");
+                put(new String("dev"), "");
+                put(new String("bootable"), "1");
+                put(new String("mode"), "w");
+                put(new String("VDI"), "");
+                put(new String("backend"), "0");
+                put(new String("protocol"), "x86_32-abi");
+                put(new String("uname"), "");
+            }
+        };
+        /*
+         * 'disk': [
+         * 'file:/OVS/Repositories/0004fb0000030000aeaca859e4a8f8c0/VirtualDisks/0004fb0000120000c444117fd87ea251.img,xvda,w']
+         */
+        String[] _xvmVifs = new String[6];
+        public ArrayList<String> _vmVifs = new ArrayList<String>();
+        public Map<String, String> vmVifs = new HashMap<String, String>() {
+            {
+                put(new String("id"), "");
+                put(new String("dev"), "");
+                put(new String("mac"), "");
+                put(new String("rate"), "");
+            }
+        };
+        /*
+         * 'vif': [ 'mac=00:21:f6:00:00:00,bridge=c0a80100']
+         */
+
+        public String vmSimpleName = ""; /* human readable name */
+        public String vmName = ""; /* usually vm uuid */
+        public String vmUuid = "";
+        /*
+         * the pool the vm.cfg will live
+         * on, this is the same as the
+         * primary storage pool (should be unified with disk pool ?)
+         */
+        public String vmPrimaryPoolUuid = "";
+        public String vmOnReboot = "restart";
+        /*
+         * default weight, weight is relative to
+         * all VMs
+         */
+        public int vmCpuWeight = 27500;
+
+        public int vmMemory = 256; /* minimum memory allowed */
+        public int vmCpuCap = 0;
+        public int vmMaxVcpus = 0; /*
+                                    * allows for dynamic adding of vcpus if
+                                    * higher than vcpus
+                                    */
+        public int vmVcpus = 1; /* default to 1, can't be higher than maxvCpus */
+        public Boolean vmHa = false; /* high available */
+        public String vmDescription = "";
+        public String vmOnPoweroff = "destroy";
+        public String vmOnCrash = "restart";
+        public String vmBootloader = "/usr/bin/pygrub"; /* if pv ? */
+        public String vmBootArgs = "";
+        public String vmExtra = "";
+        public String vmOs = "Other Linux"; /* default to linux */
+
+        public String vmCpuCompatGroup = "";
+        public String vmDomainType = "xen_pvm"; /* pv is default */
+        public String vmState = "------";
+        private int _vmDiskZero = 97;
+        private int _vmDisk = _vmDiskZero;
+
+        public boolean isControlDomain() {
+            if (this.vmUuid
+                    .contentEquals("00000000-0000-0000-0000-000000000000"))
+                return true;
+            return false;
+        }
+
+        public boolean setPrimaryPoolUuid(String poolId) {
+            this.vmPrimaryPoolUuid = poolId;
+            return true;
+        }
+
+        public String getPrimaryPoolUuid() {
+            return this.vmPrimaryPoolUuid;
+        }
+
+        public Map<String, Object> vmParams = new HashMap<String, Object>() {
+            {
+                put("vif", _vmVifs);
+                put("OVM_simple_name", vmSimpleName);
+                put("disk", _vmDisks);
+                put("bootargs", vmBootArgs);
+                put("uuid", vmUuid);
+                put("on_reboot", vmOnReboot);
+                put("cpu_weight", vmCpuWeight);
+                put("memory", vmMemory);
+                put("cpu_cap", vmCpuCap);
+                put("maxvcpus", vmMaxVcpus);
+                put("OVM_high_availability", vmHa);
+                put("OVM_description", vmDescription);
+                put("on_poweroff", vmOnPoweroff);
+                put("on_crash", vmOnCrash);
+                put("bootloader", vmBootloader);
+                put("name", vmName);
+                put("guest_os_type", vmOs);
+                put("vfb", _vmVnc);
+                put("vcpus", vmVcpus);
+                put("OVM_cpu_compat_group", vmCpuCompatGroup);
+                put("OVM_domain_type", vmDomainType);
+                // put("state", vmState);
+                put("extra", vmExtra);
+                // put("builder", vmBuilder);
+            };
+        };
+
+        public Map<String, Object> getVmParams() {
+            return this.vmParams;
+        }
+
+        public void setVmParams(Map<String,Object> params) {
+            this.vmParams = params;
+        }
+
+        public boolean setVmExtra(final String args) {
+            vmParams.put("extra", args);
+            return true;
+        }
+
+        public String getVmExtra() {
+            return (String) vmParams.get("extra");
+        }
+        public boolean setVmBootArgs(final String args) {
+            vmParams.put("bootargs", args);
+            return true;
+        }
+
+        public String getVmBootArgs() {
+            return (String) vmParams.get("bootargs");
+        }
+
+        public Boolean setVmMaxCpus(Integer val) {
+            if (getVmCpus() > val) {
+                vmParams.put("maxvcpus", getVmCpus());
+            } else {
+                vmParams.put("maxvcpus", val);
+            }
+            return true;
+        }
+        public Integer getVmMaxCpus() {
+            return (Integer) vmParams.get("maxvcpus");
+        }
+        public Boolean setVmCpus(Integer val) {
+            vmParams.put("vcpus", val);
+            if (getVmMaxCpus() < val) {
+                setVmMaxCpus(val);
+            }
+            return true;
+        }
+        public Integer getVmCpus() {
+            return (Integer) vmParams.get("vcpus");
+        }
+        public Boolean setVmMemory(long memory) {
+            vmParams.put("memory", Long.toString(memory));
+            return true;
+        }
+        public long getVmMemory() {
+            return Long.parseLong((String) vmParams.get("memory"));
+        }
+
+        /*
+         * public Boolean setVmBuilder(String builder) {
+         * vmParams.put("builder", builder);
+         * return true;
+         * }
+         * public String getVmBuilder() {
+         * return (String) vmParams.get("builder");
+         * }
+         */
+        public Boolean setVmDomainType(String domtype) {
+            vmParams.put("OVM_domain_type", domtype);
+            return true;
+        }
+
+        /* iiiis this a good idea ? */
+        public String getVmDomainType() {
+            String domType = (String) vmParams.get("OVM_domain_type");
+            if (domType == null) {
+                String builder = (String) vmParams.get("builder");
+                if (builder.contains("linux")) {
+                    domType = "xen_pvm";
+                } else {
+                    domType = "hvm";
+                }
+            }
+            return domType;
+        }
+        public Boolean setVmState(String state) {
+            vmParams.put("state", state);
+            return true;
+        }
+        public String getVmState() {
+            return (String) vmParams.get("state");
+        }
+        public Boolean setVmName(String name) {
+            vmParams.put("name", name);
+            vmParams.put("OVM_simple_name", name);
+            return true;
+        }
+        public String getVmName() {
+            return (String) vmParams.get("name");
+        }
+        public Boolean setVmUuid(String uuid) {
+            vmParams.put("uuid", uuid);
+            return true;
+        }
+        public String getVmUuid() {
+            return (String) vmParams.get("uuid");
+        }
+
+        /* 'vfb': ['type=vnc,vncunused=1,vnclisten=127.0.0.1,keymap=en-us'] */
+        /*
+         * 'disk': [
+         * 'file:/OVS/Repositories/0004fb0000030000aeaca859e4a8f8c0/VirtualDisks/0004fb0000120000c444117fd87ea251.img,xvda,w']
+         */
+        /* 'vif': ['mac=00:21:f6:00:00:00,bridge=c0a80100'] */
+        /* TODO: splork out VIFs this is not sane, same for VFBs and */
+        public void setVmVncs(List<String> vncs) {
+            this._vmVnc.addAll(vncs);
+        }
+        public List<String> getVmVncs() {
+            return this._vmVnc;
+        }
+        public void setVmDisks(List<String> disks) {
+            this._vmDisks.addAll(disks);
+        }
+        public List<String> getVmDisks() {
+            return this._vmDisks;
+        }
+        public void setVmVifs(List<String> vifs) {
+            this._vmVifs.addAll(vifs);
+        }
+        public List<String> getVmVifs() {
+            return this._vmVifs;
+        }
+        public boolean addVif() {
+            ArrayList<String> vif = new ArrayList<String>();
+            for (final String entry : _vmVifs.get(0).split(",")) {
+                final String[] parts = entry.split("=");
+                assert (parts.length == 2) : "Invalid entry: " + entry;
+                vif.add(parts[0] + "=" + parts[1]);
+            }
+            _vmVifs.add(StringUtils.join(vif, ","));
+            return true;
+        }
+
+        public Boolean addVif(Integer id, String bridge, String mac) {
+            String vif = "mac=" + mac + ",bridge=" + bridge;
+            _xvmVifs[id] = vif;
+            // _vmVifs.add("mac=" + mac + ",bridge=" + bridge);
+            return true;
+        }
+
+        public boolean setupVifs() {
+            for (String vif : _xvmVifs) {
+                if (vif != null)
+                    _vmVifs.add(vif);
+            }
+            return true;
+        }
+
+        public Boolean removeVif(String bridge, String mac) {
+            // vmVfbs.remove("mac="+mac+",bridge="+bridge);
+            return true;
+        }
+
+        /* 'file:/OVS/Repositories/d5f5a4480515467ca1638554f085b278/ISOs/e14c811ebbf84f0b8221e5b7404a554e.iso,hdc:cdrom,r' */
+        /* device is coupled with vmtype enumerate and cdboot ? */
+        public Boolean addRootDisk(String image) throws Exception {
+            Boolean ret = false;
+            if (_vmDisk > _vmDiskZero) {
+                Integer oVmDisk = _vmDisk;
+                _vmDisk = _vmDiskZero;
+                ret = addDisk(image, "w");
+                _vmDisk = oVmDisk;
+            } else {
+                ret = addDisk(image, "w");
+            }
+            return ret;
+        }
+        public Boolean addDataDisk(String image) throws Exception {
+            /*
+             * w! means we're able to share the disk is that wise, should be
+             * an option in CS ?
+             */
+            return addDisk(image, "w!");
+        }
+        public Boolean addIso(String image) throws Exception {
+            /* should we check for .iso ? */
+            return addDisk(image, "r!");
+        }
+        public Boolean addDisk(String image, String mode) throws Exception {
+            String devName = null;
+            /* better accounting then _vmDisk += 1 */
+            _vmDisk = _vmDiskZero + _vmDisks.size();
+            if (getVmDomainType() != null && getVmDomainType().contains("hvm")) {
+                _vmDisk += 2;
+                devName = Character.toString((char) _vmDisk);
+            } else {
+                devName = "xvd" + Character.toString((char) _vmDisk);
+            }
+
+            /* check for iso, force mode and additions */
+            if (image.endsWith(".iso")) {
+                devName = devName + ":cdrom";
+                mode = "r";
+            }
+            return _addDisk(image, devName, mode);
+        }
+
+        /* should be on device id too, or else we get random attaches... */
+        public Boolean _addDisk(String image, String devName, String mode) throws Exception {
+            if (getVmDomainType() == null) {
+                throw new Exception("Unable to add disk without domain type "
+                        + "(hvm, xen_pvm, ldoms_pvm (sparc), default)");
+            }
+            /* TODO: needs to become "checkDisk" */
+            for (String disk : _vmDisks) {
+                if (disk.contains(image)) {
+                    return true;
+                }
+            }
+            _vmDisks.add("file:" + image + "," + devName + "," + mode);
+            vmParams.put("disk", _vmDisks);
+            /* accounting is done in addDisk */
+            // _vmDisk += 1;
+            return true;
+        }
+
+        public Boolean removeDisk(String image) throws Exception {
+            for (String disk : _vmDisks) {
+                if (disk.contains(image)) {
+                    return _vmDisks.remove(disk);
+                }
+            }
+            return false;
+        }
+
+        /* TODO: the conflict between getVm and getVmConfig becomes clear */
+        /* FIX: me */
+        public String getVmRootDiskPoolId() {
+            String poolId = getVmDiskPoolId(0);
+            this.setPrimaryPoolUuid(poolId);
+            return poolId;
+        }
+
+        /* TODO: need to fork out vifs, disks and vnc stuff fill them nicely too */
+        public String getVmDiskPoolId(int disk) {
+            String diskPath = "";
+            diskPath = _getVmDiskDetail(disk, "uname");
+            String st[] = diskPath.split(File.separator);
+            return st[3];
+        }
+
+        public String _getVmDiskDetail(int disk, String dest) {
+            // System.out.println(vmParams);
+            Map<String, Object[]> o = (Map<String, Object[]>) vmParams
+                    .get("device");
+            vmDisk = (Map<String, String>) o.get("vbd")[disk];
+            return vmDisk.get(dest);
+        }
+
+        public Boolean removeDisk(String file, String device) {
+            //
+            // get index and remove
+            return true;
+        }
+
+        public boolean setVnc() {
+            ArrayList<String> vfb = new ArrayList<String>();
+            for (final String key : vmVnc.keySet()) {
+                vfb.add(key + "=" + vmVnc.get(key));
+            }
+            _vmVnc.add(StringUtils.join(vfb, ","));
+            return true;
+        }
+
+        public Boolean setVnc(String address) {
+            return setVnc("vnc", address, "en-us");
+        }
+
+        public Boolean setVnc(String type, String address, String map) {
+            /* unused off is domid + 5900, with unused=1 it will be "smart" */
+            vmVnc.put("type", type);
+            vmVnc.put("vncunused", this.getVncUsed());
+            vmVnc.put("vnclisten", address);
+            vmVnc.put("keymap", map);
+            setVnc();
+            return true;
+        }
+
+        public void setVncUsed(String used) {
+            vmVnc.put("vncused", used);
+        }
+
+        public String getVncUsed() {
+            return vmVnc.get("vncused");
+        }
+        public void setVncPassword(String pass) {
+            vmVnc.put("vncpasswd", pass);
+        }
+
+        public String getVncPassword() {
+            return vmVnc.get("vncpasswd");
+        }
+        public void setVncAddress(String address) {
+            vmVnc.put("vnclisten", address);
+        }
+        public String getVncAddress() {
+            Integer port = getVncPort();
+            if (port == null) {
+                return null;
+            }
+            return vmVnc.get("vnclisten");
+        }
+        public Integer getVncPort() {
+            if (_getVnc("port") != null) {
+                return Integer.parseInt(_getVnc("port"));
+            }
+            String vnc = getVncLocation();
+            if (vnc.contains(":")) {
+                final String[] res = vnc.split(":");
+                vmVnc.put("vnclisten", res[0]);
+                vmVnc.put("port", res[1]);
+                return Integer.parseInt(res[1]);
+            }
+            return null;
+        }
+
+        public String getVncLocation() {
+            return _getVnc("location");
+        }
+
+        public String _getVnc(String el)  {
+            Map<String, Object[]> o = (Map<String, Object[]>) vmParams
+                    .get("device");
+            vmVnc = (Map<String, String>) o.get("vfb")[0];
+            return vmVnc.get(el);
+        }
+
+        public Boolean removeVfb(String type, String address, String map) {
+            // get index and remove
+            return true;
+        }
+
+        public Object get(String key) {
+            return vmParams.get(key);
+        }
+        public <T> boolean set(String key, T arg) {
+            vmParams.put(key, arg);
+            return true;
+        }
+    }
+
+    /*
+     * delete_assembly, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self
+     * - default: None argument: repo_id - default: None argument: assembly_id -
+     * default: None
+     */
+
+    /*
+     * unconfigure_template, <class 'agent.api.hypervisor.xenxm.Xen'> argument:
+     * self - default: None argument: repo_id - default: None argument:
+     * template_id - default: None argument: params - default: None
+     */
+
+    /*
+     * sysrq_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: letter - default: None
+     */
+
+    /*
+     * list_vms, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None
+     */
+    public Map<String, Vm> listVms() throws ParserConfigurationException,
+            IOException,
+            Exception {
+        Object[] result = (Object[]) callWrapper("list_vms");
+        if (result == null) {
+            return null;
+        }
+
+        try {
+            vmList = new HashMap<String, Vm>();
+            for (Object x : result) {
+                /* put the vmparams in, as x is a hashmap */
+                // System.out.println(x);
+                Vm vm = new Vm();
+                vm.setVmParams((Map<String, Object>) x);
+                this.vmList.put((String) vm.get("name"), vm);
+
+                // System.out.println(vm.get("name") + " " + vm.get("maxmem"));
+            }
+        } catch (Exception e) {
+            System.err.println("Unable to list VMs: " + e.getMessage());
+            throw new Exception("Unable to list VMs: " + e.getMessage());
+        }
+        // System.out.println(vmList);
+        return this.vmList;
+    }
+
+    /*
+     * this should become getVmConfig later...
+     * getVmConfig returns the configuration file, while getVm returns the
+     * "live" configuration. It makes perfect sense if you think about it.....
+     * ....long enough
+     */
+    public Vm getRunningVmConfig(String name)
+            throws ParserConfigurationException, IOException, Exception {
+        listVms();
+        try {
+            Xen.Vm vm = this.vmList.get(name);
+            return vm;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    public Map<String, Vm> getRunningVmConfigs()
+            throws ParserConfigurationException, IOException, Exception {
+        return listVms();
+    }
+
+    /*
+     * delete_vm_core, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: core_date - default: None
+     */
+
+    /*
+     * delete_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None
+     */
+    public Boolean deleteVm(String repoId, String vmId) throws XmlRpcException {
+        Object x = callWrapper("delete_vm", repoId, vmId);
+        // System.out.println(x);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * save_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: checkpoint - default: None
+     *//* add checkpoint */
+    public Boolean saveVm(String repoId, String vmId) throws XmlRpcException {
+        Object x = callWrapper("save_vm", repoId, vmId);
+        // System.out.println(x);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * configure_template, <class 'agent.api.hypervisor.xenxm.Xen'> argument:
+     * self - default: None argument: repo_id - default: None argument:
+     * template_id - default: None argument: params - default: None
+     */
+
+    /*
+     * create_template, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self
+     * - default: None argument: repo_id - default: None argument: template_id -
+     * default: None argument: params - default: None
+     */
+
+    /*
+     * list_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id -
+     * default: None argument: vm_id -
+     * default: None
+     */
+    public Boolean listVm(String repoId, String vmId) throws XmlRpcException {
+        vm = (Vm) callWrapper("list_vm", repoId, vmId);
+        if (vm == null)
+            return false;
+
+        return true;
+    }
+
+    /*
+     * dump_vm_core, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: live - default: None argument: crash - default:
+     * None argument: reset - default: None
+     */
+
+    /*
+     * assembly_del_file, <class 'agent.api.hypervisor.xenxm.Xen'> argument:
+     * self - default: None argument: repo_id - default: None argument:
+     * assembly_id - default: None argument: filename - default: None
+     */
+
+    /*
+     * get_template_config, <class 'agent.api.hypervisor.xenxm.Xen'> argument:
+     * self - default: None argument: repo_id - default: None argument:
+     * template_id - default: None
+     */
+
+    /*
+     * set_assembly_config_xml, <class 'agent.api.hypervisor.xenxm.Xen'>
+     * argument: self - default: None argument: repo_id - default: None
+     * argument: assembly_id - default: None argument: cfg - default: None
+     */
+
+    /*
+     * assembly_add_file, <class 'agent.api.hypervisor.xenxm.Xen'> argument:
+     * self - default: None argument: repo_id - default: None argument:
+     * assembly_id - default: None argument: url - default: None argument:
+     * filename - default: None argument: option - default: None
+     */
+
+    /*
+     * send_to_guest, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: params - default: None
+     */
+
+    /*
+     * set_assembly_config, <class 'agent.api.hypervisor.xenxm.Xen'> argument:
+     * self - default: None argument: repo_id - default: None argument:
+     * assembly_id - default: None argument: cfg - default: None
+     */
+
+    /*
+     * configure_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id -
+     * default: None argument: vm_id -
+     * default: None argument: params -
+     * default: None
+     */
+    public Boolean configureVm(String repoId, String vmId,
+            Map<String, Object> params)
+            throws XmlRpcException {
+        Object x = callWrapper("configure_vm",
+                repoId,
+                vmId,
+                params);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    public Boolean configureVm(String repoId, String vmId)
+            throws XmlRpcException {
+        return configureVm(repoId,
+                vmId,
+                this.vm.getVmParams());
+    }
+
+    /*
+     * cleanup_migration_target, <class 'agent.api.hypervisor.xenxm.Xen'>
+     * argument: self - default: None argument: repo_id - default: None
+     * argument: vm_id - default: None
+     */
+
+    /*
+     * pause_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None
+     */
+    public Boolean pauseVm(String repoId, String vmId) throws XmlRpcException {
+        Object x = callWrapper("pause_vm", repoId, vmId);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * setup_migration_target, <class 'agent.api.hypervisor.xenxm.Xen'>
+     * argument: self - default: None argument: repo_id - default: None
+     * argument: vm_id - default: None
+     */
+
+    /*
+     * deploy_assembly, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self
+     * - default: None argument: repo_id - default: None argument: assembly_id -
+     * default: None argument: to_deploy - default: None argument:
+     * target_repo_id - default: None argument: option - default: None
+     */
+
+    /*
+     * stop_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: force - default: None
+     */
+    public Boolean stopVm(String repoId, String vmId) throws XmlRpcException {
+        Object x = callWrapper("stop_vm", repoId, vmId, false);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    public Boolean stopVm(String repoId, String vmId, Boolean force)
+            throws XmlRpcException {
+        Object x = callWrapper("stop_vm", repoId, vmId, force);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * set_template_config, <class 'agent.api.hypervisor.xenxm.Xen'> argument:
+     * self - default: None argument: repo_id - default: None argument:
+     * template_id - default: None argument: params - default: None
+     */
+
+    /*
+     * assembly_rename_file, <class 'agent.api.hypervisor.xenxm.Xen'> argument:
+     * self - default: None argument: repo_id - default: None argument:
+     * assembly_id - default: None argument: filename - default: None argument:
+     * new_filename - default: None
+     */
+
+    /*
+     * migrate_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: dest - default: None argument: live - default:
+     * None argument: ssl - default: None
+     */
+    public Boolean migrateVm(String repoId, String vmId, String dest)
+            throws XmlRpcException {
+        Object x = callWrapper("migrate_vm", repoId, vmId, dest);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    public Boolean migrateVm(String repoId, String vmId, String dest,
+            boolean live, boolean ssl) throws XmlRpcException {
+        Object x = callWrapper("migrate_vm", repoId, vmId, dest, live, ssl);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * configure_vm_ha, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: enable_ha - default: None
+     */
+    public Boolean configureVmHa(String repoId, String vmId, Boolean ha)
+            throws XmlRpcException {
+        Object x = callWrapper("configure_vm_ha", repoId, vmId, ha);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * create_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: params - default: None
+     */
+    public Boolean createVm(String repoId, String vmId) throws XmlRpcException {
+        Object x = callWrapper("create_vm", repoId, vmId, vm.getVmParams());
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    public Boolean createVm(String repoId, String vmId,
+            Map<String, Object> vmParams) throws XmlRpcException {
+        Object x = callWrapper("create_vm", repoId, vmId, vmParams);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * pack_assembly, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: assembly_id -
+     * default: None
+     */
+
+    /*
+     * restore_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: paused - default: None
+     */
+
+    /*
+     * start_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None
+     */
+    public Boolean startVm(String repoId, String vmId) throws XmlRpcException {
+        Object x = callWrapper("start_vm", repoId, vmId);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * unpause_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None
+     */
+    public Boolean unpauseVm(String repoId, String vmId)
+            throws XmlRpcException {
+        Object x = callWrapper("unpause_vm", repoId, vmId);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * trigger_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: name - default: None argument: vcpu - default:
+     * None
+     */
+
+    /*
+     * set_vm_config, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: params - default: None
+     */
+
+    /*
+     * delete_template, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self
+     * - default: None argument: repo_id - default: None argument: template_id -
+     * default: None
+     */
+
+    /*
+     * reboot_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: wait - default: None
+     */
+    public Boolean rebootVm(String repoId, String vmId, int wait)
+            throws XmlRpcException {
+        Object x = callWrapper("reboot_vm", repoId, vmId, wait);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    public Boolean rebootVm(String repoId, String vmId) throws XmlRpcException {
+        Object x = callWrapper("reboot_vm", repoId, vmId, 3);
+        if (x == null)
+            return true;
+
+        return false;
+    }
+
+    /*
+     * unpack_assembly, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self
+     * - default: None argument: repo_id - default: None argument: assembly_id -
+     * default: None
+     */
+
+    /*
+     * get_vm_config, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None
+     */
+    public Vm getVmConfig(String vmName) throws XmlRpcException, Exception {
+        this.vm = this.getRunningVmConfig(vmName);
+        if (vm == null)
+            return this.vm;
+        return getVmConfig(vm.getVmRootDiskPoolId(), vm.getVmUuid());
+    }
+
+    public Vm getVmConfig() {
+        return this.vm;
+    }
+
+    /*
+     * returns the configuration file contents, so we parse it for configuration
+     * alterations we might want to do (/$repo/VirtualMachines/$uuid/vm.cfg)
+     */
+    public Vm getVmConfig(String repoId, String vmId)
+            throws XmlRpcException {
+        Xen.Vm nVm = new Xen.Vm();
+        Map<String, Object[]> x = (Map<String, Object[]>) callWrapper("get_vm_config",
+                repoId,
+                vmId);
+        if (x == null) {
+            return nVm;
+        }
+        nVm.setVmVifs(Arrays.asList(Arrays.copyOf(x.get("vif"),
+                x.get("vif").length,
+                String[].class)));
+        x.remove("vif");
+        nVm.setVmDisks(Arrays.asList(Arrays.copyOf(x.get("disk"),
+                x.get("disk").length,
+                String[].class)));
+        x.remove("disk");
+        nVm.setVmVifs(Arrays.asList(Arrays.copyOf(x.get("vfb"),
+                x.get("vfb").length,
+                String[].class)));
+        x.remove("vfb");
+        Map<String, Object> remains = new HashMap<String, Object>();
+        for (final Map.Entry<String, Object[]> not : x.entrySet()) {
+            remains.put(not.getKey(), not.getValue());
+        }
+        nVm.setVmParams(remains);
+        nVm.setPrimaryPoolUuid(repoId);
+        /* to make sure stuff doesn't blow up in our face... */
+        this.vm = nVm;
+        return nVm;
+    }
+
+    /*
+     * get_assembly_config_xml, <class 'agent.api.hypervisor.xenxm.Xen'>
+     * argument: self - default: None argument: repo_id - default: None
+     * argument: assembly_id - default: None
+     */
+
+    /*
+     * import_assembly, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self
+     * - default: None argument: repo_id - default: None argument: assembly_id -
+     * default: None argument: url - default: None argument: option - default:
+     * None
+     */
+
+    /*
+     * create_assembly, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self
+     * - default: None argument: repo_id - default: None argument: assembly_id -
+     * default: None argument: templates - default: None
+     */
+
+    /*
+     * get_assembly_config, <class 'agent.api.hypervisor.xenxm.Xen'> argument:
+     * self - default: None argument: repo_id - default: None argument:
+     * assembly_id - default: None
+     */
+
+    /*
+     * unconfigure_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: params - default: None
+     */
+
+    /*
+     * import_template, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self
+     * - default: None argument: repo_id - default: None argument: template_id -
+     * default: None argument: url_list - default: None argument: option -
+     * default: None
+     */
+
+    /*
+     * import_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: url_list - default: None argument: option -
+     * default: None
+     */
+
+    /*
+     * list_vm_core, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None
+     */
+}
