renamed sficonfig into just config
[sface.git] / sface / config.py
diff --git a/sface/config.py b/sface/config.py
new file mode 100644 (file)
index 0000000..cb29cbb
--- /dev/null
@@ -0,0 +1,155 @@
+# config for sface 
+# uses in this order
+# command-line args
+# ~/.sfi/sfi_config
+###
+
+import os
+import types
+from optparse import OptionParser
+
+
+class Config:
+
+    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 Config.supported ]
+
+    def field_labels (self):
+        return [ (tup[0],tup[5]) for tup in Config.supported ]
+
+    def sfi_field (self, sfi):
+        for tuple in Config.supported:
+            if tuple[1]==sfi: return tuple[0]
+        return None
+
+    def field_default (self, field):
+        for tuple in Config.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 Config.supported:
+            self.define_accessor (field,sfi,default)
+
+    def define_accessor (self,field,sfi,default):
+        get_name="get" + field.capitalize();
+        if not hasattr(Config,get_name):
+            def get_call (self): return getattr(self,field)
+            setattr (Config, get_name, get_call)
+        set_name="set" + field.capitalize();
+        if not hasattr(Config,set_name):
+            def set_call (self, newvalue): setattr (self, field, newvalue)
+            setattr (Config, 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):
+        tmp={}
+        try:
+            execfile(self.filename(), tmp)
+        except:
+            print "Warning - no config file found %s"%self.filename()
+            pass
+        for (field,sfi,default,_,__,___) in Config.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):
+        configfile = self.filename()
+        tmpfile = configfile + ".tmp"
+
+        out = open(tmpfile, "w")
+        lineno=0
+        fields=self.fields()
+        for line in open(configfile):
+            lineno += 1
+            try:
+                sfi, val = line.split('=')
+                sfi = sfi.strip()
+                val = val.strip()
+                field=self.sfi_field(sfi)
+                if field:
+                    newval=getattr(self,field)
+                    if not self.is_bool_field(field): newval="'%s'"%newval
+                    line = "%s = %s\n" % (sfi, newval)
+            except:
+                if self.debug:
+                    import traceback
+                    print 'line',lineno,'ignored',line
+            out.write(line)
+        out.close()
+
+        os.unlink(configfile)
+        os.rename(tmpfile, configfile)
+
+    # check if a field is a boolean field
+    def is_bool_field(self, field):
+        for (f,_,default,__,___,____) in Config.supported:
+            if field==f: return isinstance(default,bool)
+        return None
+
+    # to accept strings as bools
+    def is_true(self,value):
+        if value==True: return True
+        if isinstance(value,types.StringTypes) and value.lower()=='true': return True
+
+    def add_options_to_OptionParser (self, parser):
+        for (field,_,default,short,long,msg) in Config.supported:
+            if isinstance(default,bool):
+                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):
+#        Config.SFI_USER = user
+#
+#        # Should probably get authority from user record instead...
+#        a = user.split('.')
+#        Config.SFI_AUTH = '.'.join(a[:len(a)-1])
+
+    def getSliceRSpecFile(self):
+        return os.path.expanduser("~/.sfi/%s.rspec" % self.getSlice())
+        
+
+# configuration singleton
+config = Config()
+config.define_accessors()