2 # Copyright (C) 2002 Cluster File Systems, Inc.
3 # Author: Robert Read <rread@clusterfs.com>
5 # This file is part of Lustre, http://www.lustre.org.
7 # Lustre is free software; you can redistribute it and/or
8 # modify it under the terms of version 2 of the GNU General Public
9 # License as published by the Free Software Foundation.
11 # Lustre is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with Lustre; if not, write to the Free Software
18 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 lmc - lustre configurtion data manager
24 See lustre book for documentation for lmc.
28 import sys, os, getopt, string, exceptions
29 import xml.dom.minidom
30 from xml.dom.ext import PrettyPrint
35 print """usage: lmc --add object [object parameters]
37 Object creation command summary:
42 --recovery_upcall path
47 --nettype tcp|elan|toe|gm
78 --add mtpt - Mountpoint
82 --ost ost_name OR --lov lov_name
87 msg = string.join(map(str,args))
88 raise OptionError("Error: " + msg)
97 msg = string.join(map(str,args))
98 print "Warning: ", msg
101 # manage names and uuids
102 # need to initialize this by walking tree to ensure
103 # no duplicate names or uuids are created.
104 # this are just place holders for now.
105 # consider changing this to be like OBD-dev-host
109 while names.has_key(ret):
110 ret = "%s_%d" % (base, ctr)
116 return "%s_UUID" % (name)
119 ldlm_uuid = 'ldlm_UUID'
121 ptlrpc_name = 'RPCDEV'
122 ptlrpc_uuid = 'RPCDEV_UUID'
125 """Create a new empty lustre document"""
126 # adding ldlm here is a bit of a hack, but one is enough.
128 <ldlm name="%s" uuid="%s"/>
129 <ptlrpc name="%s" uuid="%s"/>
130 </lustre>""" % (ldlm_name, ldlm_uuid,
131 ptlrpc_name, ptlrpc_uuid)
132 return dom.parseString(str)
138 """initialize auto-name generation tables"""
140 # get all elements that contain a name attribute
141 for n in doc.childNodes:
142 if n.nodeType == n.ELEMENT_NODE:
144 names[getName(n)] = 1
145 uuids[getUUID(n)] = 1
148 def get_format_flag(options):
149 if options.has_key('format'):
150 if options['format']:
154 ############################################################
155 # Build config objects using DOM
160 def __init__(self, doc):
163 def ref(self, type, uuid):
164 """ generate <[type]_ref uuidref="[uuid]"/> """
165 tag = "%s_ref" % (type)
166 ref = self.doc.createElement(tag)
167 ref.setAttribute("uuidref", uuid)
170 def newService(self, tag, name, uuid):
171 """ create a new service elmement, which requires name and uuid attributes """
172 new = self.doc.createElement(tag)
173 new.setAttribute("uuid", uuid);
174 new.setAttribute("name", name);
177 def addText(self, node, str):
178 txt = self.doc.createTextNode(str)
179 node.appendChild(txt)
181 def addElement(self, node, tag, str=None):
182 """ create a new element and add it as a child to node. If str is passed,
183 a text node is created for the new element"""
184 new = self.doc.createElement(tag)
186 self.addText(new, str)
187 node.appendChild(new)
190 def network(self, name, uuid, nid, net, hostaddr="", port=0, tcpbuf=0, irq_aff=0, nid_xchg=0):
191 """create <network> node"""
192 network = self.newService("network", name, uuid)
193 network.setAttribute("nettype", net);
194 self.addElement(network, "nid", nid)
196 self.addElement(network, "hostaddr", hostaddr)
198 self.addElement(network, "port", "%d" %(port))
200 self.addElement(network, "sendmem", "%d" %(tcpbuf))
201 self.addElement(network, "recvmem", "%d" %(tcpbuf))
203 self.addElement(network, "irqaffinity", "%d" %(irq_aff))
205 self.addElement(network, "nidexchange", "%d" %(nid_xchg))
209 def routetbl(self, name, uuid):
210 """create <routetbl> node"""
211 rtbl = self.newService("routetbl", name, uuid)
214 def route(self, net_type, gw, lo, hi):
215 """ create one entry for the route table """
216 ref = self.doc.createElement('route')
217 ref.setAttribute("type", net_type)
218 ref.setAttribute("gw", gw)
219 ref.setAttribute("lo", lo)
221 ref.setAttribute("hi", hi)
224 def profile(self, name, uuid):
225 """ create a host """
226 profile = self.newService("profile", name, uuid)
229 def node(self, name, uuid, prof_uuid):
230 """ create a host """
231 node = self.newService("node", name, uuid)
232 node.appendChild(self.ref("profile", prof_uuid))
235 def ldlm(self, name, uuid):
236 """ create a ldlm """
237 ldlm = self.newService("ldlm", name, uuid)
240 def osd(self, name, uuid, fs, osdtype, devname, format, ost_uuid, node_uuid, dev_size=0):
241 osd = self.newService("osd", name, uuid)
242 osd.setAttribute('osdtype', osdtype)
243 osd.appendChild(self.ref("target", ost_uuid))
244 osd.appendChild(self.ref("node", node_uuid))
246 self.addElement(osd, "fstype", fs)
248 dev = self.addElement(osd, "devpath", devname)
249 self.addElement(osd, "autoformat", format)
251 self.addElement(osd, "devsize", "%s" % (dev_size))
254 def cobd(self, name, uuid, real_uuid, cache_uuid):
255 cobd = self.newService("cobd", name, uuid)
256 cobd.appendChild(self.ref("realobd",real_uuid))
257 cobd.appendChild(self.ref("cacheobd",cache_uuid))
260 def ost(self, name, uuid, osd_uuid):
261 ost = self.newService("ost", name, uuid)
262 ost.appendChild(self.ref("active", osd_uuid))
265 def oss(self, name, uuid):
266 oss = self.newService("oss", name, uuid)
269 def lov(self, name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern):
270 lov = self.newService("lov", name, uuid)
271 lov.appendChild(self.ref("mds", mds_uuid))
272 lov.setAttribute("stripesize", str(stripe_sz))
273 lov.setAttribute("stripecount", str(stripe_cnt))
274 lov.setAttribute("stripepattern", str(pattern))
277 def lovconfig(self, name, uuid, lov_uuid):
278 lovconfig = self.newService("lovconfig", name, uuid)
279 lovconfig.appendChild(self.ref("lov", lov_uuid))
282 def mds(self, name, uuid, mdd_uuid):
283 mds = self.newService("mds", name, uuid)
284 mds.appendChild(self.ref("active",mdd_uuid))
287 def mdsdev(self, name, uuid, fs, devname, format, node_uuid,
288 mds_uuid, dev_size=0 ):
289 mdd = self.newService("mdsdev", name, uuid)
290 self.addElement(mdd, "fstype", fs)
291 dev = self.addElement(mdd, "devpath", devname)
292 self.addElement(mdd, "autoformat", format)
294 self.addElement(mdd, "devsize", "%s" % (dev_size))
295 mdd.appendChild(self.ref("node", node_uuid))
296 mdd.appendChild(self.ref("target", mds_uuid))
299 def mountpoint(self, name, uuid, mds_uuid, osc_uuid, path):
300 mtpt = self.newService("mountpoint", name, uuid)
301 mtpt.appendChild(self.ref("mds", mds_uuid))
302 mtpt.appendChild(self.ref("obd", osc_uuid))
303 self.addElement(mtpt, "path", path)
306 def echo_client(self, name, uuid, osc_uuid):
307 ec = self.newService("echoclient", name, uuid)
308 ec.appendChild(self.ref("obd", osc_uuid))
311 ############################################################
312 # Utilities to query a DOM tree
313 # Using this functions we can treat use config information
314 # directly as a database.
316 return n.getAttribute('name')
319 return node.getAttribute('uuid')
322 def findByName(lustre, name, tag = ""):
323 for n in lustre.childNodes:
324 if n.nodeType == n.ELEMENT_NODE:
325 if tag and n.nodeName != tag:
327 if getName(n) == name:
330 n = findByName(n, name)
335 def lookup(node, uuid):
336 for n in node.childNodes:
337 if n.nodeType == n.ELEMENT_NODE:
338 if getUUID(n) == uuid:
346 def name2uuid(lustre, name, tag="", fatal=1):
347 ret = findByName(lustre, name, tag)
350 error('name2uuid:', '"'+name+'"', tag, 'element not found.')
356 # XXX: assumes only one network element per node. will fix this
357 # as soon as support for routers is added
358 def get_net_uuid(lustre, node_name):
359 """ get a network uuid for a node_name """
360 node = findByName(lustre, node_name, "node")
362 error ('get_net_uuid:', '"'+node_name+'"', "node element not found.")
363 net = node.getElementsByTagName('network')
365 return getUUID(net[0])
369 def lov_add_obd(gen, lov, osc_uuid):
370 lov.appendChild(gen.ref("obd", osc_uuid))
372 def ref_exists(profile, uuid):
373 elist = profile.childNodes
375 if e.nodeType == e.ELEMENT_NODE:
376 ref = e.getAttribute('uuidref')
381 # ensure that uuid is not already in the profile
382 # return true if uuid is added
383 def node_add_profile(gen, node, ref, uuid):
384 refname = "%s_ref" % "profile"
385 ret = node.getElementsByTagName(refname)
387 error('node has no profile ref:', node)
388 prof_uuid = ret[0].getAttribute('uuidref')
389 profile = lookup(node.parentNode, prof_uuid)
391 error("no profile found:", prof_uuid)
392 if ref_exists(profile, uuid):
394 profile.appendChild(gen.ref(ref, uuid))
397 def get_attr(dom_node, attr, default=""):
398 v = dom_node.getAttribute(attr)
403 ############################################################
406 def do_add_node(gen, lustre, options, node_name):
407 uuid = new_uuid(node_name)
408 prof_name = new_name("PROFILE_" + node_name)
409 prof_uuid = new_uuid(prof_name)
410 profile = gen.profile(prof_name, prof_uuid)
411 node = gen.node(node_name, uuid, prof_uuid)
412 lustre.appendChild(node)
413 lustre.appendChild(profile)
415 node_add_profile(gen, node, 'ldlm', ldlm_uuid)
416 node_add_profile(gen, node, 'ptlrpc', ptlrpc_uuid)
417 if has_option(options, 'router'):
418 node.setAttribute('router', '1')
419 if has_option(options, 'timeout'):
420 node.setAttribute('timeout', get_option(options, 'timeout'))
421 if has_option(options, 'recovery_upcall'):
422 node.setAttribute('recovery_upcall', get_option(options, 'recovery_upcall'))
426 def add_node(gen, lustre, options):
427 """ create a node with a network config """
429 node_name = get_option(options, 'node')
430 ret = findByName(lustre, node_name, "node")
432 print "Node:", node_name, "exists."
434 do_add_node(gen, lustre, options, node_name)
437 def add_net(gen, lustre, options):
438 """ create a node with a network config """
440 node_name = get_option(options, 'node')
441 nid = get_option(options, 'nid')
442 hostaddr = get_option(options, 'hostaddr', '')
443 net_type = get_option(options, 'nettype')
445 if net_type in ('tcp', 'toe'):
446 port = get_option_int(options, 'port', DEFAULT_PORT)
447 tcpbuf = get_option_int(options, 'tcpbuf', 0)
448 irq_aff = get_option_int(options, 'irq_affinity', 0)
449 nid_xchg = get_option_int(options, 'nid_exchange', 0)
450 elif net_type in ('elan', 'gm'):
456 print "Unknown net_type: ", net_type
459 ret = findByName(lustre, node_name, "node")
461 node = do_add_node(gen, lustre, options, node_name)
464 net_name = new_name('NET_'+ node_name +'_'+ net_type)
465 net_uuid = new_uuid(net_name)
466 node.appendChild(gen.network(net_name, net_uuid, nid, net_type, hostaddr, port, tcpbuf, irq_aff, nid_xchg))
467 node_add_profile(gen, node, "network", net_uuid)
470 def add_route(gen, lustre, options):
471 """ create a node with a network config """
473 node_name = get_option(options, 'node')
474 net_type = get_option(options, 'nettype')
475 gw = get_option(options, 'gw')
476 lo = get_option(options, 'lo')
477 hi = get_option(options, 'hi', '')
479 node = findByName(lustre, node_name, "node")
481 error (node_name, " not found.")
483 rlist = node.getElementsByTagName('routetbl')
487 rtbl_name = new_name("RTBL_" + node_name)
488 rtbl_uuid = new_uuid(rtbl_name)
489 rtbl = gen.routetbl(rtbl_name, rtbl_uuid)
490 node.appendChild(rtbl)
491 node_add_profile(gen, node, "routetbl", rtbl_uuid)
492 rtbl.appendChild(gen.route(net_type, gw, lo, hi))
495 def add_mds(gen, lustre, options):
496 node_name = get_option(options, 'node')
497 mds_name = get_option(options, 'mds')
498 mdd_name = new_name("MDD_" + mds_name +"_" + node_name)
499 mdd_uuid = new_uuid(mdd_name)
501 mds_uuid = name2uuid(lustre, mds_name, fatal=0)
503 mds_uuid = new_uuid(mds_name)
504 mds = gen.mds(mds_name, mds_uuid, mdd_uuid)
505 lustre.appendChild(mds)
507 devname = get_option(options, 'dev')
508 size = get_option(options, 'size', 0)
509 fstype = get_option(options, 'fstype', 'extN')
511 node_uuid = name2uuid(lustre, node_name, 'node')
513 node = findByName(lustre, node_name, "node")
514 node_add_profile(gen, node, "mdsdev", mdd_uuid)
515 net_uuid = get_net_uuid(lustre, node_name)
517 error("NODE: ", node_name, "not found")
519 mdd = gen.mdsdev(mdd_name, mdd_uuid, fstype, devname, get_format_flag(options),
520 node_uuid, mds_uuid, dev_size=size)
521 lustre.appendChild(mdd)
524 def add_ost(gen, lustre, options):
525 node_name = get_option(options, 'node')
526 lovname = get_option(options, 'lov', '')
527 osdtype = get_option(options, 'osdtype', 'obdfilter', deprecated_tag="obdtype")
529 node_uuid = name2uuid(lustre, node_name)
531 if osdtype == 'obdecho':
537 devname = get_option(options, 'dev', '') # can be unset for bluearcs
538 size = get_option(options, 'size', 0)
539 fstype = get_option(options, 'fstype', 'extN')
541 ostname = get_option(options, 'ost', '', deprecated_tag='obd')
543 ostname = new_name('OST_'+ node_name)
545 osdname = new_name("OSD_" + ostname)
546 osd_uuid = new_uuid(osdname)
548 ost_uuid = name2uuid(lustre, ostname, fatal=0)
550 ost_uuid = get_option(options, 'ostuuid', '', deprecated_tag = 'obduuid')
552 if lookup(lustre, ost_uuid):
553 error("Duplicate OST UUID:", ost_uuid)
555 ost_uuid = new_uuid(ostname)
557 ost = gen.ost(ostname, ost_uuid, osd_uuid)
558 lustre.appendChild(ost)
560 lov = findByName(lustre, lovname, "lov")
562 error('add_ost:', '"'+lovname+'"', "lov element not found.")
563 lov_add_obd(gen, lov, ost_uuid)
565 osd = gen.osd(osdname, osd_uuid, fstype, osdtype, devname, get_format_flag(options), ost_uuid,
568 node = findByName(lustre, node_name, "node")
570 ## if node_add_profile(gen, node, 'oss', oss_uuid):
572 ## oss_uuid = new_uuid(ossname)
573 ## oss = gen.oss(ossname, oss_uuid)
574 ## lustre.appendChild(oss)
576 node_add_profile(gen, node, 'osd', osd_uuid)
577 lustre.appendChild(osd)
580 def add_cobd(gen, lustre, options):
581 node_name = get_option(options, 'node')
582 name = new_name('COBD_' + node_name)
583 uuid = new_uuid(name)
585 real_name = get_option(options, 'real_obd')
586 cache_name = get_option(options, 'cache_obd')
588 real_uuid = name2uuid(lustre, real_name, tag='obd')
589 cache_uuid = name2uuid(lustre, cache_name, tag='obd')
591 node = findByName(lustre, node_name, "node")
592 node_add_profile(gen, node, "cobd", uuid)
593 cobd = gen.cobd(name, uuid, real_uuid, cache_uuid)
594 lustre.appendChild(cobd)
597 def add_echo_client(gen, lustre, options):
598 """ add an echo client to the profile for this node. """
599 node_name = get_option(options, 'node')
600 lov_name = get_option(options, 'ost')
602 node = findByName(lustre, node_name, 'node')
604 echoname = new_name('ECHO_'+ node_name)
605 echo_uuid = new_uuid(echoname)
606 node_add_profile(gen, node, 'echoclient', echo_uuid)
608 lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0)
610 lov_uuid = name2uuid(lustre, lov_name, tag='ost', fatal=1)
612 echo = gen.echo_client(echoname, echo_uuid, lov_uuid)
613 lustre.appendChild(echo)
616 def add_lov(gen, lustre, options):
619 lov_orig = get_option(options, 'lov')
620 name = new_name(lov_orig)
622 warning("name:", lov_orig, "already used. using:", name)
624 mds_name = get_option(options, 'mds')
625 stripe_sz = get_option_int(options, 'stripe_sz')
626 stripe_cnt = get_option_int(options, 'stripe_cnt', 0)
627 pattern = get_option_int(options, 'stripe_pattern', 0)
628 uuid = new_uuid(name)
630 ret = findByName(lustre, name, "lov")
632 error("LOV: ", name, " already exists.")
634 mds_uuid = name2uuid(lustre, mds_name, 'mds')
635 lov = gen.lov(name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
636 lustre.appendChild(lov)
638 # add an lovconfig entry to the active mdsdev profile
639 lovconfig_name = new_name('LVCFG_' + name)
640 lovconfig_uuid = new_uuid(lovconfig_name)
641 mds = findByName(lustre, mds_name)
642 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
643 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
644 lustre.appendChild(lovconfig)
647 def add_mtpt(gen, lustre, options):
648 """ create mtpt on a node """
649 node_name = get_option(options, 'node')
651 path = get_option(options, 'path')
652 mds_name = get_option(options, 'mds')
653 lov_name = get_option(options, 'lov', '')
655 lov_name = get_option(options, 'ost', '', deprecated_tag='obd')
657 error("--add mtpt requires either --lov lov_name or --ost ost_name")
659 name = new_name('MNT_'+ node_name)
661 ret = findByName(lustre, name, "mountpoint")
663 error("MOUNTPOINT: ", name, " already exists.")
665 mds_uuid = name2uuid(lustre, mds_name, tag='mds')
666 lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0)
668 lov_uuid = name2uuid(lustre, lov_name, tag='ost', fatal=1)
670 uuid = new_uuid(name)
671 mtpt = gen.mountpoint(name, uuid, mds_uuid, lov_uuid, path)
672 node = findByName(lustre, node_name, "node")
674 error('node:', node_name, "not found.")
675 node_add_profile(gen, node, "mountpoint", uuid)
676 lustre.appendChild(mtpt)
678 # obsolete, leaving behind for reference
679 def add_oscref(gen, lustre, options):
680 """ create mtpt on a node """
681 node_name = get_option(options, 'node')
682 osc_name = get_option(options, 'osc')
684 osc_uuid = name2uuid(lustre, osc_name, tag='osc')
685 node = findByName(lustre, node_name, "node")
687 error('node:', node_name, "not found")
688 node_add_profile(gen, node, "osc",osc_uuid)
690 ############################################################
691 # Command line processing
693 class OptionError (exceptions.Exception):
694 def __init__(self, args):
697 def has_option(options, tag):
698 """Look for tag in options hash and return the true if set"""
699 if options.has_key(tag):
703 def get_option(options, tag, default = None, deprecated_tag=None):
704 """Look for tag in options hash and return the value if set. If not
705 set, then if return default it is set, otherwise exception."""
706 if options.has_key(tag):
708 elif deprecated_tag and options.has_key(deprecated_tag):
709 warning('--'+deprecated_tag, " is deprecated, please use:", '--'+tag)
710 return options[deprecated_tag]
711 elif default != None:
714 raise OptionError("--add %s requires --%s <value>" % (options['add'], tag))
715 # this exception should print an error like '--add blah requires --<tag> value'
717 def get_option_int(options, tag, default = None):
718 """Return an integer option. Raise exception if the value is not an int"""
719 val = get_option(options, tag, default)
723 raise OptionError("--%s <num> (value must be integer)" % (tag))
726 def parse_cmdline(argv):
727 short_opts = "ho:i:m:"
728 long_opts = ["add=", "node=", "nettype=", "nid=", "tcpbuf=", "port=",
729 "echo_client=", "stripe_sz=", "stripe_cnt=", "stripe_pattern=",
730 "mds=", "route", "router", "merge=", "format", "reformat", "output=",
731 "dev=", "size=", "obd=", "ost=", "obdtype=", "osdtype=", "obduuid=", "in=",
732 "ostuuid=", "path=", "help", "batch=", "lov=", "gw=", "lo=", "hi=",
733 "osc=", "real_obd=", "cache_obd=", "fstype=",
734 "timeout=", "recovery_upcall=", "nid_exchange=", "irq_affinity=",
740 opts, args = getopt.getopt(argv, short_opts, long_opts)
741 except getopt.error, e:
742 panic(string.join(sys.argv), e)
745 # Commands to create new devices
764 options['timeout'] = a
765 if o == "--recovery_upcall":
766 options['recovery_upcall'] = a
768 options['router'] = 1
773 if o == "--hostaddr":
774 options['hostaddr'] = a
776 options['nettype'] = a
780 options['tcpbuf'] = a
787 if o == "--nid_exchange":
788 options['nid_exchange'] = a
789 if o == "--irq_affinity":
790 options['irq_affinity'] = a
802 options['obdtype'] = a
804 options['osdtype'] = a
806 options['fstype'] = a
808 options['obduuid'] = a
810 options['ostuuid'] = a
813 if o == "--stripe_sz":
814 options['stripe_sz'] = a
815 if o == "--stripe_cnt":
816 options['stripe_cnt'] = a
817 if o == "--stripe_pattern":
818 options['stripe_pattern'] = a
827 if o == "--cache_obd":
828 options['cache_obd'] = a
829 if o == "--real_obd":
830 options['real_obd'] = a
833 if o in ("-h", "--help"):
835 if o in ("-o", "--output"):
836 options['output'] = a
837 if o in ("-m", "--merge"):
840 options['format'] = 1
841 if o == "--reformat":
842 warning("the lmc --reformat option is not supported. Use lconf --reformat")
843 options['reformat'] = 1
846 if o in ("--in" , "-i"):
852 # simple class for profiling
859 self._start = time.time()
860 def stop(self, msg=''):
861 self._stop = time.time()
865 return self._stop - self._start
866 def display(self, msg):
868 str = '%s: %g secs' % (msg, d)
873 ############################################################
877 def add(devtype, gen, lustre, options):
879 add_net(gen, lustre, options)
880 elif devtype =='osc':
881 add_osc(gen, lustre, options)
882 elif devtype == 'mtpt':
883 add_mtpt(gen, lustre, options)
884 elif devtype == 'mds':
885 add_mds(gen, lustre, options)
886 elif devtype == 'ost':
887 add_ost(gen, lustre, options)
888 elif devtype == 'lov':
889 add_lov(gen, lustre, options)
890 elif devtype == 'route':
891 add_route(gen, lustre, options)
892 elif devtype == 'node':
893 add_node(gen, lustre, options)
894 elif devtype == 'echo_client':
895 add_echo_client(gen, lustre, options)
896 elif devtype == 'cobd':
897 add_cobd(gen, lustre, options)
899 error("unknown device type:", devtype)
901 def do_command(gen, lustre, options, args):
902 if options.has_key('add'):
903 add(options['add'], gen, lustre, options)
905 error("Missing command")
908 options, args = parse_cmdline(sys.argv[1:])
911 if options.has_key('merge'):
912 outFile = options['merge']
913 if os.access(outFile, os.R_OK):
914 doc = xml.dom.minidom.parse(outFile)
916 doc = new_lustre(xml.dom.minidom)
917 elif options.has_key('in'):
918 doc = xml.dom.minidom.parse(options['in'])
920 doc = new_lustre(xml.dom.minidom)
922 if options.has_key('output'):
923 outFile = options['output']
925 lustre = doc.documentElement
927 if lustre.tagName != "lustre":
928 print "Existing config not valid."
933 if options.has_key('batch'):
934 fp = open(options['batch'])
935 batchCommands = fp.readlines()
937 for cmd in batchCommands:
938 options, args = parse_cmdline(string.split(cmd))
940 do_command(gen, lustre, options, args)
941 except OptionError, e:
945 do_command(gen, lustre, options, args)
946 except OptionError, e:
947 panic(string.join(sys.argv),e)
952 PrettyPrint(doc, open(outFile,"w"))
954 if __name__ == "__main__":