3 # Interactively prompts for variable values
4 # expected arguments are
5 # command -d [default-xml [custom-xml [ consolidated-xml ]]]
7 # -d is for the myplc-devel package
9 # we use 3 instances of PLCConfiguration throughout:
10 # cdef : models the defaults, from plc_default.xml
11 # cread : merged from plc_default & configs/site.xml
12 # cwrite : site.xml + pending changes
20 from plc_config import PLCConfiguration
21 from plc_config import ConfigurationException
25 release_rev = "$Revision$"
27 def init_flavour (flavour):
29 global usual_variables
30 if (flavour == "devel"):
32 usual_variables=("PLC_DEVEL_FEDORA_URL",
34 config_dir = "/plc/devel/data/etc/planetlab"
37 usual_variables=("PLC_NAME",
43 "PLC_MAIL_SUPPORT_ADDRESS",
51 config_dir = "/etc/planetlab"
52 global def_default_config
53 def_default_config= "%s/default_config.xml" % config_dir
54 global def_site_config
55 def_site_config = "%s/configs/site.xml" % config_dir
56 global def_consolidated_config
57 def_consolidated_config = "%s/plc_config.xml" % config_dir
60 mainloop_usage= """Available commands:
61 Uppercase versions give variables comments, when available
62 u/U\t\t\tEdit usual variables
63 w\t\t\tWrite & consolidate
64 r\t\t\tRestart %s service
65 q\t\t\tQuit (without saving)
68 l/L [<cat>|<var>]\tShow Locally modified variables/values
69 s/S [<cat>|<var>]\tShow variables/values (all, in category, single)
70 e/E [<cat>|<var>]\tEdit variables (all, in category, single)
72 c\t\t\tList categories
73 v/V [<cat>|<var>]List Variables (all, in category, single)
75 Typical usage involves: u, [l,] w, r, q
79 command_usage="Usage: %s [-d] [-v] [default-xml [site-xml [consolidated-xml]]]"% sys.argv[0]
82 -v shows version and exits
83 \t default-xml defaults to %s
84 \t site-xml defaults to %s
85 \t consolidated-xml defaults to %s""" % (def_default_config,def_site_config, def_consolidated_config)
87 Unless you specify the -d option, meaning you want to configure
88 myplc-devel instead of regular myplc, in which case"""
89 init_flavour ("devel")
91 \t default-xml defaults to %s
92 \t site-xml defaults to %s
93 \t consolidated-xml defaults to %s""" % (def_default_config,def_site_config, def_consolidated_config)
98 variable_usage= """Edit Commands :
99 #\tShow variable comments
100 .\tStops prompting, return to mainloop
101 /\tCleans any site-defined value, reverts to default
102 =\tShows default value
103 >\tSkips to next category
108 def get_value (config, category_id, variable_id):
109 (category, variable) = config.get (category_id, variable_id)
110 return variable['value']
112 def get_current_value (cread, cwrite, category_id, variable_id):
113 # the value stored in cwrite, if present, is the one we want
115 result=get_value (cwrite,category_id,variable_id)
117 result=get_value (cread,category_id,variable_id)
120 # refrain from using plc_config's _sanitize
121 def get_varname (config, category_id, variable_id):
122 (category, variable) = config.get (category_id, variable_id)
123 return (category_id+"_"+variable['id']).upper()
125 # could not avoid using _sanitize here..
126 def get_name_comments (config, cid, vid):
128 (category, variable) = config.get (cid, vid)
129 (id, name, value, comments) = config._sanitize_variable (cid,variable)
130 return (name,comments)
134 def print_name_comments (config, cid, vid):
135 (name,comments)=get_name_comments(config,cid,vid)
137 print "### %s" % name
139 for line in comments:
142 print "!!! No comment associated to %s_%s" % (cid,vid)
145 def list_categories (config):
147 for (category_id, (category, variables)) in config.variables().iteritems():
148 result += [category_id]
151 def print_categories (config):
152 print "Known categories"
153 for cid in list_categories(config):
154 print "%s" % (cid.upper())
157 def list_category (config, cid):
159 for (category_id, (category, variables)) in config.variables().iteritems():
160 if (cid == category_id):
161 for variable in variables.values():
162 result += ["%s_%s" %(cid,variable['id'])]
165 def print_category (config, cid, show_comments=True):
168 vids=list_category(config,cid)
170 print "%s : no such category"%CID
172 print "Category %s contains" %(CID)
177 def consolidate (default_config, site_config, consolidated_config):
179 conso = PLCConfiguration (default_config)
180 conso.load (site_config)
181 conso.save (consolidated_config)
182 except Exception, inst:
183 print "Could not consolidate, %s" % (str(inst))
185 print ("Merged\n\t%s\nand\t%s\ninto\t%s"%(default_config,site_config,
186 consolidated_config))
187 os.system("set -x ; service plc reload")
191 print ("==================== Stopping %s" % service)
192 os.system("service %s stop" % service)
193 print ("==================== Starting %s" % service)
194 os.system("service %s start" % service)
197 def prompt_variable (cdef, cread, cwrite, category, variable,
198 show_comments, support_next=False):
200 assert category.has_key('id')
201 assert variable.has_key('id')
203 category_id = category ['id']
204 variable_id = variable['id']
207 default_value = get_value(cdef,category_id,variable_id)
208 current_value = get_current_value(cread,cwrite,category_id, variable_id)
209 varname = get_varname (cread,category_id, variable_id)
212 print_name_comments (cdef, category_id, variable_id)
213 prompt = "== %s : [%s] " % (varname,current_value)
215 answer = raw_input(prompt).strip()
217 raise Exception ('BailOut')
220 if (answer == "") or (answer == current_value):
222 elif (answer == "."):
223 raise Exception ('BailOut')
224 elif (answer == "#"):
225 print_name_comments(cread,category_id,variable_id)
226 elif (answer == "?"):
227 print variable_usage.strip()
228 elif (answer == "="):
229 print ("%s defaults to %s" %(varname,default_value))
230 # revert to default : remove from cwrite (i.e. site-config)
231 elif (answer == "/"):
232 cwrite.delete(category_id,variable_id)
233 print ("%s reverted to %s" %(varname,default_value))
235 elif (answer == ">"):
237 raise Exception ('NextCategory')
239 print "No support for next category"
241 variable['value'] = answer
242 cwrite.set(category,variable)
245 def prompt_variables_all (cdef, cread, cwrite, show_comments):
247 for (category_id, (category, variables)) in cread.variables().iteritems():
248 print ("========== Category = %s" % category_id.upper())
249 for variable in variables.values():
251 newvar = prompt_variable (cdef, cread, cwrite, category, variable,
253 except Exception, inst:
254 if (str(inst) == 'NextCategory'): break
257 except Exception, inst:
258 if (str(inst) == 'BailOut'): return
261 def prompt_variables_category (cdef, cread, cwrite, cid, show_comments):
265 print ("========== Category = %s" % CID)
266 for vid in list_category(cdef,cid):
267 (category,variable) = cdef.locate_varname(vid.upper())
268 newvar = prompt_variable (cdef, cread, cwrite, category, variable,
269 show_comments, False)
270 except Exception, inst:
271 if (str(inst) == 'BailOut'): return
275 def show_variable (cdef, cread, cwrite,
276 category, variable,show_value,show_comments):
277 assert category.has_key('id')
278 assert variable.has_key('id')
280 category_id = category ['id']
281 variable_id = variable['id']
283 default_value = get_value(cdef,category_id,variable_id)
284 current_value = get_current_value(cread,cwrite,category_id,variable_id)
285 varname = get_varname (cread,category_id, variable_id)
287 print_name_comments (cdef, category_id, variable_id)
289 print "%s = %s" % (varname,current_value)
291 print "%s" % (varname)
293 def show_variables_all (cdef, cread, cwrite, show_value, show_comments):
294 for (category_id, (category, variables)) in cread.variables().iteritems():
295 print ("========== Category = %s" % category_id.upper())
296 for variable in variables.values():
297 show_variable (cdef, cread, cwrite,
298 category, variable,show_value,show_comments)
300 def show_variables_category (cdef, cread, cwrite, cid, show_value,show_comments):
303 print ("========== Category = %s" % CID)
304 for vid in list_category(cdef,cid):
305 (category,variable) = cdef.locate_varname(vid.upper())
306 show_variable (cdef, cread, cwrite, category, variable,
307 show_value,show_comments)
310 re_mainloop_0arg="^(?P<command>[uUwrqlLsSeEcvVhH\?])[ \t]*$"
311 re_mainloop_1arg="^(?P<command>[sSeEvV])[ \t]+(?P<arg>\w+)$"
312 matcher_mainloop_0arg=re.compile(re_mainloop_0arg)
313 matcher_mainloop_1arg=re.compile(re_mainloop_1arg)
315 def mainloop (cdef, cread, cwrite, default_config, site_config, consolidated_config):
318 answer = raw_input("Enter command (u for usual changes, w to save, ? for help) ").strip()
321 if (answer == "") or (answer in "?hH"):
324 groups_parse = matcher_mainloop_0arg.match(answer)
327 command = groups_parse.group('command')
330 groups_parse = matcher_mainloop_1arg.match(answer)
332 command = groups_parse.group('command')
333 arg=groups_parse.group('arg')
335 print ("Unknown command >%s< -- use h for help" % answer)
338 show_comments=command.isupper()
339 command=command.lower()
345 variables=list_category (cdef,arg)
347 # category_id as the category name
348 # variables as the list of variable names
352 (category,variable)=cdef.locate_varname(arg)
354 # category/variable as output by locate_varname
357 print "%s: no such category or variable" % arg
360 if (command in "qQ"):
361 # todo check confirmation
363 elif (command in "wW"):
365 # Confirm that various constraints are met before saving file.
366 cwrite.verify(cdef, cread)
367 cwrite.save(site_config)
368 except ConfigurationException, e:
369 print "Save failed due to a configuration exception: %s" % e
372 import traceback; print traceback.print_exc()
373 print ("Could not save -- fix write access on %s" % site_config)
375 print ("Wrote %s" % site_config)
376 consolidate(default_config, site_config, consolidated_config)
377 print ("You might want to type 'r' (restart plc) or 'q' (quit)")
378 elif (command == "u"):
380 for varname in usual_variables:
381 (category,variable) = cdef.locate_varname(varname)
382 prompt_variable(cdef, cread, cwrite, category, variable, False)
383 except Exception, inst:
384 if (str(inst) != 'BailOut'):
386 elif (command == "r"):
388 elif (command == "c"):
389 print_categories(cread)
390 elif (command in "eE"):
392 prompt_variables_all(cdef, cread, cwrite,show_comments)
393 elif mode == 'CATEGORY':
394 prompt_variables_category(cdef,cread,cwrite,category_id,show_comments)
395 elif mode == 'VARIABLE':
397 prompt_variable (cdef,cread,cwrite,category,variable,
399 except Exception, inst:
400 if (str(inst) != 'BailOut'):
402 elif (command in "vVsSlL"):
403 show_value=(command in "sSlL")
404 (c1,c2,c3) = (cdef, cread, cwrite)
405 if (command in "lL"):
406 (c1,c2,c3) = (cwrite,cwrite,cwrite)
408 show_variables_all(c1,c2,c3,show_value,show_comments)
409 elif mode == 'CATEGORY':
410 show_variables_category(c1,c2,c3,category_id,show_value,show_comments)
411 elif mode == 'VARIABLE':
412 show_variable (c1,c2,c3,category,variable,show_value,show_comments)
414 print ("Unknown command >%s< -- use h for help" % answer)
417 # creates directory for file if not yet existing
418 def check_dir (config_file):
419 dirname = os.path.dirname (config_file)
420 if (not os.path.exists (dirname)):
421 os.makedirs(dirname,0755)
422 if (not os.path.exists (dirname)):
423 print "Cannot create dir %s - exiting" % dirname
426 print "Created directory %s" % dirname
435 # default is myplc (non -devel) unless -d is specified
437 optlist,list = getopt.getopt(argv,":dhv")
442 print ("This is %s - %s" %(command,release_rev))
445 init_flavour("devel")
449 (default_config,site_config,consolidated_config) = (def_default_config, def_site_config, def_consolidated_config)
451 (default_config,site_config,consolidated_config) = (argv[0], def_site_config, def_consolidated_config)
453 (default_config, site_config,consolidated_config) = (argv[0], argv[1], def_consolidated_config)
455 (default_config, site_config,consolidated_config) = argv
459 for c in (default_config,site_config,consolidated_config):
463 # the default settings only - read only
464 cdef = PLCConfiguration(default_config)
466 # in effect : default settings + local settings - read only
467 cread = PLCConfiguration(default_config)
470 print ("default config files not found, is myplc installed ?")
473 # local settings only, will be modified & saved
474 cwrite=PLCConfiguration()
477 cread.load(site_config)
478 cwrite.load(site_config)
480 cwrite = PLCConfiguration()
482 mainloop (cdef, cread, cwrite,default_config, site_config, consolidated_config)
485 if __name__ == '__main__':