ia64/xen-unstable

annotate tools/vnet/scripts/vn @ 19527:0e24e9674ded

tools: Always use sane upstream (`native') python paths

Previously, by default we would install our python modules into
/usr/lib/python/xen, for example /usr/lib/python/xen/__init__.py.
Upstream python's standard install location (a) includes the Python
version number and (b) puts things in site-packages by default.

Our best conjecture for the reason for this was an attempt to make the
installs portable between different python versions. However, that
doesn't work because compiled python modules (.pyc), and C python
extensions corresponding to one version of python, are not compatible
across different versions of python.

This is why upstream include the version number.

site-packages is the standard location for locally-installed packages
and is automatically included on the python search path.

In this change, we abandon our own unusual python path setup:

* Invoke setup.py in an entirely standard manner. We pass
PREFIX and DESTDIR using the appropriate options provided by
setup.py for those purposes (adding them to setup.py calls
which were previously lacking them).

* Since the installation locations are now on the standard
python path, we no longer need to add anything to the path
in any of our python utilities. Therefore remove all that
code from every python script. (Many of these scripts
unconditionally added /usr/lib/python and /usr/lib64/python which
is wrong even in the old world.)

* There is no longer any special `Xen python path'. xen-python-path
is no longer needed. It is no longer called by anything in our
tree. However since out-of-tree callers may still invoke it, we
retain it. It now prints a fixed string referring to a directory
which does not to exist; callers (who use it to augment their
python path) will thus add a nonexistent directory to their python
path which is harmless.

* Remove various workarounds including use of setup.py --home
(which is intended for something completely different).

* Remove tests for the XEN_PYTHON_NATIVE_INSTALL build-time
environment variable. The new behaviour is the behaviour which we
should have had if this variable had been set. That is, it is now
as if this variable was always set but also bugs in the resulting
install have been fixed.

This should be a proper fix for the bug addressed by c/s 19515.

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Apr 08 19:13:04 2009 +0100 (2009-04-08)
parents 71b0f00f6344
children
rev   line source
kaf24@8813 1 #!/usr/bin/env python2.4
kaf24@8813 2 # -*- mode: python; -*-
kaf24@8813 3 #============================================================================
kaf24@8813 4 # Copyright (C) 2005, 2006 Mike Wray <mike.wray@hp.com>
kaf24@8813 5 #
kaf24@8813 6 # This library is free software; you can redistribute it and/or modify
kaf24@8813 7 # it under the terms of the GNU Lesser General Public License as published by
kaf24@8813 8 # the Free Software Foundation; either version 2.1 of the License, or
kaf24@8813 9 # (at your option) any later version.
kaf24@8813 10 #
kaf24@8813 11 # This library is distributed in the hope that it will be useful,
kaf24@8813 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
kaf24@8813 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
kaf24@8813 14 # GNU Lesser General Public License for more details.
kaf24@8813 15 #
kaf24@8813 16 # You should have received a copy of the GNU Lesser General Public License
kaf24@8813 17 # along with this library; if not, write to the Free Software
kaf24@8813 18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
kaf24@8813 19 #============================================================================
kaf24@8813 20
kaf24@8813 21 # Vnet (network virtualization) control utility.
kaf24@8813 22
kaf24@8813 23 import os
kaf24@8813 24 import os.path
kaf24@8813 25 import re
kaf24@8813 26 import socket
kaf24@8813 27 import sys
kaf24@8813 28 from getopt import getopt, GetoptError
kaf24@8813 29
kaf24@8813 30 from xen.xend import sxp
kaf24@8813 31 from xen.xend.PrettyPrint import prettyprint
kaf24@8813 32
kaf24@8813 33 # Path of unix-domain socket to vnetd.
kaf24@8813 34 VNETD_PATH = "/tmp/vnetd"
kaf24@8813 35
kaf24@8813 36 def vnetd_running():
kaf24@8813 37 return os.path.exists(VNETD_PATH)
kaf24@8813 38
kaf24@8813 39 def vnetd_open():
kaf24@8813 40 sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
kaf24@8813 41 sock.connect(VNETD_PATH)
kaf24@8813 42 fi = sock.makefile('r', 0)
kaf24@8813 43 fo = sock.makefile('w', 0)
kaf24@8813 44 return (fi, fo)
kaf24@8813 45
kaf24@8813 46 os.defpath += ':/sbin:/usr/sbin:/usr/local/sbin'
kaf24@8813 47 CMD_IFCONFIG = 'ifconfig'
kaf24@8813 48 CMD_BRCTL = 'brctl'
kaf24@8813 49
kaf24@8813 50 opts = None
kaf24@8813 51
kaf24@8813 52 class Opts:
kaf24@8813 53
kaf24@8813 54 def __init__(self, **kwds):
kaf24@8813 55 for (k, v) in kwds.items():
kaf24@8813 56 setattr(self, k, v)
kaf24@8813 57
kaf24@8813 58 opts = Opts(verbose=False, dryrun=False)
kaf24@8813 59
kaf24@8813 60 def set_opts(val):
kaf24@8813 61 global opts
kaf24@8813 62 opts = val
kaf24@8813 63 return opts
kaf24@8813 64
kaf24@8813 65 def cmd(prog, *args):
kaf24@8813 66 """Execute command 'prog' with 'args', optionally printing the command.
kaf24@8813 67 """
kaf24@8813 68 global opts
kaf24@8813 69 command = " ".join([ prog ] + map(str, args))
kaf24@8813 70 if opts.verbose:
kaf24@8813 71 print command
kaf24@8813 72 if not opts.dryrun:
kaf24@8813 73 os.system(command)
kaf24@8813 74
kaf24@8813 75 def vif_bridge_add(bridge, vif):
kaf24@8813 76 """Add a network interface to a bridge.
kaf24@8813 77 """
kaf24@8813 78 cmd(CMD_BRCTL, 'addif', bridge, vif)
kaf24@8813 79
kaf24@8813 80 def vif_bridge_rem(bridge, vif):
kaf24@8813 81 """Remove a network interface from a bridge.
kaf24@8813 82 """
kaf24@8813 83 cmd(CMD_BRCTL, 'delif', bridge, vif)
kaf24@8813 84
kaf24@8813 85 def bridge_create(bridge, **kwd):
kaf24@8813 86 """Create a bridge.
kaf24@8813 87 Defaults hello time to 0, forward delay to 0 and stp off.
kaf24@8813 88 """
kaf24@8813 89 cmd(CMD_BRCTL, 'addbr', bridge)
kaf24@8813 90 if kwd.get('hello', None) is None:
kaf24@8813 91 kwd['hello'] = 0
kaf24@8813 92 if kwd.get('fd', None) is None:
kaf24@8813 93 kwd['fd'] = 0
kaf24@8813 94 if kwd.get('stp', None) is None:
kaf24@8813 95 kwd['stp'] = 'off'
kaf24@8813 96 bridge_set(bridge, **kwd)
kaf24@8813 97 cmd(CMD_IFCONFIG, bridge, "up")
kaf24@8813 98
kaf24@8813 99 def bridge_set(bridge, hello=None, fd=None, stp=None):
kaf24@8813 100 """Set bridge parameters.
kaf24@8813 101 """
kaf24@8813 102 if hello is not None:
kaf24@8813 103 cmd(CMD_BRCTL, 'sethello', bridge, hello)
kaf24@8813 104 if fd is not None:
kaf24@8813 105 cmd(CMD_BRCTL, 'setfd', bridge, fd)
kaf24@8813 106 if stp is not None:
kaf24@8813 107 cmd(CMD_BRCTL, 'stp', bridge, stp)
kaf24@8813 108
kaf24@8813 109 def bridge_del(bridge):
kaf24@8813 110 """Delete a bridge.
kaf24@8813 111 """
kaf24@8813 112 cmd(CMD_IFCONFIG, bridge, 'down')
kaf24@8813 113 cmd(CMD_BRCTL, 'delbr', bridge)
kaf24@8813 114
kaf24@8813 115 class Bridge:
kaf24@8813 116 # Network interfaces are at /sys/class/net/*.
kaf24@8813 117 # A bridge interface has ./bridge dir, ./brif is dir of bridged interfaces
kaf24@8813 118 # (symlinks to the brport dirs).
kaf24@8813 119 # If an interface is bridged ./brport is bridged port info,
kaf24@8813 120 # brport/bridge is a symlink to the bridge.
kaf24@8813 121
kaf24@8813 122 INTERFACE_DIR = "/sys/class/net"
kaf24@8813 123
kaf24@8813 124 def isBridge(klass, dev):
kaf24@8813 125 """Test if a network interface is a bridge.
kaf24@8813 126 """
kaf24@8813 127 devdir = os.path.join(klass.INTERFACE_DIR, dev)
kaf24@8813 128 brdir = os.path.join(devdir, "bridge")
kaf24@8813 129 try:
kaf24@8813 130 os.stat(brdir)
kaf24@8813 131 return True
kaf24@8813 132 except:
kaf24@8813 133 return False
kaf24@8813 134
kaf24@8813 135 isBridge = classmethod(isBridge)
kaf24@8813 136
kaf24@8813 137 def getInterfaces(klass):
kaf24@8813 138 """Get a list of the network interfaces.
kaf24@8813 139 """
kaf24@8813 140 try:
kaf24@8813 141 v = os.listdir(klass.INTERFACE_DIR)
kaf24@8813 142 v.sort()
kaf24@8813 143 return v
kaf24@8813 144 except:
kaf24@8813 145 return []
kaf24@8813 146
kaf24@8813 147 getInterfaces = classmethod(getInterfaces)
kaf24@8813 148
kaf24@8813 149 def getInterfaceAddr(klass, intf):
kaf24@8813 150 intfdir = os.path.join(klass.INTERFACE_DIR, intf)
kaf24@8813 151 addrfile = os.path.join(intfdir, "address")
kaf24@8813 152 try:
kaf24@8813 153 f = file(addrfile, "rb")
kaf24@8813 154 except Exception, ex:
kaf24@8813 155 #print ex
kaf24@8813 156 return None
kaf24@8813 157 try:
kaf24@8813 158 return f.readline().strip()
kaf24@8813 159 finally:
kaf24@8813 160 f.close()
kaf24@8813 161
kaf24@8813 162 getInterfaceAddr = classmethod(getInterfaceAddr)
kaf24@8813 163
kaf24@8813 164 def getBridges(klass):
kaf24@8813 165 """Get a list of the bridges.
kaf24@8813 166 """
kaf24@8813 167 return [ dev for dev in klass.getInterfaces() if klass.isBridge(dev) ]
kaf24@8813 168
kaf24@8813 169 getBridges = classmethod(getBridges)
kaf24@8813 170
kaf24@8813 171 def getBridgeInterfaces(klass, dev):
kaf24@8813 172 """Get a list of the interfaces attached to a bridge.
kaf24@8813 173 """
kaf24@8813 174 devdir = os.path.join(klass.INTERFACE_DIR, dev)
kaf24@8813 175 intfdir = os.path.join(devdir, "brif")
kaf24@8813 176 try:
kaf24@8813 177 v = os.listdir(intfdir)
kaf24@8813 178 v.sort()
kaf24@8813 179 return v
kaf24@8813 180 except:
kaf24@8813 181 return []
kaf24@8813 182
kaf24@8813 183 getBridgeInterfaces = classmethod(getBridgeInterfaces)
kaf24@8813 184
kaf24@8813 185 def getBridge(klass, dev):
kaf24@8813 186 """Get the bridge an interface is attached to (if any).
kaf24@8813 187 """
kaf24@8813 188 devdir = os.path.join(klass.INTERFACE_DIR, dev)
kaf24@8813 189 brfile = os.path.join(devdir, "brport/bridge")
kaf24@8813 190 try:
kaf24@8813 191 brpath = os.readlink(brfile)
kaf24@8813 192 return os.path.basename(brpath)
kaf24@8813 193 except:
kaf24@8813 194 return None
kaf24@8813 195
kaf24@8813 196 getBridge = classmethod(getBridge)
kaf24@8813 197
kaf24@8813 198 def vnet_cmd(expr):
kaf24@8813 199 """Send a command expression to the vnet implementation.
kaf24@8813 200 """
kaf24@8813 201 if vnetd_running():
kaf24@8813 202 (fi, fo) = vnetd_open()
kaf24@8813 203 else:
kaf24@8813 204 fi = None
kaf24@8813 205 fo = file("/proc/vnet/policy", "wb")
kaf24@8813 206 try:
kaf24@8813 207 sxp.show(expr, fo)
kaf24@8813 208 fo.flush()
kaf24@8813 209 finally:
kaf24@8813 210 if fi: fi.close()
kaf24@8813 211 if fo: fo.close()
kaf24@8813 212
kaf24@8813 213 def varp_flush():
kaf24@8813 214 """Flush the varp cache.
kaf24@8813 215 """
kaf24@8813 216 expr = ['varp.flush']
kaf24@8813 217 return vnet_cmd(expr)
kaf24@8813 218
kaf24@8813 219 def vif_add(vnetid, vmac):
kaf24@8813 220 """Tell the vnet implementation to add a vif to a vnet.
kaf24@8813 221 """
kaf24@8813 222 expr = ['vif.add', ['vnet', vnetid], ['vmac', vmac]]
kaf24@8813 223 return vnet_cmd(expr)
kaf24@8813 224
kaf24@8813 225 def vif_del(vnetid, vmac):
kaf24@8813 226 """Tell the vnet implementation to delete a vif from a vnet.
kaf24@8813 227 """
kaf24@8813 228 expr = ['vif.del', ['vnet', vnetid], ['vmac', vmac]]
kaf24@8813 229 return vnet_cmd(expr)
kaf24@8813 230
kaf24@8813 231 def vnet_add(vnetid, vnetif=None, security=None):
kaf24@8813 232 """Tell the vnet implementation to add a vnet.
kaf24@8813 233 """
kaf24@8813 234 expr = ['vnet.add', ['id', vnetid]]
kaf24@8813 235 if vnetif:
kaf24@8813 236 expr.append(['vnetif', vnetif])
kaf24@8813 237 if security:
kaf24@8813 238 expr.append(['security', security])
kaf24@8813 239 return vnet_cmd(expr)
kaf24@8813 240
kaf24@8813 241 def peer_add(addr, port=None):
kaf24@8813 242 expr = ['peer.add', ['addr', addr]]
kaf24@8813 243 if port:
kaf24@8813 244 expr.append(['port', port])
kaf24@8813 245 return vnet_cmd(expr)
kaf24@8813 246
kaf24@8813 247 def peer_del(addr, port=None):
kaf24@8813 248 expr = ['peer.del', ['addr', addr]]
kaf24@8813 249 return vnet_cmd(expr)
kaf24@8813 250
kaf24@8813 251 def vnet_del(vnetid):
kaf24@8813 252 """Tell the vnet implementation to delete a vnet.
kaf24@8813 253 """
kaf24@8813 254 expr = ['vnet.del', ['id', vnetid]]
kaf24@8813 255 return vnet_cmd(expr)
kaf24@8813 256
kaf24@8813 257 def vnet_create(vnetid, vnetif=None, bridge=None, security=None):
kaf24@8813 258 """Tell the vnet implementation to add a vnet.
kaf24@8813 259 If 'bridge' is non-null, create the bridge and add the vnet interface
kaf24@8813 260 to it.
kaf24@8813 261 """
kaf24@8813 262 vnet_add(vnetid, vnetif=vnetif, security=security)
kaf24@8813 263 val = vnet_lookup(vnetid)
kaf24@8813 264 if not vnetif:
kaf24@8813 265 vnetif = sxp.child_value(val, "vnetif")
kaf24@8813 266 vmac = get_mac(vnetif)
kaf24@8813 267 emac = get_mac("eth0") or get_mac("eth1") or get_mac("eth2")
kaf24@8813 268 if emac and vmac != emac:
kaf24@8813 269 set_mac(vnetif, emac)
kaf24@8813 270 cmd(CMD_IFCONFIG, vnetif, 'up')
kaf24@8813 271 if bridge:
kaf24@8813 272 bridge_create(bridge)
kaf24@8813 273 vif_bridge_add(bridge, vnetif)
kaf24@8813 274 return val
kaf24@8813 275
kaf24@8813 276 def vnet_delete(vnet, delbridge=False):
kaf24@8813 277 """Tell the vnet implementation to delete a vnet.
kaf24@8813 278 If the vnet interface is attached to a bridge,
kaf24@8813 279 remove it from the bridge, and if delbridge is true
kaf24@8813 280 delete the bridge.
kaf24@8813 281 """
kaf24@8813 282 v = vnet_lookup(vnet)
kaf24@8813 283 if not v:
kaf24@8813 284 raise GetoptError("vnet not found: %s" % vnet)
kaf24@8813 285 vnetid = sxp.child_value(v, "id")
kaf24@8813 286 vnetif = sxp.child_value(v, "vnetif")
kaf24@8813 287 bridge = Bridge.getBridge(vnetif)
kaf24@8813 288 if bridge:
kaf24@8813 289 vif_bridge_rem(bridge, vnetif)
kaf24@8813 290 if delbridge:
kaf24@8813 291 bridge_del(bridge)
kaf24@8813 292 return vnet_del(vnetid)
kaf24@8813 293
kaf24@8813 294 def get_mac(intf):
kaf24@8813 295 """Get the mac address of an interface.
kaf24@8813 296 """
kaf24@8813 297 try:
kaf24@8813 298 return Bridge.getInterfaceAddr(intf)
kaf24@8813 299 except:
kaf24@8813 300 pass
kaf24@8813 301
kaf24@8813 302 hwre = re.compile(".*\s+HWaddr\s+(?P<mac>\S*)\s+.*")
kaf24@8813 303 fin = os.popen("%s %s" % (CMD_IFCONFIG, intf), 'r')
kaf24@8813 304 try:
kaf24@8813 305 for x in fin:
kaf24@8813 306 m = hwre.match(x)
kaf24@8813 307 if not m:
kaf24@8813 308 continue
kaf24@8813 309 info = m.groupdict()
kaf24@8813 310 return info['mac']
kaf24@8813 311 return None
kaf24@8813 312 finally:
kaf24@8813 313 fin.close()
kaf24@8813 314
kaf24@8813 315 def set_mac(intf, mac):
kaf24@8813 316 cmd(CMD_IFCONFIG, intf, 'down')
kaf24@8813 317 cmd(CMD_IFCONFIG, intf, 'hw', 'ether', mac)
kaf24@8813 318 cmd(CMD_IFCONFIG, intf, 'up')
kaf24@8813 319
kaf24@8813 320 def get_addr(host):
kaf24@8813 321 return socket.gethostbyname(host)
kaf24@8813 322
kaf24@8813 323 def get_port(srv):
kaf24@8813 324 return srv
kaf24@8813 325
kaf24@8813 326 def vnetidof(v):
kaf24@8813 327 """Normalise a vnet id. Adds leading 0 fields to make up 8 if
kaf24@8813 328 there aren't enough. Pads all fields to 4 hex digits.
kaf24@8813 329 """
kaf24@8813 330 try:
kaf24@8813 331 l = v.split(":")
kaf24@8813 332 l = [ int(x or 0, 16) for x in l ]
kaf24@8813 333 l = [ 0 ] * (8 - len(l)) + l
kaf24@8813 334 return ":".join([ "%04x" % x for x in l ])
kaf24@8813 335 except:
kaf24@8813 336 return None
kaf24@8813 337
kaf24@8813 338 def vnet_lookup(vnet, vnets=None):
kaf24@8813 339 """Find the vnet with the given vnet id or vnet interface.
kaf24@8813 340
kaf24@8813 341 @param vnet id or interface
kaf24@8813 342 @param vnets list of vnet info to use (get from implementation if None)
kaf24@8813 343 @return vnet info or None if not found
kaf24@8813 344 """
kaf24@8813 345 vnetid = vnetidof(vnet)
kaf24@8813 346 if vnets is None:
kaf24@8813 347 vnets = vnet_list()
kaf24@8813 348 for v in vnets:
kaf24@8813 349 vid = sxp.child_value(v, "id")
kaf24@8813 350 if vid == vnet or vid == vnetid:
kaf24@8813 351 return v
kaf24@8813 352 if sxp.child_value(v, "vnetif") == vnet:
kaf24@8813 353 return v
kaf24@8813 354 return None
kaf24@8813 355
kaf24@8813 356 def get_vnetid(vnet):
kaf24@8813 357 """Get the normalised vnet id of the given vnet id or vnet interface.
kaf24@8813 358 Raises an error if the vnet cannot be found.
kaf24@8813 359 """
kaf24@8813 360 v = vnet_lookup(vnet)
kaf24@8813 361 if not v:
kaf24@8813 362 raise GetoptError("vnet not found: %s" % vnet)
kaf24@8813 363 vnetid = sxp.child_value(v, "id")
kaf24@8813 364 return vnetid
kaf24@8813 365
kaf24@8813 366 def vif_list():
kaf24@8813 367 """Get the list of vif info from the vnet implementation.
kaf24@8813 368 """
kaf24@8813 369 if vnetd_running():
kaf24@8813 370 (fi, fo) = vnetd_open()
kaf24@8813 371 sxp.show(['vif.list'], fo)
kaf24@8813 372 fo.flush()
kaf24@8813 373 else:
kaf24@8813 374 fi = file("/proc/vnet/vifs")
kaf24@8813 375 fo = None
kaf24@8813 376 try:
kaf24@8813 377 return sxp.parse(fi) or []
kaf24@8813 378 finally:
kaf24@8813 379 if fi: fi.close()
kaf24@8813 380 if fo: fo.close()
kaf24@8813 381
kaf24@8813 382 def vnets_filter(vnetlist, vnets):
kaf24@8813 383 """Filter a list of vnet info by a list of vnet ids or interfaces.
kaf24@8813 384 """
kaf24@8813 385 if vnets is None:
kaf24@8813 386 val = vnetlist
kaf24@8813 387 else:
kaf24@8813 388 val = []
kaf24@8813 389 for x in vnets:
kaf24@8813 390 v = vnet_lookup(x, vnets=vnetlist)
kaf24@8813 391 if not v:
kaf24@8813 392 continue
kaf24@8813 393 val.append(v)
kaf24@8813 394 return val
kaf24@8813 395
kaf24@8813 396 def vnet_list(vnets=None):
kaf24@8813 397 """Get the list of vnet info from the vnet implementation,
kaf24@8813 398 sorted by vnet id.
kaf24@8813 399
kaf24@8813 400 @param vnets list of vnet ids or interfaces to filter the results by
kaf24@8813 401 """
kaf24@8813 402 if vnetd_running():
kaf24@8813 403 (fi, fo) = vnetd_open()
kaf24@8813 404 sxp.show(['vnet.list'], fo)
kaf24@8813 405 fo.flush()
kaf24@8813 406 else:
kaf24@8813 407 fi = file("/proc/vnet/vnets")
kaf24@8813 408 fo = None
kaf24@8813 409 try:
kaf24@8813 410 val = vnets_filter(sxp.parse(fi) or [], vnets)
kaf24@8813 411 val.sort(lambda x, y:
kaf24@8813 412 cmp(sxp.child_value(x, "id"),
kaf24@8813 413 sxp.child_value(y, "id")))
kaf24@8813 414 return val
kaf24@8813 415 finally:
kaf24@8813 416 if fi: fi.close()
kaf24@8813 417 if fo: fo.close()
kaf24@8813 418
kaf24@8813 419 def vnif_list(vnets=None):
kaf24@8813 420 """Get the list of vnet interface names from the vnet implementation.
kaf24@8813 421
kaf24@8813 422 @param vnets list of vnet ids or interfaces to filter the results by
kaf24@8813 423 """
kaf24@8813 424 vnifs = []
kaf24@8813 425 for v in vnet_list(vnets=vnets):
kaf24@8813 426 vnetif = sxp.child_value(v, "vnetif")
kaf24@8813 427 if vnetif:
kaf24@8813 428 vnifs.append(vnetif)
kaf24@8813 429 return vnifs
kaf24@8813 430
kaf24@8813 431 def varp_list():
kaf24@8813 432 """Get the list of varp info from the vnet implementation.
kaf24@8813 433 """
kaf24@8813 434 if vnetd_running():
kaf24@8813 435 (fi, fo) = vnetd_open()
kaf24@8813 436 sxp.show(['varp.list'], fo)
kaf24@8813 437 fo.flush()
kaf24@8813 438 else:
kaf24@8813 439 fi = file("/proc/vnet/varp")
kaf24@8813 440 fo = None
kaf24@8813 441 try:
kaf24@8813 442 return sxp.parse(fi) or []
kaf24@8813 443 finally:
kaf24@8813 444 if fi: fi.close()
kaf24@8813 445 if fo: fo.close()
kaf24@8813 446
kaf24@8813 447 def peer_list():
kaf24@8813 448 if vnetd_running():
kaf24@8813 449 (fi, fo) = vnetd_open()
kaf24@8813 450 sxp.show(['peer.list'], fo)
kaf24@8813 451 fo.flush()
kaf24@8813 452 else:
kaf24@8813 453 fi = file("/proc/vnet/peers")
kaf24@8813 454 fo = None
kaf24@8813 455 try:
kaf24@8813 456 return sxp.parse(fi) or []
kaf24@8813 457 finally:
kaf24@8813 458 if fi: fi.close()
kaf24@8813 459 if fo: fo.close()
kaf24@8813 460
kaf24@8813 461 class Opt:
kaf24@8813 462 """Declares command-line options for a command.
kaf24@8813 463 """
kaf24@8813 464
kaf24@8813 465 def getopt(klass, argv, opts, args):
kaf24@8813 466 """Get options and args from argv.
kaf24@8813 467 The value opts in the return value has an attribute for
kaf24@8813 468 eacho option or arg. The value args in the return value
kaf24@8813 469 is the remaining arguments.
kaf24@8813 470
kaf24@8813 471 @param argv arguments
kaf24@8813 472 @param opts option specifiers (list of Opt objects)
kaf24@8813 473 @param args arg specififiers (list of Arg objects)
kaf24@8813 474 @return (opts, args)
kaf24@8813 475 """
kaf24@8813 476 shortopts = "".join([ x.optShort() for x in opts ])
kaf24@8813 477 longopts = [ x.optLong() for x in opts ]
kaf24@8813 478 (ovals, oargs) = getopt(argv[1:], shortopts, longopts)
kaf24@8813 479 odir = Opts()
kaf24@8813 480 for x in opts:
kaf24@8813 481 x.setDefault(odir)
kaf24@8813 482 for (k, v) in ovals:
kaf24@8813 483 for x in opts:
kaf24@8813 484 x.setOpt(k, v, odir)
kaf24@8813 485 argc = len(oargs)
kaf24@8813 486 if len(oargs) < len(args):
kaf24@8813 487 raise GetoptError("insufficient arguments for %s" % argv[0])
kaf24@8813 488 for (x, v) in zip(args, oargs):
kaf24@8813 489 x.setArg(v, odir)
kaf24@8813 490 return (odir, oargs[len(args): ])
kaf24@8813 491
kaf24@8813 492 getopt = classmethod(getopt)
kaf24@8813 493
kaf24@8813 494 def gethelp(klass, opts, args):
kaf24@8813 495 l = []
kaf24@8813 496 for x in opts:
kaf24@8813 497 l.append(x.help())
kaf24@8813 498 for x in args:
kaf24@8813 499 l.append(x.help())
kaf24@8813 500 return " ".join(l)
kaf24@8813 501
kaf24@8813 502 gethelp = classmethod(gethelp)
kaf24@8813 503
kaf24@8813 504 """A command=-line option.
kaf24@8813 505
kaf24@8813 506 @param name option name (this attribute is set to value in opts)
kaf24@8813 507 @param short short option flag (single-character string)
kaf24@8813 508 @param long long option name (defaults to option name, pass "" to suppress)
kaf24@8813 509 @param arg argument name (option has no arg if not specified)
kaf24@8813 510 """
kaf24@8813 511 def __init__(self, name, short=None, long=None, arg=False):
kaf24@8813 512 self.name = name
kaf24@8813 513 self.short = short
kaf24@8813 514 if long is None:
kaf24@8813 515 long = name
kaf24@8813 516 elif not long:
kaf24@8813 517 long = None
kaf24@8813 518 self.long = long
kaf24@8813 519 self.arg = arg
kaf24@8813 520
kaf24@8813 521 def help(self):
kaf24@8813 522 s = self.keyShort()
kaf24@8813 523 l = self.keyLong()
kaf24@8813 524 if s and l:
kaf24@8813 525 return "[%s | %s]" % (s, l)
kaf24@8813 526 else:
kaf24@8813 527 return s or l
kaf24@8813 528
kaf24@8813 529 def keyShort(self):
kaf24@8813 530 if self.short:
kaf24@8813 531 return "-%s" % self.short
kaf24@8813 532 else:
kaf24@8813 533 return None
kaf24@8813 534
kaf24@8813 535 def keyLong(self):
kaf24@8813 536 if self.long:
kaf24@8813 537 return "--%s" % self.long
kaf24@8813 538 else:
kaf24@8813 539 return None
kaf24@8813 540
kaf24@8813 541 def optLong(self):
kaf24@8813 542 if not self.long:
kaf24@8813 543 return None
kaf24@8813 544 if self.arg:
kaf24@8813 545 return "%s=" % self.long
kaf24@8813 546 else:
kaf24@8813 547 return self.long
kaf24@8813 548
kaf24@8813 549 def optShort(self):
kaf24@8813 550 if not self.short:
kaf24@8813 551 return None
kaf24@8813 552 if self.arg:
kaf24@8813 553 return "%s:" % self.short
kaf24@8813 554 else:
kaf24@8813 555 return self.short
kaf24@8813 556
kaf24@8813 557 def setDefault(self, vals):
kaf24@8813 558 if self.arg:
kaf24@8813 559 setattr(vals, self.name, None)
kaf24@8813 560 else:
kaf24@8813 561 setattr(vals, self.name, False)
kaf24@8813 562
kaf24@8813 563 def setOpt(self, k, v, vals):
kaf24@8813 564 if k in [ self.keyShort(), self.keyLong() ]:
kaf24@8813 565 if self.arg:
kaf24@8813 566 setattr(vals, self.name, v)
kaf24@8813 567 else:
kaf24@8813 568 if v not in [ None, '' ]:
kaf24@8813 569 raise GetoptError("option %s does not take an argument" % k)
kaf24@8813 570 setattr(vals, self.name, True)
kaf24@8813 571
kaf24@8813 572 class Arg:
kaf24@8813 573
kaf24@8813 574 """A command-line parameter. Args get their values from arguments
kaf24@8813 575 left over after option processing and are assigned in order.
kaf24@8813 576 The value is accessible as the attribute called 'name' in opts.
kaf24@8813 577
kaf24@8813 578 @param name argument name
kaf24@8813 579 """
kaf24@8813 580 def __init__(self, name):
kaf24@8813 581 self.name = name
kaf24@8813 582
kaf24@8813 583 def setArg(self, v, vals):
kaf24@8813 584 setattr(vals, self.name, v)
kaf24@8813 585
kaf24@8813 586 def help(self):
kaf24@8813 587 return "<%s>" % self.name
kaf24@8813 588
kaf24@8813 589 class VnMain:
kaf24@8813 590
kaf24@8813 591 """Methods beginning with this prefix are commands.
kaf24@8813 592 They must all have arguments like this:
kaf24@8813 593
kaf24@8813 594 op_foo(self, argv, args, opts)
kaf24@8813 595
kaf24@8813 596 argv: original command-line arguments
kaf24@8813 597 args: arguments left after option processing
kaf24@8813 598 opts: option and arg values (accessible as attributes)
kaf24@8813 599
kaf24@8813 600 Method options are specified by setting attribute
kaf24@8813 601 .opts on the method to a list of Option objects.
kaf24@8813 602 For args set .args to a list of Arg objects.
kaf24@8813 603 Use .use for short usage string, .help for long help.
kaf24@8813 604
kaf24@8813 605 Each option or arg defines an attribute in opts. For example
kaf24@8813 606 an option with name 'foo' is accessible as 'opts.foo'.
kaf24@8813 607 """
kaf24@8813 608 opPrefix = "op_"
kaf24@8813 609
kaf24@8813 610 def __init__(self, argv):
kaf24@8813 611 if argv:
kaf24@8813 612 self.name = argv[0]
kaf24@8813 613 else:
kaf24@8813 614 self.name = "vn"
kaf24@8813 615 self.argv = argv
kaf24@8813 616 self.argc = len(argv)
kaf24@8813 617
kaf24@8813 618 def error(self, v):
kaf24@8813 619 print >>sys.stderr, "%s: %s" % (self.name, v)
kaf24@8813 620 sys.exit(1)
kaf24@8813 621
kaf24@8813 622 def getFunction(self, opname):
kaf24@8813 623 key = self.opPrefix + opname.replace("-", "_")
kaf24@8813 624 fn = getattr(self, key, None)
kaf24@8813 625 if not fn:
kaf24@8813 626 raise ValueError("unknown command: %s" % opname)
kaf24@8813 627 return fn
kaf24@8813 628
kaf24@8813 629 def main(self):
kaf24@8813 630 if self.argc < 2:
kaf24@8813 631 args = ["help"]
kaf24@8813 632 else:
kaf24@8813 633 args = self.argv[1:]
kaf24@8813 634 try:
kaf24@8813 635 fn = self.getFunction(args[0])
kaf24@8813 636 except ValueError, ex:
kaf24@8813 637 self.error(ex)
kaf24@8813 638 try:
kaf24@8813 639 fnopts = self.getOpts(fn)
kaf24@8813 640 fnargs = self.getArgs(fn)
kaf24@8813 641 (opts, parms) = Opt.getopt(args, fnopts, fnargs)
kaf24@8813 642 return fn(args, parms, opts)
kaf24@8813 643 except GetoptError, ex:
kaf24@8813 644 self.error(ex)
kaf24@8813 645 except ValueError, ex:
kaf24@8813 646 self.error(ex)
kaf24@8813 647 except Exception, ex:
kaf24@8813 648 import traceback; traceback.print_exc()
kaf24@8813 649 self.error(ex)
kaf24@8813 650
kaf24@8813 651 def getOpts(self, meth):
kaf24@8813 652 return getattr(meth, "opts", [])
kaf24@8813 653
kaf24@8813 654 def getArgs(self, meth):
kaf24@8813 655 return getattr(meth, "args", [])
kaf24@8813 656
kaf24@8813 657 def getUse(self, meth):
kaf24@8813 658 return getattr(meth, "use", "")
kaf24@8813 659
kaf24@8813 660 def getHelp(self, meth):
kaf24@8813 661 return getattr(meth, "help", "") or self.getUse(meth)
kaf24@8813 662
kaf24@8813 663 def fnHelp(self, meth):
kaf24@8813 664 return Opt.gethelp(self.getOpts(meth), self.getArgs(meth))
kaf24@8813 665
kaf24@8813 666 def printHelp(self, fn, opt_long):
kaf24@8813 667 meth = getattr(self, fn)
kaf24@8813 668 opname = fn[len(self.opPrefix):].replace("_", "-")
kaf24@8813 669 if opt_long:
kaf24@8813 670 help = self.getHelp(meth)
kaf24@8813 671 print "\n %s" % opname
kaf24@8813 672 if help:
kaf24@8813 673 print "%s" % help
kaf24@8813 674 else:
kaf24@8813 675 use = self.getUse(meth)
kaf24@8813 676 print " %s %s" % (opname, self.fnHelp(meth))
kaf24@8813 677 if use:
kaf24@8813 678 print "\t\t%s" % use
kaf24@8813 679
kaf24@8813 680 def show_vnif(self, dev):
kaf24@8813 681 cmd(CMD_IFCONFIG, dev)
kaf24@8813 682 bridge = Bridge.getBridge(dev)
kaf24@8813 683 if bridge:
kaf24@8813 684 print " Bridge:", bridge
kaf24@8813 685 interfaces = Bridge.getBridgeInterfaces(bridge)
kaf24@8813 686 if dev in interfaces:
kaf24@8813 687 interfaces.remove(dev)
kaf24@8813 688 if interfaces:
kaf24@8813 689 print " Interfaces:", ", ".join(interfaces)
kaf24@8813 690 print
kaf24@8813 691
kaf24@8813 692 def op_help(self, argv, args, opts):
kaf24@8813 693 if opts.long:
kaf24@8813 694 print '%s <command> <options>' % self.name
kaf24@8813 695 print self.long_help
kaf24@8813 696 else:
kaf24@8813 697 print '%s:' % self.name
kaf24@8813 698 l = dir(self)
kaf24@8813 699 l.sort()
kaf24@8813 700 for fn in l:
kaf24@8813 701 if fn.startswith(self.opPrefix):
kaf24@8813 702 self.printHelp(fn, opts.long)
kaf24@8813 703 print
kaf24@8813 704
kaf24@8813 705 op_help.opts = [ Opt('long', short='l') ]
kaf24@8813 706
kaf24@8813 707 def op_vnets(self, argv, args, opts):
kaf24@8813 708 vnets = vnet_list(vnets=args or None)
kaf24@8813 709 for v in vnets:
kaf24@8813 710 prettyprint(v, width=50)
kaf24@8813 711 print
kaf24@8813 712 if not opts.long:
kaf24@8813 713 continue
kaf24@8813 714 vnif = sxp.child_value(v, "vnetif")
kaf24@8813 715 if not vnif:
kaf24@8813 716 continue
kaf24@8813 717 self.show_vnif(vnif)
kaf24@8813 718 if opts.all:
kaf24@8813 719 vnetids = {}
kaf24@8813 720 for v in vnets:
kaf24@8813 721 vnetids[sxp.child_value(v, "id")] = v
kaf24@8813 722 for v in vif_list():
kaf24@8813 723 vnet = sxp.child_value(v, "vnet")
kaf24@8813 724 if vnet not in vnetids:
kaf24@8813 725 continue
kaf24@8813 726 prettyprint(v)
kaf24@8813 727 print
kaf24@8813 728 for v in varp_list():
kaf24@8813 729 prettyprint(v)
kaf24@8813 730 print
kaf24@8813 731
kaf24@8813 732 op_vnets.opts = [ Opt('all', short='a'), Opt('long', short='l') ]
kaf24@8813 733
kaf24@8813 734 def op_vnifs(self, argv, args, opts):
kaf24@8813 735 vnifs = vnif_list(vnets=args or None)
kaf24@8813 736 for vnif in vnifs:
kaf24@8813 737 self.show_vnif(vnif)
kaf24@8813 738
kaf24@8813 739 def op_vifs(self, argv, args, opts):
kaf24@8813 740 for v in vif_list():
kaf24@8813 741 prettyprint(v)
kaf24@8813 742 print
kaf24@8813 743
kaf24@8813 744 def op_varp(self, argv, args, opts):
kaf24@8813 745 for v in varp_list():
kaf24@8813 746 prettyprint(v)
kaf24@8813 747 print
kaf24@8813 748
kaf24@8813 749 def op_varp_flush(self, argv, args, opts):
kaf24@8813 750 varp_flush()
kaf24@8813 751
kaf24@8813 752 def op_vnet_create(self, argv, args, opts):
kaf24@8813 753 return vnet_create(opts.vnet,
kaf24@8813 754 vnetif=opts.vnetif,
kaf24@8813 755 bridge=opts.bridge,
kaf24@8813 756 security=opts.security)
kaf24@8813 757
kaf24@8813 758 op_vnet_create.args = [ Arg('vnet') ]
kaf24@8813 759 op_vnet_create.opts = [ Opt('security', short='s', arg="SECURITY"),
kaf24@8813 760 Opt('bridge', short='b', arg="BRIDGE"),
kaf24@8813 761 Opt('vnetif', short='v', arg="VNETIF") ]
kaf24@8813 762
kaf24@8813 763 def op_vnet_delete(self, argv, args, opts):
kaf24@8813 764 vnetid = get_vnetid(opts.vnet)
kaf24@8813 765 return vnet_delete(vnetid, delbridge=opts.bridge)
kaf24@8813 766
kaf24@8813 767 op_vnet_delete.args = [ Arg('vnet') ]
kaf24@8813 768 op_vnet_delete.opts = [ Opt('bridge', short='b') ]
kaf24@8813 769
kaf24@8813 770 def op_vif_add(self, argv, args, opts):
kaf24@8813 771 vnetid = get_vnetid(opts.vnet)
kaf24@8813 772 if opts.interface:
kaf24@8813 773 vmac = get_mac(opts.vmac)
kaf24@8813 774 if not vmac:
kaf24@8813 775 raise ValueError("interface not found: %s" % opts.vmac)
kaf24@8813 776 else:
kaf24@8813 777 vmac = opts.vmac
kaf24@8813 778 return vif_add(vnetid, vmac)
kaf24@8813 779
kaf24@8813 780 op_vif_add.args = [ Arg('vnet'), Arg('vmac') ]
kaf24@8813 781 op_vif_add.opts = [ Opt('interface', short='i') ]
kaf24@8813 782
kaf24@8813 783 def op_vif_delete(self, argv, args, opts):
kaf24@8813 784 vnetid = get_vnetid(opts.vnet)
kaf24@8813 785 if opts.interface:
kaf24@8813 786 vmac = get_mac(opts.vmac)
kaf24@8813 787 else:
kaf24@8813 788 vmac = opts.vmac
kaf24@8813 789 return vif_del(vnetid, vmac)
kaf24@8813 790
kaf24@8813 791 op_vif_delete.args = [ Arg('vnet'), Arg('vmac') ]
kaf24@8813 792 op_vif_delete.opts = [ Opt('interface', short='i') ]
kaf24@8813 793
kaf24@8813 794 def op_peer_add(self, argv, args, opts):
kaf24@8813 795 addr = get_addr(opts.addr)
kaf24@8813 796 if(opts.port):
kaf24@8813 797 port = get_port(opts.port)
kaf24@8813 798 else:
kaf24@8813 799 port = None
kaf24@8813 800 return peer_add(addr, port)
kaf24@8813 801
kaf24@8813 802 op_peer_add.args = [ Arg('addr') ]
kaf24@8813 803 op_peer_add.opts = [ Opt('port', short='p') ]
kaf24@8813 804
kaf24@8813 805 def op_peer_delete(self, argv, args, opts):
kaf24@8813 806 addr = get_addr(opts.addr)
kaf24@8813 807 return peer_del(addr)
kaf24@8813 808
kaf24@8813 809 op_peer_delete.args = [ Arg('addr') ]
kaf24@8813 810
kaf24@8813 811 def op_peers(self, argv, args, opts):
kaf24@8813 812 for v in peer_list():
kaf24@8813 813 prettyprint(v)
kaf24@8813 814 print
kaf24@8813 815
kaf24@8813 816 def op_bridges(self, argv, args, opts):
kaf24@8813 817 if opts.long:
kaf24@8813 818 for bridge in Bridge.getBridges():
kaf24@8813 819 cmd(CMD_IFCONFIG, bridge)
kaf24@8813 820 interfaces = Bridge.getBridgeInterfaces(bridge)
kaf24@8813 821 if interfaces:
kaf24@8813 822 print " Interfaces:", ", ".join(interfaces)
kaf24@8813 823 print
kaf24@8813 824 else:
kaf24@8813 825 for bridge in Bridge.getBridges():
kaf24@8813 826 print bridge,
kaf24@8813 827 interfaces = Bridge.getBridgeInterfaces(bridge)
kaf24@8813 828 if interfaces:
kaf24@8813 829 print ":", ", ".join(interfaces)
kaf24@8813 830 else:
kaf24@8813 831 print
kaf24@8813 832
kaf24@8813 833 op_bridges.opts = [ Opt('long', short='l') ]
kaf24@8813 834
kaf24@8813 835 def op_insmod(self, argv, args, opts):
kaf24@8813 836 """Insert the vnet kernel module."""
kaf24@8813 837 cmd("/etc/xen/scripts/vnet-insert", *args)
kaf24@8813 838
kaf24@8813 839 long_help = """Control utility for vnets (virtual networking).
kaf24@8813 840 Report bugs to Mike Wray <mike.wray@hp.com>.
kaf24@8813 841 """
kaf24@8813 842
kaf24@8813 843 op_help.use = "Print help."
kaf24@8813 844 op_help.help = "Print help, long help if the option -l or --long is given."
kaf24@8813 845
kaf24@8813 846 op_vnets.use = """Print vnets."""
kaf24@8813 847 op_vnets.help = """Print vnet information, where options are:
kaf24@8813 848 -a, -all Print vnets, vifs and varp info.
kaf24@8813 849 -l, --long Print ifconfigs for vnet interfaces."""
kaf24@8813 850
kaf24@8813 851 op_vifs.use = "Print vifs."
kaf24@8813 852
kaf24@8813 853 op_vnifs.use = "Print ifconfigs for vnet network interfaces."
kaf24@8813 854
kaf24@8813 855 op_varp.use = "Print varp info and entries in the varp cache."
kaf24@8813 856
kaf24@8813 857 op_varp_flush.use = "Flush the varp cache."
kaf24@8813 858
kaf24@8813 859 op_vnet_create.use = "Create a vnet."
kaf24@8813 860
kaf24@8813 861 op_vnet_delete.use = "Delete a vnet."
kaf24@8813 862 op_vnet_delete.help = """Delete a vnet.
kaf24@8813 863 -b, --bridge Delete the bridge the vnet interface is attached to.
kaf24@8813 864 """
kaf24@8813 865
kaf24@8813 866 op_vif_add.use = "Add a vif to a vnet."
kaf24@8813 867 op_vif_add.help = """Add a vif to a vnet. Not usually needed as vifs
kaf24@8813 868 are added automatically.
kaf24@8813 869 -i, --interface The vmac is the name of an interface to get the mac from."""
kaf24@8813 870
kaf24@8813 871 op_vif_delete.use = "Delete a vif from a vnet."
kaf24@8813 872 op_vif_delete.help = """Delete a vif from a vnet. Not usually needed as vifs
kaf24@8813 873 are removed periodically.
kaf24@8813 874 -i, --interface The vmac is the name of an interface to get the mac from."""
kaf24@8813 875
kaf24@8813 876 op_peer_add.use = "Add a peer."
kaf24@8813 877 op_peer_add.help = """Add a peer: <addr> <port>
kaf24@8813 878 Vnets use multicast to discover interfaces, but networks are often configured
kaf24@8813 879 not to forward multicast. Vnets forward multicasts to peers using UDP.
kaf24@8813 880 Only add peers if multicasts are not working, check with
kaf24@8813 881
kaf24@8813 882 ping -b 224.10.0.1
kaf24@8813 883
kaf24@8813 884 Only add peers at one machine in a subnet, otherwise you may cause forwarding
kaf24@8813 885 loops.
kaf24@8813 886 """
kaf24@8813 887
kaf24@8813 888 op_peer_delete.use = "Delete a peer."
kaf24@8813 889 op_peer_delete.help= "Delete a peer: <addr>"
kaf24@8813 890
kaf24@8813 891 op_peers.use = "List peers."
kaf24@8813 892 op_peers.help = "List peers."
kaf24@8813 893
kaf24@8813 894 op_bridges.use = "Print bridges."
kaf24@8813 895
kaf24@8813 896 op_insmod.use = "Insert the vnet kernel module, optionally with parameters."
kaf24@8813 897
kaf24@8813 898 if __name__ == "__main__":
kaf24@8813 899 vn = VnMain(sys.argv)
kaf24@8813 900 vn.main()
kaf24@8813 901