[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Move XendVnet from using DBMap etc to using xstransact. This is the last



# HG changeset patch
# User emellor@ewan
# Node ID 70d5bfbf23d4c7ba21b4029ad63471959f854b86
# Parent  a73ab0ddf990f2e3c341a43e3aa3d7d0e3a7cc61
Move XendVnet from using DBMap etc to using xstransact.  This is the last
dependency upon xsnode, xsobj, and xsresource, so these can all go.

Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>

diff -r a73ab0ddf990 -r 70d5bfbf23d4 tools/python/xen/xend/XendVnet.py
--- a/tools/python/xen/xend/XendVnet.py Sun Oct  2 17:21:01 2005
+++ b/tools/python/xen/xend/XendVnet.py Sun Oct  2 17:22:22 2005
@@ -13,6 +13,7 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #============================================================================
 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
+# Copyright (C) 2005 XenSource Ltd
 #============================================================================
 
 """Handler for vnet operations.
@@ -22,7 +23,8 @@
 from xen.xend import sxp
 from xen.xend.XendError import XendError
 from xen.xend.XendLogging import log
-from xen.xend.xenstore import XenNode, DBMap, DBVar
+from xen.xend.xenstore.xstransact import xstransact
+
 
 def vnet_cmd(cmd):
     out = None
@@ -39,39 +41,40 @@
     
     vifctl_ops = {'up': 'vif.add', 'down': 'vif.del'}
 
-    __exports__ = [
-        DBVar('id',     ty='str'),
-        DBVar('dbid',   ty='str'),
-        DBVar('config', ty='sxpr'),
-       ]
-    
-    def __init__(self, db, config=None):
+    def __init__(self, dbpath, config=None):
         if config:
-            self.id = sxp.child_value(config, 'id')
-            self.id = str(self.id)
+            self.id = str(sxp.child_value(config, 'id'))
             self.dbid = self.id.replace(':', '-')
-            self.db = db.addChild(self.dbid)
+            self.dbpath = dbpath + '/' + self.dbid
             self.config = config
         else:
-            self.db = db
+            self.dbpath = dbpath
             self.importFromDB()
-            config = self.config
             
-        self.bridge = sxp.child_value(config, 'bridge')
+        self.bridge = sxp.child_value(self.config, 'bridge')
         if not self.bridge:
             self.bridge = "vnet%s" % self.id
-        self.vnetif = sxp.child_value(config, 'vnetif')
+        self.vnetif = sxp.child_value(self.config, 'vnetif')
         if not self.vnetif:
             self.vnetif = "vnif%s" % self.id
 
-    def saveToDB(self, save=False, sync=False):
-        self.db.saveDB(save=save, sync=sync)
 
     def exportToDB(self, save=False, sync=False):
-        self.db.exportToDB(self, fields=self.__exports__, save=save, sync=sync)
+        to_store = {
+            'id' : self.id,
+            'dbid' : self.dbid,
+            'config' : sxp.to_string
+            }
+        xstransact.Write(self.dbpath, to_store)
+
 
     def importFromDB(self):
-        self.db.importFromDB(self, fields=self.__exports__)
+        (self.id, self.dbid, c) = xstransact.Gather(self.dbpath,
+                                                    ('id', str),
+                                                    ('dbid', str),
+                                                    ('config', str))
+        self.config = sxp.from_string(c)
+
 
     def sxpr(self):
         return self.config
@@ -88,7 +91,7 @@
         Brctl.vif_bridge_rem({'bridge': self.bridge, 'vif': self.vnetif})
         Brctl.bridge_del(self.bridge)
         val = vnet_cmd(['vnet.del', self.id])
-        self.db.delete()
+        xstransact.Remove(self.dbpath)
         return val
 
     def vifctl(self, op, vif, vmac):
@@ -107,18 +110,17 @@
     def __init__(self):
         # Table of vnet info indexed by vnet id.
         self.vnet = {}
-        self.db = DBMap(db=XenNode(self.dbpath))
-        self.db.readDB()
-        for vnetdb in self.db.values():
+        listing = xstransact.List(self.dbpath)
+        for entry in listing:
             try:
-                info = XendVnetInfo(vnetdb)
+                info = XendVnetInfo(self.dbpath + '/' + entry)
                 self.vnet[info.id] = info
                 info.configure()
             except XendError, ex:
                 log.warning("Failed to configure vnet %s: %s", str(info.id), 
str(ex))
             except Exception, ex:
                 log.exception("Vnet error")
-                vnetdb.delete()
+                xstransact.Remove(self.dbpath + '/' + entry)
 
     def vnet_of_bridge(self, bridge):
         """Get the vnet for a bridge (if any).
@@ -155,9 +157,9 @@
 
         @param config: config
         """
-        info = XendVnetInfo(self.db, config=config)
+        info = XendVnetInfo(self.dbpath, config=config)
         self.vnet[info.id] = info
-        info.saveToDB()
+        info.exportToDB()
         info.configure()
 
     def vnet_delete(self, id):
diff -r a73ab0ddf990 -r 70d5bfbf23d4 tools/python/xen/xend/xenstore/__init__.py
--- a/tools/python/xen/xend/xenstore/__init__.py        Sun Oct  2 17:21:01 2005
+++ b/tools/python/xen/xend/xenstore/__init__.py        Sun Oct  2 17:22:22 2005
@@ -14,5 +14,3 @@
 #============================================================================
 # Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
 #============================================================================
-from xsnode import *
-from xsobj import *
diff -r a73ab0ddf990 -r 70d5bfbf23d4 tools/python/xen/xend/xenstore/xsnode.py
--- a/tools/python/xen/xend/xenstore/xsnode.py  Sun Oct  2 17:21:01 2005
+++ /dev/null   Sun Oct  2 17:22:22 2005
@@ -1,477 +0,0 @@
-#============================================================================
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of version 2.1 of the GNU Lesser General Public
-# License as published by the Free Software Foundation.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-#============================================================================
-# Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
-#============================================================================
-import errno
-import os
-import os.path
-import select
-import socket
-import sys
-import threading
-import time
-
-from xen.lowlevel import xs
-from xen.xend import sxp
-from xen.xend.PrettyPrint import prettyprint
-
-SELECT_TIMEOUT = 2.0
-
-def getEventPath(event):
-    if event and event.startswith("/"):
-        event = event[1:]
-    return os.path.join("/event", event)
-
-def getEventIdPath(event):
-    return os.path.join(getEventPath(event), "@eid")
-
-class Subscription:
-
-    def __init__(self, path, fn, sid):
-        self.path = path
-        self.watcher = None
-        self.fn = fn
-        self.sid = sid
-
-    def getPath(self):
-        return self.path
-
-    def getSid(self):
-        return self.sid
-
-    def watch(self, watcher):
-        self.watcher = watcher
-        watcher.addSubs(self)
-
-    def unwatch(self):
-        watcher = self.watcher
-        if watcher:
-            self.watcher = None
-            watcher.delSubs(self)
-        return watcher
-
-    def notify(self, token, path, val):
-        try:
-            self.fn(self, token, path, val)
-        except SystemExit:
-            raise
-        except Exception, ex:
-            pass
-
-class Watcher:
-
-    def __init__(self, store, path):
-        self.path = path
-        store.mkdirs(self.path)
-        self.xs = None
-        self.subscriptions = []
-
-    def fileno(self):
-        if self.xs:
-            return self.xs.fileno()
-        else:
-            return -1
-
-    def getPath(self):
-        return self.path
-
-    def getToken(self):
-        return self.path
-
-    def addSubs(self, subs):
-        self.subscriptions.append(subs)
-        self.watch()
-
-    def delSubs(self, subs):
-        self.subscriptions.remove(subs)
-        if len(self.subscriptions) == 0:
-            self.unwatch()
-
-    def watch(self):
-        if self.xs: return
-        self.xs = xs.open()
-        self.xs.watch(path=self.getPath(), token=self.getToken())
-
-    def unwatch(self):
-        if self.xs:
-## Possibly crashes xenstored.
-##            try:
-##                self.xs.unwatch(path=self.getPath(), token=self.getToken())
-##            except Exception, ex:
-##                print 'Watcher>unwatch>', ex
-            try:
-                self.xs.close()
-            except Exception, ex:
-                pass
-            self.xs = None
-            
-    def watching(self):
-        return self.xs is not None
-
-    def getNotification(self):
-        p = self.xs.read_watch()
-        self.xs.acknowledge_watch(p[1])
-        return p
-
-    def notify(self):
-        try:
-            (path, token) = self.getNotification()
-            if path.endswith("@eid"):
-                pass
-            else:
-                val = self.xs.read(path)
-                for subs in self.subscriptions:
-                    subs.notify(token, path, val)
-        except SystemExit:
-            raise
-        except Exception, ex:
-            raise
-
-class EventWatcher(Watcher):
-
-    def __init__(self, store, path, event):
-        Watcher.__init__(self, store, path)
-        self.event = event
-        self.eidPath = getEventIdPath(event)
-        if not store.exists(self.eidPath):
-            store.write(self.eidPath, str(0))
-
-    def getEvent(self):
-        return self.event
-
-    def getToken(self):
-        return self.event
-
-class XenStore:
-
-    xs = None
-    watchThread = None
-    subscription_id = 1
-    
-    def __init__(self):
-        self.subscriptions = {}
-        self.watchers = {}
-        self.write("/", "")
-
-    def getxs(self):
-        if self.xs is None:
-            ex = None
-            for i in range(0,20):
-                try:
-                    self.xs = xs.open()
-                    ex = None
-                    break
-                except SystemExit:
-                    raise
-                except Exception, ex:
-                    print >>sys.stderr, "Exception connecting to xenstored:", 
ex
-                    print >>sys.stderr, "Trying again..."
-                    time.sleep(1)
-            else:
-                raise ex
-            
-        #todo would like to reconnect if xs conn closes (e.g. daemon restart).
-        return self.xs
-
-    def dump(self, path="/", out=sys.stdout):
-        print 'dump>', path
-        val = ['node']
-        val.append(['path',  path])
-##         perms = ['perms']
-##         for p in self.getPerms(path):
-##             l = ['perm']
-##             l.append('dom', p.get['dom'])
-##             for k in ['read', 'write', 'create', 'owner']:
-##                 v = p.get(k)
-##                 l.append([k, v])
-##             perms.append(l)
-##         val.append(perms)
-        data = self.read(path)
-        if data:
-            val.append(['data',  data])
-        children = ['children']
-        for x in self.lsPaths(path):
-            print 'dump>', 'child=', x
-            children.append(self.dump(x))
-        if len(children) > 1:
-            val.append(children)
-        prettyprint(val, out=out)
-        return val
-
-    def getPerms(self, path):
-        return self.getxs().get_permissions(path)
-
-    def ls(self, path="/"):
-        return self.getxs().ls(path)
-
-    def lsPaths(self, path="/"):
-        return [ os.path.join(path, x) for x in self.ls(path) ]
-
-    def lsr(self, path="/", list=None):
-        if list is None:
-            list = []
-        list.append(path)
-        for x in self.lsPaths(path):
-            list.append(x)
-            self.lsr(x, list=list)
-        return list
-
-    def rm(self, path):
-        try:
-            #for x in self.lsPaths():
-            #    self.getxs().rm(x)
-            self.getxs().rm(path)
-        except:
-            pass
-
-    def exists(self, path):
-        try:
-            self.getxs().ls(path)
-            return True
-        except RuntimeError, ex:
-            if ex.args[0] == errno.ENOENT:
-                return False
-            else:
-                raise RuntimeError(ex.args[0],
-                                   ex.args[1] +
-                                   (', in exists(%s)' % (str(path))))
-
-    def mkdirs(self, path):
-        if self.exists(path):
-            return
-        elts = path.split("/")
-        p = "/"
-        for x in elts:
-            if x == "": continue
-            p = os.path.join(p, x)
-            if not self.exists(p):
-                self.getxs().write(p, "")
-
-    def read(self, path):
-        try:
-            return self.getxs().read(path)
-        except RuntimeError, ex:
-            if ex.args[0] == errno.EISDIR:
-                return None
-            else:
-                raise
-
-    def create(self, path):
-        self.write(path, "")
-
-    def write(self, path, data):
-        try:
-            self.getxs().write(path, data)
-        except RuntimeError, ex:
-            raise RuntimeError(ex.args[0],
-                               ex.args[1] +
-                               (', while writing %s : %s' % (str(path),
-                                                             str(data))))
-
-    def begin(self):
-        self.getxs().transaction_start()
-
-    def commit(self, abandon=False):
-        self.getxs().transaction_end(abort=abandon)
-
-    def watch(self, path, fn):
-        watcher = self.watchers.get(path)
-        if not watcher:
-            watcher = self.addWatcher(Watcher(self, path))
-        return self.addSubscription(watcher, fn)
-        
-    def unwatch(self, sid):
-        s = self.subscriptions.get(sid)
-        if not s: return
-        del self.subscriptions[s.sid]
-        watcher = s.unwatch()
-        if watcher and not watcher.watching():
-            try:
-                del self.watchers[watcher.getPath()]
-            except:
-                pass
-
-    def subscribe(self, event, fn):
-        path = getEventPath(event)
-        watcher = self.watchers.get(path)
-        if not watcher:
-            watcher = self.addWatcher(EventWatcher(self, path, event))
-        return self.addSubscription(watcher, fn)
-
-    unsubscribe = unwatch
-
-    def sendEvent(self, event, data):
-        eventPath = getEventPath(event)
-        eidPath = getEventIdPath(event)
-        try:
-            #self.begin(eventPath)
-            self.mkdirs(eventPath)
-            eid = 1
-            if self.exists(eidPath):
-                try:
-                    eid = int(self.read(eidPath))
-                    eid += 1
-                except Exception, ex:
-                    pass
-            self.write(eidPath, str(eid))
-            self.write(os.path.join(eventPath, str(eid)), data)
-        finally:
-            #self.commit()
-            pass
-
-    def addWatcher(self, watcher):
-        self.watchers[watcher.getPath()] = watcher
-        self.watchStart()
-        return watcher
-
-    def addSubscription(self, watcher, fn):
-        self.subscription_id += 1
-        subs = Subscription(watcher.getPath(), fn, self.subscription_id)
-        self.subscriptions[subs.sid] = subs
-        subs.watch(watcher)
-        return subs.sid
-
-    def watchStart(self):
-        if self.watchThread: return
-        self.watchThread = threading.Thread(name="Watcher",
-                                            target=self.watchMain)
-        self.watchThread.setDaemon(True)
-        self.watchThread.start()
-        
-    def watchMain(self):
-        try:
-            while True:
-                if self.watchThread is None: return
-                if not self.watchers:
-                    return
-                rd = self.watchers.values()
-                try:
-                    (srd, swr, ser) = select.select(rd, [], [], SELECT_TIMEOUT)
-                    for watcher in srd:
-                        watcher.notify()
-                except socket.error, ex:
-                    if ex.args[0] in (EAGAIN, EINTR):
-                        pass
-                    else:
-                        raise
-        finally:
-            self.watchThread = None
-
-def getXenStore():
-    global xenstore
-    try:
-        return xenstore
-    except:
-        xenstore = XenStore()
-        return xenstore
-
-def sendEvent(event, val):
-    getXenStore.sendEvent(event, val)
-
-def subscribe(event, fn):
-    return getXenStore().subscribe(event, fn)
-
-def unsubscribe(sid):
-    getXenStore().unsubscribe(sid)
-
-class XenNode:
-
-    def __init__(self, path="/", create=True):
-        self.store = getXenStore()
-        self.path = path
-        if not self.store.exists(path):
-            if create:
-                self.store.create(path)
-            else:
-                raise ValueError("path does not exist: '%s'" % path)
-
-    def getStore(self):
-        return self.store
-
-    def relPath(self, path=""):
-        if not path:
-            return self.path
-        if path and path.startswith("/"):
-            path = path[1:]
-        return os.path.join(self.path, path)
-
-    def delete(self, path=""):
-        self.store.rm(self.relPath(path))
-
-    def exists(self, path=""):
-        return self.store.exists(self.relPath(path))
-
-    def getNode(self, path="", create=True):
-        if path == "":
-            return self
-        else:
-            return XenNode(self.relPath(path=path), create=create)
-
-    getChild = getNode
-
-    def getData(self, path=""):
-        path = self.relPath(path)
-        try:
-            return self.store.read(path)
-        except:
-            return None
-
-    def setData(self, data, path=""):
-        return self.store.write(self.relPath(path), data)
-
-    def getLock(self):
-        return None
-
-    def lock(self, lockid):
-        return None
-
-    def unlock(self, lockid):
-        return None
-
-    def deleteChild(self, name):
-        self.delete(name)
-
-    def deleteChildren(self):
-        for name in self.ls():
-            self.deleteChild(name)
-
-    def getChildren(self):
-        return [ self.getNode(name) for name in self.ls() ]
-
-    def ls(self):
-        return self.store.ls(self.path)
-
-    def watch(self, fn, path=""):
-        """Watch a path for changes. The path is relative
-        to the node and defaults to the node itself.
-        """
-        return self.store.watch(self.relPath(path), fn)
-
-    def unwatch(self, sid):
-        return self.store.unwatch(sid)
-
-    def subscribe(self, event, fn):
-        return self.store.subscribe(event, fn)
-
-    def unsubscribe(self, sid):
-        self.store.unsubscribe(sid)
-
-    def sendEvent(self, event, data):
-        return self.store.sendEvent(event, data)
-
-    def __repr__(self):
-        return "<XenNode %s>" % self.path
-
-
diff -r a73ab0ddf990 -r 70d5bfbf23d4 tools/python/xen/xend/xenstore/xsobj.py
--- a/tools/python/xen/xend/xenstore/xsobj.py   Sun Oct  2 17:21:01 2005
+++ /dev/null   Sun Oct  2 17:22:22 2005
@@ -1,537 +0,0 @@
-#============================================================================
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of version 2.1 of the GNU Lesser General Public
-# License as published by the Free Software Foundation.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-#============================================================================
-# Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
-#============================================================================
-import string
-import types
-
-from xen.xend.XendLogging import log
-
-from xen.xend import sxp
-from xsnode import XenNode
-from xen.util.mac import macToString, macFromString
-
-VALID_KEY_CHARS = string.ascii_letters + string.digits + "_-@"
-
-def hasAttr(obj, attr):
-    if isinstance(obj, dict):
-        return obj.contains(attr)
-    else:
-        return hasattr(obj, attr)
-
-def getAttr(obj, attr):
-    try:
-        if isinstance(obj, dict):
-            return obj.get(attr)
-        else:
-            return getattr(obj, attr, None)
-    except AttributeError:
-        return None
-    except LookupError:
-        return None
-
-def setAttr(obj, attr, val):
-    if isinstance(obj, dict):
-        obj[attr] = val
-    else:
-        setattr(obj, attr, val)
-
-class DBConverter:
-    """Conversion of values to and from strings in xenstore.
-    """
-
-    converters = {}
-
-    def checkType(cls, ty):
-        if ty is None or ty in cls.converters:
-            return
-        raise ValueError("invalid converter type: '%s'" % ty)
-
-    checkType = classmethod(checkType)
-    
-    def getConverter(cls, ty=None):
-        if ty is None:
-            ty = "str"
-        conv = cls.converters.get(ty)
-        if not conv:
-            raise ValueError("no converter for type: '%s'" % ty)
-        return conv
-
-    getConverter = classmethod(getConverter)
-
-    def exportTypeToDB(cls, db, path, val, ty=None):
-        return cls.getConverter(ty).exportToDB(db, path, val)
-
-    exportTypeToDB = classmethod(exportTypeToDB)
-
-    def importTypeFromDB(cls, db, path, ty=None):
-        return cls.getConverter(ty).importFromDB(db, path)
-
-    importTypeFromDB = classmethod(importTypeFromDB)
-
-    # Must define in subclass.
-    name = None
-
-    def __init__(self):
-        self.register()
-    
-    def register(self):
-        if not self.name:
-            raise ValueError("invalid converter name: '%s'" % self.name)
-        self.converters[self.name] = self
-
-    def exportToDB(self, db, path, val):
-        if val is None:
-            return
-        try:
-            data = self.toDB(val)
-        except Exception, ex:
-            raise
-        setattr(db, path, data)
-
-    def importFromDB(self, db, path):
-        data = getAttr(db, path)
-        if data is None:
-            val = None
-        else:
-            try:
-                val = self.fromDB(data.getData())
-            except Exception, ex:
-                raise
-        return val
-        
-    def toDB(self, val):
-        raise NotImplementedError()
-
-    def fromDB(self, val):
-        raise NotImplementedError()
-
-class StrConverter(DBConverter):
-
-    name = "str"
-    
-    def toDB(self, val):
-        # Convert True/False to 1/0, otherwise they convert to
-        # 'True' and 'False' rather than '1' and '0', even though
-        # isinstance(True/False, int) is true.
-        if isinstance(val, bool):
-            val = int(val)
-        return str(val)
-
-    def fromDB(self, data):
-        return data
-
-StrConverter()
-    
-class BoolConverter(DBConverter):
-
-    name = "bool"
-
-    def toDB(self, val):
-        return str(int(bool(val)))
-
-    def fromDB(self, data):
-        return bool(int(data))
-
-BoolConverter()
-
-class SxprConverter(DBConverter):
-
-    name = "sxpr"
-    
-    def toDB(self, val):
-        return sxp.to_string(val)
-
-    def fromDB(self, data):
-        return sxp.from_string(data)
-    
-SxprConverter()
-
-class IntConverter(DBConverter):
-
-    name = "int"
-    
-    def toDB(self, val):
-        return str(int(val))
-
-    def fromDB(self, data):
-        return int(data)
-    
-IntConverter()
-    
-class FloatConverter(DBConverter):
-
-    name = "float"
-    
-    def toDB(self, val):
-        return str(float(val))
-
-    def fromDB(self, data):
-        return float(data)
-    
-FloatConverter()
-    
-class LongConverter(DBConverter):
-
-    name = "long"
-    
-    def toDB(self, val):
-        return str(long(val))
-
-    def fromDB(self, data):
-        return long(data)
-    
-LongConverter()
-
-class MacConverter(DBConverter):
-
-    name = "mac"
-    
-    def toDB(self, val):
-        return macToString(val)
-
-    def fromDB(self, data):
-        return macFromString(data)
-    
-MacConverter()
-
-class DBVar:
-
-    def __init__(self, var, ty=None, path=None):
-        DBConverter.checkType(ty)
-        if path is None:
-            path = var
-        self.var = var
-        self.ty = ty
-        self.path = path
-        varpath = filter(bool, self.var.split())
-        self.attrpath = varpath[:-1]
-        self.attr = varpath[-1]
-
-    def exportToDB(self, db, obj):
-        val = self.getObj(obj)
-        DBConverter.exportTypeToDB(db, self.path, val, ty=self.ty)
-
-    def importFromDB(self, db, obj):
-        val = DBConverter.importTypeFromDB(db, self.path, ty=self.ty)
-        self.setObj(obj, val)
-
-    def getObj(self, obj):
-        o = obj
-        for x in self.attrpath:
-            o = getAttr(o, x)
-            if o is None:
-                return None
-        return getAttr(o, self.attr)
-
-    def setObj(self, obj, val):
-        o = obj
-        for x in self.attrpath:
-            o = getAttr(o, x)
-        # Don't set obj attr if val is None.
-        if val is None and hasAttr(o, self.attr):
-            return
-        setAttr(o, self.attr, val)
-
-class DBMap(dict):
-    """A persistent map. Extends dict with persistence.
-    Set and get values using the usual map syntax:
-
-    m[k],     m.get(k)
-    m[k] = v
-
-    Also supports being treated as an object with attributes.
-    When 'k' is a legal identifier you may also use
-
-    m.k,     getattr(m, k)
-    m.k = v, setattr(m, k)
-    k in m,  hasattr(m, k)
-
-    When setting you can pass in a normal value, for example
-
-    m.x = 3
-
-    Getting works too:
-
-    m.x ==> 3
-
-    while m['x'] will return the map for x.
-
-    m['x'].getData() ==> 3
-    
-    To get values from subdirs use get() to get the subdir first:
-
-    get(m, 'foo').x
-    m['foo'].x
-
-    instead of m.foo.x, because m.foo will return the data for field foo,
-    not the directory.
-
-    You can assign values into a subdir by passing a map:
-
-    m.foo = {'x': 1, 'y':2 }
-
-    You can also use paths as keys:
-
-    m['foo/x'] = 1
-
-    sets field x in subdir foo.
-    
-    """
-
-    __db__          = None
-    __data__        = None
-    __perms__       = None
-    __parent__      = None
-    __name__        = ""
-
-    __transaction__ = False
-
-    # True if value set since saved (or never saved).
-    __dirty__       = True
-
-    def __init__(self, parent=None, name="", db=None):
-        if parent is None:
-            self.__name__ = name
-        else:
-            if not isinstance(parent, DBMap):
-                raise ValueError("invalid parent")
-            self.__parent__ = parent
-            self.__name__ = name
-            db = self.__parent__.getChildDB(name)
-        self.setDB(db)
-
-    def getName(self):
-        return self.__name__
-
-    def getPath(self):
-        return self.__db__ and self.__db__.relPath()
-
-    def watch(self, fn, path=""):
-        return self.__db__.watch(fn, path=path)
-
-    def unwatch(self, sid):
-        return self.__db__.unwatch(sid)
-
-    def subscribe(self, event, fn):
-        return self.__db__.subscribe(event, fn)
-
-    def unsubscribe(self, sid):
-        return self.__db__.unsubscribe(sid)
-
-    def sendEvent(self, event, val):
-        return self.__db__.sendEvent(event, val)
-        
-    def transactionBegin(self):
-        # Begin a transaction.
-        pass
-
-    def transactionCommit(self):
-        # Commit writes to db.
-        pass
-
-    def transactionFail(self):
-        # Fail a transaction.
-        # We have changed values, what do we do?
-        pass
-
-    def checkName(self, k):
-        if k == "":
-            raise ValueError("invalid key, empty string")
-        for c in k:
-            if c in VALID_KEY_CHARS: continue
-            raise ValueError("invalid key char '%s'" % c)
-
-    def _setData(self, v):
-        #print 'DBMap>_setData>', self.getPath(), 'data=', v
-        if v != self.__data__:
-            self.__dirty__ = True
-        self.__data__ = v
-
-    def setData(self, v):
-        if isinstance(v, dict):
-            for (key, val) in v.items():
-                self[key] = val
-        else:
-            self._setData(v)
-
-    def getData(self):
-        return self.__data__
-
-    def _set(self, k, v):
-        dict.__setitem__(self, k, v)
-
-    def _get(self, k):
-        try:
-            return dict.__getitem__(self, k)
-        except:
-            return None
-
-    def _del(self, k, v):
-        try:
-            dict.__delitem__(self, k)
-        except:
-            pass
-
-    def _contains(self, k):
-        return dict.__contains__(self, k)
-        
-    def __setitem__(self, k, v, save=False):
-        node = self.addChild(k)
-        node.setData(v)
-        if save:
-            node.saveDB()
-
-    def __getitem__(self, k):
-        if self._contains(k):
-            v = self._get(k)
-        else:
-            v = self.readChildDB(k)
-            self._set(k, v)
-        return v
-
-    def __delitem__(self, k):
-        self._del(k)
-        self.deleteChildDB(k)
-
-    def __repr__(self):
-        if len(self):
-            return dict.__repr__(self)
-        else:
-            return repr(self.__data__)
-
-    def __setattr__(self, k, v):
-        if k.startswith("__"):
-            object.__setattr__(self, k, v)
-        else:
-            self.__setitem__(k, v, save=True)
-        return v
-    
-    def __getattr__(self, k):
-        if k.startswith("__"):
-            v = object.__getattr__(self, k)
-        else:
-            try:
-                v = self.__getitem__(k).getData()
-            except LookupError, ex:
-                raise AttributeError(ex.args)
-        return v
-
-    def __delattr__(self, k):
-        return self.__delitem__(k)
-
-    def delete(self):
-        dict.clear(self)
-        self.__data__ = None
-        if self.__db__:
-            self.__db__.delete()
-
-    def clear(self):
-        dict.clear(self)
-        if self.__db__:
-            self.__db__.deleteChildren()
-
-    def getChild(self, k):
-        return self._get(k)
-
-    def getChildDB(self, k):
-        self.checkName(k)
-        return self.__db__ and self.__db__.getChild(k)
-
-    def deleteChildDB(self, k):
-        if self.__db__:
-            self.__db__.deleteChild(k)
-
-    def _addChild(self, k):
-        kid = self._get(k)
-        if kid is None:
-            kid = DBMap(parent=self, name=k, db=self.getChildDB(k))
-            self._set(k, kid)
-        return kid
-
-    def addChild(self, path):
-        l = path.split("/")
-        n = self
-        for x in l:
-            if x == "": continue
-            n = n._addChild(x)
-        return n
-
-    def setDB(self, db):
-        if (db is not None) and not isinstance(db, XenNode):
-            raise ValueError("invalid db")
-        self.__db__ = db
-        for (k, v) in self.items():
-            if v is None: continue
-            if isinstance(v, DBMap):
-                v._setDB(self.addChild(k), restore)
-
-    def readDB(self):
-        if self.__db__ is None:
-            return
-        self.__data__ = self.__db__.getData()
-        l = self.__db__.ls()
-        if l:
-            for k in l:
-                n = self.addChild(k)
-                n.readDB()
-        self.__dirty__ = False
-
-    def readChildDB(self, k):
-        if self.__db__ and (k in self.__db__.ls()):
-            n = self.addChild(k)
-            n.readDB()
-        raise LookupError("invalid key '%s'" % k)
-
-    def saveDB(self, sync=False, save=False):
-        """Save unsaved data to db.
-        If save or sync is true, saves whether dirty or not.
-        If sync is true, removes db entries not in the map.
-        """
-        
-        if self.__db__ is None:
-            #print 'DBMap>saveDB>',self.getPath(), 'no db'
-            return
-        # Write data.
-        #print 'DBMap>saveDB>', self.getPath(), 'dirty=', self.__dirty__, 
'data=', self.__data__
-        if ((self.__data__ is not None)
-            and (sync or save or self.__dirty__)):
-            self.__db__.setData(self.__data__)
-            self.__dirty__ = False
-        else:
-            #print 'DBMap>saveDB>', self.getPath(), 'not written'
-            pass
-        # Write children.
-        for (name, node) in self.items():
-            if not isinstance(node, DBMap): continue
-            node.saveDB(sync=sync, save=save)
-        # Remove db nodes not in children.
-        ###if sync:
-        ###    for name in self.__db__.ls():
-        ###        if name not in self:
-        ###            self.__db__.delete(name)
-
-    def importFromDB(self, obj, fields):
-        """Set fields in obj from db fields.
-        """
-        for f in fields:
-            f.importFromDB(self, obj)
-
-    def exportToDB(self, obj, fields, save=False, sync=False):
-        """Set fields in db from obj fields.
-        """
-        for f in fields:
-            f.exportToDB(self, obj)
-        self.saveDB(save=save, sync=sync)
diff -r a73ab0ddf990 -r 70d5bfbf23d4 
tools/python/xen/xend/xenstore/xsresource.py
--- a/tools/python/xen/xend/xenstore/xsresource.py      Sun Oct  2 17:21:01 2005
+++ /dev/null   Sun Oct  2 17:22:22 2005
@@ -1,149 +0,0 @@
-#============================================================================
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of version 2.1 of the GNU Lesser General Public
-# License as published by the Free Software Foundation.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-#============================================================================
-# Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
-#============================================================================
-# HTTP interface onto xenstore (read-only).
-# Mainly intended for testing.
-
-import os
-import os.path
-
-from xen.web.httpserver import HttpServer, UnixHttpServer
-from xen.web.SrvBase import SrvBase
-from xen.web.SrvDir import SrvDir
-from xen.xend.Args import FormFn
-from xen.xend.xenstore import XenNode
-
-def pathurl(req):
-    url = req.prePathURL()
-    if not url.endswith('/'):
-        url += '/'
-    return url
-    
-def writelist(req, l):
-    req.write('(')
-    for k in l:
-       req.write(' ' + k)
-    req.write(')')
-
-def lsData(dbnode, req, url):
-    v = dbnode.getData()
-    if v is None:
-        req.write('<p>No data')
-    else:
-        req.write('<p>Data: <pre>')
-        req.write(str(v))
-        req.write('</pre>')
-    v = dbnode.getLock()
-    if v is None:
-        req.write("<p>Unlocked")
-    else:
-        req.write("<p>Lock = %s" % v)
-
-def lsChildren(dbnode, req, url):
-    l = dbnode.ls()
-    if l:
-        req.write('<p>Children: <ul>')
-        for key in l:
-            child = dbnode.getChild(key)
-            data = child.getData()
-            if data is None: data = ""
-            req.write('<li><a href="%(url)s%(key)s">%(key)s</a> %(data)s</li>'
-                      % { "url": url, "key": key, "data": data })
-        req.write('</ul>')
-    else:
-        req.write('<p>No children')
-        
-
-class DBDataResource(SrvBase):
-    """Resource for the node data.
-    """
-
-    def __init__(self, dbnode):
-        SrvBase.__init__(self)
-        self.dbnode = dbnode
-
-    def render_GET(self, req):
-        req.write('<html><head></head><body>')
-        self.print_path(req)
-        req.write("<pre>")
-        req.write(self.getData() or self.getNoData())
-        req.write("</pre>")
-        req.write('</body></html>')
-
-    def getContentType(self):
-        # Use content-type from metadata.
-        return "text/plain"
-
-    def getData(self):
-        v = self.dbnode.getData()
-        if v is None: return v
-        return str(v)
-
-    def getNoData(self):
-        return ""
-
-class DBNodeResource(SrvDir):
-    """Resource for a DB node.
-    """
-
-    def __init__(self, dbnode):
-        SrvDir.__init__(self)
-        self.dbnode = dbnode
-
-    def get(self, x):
-        val = None
-        if x == "__data__":
-            val = DBDataResource(self.dbnode)
-        else:
-            if self.dbnode.exists(x):
-                child = self.dbnode.getChild(x, create=False)
-            else:
-                child = None
-            if child is not None:
-                val = DBNodeResource(child)
-        return val
-
-    def render_POST(self, req):
-        return self.perform(req)
-
-    def ls(self, req, use_sxp=0):
-        if use_sxp:
-            writelist(req, self.dbnode.getChildren())
-        else:
-            url = pathurl(req)
-            req.write("<fieldset>")
-            lsData(self.dbnode, req, url)
-            lsChildren(self.dbnode, req, url)
-            req.write("</fieldset>")
-
-    def form(self, req):
-        url = req.prePathURL()
-        pass
-        
-class DBRootResource(DBNodeResource):
-    """Resource for the root of a DB.
-    """
-
-    def __init__(self):
-        DBNodeResource.__init__(self, XenNode())
-
-def main(argv):
-    root = SrvDir()
-    root.putChild('xenstore', DBRootResource())
-    interface = ''
-    port = 8003
-    server = HttpServer(root=root, interface=interface, port=port)
-    server.run()

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.