vn

来自「xen 3.2.2 源码」· 代码 · 共 905 行 · 第 1/2 页

TXT
905
字号
#!/usr/bin/env python2.4#  -*- mode: python; -*-#============================================================================# Copyright (C) 2005, 2006 Mike Wray <mike.wray@hp.com>## This library is free software; you can redistribute it and/or modify# it under the terms of the GNU Lesser General Public License as published by# the Free Software Foundation; either version 2.1 of the License, or# (at your option) any later version.## This library is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the# GNU Lesser General Public License for more details.## You should have received a copy of the GNU Lesser General Public License# along with this library; if not, write to the Free Software# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA#============================================================================# Vnet (network virtualization) control utility.import osimport os.pathimport reimport socketimport sysfrom getopt import getopt, GetoptErrorsys.path.append('/usr/lib/python')sys.path.append('/usr/lib64/python')from xen.xend import sxpfrom xen.xend.PrettyPrint import prettyprint# Path of unix-domain socket to vnetd.VNETD_PATH = "/tmp/vnetd"def vnetd_running():    return os.path.exists(VNETD_PATH)def vnetd_open():    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)    sock.connect(VNETD_PATH)    fi = sock.makefile('r', 0)    fo = sock.makefile('w', 0)    return (fi, fo)os.defpath += ':/sbin:/usr/sbin:/usr/local/sbin'CMD_IFCONFIG = 'ifconfig'CMD_BRCTL    = 'brctl'opts = Noneclass Opts:    def __init__(self, **kwds):        for (k, v) in kwds.items():            setattr(self, k, v)opts = Opts(verbose=False, dryrun=False)def set_opts(val):    global opts    opts = val    return optsdef cmd(prog, *args):    """Execute command 'prog' with 'args', optionally printing the command.    """    global opts    command = " ".join([ prog ] + map(str, args))    if opts.verbose:        print command    if not opts.dryrun:        os.system(command)def vif_bridge_add(bridge, vif):    """Add a network interface to a bridge.    """    cmd(CMD_BRCTL, 'addif', bridge, vif)def vif_bridge_rem(bridge, vif):    """Remove a network interface from a bridge.    """    cmd(CMD_BRCTL, 'delif', bridge, vif)def bridge_create(bridge, **kwd):    """Create a bridge.    Defaults hello time to 0, forward delay to 0 and stp off.    """    cmd(CMD_BRCTL, 'addbr', bridge)    if kwd.get('hello', None) is None:        kwd['hello'] = 0    if kwd.get('fd', None) is None:        kwd['fd'] = 0    if kwd.get('stp', None) is None:        kwd['stp'] = 'off'    bridge_set(bridge, **kwd)    cmd(CMD_IFCONFIG, bridge, "up")def bridge_set(bridge, hello=None, fd=None, stp=None):    """Set bridge parameters.    """    if hello is not None:        cmd(CMD_BRCTL, 'sethello', bridge, hello)    if fd is not None:        cmd(CMD_BRCTL, 'setfd', bridge, fd)    if stp is not None:        cmd(CMD_BRCTL, 'stp', bridge, stp)def bridge_del(bridge):    """Delete a bridge.    """    cmd(CMD_IFCONFIG, bridge, 'down')    cmd(CMD_BRCTL, 'delbr', bridge)class Bridge:    # Network interfaces are at /sys/class/net/*.    # A bridge interface has ./bridge dir, ./brif is dir of bridged interfaces    # (symlinks to the brport dirs).    # If an interface is bridged ./brport is bridged port info,    # brport/bridge is a symlink to the bridge.    INTERFACE_DIR = "/sys/class/net"    def isBridge(klass, dev):        """Test if a network interface is a bridge.        """        devdir = os.path.join(klass.INTERFACE_DIR, dev)        brdir = os.path.join(devdir, "bridge")        try:            os.stat(brdir)            return True        except:            return False    isBridge = classmethod(isBridge)    def getInterfaces(klass):        """Get a list of the network interfaces.        """        try:            v = os.listdir(klass.INTERFACE_DIR)            v.sort()            return v        except:            return []    getInterfaces = classmethod(getInterfaces)    def getInterfaceAddr(klass, intf):        intfdir = os.path.join(klass.INTERFACE_DIR, intf)        addrfile = os.path.join(intfdir, "address")        try:            f = file(addrfile, "rb")        except Exception, ex:            #print ex            return None        try:            return f.readline().strip()        finally:            f.close()    getInterfaceAddr = classmethod(getInterfaceAddr)    def getBridges(klass):        """Get a list of the bridges.        """        return [ dev for dev in klass.getInterfaces() if klass.isBridge(dev) ]    getBridges = classmethod(getBridges)    def getBridgeInterfaces(klass, dev):        """Get a list of the interfaces attached to a bridge.        """        devdir = os.path.join(klass.INTERFACE_DIR, dev)        intfdir = os.path.join(devdir, "brif")        try:            v = os.listdir(intfdir)            v.sort()            return v        except:            return []    getBridgeInterfaces = classmethod(getBridgeInterfaces)    def getBridge(klass, dev):        """Get the bridge an interface is attached to (if any).        """        devdir = os.path.join(klass.INTERFACE_DIR, dev)        brfile = os.path.join(devdir, "brport/bridge")        try:            brpath = os.readlink(brfile)            return os.path.basename(brpath)        except:            return None    getBridge = classmethod(getBridge)def vnet_cmd(expr):    """Send a command expression to the vnet implementation.    """    if vnetd_running():        (fi, fo) = vnetd_open()    else:        fi = None        fo = file("/proc/vnet/policy", "wb")    try:        sxp.show(expr, fo)        fo.flush()    finally:        if fi: fi.close()        if fo: fo.close()def varp_flush():    """Flush the varp cache.    """    expr = ['varp.flush']    return vnet_cmd(expr)def vif_add(vnetid, vmac):    """Tell the vnet implementation to add a vif to a vnet.    """    expr = ['vif.add', ['vnet', vnetid], ['vmac', vmac]]    return vnet_cmd(expr)def vif_del(vnetid, vmac):    """Tell the vnet implementation to delete a vif from a vnet.    """    expr = ['vif.del', ['vnet', vnetid], ['vmac', vmac]]    return vnet_cmd(expr)def vnet_add(vnetid, vnetif=None, security=None):    """Tell the vnet implementation to add a vnet.    """    expr = ['vnet.add', ['id', vnetid]]    if vnetif:        expr.append(['vnetif', vnetif])    if security:        expr.append(['security', security])    return vnet_cmd(expr)def peer_add(addr, port=None):    expr = ['peer.add', ['addr', addr]]    if port:        expr.append(['port', port])    return vnet_cmd(expr)    def peer_del(addr, port=None):    expr = ['peer.del', ['addr', addr]]    return vnet_cmd(expr)def vnet_del(vnetid):    """Tell the vnet implementation to delete a vnet.    """    expr = ['vnet.del', ['id', vnetid]]    return vnet_cmd(expr)def vnet_create(vnetid, vnetif=None, bridge=None, security=None):    """Tell the vnet implementation to add a vnet.    If 'bridge' is non-null, create the bridge and add the vnet interface    to it.    """    vnet_add(vnetid, vnetif=vnetif, security=security)    val = vnet_lookup(vnetid)    if not vnetif:        vnetif = sxp.child_value(val, "vnetif")    vmac = get_mac(vnetif)    emac = get_mac("eth0") or get_mac("eth1") or get_mac("eth2")    if emac and vmac != emac:        set_mac(vnetif, emac)    cmd(CMD_IFCONFIG, vnetif, 'up')    if bridge:        bridge_create(bridge)        vif_bridge_add(bridge, vnetif)    return val        def vnet_delete(vnet, delbridge=False):    """Tell the vnet implementation to delete a vnet.    If the vnet interface is attached to a bridge,    remove it from the bridge, and if delbridge is true    delete the bridge.    """    v = vnet_lookup(vnet)        if not v:        raise GetoptError("vnet not found: %s" % vnet)    vnetid = sxp.child_value(v, "id")    vnetif = sxp.child_value(v, "vnetif")    bridge = Bridge.getBridge(vnetif)    if bridge:        vif_bridge_rem(bridge, vnetif)        if delbridge:            bridge_del(bridge)    return vnet_del(vnetid)def get_mac(intf):    """Get the mac address of an interface.    """    try:        return Bridge.getInterfaceAddr(intf)    except:        pass    hwre = re.compile(".*\s+HWaddr\s+(?P<mac>\S*)\s+.*")    fin = os.popen("%s %s" % (CMD_IFCONFIG, intf), 'r')    try:        for x in fin:            m = hwre.match(x)            if not m:                continue            info = m.groupdict()            return info['mac']        return None    finally:        fin.close()def set_mac(intf, mac):    cmd(CMD_IFCONFIG, intf, 'down')    cmd(CMD_IFCONFIG, intf, 'hw', 'ether', mac)    cmd(CMD_IFCONFIG, intf, 'up')def get_addr(host):    return socket.gethostbyname(host)def get_port(srv):    return srvdef vnetidof(v):    """Normalise a vnet id. Adds leading 0 fields to make up 8 if    there aren't enough. Pads all fields to 4 hex digits.    """    try:        l = v.split(":")        l = [ int(x or 0, 16) for x in l ]        l = [ 0 ] * (8 - len(l)) + l        return ":".join([ "%04x" % x for x in l ])    except:        return Nonedef vnet_lookup(vnet, vnets=None):    """Find the vnet with the given vnet id or vnet interface.    @param vnet id or interface    @param vnets list of vnet info to use (get from implementation if None)    @return vnet info or None if not found    """    vnetid = vnetidof(vnet)    if vnets is None:        vnets = vnet_list()    for v in vnets:        vid = sxp.child_value(v, "id")        if vid == vnet or vid == vnetid:            return v        if sxp.child_value(v, "vnetif") == vnet:            return v    return Nonedef get_vnetid(vnet):    """Get the normalised vnet id of the given vnet id or vnet interface.    Raises an error if the vnet cannot be found.    """    v = vnet_lookup(vnet)    if not v:        raise GetoptError("vnet not found: %s" % vnet)    vnetid = sxp.child_value(v, "id")    return vnetiddef vif_list():    """Get the list of vif info from the vnet implementation.    """    if vnetd_running():        (fi, fo) = vnetd_open()        sxp.show(['vif.list'], fo)        fo.flush()    else:        fi = file("/proc/vnet/vifs")        fo = None    try:        return sxp.parse(fi) or []    finally:        if fi: fi.close()        if fo: fo.close()def vnets_filter(vnetlist, vnets):    """Filter a list of vnet info by a list of vnet ids or interfaces.    """    if vnets is None:        val = vnetlist    else:        val = []        for x in vnets:            v = vnet_lookup(x, vnets=vnetlist)            if not v:                continue            val.append(v)    return valdef vnet_list(vnets=None):    """Get the list of vnet info from the vnet implementation,    sorted by vnet id.    @param vnets list of vnet ids or interfaces to filter the results by    """    if vnetd_running():        (fi, fo) = vnetd_open()        sxp.show(['vnet.list'], fo)        fo.flush()    else:        fi = file("/proc/vnet/vnets")        fo = None    try:        val = vnets_filter(sxp.parse(fi) or [], vnets)        val.sort(lambda x, y:                   cmp(sxp.child_value(x, "id"),                       sxp.child_value(y, "id")))        return val    finally:        if fi: fi.close()        if fo: fo.close()        def vnif_list(vnets=None):    """Get the list of vnet interface names from the vnet implementation.    @param vnets list of vnet ids or interfaces to filter the results by    """    vnifs = []    for v in vnet_list(vnets=vnets):        vnetif = sxp.child_value(v, "vnetif")        if vnetif:            vnifs.append(vnetif)    return vnifs        def varp_list():    """Get the list of varp info from the vnet implementation.    """    if vnetd_running():        (fi, fo) = vnetd_open()        sxp.show(['varp.list'], fo)        fo.flush()    else:        fi = file("/proc/vnet/varp")        fo = None    try:        return sxp.parse(fi) or []    finally:        if fi: fi.close()        if fo: fo.close()def peer_list():    if vnetd_running():        (fi, fo) = vnetd_open()        sxp.show(['peer.list'], fo)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?