xen-vt-testing

view tools/python/xen/xend/xenstore/xstransact.py @ 6711:1a27091a1e7a

Add remove and list support. Also make all class methods "safe".
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Fri Sep 09 17:34:40 2005 +0000 (2005-09-09)
parents 54af57682431
children 813c37b68376
line source
1 # Copyright (C) 2005 Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
3 # This file is subject to the terms and conditions of the GNU General
4 # Public License. See the file "COPYING" in the main directory of
5 # this archive for more details.
7 import errno
8 import threading
9 from xen.lowlevel import xs
11 handles = {}
13 # XXX need to g/c handles from dead threads
14 def xshandle():
15 if not handles.has_key(threading.currentThread()):
16 handles[threading.currentThread()] = xs.open()
17 return handles[threading.currentThread()]
19 class xstransact:
21 def __init__(self, path):
22 self.in_transaction = False
23 self.path = path.rstrip("/")
24 while True:
25 try:
26 xshandle().transaction_start(path)
27 self.in_transaction = True
28 return
29 except RuntimeError, ex:
30 if ex.args[0] == errno.ENOENT and path != "/":
31 path = "/".join(path.split("/")[0:-1]) or "/"
32 else:
33 raise
35 def __del__(self):
36 if self.in_transaction:
37 xshandle().transaction_end(True)
39 def commit(self):
40 if not self.in_transaction:
41 raise RuntimeError
42 self.in_transaction = False
43 return xshandle().transaction_end(False)
45 def abort(self):
46 if not self.in_transaction:
47 raise RuntimeError
48 self.in_transaction = False
49 return xshandle().transaction_end(True)
51 def _read(self, key):
52 path = "%s/%s" % (self.path, key)
53 return xshandle().read(path)
55 def read(self, *args):
56 if len(args) == 0:
57 raise TypeError
58 if len(args) == 1:
59 return self._read(args[0])
60 ret = []
61 for key in args:
62 ret.append(self._read(key))
63 return ret
65 def _write(self, key, data, create=True, excl=False):
66 path = "%s/%s" % (self.path, key)
67 xshandle().write(path, data, create=create, excl=excl)
69 def write(self, *args, **opts):
70 create = opts.get('create') or True
71 excl = opts.get('excl') or False
72 if len(args) == 0:
73 raise TypeError
74 if isinstance(args[0], dict):
75 for d in args:
76 if not isinstance(d, dict):
77 raise TypeError
78 for key in d.keys():
79 self._write(key, d[key], create, excl)
80 elif isinstance(args[0], list):
81 for l in args:
82 if not len(l) == 2:
83 raise TypeError
84 self._write(l[0], l[1], create, excl)
85 elif len(args) % 2 == 0:
86 for i in range(len(args) / 2):
87 self._write(args[i * 2], args[i * 2 + 1], create, excl)
88 else:
89 raise TypeError
91 def _remove(self, key):
92 path = "%s/%s" % (self.path, key)
93 return xshandle().rm(path)
95 def remove(self, *args):
96 if len(args) == 0:
97 raise TypeError
98 for key in args:
99 self._remove(key)
101 def _list(self, key):
102 path = "%s/%s" % (self.path, key)
103 return map(lambda x: key + "/" + x, xshandle().ls(path))
105 def list(self, *args):
106 if len(args) == 0:
107 raise TypeError
108 ret = []
109 for key in args:
110 ret.extend(self._list(key))
111 return ret
114 def Read(cls, path, *args):
115 while True:
116 try:
117 t = cls(path)
118 v = t.read(*args)
119 t.commit()
120 return v
121 except RuntimeError, ex:
122 if ex.args[0] == errno.ETIMEDOUT:
123 pass
124 raise
126 Read = classmethod(Read)
128 def Write(cls, path, *args, **opts):
129 while True:
130 try:
131 t = cls(path)
132 t.write(*args, **opts)
133 t.commit()
134 return
135 except RuntimeError, ex:
136 if ex.args[0] == errno.ETIMEDOUT:
137 pass
138 raise
140 Write = classmethod(Write)
142 def Remove(cls, *args):
143 while True:
144 try:
145 t = cls(path)
146 t.remove(*args)
147 t.commit()
148 return
149 except RuntimeError, ex:
150 if ex.args[0] == errno.ETIMEDOUT:
151 pass
152 raise
154 Remove = classmethod(Remove)
156 def List(cls, path, *args):
157 while True:
158 try:
159 t = cls(path)
160 v = t.list(*args)
161 t.commit()
162 return v
163 except RuntimeError, ex:
164 if ex.args[0] == errno.ETIMEDOUT:
165 pass
166 raise
168 List = classmethod(List)