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 + -
显示快捷键?