source: trunk/packages/xen-3.1/xen-3.1/tools/vnet/scripts/vn @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

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