mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	This is a plugin that puts in ovm3 support ranging from 3.3.1 to 3.3.2. Basic functionality is in here, advanced networking etc.. Snapshots only work when a VM is stopped now due to the semantics of OVM's raw image implementation (so snapshots should work on a storage level underneath the hypervisor shrug) This closes #113 Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
		
			
				
	
	
		
			589 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			589 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/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()
 |