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());
