ia64/xen-unstable

changeset 1487:db3e69f8ca89

bitkeeper revision 1.959.1.7 (40d0b7e204hRazr8_qoesp7P0oZMUw)

Extend xm to support most of the control interface and
get 'xm create' closer to working.
author mjw@wray-m-3.hpl.hp.com
date Wed Jun 16 21:13:06 2004 +0000 (2004-06-16)
parents 00ee5e841bd7
children 8f52e5e39641
files tools/examples/xm_dom_control.py tools/xenmgr/lib/XendClient.py tools/xenmgr/lib/XendDomain.py tools/xenmgr/lib/XendDomainInfo.py tools/xenmgr/lib/xm/create.py tools/xenmgr/lib/xm/main.py tools/xenmgr/lib/xm/opts.py tools/xenmgr/netfix tools/xenmgr/xend
line diff
     1.1 --- a/tools/examples/xm_dom_control.py	Wed Jun 16 13:51:54 2004 +0000
     1.2 +++ b/tools/examples/xm_dom_control.py	Wed Jun 16 21:13:06 2004 +0000
     1.3 @@ -8,6 +8,7 @@ import os
     1.4  import os.path
     1.5  import signal
     1.6  
     1.7 +from xenmgr import sxp
     1.8  from xenmgr.XendClient import server
     1.9  
    1.10  # usage: xc_dom_control [command] <params>
    1.11 @@ -131,13 +132,13 @@ elif cmd == 'list':
    1.12      for dom in server.xend_domains():
    1.13          info = server.xend_domain(dom)
    1.14          d = {}
    1.15 -        d['dom'] = dom
    1.16 -        d['name'] = sxp.get_child_value(info, 'name', '??')
    1.17 -        d['mem'] = int(sxp.get_child_value(info, 'memory', '0'))
    1.18 -        d['cpu'] = int(sxp.get_child_value(info, 'cpu', '0'))
    1.19 -        d['state'] = sxp.get_child_value(info, 'state', '??')
    1.20 -        d['cpu_time'] = sxp.get_child_value(info, 'cpu_time', '0')
    1.21 -        print ("%(dom)-4d %(name)-16s %(mem)7d %(cpu)3d %(state)5s %(cpu_time)8d"
    1.22 +        d['dom'] = int(dom)
    1.23 +        d['name'] = sxp.child_value(info, 'name', '??')
    1.24 +        d['mem'] = int(sxp.child_value(info, 'memory', '0'))
    1.25 +        d['cpu'] = int(sxp.child_value(info, 'cpu', '0'))
    1.26 +        d['state'] = sxp.child_value(info, 'state', '??')
    1.27 +        d['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0')
    1.28 +        print ("%(dom)-4d %(name)-16s %(mem)7d %(cpu)3d %(state)5s %(cpu_time)8.2f"
    1.29                 % d)
    1.30  
    1.31  elif cmd == 'unwatch':
     2.1 --- a/tools/xenmgr/lib/XendClient.py	Wed Jun 16 13:51:54 2004 +0000
     2.2 +++ b/tools/xenmgr/lib/XendClient.py	Wed Jun 16 21:13:06 2004 +0000
     2.3 @@ -97,7 +97,7 @@ def xend_request(url, method, data=None)
     2.4      #hdr['Accept'] = 'text/html,text/plain'
     2.5      conn = httplib.HTTPConnection(ulocation)
     2.6      #conn.response_class = Foo
     2.7 -    conn.set_debuglevel(1)
     2.8 +    if DEBUG: conn.set_debuglevel(1)
     2.9      conn.request(method, upath, args, hdr)
    2.10      resp = conn.getresponse()
    2.11      if DEBUG: print resp.status, resp.reason
    2.12 @@ -118,10 +118,7 @@ def xend_request(url, method, data=None)
    2.13      #    val = val[1]
    2.14      if isinstance(val, types.ListType) and sxp.name(val) == 'err':
    2.15          raise RuntimeError(val[1])
    2.16 -    if DEBUG: print '**val='
    2.17 -    #sxp.show(val); print
    2.18 -    PrettyPrint.prettyprint(val)
    2.19 -    if DEBUG: print '**'
    2.20 +    if DEBUG: print '**val='; sxp.show(val); print
    2.21      return val
    2.22  
    2.23  def xend_get(url, args=None):
    2.24 @@ -334,7 +331,9 @@ def main(argv):
    2.25      if not fn.startswith('xend'):
    2.26          fn = 'xend_' + fn
    2.27      args = argv[2:]
    2.28 -    getattr(server, fn)(*args)
    2.29 +    val = getattr(server, fn)(*args)
    2.30 +    PrettyPrint.prettyprint(val)
    2.31 +    print
    2.32  
    2.33  if __name__ == "__main__":
    2.34      main(sys.argv)
     3.1 --- a/tools/xenmgr/lib/XendDomain.py	Wed Jun 16 13:51:54 2004 +0000
     3.2 +++ b/tools/xenmgr/lib/XendDomain.py	Wed Jun 16 21:13:06 2004 +0000
     3.3 @@ -66,11 +66,11 @@ class XendDomain:
     3.4                  print "dom=", domid, "del"
     3.5                  self._delete_domain(domid)
     3.6          print "doms:"
     3.7 -        for d in self.domain.values(): print d
     3.8 +        for d in self.domain.values(): print 'dom', d
     3.9          print "refresh..."
    3.10          self.refresh()
    3.11          print "doms:"
    3.12 -        for d in self.domain.values(): print d
    3.13 +        for d in self.domain.values(): print 'dom', d
    3.14  
    3.15      def sync(self):
    3.16          """Sync domain db to disk.
    3.17 @@ -162,7 +162,7 @@ class XendDomain:
    3.18          else:
    3.19              d = self.domain.get(id)
    3.20              if d:
    3.21 -                d.update(dominfo)
    3.22 +                d.update(dominfo[0])
    3.23  
    3.24      def domain_ls(self):
    3.25          # List domains.
     4.1 --- a/tools/xenmgr/lib/XendDomainInfo.py	Wed Jun 16 13:51:54 2004 +0000
     4.2 +++ b/tools/xenmgr/lib/XendDomainInfo.py	Wed Jun 16 21:13:06 2004 +0000
     4.3 @@ -113,7 +113,7 @@ class XendDomainInfo:
     4.4          if self.info:
     4.5              run = (self.info['running'] and 'r') or '-'
     4.6              stop = (self.info['stopped'] and 's') or '-'
     4.7 -            state = run + state
     4.8 +            state = run + stop
     4.9              sxpr.append(['cpu', self.info['cpu']])
    4.10              sxpr.append(['state', state])
    4.11              sxpr.append(['cpu_time', self.info['cpu_time']/1e8])
     5.1 --- a/tools/xenmgr/lib/xm/create.py	Wed Jun 16 13:51:54 2004 +0000
     5.2 +++ b/tools/xenmgr/lib/xm/create.py	Wed Jun 16 21:13:06 2004 +0000
     5.3 @@ -40,7 +40,8 @@ def set_var(opt, k, v):
     5.4  
     5.5  opts.opt('define', short='D', val='VAR=VAL',
     5.6           fn=set_var, default=None,
     5.7 -         use="Set a variable before loading defaults,e.g. '-D vmid=3;ip=1.2.3.4'.")
     5.8 +         use="""Set variables before loading defaults, e.g. '-D vmid=3;ip=1.2.3.4'
     5.9 +         to set vmid and ip.""")
    5.10  
    5.11  opts.opt('dryrun', short='n',
    5.12           fn=set_true, default=0,
    5.13 @@ -71,6 +72,10 @@ opts.opt('disk', short='d', val='phy:DEV
    5.14           is exported to the domain as VDEV. The disk is read-only if MODE is r,
    5.15           read-write if mode is 'w'.""")
    5.16  
    5.17 +opts.opt('pci', val='BUS,DEV,FUNC',
    5.18 +         fn=append_value, default=[],
    5.19 +         use="""Add a PCI device to a domain.""")
    5.20 +
    5.21  opts.opt('ipaddr', short='i', val="IPADDR",
    5.22           fn=append_value, default=[],
    5.23           use="Add an IP address to the domain.")
    5.24 @@ -82,7 +87,7 @@ opts.opt('mac', short='M', val="MAC",
    5.25           are allocated a random address.""")
    5.26  
    5.27  opts.opt('nics', val="N",
    5.28 -         fn=set_int, default="1",
    5.29 +         fn=set_int, default=1,
    5.30           use="Set the number of network interfaces.")
    5.31  
    5.32  opts.opt('vnet', val='VNET',
    5.33 @@ -101,7 +106,7 @@ opts.opt('extra', short='E', val="ARGS",
    5.34           use="Set extra arguments to append to the kernel command line.")
    5.35  
    5.36  opts.opt('ip', short='I', val='IPADDR',
    5.37 -         fn=set_value, default=[],
    5.38 +         fn=set_value, default='',
    5.39           use="Set the kernel IP interface address.")
    5.40  
    5.41  opts.opt('gateway', val="IPADDR",
    5.42 @@ -138,7 +143,7 @@ def strip(pre, s):
    5.43      else:
    5.44          return s
    5.45  
    5.46 -def make_domain_config(opts):
    5.47 +def make_config(opts):
    5.48      
    5.49      config = ['config',
    5.50                ['name', opts.name ],
    5.51 @@ -151,10 +156,10 @@ def make_domain_config(opts):
    5.52      if opts.ramdisk:
    5.53          config_image.append([ 'ramdisk', os.path.abspath(opts.ramdisk) ])
    5.54      if opts.cmdline_ip:
    5.55 -        cmdline_ip = strip("ip=", opts.cmdline_ip)
    5.56 +        cmdline_ip = strip('ip=', opts.cmdline_ip)
    5.57          config_image.append(['ip', cmdline_ip])
    5.58      if opts.root:
    5.59 -        cmdline_root = strip("root=", opts.root)
    5.60 +        cmdline_root = strip('root=', opts.root)
    5.61          config_image.append(['root', opts.root])
    5.62      if opts.extra:
    5.63          config_image.append(['args', opts.extra])
    5.64 @@ -173,7 +178,7 @@ def make_domain_config(opts):
    5.65          config_devs.append(['device', config_pci])
    5.66  
    5.67      for idx in range(0, opts.nics):
    5.68 -        config_vif = ['vif' ['@', ['id', 'vif%d' % idx]]]
    5.69 +        config_vif = ['vif', ['@', ['id', 'vif%d' % idx]]]
    5.70          if idx < len(opts.mac):
    5.71              config_vif.append(['mac', opts.mac[idx]])
    5.72          config_devs.append(['device', config_vif])
    5.73 @@ -203,10 +208,11 @@ def preprocess_disk(opts):
    5.74      disk = []
    5.75      for v in opts.disk:
    5.76          d = v.split(',')
    5.77 +        print 'disk', v, d
    5.78          if len(d) != 3:
    5.79              opts.err('Invalid disk specifier: ' + v)
    5.80          disk.append(d)
    5.81 -    opts.disk = d
    5.82 +    opts.disk = disk
    5.83  
    5.84  def preprocess_pci(opts):
    5.85      if not opts.pci: return
    5.86 @@ -246,7 +252,7 @@ def preprocess(opts):
    5.87      preprocess_ip(opts)
    5.88      preprocess_nfs(opts)
    5.89           
    5.90 -def make_domain(config):
    5.91 +def make_domain(opts, config):
    5.92      """Create, build and start a domain.
    5.93      Returns: [int] the ID of the new domain.
    5.94      """
    5.95 @@ -281,7 +287,10 @@ def main(argv):
    5.96          opts.usage()
    5.97      preprocess(opts)
    5.98      config = make_config(opts)
    5.99 -    make_domain(opts, config)
   5.100 +    if opts.dryrun:
   5.101 +        PrettyPrint.prettyprint(config)
   5.102 +    else:
   5.103 +        make_domain(opts, config)
   5.104          
   5.105  if __name__ == '__main__':
   5.106      main(sys.argv)
     6.1 --- a/tools/xenmgr/lib/xm/main.py	Wed Jun 16 13:51:54 2004 +0000
     6.2 +++ b/tools/xenmgr/lib/xm/main.py	Wed Jun 16 21:13:06 2004 +0000
     6.3 @@ -2,8 +2,8 @@
     6.4  import string
     6.5  import sys
     6.6  
     6.7 +from xenmgr import sxp
     6.8  from xenmgr.XendClient import server
     6.9 -
    6.10  from xenmgr.xm import create, shutdown
    6.11  
    6.12  class Xm:
    6.13 @@ -55,7 +55,7 @@ class Xm:
    6.14      def xm_save(self, help, args):
    6.15          """Save domain state to file."""
    6.16          if help:
    6.17 -            print "save DOM FILE"
    6.18 +            print args[0], "DOM FILE"
    6.19              print "\nSave domain with id DOM to FILE."
    6.20              return
    6.21          if len(args) < 3: self.err("%s: Missing arguments" % args[0])
    6.22 @@ -66,23 +66,31 @@ class Xm:
    6.23      def xm_restore(self, help, args):
    6.24          """Create a domain from a saved state."""
    6.25          if help:
    6.26 -            print "restore FILE"
    6.27 +            print args[0], "FILE"
    6.28              print "\nRestore a domain from FILE."
    6.29          if len(args) < 2: self.err("%s: Missing file" % args[0])
    6.30          server.xend_domain_restore(dom, None, filename)
    6.31  
    6.32      def xm_ls(self, help, args):
    6.33          """List domains."""
    6.34 -        if help: self.help('xm_ls'); return
    6.35 +        if help: self.help('xm_' + args[0]); return
    6.36          doms = server.xend_domains()
    6.37 +        print 'Dom  Name             Mem(MB)  CPU  State  Time(s)'
    6.38          for dom in doms:
    6.39 -            d = server.domain(dom)
    6.40 -            print d
    6.41 +            info = server.xend_domain(dom)
    6.42 +            d = {}
    6.43 +            d['dom'] = int(dom)
    6.44 +            d['name'] = sxp.child_value(info, 'name', '??')
    6.45 +            d['mem'] = int(sxp.child_value(info, 'memory', '0'))
    6.46 +            d['cpu'] = int(sxp.child_value(info, 'cpu', '0'))
    6.47 +            d['state'] = sxp.child_value(info, 'state', '??')
    6.48 +            d['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0'))
    6.49 +            print ("%(dom)-4d %(name)-16s %(mem)4d     %(cpu)3d %(state)5s %(cpu_time)10.2f" % d)
    6.50  
    6.51      def xm_halt(self, help, args):
    6.52          """Terminate a domain immediately."""
    6.53          if help:
    6.54 -            print 'halt DOM'
    6.55 +            print args[0], 'DOM'
    6.56              print '\nTerminate domain DOM immediately.'
    6.57              return
    6.58          if len(args) < 2: self.err("%s: Missing domain" % args[0])
    6.59 @@ -96,7 +104,7 @@ class Xm:
    6.60      def xm_stop(self, help, args):
    6.61          """Stop execution of a domain."""
    6.62          if help:
    6.63 -            print 'stop DOM'
    6.64 +            print args[0], 'DOM'
    6.65              print '\nStop execution of domain DOM.'
    6.66              return
    6.67          if len(args) < 2: self.err("%s: Missing domain" % args[0])
    6.68 @@ -106,7 +114,7 @@ class Xm:
    6.69      def xm_start(self, help, args):
    6.70          """Start execution of a domain."""
    6.71          if help:
    6.72 -            print 'start DOM'
    6.73 +            print args[0], 'DOM'
    6.74              print '\nStart execution of domain DOM.'
    6.75              return
    6.76          if len(args) < 2: self.err("%s: Missing domain" % args[0])
    6.77 @@ -116,28 +124,83 @@ class Xm:
    6.78      def xm_pincpu(self, help, args):
    6.79          """Pin a domain to a cpu. """
    6.80          if help:
    6.81 -            print 'pincpu DOM CPU'
    6.82 +            print args[0],'DOM CPU'
    6.83              print '\nPin domain DOM to cpu CPU.'
    6.84              return
    6.85 -        pass
    6.86 +        if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0])
    6.87 +        v = map(int, args[1:3])
    6.88 +        server.xend_domain_pincpu(*v)
    6.89 +
    6.90 +    def xm_vif_stats(self, help, args):
    6.91 +        """Get stats for a virtual interface."""
    6.92 +        if help:
    6.93 +            print args[0], 'DOM VIF'
    6.94 +            print '\nGet stats for interface VIF on domain DOM.'
    6.95 +            return
    6.96 +        if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0])
    6.97 +        v = map(int, args[1:3])
    6.98 +        print server.xend_domain_vif_stats(*v)
    6.99 +
   6.100 +    def xm_vif_rate(self, help, args):
   6.101 +        """Set or get vif rate params."""
   6.102 +        if help:
   6.103 +            print args[0], "DOM VIF [BYTES USECS]"
   6.104 +            print '\nSet or get rate controls for interface VIF on domain DOM.'
   6.105 +            return
   6.106 +        n = len(args)
   6.107 +        if n == 3:
   6.108 +            v = map(int, args[1:n])
   6.109 +            print server.xend_domain_vif_scheduler_get(*v)
   6.110 +        elif n == 5:
   6.111 +            v = map(int, args[1:n])
   6.112 +            server.xend_domain_vif_scheduler_set(*v)
   6.113 +        else:
   6.114 +            self.err("%s: Invalid argument(s)" % args[0])
   6.115  
   6.116      def xm_bvt(self, help, args):
   6.117 -        pass
   6.118 +        """Set BVT scheduler parameters."""
   6.119 +        if help:
   6.120 +            print args[0], "DOM MCUADV WARP WARPL WARPU"
   6.121 +            print '\nSet Borrowed Virtual Time scheduler parameters.'
   6.122 +            return
   6.123 +        if len(args) != 6: self.err("%s: Invalid argument(s)" % args[0])
   6.124 +        v = map(int, args[1:6])
   6.125 +        server.xend_domain_cpu_bvt_set(*v)
   6.126  
   6.127      def xm_bvtslice(self, help, args):
   6.128 -        pass
   6.129 +        """Set the BVT scheduler slice."""
   6.130 +        if help:
   6.131 +            print args[0], 'SLICE'
   6.132 +            print '\nSet Borrowed Virtual Time scheduler slice.'
   6.133 +            return
   6.134 +        if len(args) < 2: self.err('%s: Missing slice' % args[0])
   6.135 +        server.xend_node_cpu_bvt_slice_set(slice)
   6.136  
   6.137      def xm_atropos(self, help, args):
   6.138 -        pass
   6.139 +        """Set atropos parameters."""
   6.140 +        if help:
   6.141 +            print args[0], "DOM PERIOD SLICE LATENCY XTRATIME"
   6.142 +            print "\nSet atropos parameters."
   6.143 +            return
   6.144 +        if len(args) != 5: self.err("%s: Invalid argument(s)" % args[0])
   6.145 +        v = map(int, args[1:5])
   6.146 +        server.xend_domain_cpu_atropos_set(*v)
   6.147  
   6.148 -    def xm_rrslice(self, help, args):
   6.149 -        pass
   6.150 +    def xm_rrobin(self, help, args):
   6.151 +        """Set round robin slice."""
   6.152 +        if help:
   6.153 +            print args[0], "SLICE"
   6.154 +            print "\nSet round robin scheduler slice."
   6.155 +            return
   6.156 +        if len(args) != 2: self.err("%s: Invalid argument(s)" % args[0])
   6.157 +        slice = int(args[1])
   6.158 +        server.xend_node_rrobin_set(slice)
   6.159  
   6.160      def xm_info(self, help, args):
   6.161          """Get information about the xen host."""
   6.162          if help: self.help('xm_info'); return
   6.163          info = server.xend_node()
   6.164 -        for x in info:
   6.165 +        for x in info[1:]:
   6.166              print "%-23s:" % x[0], x[1]
   6.167  
   6.168      def xm_console(self, help, args):
     7.1 --- a/tools/xenmgr/lib/xm/opts.py	Wed Jun 16 13:51:54 2004 +0000
     7.2 +++ b/tools/xenmgr/lib/xm/opts.py	Wed Jun 16 21:13:06 2004 +0000
     7.3 @@ -2,6 +2,7 @@ from getopt import getopt
     7.4  import os
     7.5  import os.path
     7.6  import sys
     7.7 +import types
     7.8  
     7.9  class Opt:
    7.10      def __init__(self, opts, name, short=None, long=None,
    7.11 @@ -78,10 +79,14 @@ class Opt:
    7.12          else:
    7.13              return 0
    7.14  
    7.15 +    def specified(self):
    7.16 +        return self.specified_opt
    7.17 +
    7.18  class Opts:
    7.19      def __init__(self, use=None):
    7.20          self._usage = use
    7.21          self._options = []
    7.22 +        self._options_map = {}
    7.23          self._argv = []
    7.24          self._vals = {}
    7.25          self._globals = {}
    7.26 @@ -90,8 +95,16 @@ class Opts:
    7.27      def opt(self, name, **args):
    7.28          x = Opt(self, name, **args)
    7.29          self._options.append(x)
    7.30 +        self._options_map[name] = x
    7.31          return x
    7.32  
    7.33 +    def getopt(self, name):
    7.34 +        return self._options_map.get(name)
    7.35 +
    7.36 +    def specified(self, name):
    7.37 +        opt = self.getopt(name)
    7.38 +        return opt and opt.specified()
    7.39 +
    7.40      def setvar(self, name, val):
    7.41          self._globals[name] = val
    7.42  
    7.43 @@ -140,28 +153,31 @@ class Opts:
    7.44              opt.show()
    7.45  
    7.46      def load_defaults(self):
    7.47 -        print 'load_defaults>', 'defaults=', self.defaults
    7.48 -        print 'load_defaults>', 'path=', self.path
    7.49          for x in [ '' ] + self.path.split(':'):
    7.50 -            print 'load_defaults>', 'x=', x, 'defaults=', self.defaults
    7.51              if x:
    7.52                  p = os.path.join(x, self.defaults)
    7.53              else:
    7.54                  p = self.defaults
    7.55 -            if os.stat(p):
    7.56 +            if os.path.exists(p):
    7.57                  self.load(p)
    7.58                  break
    7.59          else:
    7.60              self.err("Cannot open defaults file %s" % self.defaults)
    7.61  
    7.62      def load(self, defaults):
    7.63 -        print 'load>', 'defaults=', defaults
    7.64          self._globals['sys'] = sys
    7.65          self._globals['config_file'] = defaults
    7.66          execfile(defaults, self._globals, self._locals)
    7.67 -        print 'load>', 'globals=', self._globals
    7.68 -        print 'load>', 'locals=', self._locals
    7.69 -            
    7.70 +        vtypes = [ types.StringType,
    7.71 +                   types.ListType,
    7.72 +                   types.IntType,
    7.73 +                   types.FloatType
    7.74 +                   ]
    7.75 +        for (k, v) in self._locals.items():
    7.76 +            if self.specified(k): continue
    7.77 +            if not(type(v) in vtypes): continue
    7.78 +            print 'SET ', k, v
    7.79 +            setattr(self, k, v)
    7.80  
    7.81  def set_true(opt, k, v):
    7.82      opt.set(1)
     8.1 --- a/tools/xenmgr/netfix	Wed Jun 16 13:51:54 2004 +0000
     8.2 +++ b/tools/xenmgr/netfix	Wed Jun 16 21:13:06 2004 +0000
     8.3 @@ -1,4 +1,5 @@
     8.4  #!/usr/bin/python
     8.5 +#  -*- mode: python; -*-
     8.6  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     8.7  #============================================================================
     8.8  # Move the IP address from eth0 onto the Xen bridge (nbe-br).
     9.1 --- a/tools/xenmgr/xend	Wed Jun 16 13:51:54 2004 +0000
     9.2 +++ b/tools/xenmgr/xend	Wed Jun 16 21:13:06 2004 +0000
     9.3 @@ -1,4 +1,5 @@
     9.4  #!/usr/bin/python
     9.5 +#  -*- mode: python; -*-
     9.6  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     9.7  
     9.8  """Xen management daemon. Lives in /usr/sbin.