Chinaunix首页 | 论坛 | 博客
  • 博客访问: 590096
  • 博文数量: 60
  • 博客积分: 3993
  • 博客等级: 中校
  • 技术积分: 1572
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-08 17:08
文章分类

全部博文(60)

文章存档

2012年(7)

2011年(35)

2010年(8)

2009年(7)

2008年(3)

分类: Python/Ruby

2010-06-12 18:31:23

   由于Perl的libvirt接口模块问题很多,在跨度较大的libvirt的版本情况下会直接产生段错误,在当前最高的0.8.1版本下做连接压力测试时会导致xend-inotify打开文件数过多,造成out of memory 问题,此时libvirtd进程未宕,但已经无法连接,没办法只能尝试使用一直很不喜欢的Python来试试看。
 
   在相同的0.7版本下使用Python API访问有些主机会在使用getHostname时报错,原因未知。
   从安装有0.7版本Python API的服务器访问0.6.3版本libvirtd有很大几率会使远端libvirtd产生段错误(是否这也可以成为入侵的一个可能入口?)。所有对libvirtd的相关监听端口必须做好防火墙保护工作。
 
 
   不熟悉Python,只写了轮询访问并写入数据库。在Perl的相关API没有稳定下来的情况下,其它内容将使用Perl的Catalyst加上Inline::Python模块实现。
 
Xen.py是自己简单包装的class。
read_libvirtd_and_insert_into_mysql.py是直接使用的脚本
init.sql是初始化的表结构
相关环境:
system: rhel5.4
kernel: 2.6.18-164.el5xen
libvirt 0.7.0
xen api: xen-3.0.1
 
 
Xen.py
 

import sys
import libvirt
import os
import libxml2
import pdb

class Info:
        def __init__(self):
                self.init='_Init_'
                self.uri = ''
                self.mydata = ""
                self.username = 'test'
                self.password = '123456'

        def print_xml(self,key,ctx,path):
                res=ctx.xpathEval(path)
                if res is None or len(res) ==0:
                        value="Unknown"
                else:
                        value=res[0].content
                #self.print_entry(key,value)
                return value

        def print_entry(self,key,value):
                print "%-10s %-10s" %(key,value)

        def getCredentials(self,credentials, data):
                for credential in credentials:
                        if credential[0] == libvirt.VIR_CRED_AUTHNAME:
                                data = self.username
                                credential[4] = data
                        elif credential[0] == libvirt.VIR_CRED_PASSPHRASE:
                                credential[4] = self.password
                        else:
                                return -1
                return 0

        def conn(self,ip,username,password):
                flags = [libvirt.VIR_CRED_AUTHNAME,libvirt.VIR_CRED_PASSPHRASE]
                auth = [flags,self.getCredentials,self.mydata]
                if ip:
                        uri='xen+tcp://'+ip
                        self.uri=uri
                        if username and password:
                                self.username=username
                                self.password=password
                                conn = libvirt.openAuth(self.uri,auth,0)
                        else:
                                exit -2
                        return conn
                else:
                        exit -1

        def get_phy_info(self,conn):
                conn_stat=-1
                hostname='undef'
                uri='undef'
                freemem='undef'
                if conn:
                        #pdb.set_trace()
                        conn_stat=1
                        try:
                                hostname=conn.getHostname()
                        except:
                                pass
                        try:
                                uri=conn.getURI()
                        except:
                                pass
                        try:
                                freemem=conn.getFreeMemory()
                        except:
                                pass

                return(conn_stat,hostname,uri,freemem)

        def get_phy_interface(self,conn):
                interface=()
                if conn:
                        try:
                                interface=conn.listDevices('net',0)
                        except:
                                pass
                return interface

        def get_domains(self,conn):
                doms={}
                try:
                        #active#
                        for id in conn.listDomainsID():
                                dom=conn.lookupByID(id)
                                doms[dom.name()]=id
                        #inactive#
                        for name in conn.listDefinedDomains():
                                dom=conn.lookupByName(name)
                                doms[name]=-255
                except:
                        pass

                return doms

        def get_domain_info(self,conn,name):
                state=-255
                maxmem=-255
                usedmem=-255
                vcpus=-255
                file={}
                block={}
                device={}
                device_mac={}
                try:
                        dom=conn.lookupByName(name)
                        info=dom.info()
                        (state,maxmem,usedmem,vcpus)=(info[0],info[1],info[2],info[3])
                        xmldesc=dom.XMLDesc(0)
                        doc=libxml2.parseDoc(xmldesc)
                        ctx=doc.xpathNewContext()
                        devs=ctx.xpathEval("/domain/devices/*")
                        for d in devs:
                                ctx.setContextNode(d)
                                type=self.print_xml("Type",ctx,"@type")
                                if type == 'file':
                                        file[self.print_xml("Source",ctx,"source/@file")]=self.print_xml("Target:",ctx,"target/@dev")
                                elif type == 'block':
                                        block[self.print_xml("Source",ctx,"source/@dev")]=self.print_xml("Target:",ctx,"target/@dev")
                                if type == 'bridge':
                                        device[self.print_xml("Source",ctx,"source/@bridge")]=self.print_xml("DEV:",ctx,"target/@dev")
                                        device_mac[self.print_xml("DEV",ctx,"target/@dev")]=self.print_xml("MAC Addr:",ctx,"mac/@address")
                except:
                        pass
                return (state,maxmem,usedmem,vcpus,file,block,device,device_mac)



read_libvirtd_and_insert_into_mysql.py 

#!/usr/bin/env python
import sys
sys.path.append("/scripts/libvirt_py")
import Xen
import MySQLdb

def run_sql (conn,sql,status):
        #print sql
        if status==1:
                cursor=conn.cursor()
                try:
                        cursor.execute(sql)
                        row=cursor.fetchall()
                except:
                        pass
                cursor.close()
                return row
        else:
                cursor=conn.cursor()
                try:
                        cursor.execute(sql)
                except:
                        pass
                cursor.close()

def info(mysql_conn,ip,user,password):
        x=Xen.Info()
        conn=x.conn(ip,user,password)
        #print "#"*80
        #print "# Physical Matchine Info #"
        (conn_stat,hostname,uri,freemem)=x.get_phy_info(conn)
        #print "\tconn_stat:%s hostname:%s uri:%s freemem:%sM" %(conn_stat,hostname,uri,freemem/1024/1024)
        sql="SELECT ID FROM PHYSICALMATCHINE WHERE IP='%s'" %(ip)
        row=run_sql(mysql_conn,sql,1)
        id=''

        if row:
                id=row[0][0]
                sql="UPDATE PHYSICALMATCHINE SET CONN_STAT=%s,HOSTNAME='%s',URI='%s',FREEMEM=%d,UPDATETIME=now() WHERE ID=%s" %(conn_stat,hostname,uri,freemem/1024,id)
        else:
                sql="INSERT INTO PHYSICALMATCHINE (IP,CONN_STAT,HOSTNAME,URI,FREEMEM,UPDATETIME) VALUES('%s','%s','%s','%s','%d',now())" %(ip,conn_stat,hostname,uri,freemem/1024)
        run_sql(mysql_conn,sql,0)


        interfaces=x.get_phy_interface(conn)

        sql="DELETE FROM PHYSICALMACS WHERE PHYSICALMATCHINE_ID=%s" %(id)
        run_sql(mysql_conn,sql,0)
        sql="DELETE FROM DOMAININFO WHERE PHYSICALMATCHINE_ID=%s" %(id)
        run_sql(mysql_conn,sql,0)
        sql="DELETE FROM DOMAIN_FILEINFO WHERE PHYSICALMATCHINE_ID=%s" %(id)
        run_sql(mysql_conn,sql,0)
        sql="DELETE FROM DOMAIN_BLOCKINFO WHERE PHYSICALMATCHINE_ID=%s" %(id)
        run_sql(mysql_conn,sql,0)
        sql="DELETE FROM DOMAIN_NETWORKINFO WHERE PHYSICALMATCHINE_ID=%s" %(id)
        run_sql(mysql_conn,sql,0)

        for i in interfaces:
                #print "\tinterface:%s" %(i)
                j = "%s" % (i)
                mac= "%s:%s:%s:%s:%s:%s" % (i[4:6],i[7:9],i[10:12],i[13:15],i[16:18],i[19:21])
                sql="INSERT INTO PHYSICALMACS (PHYSICALMATCHINE_ID,MAC,UPDATETIME) VALUES(%s,'%s',now())" %(id,mac)
                run_sql(mysql_conn,sql,0)

        #print "# All Domains #"
        doms=x.get_domains(conn)
        for domain_name in doms.keys():
                #print "\tdomain_name:%s domain_id:%s" %(domain_name,doms[domain_name])
                (state,maxmem,usedmem,vcpus,files,blocks,devices,devices_mac)=x.get_domain_info(conn,domain_name)
                #print "\t\tstate:%s maxmem:%s usedmem:%s vcpus:%s" % (state,maxmem,usedmem,vcpus)
                sql="INSERT INTO DOMAININFO (PHYSICALMATCHINE_ID,DOMAINNAME,DOMAIN_ID,STATE,MAXMEM,USEDMEM,VCPUS,UPDATETIME) VALUES(%s,'%s','%s','%s','%s','%s','%s',now())" %(id,domain_name,doms[domain_name],state,maxmem/1024,usedmem/1024,vcpus)
                run_sql(mysql_conn,sql,0)

                #print "\t#files#"
                for f in files.keys():
                        #print "\t\t%s %s" %(f,files[f])
                        sql="INSERT INTO DOMAIN_FILEINFO (PHYSICALMATCHINE_ID,DOMAINNAME,FILENAME,DEVICETYPE,UPDATETIME) VALUES(%s,'%s','%s','%s',now())" %(id,domain_name,f,files[f])
                        run_sql(mysql_conn,sql,0)

                #print "\t#blocks#"
                for b in blocks.keys():
                        #print "\t\t%s %s" %(b,blocks[b])
                        sql="INSERT INTO DOMAIN_BLOCKINFO (PHYSICALMATCHINE_ID,DOMAINNAME,FILENAME,DEVICETYPE,UPDATETIME) VALUES(%s,'%s','%s','%s',now())" %(id,domain_name,b,blocks[b])
                        run_sql(mysql_conn,sql,0)

                #print "\t#devices#"
                for d in devices.keys():
                        #print "\t\t%s %s" %(d,devices[d])
                        sql="INSERT INTO DOMAIN_NETWORKINFO (PHYSICALMATCHINE_ID,DOMAINNAME,DEVICENAME,MAC,SOURCE,TARGET,UPDATETIME) VALUES(%s,'%s','%s','%s','%s','%s',now())" %(id,domain_name,devices[d],devices_mac[devices[d]],d,devices[d])
                        run_sql(mysql_conn,sql,0)

                #print "\t#devices_mac#"
                #for d_m in devices_mac.keys():
                        #print "\t\t%s %s" %(d_m,devices_mac[d_m])
                #print "\t"+"#"*50
        #print "#"*80


mysql_conn=MySQLdb.connect(host="localhost",user="root",passwd="",db="XEN")
user='xen'
password='xen'
sql="SELECT IP FROM XENMATCHINE"
ips=run_sql(mysql_conn,sql,1)
for i in ips:
        ip=i[0]
        #print ip
        try:
                info(mysql_conn,ip,user,password)
        except:
                pass
mysql_conn.close()


init.sql

DROP DATABASE XEN;
CREATE DATABASE XEN;
USE XEN;

CREATE TABLE XENMATCHINE (
    ID INT(10) NOT NULL auto_increment,
    IP VARCHAR(16),
    INFO VARCHAR(256),
    UPDATETIME DATETIME,
    PRIMARY KEY (ID),
    KEY IP (IP)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO XENMATCHINE (IP) VALUES ('192.168.1.1');
INSERT INTO XENMATCHINE (IP) VALUES ('192.168.1.2');
INSERT INTO XENMATCHINE (IP) VALUES ('192.168.1.3');

CREATE TABLE PHYSICALMATCHINE (
    ID INT(10) NOT NULL auto_increment,
    IP VARCHAR(16),
    CONN_STAT INT(10),
    HOSTNAME VARCHAR(64),
    URI VARCHAR(64),
    FREEMEM INT(10),
    UPDATETIME DATETIME,
    PRIMARY KEY (ID)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE PHYSICALMACS (
    PHYSICALMATCHINE_ID INT(10) NOT NULL default 1,
    MAC VARCHAR(64),
    UPDATETIME DATETIME,
    PRIMARY KEY (PHYSICALMATCHINE_ID,MAC)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE DOMAININFO (
    PHYSICALMATCHINE_ID INT(10) NOT NULL default 1,
    DOMAINNAME VARCHAR(64),
    DOMAIN_ID INT(10),
    STATE INT(10),
    MAXMEM INT(10),
    USEDMEM INT(10),
    VCPUS INT(10),
    UPDATETIME DATETIME,
    PRIMARY KEY (PHYSICALMATCHINE_ID,DOMAINNAME)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE DOMAIN_FILEINFO (
    PHYSICALMATCHINE_ID INT(10) NOT NULL default 1,
    DOMAINNAME VARCHAR(64),
    FILENAME VARCHAR(256),
    DEVICETYPE VARCHAR(64),
    UPDATETIME DATETIME,
    PRIMARY KEY (PHYSICALMATCHINE_ID,DOMAINNAME)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


CREATE TABLE DOMAIN_BLOCKINFO (
    PHYSICALMATCHINE_ID INT(10) NOT NULL default 1,
    DOMAINNAME VARCHAR(64),
    BLOCKNAME VARCHAR(256),
    DEVICETYPE VARCHAR(64),
    UPDATETIME DATETIME,
    PRIMARY KEY (PHYSICALMATCHINE_ID,DOMAINNAME)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


CREATE TABLE DOMAIN_NETWORKINFO (
    PHYSICALMATCHINE_ID INT(10) NOT NULL default 1,
    DOMAINNAME VARCHAR(64),
    DEVICENAME VARCHAR(64),
    MAC VARCHAR(64),
    SOURCE VARCHAR(64),
    TARGET VARCHAR(64),
    UPDATETIME DATETIME,
    PRIMARY KEY (PHYSICALMATCHINE_ID,DOMAINNAME)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


阅读(3529) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~