예제 #1
0
    def prepareOCFS2Nodes(clusterName, nodeString):
        def compareClusterConfig(nodes):
            def sortNodes(nodes):
                ns = []
                for n in nodes:
                    ns.insert(int(n["number"]), n)
                return ns
            
            def compareNodes(ns1, ns2):
                if len(ns1) != len(ns2):
                    return False
                
                for i in range(0, len(ns1)):
                    n1 = ns1[i]
                    n2 = ns2[i]
                    if n1["ip_address"] != n2["ip_address"] or n1["number"] != n2["number"] \
                       or n1["name"] != n2["name"]:
                        return False
                return True
                    
            if exists(OCFS2_CLUSTER_CONF):
                oldConf = parse_ocfs2_cluster_conf()
                cluster = oldConf["cluster"]
                nodesNum = cluster["node_count"]
                if len(nodes) != nodesNum:
                    return False
                
                new = sortNodes(nodes)
                old = sortNodes(oldConf["nodes"])
                return compareNodes(new, old)
            else:
                return False
        
        def configureEtcHosts(nodes):
            if not exists(ETC_HOSTS):
                orignalConf = ""
            else:
                fd = open(ETC_HOSTS, "r")
                orignalConf = fd.read()
                fd.close()
            
            pattern = r"(.*%s.*)|(.*%s.*)"
            newlines = []
            for n in nodes:
                p = pattern % (n["ip_address"], n["name"])
                orignalConf = re.sub(p, "", orignalConf)
                newlines.append("%s\t%s\n"%(n["ip_address"], n["name"]))
            
            orignalConf = orignalConf + "".join(newlines)
            # remove extra empty lines
            orignalConf = re.sub(r"\n\s*\n*", "\n", orignalConf)
            logger.debug(OvmStoragePool.prepareOCFS2Nodes, "Configure /etc/hosts:%s\n"%orignalConf)
            fd = open(ETC_HOSTS, "w")
            fd.write(orignalConf)
            fd.close()
            
        try:
            nodeString = nodeString.strip(";")
            nodes = []
            for n in nodeString.split(";"):
                params = n.split(":")
                if len(params) != 3: raise Exception("Wrong parameter(%s) in node string(%s)"%(n, nodeString))
                dict = {"number":params[0], "ip_address":params[1], "name":params[2]}
                nodes.append(dict)
            
            if len(nodes) > 255:
                raise Exception("%s nodes beyond maximum 255 allowed by OCFS2"%len(nodes))
            
            if compareClusterConfig(nodes):
               logger.debug(OvmStoragePool.prepareOCFS2Nodes, "Nodes configure are the same, return")
               rs = SUCC()
               return rs
    
            lines = []
            for n in nodes:
                lines.append("node:\n")
                lines.append("\tip_port     = %s\n" % "7777")
                lines.append("\tip_address  = %s\n" % n["ip_address"])
                lines.append("\tnumber      = %s\n" % n["number"])
                lines.append("\tname        = %s\n" % n["name"])
                lines.append("\tcluster     = %s\n" % clusterName)
                lines.append("\n")
            lines.append("cluster:\n")
            lines.append("\tnode_count  = %d\n" % len(nodes))
            lines.append("\tname        = %s\n" % clusterName)
            lines.append("\n")
            conf = "".join(lines)
            clusterm_set_ocfs2_cluster_conf(conf)
            clusterm_start_o2cb_service()
            logger.debug(OvmStoragePool.prepareOCFS2Nodes, "Configure cluster.conf to:\n%s"%conf)
            configureEtcHosts(nodes)
            rs = SUCC()
            return rs
        
        except Exception, e:
            errmsg = fmt_err_msg(e)
            logger.error(OvmStoragePool.prepareOCFS2Nodes, errmsg)
            raise XmlRpcFault(toErrCode(OvmStoragePool, OvmStoragePool.prepareOCFS2Nodes), errmsg)
            

            
예제 #2
0
    def prepareOCFS2Nodes(clusterName, nodeString):
        def compareClusterConfig(nodes):
            def sortNodes(nodes):
                ns = []
                for n in nodes:
                    ns.insert(int(n["number"]), n)
                return ns
            
            def compareNodes(ns1, ns2):
                if len(ns1) != len(ns2):
                    return False
                
                for i in range(0, len(ns1)):
                    n1 = ns1[i]
                    n2 = ns2[i]
                    if n1["ip_address"] != n2["ip_address"] or n1["number"] != n2["number"] \
                       or n1["name"] != n2["name"]:
                        return False
                return True
                    
            if exists(OCFS2_CLUSTER_CONF):
                oldConf = parse_ocfs2_cluster_conf()
                cluster = oldConf["cluster"]
                nodesNum = cluster["node_count"]
                if len(nodes) != nodesNum:
                    return False
                
                new = sortNodes(nodes)
                old = sortNodes(oldConf["nodes"])
                return compareNodes(new, old)
            else:
                return False
        
        def configureEtcHosts(nodes):
            if not exists(ETC_HOSTS):
                orignalConf = ""
            else:
                fd = open(ETC_HOSTS, "r")
                orignalConf = fd.read()
                fd.close()
            
            pattern = r"(.*%s.*)|(.*%s.*)"
            newlines = []
            for n in nodes:
                p = pattern % (n["ip_address"], n["name"])
                orignalConf = re.sub(p, "", orignalConf)
                newlines.append("%s\t%s\n"%(n["ip_address"], n["name"]))
            
            orignalConf = orignalConf + "".join(newlines)
            # remove extra empty lines
            orignalConf = re.sub(r"\n\s*\n*", "\n", orignalConf)
            logger.debug(OvmStoragePool.prepareOCFS2Nodes, "Configure /etc/hosts:%s\n"%orignalConf)
            fd = open(ETC_HOSTS, "w")
            fd.write(orignalConf)
            fd.close()
        
        def configureHostName(nodes):
            myIp = successToMap(get_master_ip())['ip']
            nodeName = None
            for n in nodes:
                if myIp == n["ip_address"]:
                    nodeName = n["name"]
                    break
            
            if nodeName == None: raise Exception("Cannot find node equals to my ip address:%s"%myIp)
            if not exists(HOSTNAME_FILE):
                originalConf = ""
            else:
                fd = open(HOSTNAME_FILE, "r")
                originalConf = fd.read()
                fd.close()
            
            pattern = r"HOSTNAME=(.*)"
            # remove any old hostname
            originalConf = re.sub(pattern, "", originalConf)
            # remove extra empty lines
            originalConf = re.sub(r"\n\s*\n*", "\n", originalConf) + "\n" + "HOSTNAME=%s"%nodeName
            logger.debug(OvmStoragePool.prepareOCFS2Nodes, "Configure %s:%s\n"%(HOSTNAME_FILE,originalConf))
            fd = open(HOSTNAME_FILE, "w")
            fd.write(originalConf)
            fd.close()
            doCmd(['hostname', nodeName])
            
        def checkStaleCluster(clusterName):
            if exists('/sys/kernel/config/cluster/'):
                dirs = os.listdir('/sys/kernel/config/cluster/')
                for dir in dirs:
                    if dir != clusterName:
                        errMsg = '''CloudStack detected there is a stale cluster(%s) on host %s. Please manually clean up it first then add again by
1) remove the host from cloudstack 
2) umount all OCFS2 device on host
3) /etc/init.d/o2cb offline %s
4) /etc/init.d/o2cb restart
if this doesn't resolve the problem, please check oracle manual to see how to offline a cluster
    ''' % (dir, get_master_ip, dir)
                        raise Exception(errMsg)
            
        try:
            checkStaleCluster(clusterName)
            nodeString = nodeString.strip(";")
            nodes = []
            for n in nodeString.split(";"):
                params = n.split(":")
                if len(params) != 3: raise Exception("Wrong parameter(%s) in node string(%s)"%(n, nodeString))
                dict = {"number":params[0], "ip_address":params[1], "name":params[2]}
                nodes.append(dict)
            
            if len(nodes) > 255:
                raise Exception("%s nodes beyond maximum 255 allowed by OCFS2"%len(nodes))
            
            if compareClusterConfig(nodes):
               logger.debug(OvmStoragePool.prepareOCFS2Nodes, "Nodes configure are the same, return")
               rs = SUCC()
               return rs
    
            lines = []
            for n in nodes:
                lines.append("node:\n")
                lines.append("\tip_port     = %s\n" % "7777")
                lines.append("\tip_address  = %s\n" % n["ip_address"])
                lines.append("\tnumber      = %s\n" % n["number"])
                lines.append("\tname        = %s\n" % n["name"])
                lines.append("\tcluster     = %s\n" % clusterName)
                lines.append("\n")
            lines.append("cluster:\n")
            lines.append("\tnode_count  = %d\n" % len(nodes))
            lines.append("\tname        = %s\n" % clusterName)
            lines.append("\n")
            conf = "".join(lines)
            
            configureHostName(nodes)
            configureEtcHosts(nodes)
            clusterm_set_ocfs2_cluster_conf(conf)
            clusterm_start_o2cb_service()
            logger.debug(OvmStoragePool.prepareOCFS2Nodes, "Configure cluster.conf to:\n%s"%conf)
            rs = SUCC()
            return rs
        
        except Exception, e:
            errmsg = fmt_err_msg(e)
            logger.error(OvmStoragePool.prepareOCFS2Nodes, errmsg)
            raise XmlRpcFault(toErrCode(OvmStoragePool, OvmStoragePool.prepareOCFS2Nodes), errmsg)