You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bh...@apache.org on 2015/03/12 07:04:54 UTC

[02/12] git commit: updated refs/heads/master to c27c694

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/resources/scripts/create_pool_cluster.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/resources/scripts/create_pool_cluster.py b/plugins/hypervisors/ovm3/src/test/resources/scripts/create_pool_cluster.py
new file mode 100755
index 0000000..6c39851
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/resources/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

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/resources/scripts/info.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/resources/scripts/info.py b/plugins/hypervisors/ovm3/src/test/resources/scripts/info.py
new file mode 100755
index 0000000..19ff71e
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/resources/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

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/resources/scripts/password.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/resources/scripts/password.py b/plugins/hypervisors/ovm3/src/test/resources/scripts/password.py
new file mode 100755
index 0000000..748023d
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/resources/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

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/resources/scripts/repo_pool.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/resources/scripts/repo_pool.py b/plugins/hypervisors/ovm3/src/test/resources/scripts/repo_pool.py
new file mode 100755
index 0000000..3886164
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/resources/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

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/resources/scripts/simple_pool.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/resources/scripts/simple_pool.py b/plugins/hypervisors/ovm3/src/test/resources/scripts/simple_pool.py
new file mode 100755
index 0000000..33789a2
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/resources/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

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/resources/scripts/socat.sh
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/resources/scripts/socat.sh b/plugins/hypervisors/ovm3/src/test/resources/scripts/socat.sh
new file mode 100755
index 0000000..c3fbc44
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/resources/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 &

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/resources/scripts/tail.sh
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/resources/scripts/tail.sh b/plugins/hypervisors/ovm3/src/test/resources/scripts/tail.sh
new file mode 100755
index 0000000..8b36123
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/resources/scripts/tail.sh
@@ -0,0 +1,2 @@
+cd /var/log
+tail -f ovm-consoled.log devmon.log messages ovs-agent.log ovmwatch.log

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java
index 3dfcc0f..db06c88 100644
--- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java
+++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java
@@ -327,7 +327,7 @@ public class ManagementServerMock {
             _znet = _networkService.getPhysicalNetwork(id);
             List<PhysicalNetworkVO> nets = _physicalNetworkDao.listByZoneAndTrafficType(_zone.getId(), TrafficType.Public);
             if (nets == null || nets.isEmpty()) {
-                _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), "vlan", null, null, null, null, null, null);
+                _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), "vlan", null, null, null, null, null, null, null);
             }
         } catch (InvalidParameterValueException e) {
             List<String> isolationMethods = new ArrayList<String>();
@@ -337,7 +337,7 @@ public class ManagementServerMock {
                     "znet");
             List<PhysicalNetworkVO> nets = _physicalNetworkDao.listByZoneAndTrafficType(_zone.getId(), TrafficType.Public);
             if (nets == null || nets.isEmpty()) {
-                _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), "vlan", null, null, null, null, null, null);
+                _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), "vlan", null, null, null, null, null, null, null);
             }
         }
         if (_znet.getState() != PhysicalNetwork.State.Enabled) {
@@ -353,7 +353,7 @@ public class ManagementServerMock {
             }
         }
         if (!found) {
-            _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Guest.toString(), "vlan", null, null, null, null, null, null);
+            _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Guest.toString(), "vlan", null, null, null, null, null, null, null);
         }
 
         Pair<List<? extends PhysicalNetworkServiceProvider>, Integer> providers =

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/pom.xml b/plugins/pom.xml
index 8034bd1..ccda955 100755
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -58,6 +58,7 @@
     <module>hypervisors/baremetal</module>
     <module>hypervisors/ucs</module>
     <module>hypervisors/hyperv</module>
+    <module>hypervisors/ovm3</module>
     <module>network-elements/elastic-loadbalancer</module>
     <module>network-elements/ovs</module>
     <module>network-elements/juniper-contrail</module>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/scripts/storage/secondary/cloud-install-sys-tmplt
----------------------------------------------------------------------
diff --git a/scripts/storage/secondary/cloud-install-sys-tmplt b/scripts/storage/secondary/cloud-install-sys-tmplt
index d31377a..25a7dae 100755
--- a/scripts/storage/secondary/cloud-install-sys-tmplt
+++ b/scripts/storage/secondary/cloud-install-sys-tmplt
@@ -20,9 +20,9 @@
 
 
 usage() {
-  printf "Usage: %s: -m <secondary storage mount point> -f <system vm template file> [-h <hypervisor name: kvm|vmware|xenserver|hyperv> ] [ -s <mgmt server secret key, if you specified any when running cloudstack-setup-database, default is password>][-u <Url to system vm template>] [-F <clean up system templates of specified hypervisor>] [-e <Template suffix, e.g vhd, ova, qcow2>] [-o <Database server hostname or ip, e.g localhost>] [-r <Database user name, e.g root>] [-d <Database password. Fllowed by nothing if the password is empty>]\n" $(basename $0) >&2
+  printf "Usage: %s: -m <secondary storage mount point> -f <system vm template file> [-h <hypervisor name: kvm|vmware|xenserver|hyperv|ovm3> ] [ -s <mgmt server secret key, if you specified any when running cloudstack-setup-database, default is password>][-u <Url to system vm template>] [-F <clean up system templates of specified hypervisor>] [-e <Template suffix, e.g vhd, ova, qcow2>] [-o <Database server hostname or ip, e.g localhost>] [-r <Database user name, e.g root>] [-d <Database password. Fllowed by nothing if the password is empty>]\n" $(basename $0) >&2
   printf "or\n" >&2
-  printf "%s: -m <secondary storage mount point> -u <http url for system vm template> [-h <hypervisor name: kvm|vmware|xenserver|hyperv> ] [ -s <mgmt server secret key>]\n" $(basename $0) >&2
+  printf "%s: -m <secondary storage mount point> -u <http url for system vm template> [-h <hypervisor name: kvm|vmware|xenserver|hyperv|ovm3> ] [ -s <mgmt server secret key>]\n" $(basename $0) >&2
 }
 
 failed() {
@@ -165,6 +165,10 @@ then
    then
       ext="vhd"
       templateId=(`mysql -h $dbHost --user=$dbUser --password=$dbPassword --skip-column-names -U cloud -e "select max(id) from cloud.vm_template where type = \"SYSTEM\" and hypervisor_type = \"Hyperv\" and removed is null"`)
+   elif [ "$hyper" == "ovm3" ]
+   then
+      ext="raw"
+      templateId=(`mysql -h $dbHost --user=$dbUser --password=$dbPassword --skip-column-names -U cloud -e "select max(id) from cloud.vm_template where type = \"SYSTEM\" and hypervisor_type = \"Ovm3\" and removed is null"`)
    else
       usage
       failed 2
@@ -177,7 +181,10 @@ then
 	failed 8
 fi
 
-localfile=$(uuidgen).$ext
+_uuid=$(uuidgen)
+localfile=$_uuid.$ext
+
+_res=(`mysql -h $dbHost --user=$dbUser --password=$dbPassword --skip-column-names -U cloud -e "update cloud.vm_template set uuid=\"$_uuid\" where id=\"$templateId\""`)
 
 mntpoint=`echo "$mntpoint" | sed 's|/*$||'`
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/scripts/vm/hypervisor/ovm3/cloudstack.py
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/ovm3/cloudstack.py b/scripts/vm/hypervisor/ovm3/cloudstack.py
new file mode 100644
index 0000000..e82863e
--- /dev/null
+++ b/scripts/vm/hypervisor/ovm3/cloudstack.py
@@ -0,0 +1,588 @@
+#!/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.
+#
+# TODO: Needs cleaning and sanitazation.
+#
+import logging
+import time
+import re
+import os.path
+import paramiko
+import subprocess
+import socket
+import tempfile
+import logging
+import logging.handlers
+
+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_dom0_port': dom0CheckPort,
+            'check_domr_ssh': domrCheckSsh,
+            'check_dom0_ip': dom0CheckIp,
+            # rename to dom0StorageStatusCheck
+            'check_dom0_storage_health_check': dom0CheckStorageHealthCheck,
+            # dom0StorageStatus
+            'check_dom0_storage_health': dom0CheckStorageHealth,
+            'ovs_domr_upload_file': ovsDomrUploadFile,
+            'ovs_control_interface': ovsControlInterface,
+            'ovs_mkdirs': ovsMkdirs,
+            'ovs_check_file': ovsCheckFile,
+            'ovs_upload_ssh_key': ovsUploadSshKey,
+            'ovs_upload_file': ovsUploadFile,
+            'ovs_dom0_stats': ovsDom0Stats,
+            'ovs_domU_stats': ovsDomUStats,
+            'get_module_version': getModuleVersion,
+            'get_ovs_version': ovmVersion,
+            'ping': ping,
+#            'patch': ovmCsPatch,
+#            'ovs_agent_set_ssl': ovsAgentSetSsl,
+#            'ovs_agent_set_port': ovsAgentSetPort,
+#            'ovs_restart_agent': ovsRestartAgent,
+        }
+
+    def getName(self):
+        return self.__class__.__name__
+
+domrPort = 3922
+domrKeyFile = os.path.expanduser("~/.ssh/id_rsa.cloud")
+domrRoot = "root"
+domrTimeout = 10
+
+""" The logger is here """
+def Logger(level=logging.DEBUG):
+    logger = logging.getLogger('cloudstack-agent')
+    logger.setLevel(level)
+    handler = logging.handlers.SysLogHandler(address = '/dev/log')
+    logger.addHandler(handler)
+    return logger
+
+# which version are we intended for?
+def getModuleVersion():
+    return "0.1"
+
+# call test
+def call(msg):
+    return msg
+
+def paramikoOpts(con, keyfile=domrKeyFile):
+    con.load_system_host_keys()
+    con.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+    privatekeyfile = os.path.expanduser(keyfile)
+    key = paramiko.RSAKey.from_private_key_file(privatekeyfile)
+    return key
+
+# execute something on domr
+def domrExec(host, cmd, timeout=10, username=domrRoot, port=domrPort, keyfile=domrKeyFile):
+    ssh = paramiko.SSHClient()
+    pkey = paramikoOpts(ssh, keyfile)
+    ssh.connect(host, port, username, pkey=pkey, 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()) };
+
+# too bad sftp is missing.... Oh no it isn't it's just wrong in the svm config...
+# root@s-1-VM:/var/cache/cloud# grep sftp /etc/ssh/sshd_config
+# Subsystem   sftp    /usr/libexec/openssh/sftp-server
+# root@s-1-VM:/var/cache/cloud# find / -name sftp-server -type f
+# /usr/lib/openssh/sftp-server
+#
+def domrSftp(host, localfile, remotefile, timeout=10, username=domrRoot, port=domrPort, keyfile=domrKeyFile):
+    try:
+        paramiko.common.logging.basicConfig(level=paramiko.common.DEBUG)
+        ssh = paramiko.SSHClient()
+        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+        pkey = paramikoOpts(ssh, keyfile)
+        ssh.connect(host, port, username, pkey=pkey, timeout=timeout)
+        sftp = ssh.open_sftp()
+        # either:
+        sftp.put(localfile, remotefile)
+        # or:
+        # rf = sftp.open(remotefile, 'w')
+        # rf.write(content)
+        # rf.close()
+        sftp.close()
+        ssh.close()
+    except Exception, e:
+        raise e
+    return True
+
+def domrScp(host, localfile, remotefile, timeout=10, username=domrRoot, port=domrPort, keyfile=domrKeyFile):
+    try:
+        target = "%s@%s:%s" % (username, host, remotefile)
+        cmd = ['scp', '-P', str(port), '-q', '-o', 'StrictHostKeyChecking=no', '-i', os.path.expanduser(keyfile), localfile, target]
+        rc = subprocess.call(cmd, shell=False)
+        if rc == 0:
+            return True
+    except Exception, e:
+        raise e
+    return False
+
+# check a port on dom0
+def dom0CheckPort(ip, port=domrPort, timeout=3):
+    return domrCheckPort(ip, port, timeout=timeout)
+
+# check a port on domr
+def domrCheckPort(ip, port=domrPort, timeout=3):
+    try:
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        s.settimeout(timeout)
+        s.connect((ip, port))
+        s.close()
+    except:
+        return False
+    return True
+
+# check ssh
+def domrCheckSsh(ip, port=domrPort, timeout=10):
+    x = domrExec(ip, "", port=port, timeout=timeout)
+    if (x.get("rc") == 0):
+        return True
+    return False
+
+def grep(file, string):
+    c = 0
+    for line in open(file):
+        if string in line:
+           c = c + 1
+    return c
+
+def ovmVersion():
+    path = "/etc/ovs-release"
+    return re.findall("[\d\.]+$", open(path).readline())[0]
+
+# fix known bugs....
+def ovmCsPatch(version="3.2.1"):
+    path = "/etc/xen/scripts"
+    netcom = "%s/xen-network-common.sh" % path
+    netbr = "%s/linuxbridge/ovs-vlan-bridge" % path
+    func = "setup_bridge_port"
+    # on 3.3.1 this moved to python2.6, but the restart time is already good
+    xendConst = "/usr/lib64/python2.4/site-packages/xen/xend/XendConstants.py"
+    xendRtime = "MINIMUM_RESTART_TIME"
+    netconf = "/etc/sysconfig/network"
+    netzero = "NOZEROCONF"
+    version = ovmVersion()
+
+    # this bug is present from 3.2.1 till 3.3.2
+    if grep(netcom, "_%s" % func) == 3 and grep(netbr, "_%s" % func) < 1:
+        _replaceInFile(netbr, func, "_%s" % func, True)
+
+    # zeroconf is in the way for local loopback, as it introduces a route
+    # on every interface that conflicts with what we want
+    if grep(netconf, "%s" % netzero) == 0:
+        text_file = open("%s" % netconf, "a")
+        text_file.write("%s=no\n" % netzero)
+        text_file.close()
+    else:
+        _replaceInFile(netconf,
+            netzero,
+            "no",
+            False)
+
+    # this is fixed in 3.3.1 and onwards
+    if version == "3.2.1":
+        if grep(xendConst, "%s = %s" % (xendRtime, 60)) == 1:
+            _replaceInFile(xendConst,
+                "%s = %s" % (xendRtime, 60),
+                "%s = %s" % (xendRtime, 10),
+                True)
+            ovsRestartXend()
+
+    return True
+
+def _replaceInFile(file, orig, set, full=False):
+    replaced = False
+    if os.path.isfile(file):
+        import fileinput
+        for line in fileinput.FileInput(file, inplace=1):
+            line = line.rstrip('\n')
+            if full == False:
+                if re.search("%s=" % orig, line):
+                    line = "%s=%s" % (orig, set)
+                    replaced = True
+            else:
+                if re.search(orig, line):
+                    line = line.replace(orig, set)
+                    replaced = True
+            print line
+    return replaced
+
+def _ovsIni(setting, change):
+    ini = "/etc/ovs-agent/agent.ini"
+    return _replaceInFile(ini, setting, change)
+
+# 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")
+
+def ovsRestartXend():
+    return restartService("xend")
+
+# 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, cidr):
+    controlRoute = False
+    command = ['ip route show'];
+    p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
+    while True:
+        line = p.stdout.readline()
+        if line == '' and p.poll() != None:
+            break
+        if line != '':
+            if re.search("%s" % (cidr), line) and not re.search("%s" % (dev), line):
+                command = ['ip', 'route', 'del', cidr]
+                subprocess.call(command, shell=False)
+                print "removed: %s" % (line)
+            elif re.search("%s" % (cidr), line) and re.search("%s" % (dev), line):
+                controlRoute = True
+
+    if controlRoute == False:
+        command = ['ip', 'route', 'add', cidr, 'dev', dev];
+        subprocess.call(command, shell=False)
+
+    command = ['ifconfig', dev, 'arp']
+    subprocess.call(command, shell=False)
+    # because OVM creates this and it breaks stuff if we're rebooted sometimes...
+    control = "/etc/sysconfig/network-scripts/ifcfg-%s" % (dev)
+    command = ['rm', control]
+    subprocess.call(command, shell=False)
+    return True
+
+def dom0CheckIp(ip):
+    command = ['ip addr show']
+    p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
+    while True:
+        line = p.stdout.readline()
+        if line != '':
+            if re.search("%s/" % (ip), line):
+                return True
+        else:
+            break
+    return False
+
+def dom0CheckStorageHealthCheck(path, script, guid, timeout, interval):
+    storagehealth="storagehealth.py"
+    path="/opt/cloudstack/bin"
+    running = False
+    started = False
+    c = 0
+    log = Logger()
+    command = ["pgrep -fl %s | grep -v cloudstack.py" % (storagehealth)]
+
+    p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
+    for x in p.stdout:
+        if x:
+            log.debug("%s is running %s" % (storagehealth, x.rstrip('\n')))
+            running = True
+            c = c + 1
+    if c < 1:
+        started = True
+        command = ["%s/%s -g %s -t %d -i %d" % (path, storagehealth, guid, timeout, interval)]
+        log.warning("%s started: %s/%s for %s with timeout %d and interval %d"
+                    % (storagehealth, path, storagehealth, guid, timeout, interval))
+        subprocess.call(command, shell=True, close_fds=True)
+
+    return [running, started]
+
+def dom0CheckStorageHealth(path, script, guid, timeout):
+    response = None
+    delay = timeout
+    log = Logger()
+    command = ["%s/%s -g %s -t %s -s" % (path, script, guid, timeout)]
+    p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
+    p.wait()
+    if p.returncode == 0:
+        log.warning("primary storage is accessible for %s" % (guid))
+        return True
+    else:
+        log.warning("primary storage NOT is accessible for %s" % (guid))
+        return False
+    # while True:
+    #    line = p.stdout.readline()
+    #   if line != '':
+    #        if re.search("False", line):
+    #            log.debug("primary storage NOT is accessible for %s, %s" % (guid, line))
+    #            return False
+    #    else:
+    #        break
+    # return True
+
+# create a dir if we need it
+def ovsMkdirs(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
+
+def ovsUploadFile(path, filename, content):
+    file = "%s/%s" % (path, filename)
+    try:
+        ovsMkdirs(os.path.expanduser(path))
+    except Error, v:
+        print "path was already there %s" % path
+
+    try:
+        text_file = open("%s" % file, "w")
+        text_file.write("%s" % content)
+        text_file.close()
+    except Error, v:
+        print "something went wrong creating %s: %s" % (file, v)
+        return False
+    return True
+
+def ovsDomrUploadFile(domr, path, file, content):
+    remotefile = "%s/%s" % (path, file)
+    try:
+        temp = tempfile.NamedTemporaryFile()
+        temp.write(content)
+        temp.flush()
+        # domrSftp(domr, temp.name, remotefile)
+        domrScp(domr, temp.name, remotefile)
+        temp.close
+    except Exception, e:
+        print "problem uploading file %s/%s to %s, %s" % (path, file, domr, e)
+        raise e
+    return True
+
+# upload keys
+def ovsUploadSshKey(keyfile, content):
+    keydir = os.path.expanduser("~/.ssh")
+    return ovsUploadFile(keydir, keyfile, content)
+
+# 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
+    exec_sub = ""
+    exec_opts = ""
+
+    # get options
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "eosp::",
+            [ 'port=', 'ssl=', 'exec=', 'opts='])
+    except getopt.GetoptError:
+        print "Available Options: --port=<number>, --ssl=<true|false>, --exec=<method>, --opts=<arg1,arg2..>"
+        sys.exit()
+
+    for o, a in opts:
+        if o in ('-s', '--ssl'):
+            ssl = a
+        if o in ('-p', '--port'):
+            port = int(a)
+        if o in ('-e', '--exec'):
+            exec_sub = a
+        if o in ('-o', '--opts'):
+            exec_opts = a
+
+    if exec_sub != "":
+        func = "%s(%s)" % (exec_sub, exec_opts)
+        print "exec: %s" % (func)
+        if exec_opts:
+            opts = exec_opts.split(',')
+        else:
+            opts = ""
+        print locals()[exec_sub](*opts)
+        sys.exit()
+
+    # 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
+    ovmCsPatch()
+    ovsRestartAgent()

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/scripts/vm/hypervisor/ovm3/storagehealth.py
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/ovm3/storagehealth.py b/scripts/vm/hypervisor/ovm3/storagehealth.py
new file mode 100755
index 0000000..353ca5e
--- /dev/null
+++ b/scripts/vm/hypervisor/ovm3/storagehealth.py
@@ -0,0 +1,259 @@
+#!/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.
+#
+# TODO:
+# add multipath -ll
+# add iscsiadm output
+#
+import time
+import socket
+import getopt
+import sys
+import subprocess, threading
+import logging
+import logging.handlers
+import re
+import shutil
+import os
+
+""" a class to do checks with as a thread so we can have nice timeouts """
+class Check(object):
+    def __init__(self, cmd="", failcmd="", primary="",
+            file="", timeout="120", interval=1, logger="",
+            check=False):
+        self.file=file
+        self.cmd=cmd
+        self.failcmd=failcmd
+        self.primary=primary
+        self.timeout=timeout
+        self.interval=interval
+        self.process=None
+        self.logger=logger
+        self.check=check
+        self.ok=None
+        self.results={}
+
+    def readhb(self,file=""):
+        if os.path.isfile(file):
+            text_file = open("%s" % file, "r")
+            line=text_file.readline()
+            text_file.close()
+            return line
+        return 0
+
+    def writehb(self,file=""):
+        if file:
+            nfile="%s.new" % (file)
+            epoch=time.time()
+            text_file = open("%s" % nfile, "w")
+            text_file.write("%s" % epoch)
+            text_file.close()
+            shutil.move(nfile,file)
+            self.logger.debug('Worked on file %s for %s' %
+                 (file, (time.time() - epoch)))
+
+    """ We only want mounted nfs filesystems """
+    def nfsoutput(self):
+        command="mount -v -t nfs"
+        p=subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
+        lines=map(lambda line: line.split()[2], p.stdout.readlines())
+        test=re.compile("^%s" % (primary))
+        lines=filter(test.search, lines)
+        return lines
+
+    """
+        The main run for all checks we do,
+        everything is in here on purpose.
+
+        the other FSs to heartbeat should be added to filesystems...!
+    """
+    def run(self, timeout):
+        def target():
+            filesystems=[]
+            filesystems.extend(self.nfsoutput())
+            for fs in filesystems:
+                if self.file:
+                    if self.check==False:
+                        self.writehb("%s/%s" % (fs,file))
+                    else:
+                        res=self.readhb("%s/%s" % (fs,file))
+                        delay = time.time() - float(res)
+                        if (delay < timeout) and self.ok == None:
+                            self.logger.info("%s/%s is ok %s with %s" % (fs,file,timeout,delay))
+                            self.ok = True
+                        elif (delay > timeout):
+                            self.logger.warning("%s/%s exceeded timeout %s with %s" % (fs,file,timeout, delay))
+                            self.ok = False
+                        self.results[fs] = [self.ok, delay]
+
+            epoch=time.time()
+            if self.cmd:
+                self.logger.debug('Executing: %s' % (cmd))
+                self.process = subprocess.Popen(self.cmd, shell=True)
+                self.process.communicate()
+                self.logger.info('Executed: %s in %s' %
+                    (cmd, (time.time() - epoch)))
+
+        thread = threading.Thread(target=target)
+        thread.start()
+        thread.join(self.timeout)
+        if thread.isAlive() and self.check == False:
+            self.logger.critical('Critical: thread timeout; %s' % (timeout))
+            if self.failcmd:
+                self.logger.critical('Critical: executing; %s' % (failcmd))
+                p=subprocess.Popen(failcmd, shell=True, stdout=subprocess.PIPE)
+
+""" here we figure out what we're running on more or less """
+def figureOutPrimary():
+    redhat="/etc/redhat-release"
+    if os.path.isfile(redhat):
+        for line in open(redhat):
+            if "XenServer" in line:
+                return "/var/run/sr-mount"
+            if "Oracle VM server" in line:
+                return "/OVS/Repositories/"
+    print "Unknown hypervisor, consider adding it, exiting"
+    sys.exit(42)
+
+""" The logger is here """
+def Logger(level=logging.DEBUG):
+    logger = logging.getLogger('cs-heartbeat')
+    logger.setLevel(level)
+    handler = logging.handlers.SysLogHandler(address = '/dev/log')
+    logger.addHandler(handler)
+    return logger
+
+""" main for preso-dent """
+if __name__ == '__main__':
+    me=os.path.basename(__file__)
+    timeout=120
+    interval=1
+    hostname=socket.gethostname()
+    file=".hb-%s" % (hostname)
+    cmd=""
+    level=logging.DEBUG
+    primary=""
+    checkstate=False
+    failcmd=("echo 1 > /proc/sys/kernel/sysrq "
+        "&& "
+        "echo c > /proc/sysrq-trigger")
+
+    # xenserver:
+    if me == "heartbeat":
+        #  String result = callHostPluginPremium(conn, "heartbeat",
+        #  "host", _host.uuid,
+        #  "timeout", Integer.toString(_heartbeatTimeout),
+        #  "interval", Integer.toString(_heartbeatInterval));
+        # if (result == null || !result.contains("> DONE <")) {
+        try:
+            opts, args = getopt.getopt(sys.argv[1:], "h:y:i:s",
+                [ 'host', 'timeout', 'interval', 'state'])
+        except getopt.GetoptError:
+            print """Usage:
+                host: host guid.
+                timeout: timeout to fail on
+                interval: time between checks
+                state: check the state"""
+            sys.exit()
+        for o, a in opts:
+            if o in ('host'):
+                file="hb-%s" % (a)
+            if o in ('timeout'):
+                timeout=a
+            if o in ('interval'):
+                interval=a
+            if o in ('state'):
+                checkstate=True
+    # OVM3:
+    else:
+        # get options
+        try:
+            opts, args = getopt.getopt(sys.argv[1:], "g:p:f:c:t:i:s",
+                [ 'guid=', 'primary=','failcmd=','cmd=','timeout=','interval', 'state'])
+        except getopt.GetoptError:
+            print """Usage:
+                    --guid|-g: guid of the host to check
+                    --primary|-p: match for primary storage to monitor.
+                    --failcmd|-f: executed on timeout.
+                    --cmd|-c: command to execute next to hb file(s) on primary.
+                    --timeout|-t: excute failcmd after timeout(s) is hit.
+                    --interval|-i: run the checks every %ss>
+                    --state|-s check state"""
+            sys.exit()
+
+        for o, a in opts:
+            if o in ('-g', '--guid'):
+                file=".hb-%s" % (a)
+            if o in ('-p', '--primary'):
+                primary=a
+            if o in ('-f', '--failcmd'):
+                failcmd=a
+            if o in ('-c', '--cmd'):
+                cmd=a
+            if o in ('-t', '--timeout'):
+                timeout=int(a)
+            if o in ('-i', '--interval'):
+                interval=int(a)
+            if o in ('-s', '--state'):
+                checkstate=True
+
+    if primary == "":
+        primary=figureOutPrimary()
+
+    logger=Logger(level=level)
+    if checkstate == False:
+        os.chdir("/")
+        # os.setsid()
+        os.umask(0)
+        try:
+            pid = os.fork()
+            if pid > 0:
+                # exit first parent
+                if me == "heartbeat":
+                    print "> DONE <"
+                sys.exit(0)
+        except OSError, e:
+            print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror)
+            sys.exit(1)
+
+    checker=Check(cmd=cmd,
+        failcmd=failcmd,
+        file=file,
+        timeout=timeout,
+        interval=interval,
+        logger=logger,
+        check=checkstate);
+
+    while True:
+        start=time.time()
+        checker.run(timeout)
+        runtime=time.time() - start
+        logger.debug("cmd time: %s" % (runtime))
+        if checkstate:
+            for fs in checker.results:
+                print "%s: %s" % (fs, checker.results[fs])
+            if checker.ok == False:
+                sys.exit(1)
+            else:
+                sys.exit(0)
+        if runtime > interval:
+            logger.warning('Warning: runtime %s bigger than interval %s' %
+                (runtime, interval))
+        else:
+            time.sleep(interval)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/configuration/Config.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
index 982958e..e48e0b3 100644
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -724,7 +724,7 @@ public enum Config {
             String.class,
             "hypervisor.list",
             HypervisorType.Hyperv + "," + HypervisorType.KVM + "," + HypervisorType.XenServer + "," + HypervisorType.VMware + "," + HypervisorType.BareMetal + "," +
-                HypervisorType.Ovm + "," + HypervisorType.LXC,
+                HypervisorType.Ovm + "," + HypervisorType.LXC + "," + HypervisorType.Ovm3,
             "The list of hypervisors that this deployment will use.",
             "hypervisorList"),
     ManagementNetwork("Advanced", ManagementServer.class, String.class, "management.network.cidr", null, "The cidr of management server network", null),
@@ -1077,6 +1077,29 @@ public enum Config {
     OvmPrivateNetwork("Hidden", ManagementServer.class, String.class, "ovm.private.network.device", null, "Specify the private bridge on host for private network", null),
     OvmGuestNetwork("Hidden", ManagementServer.class, String.class, "ovm.guest.network.device", null, "Specify the private bridge on host for private network", null),
 
+    // Ovm3
+    Ovm3PublicNetwork("Hidden", ManagementServer.class, String.class, "ovm3.public.network.device", null, "Specify the public bridge on host for public network", null),
+    Ovm3PrivateNetwork("Hidden", ManagementServer.class, String.class, "ovm3.private.network.device", null, "Specify the private bridge on host for private network", null),
+    Ovm3GuestNetwork("Hidden", ManagementServer.class, String.class, "ovm3.guest.network.device", null, "Specify the guest bridge on host for guest network", null),
+    Ovm3StorageNetwork("Hidden", ManagementServer.class, String.class, "ovm3.storage.network.device", null, "Specify the storage bridge on host for storage network", null),
+    Ovm3HeartBeatTimeout(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "ovm3.heartbeat.timeout",
+            "120",
+            "timeout used for primary storage check, upon timeout a panic is triggered.",
+            null),
+    Ovm3HeartBeatInterval(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "ovm3.heartbeat.interval",
+            "1",
+            "interval used to check primary storage availability.",
+            null),
+
+
     // XenServer
     XenServerPublicNetwork(
             "Hidden",

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index d1a0887..ecd28e8 100644
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -369,6 +369,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
         configValuesForValidation.add("wait");
         configValuesForValidation.add("xenserver.heartbeat.interval");
         configValuesForValidation.add("xenserver.heartbeat.timeout");
+        configValuesForValidation.add("ovm3.heartbeat.interval");
+        configValuesForValidation.add("ovm3.heartbeat.timeout");
         configValuesForValidation.add("incorrect.login.attempts.allowed");
         configValuesForValidation.add("vm.password.length");
     }
@@ -1768,7 +1770,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
                                 PhysicalNetworkTrafficTypeVO mgmtTraffic = _trafficTypeDao.findBy(mgmtPhyNetwork.getId(), TrafficType.Management);
                                 _networkSvc.addTrafficTypeToPhysicalNetwork(mgmtPhyNetwork.getId(), TrafficType.Storage.toString(), "vlan", mgmtTraffic.getXenNetworkLabel(),
                                         mgmtTraffic.getKvmNetworkLabel(), mgmtTraffic.getVmwareNetworkLabel(), mgmtTraffic.getSimulatorNetworkLabel(), mgmtTraffic.getVlan(),
-                                        mgmtTraffic.getHypervNetworkLabel());
+                                        mgmtTraffic.getHypervNetworkLabel(), mgmtTraffic.getOvm3NetworkLabel());
                                 s_logger.info("No storage traffic type was specified by admin, create default storage traffic on physical network " + mgmtPhyNetwork.getId()
                                         + " with same configure of management traffic type");
                     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/network/NetworkModelImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java
index 6088212..4db7141 100644
--- a/server/src/com/cloud/network/NetworkModelImpl.java
+++ b/server/src/com/cloud/network/NetworkModelImpl.java
@@ -1226,6 +1226,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
                     case Hyperv:
                         label = mgmtTraffic.getHypervNetworkLabel();
                         break;
+                    case Ovm3:
+                        label = mgmtTraffic.getOvm3NetworkLabel();
+                        break;
                 }
                 return label;
             }
@@ -1258,6 +1261,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
                     case Hyperv:
                         label = storageTraffic.getHypervNetworkLabel();
                         break;
+                    case Ovm3:
+                        label = storageTraffic.getOvm3NetworkLabel();
+                        break;
                 }
                 return label;
             }
@@ -1618,6 +1624,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
                     case Hyperv:
                         label = publicTraffic.getHypervNetworkLabel();
                         break;
+                    case Ovm3:
+                        label = publicTraffic.getOvm3NetworkLabel();
+                        break;
                 }
                 return label;
             }
@@ -1650,7 +1659,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
                     case Hyperv:
                         label = guestTraffic.getHypervNetworkLabel();
                         break;
-
+                    case Ovm3:
+                        label = guestTraffic.getOvm3NetworkLabel();
+                        break;
                 }
                 return label;
             }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/network/NetworkServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java
index 4f60c1a..f00d502 100644
--- a/server/src/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/com/cloud/network/NetworkServiceImpl.java
@@ -3584,7 +3584,7 @@ public class NetworkServiceImpl extends ManagerBase implements  NetworkService {
     @DB
     @ActionEvent(eventType = EventTypes.EVENT_TRAFFIC_TYPE_CREATE, eventDescription = "Creating Physical Network TrafficType", create = true)
     public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficTypeStr, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel,
-            String simulatorLabel, String vlan, String hypervLabel) {
+            String simulatorLabel, String vlan, String hypervLabel, String ovm3Label) {
 
         // verify input parameters
         PhysicalNetworkVO network = _physicalNetworkDao.findById(physicalNetworkId);
@@ -3636,7 +3636,7 @@ public class NetworkServiceImpl extends ManagerBase implements  NetworkService {
                 xenLabel = getDefaultXenNetworkLabel(trafficType);
             }
             PhysicalNetworkTrafficTypeVO pNetworktrafficType = new PhysicalNetworkTrafficTypeVO(physicalNetworkId, trafficType, xenLabel, kvmLabel, vmwareLabel, simulatorLabel,
-                    vlan, hypervLabel);
+                    vlan, hypervLabel, ovm3Label);
             pNetworktrafficType = _pNTrafficTypeDao.persist(pNetworktrafficType);
 
             // For public traffic, get isolation method of physical network and update the public network accordingly
@@ -3696,7 +3696,7 @@ public class NetworkServiceImpl extends ManagerBase implements  NetworkService {
 
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_TRAFFIC_TYPE_UPDATE, eventDescription = "Updating physical network TrafficType", async = true)
-    public PhysicalNetworkTrafficType updatePhysicalNetworkTrafficType(Long id, String xenLabel, String kvmLabel, String vmwareLabel, String hypervLabel) {
+    public PhysicalNetworkTrafficType updatePhysicalNetworkTrafficType(Long id, String xenLabel, String kvmLabel, String vmwareLabel, String hypervLabel, String ovm3Label) {
 
         PhysicalNetworkTrafficTypeVO trafficType = _pNTrafficTypeDao.findById(id);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/network/router/NetworkHelperImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/NetworkHelperImpl.java b/server/src/com/cloud/network/router/NetworkHelperImpl.java
index 2cec4c8..852a223 100644
--- a/server/src/com/cloud/network/router/NetworkHelperImpl.java
+++ b/server/src/com/cloud/network/router/NetworkHelperImpl.java
@@ -160,6 +160,7 @@ public class NetworkHelperImpl implements NetworkHelper {
         hypervisorsMap.put(HypervisorType.VMware, VirtualNetworkApplianceManager.RouterTemplateVmware);
         hypervisorsMap.put(HypervisorType.Hyperv, VirtualNetworkApplianceManager.RouterTemplateHyperV);
         hypervisorsMap.put(HypervisorType.LXC, VirtualNetworkApplianceManager.RouterTemplateLxc);
+        hypervisorsMap.put(HypervisorType.Ovm3, VirtualNetworkApplianceManager.RouterTemplateOvm3);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
index 989dd84..a502018 100644
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
@@ -41,6 +41,7 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA
     static final String RouterTemplateVmwareCK = "router.template.vmware";
     static final String RouterTemplateHyperVCK = "router.template.hyperv";
     static final String RouterTemplateLxcCK = "router.template.lxc";
+    static final String RouterTemplateOvm3CK = "router.template.ovm3";
     static final String SetServiceMonitorCK = "network.router.EnableServiceMonitoring";
     static final String RouterAlertsCheckIntervalCK = "router.alerts.check.interval";
 
@@ -54,6 +55,8 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA
             "Name of the default router template on Hyperv.", true, ConfigKey.Scope.Zone, null);
     static final ConfigKey<String> RouterTemplateLxc = new ConfigKey<String>(String.class, RouterTemplateLxcCK, "Advanced", "SystemVM Template (LXC)",
             "Name of the default router template on LXC.", true, ConfigKey.Scope.Zone, null);
+    static final ConfigKey<String> RouterTemplateOvm3 = new ConfigKey<String>(String.class, RouterTemplateOvm3CK, "Advanced", "SystemVM Template (Ovm3)",
+            "Name of the default router template on Ovm3.", true, ConfigKey.Scope.Zone, null);
 
     static final ConfigKey<String> SetServiceMonitor = new ConfigKey<String>(String.class, SetServiceMonitorCK, "Advanced", "true",
             "service monitoring in router enable/disable option, default true", true, ConfigKey.Scope.Zone, null);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index e5d3630..99f3aa1 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -226,6 +226,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
         this.hTypes.add(HypervisorType.Simulator);
         this.hTypes.add(HypervisorType.LXC);
         this.hTypes.add(HypervisorType.Hyperv);
+        this.hTypes.add(HypervisorType.Ovm3);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/resource/ResourceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java
index 6beea23..2f6e199 100644
--- a/server/src/com/cloud/resource/ResourceManagerImpl.java
+++ b/server/src/com/cloud/resource/ResourceManagerImpl.java
@@ -484,6 +484,13 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
 
         if (clusterType == Cluster.ClusterType.CloudManaged) {
             Map<String, String> details = new HashMap<String, String>();
+            // should do this nicer perhaps ?
+            if (hypervisorType == HypervisorType.Ovm3) {
+                Map<String, String> allParams = cmd.getFullUrlParams();
+                details.put("ovm3vip", allParams.get("ovm3vip"));
+                details.put("ovm3pool", allParams.get("ovm3pool"));
+                details.put("ovm3cluster", allParams.get("ovm3cluster"));
+            }
             details.put("cpuOvercommitRatio", CapacityManager.CpuOverprovisioningFactor.value().toString());
             details.put("memoryOvercommitRatio", CapacityManager.MemOverprovisioningFactor.value().toString());
             _clusterDetailsDao.persist(cluster.getId(), details);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index eabaf23..1723c1e 100644
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -1128,15 +1128,15 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
 
         if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && !vm.getHypervisorType().equals(HypervisorType.KVM)
                 && !vm.getHypervisorType().equals(HypervisorType.Ovm) && !vm.getHypervisorType().equals(HypervisorType.Hyperv) && !vm.getHypervisorType().equals(HypervisorType.LXC)
-                && !vm.getHypervisorType().equals(HypervisorType.Simulator)) {
+                && !vm.getHypervisorType().equals(HypervisorType.Simulator) && !vm.getHypervisorType().equals(HypervisorType.Ovm3)) {
             if (s_logger.isDebugEnabled()) {
-                s_logger.debug(vm + " is not XenServer/VMware/KVM/OVM/Hyperv, cannot migrate this VM.");
+                s_logger.debug(vm + " is not XenServer/VMware/KVM/Ovm/Hyperv/Ovm3, cannot migrate this VM.");
             }
-            throw new InvalidParameterValueException("Unsupported Hypervisor Type for VM migration, we support " + "XenServer/VMware/KVM/Ovm/Hyperv only");
+            throw new InvalidParameterValueException("Unsupported Hypervisor Type for VM migration, we support " + "XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only");
         }
 
         if (vm.getType().equals(VirtualMachine.Type.User) && vm.getHypervisorType().equals(HypervisorType.LXC)) {
-            throw new InvalidParameterValueException("Unsupported Hypervisor Type for User VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv only");
+            throw new InvalidParameterValueException("Unsupported Hypervisor Type for User VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only");
         }
 
         long srcHostId = vm.getHostId();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
index afe141f..ad65bd6 100644
--- a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
+++ b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
@@ -77,7 +77,7 @@ public class StoragePoolMonitor implements Listener {
             if (scCmd.getHypervisorType() == HypervisorType.XenServer || scCmd.getHypervisorType() ==  HypervisorType.KVM ||
                 scCmd.getHypervisorType() == HypervisorType.VMware || scCmd.getHypervisorType() ==  HypervisorType.Simulator ||
                 scCmd.getHypervisorType() == HypervisorType.Ovm || scCmd.getHypervisorType() == HypervisorType.Hyperv ||
-                scCmd.getHypervisorType() == HypervisorType.LXC ) {
+                scCmd.getHypervisorType() == HypervisorType.LXC || scCmd.getHypervisorType() == HypervisorType.Ovm3) {
                 List<StoragePoolVO> pools = _poolDao.listBy(host.getDataCenterId(), host.getPodId(), host.getClusterId(), ScopeType.CLUSTER);
                 List<StoragePoolVO> zoneStoragePoolsByTags = _poolDao.findZoneWideStoragePoolsByTags(host.getDataCenterId(), null);
                 List<StoragePoolVO> zoneStoragePoolsByHypervisor = _poolDao.findZoneWideStoragePoolsByHypervisor(host.getDataCenterId(), scCmd.getHypervisorType());