config with options
[sface.git] / sface / sficonfig.py
index 2ff64e7..542734e 100644 (file)
+# config for sface 
+# uses in this order
+# command-line args
+# ~/.sfi/sfi_config
+###
 
 import os
+from optparse import OptionParser
+
 
 class SfiConfig:
-    defaults = { 'SFI_AUTH' : None,
-                 'SFI_USER' : None,
-                 'SFI_SLICE' : None,
-                 'SFI_REGISTRY' : "http://www.planet-lab.org:12345",
-                 'SFI_AM' : "http://www.planet-lab.org:12346",
-                 'SFI_SM' : "http://www.planet-lab.org:12347",
-                 'SFACE_VERBOSE' : False,
-                 'SFACE_DEBUG' : False,
-                 }
+
+    d_registry= "http://www.planet-lab.org:12345"
+    d_slicemgr= "http://www.planet-lab.org:12347"
+    d_aggmgr=   "http://www.planet-lab.org:12346"
+
+    supported = [
+        # local code name, config variable name, default
+        ('slice',      'SFI_SLICE' ,   None,           '-s','--slice',         "slice HRN"),
+        ('user',       'SFI_USER',     None,           '-u','--user',          "user HRN"),
+        ('authority',  'SFI_AUTH',     None,           '-t','--auth',          "users's authority HRN"),
+        ('registry',   'SFI_REGISTRY', d_registry,     '-r','--registry',      "registry's URL"),
+        ('slicemgr',   'SFI_SM' ,      d_slicemgr,     '-m','--slicemgr',      "slice manager's URL"),
+        ('aggmgr',     'SFI_AM',       d_aggmgr,       '-a','--aggregate',     "aggregate manager's URL"),
+        ('verbose',    'SFACE_VERBOSE',False,          '-v','--verbose',       "UI verbosity"),
+        ('debug',      'SFACE_DEBUG',  False,          '-d','--debug',         "UI debug flag"),
+        ]
+
+    def fields (self):
+        return [ tup[0] for tup in SfiConfig.supported ]
+
+    def field_labels (self):
+        return [ (tup[0],tup[5]) for tup in SfiConfig.supported ]
+
+    def sfi_field (self, sfi):
+        for tuple in SfiConfig.supported:
+            if tuple[1]==sfi: return tuple[0]
+        return None
+
+    def field_default (self, field):
+        for tuple in SfiConfig.supported:
+            if tuple[0]==field: return tuple[2]
+        return None
+
+    # xxx todo - need for validators - not even sure this is still useful
+    def define_accessors (self):
+        for (field,sfi,default,_,__,___) in SfiConfig.supported:
+            self.define_accessor (field,sfi,default)
+
+    def define_accessor (self,field,sfi,default):
+        get_name="get" + field.capitalize();
+        if not hasattr(SfiConfig,get_name):
+            def get_call (self): return getattr(self,field)
+            setattr (SfiConfig, get_name, get_call)
+        set_name="set" + field.capitalize();
+        if not hasattr(SfiConfig,set_name):
+            def set_call (self, newvalue): setattr (self, field, newvalue)
+            setattr (SfiConfig, set_name, set_call)
+
+    # the generic form of accessors
+    def get(self,field): return getattr(self,field)
+    def set(self,field,value): setattr(self,field,value)
 
     def __init__(self):
         self.read_config()
 
+    def filename (self):
+        return os.path.expanduser("~/.sfi/sfi_config")
+
     def read_config(self):
-        filename = os.path.expanduser("~/.sfi/sfi_config")
-        execfile(filename, SfiConfig.__dict__)
-        for (k,v) in SfiConfig.defaults.items():
-            if not hasattr(SfiConfig,k): setattr(SfiConfig,k,v)
-        if SfiConfig.SFACE_VERBOSE:
-            print "After reading config from %s"%filename
-            for (k,v) in SfiConfig.defaults.items():
-                print "%-20s: %r"%(k,getattr(SfiConfig,k))
+        tmp={}
+        try:
+            execfile(self.filename(), tmp)
+        except:
+            print "Warning - no config file found %s"%self.filename()
+            pass
+        for (field,sfi,default,_,__,___) in SfiConfig.supported:
+            if tmp.has_key(sfi):setattr(self,field,tmp[sfi])
+            else:               setattr(self,field,default)
+        self.display("After reading config from %s"%self.filename())
+
+    def display (self, msg):
+        if self.debug:
+            print msg
+            for k in self.fields():
+                print "%-20s: %r"%(k,getattr(self,k))
 
     def save_config(self):
-        config_keys = SfiConfig.defaults.keys()
-        configfile = os.path.expanduser("~/.sfi/sfi_config")
+        configfile = self.filename()
         tmpfile = configfile + ".tmp"
 
         out = open(tmpfile, "w")
-        for line in open(os.path.expanduser("~/.sfi/sfi_config")):
+        lineno=0
+        fields=self.fields()
+        for line in open(configfile):
+            lineno += 1
             try:
-                key, val = line.split('=')
-                key = key.strip()
+                sfi, val = line.split('=')
+                sfi = sfi.strip()
                 val = val.strip()
-                if key in config_keys:
-                    line = "%s = '%s'\n" % (key, getattr(self, key))
+                field=self.sfi_field(sfi)
+                if field:
+                    line = "%s = '%s'\n" % (sfi, getattr(self, field))
             except:
-                pass
+                if self.debug:
+                    import traceback
+                    print 'line',lineno,'ignored',line
             out.write(line)
         out.close()
 
         os.unlink(configfile)
         os.rename(tmpfile, configfile)
-                    
-
-    def getAuthority(self):
-        return SfiConfig.SFI_AUTH
-
-    def getUser(self):
-        return SfiConfig.SFI_USER
-
-    def setUser(self, user):
-        SfiConfig.SFI_USER = user
 
-        # Should probably get authority from user record instead...
-        a = user.split('.')
-        SfiConfig.SFI_AUTH = '.'.join(a[:len(a)-1])
-
-    def getSlice(self):
-        return SfiConfig.SFI_SLICE
-
-    def setSlice(self, slice):
-        SfiConfig.SFI_SLICE = slice
-
-    def registry(self):
-        return SfiConfig.SFI_REGISTRY
-
-    def slicemgr(self):
-        return SfiConfig.SFI_SM
-
-    def aggmgr(self):
-        return SfiConfig.SFI_AM
+    def add_options_to_OptionParser (self, parser):
+        for (field,_,default,short,long,msg) in SfiConfig.supported:
+            if default==True or default==False:
+                parser.add_option(short,long,dest=field,action="store_true",help=msg)
+            else:
+                parser.add_option(short,long,dest=field,action="store",default=None, help=msg)
+
+    def update_from_OptionParser (self, optparse_options):
+        for field in self.fields():
+            if not hasattr(optparse_options,field) : continue
+            value=getattr(optparse_options,field)
+            if value is not None:
+                setattr(self,field,getattr(optparse_options,field))
+        
+#    def setUser(self, user):
+#        SfiConfig.SFI_USER = user
+#
+#        # Should probably get authority from user record instead...
+#        a = user.split('.')
+#        SfiConfig.SFI_AUTH = '.'.join(a[:len(a)-1])
 
     def getSliceRSpecFile(self):
         return os.path.expanduser("~/.sfi/%s.rspec" % self.getSlice())
@@ -81,3 +138,4 @@ class SfiConfig:
 
 # configuration singleton
 config = SfiConfig()
+config.define_accessors()