WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-tools

Re: [Xen-tools] [PATCH] restructure xen/xm/main.py to be more straight f

To: xen-tools@xxxxxxxxxxxxxxxxxxx
Subject: Re: [Xen-tools] [PATCH] restructure xen/xm/main.py to be more straight forward
From: Mark Williamson <mark.williamson@xxxxxxxxxxxx>
Date: Tue, 9 Aug 2005 14:30:14 +0100
Cc: Ian Pratt <m+Ian.Pratt@xxxxxxxxxxxx>
Delivery-date: Tue, 09 Aug 2005 13:31:04 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <20050809001702.GA2000@xxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-tools-request@lists.xensource.com?subject=help>
List-id: Xen control tools developers <xen-tools.lists.xensource.com>
List-post: <mailto:xen-tools@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-tools>, <mailto:xen-tools-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-tools>, <mailto:xen-tools-request@lists.xensource.com?subject=unsubscribe>
References: <20050809001702.GA2000@xxxxxxxxxxxxxxxxxxx>
Sender: xen-tools-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: KMail/1.8.2
> * It implements the standardized options proposed via my RFC for xm

Yey for standardised options!

> * It consolidates all help info, making it easier to see that the help
>   screen looks consistent across commands.  (Per command help isn't yet in
>   this patch just global help)

I'd like to point out a slightly different way of doing this: Mercurial stores 
the help all in one place (it's in the file mercurial/commands.py, btw) but 
using a data structure, rather than flat text.  The help code then 
*generates* the formatted output in a uniform way.  This would also mean that 
duplication isn't necessary to do long and short help.

What do you think?  The code in Mercurial should be eminently stealable...

> * It moves object importing into the functions that require them only,
>   allowing commands like "xm help" to be runable as non root

Mercurial (yes, I like Hg :-) also has a "demand loader" for Python modules 
which uses a rather simple but cunning hack.  Perhaps this would be an 
alternative, allowing all the imports to occur in one place (if this is 
indeed desirable).  I'm less bothered about this, though.

> * It implements a short help by default (which takes < 24 screen lines) as
>   requested by Mark W at OLS

Yey!  This should make it easier to see what new users need by default.

> +    migrate <DomId> <Host>    migrate a domain to another machine

There's a few switches here that aren't mentioned.  In create's case, there's 
probably too many to fit but for migration this may not be the case.

Whilst I'm on the subject, do we have to make live migration a switch option?  
Since it's been stable for some time now, I'd have expected it to be the 
default for the "migrate" command, with stop and copy being an override...

Cheers,
Mark

> +    pause   <DomId>           pause execution of a domain
> +    reboot   [-w|-a] <DomId>  reboot a domain
> +    restore <File>            create a domain from a saved state file
> +    save    <DomId> <File>    save domain state (and config) to file
> +    shutdown [-w|-a] <DomId>  shutdown a domain
> +    sysrq   <DomId> <letter>  send a sysrq to a domain
> +    unpause <DomId>           unpause a paused domain
> +    vcpu-enable <DomId> <VCPU>        disable VCPU in a domain
> +    vcpu-disable <DomId> <VCPU>       enable VCPU in a domain
> +    vcpu-list <DomId>                 get the list of VCPUs for a domain
> +
> +  Xen Host Commands:
> +    dmesg   [--clear]         read or clear Xen's message buffer
> +    info                      get information about the xen host
> +    log                       print the xend log
> +
> +  Scheduler Commands:
> +    bvt <options>             set BVT scheduler parameters
> +    bvt_ctxallow <Allow>      set the BVT scheduler context switch
> allowance +    sedf <options>            set simple EDF parameters
> +
> +  Virtual Device Commands:
> +    block-create <DomId> <BackDev> <FrontDev> <Mode> [BackDomId]
> +        Create a new virtual block device
> +    block-destroy <DomId> <DevId>  Destroy a domain's virtual block device
> +    block-list    <DomId>          List virtual block devices for a domain
> +    block-refresh <DomId> <DevId>  Refresh a virtual block device for a
> domain +    network-limit   <DomId> <Vif> <Credit> <Period>
> +        Limit the transmission rate of a virtual network interface
> +    network-list    <DomId>        List virtual network interfaces for a
> domain +
> +For a short list of subcommands run 'xm help'
> +For more help on xm see the xm(1) man page
> +For more help on xm create, see the xmdomain.cfg(5) man page"""
> +
> +####################################################################
> +#
> +#  Utility functions
> +#
> +####################################################################
> +
> +def arg_check(args,num,name):
> +    if len(args) < num:
> +        err("'xm %s' requires %s argument(s)!\n" % (name, num))
> +        usage(name)
>
>  def unit(c):
>      if not c.isalpha():
> @@ -49,692 +134,318 @@
>      else:
>          return value * (base / dst_base)
>
> -class Group:
> -
> -    name = ""
> -    info = ""
> -
> -    def __init__(self, xm):
> -        self.xm = xm
> -        self.progs = {}
> -
> -    def addprog(self, prog):
> -        self.progs[prog.name] = prog
> -
> -    def getprog(self, name):
> -        return self.progs.get(name)
> -
> -    def proglist(self):
> -        kl = self.progs.keys()
> -        kl.sort()
> -        return [ self.getprog(k) for k in kl ]
> -
> -    def help(self, args):
> -        if self.info:
> -            print
> -            print self.info
> -            print
> +def err(msg):
> +    print >>sys.stderr, "Error:", msg
> +
> +def handle_xend_error(cmd, dom, ex):
> +    error = str(ex)
> +    if error == "Not found" and dom != None:
> +        err("Domain '%s' not found when running 'xm %s'" % (dom, cmd))
> +        sys.exit(1)
> +    else:
> +        raise ex
> +
> +
> +#########################################################################
> +#
> +#  Main xm functions
> +#
> +#########################################################################
> +
> +def xm_create(args):
> +    from xen.xm import create
> +    # ugly hack because the opt parser apparently wants
> +    # the subcommand name just to throw it away!
> +    args.insert(0,"bogus")
> +    create.main(args)
> +
> +def xm_save(args):
> +    arg_check(args,2,"save")
> +
> +    dom = args[0] # TODO: should check if this exists
> +    savefile = os.path.abspath(args[1])
> +
> +    from xen.xend.XendClient import server
> +    server.xend_domain_save(dom, savefile)
> +
> +def xm_restore(args):
> +    arg_check(args,1,"restore")
> +
> +    savefile = os.path.abspath(args[0])
> +
> +    from xen.xend.XendClient import server
> +    info = server.xend_domain_restore(savefile)
> +    PrettyPrint.prettyprint(info)
> +    id = sxp.child_value(info, 'id')
> +    if id is not None:
> +        server.xend_domain_unpause(id)
> +
> +def xm_migrate(args):
> +    # TODO: arg_check
> +    from xen.xm import migrate
> +    # ugly hack because the opt parser apparently wants
> +    # the subcommand name just to throw it away!
> +    args.insert(0,"bogus")
> +    migrate.main(args)
> +
> +def xm_list(args):
> +    use_long = 0
> +    show_vcpus = 0
> +    (options, params) = getopt(args, 'lv', ['long','vcpus'])
> +
> +    n = len(params)
> +    for (k, v) in options:
> +        if k in ['-l', '--long']:
> +            use_long = 1
> +        if k in ['-v', '--vcpus']:
> +            show_vcpus = 1
> +
> +    domsinfo = []
> +    from xen.xend.XendClient import server
> +    if n == 0:
> +        doms = server.xend_domains()
> +        doms.sort()
> +    else:
> +        doms = params
> +    for dom in doms:
> +        info = server.xend_domain(dom)
> +        domsinfo.append(parse_doms_info(info))
> +
> +    if use_long:
> +        # this actually seems like a bad idea, as it just dumps sexp out
> +        PrettyPrint.prettyprint(info)
> +    elif show_vcpus:
> +        xm_show_vcpus(domsinfo)
> +    else:
> +        xm_brief_list(domsinfo)
> +
> +def parse_doms_info(info):
> +    dominfo = {}
> +    dominfo['dom'] = int(sxp.child_value(info, 'id', '-1'))
> +    dominfo['name'] = sxp.child_value(info, 'name', '??')
> +    dominfo['mem'] = int(sxp.child_value(info, 'memory', '0'))
> +    dominfo['cpu'] = str(sxp.child_value(info, 'cpu', '0'))
> +    dominfo['vcpus'] = int(sxp.child_value(info, 'vcpus', '0'))
> +    # if there is more than 1 cpu, the value doesn't mean much
> +    if dominfo['vcpus'] > 1:
> +        dominfo['cpu'] = '-'
> +    dominfo['state'] = sxp.child_value(info, 'state', '??')
> +    dominfo['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0'))
> +    # security identifiers
> +    if ((int(sxp.child_value(info, 'ssidref', '0'))) != 0):
> +        dominfo['ssidref1'] =  int(sxp.child_value(info, 'ssidref', '0'))
> & 0xffff +        dominfo['ssidref2'] = (int(sxp.child_value(info,
> 'ssidref', '0')) >> 16) & 0xffff +    # get out the vcpu information
> +    dominfo['vcpulist'] = []
> +    vcpu_to_cpu = sxp.child_value(info, 'vcpu_to_cpu', '-1').split('|')
> +    cpumap = sxp.child_value(info, 'cpumap', [])
> +    mask = ((int(sxp.child_value(info, 'vcpus', '0')))**2) - 1
> +    count = 0
> +    for cpu in vcpu_to_cpu:
> +        vcpuinfo = {}
> +        vcpuinfo['name']   = sxp.child_value(info, 'name', '??')
> +        vcpuinfo['dom']    = int(sxp.child_value(info, 'id', '-1'))
> +        vcpuinfo['vcpu']   = int(count)
> +        vcpuinfo['cpu']    = int(cpu)
> +        vcpuinfo['cpumap'] = int(cpumap[count])&mask
> +        count = count + 1
> +        dominfo['vcpulist'].append(vcpuinfo)
> +    return dominfo
> +
> +def xm_brief_list(domsinfo):
> +    print 'Name              Id  Mem(MB)  CPU VCPU(s)  State  Time(s)'
> +    for dominfo in domsinfo:
> +        if dominfo.has_key("ssidref1"):
> +            print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d  
> %(state)5s  %(cpu_time)7.1f     %s:%(ssidref2)02x/p:%(ssidref1)02x" %
> dominfo) else:
> -            print
> -
> -    def shortHelp(self, args):
> -        self.help(args)
> -        for p in self.proglist():
> -            p.shortHelp(args)
> -
> -class Prog:
> -    """Base class for sub-programs.
> -    """
> -
> -    """Program group it belongs to"""
> -    group = 'all'
> -    """Program name."""
> -    name = '??'
> -    """Short program info."""
> -    info = ''
> -
> -    def __init__(self, xm):
> -        self.xm = xm
> -
> -    def err(self, msg):
> -        self.xm.err(msg)
> -
> -    def help(self, args):
> -        self.shortHelp(args)
> -
> -    def shortHelp(self, args):
> -        print "%-14s %s" % (self.name, self.info)
> -
> -    def main(self, args):
> -        """Program main entry point.
> -        """
> -        pass
> -
> -
> -class ProgUnknown(Prog):
> -
> -    name = 'unknown'
> -    info = ''
> -
> -    def help(self, args):
> -        self.xm.err("Unknown command: %s\nTry '%s help' for more
> information." -                    % (args[0], self.xm.name))
> -
> -    main = help
> -
> -class Xm:
> -    """Main application.
> -    """
> -
> -    def __init__(self):
> -        self.name = 'xm'
> -        self.unknown = ProgUnknown(self)
> -        self.progs = {}
> -        self.groups = {}
> -
> -    def err(self, msg):
> -        print >>sys.stderr, "Error:", msg
> -        sys.exit(1)
> -
> -    def main(self, args):
> -        try:
> -            self.main_call(args)
> -        except socket.error, ex:
> -            print >>sys.stderr, ex
> -            self.err("Error connecting to xend, is xend running?")
> -        except XendError, ex:
> -            self.err(str(ex))
> -
> -    def main_call(self, args):
> -        """Main entry point. Dispatches to the progs.
> -        """
> -        self.name = args[0]
> -        if len(args) < 2:
> -             args.append('help')
> -     help = self.helparg(args)
> -        p = self.getprog(args[1], self.unknown)
> -        if help or len(args) < 2:
> -            p.help(args[1:])
> +            print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d  
> %(state)5s  %(cpu_time)7.1f" % dominfo) +
> +def xm_show_vcpus(domsinfo):
> +    print 'Name              Id  VCPU  CPU  CPUMAP'
> +    for dominfo in domsinfo:
> +        for vcpuinfo in dominfo['vcpulist']:
> +            print ("%(name)-16s %(dom)3d  %(vcpu)4d  %(cpu)3d 
> 0x%(cpumap)x" % +                   vcpuinfo)
> +
> +def xm_vcpu_list(args):
> +    args.insert(0,"-v")
> +    xm_list(args)
> +
> +def xm_destroy(args):
> +    arg_check(args,1,"destroy")
> +
> +    from xen.xm import destroy
> +    # ugly hack because the opt parser apparently wants
> +    # the subcommand name just to throw it away!
> +    args.insert(0,"bogus")
> +    destroy.main(args)
> +
> +# TODO: make reboot do the right thing, right now
> +# reboot and shutdown are exactly the same
> +def xm_reboot(args):
> +    arg_check(args,1,"reboot")
> +    # ugly hack because the opt parser apparently wants
> +    # the subcommand name just to throw it away!
> +    args.insert(0,"bogus")
> +    from xen.xm import shutdown
> +    shutdown.main(args)
> +
> +def xm_shutdown(args):
> +    arg_check(args,1,"shutdown")
> +
> +    # ugly hack because the opt parser apparently wants
> +    # the subcommand name just to throw it away!
> +    args.insert(0,"bogus")
> +    from xen.xm import shutdown
> +    shutdown.main(args)
> +
> +def xm_sysrq(args):
> +    from xen.xm import sysrq
> +    # ugly hack because the opt parser apparently wants
> +    # the subcommand name just to throw it away!
> +    args.insert(0,"bogus")
> +    sysrq.main(args)
> +
> +def xm_pause(args):
> +    arg_check(args, 1, "pause")
> +    dom = args[0]
> +
> +    from xen.xend.XendClient import server
> +    server.xend_domain_pause(dom)
> +
> +def xm_unpause(args):
> +    arg_check(args, 1, "unpause")
> +    dom = args[0]
> +
> +    from xen.xend.XendClient import server
> +    server.xend_domain_unpause(dom)
> +
> +#############################################################
> +
> +def cpu_make_map(cpulist):
> +    cpus = []
> +    cpumap = 0
> +    for c in cpulist.split(','):
> +        if c.find('-') != -1:
> +            (x,y) = c.split('-')
> +            for i in range(int(x),int(y)+1):
> +                cpus.append(int(i))
>          else:
> -            p.main(args[1:])
> -
> -    def helparg(self, args):
> -        for a in args:
> -            if a in ['-h', '--help']:
> -                return 1
> -        return 0
> -
> -    def prog(self, pklass):
> -        """Add a sub-program.
> -
> -        pklass  program class (Prog subclass)
> -        """
> -        p = pklass(self)
> -        self.progs[p.name] = p
> -        self.getgroup(p.group).addprog(p)
> -        return p
> -
> -    def getprog(self, name, val=None):
> -        """Get a sub-program.
> -        name  Name of the sub-program (or optionally, an unambiguous
> -              prefix of its name)
> -        val   Default return value if no (unique) match is found
> -        """
> -
> -        match = None
> -        for progname in self.progs.keys():
> -            if progname == name:
> -                match = progname
> -                break
> -            if progname.startswith(name):
> -                if not match:
> -                    match = progname
> -                else:
> -                    return val # name is ambiguous - bail out
> -
> -        return self.progs.get(match, val)
> -
> -    def group(self, klass):
> -        g = klass(self)
> -        self.groups[g.name] = g
> -        return g
> -
> -    def getgroup(self, name):
> -        return self.groups[name]
> -
> -    def grouplist(self):
> -        kl = self.groups.keys()
> -        kl.sort()
> -        return [ self.getgroup(k) for k in kl ]
> -
> -# Create the application object, then add the sub-program classes.
> -xm = Xm()
> -
> -class GroupAll(Group):
> -
> -    name = "all"
> -    info = ""
> -
> -xm.group(GroupAll)
> -
> -class GroupDomain(Group):
> -
> -    name = "domain"
> -    info = "Commands on domains:"
> -
> -xm.group(GroupDomain)
> -
> -class GroupScheduler(Group):
> -
> -    name = "scheduler"
> -    info = "Comands controlling scheduling:"
> -
> -xm.group(GroupScheduler)
> -
> -class GroupHost(Group):
> -
> -    name = "host"
> -    info = "Commands related to the xen host (node):"
> -
> -xm.group(GroupHost)
> -
> -class GroupConsole(Group):
> -
> -    name = "console"
> -    info = "Commands related to consoles:"
> -
> -xm.group(GroupConsole)
> -
> -class GroupVbd(Group):
> -
> -    name = "vbd"
> -    info = "Commands related to virtual block devices:"
> -
> -xm.group(GroupVbd)
> -
> -class GroupVif(Group):
> -
> -    name = "vif"
> -    info = "Commands related to virtual network interfaces:"
> -
> -xm.group(GroupVif)
> -
> -class ProgHelp(Prog):
> -
> -    name = "help"
> -    info = "Print help."
> -
> -    def help(self, args):
> -        if len(args) == 2:
> -            name = args[1]
> -            p = self.xm.getprog(name)
> -            if p:
> -                p.help(args[1:])
> -            else:
> -                print '%s: Unknown command: %s' % (self.name, name)
> -        else:
> -            for g in self.xm.grouplist():
> -                g.shortHelp(args)
> -            print "\nTry '%s help CMD' for help on CMD" % self.xm.name
> -
> -    main = help
> -
> -xm.prog(ProgHelp)
> -
> -class ProgCreate(Prog):
> -
> -    group = 'domain'
> -    name = "create"
> -    info = """Create a domain."""
> -
> -    def help(self, args):
> -        create.main([args[0], '-h'])
> -
> -    def main(self, args):
> -        create.main(args)
> -
> -xm.prog(ProgCreate)
> -
> -class ProgSave(Prog):
> -    group = 'domain'
> -    name = "save"
> -    info = """Save domain state (and config) to file."""
> -
> -    def help(self, args):
> -        print args[0], "DOM FILE"
> -        print """\nSave domain with id DOM to FILE."""
> -
> -    def main(self, args):
> -        if len(args) < 3: self.err("%s: Missing arguments" % args[0])
> -        dom = args[1]
> -        savefile = os.path.abspath(args[2])
> -        server.xend_domain_save(dom, savefile)
> -
> -xm.prog(ProgSave)
> -
> -class ProgRestore(Prog):
> -    group = 'domain'
> -    name = "restore"
> -    info = """Create a domain from a saved state."""
> -
> -    def help(self, args):
> -        print args[0], "FILE"
> -        print "\nRestore a domain from FILE."
> -
> -    def main(self, args):
> -        if len(args) < 2: self.err("%s: Missing arguments" % args[0])
> -        savefile = os.path.abspath(args[1])
> -        info = server.xend_domain_restore(savefile)
> -        PrettyPrint.prettyprint(info)
> -        id = sxp.child_value(info, 'id')
> -        if id is not None:
> -            server.xend_domain_unpause(id)
> -
> -xm.prog(ProgRestore)
> -
> -class ProgMigrate(Prog):
> -    group = 'domain'
> -    name = "migrate"
> -    info = """Migrate a domain to another machine."""
> -
> -    def help(self, args):
> -        migrate.help([self.name] + args)
> -
> -    def main(self, args):
> -        migrate.main(args)
> -
> -xm.prog(ProgMigrate)
> -
> -class ProgList(Prog):
> -    group = 'domain'
> -    name = "list"
> -    info = """List information about domains."""
> -
> -    short_options = 'lv'
> -    long_options = ['long','vcpus']
> -
> -    def help(self, args):
> -        if help:
> -            print args[0], '[options] [DOM...]'
> -            print """\nGet information about domains.
> -            Either all domains or the domains given.
> -
> -            -l, --long   Get more detailed information.
> -            -v, --vcpus  Show VCPU to CPU mapping.
> -            """
> -            return
> -
> -    def main(self, args):
> -        use_long = 0
> -        show_vcpus = 0
> -        (options, params) = getopt(args[1:],
> -                                   self.short_options,
> -                                   self.long_options)
> -        n = len(params)
> -        for (k, v) in options:
> -            if k in ['-l', '--long']:
> -                use_long = 1
> -            if k in ['-v', '--vcpus']:
> -                show_vcpus = 1
> -
> -        if n == 0:
> -            doms = server.xend_domains()
> -            doms.sort()
> -        else:
> -            doms = params
> -
> -        if use_long:
> -            self.long_list(doms)
> -        elif show_vcpus:
> -            self.show_vcpus(doms)
> -        else:
> -            self.brief_list(doms)
> -
> -    def brief_list(self, doms):
> -        print 'Name              Id  Mem(MB)  CPU VCPU(s)  State  Time(s)'
> -        for dom in doms:
> -            info = server.xend_domain(dom)
> -            d = {}
> -            d['dom'] = int(sxp.child_value(info, 'id', '-1'))
> -            d['name'] = sxp.child_value(info, 'name', '??')
> -            d['mem'] = int(sxp.child_value(info, 'memory', '0'))
> -            d['cpu'] = str(sxp.child_value(info, 'cpu', '0'))
> -            d['vcpus'] = int(sxp.child_value(info, 'vcpus', '0'))
> -            d['state'] = sxp.child_value(info, 'state', '??')
> -            d['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0'))
> -            if d['vcpus'] > 1:
> -                d['cpu'] = '-'
> -            if ((int(sxp.child_value(info, 'ssidref', '0'))) != 0):
> -                d['ssidref1'] =  int(sxp.child_value(info, 'ssidref',
> '0')) & 0xffff -                d['ssidref2'] = (int(sxp.child_value(info,
> 'ssidref', '0')) >> 16) & 0xffff -                print ("%(name)-16s
> %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d   %(state)5s  %(cpu_time)7.1f    
> %s:%(ssidref2)02x/p:%(ssidref1)02x" % d) -            else:
> -                print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s 
> %(vcpus)5d   %(state)5s  %(cpu_time)7.1f" % d) -
> -    def show_vcpus(self, doms):
> -        print 'Name              Id  VCPU  CPU  CPUMAP'
> -        for dom in doms:
> -            info = server.xend_domain(dom)
> -            vcpu_to_cpu = sxp.child_value(info, 'vcpu_to_cpu',
> '-1').split('|') -            cpumap = sxp.child_value(info, 'cpumap', [])
> -            mask = ((int(sxp.child_value(info, 'vcpus', '0')))**2) - 1
> -            count = 0
> -            for cpu in vcpu_to_cpu:
> -                d = {}
> -                d['name']   = sxp.child_value(info, 'name', '??')
> -                d['dom']    = int(sxp.child_value(info, 'id', '-1'))
> -                d['vcpu']   = int(count)
> -                d['cpu']    = int(cpu)
> -                d['cpumap'] = int(cpumap[count])&mask
> -                count = count + 1
> -                print ("%(name)-16s %(dom)3d  %(vcpu)4d  %(cpu)3d 
> 0x%(cpumap)x" % d) -
> -    def long_list(self, doms):
> -        for dom in doms:
> -            info = server.xend_domain(dom)
> -            PrettyPrint.prettyprint(info)
> -
> -xm.prog(ProgList)
> -
> -class ProgDestroy(Prog):
> -    group = 'domain'
> -    name = "destroy"
> -    info = """Terminate a domain immediately."""
> -
> -    def help(self, args):
> -        destroy.main([args[0], '-h'])
> -
> -    def main(self, args):
> -        destroy.main(args)
> -
> -xm.prog(ProgDestroy)
> -
> -class ProgShutdown(Prog):
> -    group = 'domain'
> -    name = "shutdown"
> -    info = """Shutdown a domain."""
> -
> -    def help(self, args):
> -        shutdown.main([args[0], '-h'])
> -
> -    def main(self, args):
> -        shutdown.main(args)
> -
> -xm.prog(ProgShutdown)
> -
> -class ProgSysrq(Prog):
> -    group = 'domain'
> -    name = "sysrq"
> -    info = """Send a sysrq to a domain."""
> -
> -    def help(self, args):
> -        sysrq.main([args[0], '-h'])
> -
> -    def main(self, args):
> -        sysrq.main(args)
> -
> -xm.prog(ProgSysrq)
> -
> -class ProgPause(Prog):
> -    group = 'domain'
> -    name = "pause"
> -    info = """Pause execution of a domain."""
> -
> -    def help(self, args):
> -        print args[0], 'DOM'
> -        print '\nPause execution of domain DOM.'
> -
> -    def main(self, args):
> -        if len(args) < 2: self.err("%s: Missing domain" % args[0])
> -        dom = args[1]
> -        server.xend_domain_pause(dom)
> -
> -xm.prog(ProgPause)
> -
> -class ProgUnpause(Prog):
> -    group = 'domain'
> -    name = "unpause"
> -    info = """Unpause a paused domain."""
> -
> -    def help(self, args):
> -        print args[0], 'DOM'
> -        print '\nUnpause execution of domain DOM.'
> -
> -    def main(self, args):
> -        if len(args) < 2: self.err("%s: Missing domain" % args[0])
> -        dom = args[1]
> -        server.xend_domain_unpause(dom)
> -
> -xm.prog(ProgUnpause)
> -
> -class ProgPincpu(Prog):
> -    group = 'domain'
> -    name = "pincpu"
> -    info = """Set which cpus a VCPU can use. """
> -
> -    def help(self, args):
> -        print args[0],'DOM VCPU CPUS'
> -        print '\nSet which cpus VCPU in domain DOM can use.'
> -
> -    # convert list of cpus to bitmap integer value
> -    def make_map(self, cpulist):
> -        cpus = []
> -        cpumap = 0
> -        for c in cpulist.split(','):
> -            if c.find('-') != -1:
> -                (x,y) = c.split('-')
> -                for i in range(int(x),int(y)+1):
> -                    cpus.append(int(i))
> -            else:
> -                cpus.append(int(c))
> -        cpus.sort()
> -        for c in cpus:
> -            cpumap = cpumap | 1<<c
> -
> -        return cpumap
> -
> -    def main(self, args):
> -        if len(args) != 4: self.err("%s: Invalid argument(s)" % args[0])
> -        dom  = args[1]
> -        vcpu = int(args[2])
> -        cpumap  = self.make_map(args[3]);
> -        server.xend_domain_pincpu(dom, vcpu, cpumap)
> -
> -xm.prog(ProgPincpu)
> -
> -class ProgMaxmem(Prog):
> -    group = 'domain'
> -    name = 'maxmem'
> -    info = """Set domain memory limit."""
> -
> -    def help(self, args):
> -        print args[0], "DOM MEMORY"
> -        print "\nSet the memory limit for domain DOM to MEMORY megabytes."
> -
> -    def main(self, args):
> -        if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0])
> -        dom = args[1]
> -        mem = int_unit(args[2], 'm')
> -        server.xend_domain_maxmem_set(dom, mem)
> -
> -xm.prog(ProgMaxmem)
> -
> -class ProgSetMem(Prog):
> -    group = 'domain'
> -    name  = 'set-mem'
> -    info  = """Set the domain's memory footprint using the balloon
> driver.""" -
> -    def help(self, args):
> -        print args[0], "DOM MEMORY_TARGET"
> -        print """\nRequest domain DOM to adjust its memory footprint to
> -MEMORY_TARGET megabytes"""
> -
> -    def main(self, args):
> -        if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0])
> -        dom = args[1]
> -        mem_target = int_unit(args[2], 'm')
> -        server.xend_domain_mem_target_set(dom, mem_target)
> -
> -xm.prog(ProgSetMem)
> -
> -class ProgVcpuhotplug(Prog):
> -    group = 'domain'
> -    name  = 'vcpu-hotplug'
> -    info  = """Enable or disable a VCPU in a domain."""
> -
> -    def help(self, args):
> -        print args[0], "DOM VCPU [0|1]"
> -        print """\nRequest virtual processor VCPU to be disabled or
> enabled in -domain DOM"""
> -
> -    def main(self, args):
> -        if len(args) != 4: self.err("%s: Invalid arguments(s)" % args[0])
> -        name = args[1]
> -        vcpu = int(args[2])
> -        state = int(args[3])
> -        dom = server.xend_domain(name)
> -        id = sxp.child_value(dom, 'id')
> -        server.xend_domain_vcpu_hotplug(id, vcpu, state)
> -
> -xm.prog(ProgVcpuhotplug)
> -
> -class ProgDomid(Prog):
> -    group = 'domain'
> -    name = 'domid'
> -    info = 'Convert a domain name to a domain id.'
> -
> -    def help(self, args):
> -        print args[0], "DOM"
> -        print '\nGet the domain id for the domain with name DOM.'
> -
> -    def main (self, args):
> -        if len(args) != 2: self.err("%s: Invalid argument(s)" % args[0])
> -        name = args[1]
> -        dom = server.xend_domain(name)
> -        print sxp.child_value(dom, 'id')
> -
> -xm.prog(ProgDomid)
> -
> -class ProgDomname(Prog):
> -    group = 'domain'
> -    name = 'domname'
> -    info = 'Convert a domain id to a domain name.'
> -
> -    def help(self, args):
> -        print args[0], "DOM"
> -        print '\nGet the name for the domain with id DOM.'
> -
> -    def main (self, args):
> -        if len(args) != 2: self.err("%s: Invalid argument(s)" % args[0])
> -        name = args[1]
> -        dom = server.xend_domain(name)
> -        print sxp.child_value(dom, 'name')
> -
> -xm.prog(ProgDomname)
> -
> -class ProgBvt(Prog):
> -    group = 'scheduler'
> -    name = "bvt"
> -    info = """Set BVT scheduler parameters."""
> -
> -    def help(self, args):
> -        print args[0], "DOM MCUADV WARPBACK WARPVALUE WARPL WARPU"
> -        print '\nSet Borrowed Virtual Time scheduler parameters.'
> -
> -    def main(self, args):
> -        if len(args) != 7: self.err("%s: Invalid argument(s)" % args[0])
> -        dom = args[1]
> -        v = map(long, args[2:7])
> -        server.xend_domain_cpu_bvt_set(dom, *v)
> -
> -xm.prog(ProgBvt)
> -
> -class ProgBvtslice(Prog):
> -    group = 'scheduler'
> -    name = "bvt_ctxallow"
> -    info = """Set the BVT scheduler context switch allowance."""
> -
> -    def help(self, args):
> -        print args[0], 'CTX_ALLOW'
> -        print '\nSet Borrowed Virtual Time scheduler context switch
> allowance.' -
> -    def main(self, args):
> -        if len(args) < 2: self.err('%s: Missing context switch allowance'
> -                                                            % args[0])
> -        slice = int(args[1])
> -        server.xend_node_cpu_bvt_slice_set(slice)
> -
> -xm.prog(ProgBvtslice)
> -
> -class ProgSedf(Prog):
> -    group = 'scheduler'
> -    name= "sedf"
> -    info = """Set simple EDF parameters."""
> -
> -    def help(self, args):
> -        print args[0], "DOM PERIOD SLICE LATENCY EXTRATIME WEIGHT"
> -        print "\nSet simple EDF parameters."
> -
> -    def main(self, args):
> -     if len(args) != 7: self.err("%s: Invalid argument(s)" % args[0])
> -     dom = args[1]
> -     v = map(int, args[2:7])
> -     server.xend_domain_cpu_sedf_set(dom, *v)
> -
> -xm.prog(ProgSedf)
> -
> -class ProgInfo(Prog):
> -    group = 'host'
> -    name = "info"
> -    info = """Get information about the xen host."""
> -
> -    def main(self, args):
> -        info = server.xend_node()
> -        for x in info[1:]:
> -            print "%-23s:" % x[0], x[1]
> -
> -xm.prog(ProgInfo)
> -
> -class ProgConsole(Prog):
> -    group = 'console'
> -    name = "console"
> -    info = """Open a console to a domain."""
> -
> -    def help(self, args):
> -        print args[0], "DOM"
> -        print "\nOpen a console to domain DOM."
> -
> -    def main(self, args):
> -        if len(args) < 2: self.err("%s: Missing domain" % args[0])
> -        dom = args[1]
> -        info = server.xend_domain(dom)
> -        domid = int(sxp.child_value(info, 'id', '-1'))
> -        cmd = "/usr/libexec/xen/xenconsole %d" % domid
> -        os.execvp('/usr/libexec/xen/xenconsole', cmd.split())
> -
> -xm.prog(ProgConsole)
> -
> -class ProgCall(Prog):
> -    name = "call"
> -    info = "Call xend api functions."
> -
> -    def help (self, args):
> -        print args[0], "function args..."
> -        print """
> -        Call a xend HTTP API function. The leading 'xend_' on the function
> -can be omitted. See xen.xend.XendClient for the API functions.
> -"""
> -
> -    def main(self, args):
> -        xend_client_main(args)
> -
> -xm.prog(ProgCall)
> -
> -class ProgDmesg(Prog):
> -    group = 'host'
> -    name  =  "dmesg"
> -    info  = """Read or clear Xen's message buffer."""
> -
> +            cpus.append(int(c))
> +    cpus.sort()
> +    for c in cpus:
> +        cpumap = cpumap | 1<<c
> +
> +    return cpumap
> +
> +def xm_cpus_set(args):
> +    arg_check(args, 3, "cpus-set")
> +
> +    dom  = args[0]
> +    vcpu = int(args[1])
> +    cpumap = cpu_make_map(args[2])
> +
> +    from xen.xend.XendClient import server
> +    server.xend_domain_pincpu(dom, vcpu, cpumap)
> +
> +def xm_mem_max(args):
> +    arg_check(args, 2, "mem-max")
> +
> +    dom = args[0]
> +    mem = int_unit(args[1], 'm')
> +
> +    from xen.xend.XendClient import server
> +    server.xend_domain_maxmem_set(dom, mem)
> +
> +def xm_mem_set(args):
> +    arg_check(args, 2, "mem-set")
> +
> +    dom = args[0]
> +    mem_target = int_unit(args[1], 'm')
> +
> +    from xen.xend.XendClient import server
> +    server.xend_domain_mem_target_set(dom, mem_target)
> +
> +# TODO: why does this lookup by name?  and what if that fails!?
> +def xm_vcpu_enable(args):
> +    arg_check(args, 2, "vcpu-enable")
> +
> +    name = args[0]
> +    vcpu = int(args[1])
> +
> +    from xen.xend.XendClient import server
> +    dom = server.xend_domain(name)
> +    id = sxp.child_value(dom, 'id')
> +    server.xend_domain_vcpu_hotplug(id, vcpu, 1)
> +
> +def xm_vcpu_disable(args):
> +    arg_check(args, 2, "vcpu-disable")
> +
> +    name = args[0]
> +    vcpu = int(args[1])
> +
> +    from xen.xend.XendClient import server
> +    dom = server.xend_domain(name)
> +    id = sxp.child_value(dom, 'id')
> +    server.xend_domain_vcpu_hotplug(id, vcpu, 0)
> +
> +def xm_domid(args):
> +    name = args[0]
> +
> +    from xen.xend.XendClient import server
> +    dom = server.xend_domain(name)
> +    print sxp.child_value(dom, 'id')
> +
> +def xm_domname(args):
> +    name = args[0]
> +
> +    from xen.xend.XendClient import server
> +    dom = server.xend_domain(name)
> +    print sxp.child_value(dom, 'name')
> +
> +def xm_bvt(args):
> +    arg_check(args, 6, "bvt")
> +    dom = args[0]
> +    v = map(long, args[1:6])
> +    from xen.xend.XendClient import server
> +    server.xend_domain_cpu_bvt_set(dom, *v)
> +
> +def xm_bvt_ctxallow(args):
> +    arg_check(args, 1, "bvt_ctxallow")
> +
> +    slice = int(args[0])
> +    from xen.xend.XendClient import server
> +    server.xend_node_cpu_bvt_slice_set(slice)
> +
> +def xm_sedf(args):
> +    arg_check(args, 6, "sedf")
> +
> +    dom = args[0]
> +    v = map(int, args[1:5])
> +    from xen.xend.XendClient import server
> +    server.xend_domain_cpu_sedf_set(dom, *v)
> +
> +def xm_info(args):
> +    from xen.xend.XendClient import server
> +    info = server.xend_node()
> +
> +    for x in info[1:]:
> +        print "%-23s:" % x[0], x[1]
> +
> +# TODO: remove as soon as console server shows up
> +def xm_console(args):
> +    arg_check(args,1,"console")
> +
> +    dom = args[0]
> +    from xen.xend.XendClient import server
> +    info = server.xend_domain(dom)
> +    domid = int(sxp.child_value(info, 'id', '-1'))
> +    cmd = "/usr/libexec/xen/xenconsole %d" % domid
> +    os.execvp('/usr/libexec/xen/xenconsole', cmd.split())
> +    console = sxp.child(info, "console")
> +
> +def xm_dmesg(args):
> +
>      gopts = Opts(use="""[-c|--clear]
>
>  Read Xen's message buffer (boot output, warning and error messages) or
> clear @@ -744,161 +455,212 @@
>      gopts.opt('clear', short='c',
>                fn=set_true, default=0,
>                use="Clear the contents of the Xen message buffer.")
> -
> -    short_options = ['-c']
> -    long_options = ['--clear']
> -
> -    def help(self, args):
> -        self.gopts.argv = args
> -        self.gopts.usage()
> -
> -    def main(self, args):
> -        self.gopts.parse(args)
> -        if not (1 <= len(args) <=2):
> -            self.gopts.err('Invalid arguments: ' + str(args))
> -
> -        if not self.gopts.vals.clear:
> -            print server.xend_node_get_dmesg()
> -        else:
> -            server.xend_node_clear_dmesg()
> -
> -xm.prog(ProgDmesg)
> -
> -class ProgLog(Prog):
> -    group = 'host'
> -    name  =  "log"
> -    info  = """Print the xend log."""
> -
> -    def main(self, args):
> -        print server.xend_node_log()
> -
> -xm.prog(ProgLog)
> -
> -class ProgVifCreditLimit(Prog):
> -    group = 'vif'
> -    name= "vif-limit"
> -    info = """Limit the transmission rate of a virtual network
> interface.""" -
> -    def help(self, args):
> -        print args[0], "DOMAIN VIF CREDIT_IN_BYTES PERIOD_IN_USECS"
> -        print "\nSet the credit limit of a virtual network interface."
> -
> -    def main(self, args):
> -        if len(args) != 5: self.err("%s: Invalid argument(s)" % args[0])
> -        dom = args[1]
> -        v = map(int, args[2:5])
> -        server.xend_domain_vif_limit(dom, *v)
> -
> -xm.prog(ProgVifCreditLimit)
> -
> -class ProgVifList(Prog):
> -    group = 'vif'
> -    name  = 'vif-list'
> -    info  = """List virtual network interfaces for a domain."""
> -
> -    def help(self, args):
> -        print args[0], "DOM"
> -        print "\nList virtual network interfaces for domain DOM"
> -
> -    def main(self, args):
> -        if len(args) != 2: self.err("%s: Invalid argument(s)" % args[0])
> -        dom = args[1]
> -        for x in server.xend_domain_devices(dom, 'vif'):
> -            sxp.show(x)
> +    # Work around for gopts
> +    args.insert(0,"bogus")
> +    gopts.parse(args)
> +    if not (1 <= len(args) <= 2):
> +        err('Invalid arguments: ' + str(args))
> +
> +    from xen.xend.XendClient import server
> +    if not gopts.vals.clear:
> +        print server.xend_node_get_dmesg()
> +    else:
> +        server.xend_node_clear_dmesg()
> +
> +def xm_log(args):
> +    from xen.xend.XendClient import server
> +    print server.xend_node_log()
> +
> +def xm_network_limit(args):
> +    arg_check(args,4,"network-limit")
> +    dom = args[0]
> +    v = map(int, args[1:4])
> +    from xen.xend.XendClient import server
> +    server.xend_domain_vif_limit(dom, *v)
> +
> +def xm_network_list(args):
> +    arg_check(args,1,"network-list")
> +    dom = args[0]
> +    from xen.xend.XendClient import server
> +    for x in server.xend_domain_devices(dom, 'vif'):
> +        sxp.show(x)
> +        print
> +
> +def xm_block_list(args):
> +    arg_check(args,1,"block-list")
> +    dom = args[0]
> +    from xen.xend.XendClient import server
> +    for x in server.xend_domain_devices(dom, 'vbd'):
> +        sxp.show(x)
> +        print
> +
> +def xm_block_create(args):
> +    n = len(args)
> +    if n < 4 or n > 5:
> +        err("%s: Invalid argument(s)" % args[0])
> +        usage("block-create")
> +
> +    dom = args[0]
> +    vbd = ['vbd',
> +           ['uname', args[1]],
> +           ['dev',   args[2]],
> +           ['mode',  args[3]]]
> +    if n == 5:
> +        vbd.append(['backend', args[4]])
> +
> +    from xen.xend.XendClient import server
> +    server.xend_domain_device_create(dom, vbd)
> +
> +def xm_block_refresh(args):
> +    arg_check(args,2,"block-refresh")
> +
> +    dom = args[0]
> +    dev = args[1]
> +
> +    from xen.xend.XendClient import server
> +    server.xend_domain_device_refresh(dom, 'vbd', dev)
> +
> +def xm_block_destroy(args):
> +    arg_check(args,2,"block-destroy")
> +
> +    dom = args[0]
> +    dev = args[1]
> +
> +    from xen.xend.XendClient import server
> +    server.xend_domain_device_destroy(dom, 'vbd', dev)
> +
> +commands = {
> +    # console commands
> +    "console": xm_console,
> +    # domain commands
> +    "domid": xm_domid,
> +    "domname": xm_domname,
> +    "create": xm_create,
> +    "destroy": xm_destroy,
> +    "restore": xm_restore,
> +    "save": xm_save,
> +    "shutdown": xm_shutdown,
> +    "reboot": xm_reboot,
> +    "list": xm_list,
> +    # memory commands
> +    "mem-max": xm_mem_max,
> +    "mem-set": xm_mem_set,
> +    # cpu commands
> +    "cpus-set": xm_cpus_set,
> +#    "cpus-list": xm_cpus_list,
> +    "vcpu-enable": xm_vcpu_enable,
> +    "vcpu-disable": xm_vcpu_disable,
> +    "vcpu-list": xm_vcpu_list,
> +    # migration
> +    "migrate": xm_migrate,
> +    # special
> +    "sysrq": xm_sysrq,
> +    "pause": xm_pause,
> +    "unpause": xm_unpause,
> +    # host commands
> +    "dmesg": xm_dmesg,
> +    "info": xm_info,
> +    "log": xm_log,
> +    # scheduler
> +    "bvt": xm_bvt,
> +    "bvt_ctxallow": xm_bvt_ctxallow,
> +    "sedf": xm_sedf,
> +    # block
> +    "block-create": xm_block_create,
> +    "block-destroy": xm_block_destroy,
> +    "block-list": xm_block_list,
> +    "block-refresh": xm_block_refresh,
> +    # network
> +    "network-limit": xm_network_limit,
> +    "network-list": xm_network_list
> +    }
> +
> +aliases = {
> +    "balloon": "mem-set",
> +    "vif-list": "network-list",
> +    "vif-limit": "network-limit",
> +    "vbd-create": "block-create",
> +    "vbd-destroy": "block-destroy",
> +    "vbd-list": "block-list",
> +    "vbd-refresh": "block-refresh",
> +    }
> +
> +help = {
> +    "--long": longhelp
> +   }
> +
> +def xm_lookup_cmd(cmd):
> +    if commands.has_key(cmd):
> +        return commands[cmd]
> +    elif aliases.has_key(cmd):
> +        deprecated(cmd,aliases[cmd])
> +        return commands[aliases[cmd]]
> +    else:
> +        err('Sub Command %s not found!' % cmd)
> +        usage()
> +
> +def deprecated(old,new):
> +    err('Option %s is deprecated, and will be removed in future!!!' % old)
> +    err('Option %s is the new replacement, see "xm help %s" for more info'
> % (new, new)) +
> +def usage(cmd=None):
> +    if cmd == "full":
> +        print fullhelp
> +    elif help.has_key(cmd):
> +        print help[cmd]
> +    else:
> +        print shorthelp
> +    sys.exit(1)
> +
> +def main(argv=sys.argv):
> +    if len(argv) < 2:
> +        usage()
> +
> +    if re.compile('-*help').match(argv[1]):
> +     if len(argv) > 2 and help.has_key(argv[2]):
> +         usage(argv[2])
> +     else:
> +         usage()
> +     sys.exit(0)
> +
> +    cmd = xm_lookup_cmd(argv[1])
> +
> +    # strip off prog name and subcmd
> +    args = argv[2:]
> +    if cmd:
> +        try:
> +            from xen.xend.XendClient import XendError
> +            rc = cmd(args)
> +            if rc:
> +                usage()
> +        except socket.error, ex:
> +            print >>sys.stderr, ex
> +            err("Error connecting to xend, is xend running?")
> +            sys.exit(1)
> +        except IOError:
> +            err("Most commands need root access.  Please try again as
> root") +            sys.exit(1)
> +        except XendError, ex:
> +            if len(args) > 0:
> +                handle_xend_error(argv[1], args[0], ex)
> +            else:
> +                print "Unexpected error:", sys.exc_info()[0]
> +                print
> +                print "Please report to xen-devel@xxxxxxxxxxxxxxxxxxx"
> +                raise
> +        except SystemExit:
> +            sys.exit(1)
> +        except:
> +            print "Unexpected error:", sys.exc_info()[0]
>              print
> -
> -xm.prog(ProgVifList)
> -
> -class ProgVbdList(Prog):
> -    group = 'vbd'
> -    name  = 'vbd-list'
> -    info  = """List virtual block devices for a domain."""
> -
> -    def help(self, args):
> -        print args[0], "DOM"
> -        print "\nList virtual block devices for domain DOM"
> -
> -    def main(self, args):
> -        if len(args) != 2: self.err("%s: Invalid argument(s)" % args[0])
> -        dom = args[1]
> -        for x in server.xend_domain_devices(dom, 'vbd'):
> -            sxp.show(x)
> -            print
> -
> -xm.prog(ProgVbdList)
> -
> -class ProgVbdCreate(Prog):
> -    group = 'vbd'
> -    name  = 'vbd-create'
> -    info = """Create a new virtual block device for a domain"""
> -
> -    def help(self, args):
> -        print args[0], "DOM UNAME DEV MODE [BACKEND]"
> -        print """
> -Create a virtual block device for a domain.
> -
> -  UNAME   - device to export, e.g. phy:hda2
> -  DEV     - device name in the domain, e.g. sda1
> -  MODE    - access mode: r for read, w for read-write
> -  BACKEND - backend driver domain
> -"""
> -
> -    def main(self, args):
> -        n = len(args)
> -        if n < 5 or n > 6: self.err("%s: Invalid argument(s)" % args[0])
> -        dom = args[1]
> -        vbd = ['vbd',
> -               ['uname', args[2]],
> -               ['dev',   args[3]],
> -               ['mode',  args[4]]]
> -        if n == 6:
> -            vbd.append(['backend', args[5]])
> -        server.xend_domain_device_create(dom, vbd)
> -
> -xm.prog(ProgVbdCreate)
> -
> -class ProgVbdRefresh(Prog):
> -    group = 'vbd'
> -    name  = 'vbd-refresh'
> -    info = """Refresh a virtual block device for a domain"""
> -
> -    def help(self, args):
> -        print args[0], "DOM DEV"
> -        print """
> -Refresh a virtual block device for a domain.
> -
> -  DEV     - idx field in the device information
> -"""
> -
> -    def main(self, args):
> -        if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0])
> -        dom = args[1]
> -        dev = args[2]
> -        server.xend_domain_device_refresh(dom, 'vbd', dev)
> -
> -xm.prog(ProgVbdRefresh)
> -
> -
> -class ProgVbdDestroy(Prog):
> -    group = 'vbd'
> -    name = 'vbd-destroy'
> -    info = """Destroy a domain's virtual block device"""
> -
> -    def help(self, args):
> -        print args[0], "DOM DEV"
> -        print """
> -Destroy vbd DEV attached to domain DOM. Detaches the device
> -from the domain, but does not destroy the device contents.
> -The device indentifier DEV is the idx field in the device
> -information. This is visible in 'xm vbd-list'."""
> -
> -    def main(self, args):
> -        if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0])
> -        dom = args[1]
> -        dev = args[2]
> -        server.xend_domain_device_destroy(dom, 'vbd', dev)
> -
> -xm.prog(ProgVbdDestroy)
> -
> -def main(args):
> -    xm.main(args)
> +            print "Please report to xen-devel@xxxxxxxxxxxxxxxxxxx"
> +            raise
> +
> +    else:
> +        usage()
> +
> +if __name__ == "__main__":
> +    main()
> +
> +
> +

_______________________________________________
Xen-tools mailing list
Xen-tools@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-tools

<Prev in Thread] Current Thread [Next in Thread>