X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=plc-config-tty;h=79f72333e37f6d350288113c31a65880a1a89e67;hb=f894d8a8fcda4d9fc6eb9da39bbe39ad06d95284;hp=95c1e2f2aa94bae7596266ab615e9b72b12e0f3b;hpb=f81410365785122c6d5a6a384fa06cc0bff698ca;p=myplc.git diff --git a/plc-config-tty b/plc-config-tty index 95c1e2f..79f7233 100755 --- a/plc-config-tty +++ b/plc-config-tty @@ -2,40 +2,98 @@ # Interactively prompts for variable values # expected arguments are -# command [default-xml [custom-xml]] +# command -d [default-xml [custom-xml [ consolidated-xml ]]] # -# Two-steps logic: -# (1) scans all variables (todo: pass categories as arguments) -# and prompts for value -# current value proposed as default -# also allows to remove site-dependent setting -# (2) epilogue : allows to -# list the site-dependent vars with values -# and to locally (re-)edit a variable from its shell name -# quit with or without saving +# -d is for the myplc-devel package + +# we use 3 instances of PLCConfiguration throughout: +# cdef : models the defaults, from plc_default.xml +# cread : merged from plc_default & configs/site.xml +# cwrite : site.xml + pending changes import sys import os import re import readline +import getopt from plc_config import PLCConfiguration #################### -release = "$Id" +release_id = "$Id: plc-config-tty,v 1.10 2006/12/12 10:14:44 thierry Exp $" +release_rev = "$Revision: 1.10 $" + +def init_flavour (flavour): + global service + global usual_variables + if (flavour == "devel"): + service="plc-devel" + usual_variables=("PLC_DEVEL_FEDORA_URL", + "PLC_DEVEL_CVSROOT") + config_dir = "/plc/devel/data/etc/planetlab" + else: + service="plc" + usual_variables=("PLC_NAME", + "PLC_SLICE_PREFIX", + "PLC_ROOT_USER", + "PLC_ROOT_PASSWORD", + "PLC_MAIL_ENABLED", + "PLC_MAIL_SUPPORT_ADDRESS", + "PLC_DB_HOST", + "PLC_API_HOST", + "PLC_WWW_HOST", + "PLC_BOOT_HOST", + "PLC_NET_DNS1", + "PLC_NET_DNS2", + ) + config_dir = "/etc/planetlab" + global def_default_config + def_default_config= "%s/default_config.xml" % config_dir + global def_site_config + def_site_config = "%s/configs/site.xml" % config_dir + global def_consolidated_config + def_consolidated_config = "%s/plc_config.xml" % config_dir -def_main_config = "/etc/planetlab/default_config.xml" -def_site_config = "/etc/planetlab/configs/site.xml" -def_consolidated_config = "/etc/planetlab/plc_config.xml" + global mainloop_usage + mainloop_usage= """Available commands: + Uppercase versions give variables comments, when available +-u/U\t\t\tEdit usual variables +-w\t\t\tWrite & consolidate +-r\t\t\tRestart %s service +-q\t\t\tQuit (without saving) +-h/?\t\t\tThis help +--- +l/L [|]\tShow Locally modified variables/values +-s/S [|]\tShow variables/values (all, in category, single) +-e/E [|]\tEdit variables (all, in category, single) +--- +-c\t\t\tList categories +-v/V [|]List Variables (all, in category, single) +--- +Typical usage involves: u, [l,] w, r, q +""" % service -command_usage="""Usage: %s [default-xml [site-xml [consolidated-xml]]] +def usage (): + command_usage="Usage: %s [-d] [-v] [default-xml [site-xml [consolidated-xml]]]"% sys.argv[0] + init_flavour ("boot") + command_usage +=""" + -v shows version and exits +\t default-xml defaults to %s +\t site-xml defaults to %s +\t consolidated-xml defaults to %s""" % (def_default_config,def_site_config, def_consolidated_config) + command_usage += """ + Unless you specify the -d option, meaning you want to configure + myplc-devel instead of regular myplc, in which case""" + init_flavour ("devel") + command_usage +=""" \t default-xml defaults to %s \t site-xml defaults to %s -\t consolidated-xml defaults to %s -""" % (sys.argv[0],def_main_config,def_site_config, def_consolidated_config) +\t consolidated-xml defaults to %s""" % (def_default_config,def_site_config, def_consolidated_config) + print(command_usage) + sys.exit(1) #################### -variable_usage= """Special answers : +variable_usage= """Edit Commands : #\tShow variable comments .\tStops prompting, return to mainloop /\tCleans any site-defined value, reverts to default @@ -44,21 +102,97 @@ variable_usage= """Special answers : ?\tThis help """ -def usage (): - print(command_usage) - sys.exit(1) - #################### def get_value (config, category_id, variable_id): (category, variable) = config.get (category_id, variable_id) return variable['value'] +def get_current_value (cread, cwrite, category_id, variable_id): + # the value stored in cwrite, if present, is the one we want + try: + result=get_value (cwrite,category_id,variable_id) + except: + result=get_value (cread,category_id,variable_id) + return result + # refrain from using plc_config's _sanitize def get_varname (config, category_id, variable_id): (category, variable) = config.get (category_id, variable_id) return (category_id+"_"+variable['id']).upper() -def prompt_variable (cdef, cread, cwrite, category, variable): +# could not avoid using _sanitize here.. +def get_name_comments (config, cid, vid): + try: + (category, variable) = config.get (cid, vid) + (id, name, value, comments) = config._sanitize_variable (cid,variable) + return (name,comments) + except: + return (None,[]) + +def print_name_comments (config, cid, vid): + (name,comments)=get_name_comments(config,cid,vid) + if name: + print "### %s" % name + if comments: + for line in comments: + print "# %s" % line + else: + print "!!! No comment associated to %s_%s" % (cid,vid) + +#################### +def list_categories (config): + result=[] + for (category_id, (category, variables)) in config.variables().iteritems(): + result += [category_id] + return result + +def print_categories (config): + print "Known categories" + for cid in list_categories(config): + print "%s" % (cid.upper()) + +#################### +def list_category (config, cid): + result=[] + for (category_id, (category, variables)) in config.variables().iteritems(): + if (cid == category_id): + for variable in variables.values(): + result += ["%s_%s" %(cid,variable['id'])] + return result + +def print_category (config, cid, show_comments=True): + cid=cid.lower() + CID=cid.upper() + vids=list_category(config,cid) + if (len(vids) == 0): + print "%s : no such category"%CID + else: + print "Category %s contains" %(CID) + for vid in vids: + print vid.upper() + +#################### +def consolidate (default_config, site_config, consolidated_config): + try: + conso = PLCConfiguration (default_config) + conso.load (site_config) + conso.save (consolidated_config) + except Exception, inst: + print "Could not consolidate, %s" % (str(inst)) + return + print ("Merged\n\t%s\nand\t%s\ninto\t%s"%(default_config,site_config, + consolidated_config)) + +#################### +def restart_plc (): + print ("==================== Stopping %s" % service) + os.system("service %s stop" % service) + print ("==================== Starting %s" % service) + os.system("service %s start" % service) + +#################### +def prompt_variable (cdef, cread, cwrite, category, variable, + show_comments, support_next=False): assert category.has_key('id') assert variable.has_key('id') @@ -68,9 +202,11 @@ def prompt_variable (cdef, cread, cwrite, category, variable): while True: default_value = get_value(cdef,category_id,variable_id) - current_value = get_value(cread,category_id, variable_id) + current_value = get_current_value(cread,cwrite,category_id, variable_id) varname = get_varname (cread,category_id, variable_id) + if show_comments : + print_name_comments (cdef, category_id, variable_id) prompt = "== %s : [%s] " % (varname,current_value) try: answer = raw_input(prompt).strip() @@ -82,16 +218,8 @@ def prompt_variable (cdef, cread, cwrite, category, variable): return None elif (answer == "."): raise Exception ('BailOut') - elif (answer == ">"): - raise Exception ('NextCategory') elif (answer == "#"): - if friendly_name is not None: - print ("### " + friendly_name) - if comments == None: - print ("!!! No comment associated to %s" % varname) - else: - for line in comments: - print ("# " + line) + print_name_comments(cread,category_id,variable_id) elif (answer == "?"): print variable_usage.strip() elif (answer == "="): @@ -101,19 +229,24 @@ def prompt_variable (cdef, cread, cwrite, category, variable): cwrite.delete(category_id,variable_id) print ("%s reverted to %s" %(varname,default_value)) return + elif (answer == ">"): + if support_next: + raise Exception ('NextCategory') + else: + print "No support for next category" else: variable['value'] = answer cwrite.set(category,variable) return -#################### -def prompt_all_variables (cdef, cread, cwrite): +def prompt_variables_all (cdef, cread, cwrite, show_comments): try: for (category_id, (category, variables)) in cread.variables().iteritems(): - print ("========== Category = %s" % category_id) + print ("========== Category = %s" % category_id.upper()) for variable in variables.values(): try: - newvar = prompt_variable (cdef, cread, cwrite, category, variable) + newvar = prompt_variable (cdef, cread, cwrite, category, variable, + show_comments, True) except Exception, inst: if (str(inst) == 'NextCategory'): break else: raise @@ -122,137 +255,214 @@ def prompt_all_variables (cdef, cread, cwrite): if (str(inst) == 'BailOut'): return else: raise - -#################### -def consolidate (main_config, site_config, consolidated_config): +def prompt_variables_category (cdef, cread, cwrite, cid, show_comments): + cid=cid.lower() + CID=cid.upper() try: - conso = PLCConfiguration (main_config) - conso.load (site_config) - conso.save (consolidated_config) + print ("========== Category = %s" % CID) + for vid in list_category(cdef,cid): + (category,variable) = cdef.locate_varname(vid.upper()) + newvar = prompt_variable (cdef, cread, cwrite, category, variable, + show_comments, False) except Exception, inst: - print "Could not consolidate, %s" % (str(inst)) - return - print ("Merged\n\t%s\nand\t%s\ninto\t%s"%(main_config,site_config,consolidated_config)) - + if (str(inst) == 'BailOut'): return + else: raise + #################### -def restart_plc (): - print ("==================== Stopping plc") - os.system("service plc stop") - print ("==================== Starting plc") - os.system("service plc start") +def show_variable (cdef, cread, cwrite, + category, variable,show_value,show_comments): + assert category.has_key('id') + assert variable.has_key('id') + + category_id = category ['id'] + variable_id = variable['id'] + + default_value = get_value(cdef,category_id,variable_id) + current_value = get_current_value(cread,cwrite,category_id,variable_id) + varname = get_varname (cread,category_id, variable_id) + if show_comments : + print_name_comments (cdef, category_id, variable_id) + if show_value: + print "%s = %s" % (varname,current_value) + else: + print "%s" % (varname) + +def show_variables_all (cdef, cread, cwrite, show_value, show_comments): + for (category_id, (category, variables)) in cread.variables().iteritems(): + print ("========== Category = %s" % category_id.upper()) + for variable in variables.values(): + show_variable (cdef, cread, cwrite, + category, variable,show_value,show_comments) + +def show_variables_category (cdef, cread, cwrite, cid, show_value,show_comments): + cid=cid.lower() + CID=cid.upper() + print ("========== Category = %s" % CID) + for vid in list_category(cdef,cid): + (category,variable) = cdef.locate_varname(vid.upper()) + show_variable (cdef, cread, cwrite, category, variable, + show_value,show_comments) #################### -mainloop_usage= """Available commands -c\tEdits commonly tuned variables -e\tEdits all variables -p\tPrints all locally-customized vars and values -e \tPrompts (edit) fro variable -p \tShows current setting for -l\tlists all known variables -w\tsaves & consolidates -r\trestarts plc service -q\tQuits without saving ---- -Typical usage involves: c, [p,] w, r -""" +re_mainloop_0arg="^(?P[uUwrqlLsSeEcvVhH\?])[ \t]*$" +re_mainloop_1arg="^(?P[sSeEvV])[ \t]+(?P\w+)$" +matcher_mainloop_0arg=re.compile(re_mainloop_0arg) +matcher_mainloop_1arg=re.compile(re_mainloop_1arg) -re_mainloop_var="^(?P[pe])[ \t]+(?P\w+)$" -matcher_mainloop_var=re.compile(re_mainloop_var) - -common_variables=("PLC_NAME", - "PLC_ROOT_USER", - "PLC_ROOT_PASSWORD", - "PLC_MAIL_SUPPORT_ADDRESS", - "PLC_DB_HOST", - "PLC_API_HOST", - "PLC_WWW_HOST", - "PLC_BOOT_HOST", - "PLC_NET_DNS1", - "PLC_NET_DNS2") - -def mainloop (cdef, cread, cwrite,main_config, site_config, consolidated_config): +def mainloop (cdef, cread, cwrite, default_config, site_config, consolidated_config): while True: try: - answer = raw_input("Enter command (c for usual changes, w to save, ? for help) ").strip() + answer = raw_input("Enter command (u for usual changes, w to save, ? for help) ").strip() except EOFError: answer ="" - answer=answer.lower() - if (answer == "") or (answer == "?") or (answer == "h"): + if (answer == "") or (answer in "?hH"): print mainloop_usage - elif (answer == "q"): + continue + groups_parse = matcher_mainloop_0arg.match(answer) + command=None + if (groups_parse): + command = groups_parse.group('command') + arg=None + else: + groups_parse = matcher_mainloop_1arg.match(answer) + if (groups_parse): + command = groups_parse.group('command') + arg=groups_parse.group('arg') + if not command: + print ("Unknown command >%s< -- use h for help" % answer) + continue + + show_comments=command.isupper() + command=command.lower() + + mode='ALL' + if arg: + mode=None + arg=arg.lower() + variables=list_category (cdef,arg) + if len(variables): + # category_id as the category name + # variables as the list of variable names + mode='CATEGORY' + category_id=arg + arg=arg.upper() + (category,variable)=cdef.locate_varname(arg) + if variable: + # category/variable as output by locate_varname + mode='VARIABLE' + if not mode: + print "%s: no such category or variable" % arg + continue + + if (command in "qQ"): # todo check confirmation return - elif (answer == "e"): - prompt_all_variables(cdef, cread, cwrite) - elif (answer == "w"): + elif (command in "wW"): try: cwrite.save(site_config) except: print ("Could not save -- fix write access on %s" % site_config) break print ("Wrote %s" % site_config) - consolidate(main_config, site_config, consolidated_config) + consolidate(default_config, site_config, consolidated_config) print ("You might want to type 'r' (restart plc) or 'q' (quit)") - elif (answer == "l"): - print ("Config involves the following variables") - sys.stdout.write(cread.output_variables()) - elif (answer == "p"): - print ("Current site config") - sys.stdout.write(cwrite.output_shell(False)) - elif (answer == "c"): + elif (command == "u"): try: - for varname in common_variables: + for varname in usual_variables: (category,variable) = cdef.locate_varname(varname) - prompt_variable(cdef, cread, cwrite, category, variable) + prompt_variable(cdef, cread, cwrite, category, variable, False) except Exception, inst: if (str(inst) != 'BailOut'): raise - elif (answer == "r"): + elif (command == "r"): restart_plc() + elif (command == "c"): + print_categories(cread) + elif (command in "eE"): + if mode == 'ALL': + prompt_variables_all(cdef, cread, cwrite,show_comments) + elif mode == 'CATEGORY': + prompt_variables_category(cdef,cread,cwrite,category_id,show_comments) + elif mode == 'VARIABLE': + try: + prompt_variable (cdef,cread,cwrite,category,variable, + show_comments,False) + except Exception, inst: + if (str(inst) != 'BailOut'): + raise + elif (command in "vVsSlL"): + show_value=(command in "sSlL") + (c1,c2,c3) = (cdef, cread, cwrite) + if (command in "lL"): + (c1,c2,c3) = (cwrite,cwrite,cwrite) + if mode == 'ALL': + show_variables_all(c1,c2,c3,show_value,show_comments) + elif mode == 'CATEGORY': + show_variables_category(c1,c2,c3,category_id,show_value,show_comments) + elif mode == 'VARIABLE': + show_variable (c1,c2,c3,category,variable,show_value,show_comments) + else: + print ("Unknown command >%s< -- use h for help" % answer) + +#################### +def check_dir (config_file): + dirname = os.path.dirname (config_file) + if (not os.path.exists (dirname)): + print "Config file %s located under a non-existing directory" % config_file + answer=raw_input("Want to create %s [y]/n ? " % dirname) + answer = answer.lower() + if (answer == 'n'): + print "Cannot proceed - good bye" + sys.exit(1) else: - groups_var = matcher_mainloop_var.match(answer) - if (groups_var): - command = groups_var.group('command') - varname = groups_var.group('varname') - (category,variable) = cdef.locate_varname(varname) - if not category: - print "Unknown variable %s" % varname - elif (command == 'p'): - print ("%s = %s" % (varname,get_value(cwrite, - category['id'], - variable['id']))) - else: - try: - prompt_variable(cdef, cread, cwrite, category,variable) - except Exception, inst: - if (str(inst) != 'BailOut'): - raise + os.makedirs(dirname,0755) + if (not os.path.exists (dirname)): + print "Cannot create dir %s - exiting" % dirname + sys.exit(1) else: - print ("Unknown command >%s<" % answer) + print "Created directory %s" % dirname + #################### def main (): - save = True command=sys.argv[0] argv = sys.argv[1:] + + save = True + # default is myplc (non -devel) unless -d is specified + init_flavour("boot") + optlist,list = getopt.getopt(argv,":dhv") + for opt in optlist: + if opt[0] == "-h": + usage() + if opt[0] == "-v": + print ("This is %s - %s" %(command,release_rev)) + sys.exit(1) + if opt[0] == "-d": + init_flavour("devel") + argv=argv[1:] + if len(argv) == 0: - (main_config,site_config,consolidated_config) = (def_main_config, def_site_config, def_consolidated_config) + (default_config,site_config,consolidated_config) = (def_default_config, def_site_config, def_consolidated_config) elif len(argv) == 1: - (main_config,site_config,consolidated_config) = (argv[1], def_site_config, def_consolidated_config) + (default_config,site_config,consolidated_config) = (argv[0], def_site_config, def_consolidated_config) elif len(argv) == 2: - (main_config, site_config,consolidated_config) = (argv[1], argv[2], def_consolidated_config) + (default_config, site_config,consolidated_config) = (argv[0], argv[1], def_consolidated_config) elif len(argv) == 3: - (main_config, site_config,consolidated_config) = argv + (default_config, site_config,consolidated_config) = argv else: usage() + for c in (default_config,site_config,consolidated_config): + check_dir (c) + try: # the default settings only - read only - cdef = PLCConfiguration(main_config) + cdef = PLCConfiguration(default_config) # in effect : default settings + local settings - read only - cread = PLCConfiguration(main_config) + cread = PLCConfiguration(default_config) except: print ("default config files not found, is myplc installed ?") @@ -267,8 +477,7 @@ def main (): except: cwrite = PLCConfiguration() - print ("This is %s - %s -- Type ? at the prompt for help" %(command,release)) - mainloop (cdef, cread, cwrite,main_config, site_config, consolidated_config) + mainloop (cdef, cread, cwrite,default_config, site_config, consolidated_config) return 0 if __name__ == '__main__':