X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;ds=sidebyside;f=lustre%2Futils%2Flmc;h=3d7c7bf210692e94896c44bacd442b28490718c7;hb=7312616768bfed768ecc00ba20322c37568138d0;hp=ac5391317bf4db6f9f26bf99c3dd1be3a34c2163;hpb=b86e1d538ef4ef6eba35a2c49c90e316f4c22f54;p=fs%2Flustre-release.git diff --git a/lustre/utils/lmc b/lustre/utils/lmc index ac53913..3d7c7bf 100755 --- a/lustre/utils/lmc +++ b/lustre/utils/lmc @@ -1,7 +1,6 @@ #!/usr/bin/env python -# -# Copyright (C) 2002 Cluster File Systems, Inc. -# Author: Robert Read +# Copyright (C) 2002 Cluster File Systems, Inc. +# Author: Robert Read # This file is part of Lustre, http://www.lustre.org. # @@ -26,6 +25,13 @@ lmc - lustre configurtion data manager # create nodes ./lmc --output config.xml --node server --net server1 tcp ./lmc --merge config.xml --node client --net client1 tcp +./lmc --merge config.xml --node client --route gw lo [hi] +./lmc --merge config.xml --router --node gw1 --net gw1 tcp +./lmc --merge config.xml --node gw1 --net 1 elan + +./lmc --merge config.xml --route elan 1 1 100 +./lmc --merge config.xml --route tcp gw1 ba1 + # configure server @@ -41,7 +47,7 @@ lmc - lustre configurtion data manager """ -import sys, getopt, string +import sys, os, getopt, string import xml.dom.minidom from xml.dom.ext import PrettyPrint @@ -52,30 +58,36 @@ def usage(): print """usage: lmc [--node --ost | --mtpt | --lov] args Commands: --node node_name - Node_name by itself it will create a new node. When used with other - commands it specifies the node to modify + Node_name by itself it will create a new node. If the --router + option is used when creating a new node, then that node will also + be configured as a router. When used with other commands it + specifies the node to modify. --net hostname nettype [port, recv_buf, send_buf] - Nettype is either tcp, elan, or gm. - Requires a node argument + Nettype is either tcp, toe, elan, or gm. + Requires --node + +--route net gw lo [hi] + This command is used to create routes. NET is the + network type this route will be used on. The GW is an address of + one of the local interfaces. LO and HI represent a range of + addresses that can be reached through the gateway. If HI is not + set, then a route to the specific host in LO is created. --mds device [size] Create a MDS using the device Requires --node ---lov lov_name [mdc_name stripe_sz stripe_off pattern] +--lov lov_name [mds_name stripe_sz sub_stripe_count pattern] Creates a logical volume When used with other commands, it specifics the lov to modify ---mdc mdc_name - Configures a MDC for a node. - Requires --node - --ost device [size] Creates an OBD/OST/OSC configuration triplet for a new device. When used on "host", the device will be initialized and the OST will be enabled. On client nodes, the OSC will be avaiable. Requires --node + Optional --obduuid Specifies the UUID used for the obd. If --lov lov_name is used, this device is added to lov. --mtpt /mnt/point mds_name lov_name|osc_name @@ -85,6 +97,9 @@ Commands: Options: --merge="xml file" Add the new objects to an existing file --format Format the partitions if unformated + NB: The autoformat option has been disabled until a safe + method is implemented to determine if a block device has a + filesystem. --reformat Reformat partitions (this should be an lconf arg, I think) --obdtype="obdtype" Specifiy obdtype: valid ones are obdecho and obdfilter. @@ -95,9 +110,13 @@ Options: def error(*args): msg = string.join(map(str,args)) - print msg + print "Error: ", msg sys.exit(1) +def warning(*args): + msg = string.join(map(str,args)) + print "Warning: ", msg + # # manage names and uuids # need to initialize this by walking tree to ensure @@ -113,7 +132,7 @@ def new_name(base): names[ret] = 1 return ret -def get_uuid(name): +def new_uuid(name): return "%s_UUID" % (name) ldlm_name = 'ldlm' @@ -121,7 +140,9 @@ ldlm_uuid = 'ldlm_UUID' def new_lustre(dom): """Create a new empty lustre document""" # adding ldlm here is a bit of a hack, but one is enough. - str = """ """ % (ldlm_name, ldlm_uuid) + str = """ + + """ % (ldlm_name, ldlm_uuid) return dom.parseString(str) names = {} @@ -144,6 +165,9 @@ def get_format_flag(options): return 'yes' return 'no' +############################################################ +# Build config objects using DOM +# class GenConfig: doc = None dom = None @@ -177,15 +201,29 @@ class GenConfig: node.appendChild(new) return new - def network(self, name, uuid, hostname, net, port=0): + def network(self, name, uuid, hostname, net, port=0, tcpbuf=0): """create node""" network = self.newService("network", name, uuid) network.setAttribute("type", net); self.addElement(network, "server", hostname) if port: self.addElement(network, "port", "%d" %(port)) + if tcpbuf: + self.addElement(network, "send_mem", "%d" %(tcpbuf)) + self.addElement(network, "recv_mem", "%d" %(tcpbuf)) + return network + def route(self, net_type, gw, lo, hi): + """ create one entry for the route table """ + ref = self.doc.createElement('route') + ref.setAttribute("type", net_type) + ref.setAttribute("gw", gw) + ref.setAttribute("lo", lo) + if hi: + ref.setAttribute("hi", hi) + return ref + def node(self, name, uuid): """ create a host """ node = self.newService("node", name, uuid) @@ -221,15 +259,20 @@ class GenConfig: ost.appendChild(self.ref("obd", obd_uuid)) return ost - def lov(self, name, uuid, mds_uuid, stripe_sz, stripe_off, pattern): + def lov(self, name, uuid, mds_uuid, stripe_sz, stripe_count, pattern): lov = self.newService("lov", name, uuid) lov.appendChild(self.ref("mds", mds_uuid)) devs = self.addElement(lov, "devices" ) devs.setAttribute("stripesize", stripe_sz) - devs.setAttribute("stripeoffset", stripe_off) + devs.setAttribute("stripecount", stripe_count) devs.setAttribute("pattern", pattern) return lov + def lovconfig(self, name, uuid, lov_uuid): + lovconfig = self.newService("lovconfig", name, uuid) + lovconfig.appendChild(self.ref("lov", lov_uuid)) + return lovconfig + def mds(self, name, uuid, fs, devname, format, net_uuid, node_uuid, failover_uuid = "", dev_size=0 ): mds = self.newService("mds", name, uuid) @@ -244,18 +287,22 @@ class GenConfig: mds.appendChild(self.ref("failover", failover_uuid)) return mds - def mdc(self, name, uuid, mds_uuid): - mdc = self.newService("mdc", name, uuid) - mdc.appendChild(self.ref("mds", mds_uuid)) - return mdc - - def mountpoint(self, name, uuid, mdc_uuid, osc_uuid, path): + def mountpoint(self, name, uuid, mds_uuid, osc_uuid, path): mtpt = self.newService("mountpoint", name, uuid) - mtpt.appendChild(self.ref("mdc", mdc_uuid)) + mtpt.appendChild(self.ref("mds", mds_uuid)) mtpt.appendChild(self.ref("osc", osc_uuid)) self.addElement(mtpt, "path", path) return mtpt + def echo_client(self, name, uuid, osc_uuid): + ec = self.newService("echo_client", name, uuid) + ec.appendChild(self.ref("osc", osc_uuid)) + return ec + +############################################################ +# Utilities to query a DOM tree +# Using this functions we can treat use config information +# directly as a database. def getName(n): return n.getAttribute('name') @@ -275,6 +322,7 @@ def findByName(lustre, name, tag = ""): if n: return n return None + def lookup(node, uuid): for n in node.childNodes: if n.nodeType == n.ELEMENT_NODE: @@ -291,40 +339,44 @@ def mds2node(lustre, mds_name): mds = findByName(lustre, mds_name, 'mds') ref = mds.getElementsByTagName('node_ref') if not ref: - error("no node found for:", mds_name) + error("mds2node:", "no node_ref found for", '"'+mds_name+'"') node_uuid = ref[0].getAttribute('uuidref') node = lookup(lustre, node_uuid) if not node: - error("no node found for :", mds_name) + error('mds2node:', "no node found for :", '"'+mds_name+'"') return node + def name2uuid(lustre, name, tag="", fatal=1): ret = findByName(lustre, name, tag) if not ret: if fatal: - error('name2uuid:', name, "not found.") + error('name2uuid:', '"'+name+'"', tag, 'element not found.') else: return "" return getUUID(ret) + # XXX: assumes only one network element per node. will fix this # as soon as support for routers is added def get_net_uuid(lustre, node_name): """ get a network uuid for a node_name """ node = findByName(lustre, node_name, "node") if not node: - error ("node not found:", node_name) + error ('get_net_uuid:', '"'+node_name+'"', "node element not found.") net = node.getElementsByTagName('network') if net: return getUUID(net[0]) return None + def lov_add_osc(gen, lov, osc_uuid): devs = lov.getElementsByTagName('devices') if len(devs) == 1: devs[0].appendChild(gen.ref("osc", osc_uuid)) else: error("No devices element found for LOV:", lov) + def node_add_profile(gen, node, ref, uuid): ret = node.getElementsByTagName('profile') @@ -332,9 +384,140 @@ def node_add_profile(gen, node, ref, uuid): error('node has no profile:', node) ret[0].appendChild(gen.ref(ref, uuid)) +def get_attr(dom_node, attr, default=""): + v = dom_node.getAttribute(attr) + if v: + return v + return default + +############################################################ +# Top level commands # -# Create a new obd, osc, and ost. Add them to the DOM. -# +def do_add_node(gen, lustre, options, node_name): + uuid = new_uuid(node_name) + node = gen.node(node_name, uuid) + node_add_profile(gen, node, 'ldlm', ldlm_uuid) + if options.has_key('router'): + node.setAttribute('router', '1') + lustre.appendChild(node) + return node + + +def add_node(gen, lustre, options, args): + """ create a node with a network config """ + if len(args) > 1: + usage() + + node_name = options['node'] + + ret = findByName(lustre, node_name, "node") + if ret: + print "Node:", node_name, "exists." + return + do_add_node(gen, lustre, options, node_name) + + +def add_net(gen, lustre, options, args): + """ create a node with a network config """ + if len(args) < 2: + usage() + + node_name = options['node'] + nid = args[0] + net_type = args[1] + port = 0 + tcpbuf = 0 + + if net_type in ('tcp', 'toe'): + if len(args) > 2: + port = int(args[2]) + else: + port = DEFAULT_PORT + if options.has_key('tcpbuf'): + tcpbuf = int(options['tcpbuf']) + elif net_type in ('elan', 'gm'): + port = 0 + else: + print "Unknown net_type: ", net_type + sys.exit(2) + + ret = findByName(lustre, node_name, "node") + if not ret: + node = do_add_node(gen, lustre, options, node_name) + else: + node = ret + net_name = new_name('NET_'+ node_name +'_'+ net_type) + net_uuid = new_uuid(net_name) + node.appendChild(gen.network(net_name, net_uuid, nid, net_type, port, tcpbuf)) + node_add_profile(gen, node, "network", net_uuid) + + +def add_route(gen, lustre, options, args): + """ create a node with a network config """ + if len(args) < 3: + usage() + + node_name = options['node'] + net_type= args[0] + gw = args[1] + lo = args[2] + hi = '' + + if len(args) > 3: + hi = args[3] + + node = findByName(lustre, node_name, "node") + if not node: + error (node_name, " not found.") + + netlist = node.getElementsByTagName('network') + net = netlist[0] + rlist = net.getElementsByTagName('route_tbl') + if len(rlist) > 0: + rtbl = rlist[0] + else: + rtbl = gen.addElement(net, 'route_tbl') + rtbl.appendChild(gen.route(net_type, gw, lo, hi)) + + +def add_mds(gen, lustre, options, args): + fstype = 'extN' + + if len(args) < 1: + usage() + + if options.has_key('node'): + node_name = options['node'] + else: + error("--mds requires a --node argument") + + if options.has_key('fstype'): + fstype = options['fstype'] + + mds_name = new_name(options['mds']) + if mds_name != options['mds']: + warning("name:", options['mds'], "already used. using:", mds_name) + devname = args[0] + if len(args) > 1: + size = args[1] + else: + size = 0 + + mds_uuid = new_uuid(mds_name) + + node_uuid = name2uuid(lustre, node_name, 'node') + + node = findByName(lustre, node_name, "node") + node_add_profile(gen, node, "mds", mds_uuid) + net_uuid = get_net_uuid(lustre, node_name) + if not net_uuid: + error("NODE: ", node_name, "not found") + + mds = gen.mds(mds_name, mds_uuid, fstype, devname, get_format_flag(options), + net_uuid, node_uuid, dev_size=size) + lustre.appendChild(mds) + + def add_ost(gen, lustre, options, args): lovname = '' obdtype = 'obdfilter' @@ -352,7 +535,8 @@ def add_ost(gen, lustre, options, args): if options.has_key('obdtype'): obdtype = options['obdtype'] - + if options.has_key('fstype'): + fstype = options['fstype'] if obdtype == 'obdecho': fstype = '' else: @@ -365,9 +549,15 @@ def add_ost(gen, lustre, options, args): obdname = new_name('OBD_'+ node_name) oscname = new_name('OSC_'+ node_name) ostname = new_name('OST_'+ node_name) - obd_uuid = get_uuid(obdname) - ost_uuid = get_uuid(ostname) - osc_uuid = get_uuid(oscname) + if options.has_key('obduuid'): + obd_uuid = options['obduuid'] + obd = lookup(lustre, obd_uuid) + if obd: + error("Duplicate OBD UUID:", obd_uuid) + else: + obd_uuid = new_uuid(obdname) + ost_uuid = new_uuid(ostname) + osc_uuid = new_uuid(oscname) net_uuid = get_net_uuid(lustre, node_name) if not net_uuid: @@ -380,7 +570,7 @@ def add_ost(gen, lustre, options, args): if lovname: lov = findByName(lustre, lovname, "lov") if not lov: - error("LOV:", lovname, "not found.") + error('add_ost:', '"'+lovname+'"', "lov element not found.") lov_add_osc(gen, lov, osc_uuid) node = findByName(lustre, node_name, "node") @@ -390,57 +580,45 @@ def add_ost(gen, lustre, options, args): lustre.appendChild(obd) lustre.appendChild(osc) lustre.appendChild(ost) + -def add_net(gen, lustre, options, args): - """ create a node with a network config """ - if len(args) < 2: +# this is generally only used by llecho.sh +def add_osc(gen, lustre, options, args): + """ add the osc to the profile for this node. """ + if len(args) < 1: usage() - - node_name = options['node'] - nid = args[0] - net_type = args[1] - - if net_type == 'tcp': - if len(args) > 2: - port = int(args[2]) - else: - port = DEFAULT_PORT - # add send, recv buffer size here - elif net_type in ('elan', 'gm'): - port = 0 + osc_name = args[0] + if options.has_key('node'): + node_name = options['node'] else: - print "Unknown net_type: ", net_type - sys.exit(2) + error("--osc requires a --node argument") + osc_uuid = name2uuid(lustre, osc_name) # either 'osc' or 'lov' + node = findByName(lustre, node_name, "node") + node_add_profile(gen, node, 'osc', osc_uuid) - ret = findByName(lustre, node_name, "node") - if not ret: - node = do_add_node(gen, lustre, node_name) - else: - node = ret - net_name = new_name('NET_'+ node_name +'_'+ net_type) - net_uuid = get_uuid(net_name) - node.appendChild(gen.network(net_name, net_uuid, nid, net_type, port)) - node_add_profile(gen, node, "network", net_uuid) -def do_add_node(gen, lustre, node_name): - uuid = get_uuid(node_name) - node = gen.node(node_name, uuid) - node_add_profile(gen, node, 'ldlm', ldlm_uuid) - lustre.appendChild(node) - return node - -def add_node(gen, lustre, options, args): - """ create a node with a network config """ - if len(args) > 1: +#ditto +def add_echo_client(gen, lustre, options, args): + """ add an echo client to the profile for this node. """ + if len(args) < 1: usage() + lov_name = args[0] + if options.has_key('node'): + node_name = options['node'] + else: + error("--echo_client requires a --node argument") + node = findByName(lustre, node_name, "node") - node_name = options['node'] + echoname = new_name('ECHO_'+ node_name) + echo_uuid = new_uuid(echoname) + node_add_profile(gen, node, 'echo_client', echo_uuid) - ret = findByName(lustre, node_name, "node") - if ret: - print "Node:", node_name, "exists." - return - do_add_node(gen, lustre, node_name) + lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0) + if not lov_uuid: + lov_uuid = name2uuid(lustre, lov_name, tag='osc', fatal=1) + + echo = gen.echo_client(echoname, echo_uuid, lov_uuid) + lustre.appendChild(echo) def add_lov(gen, lustre, options, args): @@ -448,23 +626,33 @@ def add_lov(gen, lustre, options, args): if len(args) < 4: usage() - name = options['lov'] + name = new_name(options['lov']) + if name != options['lov']: + warning("name:", options['lov'], "already used. using:", name) + mds_name = args[0] stripe_sz = args[1] - stripe_off = args[2] + stripe_count = args[2] pattern = args[3] - uuid = get_uuid(name) + uuid = new_uuid(name) ret = findByName(lustre, name, "lov") if ret: error("LOV: ", name, " already exists.") - mds_uuid = name2uuid(lustre, mds_name) - - node = mds2node(lustre, mds_name) - node_add_profile(gen, node, "lov", uuid) - lov = gen.lov(name, uuid, mds_uuid, stripe_sz, stripe_off, pattern) + mds_uuid = name2uuid(lustre, mds_name, 'mds') + lov = gen.lov(name, uuid, mds_uuid, stripe_sz, stripe_count, pattern) lustre.appendChild(lov) + + # add an lovconfig entry to the mds profile + lovconfig_name = new_name('LVCFG_' + name) + lovconfig_uuid = new_uuid(lovconfig_name) + node = mds2node(lustre, mds_name) + node_add_profile(gen, node, "lovconfig", lovconfig_uuid) + lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid) + lustre.appendChild(lovconfig) + + def add_mtpt(gen, lustre, options, args): """ create mtpt on a node """ @@ -479,7 +667,6 @@ def add_mtpt(gen, lustre, options, args): path = args[0] mds_name = args[1] lov_name = args[2] - mdc_name = 'MDC_' + mds_name name = new_name('MNT_'+ node_name) @@ -487,83 +674,29 @@ def add_mtpt(gen, lustre, options, args): if ret: error("MOUNTPOINT: ", name, " already exists.") - mdc_uuid = name2uuid(lustre, mdc_name) + mds_uuid = name2uuid(lustre, mds_name, tag='mds') lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0) if not lov_uuid: lov_uuid = name2uuid(lustre, lov_name, tag='osc', fatal=1) - uuid = get_uuid(name) - mtpt = gen.mountpoint(name, uuid, mdc_uuid, lov_uuid, path) + uuid = new_uuid(name) + mtpt = gen.mountpoint(name, uuid, mds_uuid, lov_uuid, path) node = findByName(lustre, node_name, "node") if not node: error('node:', node_name, "not found.") node_add_profile(gen, node, "mountpoint", uuid) - node_add_profile(gen, node, "mdc", mdc_uuid) lustre.appendChild(mtpt) -def add_mdc(gen, lustre, options, args): - """ create mtpt on a node """ - if len(args) < 1: - usage() - - if options.has_key('node'): - node_name = options['node'] - else: - error("--mdc requires a --node argument") - - mdc_name = args[0] - mdc_uuid = name2uuid(lustre, mdc_name) - node = findByName(lustre, node_name, "node") - if not node: - error('node:', node_name, "not found.") - node_add_profile(gen, node, "mdc", mdc_uuid) - -def add_mds(gen, lustre, options, args): - if len(args) < 1: - usage() - - if options.has_key('node'): - node_name = options['node'] - else: - error("--mds requires a --node argument") - - mds_name = new_name(options['mds']) - devname = args[0] - if len(args) > 1: - size = args[1] - else: - size = 0 - - mdc_name = 'MDC_' + mds_name - mds_uuid = get_uuid(mds_name) - mdc_uuid = get_uuid(mdc_name) - - node_uuid = name2uuid(lustre, node_name) - - node = findByName(lustre, node_name, "node") - node_add_profile(gen, node, "mds", mds_uuid) - net_uuid = get_net_uuid(lustre, node_name) - if not net_uuid: - error("NODE: ", node_name, "not found") - - - mds = gen.mds(mds_name, mds_uuid, "extN", devname, get_format_flag(options), - net_uuid, node_uuid, dev_size=size) - mdc = gen.mdc(mdc_name, mdc_uuid, mds_uuid) - lustre.appendChild(mds) - lustre.appendChild(mdc) - - -# +############################################################ # Command line processing # - def parse_cmdline(argv): short_opts = "ho:i:m:" - long_opts = ["ost", "mtpt", "lov=", "node=", "mds=", "net", - "mdc", "merge=", "format", "reformat", "output=", - "obdtype=", "in=", "help"] + long_opts = ["ost", "osc", "mtpt", "lov=", "node=", "mds=", "net", + "echo_client", "tcpbuf=", + "route", "router", "merge=", "format", "reformat", "output=", + "obdtype=", "fstype=", "obduuid=", "in=", "help", "batch="] opts = [] args = [] options = {} @@ -574,38 +707,58 @@ def parse_cmdline(argv): usage() for o, a in opts: - if o in ("-h", "--help"): - usage() - if o in ("-o", "--output"): - options['output'] = a + # Commands to create new devices if o == "--ost": options['ost'] = 1 + if o == "--osc": + options['osc'] = 1 + if o == "--echo_client": + options['echo_client'] = 1 if o == "--mds": options['mds'] = a - if o == "--mdc": - options['mdc'] = 1 if o == "--net": options['net'] = 1 if o == "--mtpt": options['mtpt'] = 1 if o == "--node": options['node'] = a + if o == "--route": + options['route'] = 1 + if o == "--router": + options['router'] = 1 if o == "--lov": options['lov'] = a - if o in ("-m", "--merge"): - options['merge'] = a + + # Options for commands if o == "--obdtype": options['obdtype'] = a + if o == "--fstype": + options['fstype'] = a + if o == "--obduuid": + options['obduuid'] = a + if o == "--tcpbuf": + options['tcpbuf'] = a + + # lmc options + if o in ("-h", "--help"): + usage() + if o in ("-o", "--output"): + options['output'] = a + if o in ("-m", "--merge"): + options['merge'] = a if o == "--format": options['format'] = 1 if o == "--reformat": options['reformat'] = 1 + if o == "--batch": + options['batch'] = a if o in ("--in" , "-i"): options['in'] = a return options, args +# simple class for profiling import time class chrono: def __init__(self): @@ -624,6 +777,31 @@ class chrono: str = '%s: %g secs' % (msg, d) print str +############################################################ +# Main +# +def do_command(gen, lustre, options, args): + if options.has_key('ost'): + add_ost(gen, lustre, options, args) + elif options.has_key('osc'): + add_osc(gen, lustre, options, args) + elif options.has_key('echo_client'): + add_echo_client(gen, lustre, options, args) + elif options.has_key('mtpt'): + add_mtpt(gen, lustre, options, args) + elif options.has_key('mds'): + add_mds(gen, lustre, options, args) + elif options.has_key('net'): + add_net(gen, lustre, options, args) + elif options.has_key('lov'): + add_lov(gen, lustre, options, args) + elif options.has_key('route'): + add_route(gen, lustre, options, args) + elif options.has_key('node'): + add_node(gen, lustre, options, args) + else: + print "Missing command" + usage() def main(): options, args = parse_cmdline(sys.argv[1:]) @@ -631,7 +809,10 @@ def main(): if options.has_key('merge'): outFile = options['merge'] - doc = xml.dom.minidom.parse(outFile) + if os.access(outFile, os.R_OK): + doc = xml.dom.minidom.parse(outFile) + else: + doc = new_lustre(xml.dom.minidom) elif options.has_key('in'): doc = xml.dom.minidom.parse(options['in']) else: @@ -647,23 +828,16 @@ def main(): sys.exit(1) gen = GenConfig(doc) - if options.has_key('ost'): - add_ost(gen, lustre, options, args) - elif options.has_key('mtpt'): - add_mtpt(gen, lustre, options, args) - elif options.has_key('mds'): - add_mds(gen, lustre, options, args) - elif options.has_key('mdc'): - add_mdc(gen, lustre, options, args) - elif options.has_key('net'): - add_net(gen, lustre, options, args) - elif options.has_key('lov'): - add_lov(gen, lustre, options, args) - elif options.has_key('node'): - add_node(gen, lustre, options, args) + + if options.has_key('batch'): + fp = open(options['batch']) + batchCommands = fp.readlines() + fp.close() + for cmd in batchCommands: + options, args = parse_cmdline(string.split(cmd)) + do_command(gen, lustre, options, args) else: - print "Missing command" - usage() + do_command(gen, lustre, options, args) if outFile == '-': PrettyPrint(doc)