summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCsaba Henk <csaba@gluster.com>2011-02-07 20:42:24 +0000
committerAnand V. Avati <avati@dev.gluster.com>2011-02-10 22:17:54 -0800
commit07402f590e12b097e8267e924e0ae69d9b8964fb (patch)
tree5828f0b4514ad36516509ff119cbf2a6b4d5b5a2
parentebd7e1771c69a056f0456ff2dccac4319806f63b (diff)
syncdaemon: config revamp #3: implement command line get/set/del interface to configuration
The INI style config file has following type of sections: - [global] - [peers <local>] - [peers <local> <remote>] Option dispatch to sections is derived from command line (ie., [global] if no arg given, [peers <local>] with <local> being the only arg, [peers <local> <remote>] if <local> and <remote> args are provided). So this all happens under the hood, gsyncd users need not to specify sections. New command line options: - query options: --config-get-all --config-get OPT - modify options: --config-set OPT VAL --config-del OPT Signed-off-by: Csaba Henk <csaba@gluster.com> Signed-off-by: Anand V. Avati <avati@dev.gluster.com> BUG: 1570 (geosync related changes) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1570
-rw-r--r--configinterface.py50
-rw-r--r--xlators/features/marker/utils/syncdaemon/gsyncd.py47
2 files changed, 82 insertions, 15 deletions
diff --git a/configinterface.py b/configinterface.py
new file mode 100644
index 000000000..7bc1d4731
--- /dev/null
+++ b/configinterface.py
@@ -0,0 +1,50 @@
+import ConfigParser
+
+DEF_SECT = 'global'
+
+class GConffile(object):
+
+ def __init__(self, path, peers):
+ if peers:
+ self.section = 'peers ' + ' '.join(peers)
+ else:
+ self.section = DEF_SECT
+ self.path = path
+ self.config = ConfigParser.RawConfigParser({}, dict)
+ self.config.read(path)
+
+ def update_to(self, dct):
+ for sect in set([DEF_SECT, self.section]):
+ if self.config.has_section(sect):
+ dct.update(self.config._sections[sect])
+
+ def get(self, opt=None):
+ d = {}
+ self.update_to(d)
+ if opt:
+ d = {opt: d.get(opt, "")}
+ for k, v in d.iteritems():
+ if k == '__name__':
+ continue
+ print("%s: %s" % (k, v))
+
+ def write(self):
+ f = None
+ try:
+ f = open(self.path, 'wb')
+ self.config.write(f)
+ finally:
+ if f:
+ f.close()
+
+ def set(self, opt, val):
+ if not self.config.has_section(self.section):
+ self.config.add_section(self.section)
+ self.config.set(self.section, opt, val)
+ self.write()
+
+ def delete(self, opt):
+ if not self.config.has_section(self.section):
+ return
+ if self.config.remove_option(self.section, opt):
+ self.write()
diff --git a/xlators/features/marker/utils/syncdaemon/gsyncd.py b/xlators/features/marker/utils/syncdaemon/gsyncd.py
index c414c2a9c..f8200dd58 100644
--- a/xlators/features/marker/utils/syncdaemon/gsyncd.py
+++ b/xlators/features/marker/utils/syncdaemon/gsyncd.py
@@ -8,13 +8,13 @@ import logging
import signal
import select
import shutil
-import ConfigParser
import optparse
from optparse import OptionParser, SUPPRESS_HELP
from logging import Logger
from errno import EEXIST, ENOENT
from gconf import gconf
+from configinterface import GConffile
import resource
class GLogger(Logger):
@@ -177,23 +177,30 @@ def main_i():
op.add_option('--debug', dest="go_daemon", action='callback', callback=lambda *a: (store_local_curry('dont')(*a),
a[-1].values.__dict__.get('log_level') or \
a[-1].values.__dict__.update(log_level='DEBUG')))
+ op.add_option('--config-get', metavar='OPT', type=str, dest='config', action='callback', callback=store_local)
+ op.add_option('--config-get-all', dest='config', action='callback', callback=store_local_curry(True))
+ op.add_option('--config-set', metavar='OPT VAL', type=str, nargs=2, dest='config', action='callback', callback=store_local)
+ op.add_option('--config-del', metavar='OPT', type=str, dest='config', action='callback', callback=lambda o, oo, vx, p:
+ store_local(o, oo, (vx, False), p))
+
# precedence for sources of values: 1) commandline, 2) cfg file, 3) defaults
# -- for this to work out we need to tell apart defaults from explicitly set
# options... so churn out the defaults here and call the parser with virgin
# values container.
defaults = op.get_default_values()
opts, args = op.parse_args(values=optparse.Values())
- if not (len(args) == 2 or (len(args) == 1 and rconf.get('listen'))):
+ if not (len(args) == 2 or (len(args) == 1 and rconf.get('listen')) or (len(args) <= 2 and rconf.get('config'))):
sys.stderr.write("error: incorrect number of arguments\n\n")
sys.stderr.write(op.get_usage() + "\n")
sys.exit(1)
- local = resource.parse_url(args[0])
- remote = None
- if len(args) > 1:
- remote = resource.parse_url(args[1])
- if not local.can_connect_to(remote):
- raise RuntimeError("%s cannot work with %s" % (local.path, remote and remote.path))
+ local = remote = None
+ if args:
+ local = resource.parse_url(args[0])
+ if len(args) > 1:
+ remote = resource.parse_url(args[1])
+ if not local.can_connect_to(remote):
+ raise RuntimeError("%s cannot work with %s" % (local.path, remote and remote.path))
pa = ([], [])
canon = [False, True]
for x in (local, remote):
@@ -201,15 +208,25 @@ def main_i():
for i in range(2):
pa[i].append(x.get_url(canonical=canon[i]))
peers, canon_peers = pa
-
- gconf.__dict__.update(defaults.__dict__)
if not 'config_file' in rconf:
rconf['config_file'] = os.path.join(os.path.dirname(sys.argv[0]), "conf/gsyncd.conf")
- cfg = ConfigParser.RawConfigParser({}, dict)
- cfg.read(rconf['config_file'])
- for sect in ('global', 'peers ' + ' '.join(canon_peers)):
- if cfg.has_section(sect):
- gconf.__dict__.update(cfg._sections[sect])
+ gcnf = GConffile(rconf['config_file'], canon_peers)
+
+ confdata = rconf.get('config')
+ if confdata:
+ if isinstance(confdata, tuple):
+ if confdata[1]:
+ gcnf.set(*confdata)
+ else:
+ gcnf.delete(confdata[0])
+ else:
+ if confdata == True:
+ confdata = None
+ gcnf.get(confdata)
+ return
+
+ gconf.__dict__.update(defaults.__dict__)
+ gcnf.update_to(gconf.__dict__)
gconf.__dict__.update(opts.__dict__)
go_daemon = rconf['go_daemon']