diff options
Diffstat (limited to 'geo-replication/syncdaemon/gsyncdconfig.py')
| -rw-r--r-- | geo-replication/syncdaemon/gsyncdconfig.py | 145 |
1 files changed, 126 insertions, 19 deletions
diff --git a/geo-replication/syncdaemon/gsyncdconfig.py b/geo-replication/syncdaemon/gsyncdconfig.py index ad313022b4e..8848071997a 100644 --- a/geo-replication/syncdaemon/gsyncdconfig.py +++ b/geo-replication/syncdaemon/gsyncdconfig.py @@ -1,7 +1,23 @@ -from ConfigParser import ConfigParser, NoSectionError +# -*- coding: utf-8 -*- +# +# Copyright (c) 2016 Red Hat, Inc. <http://www.redhat.com> +# This file is part of GlusterFS. +# +# This file is licensed to you under your choice of the GNU Lesser +# General Public License, version 3 or any later version (LGPLv3 or +# later), or the GNU General Public License, version 2 (GPLv2), in all +# cases as published by the Free Software Foundation. +# + +try: + from ConfigParser import RawConfigParser, NoSectionError +except ImportError: + from configparser import RawConfigParser, NoSectionError import os +import shutil from string import Template from datetime import datetime +from threading import Lock # Global object which can be used in other modules @@ -20,6 +36,7 @@ class GconfInvalidValue(Exception): class Gconf(object): def __init__(self, default_conf_file, custom_conf_file=None, args={}, extra_tmpl_args={}, override_from_args=False): + self.lock = Lock() self.default_conf_file = default_conf_file self.custom_conf_file = custom_conf_file self.tmp_conf_file = None @@ -36,6 +53,8 @@ class Gconf(object): self.args = args self.extra_tmpl_args = extra_tmpl_args self.override_from_args = override_from_args + # Store default values only if overwritten, Only for JSON/CLI output + self.default_values = {} self._load() def _tmpl_substitute(self): @@ -63,6 +82,8 @@ class Gconf(object): "to_" + self.gconf_typecast.get(k, "string"), None) if cast_func is not None: self.gconf[k] = cast_func(v) + if self.default_values.get(k, None) is not None: + self.default_values[k] = cast_func(v) def reset(self, name): # If custom conf file is not set then it is only read only configs @@ -73,7 +94,7 @@ class Gconf(object): if name != "all" and not self._is_configurable(name): raise GconfNotConfigurable() - cnf = ConfigParser() + cnf = RawConfigParser() with open(self.custom_conf_file) as f: cnf.readfp(f) @@ -117,7 +138,7 @@ class Gconf(object): if curr_val == value: return True - cnf = ConfigParser() + cnf = RawConfigParser() with open(self.custom_conf_file) as f: cnf.readfp(f) @@ -144,14 +165,20 @@ class Gconf(object): if value is not None and not self._is_valid_value(name, value): raise GconfInvalidValue() + + def _load_with_lock(self): + with self.lock: + self._load() + def _load(self): self.gconf = {} self.template_conf = [] self.gconf_typecast = {} self.non_configurable_configs = [] self.session_conf_items = [] + self.default_values = {} - conf = ConfigParser() + conf = RawConfigParser() # Default Template config file with open(self.default_conf_file) as f: conf.readfp(f) @@ -196,6 +223,7 @@ class Gconf(object): if conf.has_section("vars"): for k, v in conf.items("vars"): self.session_conf_items.append(k) + self.default_values[k] = self.gconf.get(k, "") self.gconf[k] = v.strip() # Overwrite the Slave configurations which are sent as @@ -209,35 +237,62 @@ class Gconf(object): self._tmpl_substitute() self._do_typecast() - def reload(self): + def reload(self, with_lock=True): if self._is_config_changed(): - self._load() + if with_lock: + self._load_with_lock() + else: + self._load() - def get(self, name, default_value=None): - return self.gconf.get(name, default_value) + def get(self, name, default_value=None, with_lock=True): + if with_lock: + with self.lock: + return self.gconf.get(name, default_value) + else: + return self.gconf.get(name, default_value) def getall(self, show_defaults=False, show_non_configurable=False): cnf = {} if not show_defaults: for k in self.session_conf_items: if k not in self.non_configurable_configs: - cnf[k] = self.get(k) - + dv = self.default_values.get(k, "") + cnf[k] = { + "value": self.get(k), + "default": dv, + "configurable": True, + "modified": False if dv == "" else True + } return cnf # Show all configs including defaults for k, v in self.gconf.items(): + configurable = False if k in self.non_configurable_configs \ + else True + dv = self.default_values.get(k, "") + modified = False if dv == "" else True if show_non_configurable: - cnf[k] = v + cnf[k] = { + "value": v, + "default": dv, + "configurable": configurable, + "modified": modified + } else: if k not in self.non_configurable_configs: - cnf[k] = v + cnf[k] = { + "value": v, + "default": dv, + "configurable": configurable, + "modified": modified + } return cnf def getr(self, name, default_value=None): - self.reload() - return self.get(name, default_value) + with self.lock: + self.reload(with_lock=False) + return self.get(name, default_value, with_lock=False) def get_help(self, name=None): pass @@ -274,6 +329,9 @@ class Gconf(object): if item["validation"] == "unixtime": return validate_unixtime(value) + if item["validation"] == "int": + return validate_int(value) + return False def _is_config_changed(self): @@ -286,6 +344,53 @@ class Gconf(object): return False +def is_config_file_old(config_file, mastervol, slavevol): + cnf = RawConfigParser() + cnf.read(config_file) + session_section = "peers %s %s" % (mastervol, slavevol) + try: + return dict(cnf.items(session_section)) + except NoSectionError: + return None + +def config_upgrade(config_file, ret): + config_file_backup = os.path.join(os.path.dirname(config_file), "gsyncd.conf.bkp") + + #copy old config file in a backup file + shutil.copyfile(config_file, config_file_backup) + + #write a new config file + config = RawConfigParser() + config.add_section('vars') + + for key, value in ret.items(): + #handle option name changes + if key == "use_tarssh": + new_key = "sync-method" + if value == "true": + new_value = "tarssh" + else: + new_value = "rsync" + config.set('vars', new_key, new_value) + elif key == "timeout": + new_key = "slave-timeout" + config.set('vars', new_key, value) + #for changes like: ignore_deletes to ignore-deletes + else: + new_key = key.replace("_", "-") + config.set('vars', new_key, value) + + with open(config_file, 'w') as configfile: + config.write(configfile) + + +def validate_int(value): + try: + _ = int(value) + return True + except ValueError: + return False + def validate_unixtime(value): try: @@ -299,11 +404,13 @@ def validate_unixtime(value): def validate_minmax(value, minval, maxval): - value = int(value) - minval = int(minval) - maxval = int(maxval) - - return value >= minval and value <= maxval + try: + value = int(value) + minval = int(minval) + maxval = int(maxval) + return value >= minval and value <= maxval + except ValueError: + return False def validate_choice(value, allowed_values): |
