# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id$
-#
import codecs
import os
import re
-import readline
import sys
import textwrap
import time
You may also save() the configuration. If a file path or object is
not specified, the configuration will be written to the file path
or object that was first loaded.
-
+
plc.save()
plc.save("/etc/planetlab/plc_config.xml")
"""
It looks for filled-in values in the order of, local object (self),
followed by cread (read values), and finally default values.
- Arguments:
+ Arguments:
default configuration
site configuration
if not category.has_key('id') or type(category['id']) not in types.StringTypes:
return
-
+
category_id = category['id'].lower()
if self._variables.has_key(category_id):
for tag in ['name', 'value', 'description']:
if variable.has_key(tag):
self._set_text_of_child(variable_element, tag, variable[tag])
-
+
if category_element.getElementsByTagName('variablelist'):
variablelist_element = category_element.getElementsByTagName('variablelist')[0]
else:
(variable, category) when found
(None, None) otherwise
"""
-
+
for (category_id, (category, variables)) in self._variables.iteritems():
for variable in variables.values():
(id, name, value, comments) = self._sanitize_variable(category_id, variable)
for attribute in ['type']:
if package.has_key(attribute):
packagereq_element.setAttribute(attribute, package[attribute])
-
+
if group_element.getElementsByTagName('packagelist'):
packagelist_element = group_element.getElementsByTagName('packagelist')[0]
else:
return buf.getvalue()
+ def validate_type(self, variable_type, value):
+
+ # ideally we should use the "validate_*" methods in PLCAPI or
+ # even declare some checks along with the default
+ # configuration (using RELAX NG?) but this shall work for now.
+ def ip_validator(val):
+ import socket
+ try:
+ socket.inet_aton(val)
+ return True
+ except: return False
+
+ def email_validator(val):
+ return re.match('\A[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9._\-]+\.[a-zA-Z]+\Z', val)
+
+ def boolean_validator (val):
+ return val in ['true', 'false']
+
+ validators = {
+ 'email' : email_validator,
+ 'ip': ip_validator,
+ 'boolean': boolean_validator,
+ }
+
+ # validate it if not a know type.
+ validator = validators.get(variable_type, lambda x: True)
+ return validator(value)
+
+
# xml.dom.minidom.Text.writexml adds surrounding whitespace to textual
# data when pretty-printing. Override this behavior.
####################
# GLOBAL VARIABLES
#
-release_id = "$Id:$"
-release_rev = "$Revision:$"
-release_url = "$URL:$"
-
g_configuration=None
usual_variables=None
config_dir=None
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
+ w\t\t\tWrite
+ r\t\t\tRestart %(service)s service
+ R\t\t\tReload %(service)s service (rebuild config files for sh, python....)
q\t\t\tQuit (without saving)
h/?\t\t\tThis help
---
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)
+ v/V [<cat>|<var>]\tList Variables (all, in category, single)
---
Typical usage involves: u, [l,] w, r, q
-""" % service
+""" % globals()
def usage ():
command_usage="%prog [options] [default-xml [site-xml [consolidated-xml]]]"
(category, variable) = config.get (category_id, variable_id)
return variable['value']
+def get_type (config, category_id, variable_id):
+ (category, variable) = config.get (category_id, variable_id)
+ return variable['type']
+
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 (cread,category_id,variable_id)
return result
-# refrain from using plc_config's _sanitize
+# 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()
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()
def reload_service ():
global service
- os.system("set -x ; service %s reload" % service)
-
+ os.system("set -x ; systemctl reload %s" % service)
+
####################
def restart_service ():
global service
print ("==================== Stopping %s" % service)
- os.system("service %s stop" % service)
+ os.system("systemctl stop %s" % service)
print ("==================== Starting %s" % service)
- os.system("service %s start" % service)
+ os.system("systemctl start %s" % service)
####################
def prompt_variable (cdef, cread, cwrite, category, variable,
while True:
default_value = get_value(cdef,category_id,variable_id)
+ variable_type = get_type(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)
else:
print "No support for next category"
else:
- variable['value'] = answer
- cwrite.set(category,variable)
- return
+ if cdef.validate_type(variable_type, answer):
+ variable['value'] = answer
+ cwrite.set(category,variable)
+ return
+ else:
+ print "Not a valid value"
def prompt_variables_all (cdef, cread, cwrite, show_comments):
try:
except Exception, inst:
if (str(inst) == 'NextCategory'): break
else: raise
-
+
except Exception, inst:
if (str(inst) == 'BailOut'): return
else: raise
continue
show_comments=command.isupper()
- command=command.lower()
mode='ALL'
if arg:
print "%s: no such category or variable" % arg
continue
- if (command in "qQ"):
+ if command in "qQ":
# todo check confirmation
return
- elif (command == "w"):
+ elif command == "w":
try:
# Confirm that various constraints are met before saving file.
validate_variables = g_configuration.get('validate_variables',{})
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"):
+ (service, service))
+ elif command in "uU":
global usual_variables
try:
for varname in usual_variables:
except Exception, inst:
if (str(inst) != 'BailOut'):
raise
- elif (command == "r"):
+ elif command == "r":
restart_service()
- elif (command == "R"):
+ elif command == "R":
reload_service()
- elif (command == "c"):
+ elif command == "c":
print_categories(cread)
- elif (command in "eE"):
+ elif command in "eE":
if mode == 'ALL':
prompt_variables_all(cdef, cread, cwrite,show_comments)
elif mode == 'CATEGORY':
prompt_variable (cdef,cread,cwrite,category,variable,
show_comments,False)
except Exception, inst:
- if (str(inst) != 'BailOut'):
+ if str(inst) != 'BailOut':
raise
- elif (command in "vVsSlL"):
+ elif command in "vVsSlL":
show_value=(command in "sSlL")
(c1,c2,c3) = (cdef, cread, cwrite)
- if (command in "lL"):
+ if command in "lL":
(c1,c2,c3) = (cwrite,cwrite,cwrite)
if mode == 'ALL':
show_variables_all(c1,c2,c3,show_value,show_comments)
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 = OptionParser(usage=usage())
parser.set_defaults(config_dir=configuration['config_dir'],
service=configuration['service'],
usual_variables=configuration['usual_variables'])
# local settings only, will be modified & saved
cwrite=PLCConfiguration()
-
+
try:
cread.load(site_config)
cwrite.load(site_config)