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",
42 "PLC_MAIL_SUPPORT_ADDRESS",
50 config_dir = "/etc/planetlab"
51 global def_default_config
52 def_default_config= "%s/default_config.xml" % config_dir
53 global def_site_config
54 def_site_config = "%s/configs/site.xml" % config_dir
55 global def_consolidated_config
56 def_consolidated_config = "%s/plc_config.xml" % config_dir
59 mainloop_usage= """Available commands:
60 Uppercase versions give variables comments, when available
61 u/U\t\t\tEdit usual variables
62 w\t\t\tWrite & consolidate
63 r\t\t\tRestart %s service
64 q\t\t\tQuit (without saving)
67 l/L [<cat>|<var>]\tShow Locally modified variables/values
68 s/S [<cat>|<var>]\tShow variables/values (all, in category, single)
69 e/E [<cat>|<var>]\tEdit variables (all, in category, single)
71 c\t\t\tList categories
72 v/V [<cat>|<var>]List Variables (all, in category, single)
74 Typical usage involves: u, [l,] w, r, q
78 command_usage="Usage: %s [-d] [-v] [default-xml [site-xml [consolidated-xml]]]"% sys.argv[0]
81 -v shows version and exits
82 \t default-xml defaults to %s
83 \t site-xml defaults to %s
84 \t consolidated-xml defaults to %s""" % (def_default_config,def_site_config, def_consolidated_config)
86 Unless you specify the -d option, meaning you want to configure
87 myplc-devel instead of regular myplc, in which case"""
88 init_flavour ("devel")
90 \t default-xml defaults to %s
91 \t site-xml defaults to %s
92 \t consolidated-xml defaults to %s""" % (def_default_config,def_site_config, def_consolidated_config)
97 variable_usage= """Edit Commands :
98 #\tShow variable comments
99 .\tStops prompting, return to mainloop
100 /\tCleans any site-defined value, reverts to default
101 =\tShows default value
102 >\tSkips to next category
107 def get_value (config, category_id, variable_id):
108 (category, variable) = config.get (category_id, variable_id)
109 return variable['value']
111 def get_current_value (cread, cwrite, category_id, variable_id):
112 # the value stored in cwrite, if present, is the one we want
114 result=get_value (cwrite,category_id,variable_id)
116 result=get_value (cread,category_id,variable_id)
119 # refrain from using plc_config's _sanitize
120 def get_varname (config, category_id, variable_id):
121 (category, variable) = config.get (category_id, variable_id)
122 return (category_id+"_"+variable['id']).upper()
124 # could not avoid using _sanitize here..
125 def get_name_comments (config, cid, vid):
127 (category, variable) = config.get (cid, vid)
128 (id, name, value, comments) = config._sanitize_variable (cid,variable)
129 return (name,comments)
133 def print_name_comments (config, cid, vid):
134 (name,comments)=get_name_comments(config,cid,vid)
136 print "### %s" % name
138 for line in comments:
141 print "!!! No comment associated to %s_%s" % (cid,vid)
144 def list_categories (config):
146 for (category_id, (category, variables)) in config.variables().iteritems():
147 result += [category_id]
150 def print_categories (config):
151 print "Known categories"
152 for cid in list_categories(config):
153 print "%s" % (cid.upper())
156 def list_category (config, cid):
158 for (category_id, (category, variables)) in config.variables().iteritems():
159 if (cid == category_id):
160 for variable in variables.values():
161 result += ["%s_%s" %(cid,variable['id'])]
164 def print_category (config, cid, show_comments=True):
167 vids=list_category(config,cid)
169 print "%s : no such category"%CID
171 print "Category %s contains" %(CID)
176 def consolidate (default_config, site_config, consolidated_config):
178 conso = PLCConfiguration (default_config)
179 conso.load (site_config)
180 conso.save (consolidated_config)
181 except Exception, inst:
182 print "Could not consolidate, %s" % (str(inst))
184 print ("Merged\n\t%s\nand\t%s\ninto\t%s"%(default_config,site_config,
185 consolidated_config))
186 os.system("set -x ; service plc reload")
190 print ("==================== Stopping %s" % service)
191 os.system("service %s stop" % service)
192 print ("==================== Starting %s" % service)
193 os.system("service %s start" % service)
196 def prompt_variable (cdef, cread, cwrite, category, variable,
197 show_comments, support_next=False):
199 assert category.has_key('id')
200 assert variable.has_key('id')
202 category_id = category ['id']
203 variable_id = variable['id']
206 default_value = get_value(cdef,category_id,variable_id)
207 current_value = get_current_value(cread,cwrite,category_id, variable_id)
208 varname = get_varname (cread,category_id, variable_id)
211 print_name_comments (cdef, category_id, variable_id)
212 prompt = "== %s : [%s] " % (varname,current_value)
214 answer = raw_input(prompt).strip()
216 raise Exception ('BailOut')
219 if (answer == "") or (answer == current_value):
221 elif (answer == "."):
222 raise Exception ('BailOut')
223 elif (answer == "#"):
224 print_name_comments(cread,category_id,variable_id)
225 elif (answer == "?"):
226 print variable_usage.strip()
227 elif (answer == "="):
228 print ("%s defaults to %s" %(varname,default_value))
229 # revert to default : remove from cwrite (i.e. site-config)
230 elif (answer == "/"):
231 cwrite.delete(category_id,variable_id)
232 print ("%s reverted to %s" %(varname,default_value))
234 elif (answer == ">"):
236 raise Exception ('NextCategory')
238 print "No support for next category"
240 variable['value'] = answer
241 cwrite.set(category,variable)
244 def prompt_variables_all (cdef, cread, cwrite, show_comments):
246 for (category_id, (category, variables)) in cread.variables().iteritems():
247 print ("========== Category = %s" % category_id.upper())
248 for variable in variables.values():
250 newvar = prompt_variable (cdef, cread, cwrite, category, variable,
252 except Exception, inst:
253 if (str(inst) == 'NextCategory'): break
256 except Exception, inst:
257 if (str(inst) == 'BailOut'): return
260 def prompt_variables_category (cdef, cread, cwrite, cid, show_comments):
264 print ("========== Category = %s" % CID)
265 for vid in list_category(cdef,cid):
266 (category,variable) = cdef.locate_varname(vid.upper())
267 newvar = prompt_variable (cdef, cread, cwrite, category, variable,
268 show_comments, False)
269 except Exception, inst:
270 if (str(inst) == 'BailOut'): return
274 def show_variable (cdef, cread, cwrite,
275 category, variable,show_value,show_comments):
276 assert category.has_key('id')
277 assert variable.has_key('id')
279 category_id = category ['id']
280 variable_id = variable['id']
282 default_value = get_value(cdef,category_id,variable_id)
283 current_value = get_current_value(cread,cwrite,category_id,variable_id)
284 varname = get_varname (cread,category_id, variable_id)
286 print_name_comments (cdef, category_id, variable_id)
288 print "%s = %s" % (varname,current_value)
290 print "%s" % (varname)
292 def show_variables_all (cdef, cread, cwrite, show_value, show_comments):
293 for (category_id, (category, variables)) in cread.variables().iteritems():
294 print ("========== Category = %s" % category_id.upper())
295 for variable in variables.values():
296 show_variable (cdef, cread, cwrite,
297 category, variable,show_value,show_comments)
299 def show_variables_category (cdef, cread, cwrite, cid, show_value,show_comments):
302 print ("========== Category = %s" % CID)
303 for vid in list_category(cdef,cid):
304 (category,variable) = cdef.locate_varname(vid.upper())
305 show_variable (cdef, cread, cwrite, category, variable,
306 show_value,show_comments)
309 re_mainloop_0arg="^(?P<command>[uUwrqlLsSeEcvVhH\?])[ \t]*$"
310 re_mainloop_1arg="^(?P<command>[sSeEvV])[ \t]+(?P<arg>\w+)$"
311 matcher_mainloop_0arg=re.compile(re_mainloop_0arg)
312 matcher_mainloop_1arg=re.compile(re_mainloop_1arg)
314 def mainloop (cdef, cread, cwrite, default_config, site_config, consolidated_config):
317 answer = raw_input("Enter command (u for usual changes, w to save, ? for help) ").strip()
320 if (answer == "") or (answer in "?hH"):
323 groups_parse = matcher_mainloop_0arg.match(answer)
326 command = groups_parse.group('command')
329 groups_parse = matcher_mainloop_1arg.match(answer)
331 command = groups_parse.group('command')
332 arg=groups_parse.group('arg')
334 print ("Unknown command >%s< -- use h for help" % answer)
337 show_comments=command.isupper()
338 command=command.lower()
344 variables=list_category (cdef,arg)
346 # category_id as the category name
347 # variables as the list of variable names
351 (category,variable)=cdef.locate_varname(arg)
353 # category/variable as output by locate_varname
356 print "%s: no such category or variable" % arg
359 if (command in "qQ"):
360 # todo check confirmation
362 elif (command in "wW"):
364 # Confirm that various constraints are met before saving file.
365 cwrite.verify(cdef, cread)
366 cwrite.save(site_config)
367 except ConfigurationException, e:
368 print "Save failed due to a configuration exception: %s" % e
371 import traceback; print traceback.print_exc()
372 print ("Could not save -- fix write access on %s" % site_config)
374 print ("Wrote %s" % site_config)
375 consolidate(default_config, site_config, consolidated_config)
376 print ("You might want to type 'r' (restart plc) or 'q' (quit)")
377 elif (command == "u"):
379 for varname in usual_variables:
380 (category,variable) = cdef.locate_varname(varname)
381 prompt_variable(cdef, cread, cwrite, category, variable, False)
382 except Exception, inst:
383 if (str(inst) != 'BailOut'):
385 elif (command == "r"):
387 elif (command == "c"):
388 print_categories(cread)
389 elif (command in "eE"):
391 prompt_variables_all(cdef, cread, cwrite,show_comments)
392 elif mode == 'CATEGORY':
393 prompt_variables_category(cdef,cread,cwrite,category_id,show_comments)
394 elif mode == 'VARIABLE':
396 prompt_variable (cdef,cread,cwrite,category,variable,
398 except Exception, inst:
399 if (str(inst) != 'BailOut'):
401 elif (command in "vVsSlL"):
402 show_value=(command in "sSlL")
403 (c1,c2,c3) = (cdef, cread, cwrite)
404 if (command in "lL"):
405 (c1,c2,c3) = (cwrite,cwrite,cwrite)
407 show_variables_all(c1,c2,c3,show_value,show_comments)
408 elif mode == 'CATEGORY':
409 show_variables_category(c1,c2,c3,category_id,show_value,show_comments)
410 elif mode == 'VARIABLE':
411 show_variable (c1,c2,c3,category,variable,show_value,show_comments)
413 print ("Unknown command >%s< -- use h for help" % answer)
416 # creates directory for file if not yet existing
417 def check_dir (config_file):
418 dirname = os.path.dirname (config_file)
419 if (not os.path.exists (dirname)):
420 os.makedirs(dirname,0755)
421 if (not os.path.exists (dirname)):
422 print "Cannot create dir %s - exiting" % dirname
425 print "Created directory %s" % dirname
434 # default is myplc (non -devel) unless -d is specified
436 optlist,list = getopt.getopt(argv,":dhv")
441 print ("This is %s - %s" %(command,release_rev))
444 init_flavour("devel")
448 (default_config,site_config,consolidated_config) = (def_default_config, def_site_config, def_consolidated_config)
450 (default_config,site_config,consolidated_config) = (argv[0], def_site_config, def_consolidated_config)
452 (default_config, site_config,consolidated_config) = (argv[0], argv[1], def_consolidated_config)
454 (default_config, site_config,consolidated_config) = argv
458 for c in (default_config,site_config,consolidated_config):
462 # the default settings only - read only
463 cdef = PLCConfiguration(default_config)
465 # in effect : default settings + local settings - read only
466 cread = PLCConfiguration(default_config)
469 print ("default config files not found, is myplc installed ?")
472 # local settings only, will be modified & saved
473 cwrite=PLCConfiguration()
476 cread.load(site_config)
477 cwrite.load(site_config)
479 cwrite = PLCConfiguration()
481 mainloop (cdef, cread, cwrite,default_config, site_config, consolidated_config)
484 if __name__ == '__main__':