1 import sys, types, string, os
6 # ============================================================
7 # XML processing and query
13 self.lookup_uuid_cache = {}
14 self.lookup_name_cache = {}
15 self.lookup_class_cache = {}
16 self.lookup_val_cache = {}
17 self.lookup_refs_cache = {}
18 self.lookup_lovtgts_cache = {}
19 self.lookup_nid2srv_cache = {}
20 self.lookup_activedev_cache = {}
21 self.lookup_tgtdev_cache = {}
22 self.lookup_group_cache = {}
24 self.lookup_allrefs_cache = None
25 self.lookup_networks_cache = None
27 def lookup(self, uuid):
28 """ lookup returns a new LustreDB instance"""
29 if self.caching_enabled and self.lookup_uuid_cache.has_key(uuid):
30 res = self.lookup_uuid_cache[uuid]
32 res = self._lookup_by_uuid(uuid)
33 if self.caching_enabled:
34 self.lookup_uuid_cache[uuid] = res
37 def lookup_name(self, name, class_name = ""):
38 """ lookup returns a new LustreDB instance"""
39 if self.caching_enabled and self.lookup_name_cache.has_key((name, class_name)):
40 res = self.lookup_name_cache[(name, class_name)]
42 res = self._lookup_by_name(name, class_name)
43 if self.caching_enabled:
44 self.lookup_name_cache[(name, class_name)] = res
47 def lookup_class(self, class_name):
48 """ lookup returns a new LustreDB instance"""
49 if self.caching_enabled and self.lookup_class_cache.has_key(class_name):
50 res = self.lookup_class_cache[class_name]
52 res = self._lookup_by_class(class_name)
53 if self.caching_enabled:
54 self.lookup_class_cache[class_name] = res
57 def get_val(self, tag, default=None):
58 if self.caching_enabled and self.lookup_class_cache.has_key(tag):
59 v = self.lookup_val_cache[tag]
61 v = self._get_val(tag)
62 if self.caching_enabled:
63 self.lookup_val_cache[tag] = v
71 return self._get_class()
73 def get_val_int(self, tag, default=0):
74 str = self.get_val(tag)
80 raise Lustre.LconfError("text value is not integer: " + str)
82 def get_first_ref(self, tag):
83 """ Get the first uuidref of the type TAG. Only
84 one is expected. Returns the uuid."""
85 uuids = self.get_refs(tag)
90 def get_refs(self, tag):
91 """ Get all the refs of type TAG. Returns list of uuids. """
92 if self.caching_enabled and self.lookup_refs_cache.has_key(tag):
93 uuids = self.lookup_refs_cache[tag]
95 uuids = self._get_refs(tag)
96 if self.caching_enabled:
97 self.lookup_refs_cache[tag] = uuids
100 def get_all_refs(self):
101 """ Get all the refs. Returns list of uuids. """
102 if self.caching_enabled and self.lookup_allrefs_cache:
103 uuids = self.lookup_allrefs_cache
105 uuids = self._get_all_refs()
106 if self.caching_enabled:
107 self.lookup_allrefs_cache = uuids
110 def get_lov_tgts(self, tag):
111 """ Returns list of lov tgts. """
112 if self.caching_enabled and self.lookup_lovtgts_cache.has_key(tag):
113 tgts = self.lookup_lovtgts_cache[tag]
115 tgts = self._get_lov_tgts(tag)
116 if self.caching_enabled:
117 self.lookup_lovtgts_cache[tag] = tgts
120 def nid2server(self, nid, net_type, cluster_id):
121 if self.caching_enabled and self.lookup_nid2srv_cache.has_key((nid, net_type, cluster_id)):
122 res = self.lookup_nid2srv_cache[(nid, net_type, cluster_id)]
124 netlist = self.lookup_class('network')
125 for net_db in netlist:
126 if (net_db.get_val('nid') == nid and
127 net_db.get_val('nettype') == net_type and
128 net_db.get_val('clusterid') == cluster_id):
131 if self.caching_enabled:
132 self.lookup_nid2srv_cache[(nid, net_type, cluster_id)] = res
135 # Find the target_device for target on a node
136 # node->profiles->device_refs->target
137 def get_node_tgt_dev(self, node_name, target_uuid):
138 node_db = self.lookup_name(node_name)
141 return node_db.get_tgt_dev(target_uuid)
143 # get all network uuids for this node
144 def get_networks(self):
145 if self.caching_enabled and self.lookup_networks_cache:
146 ret = self.lookup_networks_cache
149 prof_list = self.get_refs('profile')
150 for prof_uuid in prof_list:
151 prof_db = self.lookup(prof_uuid)
152 net_list = prof_db.get_refs('network')
153 for net_uuid in net_list:
155 if self.caching_enabled:
156 self.lookup_networks_cache = ret
159 def get_active_dev(self, tgtuuid):
160 if self.caching_enabled and self.lookup_activedev_cache.has_key(tgtuuid):
161 tgt_dev_uuid = self.lookup_activedev_cache[tgtuuid]
163 tgt = self.lookup(tgtuuid)
164 tgt_dev_uuid = tgt.get_first_ref('active')
165 if self.caching_enabled:
166 self.lookup_activedev_cache[tgtuuid] = tgt_dev_uuid
169 def get_tgt_dev(self, tgtuuid):
170 if self.caching_enabled and self.lookup_tgtdev_cache.has_key(tgtuuid):
171 res = self.lookup_tgtdev_cache[tgtuuid]
173 prof_list = self.get_refs('profile')
175 for prof_uuid in prof_list:
176 prof_db = self.lookup(prof_uuid)
178 panic("profile:", profile, "not found.")
179 for ref_class, ref_uuid in prof_db.get_all_refs():
180 if ref_class in ('osd', 'mdsdev'):
181 devdb = self.lookup(ref_uuid)
182 uuid = devdb.get_first_ref('target')
188 if self.caching_enabled:
189 self.lookup_tgtdev_cache[tgtuuid] = res
192 def get_group(self, group):
193 if self.caching_enabled and self.lookup_group_cache.has_key(group):
194 ret = self.lookup_group_cache[group]
197 devs = self.lookup_class('mds')
199 if tgt.get_val('group', tgt.get_val('name')) == group:
200 ret.append(tgt.getUUID())
201 devs = self.lookup_class('ost')
203 if tgt.get_val('group', tgt.get_val('name')) == group:
204 ret.append(tgt.getUUID())
205 if self.caching_enabled:
206 self.lookup_group_cache[group] = ret
209 # Change the current active device for a target
210 def update_active(self, tgtuuid, new_uuid):
211 self._update_active(tgtuuid, new_uuid)
213 def get_version(self):
214 return self.get_val('version')
217 return self.get_val('mtime')
219 class LustreDB_XML(LustreDB):
220 def __init__(self, dom, root_node):
221 LustreDB.__init__(self)
225 self.root_node = root_node
231 def xmltext(self, dom_node, tag):
232 list = dom_node.getElementsByTagName(tag)
236 if dom_node.firstChild:
237 txt = string.strip(dom_node.firstChild.data)
241 def xmlattr(self, dom_node, attr):
242 return dom_node.getAttribute(attr)
244 def _get_val(self, tag):
245 """a value could be an attribute of the current node
246 or the text value in a child node"""
247 ret = self.xmlattr(self.dom_node, tag)
249 ret = self.xmltext(self.dom_node, tag)
252 def _get_class(self):
253 return self.dom_node.nodeName
255 def get_ref_type(self, ref_tag):
256 res = string.split(ref_tag, '_')
260 # [(ref_class, ref_uuid),]
261 def _get_all_refs(self):
263 for n in self.dom_node.childNodes:
264 if n.nodeType == n.ELEMENT_NODE:
265 ref_uuid = self.xml_get_ref(n)
266 ref_class = self.get_ref_type(n.nodeName)
267 list.append((ref_class, ref_uuid))
272 def _get_refs(self, tag):
273 """ Get all the refs of type TAG. Returns list of uuids. """
275 refname = '%s_ref' % tag
276 reflist = self.dom_node.getElementsByTagName(refname)
278 uuids.append(self.xml_get_ref(r))
281 def _get_lov_tgts(self, tag):
282 """ Get all the refs of type TAG. Returns list of lov_tgts. """
284 tgtlist = self.dom_node.getElementsByTagName(tag)
286 uuidref = tgt.getAttribute('uuidref')
287 index = tgt.getAttribute('index')
288 generation = tgt.getAttribute('generation')
289 active = int(tgt.getAttribute('active'))
290 tgts.append((uuidref, index, generation, active))
293 def xmllookup_by_uuid(self, dom_node, uuid):
294 for n in dom_node.childNodes:
295 if n.nodeType == n.ELEMENT_NODE:
296 if self.xml_get_uuid(n) == uuid:
299 n = self.xmllookup_by_uuid(n, uuid)
303 def _lookup_by_uuid(self, uuid):
304 dom = self. xmllookup_by_uuid(self.root_node, uuid)
306 return LustreDB_XML(dom, self.root_node)
308 def xmllookup_by_name(self, dom_node, name):
309 for n in dom_node.childNodes:
310 if n.nodeType == n.ELEMENT_NODE:
311 if self.xml_get_name(n) == name:
314 n = self.xmllookup_by_name(n, name)
318 def _lookup_by_name(self, name, class_name):
319 dom = self.xmllookup_by_name(self.root_node, name)
321 return LustreDB_XML(dom, self.root_node)
323 def xmllookup_by_class(self, dom_node, class_name):
324 return dom_node.getElementsByTagName(class_name)
326 def _lookup_by_class(self, class_name):
328 domlist = self.xmllookup_by_class(self.root_node, class_name)
330 ret.append(LustreDB_XML(node, self.root_node))
333 def xml_get_name(self, n):
334 return n.getAttribute('name')
337 return self.xml_get_name(self.dom_node)
339 def xml_get_ref(self, n):
340 return n.getAttribute('uuidref')
342 def xml_get_uuid(self, dom_node):
343 return dom_node.getAttribute('uuid')
346 return self.xml_get_uuid(self.dom_node)
348 # Convert routes from the router to a route that will be used
349 # on the local system. The network type and gw are changed to the
350 # interface on the router the local system will connect to.
351 def get_local_routes(self, type, gw):
352 """ Return the routes as a list of tuples of the form:
353 [(type, gw, lo, hi),]"""
355 tbl = self.dom_node.getElementsByTagName('routetbl')
357 routes = t.getElementsByTagName('route')
359 net_type = self.xmlattr(r, 'type')
361 lo = self.xmlattr(r, 'lo')
362 hi = self.xmlattr(r, 'hi')
363 tgt_cluster_id = self.xmlattr(r, 'tgtclusterid')
364 res.append((type, gw, tgt_cluster_id, lo, hi))
367 def get_route_tbl(self):
369 for r in self.dom_node.getElementsByTagName('route'):
370 net_type = self.xmlattr(r, 'type')
371 gw = self.xmlattr(r, 'gw')
372 gw_cluster_id = self.xmlattr(r, 'gwclusterid')
373 tgt_cluster_id = self.xmlattr(r, 'tgtclusterid')
374 lo = self.xmlattr(r, 'lo')
375 hi = self.xmlattr(r, 'hi')
376 ret.append((net_type, gw, gw_cluster_id, tgt_cluster_id, lo, hi))
379 def get_hostaddr(self):
381 list = self.dom_node.getElementsByTagName('hostaddr')
383 ret.append(node.firstChild.data)
386 def _update_active(self, tgt, new):
387 raise Lustre.LconfError("updates not implemented for XML")
389 # ================================================================
391 class LustreDB_LDAP(LustreDB):
392 def __init__(self, name, attrs,
395 url = "ldap://localhost",
396 user = "cn=Manager, fs=lustre",
399 LustreDB.__init__(self)
404 self._parent = parent
410 self._base = parent._base
417 self.l = ldap.initialize(self._url)
418 # Set LDAP protocol version used
419 self.l.protocol_version=ldap.VERSION3
420 # user and pw only needed if modifying db
421 self.l.bind_s(self._user, self._pw, ldap.AUTH_SIMPLE);
422 except ldap.LDAPError, e:
423 raise Lustre.LconfError('Unable to connect to ldap server:' + self._url)
426 self._name, self._attrs = self.l.search_s(self._base,
428 except ldap.LDAPError, e:
429 raise Lustre.LconfError("no config found in ldap: %s"
434 def ldap_search(self, filter):
435 """Return list of uuids matching the filter."""
441 for name, attrs in self.l.search_s(dn, ldap.SCOPE_ONELEVEL,
443 for v in attrs['uuid']:
445 except ldap.NO_SUCH_OBJECT, e:
447 except ldap.LDAPError, e:
448 print e # FIXME: die here?
451 ret.append(self._lookup_by_uuid(uuid))
454 def _lookup_by_name(self, name, class_name):
455 list = self.ldap_search("lustreName=%s" %(name))
460 def _lookup_by_class(self, class_name):
461 return self.ldap_search("objectclass=%s" %(string.upper(class_name)))
463 def _lookup_by_uuid(self, uuid):
465 dn = "uuid=%s,%s" % (uuid, self._base)
468 for name, attrs in self.l.search_s(dn, ldap.SCOPE_BASE,
470 ret = LustreDB_LDAP(name, attrs, parent = self)
472 except ldap.NO_SUCH_OBJECT, e:
473 pass # just return empty list
474 except ldap.LDAPError, e:
475 print e # FIXME: die here?
479 def _get_val(self, k):
483 if self._attrs.has_key(k):
485 if type(v) == types.ListType:
491 def _get_class(self):
492 return string.lower(self._attrs['objectClass'][0])
494 def get_ref_type(self, ref_tag):
497 def _get_lov_tgts(self, tag):
498 """ Get all the refs of type TAG. Returns list of lov_tgts. """
503 # [(ref_class, ref_uuid),]
504 def _get_all_refs(self):
506 for k in self._attrs.keys():
507 if re.search('.*Ref', k):
508 for uuid in self._attrs[k]:
509 ref_class = self.get_ref_type(k)
510 reflist.append((ref_class, uuid))
513 def _get_refs(self, tag):
514 """ Get all the refs of type TAG. Returns list of uuids. """
515 refname = '%sRef' % tag
517 if self._attrs.has_key(refname):
518 return self._attrs[refname]
521 for obj in self._lookup_by_class("*"):
522 if obj._attrs.has_key(refname):
523 reflist.extend(obj._attrs[refname])
528 return self._get_val('lustreName')
531 return self._get_val('uuid')
533 def get_route_tbl(self):
536 def get_hostaddr(self):
537 return self._get_refs('hostaddr')
539 def _update_active(self, tgtuuid, newuuid):
540 """Return list of uuids matching the filter."""
542 dn = "uuid=%s,%s" %(tgtuuid, self._base)
546 self.l.modify_s(dn, [(ldap.MOD_REPLACE, "activeRef", newuuid)])
547 except ldap.NO_SUCH_OBJECT, e:
549 except ldap.LDAPError, e:
550 print e # FIXME: die here?