#!/bin/env python
-# Interactively prompts for variable values
-# expected arguments are
-# command -d [default-xml [custom-xml [ consolidated-xml ]]]
-
-# 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 traceback
-from optparse import OptionParser
-
-from plc_config import PLCConfiguration
-from plc_config import ConfigurationException
-
-####################
-release_id = "$Id$"
-release_rev = "$Revision$"
-release_url = "$URL$"
+import plc_config
-flavours={}
-
-def noop_validator(v):
- pass
-
-def plc_validator(validated_variables):
+def validator(validated_variables):
maint_user = validated_variables["PLC_API_MAINTENANCE_USER"]
root_user = validated_variables["PLC_ROOT_USER"]
if maint_user == root_user:
- raise ConfigurationException("PLC_API_MAINTENANCE_USER=%s cannot be the same as PLC_ROOT_USER=%s"%(maint_user,root_user))
-
-flavours["plc"]={'service':"plc",
- 'usual_variables':["PLC_NAME",
- "PLC_SHORTNAME",
- "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",
- 'validate_variables':{"PLC_API":"MAINTENANCE_USER","PLC":"ROOT_USER"},
- 'validator':plc_validator,
- }
-
-defined_flavour = "plc"
-
-# historically we could also configure the devel pkg....
-def init_flavour (flavour):
- global service, usual_variables
-
- global defined_flavour
- if flavours.has_key(flavour):
- defined_flavour = flavour
- else:
- defined_flavour = "plc"
-
- flav=flavours.get(flavour,flavours["plc"])
- service=flav["service"]
- usual_variables=flav["usual_variables"]
- config_dir=flav["config_dir"]
-
- global def_default_config, def_site_config, def_consolidated_config
- def_default_config= "%s/default_config.xml" % config_dir
- def_site_config = "%s/configs/site.xml" % config_dir
- def_consolidated_config = "%s/%s_config.xml" % (config_dir, service)
-
- global mainloop_usage
- mainloop_usage= """Available commands:
- Uppercase versions give variables comments, when available
- u/U\t\t\tEdit usual variables
- w/W\t\t\tWrite / Write & reload
- r\t\t\tRestart %s service
- q\t\t\tQuit (without saving)
- h/?\t\t\tThis help
----
- l/L [<cat>|<var>]\tShow Locally modified variables/values
- s/S [<cat>|<var>]\tShow variables/values (all, in category, single)
- e/E [<cat>|<var>]\tEdit variables (all, in category, single)
----
- c\t\t\tList categories
- v/V [<cat>|<var>]List Variables (all, in category, single)
----
-Typical usage involves: u, [l,] w, r, q
-""" % service
-
-def usage ():
- command_usage="%prog [options] [default-xml [site-xml [consolidated-xml]]]"
- init_flavour ("plc")
- command_usage +="""
-\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)
- return command_usage
-
-####################
-variable_usage= """Edit Commands :
-#\tShow variable comments
-.\tStops prompting, return to mainloop
-/\tCleans any site-defined value, reverts to default
-=\tShows default value
->\tSkips to next category
-?\tThis help
-"""
-
-####################
-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()
-
-# 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):
- global service
- 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 reload_service ():
- global service
- os.system("set -x ; service %s reload" % service)
-
-####################
-def restart_service ():
- global service
- 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')
-
- category_id = category ['id']
- variable_id = variable['id']
-
- while True:
- 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)
- prompt = "== %s : [%s] " % (varname,current_value)
- try:
- answer = raw_input(prompt).strip()
- except EOFError :
- raise Exception ('BailOut')
- except KeyboardInterrupt:
- print "\n"
- raise Exception ('BailOut')
-
- # no change
- if (answer == "") or (answer == current_value):
- return None
- elif (answer == "."):
- raise Exception ('BailOut')
- elif (answer == "#"):
- print_name_comments(cread,category_id,variable_id)
- elif (answer == "?"):
- print variable_usage.strip()
- elif (answer == "="):
- print ("%s defaults to %s" %(varname,default_value))
- # revert to default : remove from cwrite (i.e. site-config)
- elif (answer == "/"):
- 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_variables_all (cdef, cread, cwrite, show_comments):
- try:
- for (category_id, (category, variables)) in cread.variables().iteritems():
- print ("========== Category = %s" % category_id.upper())
- for variable in variables.values():
- try:
- newvar = prompt_variable (cdef, cread, cwrite, category, variable,
- show_comments, True)
- except Exception, inst:
- if (str(inst) == 'NextCategory'): break
- else: raise
-
- except Exception, inst:
- if (str(inst) == 'BailOut'): return
- else: raise
-
-def prompt_variables_category (cdef, cread, cwrite, cid, show_comments):
- cid=cid.lower()
- CID=cid.upper()
- try:
- 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:
- if (str(inst) == 'BailOut'): return
- else: raise
-
-####################
-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)
-
-####################
-re_mainloop_0arg="^(?P<command>[uUwrRqlLsSeEcvVhH\?])[ \t]*$"
-re_mainloop_1arg="^(?P<command>[sSeEvV])[ \t]+(?P<arg>\w+)$"
-matcher_mainloop_0arg=re.compile(re_mainloop_0arg)
-matcher_mainloop_1arg=re.compile(re_mainloop_1arg)
-
-def mainloop (cdef, cread, cwrite, default_config, site_config, consolidated_config):
- global service
- while True:
- try:
- answer = raw_input("Enter command (u for usual changes, w to save, ? for help) ").strip()
- except EOFError:
- answer =""
- except KeyboardInterrupt:
- print "\nBye"
- sys.exit()
-
- if (answer == "") or (answer in "?hH"):
- print mainloop_usage
- 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 (command == "w"):
- global defined_flavour
- try:
- # Confirm that various constraints are met before saving file.
- validate_variables = flavours[defined_flavour].get('validate_variables',{})
- validated_variables = cwrite.verify(cdef, cread, validate_variables)
- validator = flavours[defined_flavour].get('validator',noop_validator)
- validator(validated_variables)
- cwrite.save(site_config)
- except ConfigurationException, e:
- print "Save failed due to a configuration exception: %s" % e
- break;
- except:
- print traceback.print_exc()
- print ("Could not save -- fix write access on %s" % site_config)
- break
- print ("Wrote %s" % site_config)
- consolidate(default_config, site_config, consolidated_config)
- print ("You might want to type 'r' (restart %s), 'R' (reload %s) or 'q' (quit)" % \
- (service,service))
- elif (command == "u"):
- try:
- for varname in usual_variables:
- (category,variable) = cdef.locate_varname(varname)
- prompt_variable(cdef, cread, cwrite, category, variable, False)
- except Exception, inst:
- if (str(inst) != 'BailOut'):
- raise
- elif (command == "r"):
- restart_service()
- elif (command == "R"):
- reload_service()
- 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)
-
-####################
-# creates directory for file if not yet existing
-def check_dir (config_file):
- dirname = os.path.dirname (config_file)
- if (not os.path.exists (dirname)):
- try:
- os.makedirs(dirname,0755)
- except OSError, e:
- print "Cannot create dir %s due to %s - exiting" % (dirname,e)
- sys.exit(1)
-
- if (not os.path.exists (dirname)):
- print "Cannot create dir %s - exiting" % dirname
- sys.exit(1)
- else:
- print "Created directory %s" % dirname
-
-####################
-def main ():
+ errStr="PLC_API_MAINTENANCE_USER=%s cannot be the same as PLC_ROOT_USER=%s"%(maint_user,root_user)
+ raise plc_config.ConfigurationException(errStr)
+
+usual_variables = [ \
+ "PLC_NAME",
+ "PLC_SHORTNAME",
+ "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",
+ ]
+
+configuration={ \
+ 'name':'plc',
+ 'service':"plc",
+ 'usual_variables':usual_variables,
+ 'config_dir':"/etc/planetlab",
+ 'validate_variables':{"PLC_API":"MAINTENANCE_USER","PLC":"ROOT_USER"},
+ 'validator':validator,
+ }
+if __name__ == '__main__':
command=sys.argv[0]
argv = sys.argv[1:]
- save = True
- parser = OptionParser(usage=usage(), version="%prog 1.0" + release_rev + release_url )
- parser.set_defaults(flavour="plc",
- config="flavour.config",
- config_dir=None,
- service=None,
- usual_variables=[])
- parser.add_option("","--configdir",dest="config_dir",help="specify configuration directory")
- parser.add_option("","--service",dest="service",help="specify /etc/init.d style service name")
- parser.add_option("","--usual_variable",dest="usual_variables",action="append", help="add a usual variable")
- parser.add_option("","--flavour",dest="flavour", help="Sets the configuration flavour")
-
- (config,args) = parser.parse_args()
- if len(args)>3:
- parser.error("too many arguments")
-
- if config.flavour not in flavours:
- if config.service==None:
- parser.error("unknown flavour '%s'" % config.flavour)
- else:
- flavours[config.flavour]={}
- flavour=flavours[config.flavour]
- flavour['service']=config.service
- flavour['usual_variables']=config.usual_variables
- if config.config_dir==None:
- flavour['config_dir']="/etc/%s"%config.service
- else:
- flavour['config_dir']=config.config_dir
- else:
- flavour=flavours[config.flavour]
-
- # in case the config dir should be something other than /etc/planetlab
- if config.config_dir <> None:
- flavour['config_dir']=config.config_dir
-
- # add in new usual_variables defined on the command line
- for usual_variable in config.usual_variables:
- if usual_variable not in flavour['usual_variables']:
- flavour['usual_variables'].append(usual_variable)
-
- # intialize flavour
- init_flavour(config.flavour)
-
- (default_config,site_config,consolidated_config) = (def_default_config, def_site_config, def_consolidated_config)
- if len(args) >= 1:
- default_config=args[0]
- if len(args) >= 2:
- site_config=args[1]
- if len(args) == 3:
- consolidated_config=args[2]
-
- for c in (default_config,site_config,consolidated_config):
- check_dir (c)
-
- try:
- # the default settings only - read only
- cdef = PLCConfiguration(default_config)
-
- # in effect : default settings + local settings - read only
- cread = PLCConfiguration(default_config)
-
- except ConfigurationException, e:
- print ("Error %s in default config file %s" %(e,default_config))
- return 1
- except:
- print traceback.print_exc()
- print ("default config files %s not found, is myplc installed ?" % default_config)
- return 1
-
-
- # local settings only, will be modified & saved
- cwrite=PLCConfiguration()
-
- try:
- cread.load(site_config)
- cwrite.load(site_config)
- except:
- cwrite = PLCConfiguration()
-
- mainloop (cdef, cread, cwrite, default_config, site_config, consolidated_config)
- return 0
-
-if __name__ == '__main__':
- main()
+ plc_config.main(command,argv,configuration)
# $Id$
#
-import xml.dom.minidom
-from xml.parsers.expat import ExpatError
-from StringIO import StringIO
-import time
-import re
-import textwrap
import codecs
import os
+import re
+import readline
+import sys
+import textwrap
+import time
+import traceback
import types
-
+import xml.dom.minidom
+from xml.parsers.expat import ExpatError
+from StringIO import StringIO
+from optparse import OptionParser
class ConfigurationException(Exception): pass
writer.write(newl)
+####################
+# GLOBAL VARIABLES
+#
+release_id = "$Id:$"
+release_rev = "$Revision:$"
+release_url = "$URL:$"
+
+g_configuration=None
+usual_variables=None
+config_dir=None
+service=None
+
+def noop_validator(validated_variables):
+ pass
+
+
+# historically we could also configure the devel pkg....
+def init_configuration ():
+ global g_configuration
+ global usual_variables, config_dir, service
+
+ usual_variables=g_configuration["usual_variables"]
+ config_dir=g_configuration["config_dir"]
+ service=g_configuration["service"]
+
+ global def_default_config, def_site_config, def_consolidated_config
+ def_default_config= "%s/default_config.xml" % config_dir
+ def_site_config = "%s/configs/site.xml" % config_dir
+ def_consolidated_config = "%s/%s_config.xml" % (config_dir, service)
+
+ global mainloop_usage
+ mainloop_usage= """Available commands:
+ Uppercase versions give variables comments, when available
+ u/U\t\t\tEdit usual variables
+ w/W\t\t\tWrite / Write & reload
+ r\t\t\tRestart %s service
+ q\t\t\tQuit (without saving)
+ h/?\t\t\tThis help
+---
+ l/L [<cat>|<var>]\tShow Locally modified variables/values
+ s/S [<cat>|<var>]\tShow variables/values (all, in category, single)
+ e/E [<cat>|<var>]\tEdit variables (all, in category, single)
+---
+ c\t\t\tList categories
+ v/V [<cat>|<var>]List Variables (all, in category, single)
+---
+Typical usage involves: u, [l,] w, r, q
+""" % service
+
+def usage ():
+ command_usage="%prog [options] [default-xml [site-xml [consolidated-xml]]]"
+ init_configuration ()
+ command_usage +="""
+\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)
+ return command_usage
+
+####################
+variable_usage= """Edit Commands :
+#\tShow variable comments
+.\tStops prompting, return to mainloop
+/\tCleans any site-defined value, reverts to default
+=\tShows default value
+>\tSkips to next category
+?\tThis help
+"""
+
+####################
+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()
+
+# 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):
+ global service
+ 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 reload_service ():
+ global service
+ os.system("set -x ; service %s reload" % service)
+
+####################
+def restart_service ():
+ global service
+ 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')
+
+ category_id = category ['id']
+ variable_id = variable['id']
+
+ while True:
+ 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)
+ prompt = "== %s : [%s] " % (varname,current_value)
+ try:
+ answer = raw_input(prompt).strip()
+ except EOFError :
+ raise Exception ('BailOut')
+ except KeyboardInterrupt:
+ print "\n"
+ raise Exception ('BailOut')
+
+ # no change
+ if (answer == "") or (answer == current_value):
+ return None
+ elif (answer == "."):
+ raise Exception ('BailOut')
+ elif (answer == "#"):
+ print_name_comments(cread,category_id,variable_id)
+ elif (answer == "?"):
+ print variable_usage.strip()
+ elif (answer == "="):
+ print ("%s defaults to %s" %(varname,default_value))
+ # revert to default : remove from cwrite (i.e. site-config)
+ elif (answer == "/"):
+ 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_variables_all (cdef, cread, cwrite, show_comments):
+ try:
+ for (category_id, (category, variables)) in cread.variables().iteritems():
+ print ("========== Category = %s" % category_id.upper())
+ for variable in variables.values():
+ try:
+ newvar = prompt_variable (cdef, cread, cwrite, category, variable,
+ show_comments, True)
+ except Exception, inst:
+ if (str(inst) == 'NextCategory'): break
+ else: raise
+
+ except Exception, inst:
+ if (str(inst) == 'BailOut'): return
+ else: raise
+
+def prompt_variables_category (cdef, cread, cwrite, cid, show_comments):
+ cid=cid.lower()
+ CID=cid.upper()
+ try:
+ 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:
+ if (str(inst) == 'BailOut'): return
+ else: raise
+
+####################
+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)
+
+####################
+re_mainloop_0arg="^(?P<command>[uUwrRqlLsSeEcvVhH\?])[ \t]*$"
+re_mainloop_1arg="^(?P<command>[sSeEvV])[ \t]+(?P<arg>\w+)$"
+matcher_mainloop_0arg=re.compile(re_mainloop_0arg)
+matcher_mainloop_1arg=re.compile(re_mainloop_1arg)
+
+def mainloop (cdef, cread, cwrite, default_config, site_config, consolidated_config):
+ global service
+ while True:
+ try:
+ answer = raw_input("Enter command (u for usual changes, w to save, ? for help) ").strip()
+ except EOFError:
+ answer =""
+ except KeyboardInterrupt:
+ print "\nBye"
+ sys.exit()
+
+ if (answer == "") or (answer in "?hH"):
+ print mainloop_usage
+ 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 (command == "w"):
+ try:
+ # Confirm that various constraints are met before saving file.
+ validate_variables = g_configuration.get('validate_variables',{})
+ validated_variables = cwrite.verify(cdef, cread, validate_variables)
+ validator = g_configuration.get('validator',noop_validator)
+ validator(validated_variables)
+ cwrite.save(site_config)
+ except ConfigurationException, e:
+ print "Save failed due to a configuration exception: %s" % e
+ break;
+ except:
+ print traceback.print_exc()
+ print ("Could not save -- fix write access on %s" % site_config)
+ break
+ print ("Wrote %s" % site_config)
+ consolidate(default_config, site_config, consolidated_config)
+ print ("You might want to type 'r' (restart %s), 'R' (reload %s) or 'q' (quit)" % \
+ (service,service))
+ elif (command == "u"):
+ global usual_variables
+ try:
+ for varname in usual_variables:
+ (category,variable) = cdef.locate_varname(varname)
+ if not (category is None and variable is None):
+ prompt_variable(cdef, cread, cwrite, category, variable, False)
+ except Exception, inst:
+ if (str(inst) != 'BailOut'):
+ raise
+ elif (command == "r"):
+ restart_service()
+ elif (command == "R"):
+ reload_service()
+ 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)
+
+####################
+# creates directory for file if not yet existing
+def check_dir (config_file):
+ dirname = os.path.dirname (config_file)
+ if (not os.path.exists (dirname)):
+ try:
+ os.makedirs(dirname,0755)
+ except OSError, e:
+ print "Cannot create dir %s due to %s - exiting" % (dirname,e)
+ sys.exit(1)
+
+ if (not os.path.exists (dirname)):
+ print "Cannot create dir %s - exiting" % dirname
+ sys.exit(1)
+ else:
+ print "Created directory %s" % dirname
+
+####################
+def optParserSetup(configuration):
+ parser = OptionParser(usage=usage(), version="%prog 1.0" + release_rev + release_url )
+ parser.set_defaults(config_dir=configuration['config_dir'],
+ service=configuration['service'],
+ usual_variables=configuration['usual_variables'])
+ parser.add_option("","--configdir",dest="config_dir",help="specify configuration directory")
+ parser.add_option("","--service",dest="service",help="specify /etc/init.d style service name")
+ parser.add_option("","--usual_variable",dest="usual_variables",action="append", help="add a usual variable")
+ return parser
+
+def main(command,argv,configuration):
+ global g_configuration
+ g_configuration=configuration
+
+ parser = optParserSetup(configuration)
+ (config,args) = parser.parse_args()
+ if len(args)>3:
+ parser.error("too many arguments")
+
+ configuration['service']=config.service
+ configuration['usual_variables']=config.usual_variables
+ configuration['config_dir']=config.config_dir
+ # add in new usual_variables defined on the command line
+ for usual_variable in config.usual_variables:
+ if usual_variable not in configuration['usual_variables']:
+ configuration['usual_variables'].append(usual_variable)
+
+ # intialize configuration
+ init_configuration()
+
+ (default_config,site_config,consolidated_config) = (def_default_config, def_site_config, def_consolidated_config)
+ if len(args) >= 1:
+ default_config=args[0]
+ if len(args) >= 2:
+ site_config=args[1]
+ if len(args) == 3:
+ consolidated_config=args[2]
+
+ for c in (default_config,site_config,consolidated_config):
+ check_dir (c)
+
+ try:
+ # the default settings only - read only
+ cdef = PLCConfiguration(default_config)
+
+ # in effect : default settings + local settings - read only
+ cread = PLCConfiguration(default_config)
+
+ except ConfigurationException, e:
+ print ("Error %s in default config file %s" %(e,default_config))
+ return 1
+ except:
+ print traceback.print_exc()
+ print ("default config files %s not found, is myplc installed ?" % default_config)
+ return 1
+
+
+ # local settings only, will be modified & saved
+ cwrite=PLCConfiguration()
+
+ try:
+ cread.load(site_config)
+ cwrite.load(site_config)
+ except:
+ cwrite = PLCConfiguration()
+
+ mainloop (cdef, cread, cwrite, default_config, site_config, consolidated_config)
+ return 0
+
if __name__ == '__main__':
import sys
if len(sys.argv) > 1 and sys.argv[1] in ['build', 'install', 'uninstall']: