[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |