to be able to build on Darwin/OS X and other BSD-based systems.
[sfa.git] / geni-config-tty
1 #!/usr/bin/python
2
3 # Interactively prompts for variable values
4 # expected arguments are
5 # command -d [default-xml [custom-xml [ consolidated-xml ]]]
6 #
7 # -d is for the myplc-devel package
8
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
13
14 import sys
15 import os
16 import re
17 import readline
18 import traceback
19 from optparse import OptionParser
20
21 from geni.util.config import Config
22
23 usual_variables = ["GENI_REGISTRY_ROOT_AUTH",
24                    "GENI_REGISTRY_LEVEL1_AUTH",
25                    "GENI_REGISTRY_ENABLED",
26                    "GENI_REGISTRY_HOST", 
27                    "GENI_REGISTRY_PORT",
28                    "GENI_AGGREGATE_ENABLED",
29                    "GENI_AGGREGATE_HOST",
30                    "GENI_AGGREGATE_PORT",
31                    "GENI_SM_ENABLED",
32                    "GENI_SM_HOST",
33                    "GENI_SM_PORT",
34                    "GENI_PLC_USER",
35                    "GENI_PLC_PASSWORD",    
36                    "GENI_PLC_HOST",
37                    "GENI_PLC_PORT",
38                    "GENI_PLC_API_PATH"
39                    ]
40
41
42 mainloop_usage= """Available commands:
43  u/U\t\t\tEdit usual variables
44  w/W\t\t\tWrite / Write & reload
45  q\t\t\tQuit (without saving)
46  h/?\t\t\tThis help
47 ---
48  l/L [<var>]\tShow Locally modified variables/values
49  s/S [<var>]\tShow all current variables/values 
50  e/E [<var>]\tEdit variables (all, in category, single)
51 ---
52 """ 
53
54 command_usage="%prog [options]"
55 command_usage += """
56   Unless you specify the -d option, meaning you want to configure
57   using defaults without interactive prompts""" 
58
59 variable_usage= """Edit Commands :
60 .\tStops prompting, return to mainloop
61 =\tShows default value
62 ?\tThis help    
63 """
64
65 def save_config(changes, config_file):
66     # always validate before saving
67     changes = validate(changes) 
68     
69     cfile = open(config_file, 'r')
70     lines = cfile.readlines()
71     newlines = []
72     cfile.close()
73     for line in lines:
74         added = False
75         for variable in changes:
76             if line.startswith(variable):
77                 try:
78                     value = int(changes[variable])
79                     newline = '%s=%s\n' % (variable, value)
80                     newlines.append(newline)
81                 except:
82                     value = changes[variable]
83                     newline = '%s="%s"\n' % (variable, value)
84                     newlines.append(newline)
85                 added = True
86                 break
87         if not added:
88             newlines.append(line) 
89     
90     cfile = open(config_file, 'w')
91     cfile.writelines(newlines)
92     cfile.close()
93
94 def validate(changes):
95     defaults = get_defaults()
96     
97     if not changes:
98         return
99
100     # GENI_INTERFACE_HRN is GENI_REGISTRY_LEVEL1_AUTH, if thats blank it
101     # then defaults to GENI_REGISTRY_ROOT_AUTH 
102     # GENI_REGISTRY_LEVEL1_AUTH, so if either of these are present we must 
103     # update GENI_INTERFACE_HRN
104     if 'GENI_REGISTRY_ROOT_AUTH' in changes:
105         root_auth = changes['GENI_REGISTRY_ROOT_AUTH']
106     else:
107         root_auth = defaults['GENI_REGISTRY_ROOT_AUTH']
108              
109     if 'GENI_REGISTRY_LEVEL1_AUTH' in changes:
110         level1_auth = changes['GENI_REGISTRY_LEVEL1_AUTH']
111     else:
112         level1_auth = default['GENI_REGISTRY_LEVEL1_AUTH']
113                 
114     if level1_auth:
115         interface_hrn = level1_auth
116     else:
117         interface_hrn = root_auth
118     changes['GENI_INTERFACE_HRN'] = interface_hrn
119     return changes                            
120
121 def get_defaults():
122     geni_config = Config()
123     plc_vars = {'PLC_API_MAINTENANCE_PASSWORD': 'GENI_PLC_PASSWORD',
124                 'PLC_API_MAINTENANCE_USER': 'GENI_PLC_USER'
125                }
126     try:
127         from geni.util.config import plcConfig
128         plc_config = plcConfig
129     except:
130         plc_config = None
131     
132     defaults = {}
133     for var in dir(geni_config):
134         if var.startswith('GENI'):
135             value = eval("geni_config.%s" % var)
136             defaults[var] = value
137
138     # some defaults come from plc_config
139     for var in dir(plc_config):
140         if var in plc_vars:
141             value = eval("plc_config.%s" % var)
142             defaults[plc_vars[var]] = value
143
144     return defaults       
145
146 def prompt_variable(variable, default_config):
147     if variable in default_config:
148         default_value = default_config[variable]
149     else:
150         default_value = ""  
151    
152     while True:
153         prompt = "%(variable)s : [%(default_value)s] " % locals()
154         try: 
155             answer = raw_input(prompt).strip()
156         except EOFError:
157             raise Exception ('BailOut')
158         except KeyboardInterrupt:
159             print "\n"
160             raise Excception ('BailOut')
161
162         if (answer == "") or (answer == default_value):
163             return default_value
164         elif answer in ['""', "''"]:
165             return ""
166         elif (answer == "."):
167             raise Exception ('BailOut')
168         elif (answer == "?"):
169             print variable_usage.strip()
170         elif (answer == "="):
171             print ("%s defaults to %s" %(variable,default_value))
172         else:
173             return answer
174
175 def show_variable(variable, value_dict):
176     print "%s=%s" % (variable, value_dict[variable])                    
177     
178 def mainloop (default_config, config_file):
179     changes = {}
180     while True:
181         try:
182             answer = raw_input("Enter command (u for usual changes, w to save, ? for help) ").strip()
183         except EOFError:
184             answer =""
185         except KeyboardInterrupt:
186             print "\nBye"
187             sys.exit()
188
189         if (answer == "") or (answer in "?hH"):
190             print mainloop_usage
191             continue
192         if answer in ['?']:
193             print "help"  
194
195         if (answer in ["q","Q"]):
196             return
197         elif (answer == "w"):
198             save_config(changes, config_file)
199         elif (answer == "u"):
200             try: 
201                 for varname in usual_variables:
202                     changes[varname] = prompt_variable(varname, default_config)
203             except Exception, inst:
204                 if (str(inst) != 'BailOut'):
205                     raise
206         elif (answer in ["e","E"]):
207             try:
208                 prompt_variable (cdef,cread,cwrite,category,variable,
209                                  show_comments,False)
210             except Exception, inst:
211                 if (str(inst) != 'BailOut'):
212                     raise
213         elif (answer in "sS"):
214             for varname in usual_variables:
215                 show_variable (varname, default_config)
216         elif (answer in "lL"):
217             if not changes:
218                 print "No changes to display"
219             else:
220                 for varname in changes:
221                     show_variable(varname, changes)
222         else:
223             print ("Unknown command >%s< -- use h for help" % answer)
224
225 ####################
226 def main ():
227
228     command=sys.argv[0]
229     argv = sys.argv[1:]
230     save = True
231     parser = OptionParser(usage=command_usage, version="%prog 1.0")
232     parser.set_defaults(config_dir="/etc/geni",
233                         usual_variables=[])
234     parser.add_option("","--configdir",dest="config_dir",action="append", help="specify configuration directory")
235     parser.add_option("","--usual_variable",dest="usual_variables",action="append", help="add a usual variable")
236     parser.add_option("-d", "--default", action="count", help="dont prompt for values, just use defaults")
237     (config,args) = parser.parse_args()
238     if len(args)>3:
239         parser.error("too many arguments")
240
241     config_dir = parser.values.config_dir
242     config_file = os.sep.join([config_dir, 'geni_config'])
243     defaults = get_defaults()
244     # if -d is specified dont prompt, just configure with defaults
245     if '-d' in argv:
246         save_config(defaults, config_file)
247     else:        
248         mainloop (defaults, config_file)
249     return 0
250
251 if __name__ == '__main__':
252     main()