def _new_lines(self, search_key, new_key): try: attrs = self.dop.get(self._module, search_key, with_attr=True) action = attrs['action'] iscomment = attrs['comment'] val = attrs['value'] except: action = self.dop.action(self._module, search_key) iscomment = self.dop.iscomment(self._module, search_key) val = self.dop.get(self._module, search_key) pass #print val dop = DictOp() dop.addconf('__', {}) if action == "delete": dop.add('__', new_key, val) dop.delete('__', new_key) elif action == "set": dop.set('__', new_key, val) else: dop.add('__', new_key, val) if iscomment is True: dop.comment('__', new_key) #preprint_r(dop.getconf('__')) new_lines = self._value_to_lines(dop.getconf('__')) #print "\n".join(new_lines) return new_lines
def _get_iscsi_config(node): path = iscsi_get_config_path_node(node) parser = iscsidParser() dop = DictOp() dop.addconf(MODULE, parser.read_conf(path)) return dop
def convert_old_style(self, conf_arr): dop = DictOp() dop.addconf("__",{}) orders = [] for cnt in range(0,20): try: try: exec("action = conf_arr['ADDRESS%d']['action']" % cnt) except: action = None exec("address = conf_arr['ADDRESS%d']['value']" % cnt) exec("netmask = conf_arr['NETMASK%d']['value']" % cnt) exec("gateway = conf_arr['GATEWAY%d']['value']" % cnt) target = "%s/%s" % (address,netmask,) net = NetworkAddress(target) try: target = net.cidr except: pass dop.add("__",[target],gateway) if action == "delete": dop.delete("__",[target]) orders.append([target]) except: pass if len(orders) != 0: dop.add("__",['@ORDERS'],orders) return dop.getconf("__")
class nullParser: _comment = "" _module = "null_parser" def __init__(self,paths=[]): self.dop = DictOp() self.dop.addconf(self._module,{}) self.set_source_file(paths) def set_comment(self, comment=""): self._comment = comment def set_source_file(self,paths=[]): if type(paths) == str: paths = [paths] self.paths = paths return True def get_source_file(self): return self.paths def source_file(self): return self.get_source_file() def read_conf(self): return self.dop.getconf(self._module) def write_conf(self,conf_arr={},dryrun=False): retval = True return retval
def _new_lines(self,search_key,new_key): try: attrs = self.dop.get(self._module,search_key,with_attr=True) action = attrs['action'] iscomment = attrs['comment'] val = attrs['value'] except: action = self.dop.action(self._module,search_key) iscomment = self.dop.iscomment(self._module,search_key) val = self.dop.get(self._module,search_key) pass #print val dop = DictOp() dop.addconf('__',{}) if action == "delete": dop.add('__',new_key,val) dop.delete('__',new_key) elif action == "set": dop.set('__',new_key,val) else: dop.add('__',new_key,val) if iscomment is True: dop.comment('__',new_key) #preprint_r(dop.getconf('__')) new_lines = self._value_to_lines(dop.getconf('__')) #print "\n".join(new_lines) return new_lines
def _pre_write_conf(self, conf_arr={}): # Change permission to be able to read/write data kss group. if os.path.exists(COLLECTD_DATA_DIR): if os.getuid() == 0: r_chgrp(COLLECTD_DATA_DIR, KARESANSUI_GROUP) r_chmod(COLLECTD_DATA_DIR, "g+rwx") r_chmod(COLLECTD_DATA_DIR, "o-rwx") dop = DictOp() dop.addconf("__", conf_arr) if dop.isset("__", ["python"]) is True: dop.cdp_unset("__", ["python", "Plugin", "python", "@ORDERS"], multiple_file=True) orders = [] orders.append(['Encoding']) orders.append(['LogTraces']) orders.append(['Interactive']) orders.append(['ModulePath']) orders.append(['Import']) orders.append(['Module']) dop.cdp_set("__", ["python", "Plugin", "python", "@ORDERS"], orders, is_opt_multi=True, multiple_file=True) return dop.getconf("__")
def process(self): (opts, args) = getopts() chkopts(opts) self.up_progress(1) dop = DictOp() modules = opts.module.split(":") files = opts.file.split(":") retval = True cnt = 0 for _mod in modules: _file = files[cnt] try: exec( "from karesansui.lib.parser.%s import %sParser as Parser" % ( _mod, _mod, )) self.up_progress(5) parser = Parser() self.up_progress(5) if opts.raw is True: raw_str = "Config_Raw_%s = {}\n" % (_mod, ) for _src in parser.source_file(): raw_str = "%sConfig_Raw_%s['%s'] = \"\"\"%s\"\"\"\n" % ( raw_str, _mod, _src, open(_src).read()) ConfigFile(_file).write(raw_str) else: # 設定ファイルの読み込み extra_args = {} extra_args["include"] = opts.include conf_arr = parser.read_conf(extra_args=extra_args) dop.addconf(_mod, conf_arr) #dop.preprint_r(_mod) # 辞書配列ファイルに書き込み _var = "Config_Dict_%s" % (_mod, ) if opts.php is True: _str = python_dict_to_php_array( dop.getconf(_mod), _var) ConfigFile(_file).write(_str) else: ConfigFile(_file).write("%s = %s\n" % ( _var, str(dop.getconf(_mod)), )) finally: cnt = cnt + 1 self.up_progress(10) return True
def convert_new_style(self, conf_arr): dop = DictOp() dop.addconf("__",{}) orders = [] try: old_orders = conf_arr['@ORDERS']['value'] except: old_orders = [] cnt = 0 for _k,_v in conf_arr.iteritems(): if _k[0] != "@": net = NetworkAddress(_k) try: ipaddr = net.ipaddr netmask = net.netmask gateway = _v['value'] try: action = _v['action'] except: action = None try: index = old_orders.index([_k]) except: index = cnt dop.add("__",["ADDRESS%d" % index],ipaddr) if action == "delete": dop.delete("__",["ADDRESS%d" % index]) orders.insert(cnt*3+0,["ADDRESS%d" % index]) dop.add("__",["NETMASK%d" % index],netmask) if action == "delete": dop.delete("__",["NETMASK%d" % index]) orders.insert(cnt*3+1,["NETMASK%d" % index]) dop.add("__",["GATEWAY%d" % index],gateway) if action == "delete": dop.delete("__",["GATEWAY%d" % index]) orders.insert(cnt*3+2,["GATEWAY%d" % index]) cnt = cnt + 1 except: pass if len(orders) != 0: dop.add("__",['@ORDERS'],orders) return dop.getconf("__")
def process(self): (opts, args) = getopts() chkopts(opts) self.up_progress(1) dop = DictOp() modules = opts.module.split(":") files = opts.file.split(":") retval = True cnt = 0 for _mod in modules: _file = files[cnt] try: exec("from karesansui.lib.parser.%s import %sParser as Parser" % (_mod,_mod,)) self.up_progress(5) parser = Parser() self.up_progress(5) if opts.raw is True: raw_str = "Config_Raw_%s = {}\n" % (_mod,) for _src in parser.source_file(): raw_str = "%sConfig_Raw_%s['%s'] = \"\"\"%s\"\"\"\n" % (raw_str,_mod,_src,open(_src).read()) ConfigFile(_file).write(raw_str) else: # 設定ファイルの読み込み extra_args = {} extra_args["include"] = opts.include conf_arr = parser.read_conf(extra_args=extra_args) dop.addconf(_mod,conf_arr) #dop.preprint_r(_mod) # 辞書配列ファイルに書き込み _var = "Config_Dict_%s" % (_mod,) if opts.php is True: _str = python_dict_to_php_array(dop.getconf(_mod),_var) ConfigFile(_file).write(_str) else: ConfigFile(_file).write("%s = %s\n" % (_var,str(dop.getconf(_mod)),)) finally: cnt = cnt + 1 self.up_progress(10) return True
def _PUT(self, *param, **params): host_id = self.chk_hostby1(param) if host_id is None: return web.notfound() host = findbyhost1(self.orm, host_id) if not validates_iptables_save(self, host): return web.badrequest(self.view.alert) from karesansui.lib.dict_op import DictOp dop = DictOp() dop.addconf("iptables", {}) dop.set("iptables",["config"],self.input.iptables_save.split("\r\n")) retval = write_conf(dop, self, host) if retval is False: return web.internalerror('Internal Server Error. (Adding Task)') return web.accepted(url=web.ctx.path)
class iscsidParser: _module = "hosts" def __init__(self): self.dop = DictOp() self.dop.addconf(self._module, {}) self.parser = Parser() self.parser.set_delim("[ \t]*=[ \t]*") self.parser.set_new_delim(" = ") self.parser.set_comment("#") self.base_parser_name = self.parser.__class__.__name__ pass def set_footer(self, footer=""): self.parser.set_footer(footer) def source_file(self): retval = [ISCSI_DEFAULT_CONFIG_PATH] return retval def read_conf(self, conf_path=None, extra_args=None): retval = {} if conf_path is None: conf_path = ISCSI_DEFAULT_CONFIG_PATH self.parser.set_source_file([conf_path]) conf_arr = self.parser.read_conf() try: self.dop.addconf(self._module, conf_arr[conf_path]['value']) except: pass self.dop.set(self._module, ['@BASE_PARSER'], self.base_parser_name) #self.dop.preprint_r(self._module) return self.dop.getconf(self._module) def write_conf(self, conf_arr={}, conf_path=None, extra_args=None, dryrun=False): retval = True if conf_path is None: conf_path = ISCSI_DEFAULT_CONFIG_PATH try: self.dop.addconf("parser", {}) self.dop.set("parser", [conf_path], conf_arr) #self.dop.preprint_r("parser") arr = self.dop.getconf("parser") self.parser.write_conf(arr, dryrun=dryrun) except: pass return retval
class iscsidParser: _module = "hosts" def __init__(self): self.dop = DictOp() self.dop.addconf(self._module,{}) self.parser = Parser() self.parser.set_delim("[ \t]*=[ \t]*") self.parser.set_new_delim(" = ") self.parser.set_comment("#") self.base_parser_name = self.parser.__class__.__name__ pass def set_footer(self, footer=""): self.parser.set_footer(footer) def source_file(self): retval = [ISCSI_DEFAULT_CONFIG_PATH] return retval def read_conf(self, conf_path=None, extra_args=None): retval = {} if conf_path is None: conf_path = ISCSI_DEFAULT_CONFIG_PATH self.parser.set_source_file([conf_path]) conf_arr = self.parser.read_conf() try: self.dop.addconf(self._module,conf_arr[conf_path]['value']) except: pass self.dop.set(self._module,['@BASE_PARSER'],self.base_parser_name) #self.dop.preprint_r(self._module) return self.dop.getconf(self._module) def write_conf(self, conf_arr={}, conf_path=None, extra_args=None, dryrun=False): retval = True if conf_path is None: conf_path = ISCSI_DEFAULT_CONFIG_PATH try: self.dop.addconf("parser",{}) self.dop.set("parser",[conf_path],conf_arr) #self.dop.preprint_r("parser") arr = self.dop.getconf("parser") self.parser.write_conf(arr,dryrun=dryrun) except: pass return retval
def _pre_write_conf(self,conf_arr={}): # Change permission to be able to read/write data kss group. if os.path.exists(COLLECTD_DATA_DIR): if os.getuid() == 0: r_chgrp(COLLECTD_DATA_DIR,KARESANSUI_GROUP) r_chmod(COLLECTD_DATA_DIR,"g+rwx") r_chmod(COLLECTD_DATA_DIR,"o-rwx") dop = DictOp() dop.addconf("__",conf_arr) if dop.isset("__",["python"]) is True: dop.cdp_unset("__",["python","Plugin","python","@ORDERS"],multiple_file=True) orders = [] orders.append(['Encoding']) orders.append(['LogTraces']) orders.append(['Interactive']) orders.append(['ModulePath']) orders.append(['Import']) orders.append(['Module']) dop.cdp_set("__",["python","Plugin","python","@ORDERS"],orders,is_opt_multi=True,multiple_file=True) return dop.getconf("__")
class modprobe_confParser: _module = "modprobe_conf" def __init__(self): self.dop = DictOp() self.dop.addconf(self._module, {}) self.parser = Parser() self.parser.set_delim(" ") self.parser.set_new_delim(" ") self.parser.set_comment("#") self.base_parser_name = self.parser.__class__.__name__ pass def source_file(self): retval = [PARSER_MODPROBE_CONF] return retval def read_conf(self, extra_args=None): retval = {} self.parser.set_source_file([PARSER_MODPROBE_CONF]) conf_arr = self.parser.read_conf() try: self.dop.addconf(self._module, conf_arr[PARSER_MODPROBE_CONF]['value']) except: pass self.dop.set(self._module, ['@BASE_PARSER'], self.base_parser_name) #self.dop.preprint_r(self._module) return self.dop.getconf(self._module) def write_conf(self, conf_arr={}, extra_args=None, dryrun=False): retval = True try: self.dop.addconf("parser", {}) self.dop.set("parser", [PARSER_MODPROBE_CONF], conf_arr) #self.dop.preprint_r("parser") arr = self.dop.getconf("parser") self.parser.write_conf(arr, dryrun=dryrun) except: pass return retval
class modprobe_confParser: _module = "modprobe_conf" def __init__(self): self.dop = DictOp() self.dop.addconf(self._module,{}) self.parser = Parser() self.parser.set_delim(" ") self.parser.set_new_delim(" ") self.parser.set_comment("#") self.base_parser_name = self.parser.__class__.__name__ pass def source_file(self): retval = [PARSER_MODPROBE_CONF] return retval def read_conf(self,extra_args=None): retval = {} self.parser.set_source_file([PARSER_MODPROBE_CONF]) conf_arr = self.parser.read_conf() try: self.dop.addconf(self._module,conf_arr[PARSER_MODPROBE_CONF]['value']) except: pass self.dop.set(self._module,['@BASE_PARSER'],self.base_parser_name) #self.dop.preprint_r(self._module) return self.dop.getconf(self._module) def write_conf(self,conf_arr={},extra_args=None,dryrun=False): retval = True try: self.dop.addconf("parser",{}) self.dop.set("parser",[PARSER_MODPROBE_CONF],conf_arr) #self.dop.preprint_r("parser") arr = self.dop.getconf("parser") self.parser.write_conf(arr,dryrun=dryrun) except: pass return retval
class emlParser(Parser): _module = "eml" def __init__(self): self.dop = DictOp() self.dop.addconf(self._module,{}) self.base_parser_name = Parser.__name__ self.encoding = "UTF-8" pass def source_file(self): try: retval = self.get_source_file() except: retval = [] return retval def _parse_mail(self,mail): retval = {} try: body = mail.get_payload() boundary = mail.get_boundary() charsets = mail.get_charsets() # ['iso-8859-1'] content_charset = mail.get_content_charset() # 'iso-8859-1' content_maintype = mail.get_content_maintype() # 'text' content_subtype = mail.get_content_subtype() # 'plain' content_type = mail.get_content_type() # 'text/plain' default_type = mail.get_default_type() # 'text/plain' filename = mail.get_filename() # ?? params = mail.get_params() # [('text/plain', ''), ('charset', 'iso-8859-1')] is_multipart = mail.is_multipart() # False if type(body) is list: new_body = [] for _mail in body: new_body.append(self._parse_mail(_mail)) body = new_body retval = {} retval['body'] = body retval['boundary'] = boundary retval['charsets'] = charsets retval['content_charset'] = content_charset retval['content_maintype'] = content_maintype retval['content_subtype'] = content_subtype retval['content_type'] = content_type retval['default_type'] = default_type retval['filename'] = filename retval['params'] = params retval['is_multipart'] = is_multipart except: pass #preprint_r(retval) return retval def parse(self,file=None,message=None): retval = {} try: if file is not None and os.path.exists(file): message = open(file).read() mail = email.Parser.Parser().parsestr(message) headers = mail._headers msgs = self._parse_mail(mail) if type(msgs['body']) is list: rawbody = "" if file is not None and os.path.exists(file): f = open(file) line = f.readline() while line: line = f.readline() if line.rstrip() == "": rawbody += line rawbody += ''.join(f.readlines()) break f.close else: in_body = False for line in message.split("\n"): if line.rstrip() == "": in_body = True if in_body is True: rawbody += line + "\n" elif type(msgs['body']) is str: rawbody = msgs['body'] retval["headers"] = headers retval["msgs"] = msgs retval["rawbody"] = rawbody except: pass #preprint_r(retval) return retval def read_conf(self,extra_args=None): retval = {} self.dop.addconf(self._module,{}) try: self.set_source_file(extra_args["file"]) for _file in self.source_file(): if os.path.exists(_file): mail = self.parse(file=_file) headers = mail['headers'] msgs = mail['msgs'] rawbody = mail['rawbody'] self.dop.add(self._module,[_file,'@msgs'] ,msgs) self.dop.add(self._module,[_file,'@headers'],headers) for _header in headers: self.dop.add(self._module,[_file,'header',_header[0]],_header[1]) self.dop.add(self._module,[_file,'rawbody'] ,rawbody) except: pass try: message = extra_args["message"] try: message = message.encode(self.encoding) except: pass if message != "" and message is not None: mail = self.parse(message=message) headers = mail['headers'] msgs = mail['msgs'] rawbody = mail['rawbody'] self.dop.add(self._module,["@message",'@msgs'] ,msgs) self.dop.add(self._module,["@message",'@headers'],headers) for _header in headers: self.dop.add(self._module,["@message",'header',_header[0]],_header[1]) self.dop.add(self._module,["@message",'rawbody'] ,rawbody) except: pass return self.dop.getconf(self._module) def write_conf(self,conf_arr={},extra_args=None,dryrun=False): retval = True return retval
class xmlLikeConfParser: _delim = "[ \t]+" _new_delim = " " _comment = "#" _reserved_key_prefix = "@" _indent = " " _module = "xml_like_conf_parser" _footer = "-- Generated by karesansui" def __init__(self,paths=[]): self.dop = DictOp() self.dop.addconf(self._module,{}) self.set_source_file(paths) self.opt_uni = ['PIDFile'] self.opt_multi = ['LoadPlugin','Include'] self.opt_sect = ['Directory','VirtualHost','View'] def set_opt_uni(self, opts): self.opt_uni = opts def set_opt_multi(self, opts): self.opt_multi = opts def set_opt_sect(self, opts): self.opt_sect = opts def set_delim(self, delim=" "): self._delim = delim def set_new_delim(self, delim=" "): self._new_delim = delim def set_comment(self, comment="#"): self._comment = comment def set_reserved_key_prefix(self, prefix="@"): self._reserved_key_prefix = prefix def set_footer(self, footer=""): self._footer = footer def set_source_file(self,paths=[]): if type(paths) == str: paths = [paths] self.paths = paths return True def get_source_file(self): return self.paths def source_file(self): return self.get_source_file() def build_value(self, value=None, precomment=[], postcomment=None): if type(precomment) == str: precomment = [precomment] return [value, [precomment, postcomment], ] def read_conf(self): retval = {} orders_key = "%sORDERS" % (self._reserved_key_prefix,) for _afile in self.source_file(): res = ConfigFile(_afile).read() self.orders = [] self.dop.set(self._module,[_afile],self._read_conf(res)) self.dop.set(self._module,[_afile,orders_key],self.orders) return self.dop.getconf(self._module) def _read_conf(self,lines,level=0): dop = DictOp() dop.addconf("__",{}) pre_comment = [] # 設定の前のコメント リスト配列 post_comment = None # 設定行のコメント 文字列 _in_section = False _res = [] for _aline in lines: if _in_section is True: regex = "[ \t]*(?P<comment>#*)[ \t]*</(?P<key>%s)>" % _section_key #'|'.join(self.opt_sect) _regex = re.compile(r"%s" % regex) m = _regex.match(_aline) if m: _comment = m.group('comment') _key = m.group('key').strip() values = self.build_value(self._read_conf(_res,level),pre_comment,post_comment) dop.set("__",[_key,_section_val],values) if _comment != "": dop.comment("__",[_key,_section_val]) if level == 1: self.orders.append([_key,_section_val]) pre_comment = [] post_comment = None _in_section = False _res = [] level = level - 1 else: _res.append(_aline) else: _aline = _aline.rstrip('\r\n') if _aline.strip() == "": pre_comment.append(_aline) continue match = False for _type in ['uni','multi','sect']: exec("regex = '|'.join(self.opt_%s)" % _type) if _type == "sect": regex = "[ \t]*(?P<comment>#*)[ \t]*<(?P<key>%s)(?P<section>.*)>" % regex elif _type == "multi": regex = "[ \t]*(?P<comment>#*)[ \t]*(?P<key>%s)[ \t]+(?P<value>.+)" % regex elif _type == "uni": regex = "[ \t]*(?P<comment>#*)[ \t]*(?P<key>%s)[ \t]+(?P<value>.+)" % regex _regex = re.compile(r"%s" % regex) m = _regex.match(_aline) if m: match = True _comment = m.group('comment') _key = m.group('key').strip() if _type == "sect": _section_key = _key _section_val = re.sub(r"[\"']","",m.group('section').strip()) _in_section = True level = level + 1 elif _type == "multi": _value = m.group('value').strip() if _value.find(self._comment) > 0: post_comment = _value[_value.find(self._comment):] _value = re.sub("%s$" % post_comment, "", _value).rstrip() values = self.build_value(_value,pre_comment,post_comment) dop.set("__",[_key,_value],values) if _comment != "": dop.comment("__",[_key,_value]) if level == 0: self.orders.append([_key,_value]) pre_comment = [] post_comment = None elif _type == "uni": _value = m.group('value').strip() if _value.find(self._comment) > 0: post_comment = _value[_value.find(self._comment):] _value = re.sub("%s$" % post_comment, "", _value).rstrip() values = self.build_value(_value,pre_comment,post_comment) dop.set("__",[_key],values) if _comment != "": dop.comment("__",[_key]) if level == 0: self.orders.append([_key]) pre_comment = [] post_comment = None break if match is False: # ブラケットディレクティブのパラメータは除外する (よって、ブラケットディレクティブは全ての定義が必要!) # example: "<undefined_directive 'foobar'>" regex_exclude1 = "[ \t]*(?P<comment>#*)[ \t]*(?P<key>%s)[ \t]" % '|'.join(self.opt_sect) _regex_exclude1 = re.compile(r"%s" % regex_exclude1) # 未定義のパラメータの値がクオートせずにスペース区切りで3つ以上の値を指定している場合はコメント行とみなす # example: "# Read this configuration file" regex_exclude2 = "[ \t]*#+[ \t]*[^ \t]+([ \t]+[^ \t]+){3,}" _regex_exclude2 = re.compile(r"%s" % regex_exclude2) # 未定義のパラメータの値がクオートせずにスペース区切りで2つ以上の値を指定していて、かつ、最後が:で終わる場合はコメント行とみなす # example: "# Read this configuration:" regex_exclude3 = "[ \t]*#+[ \t]*[^ \t]+([ \t]+[^ \t]+){2,}:$" _regex_exclude3 = re.compile(r"%s" % regex_exclude3) # 未定義のパラメータの値が0個以上で、かつ、最後が:で終わる場合はコメント行とみなす # example: "# Read #" regex_exclude4 = "[ \t]*#+[ \t]*[^ \t]+.+[ \t]+#+$" _regex_exclude4 = re.compile(r"%s" % regex_exclude4) m1 = _regex_exclude1.match(_aline) m2 = _regex_exclude2.match(_aline) m3 = _regex_exclude3.match(_aline) m4 = _regex_exclude4.match(_aline) if not m1 and not m2 and not m3 and not m4: # opt_xxxに未定義のパラメータはuniパラメータとする regex = "[ \t]*(?P<comment>#*)[ \t]*(?P<key>[A-Z][^ \t]+)[ \t]+(?P<value>.+)" _regex = re.compile(r"%s" % regex) m = _regex.match(_aline) if m: _comment = m.group('comment') _key = m.group('key').strip() _value = m.group('value').strip() if _value.find(self._comment) > 0: post_comment = _value[_value.find(self._comment):] _value = re.sub("%s$" % post_comment, "", _value).rstrip() values = self.build_value(_value,pre_comment,post_comment) dop.set("__",[_key],values) if _comment != "": dop.comment("__",[_key]) if level == 0: self.orders.append([_key]) pre_comment = [] post_comment = None match = True if match is False: if _aline.lstrip()[0:1] == self._comment: footer_regex = re.compile(self._footer) m = footer_regex.search(_aline) if not m: comment = _aline[_aline.find(self._comment):] pre_comment.append(comment) continue if len(pre_comment) > 0: eof_key = "%sEOF" % (self._reserved_key_prefix,) new_value = self.build_value("",pre_comment,post_comment) dop.set("__",[eof_key],new_value) return dop.getconf("__") def _value_to_lines(self,conf_arr,level=0): lines = [] orders_key = "%sORDERS" % (self._reserved_key_prefix,) dop = DictOp() dop.addconf("__",conf_arr) for _k,_v in dop.getconf("__").iteritems(): action = dop.action("__",[_k]) if action == "delete": continue iscomment = dop.iscomment("__",[_k]) value = dop.get("__",[_k]) if type(value) == list: _val = value[0] if type(_val) != dict: _pre_comment = value[1][0] _post_comment = value[1][1] pre_comment = [] try: for _aline in _pre_comment: if _aline.strip() == "": pass elif _aline[0:1] != self._comment: _prefix = "" if level > 0: _prefix += str_repeat(self._indent,level) _prefix += self._comment _aline = "%s %s" % (_prefix,_aline,) pre_comment.append(_aline) except: pass if len(pre_comment) > 0: #preprint_r(pre_comment) lines = lines + pre_comment post_comment = _post_comment try: if post_comment is not None and post_comment[0:1] != self._comment: post_comment = "%s %s" % (self._comment,post_comment,) except: pass else: pass else: _val = value _prefix = "" if iscomment is True: _prefix += self._comment if level > 0: _prefix += str_repeat(self._indent,level) if type(_val) == dict: # ORDER順に設定する orders = [] try: old_orders = _val[orders_key]['value'] except: old_orders = [] for kk in old_orders: if type(kk) is list: orders.append(kk[0]) elif type(kk) is str: orders.append(kk) for kk in _val.keys(): if not kk in orders: orders.append(kk) #for _k2,_v2 in _val.iteritems(): for _k2 in orders: if _k2 == orders_key: continue _v2 = _val[_k2] sub_value = {} sub_value[_k2] = _v2 try: iscomment = sub_value[_k2]['comment'] except: iscomment = False try: action = sub_value[_k2]['action'] except: action = "" if action == "delete": continue #try: # sub_value[_k2]['value'][1][0] # lines = lines + sub_value[_k2]['value'][1][0] #except: # pass is_sect = False if _k in self.opt_multi and _k2 == _v2["value"][0]: for _k3,_v3 in sub_value.iteritems(): try: iscomment3 = sub_value[_k3]['comment'] except: iscomment3 = iscomment try: action3 = sub_value[_k3]['action'] except: action3 = "" _prefix = "" if iscomment is True: _prefix += self._comment if level > 0: _prefix += str_repeat(self._indent,level) lines.append("%s%-18s%s%s" % (_prefix,_k,self._new_delim,_k2)) elif _k in self.opt_sect: is_sect = True _prefix = "" if iscomment is True: _prefix += self._comment if level > 0: _prefix += str_repeat(self._indent,level) if _k2 == "": lines.append("%s<%s>" % (_prefix,_k)) else: lines.append("%s<%s \"%s\">" % (_prefix,_k,_k2)) new_level = level + 1 new_lines = self._value_to_lines(sub_value,level=new_level) for _aline in new_lines: _prefix2 = "" if iscomment is True: _prefix2 += self._comment new_aline = "%s%s" % (_prefix2,_aline,) new_aline = re.sub("^%s+" % self._comment,self._comment,new_aline) lines.append(new_aline) #lines = lines + new_lines if is_sect is True: lines.append("%s</%s>" % (_prefix,_k,)) else: aline = "" if _k in self.opt_multi: aline += "%s%-18s%s%s" % (_prefix,_k,self._new_delim,_val,) else: if re.match("^[A-Z]+[a-z]",_k): aline += "%s%-18s%s%s" % (_prefix,_k,self._new_delim,_val,) if post_comment is not None: aline = "%s %s" % (aline,post_comment,) if aline != "": lines.append(aline) return lines def write_conf(self,conf_arr={},dryrun=False): retval = True self.dop.addconf(self._module,conf_arr) orders_key = "%sORDERS" % (self._reserved_key_prefix,) eof_key = "%sEOF" % (self._reserved_key_prefix,) for _path,_v in conf_arr.iteritems(): if _path[0:1] != "/": continue lines = [] try: _v['value'] except: continue exclude_regex = "^%s[A-Z0-9\_]+$" % self._reserved_key_prefix # まずはオーダの順 if self.dop.isset(self._module,[_path,orders_key]) is True: for _k2 in self.dop.get(self._module,[_path,orders_key]): try: if type(_k2) == str: _k2 = [_k2] _search_key = [_path] + _k2 is_opt_multi = False if _k2[0] in self.opt_multi: _tmp_conf = self.dop.get(self._module,_search_key) # multiとsectがかぶったオプションの対応 strならmulti if type(_tmp_conf[0]) == str: is_opt_multi = True if is_opt_multi is True: _k2.pop() new_lines = self._new_lines(_search_key,_k2) lines = lines + new_lines self.dop.unset(self._module,_search_key) except: pass # オーダにないものは最後に追加 for _k2,_v2 in self.dop.get(self._module,[_path]).iteritems(): #if _k2 != orders_key: m = re.match(exclude_regex,_k2) if not m: try: if type(_k2) == str: _k2 = [_k2] _search_key = [_path] + _k2 if _k2[0] in self.opt_multi: for _k3,_v3 in self.dop.get(self._module,_search_key).iteritems(): _search_key.append(_k3) new_lines = self._new_lines(_search_key,_k2) lines = lines + new_lines else: new_lines = self._new_lines(_search_key,_k2) lines = lines + new_lines except: pass # 最後のコメント用の処理 if self._footer != "": if self.dop.isset(self._module,[_path,eof_key]) is False: self.dop.cdp_set(self._module,[_path,eof_key],"",force=True) eof_val = self.dop.get(self._module,[_path,eof_key]) eof_action = self.dop.action(self._module,[_path,eof_key]) eof_comment = self.dop.comment(self._module,[_path,eof_key]) try: key = " %s - %s on %s" % (self._footer,self._module,time.strftime("%c",time.localtime())) value = {} value[key] = {} value[key]["value"] = eof_val value[key]["action"] = eof_action value[key]["comment"] = eof_comment self.set_new_delim(delim=" ") lines = lines + self._value_to_lines(value) except: pass if dryrun is False: if len(lines) > 0: ConfigFile(_path).write("\n".join(lines) + "\n") else: print "%s -- filename: %s" % (self._comment,_path,) print "\n".join(lines) return retval def _new_lines(self,search_key,new_key): try: attrs = self.dop.get(self._module,search_key,with_attr=True) action = attrs['action'] iscomment = attrs['comment'] val = attrs['value'] except: action = self.dop.action(self._module,search_key) iscomment = self.dop.iscomment(self._module,search_key) val = self.dop.get(self._module,search_key) pass #print val dop = DictOp() dop.addconf('__',{}) if action == "delete": dop.add('__',new_key,val) dop.delete('__',new_key) elif action == "set": dop.set('__',new_key,val) else: dop.add('__',new_key,val) if iscomment is True: dop.comment('__',new_key) #preprint_r(dop.getconf('__')) new_lines = self._value_to_lines(dop.getconf('__')) #print "\n".join(new_lines) return new_lines
def _value_to_lines(self,conf_arr,level=0): lines = [] orders_key = "%sORDERS" % (self._reserved_key_prefix,) dop = DictOp() dop.addconf("__",conf_arr) for _k,_v in dop.getconf("__").iteritems(): action = dop.action("__",[_k]) if action == "delete": continue iscomment = dop.iscomment("__",[_k]) value = dop.get("__",[_k]) if type(value) == list: _val = value[0] if type(_val) != dict: _pre_comment = value[1][0] _post_comment = value[1][1] pre_comment = [] try: for _aline in _pre_comment: if _aline.strip() == "": pass elif _aline[0:1] != self._comment: _prefix = "" if level > 0: _prefix += str_repeat(self._indent,level) _prefix += self._comment _aline = "%s %s" % (_prefix,_aline,) pre_comment.append(_aline) except: pass if len(pre_comment) > 0: #preprint_r(pre_comment) lines = lines + pre_comment post_comment = _post_comment try: if post_comment is not None and post_comment[0:1] != self._comment: post_comment = "%s %s" % (self._comment,post_comment,) except: pass else: pass else: _val = value _prefix = "" if iscomment is True: _prefix += self._comment if level > 0: _prefix += str_repeat(self._indent,level) if type(_val) == dict: # ORDER順に設定する orders = [] try: old_orders = _val[orders_key]['value'] except: old_orders = [] for kk in old_orders: if type(kk) is list: orders.append(kk[0]) elif type(kk) is str: orders.append(kk) for kk in _val.keys(): if not kk in orders: orders.append(kk) #for _k2,_v2 in _val.iteritems(): for _k2 in orders: if _k2 == orders_key: continue _v2 = _val[_k2] sub_value = {} sub_value[_k2] = _v2 try: iscomment = sub_value[_k2]['comment'] except: iscomment = False try: action = sub_value[_k2]['action'] except: action = "" if action == "delete": continue #try: # sub_value[_k2]['value'][1][0] # lines = lines + sub_value[_k2]['value'][1][0] #except: # pass is_sect = False if _k in self.opt_multi and _k2 == _v2["value"][0]: for _k3,_v3 in sub_value.iteritems(): try: iscomment3 = sub_value[_k3]['comment'] except: iscomment3 = iscomment try: action3 = sub_value[_k3]['action'] except: action3 = "" _prefix = "" if iscomment is True: _prefix += self._comment if level > 0: _prefix += str_repeat(self._indent,level) lines.append("%s%-18s%s%s" % (_prefix,_k,self._new_delim,_k2)) elif _k in self.opt_sect: is_sect = True _prefix = "" if iscomment is True: _prefix += self._comment if level > 0: _prefix += str_repeat(self._indent,level) if _k2 == "": lines.append("%s<%s>" % (_prefix,_k)) else: lines.append("%s<%s \"%s\">" % (_prefix,_k,_k2)) new_level = level + 1 new_lines = self._value_to_lines(sub_value,level=new_level) for _aline in new_lines: _prefix2 = "" if iscomment is True: _prefix2 += self._comment new_aline = "%s%s" % (_prefix2,_aline,) new_aline = re.sub("^%s+" % self._comment,self._comment,new_aline) lines.append(new_aline) #lines = lines + new_lines if is_sect is True: lines.append("%s</%s>" % (_prefix,_k,)) else: aline = "" if _k in self.opt_multi: aline += "%s%-18s%s%s" % (_prefix,_k,self._new_delim,_val,) else: if re.match("^[A-Z]+[a-z]",_k): aline += "%s%-18s%s%s" % (_prefix,_k,self._new_delim,_val,) if post_comment is not None: aline = "%s %s" % (aline,post_comment,) if aline != "": lines.append(aline) return lines
def process(self): (opts, args) = getopts() chkopts(opts) self.up_progress(10) exist_bond_list = get_ifconfig_info("regex:^bond") if opts.dev not in exist_bond_list: raise KssCommandOptException('Target bonding device not found. target=%s' % opts.dev) self.up_progress(10) dop = DictOp() ifcfg_parser = ifcfgParser() dop.addconf("ifcfg", ifcfg_parser.read_conf()) if dop.getconf("ifcfg") == {}: raise KssCommandException('Failure read network config file.') if dop.get("ifcfg", opts.dev) is False: raise KssCommandException('Target device ifcfg file not found.') self.up_progress(10) restore_dev_list = [] for dev in dop.getconf("ifcfg").keys(): if dop.get("ifcfg", [dev, "MASTER"]) == opts.dev: restore_dev_list.append(dev) self.up_progress(10) if opts.succession is True: bond_bridge = dop.get("ifcfg", [opts.dev, "BRIDGE"]) bond_dev = opts.dev if bond_bridge: bond_dev = bond_bridge ipaddr = dop.get("ifcfg", [bond_dev, "IPADDR"]) netmask = dop.get("ifcfg", [bond_dev, "NETMASK"]) gateway = dop.get("ifcfg", [bond_dev, "GATEWAY"]) bonding_opts = dop.get("ifcfg", [opts.dev, "BONDING_OPTS"]) bonding_opts = bonding_opts.strip('"') primary_dev = None for combination in bonding_opts.split(" "): if re.match("primary", combination): (key,val) = combination.split("=") val = val.strip() primary_dev = val self.up_progress(10) for restore_dev in restore_dev_list: if move_file("%s/ifcfg-%s" % (VENDOR_DATA_BONDING_EVACUATION_DIR, restore_dev), NETWORK_IFCFG_DIR) is False: raise KssCommandException('Failure restore ifcfg file.') if os.path.isfile("%s/ifcfg-p%s" % (VENDOR_DATA_BONDING_EVACUATION_DIR, restore_dev)): if move_file("%s/ifcfg-p%s" % (VENDOR_DATA_BONDING_EVACUATION_DIR, restore_dev), NETWORK_IFCFG_DIR) is False: raise KssCommandException('Failure restore ifcfg file.') self.up_progress(10) if opts.succession is True and primary_dev is not None: dop = DictOp() ifcfg_parser = ifcfgParser() dop.addconf("ifcfg", ifcfg_parser.read_conf()) if dop.getconf("ifcfg") == {}: raise KssCommandException('Failure read network config file.') if ipaddr: dop.set("ifcfg", [primary_dev, "IPADDR"], ipaddr) if netmask: dop.set("ifcfg", [primary_dev, "NETMASK"], netmask) if gateway: dop.set("ifcfg", [primary_dev, "GATEWAY"], gateway) if ifcfg_parser.write_conf(dop.getconf("ifcfg")) is False: raise KssCommandException('Failure write network config file.') self.up_progress(10) remove_file("%s/ifcfg-%s" % (NETWORK_IFCFG_DIR, opts.dev)) self.up_progress(10) dop = DictOp() modprobe_parser = modprobe_confParser() dop.addconf("modprobe_conf", modprobe_parser.read_conf()) if dop.getconf("modprobe_conf") == {}: raise KssCommandException('Failure read modprobe config file.') dop.unset("modprobe_conf", ["alias", opts.dev]) if modprobe_parser.write_conf(dop.getconf("modprobe_conf")) is False: raise KssCommandException('Failure write modprobe config file.') self.up_progress(10) # # Delete bridge device # bridge_list = get_bridge_info() bond_bridge = None for bridge in bridge_list: if opts.dev in bridge_list[bridge]: bond_bridge = bridge if bond_bridge: ifdown_cmd = (NETWORK_IFDOWN_COMMAND, bond_bridge, ) (ifdown_rc, ifdown_res) = execute_command(ifdown_cmd) if ifdown_rc != 0: raise KssCommandException('Failure stop interface. interface:%s' % (dev)) for brif in bridge_list[bond_bridge]: brctl_delif_cmd = (NETWORK_BRCTL_COMMAND, "delif", bond_bridge, brif, ) (brctl_rc, brctl_res) = execute_command(brctl_delif_cmd) if brctl_rc != 0: raise KssCommandException('Failure delete bridge port. bridge:%s port:%s' % (dev, brif)) brctl_delbr_cmd = (NETWORK_BRCTL_COMMAND, "delbr", bond_bridge, ) (brctl_rc, brctl_res) = execute_command(brctl_delbr_cmd) if brctl_rc != 0: raise KssCommandException('Failure delete bridge. bridge:%s' % (dev, brif)) remove_file("%s/ifcfg-%s" % (NETWORK_IFCFG_DIR, bond_bridge)) # # Unload bonding module # remove_bonding_cmd = (SYSTEM_COMMAND_REMOVE_MODULE, "bonding", ) (rmmod_rc, rmmod_res) = execute_command(remove_bonding_cmd) if rmmod_rc != 0: raise KssCommandException('Failure remove bonding module.') # # Restart network # network_restart_cmd = (NETWORK_COMMAND, "restart", ) (net_rc, net_res) = execute_command(network_restart_cmd) if net_rc != 0: raise KssCommandException('Failure restart network.') self.logger.info("Deleted bonding device. - bond=%s dev=%s" % (opts.dev, ','.join(restore_dev_list))) print >>sys.stdout, _("Deleted bonding device. - bond=%s dev=%s" % (opts.dev, ','.join(restore_dev_list))) return True
class ifcfgParser: _module = "ifcfg" def __init__(self): self.dop = DictOp() self.dop.addconf(self._module, {}) self.parser = Parser() self.exclude_device_regex = "\.old|\.bak|\.rpm.*|lo|\.20" self.exclude_device_regex = "\.old|\.bak|\.rpm.*|\.20" self.base_parser_name = self.parser.__class__.__name__ pass def source_file(self): retval = [] glob_str = "%s/%s" % ( PARSER_IFCFG_DIR, PARSER_IFCFG_FILE_PREFIX, ) for _afile in glob.glob("%s*" % glob_str): device_name = _afile.replace(glob_str, "") if re.search(r"%s" % self.exclude_device_regex, device_name) is None: retval.append(_afile) return retval def read_conf(self, extra_args=None): retval = {} for _afile in self.source_file(): device_name = os.path.basename(_afile).replace( PARSER_IFCFG_FILE_PREFIX, "") self.parser.set_source_file([_afile]) conf_arr = self.parser.read_conf() try: self.dop.set(self._module, [device_name], conf_arr[_afile]['value']) except: pass self.dop.set(self._module, ['@BASE_PARSER'], self.base_parser_name) #self.dop.preprint_r(self._module) return self.dop.getconf(self._module) def write_conf(self, conf_arr={}, extra_args=None, dryrun=False): retval = True for device_name, _v in conf_arr.iteritems(): _afile = "%s/%s%s" % (PARSER_IFCFG_DIR, PARSER_IFCFG_FILE_PREFIX, device_name) try: _v['action'] if _v['action'] == "delete": if os.path.exists(_afile): os.unlink(_afile) #pass except: continue try: _v['value'] self.dop.addconf("parser", {}) self.dop.set("parser", [_afile], _v['value']) #self.dop.preprint_r("parser") arr = self.dop.getconf("parser") self.parser.write_conf(arr, dryrun=dryrun) except: pass return retval
class collectdParser: _module = "collectd" def __init__(self): self.dop = DictOp() self.dop.addconf(self._module,{}) self.parser = Parser() self.parser.set_delim("[ \t]+") self.parser.set_new_delim("\t") self.parser.set_comment("#") self.base_parser_name = self.parser.__class__.__name__ self.opt_uni = ['Hostname', 'FQDNLookup', 'BaseDir', 'PIDFile', 'Target', 'Host', 'Key', 'LogLevel', 'Plugin', 'Subject', 'SMTPPort', 'SMTPServer', 'URL', 'Type', 'Chain'] self.opt_multi = ['Include', 'LoadPlugin', 'Collect', 'DriverOption', 'GetCapacity', 'GetSnapshot', 'Irq', 'JVMArg', 'Listen', 'PreCacheChain', 'PostCacheChain', 'Query', 'Recipient', 'Sensor', 'Server', 'WatchAdd'] self.opt_sect = ['Plugin', 'LoadPlugin', 'Threshold', 'Type', 'Chain', 'Data', 'Database', 'Directory', 'Disks', 'File', 'Host', 'Key', 'Match', 'Metric', 'Module', 'Page', 'Query', 'Recursor', 'Result', 'Router', 'Rule', 'Server', 'System', 'Table', 'Target', 'URL', 'View', 'VolumePerf', 'VolumeUsage', 'WAFL'] self.parser.set_opt_uni(self.opt_uni) self.parser.set_opt_multi(self.opt_multi) self.parser.set_opt_sect(self.opt_sect) pass def set_footer(self, footer=""): self.parser.set_footer(footer) def source_file(self): retval = [PARSER_COLLECTD_CONF] return retval def read_conf(self,extra_args=None): retval = {} self.parser.set_source_file([PARSER_COLLECTD_CONF]) conf_arr = self.parser.read_conf() try: self.dop.addconf(self._module,conf_arr[PARSER_COLLECTD_CONF]['value']) except: pass self.dop.set(self._module,['@BASE_PARSER'],self.base_parser_name) #self.dop.preprint_r(self._module) return self.dop.getconf(self._module) def write_conf(self,conf_arr={},extra_args=None,dryrun=False): retval = True try: self.dop.addconf("parser",{}) self.dop.set("parser",[PARSER_COLLECTD_CONF],conf_arr) #self.dop.preprint_r("parser") arr = self.dop.getconf("parser") self.parser.write_conf(arr,dryrun=dryrun) except: pass return retval
class collectdpluginParser: _module = "collectdplugin" def __init__(self): self.dop = DictOp() self.dop.addconf(self._module,{}) self.parser = Parser() self.parser.set_delim("[ \t]+") self.parser.set_new_delim("\t") self.parser.set_comment("#") self.base_parser_name = self.parser.__class__.__name__ from karesansui.lib.parser.collectd import collectdParser collectdp = collectdParser() self.parser.set_opt_uni(collectdp.opt_uni) self.parser.set_opt_multi(collectdp.opt_multi) self.parser.set_opt_sect(collectdp.opt_sect) pass def set_footer(self, footer=""): self.parser.set_footer(footer) def source_file(self): retval = [] glob_str = "%s/*.conf" % (PARSER_COLLECTD_PLUGIN_DIR,) for _afile in glob.glob(glob_str): retval.append(_afile) return retval def read_conf(self,extra_args=None): retval = {} for _afile in self.source_file(): plugin_name = re.sub("\.conf$","",os.path.basename(_afile)) try: extra_args['include'] if not re.search(extra_args['include'],plugin_name): continue except: pass self.parser.set_source_file([_afile]) conf_arr = self.parser.read_conf() try: self.dop.set(self._module,[plugin_name],conf_arr[_afile]['value']) except: pass self.dop.set(self._module,['@BASE_PARSER'],self.base_parser_name) #self.dop.preprint_r(self._module) return self.dop.getconf(self._module) def _pre_write_conf(self,conf_arr={}): # Change permission to be able to read/write data kss group. if os.path.exists(COLLECTD_DATA_DIR): if os.getuid() == 0: r_chgrp(COLLECTD_DATA_DIR,KARESANSUI_GROUP) r_chmod(COLLECTD_DATA_DIR,"g+rwx") r_chmod(COLLECTD_DATA_DIR,"o-rwx") dop = DictOp() dop.addconf("__",conf_arr) if dop.isset("__",["python"]) is True: dop.cdp_unset("__",["python","Plugin","python","@ORDERS"],multiple_file=True) orders = [] orders.append(['Encoding']) orders.append(['LogTraces']) orders.append(['Interactive']) orders.append(['ModulePath']) orders.append(['Import']) orders.append(['Module']) dop.cdp_set("__",["python","Plugin","python","@ORDERS"],orders,is_opt_multi=True,multiple_file=True) return dop.getconf("__") def write_conf(self,conf_arr={},extra_args=None,dryrun=False): retval = True conf_arr = self._pre_write_conf(conf_arr) for plugin_name,_v in conf_arr.iteritems(): _afile = "%s/%s.conf" % (PARSER_COLLECTD_PLUGIN_DIR,plugin_name,) try: _v['action'] if _v['action'] == "delete": if os.path.exists(_afile): os.unlink(_afile) continue except: pass #continue try: _v['value'] self.dop.addconf("parser",{}) self.dop.set("parser",[_afile],_v['value']) #self.dop.preprint_r("parser") arr = self.dop.getconf("parser") self.parser.write_conf(arr,dryrun=dryrun) except: pass return retval
def process(self): (opts, args) = getopts() chkopts(opts) self.up_progress(1) uniq_id = time.strftime("%Y%m%d%H%M%S", time.localtime()) if opts.pre_command is not None: if opts.pre_command[0:4] == "b64:": command = base64_decode(opts.pre_command[4:]) else: command = opts.pre_command self.logger.info("execute command - %s" % command) (_ret,_res) = execute_command(command.split()) if _ret != 0: error_msg = "execute error - %s" % command self.logger.error(error_msg) #raise KssCommandOptException("ERROR: %s" % error_msg) dop = DictOp() modules = opts.module.split(":") files = opts.file.split(":") source_files = [] retval = True cnt = 0 for _mod in modules: _file = files[cnt] try: exec("from karesansui.lib.parser.%s import %sParser as Parser" % (_mod,_mod,)) self.up_progress(5) parser = Parser() # 辞書オペレータに追加 self.up_progress(5) if opts.php is True: conf_arr = php_array_to_python_dict(open(_file).read()) else: exec("conf_arr = %s" % open(_file).read()) dop.addconf(_mod,conf_arr) """ 必要ならここで配列操作 通常は、配列操作後の辞書が_fileに書き込まれているので必要ない dop.add (_mod,"foo","bar") dop.delete(_mod,"foo") """ # 設定ファイル一覧に作成(バックアップ用) self.up_progress(5) source_file = parser.source_file() for _afile in source_file: _bak_afile = "%s.%s" % (_afile,uniq_id) copy_file(_afile,_bak_afile) source_files = source_files + source_file # 辞書に戻す self.up_progress(5) conf_arr = dop.getconf(_mod) #dop.preprint_r(_mod) # 設定ファイルに書き込み self.up_progress(5) extra_args = {} extra_args["include"] = opts.include if opts.early_exit is True: retval = retval and parser.write_conf(conf_arr,extra_args=extra_args) else: retval = parser.write_conf(conf_arr,extra_args=extra_args) and retval if opts.delete is True: os.unlink(_file) finally: cnt = cnt + 1 if retval is False: for _afile in source_files: _bak_afile = "%s.%s" % (_afile,uniq_id) os.unlink(_afile) copy_file(_bak_afile,_afile) os.unlink(_bak_afile) raise KssCommandOptException("ERROR: write configure failure") for _afile in source_files: _bak_afile = "%s.%s" % (_afile,uniq_id) os.unlink(_bak_afile) if opts.post_command is not None: if opts.post_command[0:4] == "b64:": command = base64_decode(opts.post_command[4:]) else: command = opts.post_command self.logger.info("execute command - %s" % command) (_ret,_res) = execute_command(command.split()) if _ret != 0: error_msg = "execute error - %s" % command self.logger.error(error_msg) raise KssCommandOptException("ERROR: %s" % error_msg) self.up_progress(10) return True
def _value_to_lines(self, conf_arr, level=0): lines = [] orders_key = "%sORDERS" % (self._reserved_key_prefix, ) dop = DictOp() dop.addconf("__", conf_arr) for _k, _v in dop.getconf("__").iteritems(): action = dop.action("__", [_k]) if action == "delete": continue iscomment = dop.iscomment("__", [_k]) value = dop.get("__", [_k]) if type(value) == list: _val = value[0] if type(_val) != dict: _pre_comment = value[1][0] _post_comment = value[1][1] pre_comment = [] try: for _aline in _pre_comment: if _aline.strip() == "": pass elif _aline[0:1] != self._comment: _prefix = "" if level > 0: _prefix += str_repeat(self._indent, level) _prefix += self._comment _aline = "%s %s" % ( _prefix, _aline, ) pre_comment.append(_aline) except: pass if len(pre_comment) > 0: #preprint_r(pre_comment) lines = lines + pre_comment post_comment = _post_comment try: if post_comment is not None and post_comment[ 0:1] != self._comment: post_comment = "%s %s" % ( self._comment, post_comment, ) except: pass else: pass else: _val = value _prefix = "" if iscomment is True: _prefix += self._comment if level > 0: _prefix += str_repeat(self._indent, level) if type(_val) == dict: # ORDER順に設定する orders = [] try: old_orders = _val[orders_key]['value'] except: old_orders = [] for kk in old_orders: if type(kk) is list: orders.append(kk[0]) elif type(kk) is str: orders.append(kk) for kk in _val.keys(): if not kk in orders: orders.append(kk) #for _k2,_v2 in _val.iteritems(): for _k2 in orders: if _k2 == orders_key: continue _v2 = _val[_k2] sub_value = {} sub_value[_k2] = _v2 try: iscomment = sub_value[_k2]['comment'] except: iscomment = False try: action = sub_value[_k2]['action'] except: action = "" if action == "delete": continue #try: # sub_value[_k2]['value'][1][0] # lines = lines + sub_value[_k2]['value'][1][0] #except: # pass is_sect = False if _k in self.opt_multi and _k2 == _v2["value"][0]: for _k3, _v3 in sub_value.iteritems(): try: iscomment3 = sub_value[_k3]['comment'] except: iscomment3 = iscomment try: action3 = sub_value[_k3]['action'] except: action3 = "" _prefix = "" if iscomment is True: _prefix += self._comment if level > 0: _prefix += str_repeat(self._indent, level) lines.append("%s%-18s%s%s" % (_prefix, _k, self._new_delim, _k2)) elif _k in self.opt_sect: is_sect = True _prefix = "" if iscomment is True: _prefix += self._comment if level > 0: _prefix += str_repeat(self._indent, level) if _k2 == "": lines.append("%s<%s>" % (_prefix, _k)) else: lines.append("%s<%s \"%s\">" % (_prefix, _k, _k2)) new_level = level + 1 new_lines = self._value_to_lines(sub_value, level=new_level) for _aline in new_lines: _prefix2 = "" if iscomment is True: _prefix2 += self._comment new_aline = "%s%s" % ( _prefix2, _aline, ) new_aline = re.sub("^%s+" % self._comment, self._comment, new_aline) lines.append(new_aline) #lines = lines + new_lines if is_sect is True: lines.append("%s</%s>" % ( _prefix, _k, )) else: aline = "" if _k in self.opt_multi: aline += "%s%-18s%s%s" % ( _prefix, _k, self._new_delim, _val, ) else: if re.match("^[A-Z]+[a-z]", _k): aline += "%s%-18s%s%s" % ( _prefix, _k, self._new_delim, _val, ) if post_comment is not None: aline = "%s %s" % ( aline, post_comment, ) if aline != "": lines.append(aline) return lines
def process(self): (opts, args) = getopts() chkopts(opts) self.up_progress(1) uniq_id = time.strftime("%Y%m%d%H%M%S", time.localtime()) if opts.pre_command is not None: if opts.pre_command[0:4] == "b64:": command = base64_decode(opts.pre_command[4:]) else: command = opts.pre_command self.logger.info("execute command - %s" % command) if opts.dry_run is True: print "" print ">>>Execute pre command: %s" % command print "" else: (_ret,_res) = execute_command(command.split()) if _ret != 0: error_msg = "execute error - %s" % command self.logger.error(error_msg) #raise KssCommandOptException("ERROR: %s" % error_msg) self.up_progress(5) from karesansui.lib.parser.collectd import collectdParser from karesansui.lib.parser.collectdplugin import collectdpluginParser dop = DictOp() collectd_parser = collectdParser() dop.addconf("collectd",collectd_parser.read_conf()) collectdplugin_parser = collectdpluginParser() extra_args = {"include":"^(%s)$" % "|".join(COLLECTD_PLUGINS)} dop.addconf("collectdplugin",collectdplugin_parser.read_conf(extra_args=extra_args)) initialize_collectd_settings(dop=dop,force=opts.force,reverse=opts.reverse) retval = collectd_parser.write_conf(dop.getconf("collectd"),dryrun=opts.dry_run) retval = collectdplugin_parser.write_conf(dop.getconf("collectdplugin"),extra_args=extra_args,dryrun=opts.dry_run) self.up_progress(30) if opts.post_command is not None: if opts.post_command[0:4] == "b64:": command = base64_decode(opts.post_command[4:]) else: command = opts.post_command self.logger.info("execute command - %s" % command) if opts.dry_run is True: print "" print ">>>Execute post command: %s" % command print "" else: (_ret,_res) = execute_command(command.split()) if _ret != 0: error_msg = "execute error - %s" % command self.logger.error(error_msg) raise KssCommandOptException("ERROR: %s" % error_msg) self.up_progress(10) return True
def process(self): (opts, args) = getopts() chkopts(opts) self.up_progress(10) original_parser = iscsidParser() new_parser = iscsidParser() dop = DictOp() dop.addconf("original", original_parser.read_conf()) dop.addconf("new", new_parser.read_conf()) self.up_progress(10) dop.cdp_set("new", ISCSI_CONFIG_KEY_AUTH_METHOD, opts.auth) if opts.auth == ISCSI_CONFIG_VALUE_AUTH_METHOD_CHAP: password = "" if opts.password is not None: password = opts.password elif opts.password_file is not None and is_readable( opts.password_file): try: fp = open(opts.password_file, "r") try: fcntl.lockf(fp.fileno(), fcntl.LOCK_SH) try: password = fp.readline().strip("\n") finally: fcntl.lockf(fp.fileno(), fcntl.LOCK_UN) self.up_progress(10) finally: fp.close() except: raise KssCommandException('Failed to read file. - target host=%s password_file=%s' \ % (opts.host,opts.password_file)) try: os.remove(opts.password_file) except: raise KssCommandException('Failed to remove file. - target host=%s password_file=%s' \ % (opts.host,opts.password_file)) dop.cdp_set("new", ISCSI_CONFIG_KEY_AUTH_METHOD, opts.auth) dop.cdp_set("new", ISCSI_CONFIG_KEY_AUTH_USER, opts.user) dop.cdp_set("new", ISCSI_CONFIG_KEY_AUTH_PASSWORD, password) else: dop.comment("new", ISCSI_CONFIG_KEY_AUTH_USER) dop.comment("new", ISCSI_CONFIG_KEY_AUTH_PASSWORD) self.up_progress(10) if opts.autostart: dop.cdp_set("new", ISCSI_CONFIG_KEY_SATRTUP, ISCSI_CONFIG_VALUE_SATRTUP_ON) else: dop.cdp_set("new", ISCSI_CONFIG_KEY_SATRTUP, ISCSI_CONFIG_VALUE_SATRTUP_OFF) new_parser.write_conf(dop.getconf("new")) self.up_progress(10) discovery_command_args = (ISCSI_CMD, ISCSI_CMD_OPTION_MODE, ISCSI_CMD_OPTION_MODE_DISCOVERY, ISCSI_CMD_OPTION_TYPE, ISCSI_CMD_OPTION_TYPE_SENDTARGETS, ISCSI_CMD_OPTION_PORTAL, opts.host) (discovery_rc, discovery_res) = execute_command(discovery_command_args) self.up_progress(10) original_parser.write_conf(dop.getconf("original")) self.up_progress(10) if discovery_rc != 0: raise KssCommandException( 'Failed to add iSCSI. - host=%s message=%s' % (opts.host, discovery_res)) if discovery_res == []: raise KssCommandException( 'Failed to add iSCSI. - host=%s message=No exist permit iSCSI disk for target.' % (opts.host)) for node_line in discovery_res: if not node_line: continue try: node = iscsi_parse_node(node_line) except: self.logger.warn( 'Failed to parse iSCSI discovery command response. message="%s"' % (node_line)) continue self.logger.info("%s" % (iscsi_print_format_node(node))) print >> sys.stdout, _("%s") % (iscsi_print_format_node(node)) return True
def process(self): (opts, args) = getopts() chkopts(opts) self.up_progress(10) config_path = iscsi_get_config_path(opts.host, opts.iqn, opts.port, opts.tpgt) parser = iscsidParser() dop = DictOp() dop.addconf("new", parser.read_conf(config_path)) self.up_progress(10) dop.cdp_set("new", ISCSI_CONFIG_KEY_AUTH_METHOD, opts.auth) if opts.auth == ISCSI_CONFIG_VALUE_AUTH_METHOD_CHAP: password = "" if opts.password is not None: password = opts.password elif opts.password_file is not None and is_readable(opts.password_file): try: fp = open(opts.password_file, "r") try: fcntl.lockf(fp.fileno(), fcntl.LOCK_SH) try: password = fp.readline().strip("\n") finally: fcntl.lockf(fp.fileno(), fcntl.LOCK_UN) self.up_progress(10) finally: fp.close() except: raise KssCommandException('Failed to read file. - target host=%s password_file=%s' \ % (opts.host,opts.password_file)) try: os.remove(opts.password_file) except: raise KssCommandException('Failed to remove file. - target host=%s password_file=%s' \ % (opts.host,opts.password_file)) dop.cdp_set("new", ISCSI_CONFIG_KEY_AUTH_USER, opts.user) dop.cdp_set("new", ISCSI_CONFIG_KEY_AUTH_PASSWORD, password) else: dop.comment("new", ISCSI_CONFIG_KEY_AUTH_USER) dop.comment("new", ISCSI_CONFIG_KEY_AUTH_PASSWORD) self.up_progress(10) if opts.autostart: dop.cdp_set("new", ISCSI_CONFIG_KEY_SATRTUP, ISCSI_CONFIG_VALUE_SATRTUP_ON) else: dop.cdp_set("new", ISCSI_CONFIG_KEY_SATRTUP, ISCSI_CONFIG_VALUE_SATRTUP_OFF) self.up_progress(10) parser.write_conf(dop.getconf("new"), config_path) self.up_progress(30) self.logger.info("Updated iSCSI node. - host=%s iqn=%s" % (opts.host, opts.iqn)) print >>sys.stdout, _("Updated iSCSI node. - host=%s iqn=%s") % (opts.host, opts.iqn) return True
def process(self): (opts, args) = getopts() chkopts(opts) self.up_progress(10) dev_list = comma_split(opts.dev) if len(dev_list) < 2: # TRANSLATORS: # bondingするためのdeviceが少ないです raise KssCommandOptException( 'ERROR: Small device for bonding. - dev=%s' % (opts.dev)) interface_list = get_ifconfig_info() for dev in dev_list: if dev not in interface_list: raise KssCommandOptException( 'ERROR: Bonding target device not found. - dev=%s' % (dev)) if opts.primary not in dev_list: raise KssCommandOptException( 'ERROR: Primary device not found in bonding device. - primary=%s dev=%s' % (opts.primary, opts.dev)) exist_bond_max_num = -1 exist_bond_list = get_ifconfig_info("regex:^bond") for bond_name in exist_bond_list.keys(): try: num = int(bond_name.replace("bond", "")) except ValueError: continue if exist_bond_max_num < num: exist_bond_max_num = num self.up_progress(10) physical_bond_name = "bond%s" % (exist_bond_max_num + 1) bridge_bond_name = "bondbr%s" % (exist_bond_max_num + 1) bond_options = '"mode=%s primary=%s miimon=%s"' % ( opts.mode, opts.primary, BONDING_CONFIG_MII_DEFAULT) self.up_progress(10) dop = DictOp() ifcfg_parser = ifcfgParser() modprobe_parser = modprobe_confParser() dop.addconf("ifcfg", ifcfg_parser.read_conf()) if dop.getconf("ifcfg") == {}: raise KssCommandException('Failure read network config file.') dop.addconf("modprobe_conf", modprobe_parser.read_conf()) if dop.getconf("modprobe_conf") == {}: raise KssCommandException('Failure read modprobe config file.') self.up_progress(10) eth_conf_copykey = [ "HWADDR", "BOOTPROTO", "ONBOOT", "USERCTL", ] bond_conf_nocopykey = [ "TYPE", "HWADDR", "MACADDR", "ETHTOOL_OPTS", "ESSID", "CHANNEL", ] self.up_progress(10) for dev in dev_list: conf = dop.get("ifcfg", dev) if dev == opts.primary: primary_conf = copy.deepcopy(conf) dop.unset("ifcfg", dev) dop.set("ifcfg", [dev, "DEVICE"], conf["DEVICE"]["value"]) for key in eth_conf_copykey: if key in conf: dop.set("ifcfg", [dev, key], conf[key]["value"]) dop.set("ifcfg", [dev, "MASTER"], physical_bond_name) dop.set("ifcfg", [dev, "SLAVE"], "yes") dop.set("ifcfg", [dev, "BOOTPROTO"], "none") if dop.get("ifcfg", "p%s" % (dev)): hwaddr = dop.get("ifcfg", ["p%s" % (dev), "HWADDR"]) if hwaddr: dop.set("ifcfg", [dev, "HWADDR"], hwaddr) dop.unset("ifcfg", "p%s" % (dev)) for key in bond_conf_nocopykey: if key in primary_conf: del primary_conf[key] dop.set("ifcfg", bridge_bond_name, primary_conf) dop.set("ifcfg", [bridge_bond_name, "DEVICE"], bridge_bond_name) dop.set("ifcfg", [bridge_bond_name, "TYPE"], "Bridge") dop.set("ifcfg", [physical_bond_name, "DEVICE"], physical_bond_name) dop.set("ifcfg", [physical_bond_name, "BRIDGE"], bridge_bond_name) dop.set("ifcfg", [physical_bond_name, "BOOTPROTO"], "none") dop.set("ifcfg", [physical_bond_name, "ONBOOT"], dop.get("ifcfg", [bridge_bond_name, "ONBOOT"])) dop.set("ifcfg", [physical_bond_name, "BONDING_OPTS"], bond_options) self.up_progress(10) dop.set("modprobe_conf", ["alias", physical_bond_name], "bonding") for dev in dev_list: if os.path.isfile("%s/ifcfg-%s" % (NETWORK_IFCFG_DIR, dev)): copy_file("%s/ifcfg-%s" % (NETWORK_IFCFG_DIR, dev), VENDOR_DATA_BONDING_EVACUATION_DIR) if os.path.isfile("%s/ifcfg-p%s" % (NETWORK_IFCFG_DIR, dev)): move_file("%s/ifcfg-p%s" % (NETWORK_IFCFG_DIR, dev), VENDOR_DATA_BONDING_EVACUATION_DIR) if ifcfg_parser.write_conf(dop.getconf("ifcfg")) is False: raise KssCommandException('Failure write network config file.') if modprobe_parser.write_conf(dop.getconf("modprobe_conf")) is False: raise KssCommandException('Failure write modprobe config file.') self.up_progress(10) # # Delete bridge device # bridge_list = get_bridge_info() for dev in dev_list: if dev in bridge_list: ifdown_cmd = ( NETWORK_IFDOWN_COMMAND, dev, ) (ifdown_rc, ifdown_res) = execute_command(ifdown_cmd) if ifdown_rc != 0: raise KssCommandException( 'Failure stop interface. interface:%s' % (dev)) for brif in bridge_list[dev]: brctl_delif_cmd = ( NETWORK_BRCTL_COMMAND, "delif", dev, brif, ) (brctl_rc, brctl_res) = execute_command(brctl_delif_cmd) if brctl_rc != 0: raise KssCommandException( 'Failure delete bridge port. bridge:%s port:%s' % (dev, brif)) brctl_delbr_cmd = ( NETWORK_BRCTL_COMMAND, "delbr", dev, ) (brctl_rc, brctl_res) = execute_command(brctl_delbr_cmd) if brctl_rc != 0: raise KssCommandException( 'Failure delete bridge. bridge:%s' % (dev, brif)) self.up_progress(10) # # Restart network # network_restart_cmd = ( NETWORK_COMMAND, "restart", ) (net_rc, net_res) = execute_command(network_restart_cmd) if net_rc != 0: raise KssCommandException('Failure restart network.') self.logger.info("Created bonding device. - dev=%s bond=%s" % (opts.dev, bridge_bond_name)) print >> sys.stdout, _("Created bonding device. - dev=%s bond=%s" % (opts.dev, bridge_bond_name)) return True
def _read_conf(self, lines, level=0): dop = DictOp() dop.addconf("__", {}) pre_comment = [] # 設定の前のコメント リスト配列 post_comment = None # 設定行のコメント 文字列 _in_section = False _res = [] for _aline in lines: if _in_section is True: regex = "[ \t]*(?P<comment>#*)[ \t]*</(?P<key>%s)>" % _section_key #'|'.join(self.opt_sect) _regex = re.compile(r"%s" % regex) m = _regex.match(_aline) if m: _comment = m.group('comment') _key = m.group('key').strip() values = self.build_value(self._read_conf(_res, level), pre_comment, post_comment) dop.set("__", [_key, _section_val], values) if _comment != "": dop.comment("__", [_key, _section_val]) if level == 1: self.orders.append([_key, _section_val]) pre_comment = [] post_comment = None _in_section = False _res = [] level = level - 1 else: _res.append(_aline) else: _aline = _aline.rstrip('\r\n') if _aline.strip() == "": pre_comment.append(_aline) continue match = False for _type in ['uni', 'multi', 'sect']: exec("regex = '|'.join(self.opt_%s)" % _type) if _type == "sect": regex = "[ \t]*(?P<comment>#*)[ \t]*<(?P<key>%s)(?P<section>.*)>" % regex elif _type == "multi": regex = "[ \t]*(?P<comment>#*)[ \t]*(?P<key>%s)[ \t]+(?P<value>.+)" % regex elif _type == "uni": regex = "[ \t]*(?P<comment>#*)[ \t]*(?P<key>%s)[ \t]+(?P<value>.+)" % regex _regex = re.compile(r"%s" % regex) m = _regex.match(_aline) if m: match = True _comment = m.group('comment') _key = m.group('key').strip() if _type == "sect": _section_key = _key _section_val = re.sub(r"[\"']", "", m.group('section').strip()) _in_section = True level = level + 1 elif _type == "multi": _value = m.group('value').strip() if _value.find(self._comment) > 0: post_comment = _value[_value.find(self._comment ):] _value = re.sub("%s$" % post_comment, "", _value).rstrip() values = self.build_value(_value, pre_comment, post_comment) dop.set("__", [_key, _value], values) if _comment != "": dop.comment("__", [_key, _value]) if level == 0: self.orders.append([_key, _value]) pre_comment = [] post_comment = None elif _type == "uni": _value = m.group('value').strip() if _value.find(self._comment) > 0: post_comment = _value[_value.find(self._comment ):] _value = re.sub("%s$" % post_comment, "", _value).rstrip() values = self.build_value(_value, pre_comment, post_comment) dop.set("__", [_key], values) if _comment != "": dop.comment("__", [_key]) if level == 0: self.orders.append([_key]) pre_comment = [] post_comment = None break if match is False: # ブラケットディレクティブのパラメータは除外する (よって、ブラケットディレクティブは全ての定義が必要!) # example: "<undefined_directive 'foobar'>" regex_exclude1 = "[ \t]*(?P<comment>#*)[ \t]*(?P<key>%s)[ \t]" % '|'.join( self.opt_sect) _regex_exclude1 = re.compile(r"%s" % regex_exclude1) # 未定義のパラメータの値がクオートせずにスペース区切りで3つ以上の値を指定している場合はコメント行とみなす # example: "# Read this configuration file" regex_exclude2 = "[ \t]*#+[ \t]*[^ \t]+([ \t]+[^ \t]+){3,}" _regex_exclude2 = re.compile(r"%s" % regex_exclude2) # 未定義のパラメータの値がクオートせずにスペース区切りで2つ以上の値を指定していて、かつ、最後が:で終わる場合はコメント行とみなす # example: "# Read this configuration:" regex_exclude3 = "[ \t]*#+[ \t]*[^ \t]+([ \t]+[^ \t]+){2,}:$" _regex_exclude3 = re.compile(r"%s" % regex_exclude3) # 未定義のパラメータの値が0個以上で、かつ、最後が:で終わる場合はコメント行とみなす # example: "# Read #" regex_exclude4 = "[ \t]*#+[ \t]*[^ \t]+.+[ \t]+#+$" _regex_exclude4 = re.compile(r"%s" % regex_exclude4) m1 = _regex_exclude1.match(_aline) m2 = _regex_exclude2.match(_aline) m3 = _regex_exclude3.match(_aline) m4 = _regex_exclude4.match(_aline) if not m1 and not m2 and not m3 and not m4: # opt_xxxに未定義のパラメータはuniパラメータとする regex = "[ \t]*(?P<comment>#*)[ \t]*(?P<key>[A-Z][^ \t]+)[ \t]+(?P<value>.+)" _regex = re.compile(r"%s" % regex) m = _regex.match(_aline) if m: _comment = m.group('comment') _key = m.group('key').strip() _value = m.group('value').strip() if _value.find(self._comment) > 0: post_comment = _value[_value.find(self._comment ):] _value = re.sub("%s$" % post_comment, "", _value).rstrip() values = self.build_value(_value, pre_comment, post_comment) dop.set("__", [_key], values) if _comment != "": dop.comment("__", [_key]) if level == 0: self.orders.append([_key]) pre_comment = [] post_comment = None match = True if match is False: if _aline.lstrip()[0:1] == self._comment: footer_regex = re.compile(self._footer) m = footer_regex.search(_aline) if not m: comment = _aline[_aline.find(self._comment):] pre_comment.append(comment) continue if len(pre_comment) > 0: eof_key = "%sEOF" % (self._reserved_key_prefix, ) new_value = self.build_value("", pre_comment, post_comment) dop.set("__", [eof_key], new_value) return dop.getconf("__")
class xmlLikeConfParser: _delim = "[ \t]+" _new_delim = " " _comment = "#" _reserved_key_prefix = "@" _indent = " " _module = "xml_like_conf_parser" _footer = "-- Generated by karesansui" def __init__(self, paths=[]): self.dop = DictOp() self.dop.addconf(self._module, {}) self.set_source_file(paths) self.opt_uni = ['PIDFile'] self.opt_multi = ['LoadPlugin', 'Include'] self.opt_sect = ['Directory', 'VirtualHost', 'View'] def set_opt_uni(self, opts): self.opt_uni = opts def set_opt_multi(self, opts): self.opt_multi = opts def set_opt_sect(self, opts): self.opt_sect = opts def set_delim(self, delim=" "): self._delim = delim def set_new_delim(self, delim=" "): self._new_delim = delim def set_comment(self, comment="#"): self._comment = comment def set_reserved_key_prefix(self, prefix="@"): self._reserved_key_prefix = prefix def set_footer(self, footer=""): self._footer = footer def set_source_file(self, paths=[]): if type(paths) == str: paths = [paths] self.paths = paths return True def get_source_file(self): return self.paths def source_file(self): return self.get_source_file() def build_value(self, value=None, precomment=[], postcomment=None): if type(precomment) == str: precomment = [precomment] return [ value, [precomment, postcomment], ] def read_conf(self): retval = {} orders_key = "%sORDERS" % (self._reserved_key_prefix, ) for _afile in self.source_file(): res = ConfigFile(_afile).read() self.orders = [] self.dop.set(self._module, [_afile], self._read_conf(res)) self.dop.set(self._module, [_afile, orders_key], self.orders) return self.dop.getconf(self._module) def _read_conf(self, lines, level=0): dop = DictOp() dop.addconf("__", {}) pre_comment = [] # 設定の前のコメント リスト配列 post_comment = None # 設定行のコメント 文字列 _in_section = False _res = [] for _aline in lines: if _in_section is True: regex = "[ \t]*(?P<comment>#*)[ \t]*</(?P<key>%s)>" % _section_key #'|'.join(self.opt_sect) _regex = re.compile(r"%s" % regex) m = _regex.match(_aline) if m: _comment = m.group('comment') _key = m.group('key').strip() values = self.build_value(self._read_conf(_res, level), pre_comment, post_comment) dop.set("__", [_key, _section_val], values) if _comment != "": dop.comment("__", [_key, _section_val]) if level == 1: self.orders.append([_key, _section_val]) pre_comment = [] post_comment = None _in_section = False _res = [] level = level - 1 else: _res.append(_aline) else: _aline = _aline.rstrip('\r\n') if _aline.strip() == "": pre_comment.append(_aline) continue match = False for _type in ['uni', 'multi', 'sect']: exec("regex = '|'.join(self.opt_%s)" % _type) if _type == "sect": regex = "[ \t]*(?P<comment>#*)[ \t]*<(?P<key>%s)(?P<section>.*)>" % regex elif _type == "multi": regex = "[ \t]*(?P<comment>#*)[ \t]*(?P<key>%s)[ \t]+(?P<value>.+)" % regex elif _type == "uni": regex = "[ \t]*(?P<comment>#*)[ \t]*(?P<key>%s)[ \t]+(?P<value>.+)" % regex _regex = re.compile(r"%s" % regex) m = _regex.match(_aline) if m: match = True _comment = m.group('comment') _key = m.group('key').strip() if _type == "sect": _section_key = _key _section_val = re.sub(r"[\"']", "", m.group('section').strip()) _in_section = True level = level + 1 elif _type == "multi": _value = m.group('value').strip() if _value.find(self._comment) > 0: post_comment = _value[_value.find(self._comment ):] _value = re.sub("%s$" % post_comment, "", _value).rstrip() values = self.build_value(_value, pre_comment, post_comment) dop.set("__", [_key, _value], values) if _comment != "": dop.comment("__", [_key, _value]) if level == 0: self.orders.append([_key, _value]) pre_comment = [] post_comment = None elif _type == "uni": _value = m.group('value').strip() if _value.find(self._comment) > 0: post_comment = _value[_value.find(self._comment ):] _value = re.sub("%s$" % post_comment, "", _value).rstrip() values = self.build_value(_value, pre_comment, post_comment) dop.set("__", [_key], values) if _comment != "": dop.comment("__", [_key]) if level == 0: self.orders.append([_key]) pre_comment = [] post_comment = None break if match is False: # ブラケットディレクティブのパラメータは除外する (よって、ブラケットディレクティブは全ての定義が必要!) # example: "<undefined_directive 'foobar'>" regex_exclude1 = "[ \t]*(?P<comment>#*)[ \t]*(?P<key>%s)[ \t]" % '|'.join( self.opt_sect) _regex_exclude1 = re.compile(r"%s" % regex_exclude1) # 未定義のパラメータの値がクオートせずにスペース区切りで3つ以上の値を指定している場合はコメント行とみなす # example: "# Read this configuration file" regex_exclude2 = "[ \t]*#+[ \t]*[^ \t]+([ \t]+[^ \t]+){3,}" _regex_exclude2 = re.compile(r"%s" % regex_exclude2) # 未定義のパラメータの値がクオートせずにスペース区切りで2つ以上の値を指定していて、かつ、最後が:で終わる場合はコメント行とみなす # example: "# Read this configuration:" regex_exclude3 = "[ \t]*#+[ \t]*[^ \t]+([ \t]+[^ \t]+){2,}:$" _regex_exclude3 = re.compile(r"%s" % regex_exclude3) # 未定義のパラメータの値が0個以上で、かつ、最後が:で終わる場合はコメント行とみなす # example: "# Read #" regex_exclude4 = "[ \t]*#+[ \t]*[^ \t]+.+[ \t]+#+$" _regex_exclude4 = re.compile(r"%s" % regex_exclude4) m1 = _regex_exclude1.match(_aline) m2 = _regex_exclude2.match(_aline) m3 = _regex_exclude3.match(_aline) m4 = _regex_exclude4.match(_aline) if not m1 and not m2 and not m3 and not m4: # opt_xxxに未定義のパラメータはuniパラメータとする regex = "[ \t]*(?P<comment>#*)[ \t]*(?P<key>[A-Z][^ \t]+)[ \t]+(?P<value>.+)" _regex = re.compile(r"%s" % regex) m = _regex.match(_aline) if m: _comment = m.group('comment') _key = m.group('key').strip() _value = m.group('value').strip() if _value.find(self._comment) > 0: post_comment = _value[_value.find(self._comment ):] _value = re.sub("%s$" % post_comment, "", _value).rstrip() values = self.build_value(_value, pre_comment, post_comment) dop.set("__", [_key], values) if _comment != "": dop.comment("__", [_key]) if level == 0: self.orders.append([_key]) pre_comment = [] post_comment = None match = True if match is False: if _aline.lstrip()[0:1] == self._comment: footer_regex = re.compile(self._footer) m = footer_regex.search(_aline) if not m: comment = _aline[_aline.find(self._comment):] pre_comment.append(comment) continue if len(pre_comment) > 0: eof_key = "%sEOF" % (self._reserved_key_prefix, ) new_value = self.build_value("", pre_comment, post_comment) dop.set("__", [eof_key], new_value) return dop.getconf("__") def _value_to_lines(self, conf_arr, level=0): lines = [] orders_key = "%sORDERS" % (self._reserved_key_prefix, ) dop = DictOp() dop.addconf("__", conf_arr) for _k, _v in dop.getconf("__").iteritems(): action = dop.action("__", [_k]) if action == "delete": continue iscomment = dop.iscomment("__", [_k]) value = dop.get("__", [_k]) if type(value) == list: _val = value[0] if type(_val) != dict: _pre_comment = value[1][0] _post_comment = value[1][1] pre_comment = [] try: for _aline in _pre_comment: if _aline.strip() == "": pass elif _aline[0:1] != self._comment: _prefix = "" if level > 0: _prefix += str_repeat(self._indent, level) _prefix += self._comment _aline = "%s %s" % ( _prefix, _aline, ) pre_comment.append(_aline) except: pass if len(pre_comment) > 0: #preprint_r(pre_comment) lines = lines + pre_comment post_comment = _post_comment try: if post_comment is not None and post_comment[ 0:1] != self._comment: post_comment = "%s %s" % ( self._comment, post_comment, ) except: pass else: pass else: _val = value _prefix = "" if iscomment is True: _prefix += self._comment if level > 0: _prefix += str_repeat(self._indent, level) if type(_val) == dict: # ORDER順に設定する orders = [] try: old_orders = _val[orders_key]['value'] except: old_orders = [] for kk in old_orders: if type(kk) is list: orders.append(kk[0]) elif type(kk) is str: orders.append(kk) for kk in _val.keys(): if not kk in orders: orders.append(kk) #for _k2,_v2 in _val.iteritems(): for _k2 in orders: if _k2 == orders_key: continue _v2 = _val[_k2] sub_value = {} sub_value[_k2] = _v2 try: iscomment = sub_value[_k2]['comment'] except: iscomment = False try: action = sub_value[_k2]['action'] except: action = "" if action == "delete": continue #try: # sub_value[_k2]['value'][1][0] # lines = lines + sub_value[_k2]['value'][1][0] #except: # pass is_sect = False if _k in self.opt_multi and _k2 == _v2["value"][0]: for _k3, _v3 in sub_value.iteritems(): try: iscomment3 = sub_value[_k3]['comment'] except: iscomment3 = iscomment try: action3 = sub_value[_k3]['action'] except: action3 = "" _prefix = "" if iscomment is True: _prefix += self._comment if level > 0: _prefix += str_repeat(self._indent, level) lines.append("%s%-18s%s%s" % (_prefix, _k, self._new_delim, _k2)) elif _k in self.opt_sect: is_sect = True _prefix = "" if iscomment is True: _prefix += self._comment if level > 0: _prefix += str_repeat(self._indent, level) if _k2 == "": lines.append("%s<%s>" % (_prefix, _k)) else: lines.append("%s<%s \"%s\">" % (_prefix, _k, _k2)) new_level = level + 1 new_lines = self._value_to_lines(sub_value, level=new_level) for _aline in new_lines: _prefix2 = "" if iscomment is True: _prefix2 += self._comment new_aline = "%s%s" % ( _prefix2, _aline, ) new_aline = re.sub("^%s+" % self._comment, self._comment, new_aline) lines.append(new_aline) #lines = lines + new_lines if is_sect is True: lines.append("%s</%s>" % ( _prefix, _k, )) else: aline = "" if _k in self.opt_multi: aline += "%s%-18s%s%s" % ( _prefix, _k, self._new_delim, _val, ) else: if re.match("^[A-Z]+[a-z]", _k): aline += "%s%-18s%s%s" % ( _prefix, _k, self._new_delim, _val, ) if post_comment is not None: aline = "%s %s" % ( aline, post_comment, ) if aline != "": lines.append(aline) return lines def write_conf(self, conf_arr={}, dryrun=False): retval = True self.dop.addconf(self._module, conf_arr) orders_key = "%sORDERS" % (self._reserved_key_prefix, ) eof_key = "%sEOF" % (self._reserved_key_prefix, ) for _path, _v in conf_arr.iteritems(): if _path[0:1] != "/": continue lines = [] try: _v['value'] except: continue exclude_regex = "^%s[A-Z0-9\_]+$" % self._reserved_key_prefix # まずはオーダの順 if self.dop.isset(self._module, [_path, orders_key]) is True: for _k2 in self.dop.get(self._module, [_path, orders_key]): try: if type(_k2) == str: _k2 = [_k2] _search_key = [_path] + _k2 is_opt_multi = False if _k2[0] in self.opt_multi: _tmp_conf = self.dop.get(self._module, _search_key) # multiとsectがかぶったオプションの対応 strならmulti if type(_tmp_conf[0]) == str: is_opt_multi = True if is_opt_multi is True: _k2.pop() new_lines = self._new_lines(_search_key, _k2) lines = lines + new_lines self.dop.unset(self._module, _search_key) except: pass # オーダにないものは最後に追加 for _k2, _v2 in self.dop.get(self._module, [_path]).iteritems(): #if _k2 != orders_key: m = re.match(exclude_regex, _k2) if not m: try: if type(_k2) == str: _k2 = [_k2] _search_key = [_path] + _k2 if _k2[0] in self.opt_multi: for _k3, _v3 in self.dop.get( self._module, _search_key).iteritems(): _search_key.append(_k3) new_lines = self._new_lines(_search_key, _k2) lines = lines + new_lines else: new_lines = self._new_lines(_search_key, _k2) lines = lines + new_lines except: pass # 最後のコメント用の処理 if self._footer != "": if self.dop.isset(self._module, [_path, eof_key]) is False: self.dop.cdp_set(self._module, [_path, eof_key], "", force=True) eof_val = self.dop.get(self._module, [_path, eof_key]) eof_action = self.dop.action(self._module, [_path, eof_key]) eof_comment = self.dop.comment(self._module, [_path, eof_key]) try: key = " %s - %s on %s" % (self._footer, self._module, time.strftime( "%c", time.localtime())) value = {} value[key] = {} value[key]["value"] = eof_val value[key]["action"] = eof_action value[key]["comment"] = eof_comment self.set_new_delim(delim=" ") lines = lines + self._value_to_lines(value) except: pass if dryrun is False: if len(lines) > 0: ConfigFile(_path).write("\n".join(lines) + "\n") else: print "%s -- filename: %s" % ( self._comment, _path, ) print "\n".join(lines) return retval def _new_lines(self, search_key, new_key): try: attrs = self.dop.get(self._module, search_key, with_attr=True) action = attrs['action'] iscomment = attrs['comment'] val = attrs['value'] except: action = self.dop.action(self._module, search_key) iscomment = self.dop.iscomment(self._module, search_key) val = self.dop.get(self._module, search_key) pass #print val dop = DictOp() dop.addconf('__', {}) if action == "delete": dop.add('__', new_key, val) dop.delete('__', new_key) elif action == "set": dop.set('__', new_key, val) else: dop.add('__', new_key, val) if iscomment is True: dop.comment('__', new_key) #preprint_r(dop.getconf('__')) new_lines = self._value_to_lines(dop.getconf('__')) #print "\n".join(new_lines) return new_lines
class staticrouteParser: _module = "staticroute" def __init__(self): self.dop = DictOp() self.dop.addconf(self._module,{}) self.exclude_device_regex = "\.old|\.bak|\.rpm.*|\.20" self.parser = Parser() self.config_style = self.detect_config_style() if self.config_style == "old": self.parser.set_delim(" via ") self.parser.set_new_delim(" via ") else: self.parser.set_delim("=") self.parser.set_new_delim("=") self.base_parser_name = self.parser.__class__.__name__ pass def detect_config_style(self): retval = PARSER_STATICROUTE_DEFAULT_CONFIG_STYLE command_args = ["grep","ADDRESS\[0\-9\]",PARSER_COMMAND_IFUP_ROUTE] (ret,res) = execute_command(command_args) if ret == 0: retval = "new" glob_str = "%s/%s" % (PARSER_STATICROUTE_DIR,PARSER_STATICROUTE_FILE_PREFIX,) for _afile in glob.glob("%s*" % glob_str): device_name = _afile.replace(glob_str,"") if re.search(r"%s" % self.exclude_device_regex, device_name) is None: command_args = ["grep"," via ",_afile] (ret,res) = execute_command(command_args) if ret == 0: retval = "old" break return retval def source_file(self): retval = [] glob_str = "%s/%s" % (PARSER_STATICROUTE_DIR,PARSER_STATICROUTE_FILE_PREFIX,) for _afile in glob.glob("%s*" % glob_str): device_name = _afile.replace(glob_str,"") if re.search(r"%s" % self.exclude_device_regex, device_name) is None: retval.append(_afile) return retval def convert_old_style(self, conf_arr): dop = DictOp() dop.addconf("__",{}) orders = [] for cnt in range(0,20): try: try: exec("action = conf_arr['ADDRESS%d']['action']" % cnt) except: action = None exec("address = conf_arr['ADDRESS%d']['value']" % cnt) exec("netmask = conf_arr['NETMASK%d']['value']" % cnt) exec("gateway = conf_arr['GATEWAY%d']['value']" % cnt) target = "%s/%s" % (address,netmask,) net = NetworkAddress(target) try: target = net.cidr except: pass dop.add("__",[target],gateway) if action == "delete": dop.delete("__",[target]) orders.append([target]) except: pass if len(orders) != 0: dop.add("__",['@ORDERS'],orders) return dop.getconf("__") def convert_new_style(self, conf_arr): dop = DictOp() dop.addconf("__",{}) orders = [] try: old_orders = conf_arr['@ORDERS']['value'] except: old_orders = [] cnt = 0 for _k,_v in conf_arr.iteritems(): if _k[0] != "@": net = NetworkAddress(_k) try: ipaddr = net.ipaddr netmask = net.netmask gateway = _v['value'] try: action = _v['action'] except: action = None try: index = old_orders.index([_k]) except: index = cnt dop.add("__",["ADDRESS%d" % index],ipaddr) if action == "delete": dop.delete("__",["ADDRESS%d" % index]) orders.insert(cnt*3+0,["ADDRESS%d" % index]) dop.add("__",["NETMASK%d" % index],netmask) if action == "delete": dop.delete("__",["NETMASK%d" % index]) orders.insert(cnt*3+1,["NETMASK%d" % index]) dop.add("__",["GATEWAY%d" % index],gateway) if action == "delete": dop.delete("__",["GATEWAY%d" % index]) orders.insert(cnt*3+2,["GATEWAY%d" % index]) cnt = cnt + 1 except: pass if len(orders) != 0: dop.add("__",['@ORDERS'],orders) return dop.getconf("__") def read_conf(self,extra_args=None): retval = {} for _afile in self.source_file(): device_name = os.path.basename(_afile).replace(PARSER_STATICROUTE_FILE_PREFIX,"") self.parser.set_source_file([_afile]) conf_arr = self.parser.read_conf() try: # oldスタイルの配列に統一する if self.config_style == "new": arr = self.convert_old_style(conf_arr[_afile]['value']) else: arr = conf_arr[_afile]['value'] self.dop.set(self._module,[device_name],arr) except: pass self.dop.set(self._module,['@BASE_PARSER'],self.base_parser_name) #self.dop.preprint_r(self._module) return self.dop.getconf(self._module) def write_conf(self,conf_arr={},extra_args=None,dryrun=False): retval = True for device_name,_v in conf_arr.iteritems(): _afile = "%s/%s%s" % (PARSER_STATICROUTE_DIR,PARSER_STATICROUTE_FILE_PREFIX,device_name) try: _v['action'] if _v['action'] == "delete": if os.path.exists(_afile): os.unlink(_afile) #pass except: continue try: _v['value'] # newスタイルの配列に統一する if self.config_style == "new": arr = self.convert_new_style(_v['value']) else: arr = _v['value'] self.dop.addconf("parser",{}) self.dop.set("parser",[_afile],arr) #self.dop.preprint_r("parser") arr = self.dop.getconf("parser") self.parser.write_conf(arr,dryrun=dryrun) except: pass return retval def do_status(self): retval = {} command_args = [PARSER_COMMAND_ROUTE] (ret,res) = execute_command(command_args) ip_regex = "\d{1,3}(\.\d{1,3}){3}" regex = re.compile("(?P<destination>%s|default)[ \t]+(?P<gateway>%s|\*)[ \t]+(?P<netmask>%s)[ \t]+(?P<flags>[UGH]+)[ \t]+(?P<metric>\d+)[ \t]+(?P<ref>\d+)[ \t]+(?P<use>\d+)[ \t]+(?P<device>[^ ]+)" % (ip_regex,ip_regex,ip_regex,)) for _aline in res: m = regex.match(_aline) if m: device = m.group('device') destination = m.group('destination') if destination == "default": destination = "0.0.0.0" netmask = m.group('netmask') target = "%s/%s" % (destination,netmask,) net = NetworkAddress(target) target = net.cidr try: retval[device] except: retval[device] = {} retval[device][target] = {} for _atype in ["use","metric","ref","flags","gateway"]: try: exec("retval[device][target]['%s'] = m.group('%s')" % (_atype,_atype,)) except: pass return retval def do_add(self,device,target,gateway): retval = True type = "-net" try: net = NetworkAddress(target) if net.netlen == 32: type = "-host" target = net.cidr except: pass command_args = [PARSER_COMMAND_ROUTE, "add", type, target, "gw", gateway, "dev", device] (ret,res) = execute_command(command_args) if ret != 0: retval = False return retval def do_del(self,device,target): retval = True type = "-net" try: net = NetworkAddress(target) if net.netlen == 32: type = "-host" target = net.cidr except: pass command_args = [PARSER_COMMAND_ROUTE, "del", type, target, "dev", device] (ret,res) = execute_command(command_args) if ret != 0: retval = False return retval
class commentDealParser: _delim = "[ \t]+" _new_delim = " " _comment = "#" _reserved_key_prefix = "@" _module = "comment_deal_parser" _footer = "-- Generated by karesansui" def __init__(self,paths=[]): self.dop = DictOp() self.dop.addconf(self._module,{}) self.set_source_file(paths) def set_delim(self, delim=" "): self._delim = delim def set_new_delim(self, delim=" "): self._new_delim = delim def set_comment(self, comment="#"): self._comment = comment def set_reserved_key_prefix(self, prefix="@"): self._reserved_key_prefix = prefix def set_footer(self, footer=""): self._footer = footer def set_source_file(self,paths=[]): if type(paths) == str: paths = [paths] self.paths = paths return True def get_source_file(self): return self.paths def source_file(self): return self.get_source_file() def build_value(self, string, precomment=[], postcomment=None): if type(precomment) == str: precomment = [precomment] return [string, [precomment, postcomment], ] def read_conf(self): retval = {} for _afile in self.source_file(): res = ConfigFile(_afile).read() orders = [] comment_1 = [] # 設定の前のコメント リスト配列 comment_2 = None # 設定行のコメント 文字列 for _aline in res: _aline = _aline.rstrip('\r\n') if _aline.strip() == "": comment_1.append(_aline) continue if _aline.lstrip()[0:1] == self._comment: footer_regex = re.compile(self._footer) m = footer_regex.search(_aline) if not m: comment = _aline[_aline.rfind(self._comment):] comment_1.append(comment) continue regex_str = "^(?P<key>[^ \t]+)%s(?P<value>.*)$" % (self._delim,) regex = re.compile(r"%s" % regex_str) m = regex.match(_aline) if m: key = m.group('key') value = m.group('value') if not value.rfind(self._comment) == -1: comment_2 = value[value.rfind(self._comment):] value = value[:value.rfind(self._comment)] new_value = self.build_value(value,comment_1,comment_2) if new_value is not False: self.dop.set(self._module,[_afile,key],new_value) orders.append(key) comment_1 = [] comment_2 = None if len(comment_1) > 0: eof_key = "%sEOF" % (self._reserved_key_prefix,) new_value = self.build_value("",comment_1,comment_2) self.dop.set(self._module,[_afile,eof_key],new_value) orders_key = "%sORDERS" % (self._reserved_key_prefix,) self.dop.set(self._module,[_afile,orders_key],orders) #self.dop.preprint_r(self._module) return self.dop.getconf(self._module) def _value_to_lines(self,value): lines = [] for _k,_v in value.iteritems(): try: if _v['action'] == "delete": continue except: pass iscomment = False try: iscomment = _v['comment'] except: pass _prefix = "" if iscomment is True: _prefix += self._comment try: val = _v['value'][0] comment_1 = [] try: for com1_aline in _v['value'][1][0]: if com1_aline.strip() == "": pass elif com1_aline[0:1] != self._comment: com1_aline = "%s %s" % (self._comment,com1_aline,) comment_1.append(com1_aline) except: pass comment_2 = _v['value'][1][1] try: if comment_2[0:1] != self._comment: comment_2 = "%s %s" % (self._comment,comment_2,) except: pass lines = lines + comment_1 aline = "%s%s%s%s" % (_prefix,_k,self._new_delim,val,) if comment_2 is not None: aline = "%s %s" % (aline,comment_2,) lines.append(aline) except: pass return lines def write_conf(self,conf_arr={},dryrun=False): retval = True self.dop.addconf(self._module,conf_arr) orders_key = "%sORDERS" % (self._reserved_key_prefix,) eof_key = "%sEOF" % (self._reserved_key_prefix,) for _path,_v in conf_arr.iteritems(): if _path[0:1] != "/": continue lines = [] try: _v['value'] except: continue exclude_regex = "^%s[A-Z0-9\_]+$" % self._reserved_key_prefix # まずはオーダの順 if self.dop.isset(self._module,[_path,orders_key]) is True: for _k2 in self.dop.get(self._module,[_path,orders_key]): m = re.match(exclude_regex,_k2) if not m: try: if type(_k2) == list: _k2 = _k2.pop() value = {} value[_k2] = _v['value'][_k2] lines = lines + self._value_to_lines(value) self.dop.unset(self._module,[_path,_k2]) except: pass # オーダにないものは最後に追加 for _k2,_v2 in self.dop.get(self._module,[_path]).iteritems(): #if _k2 != orders_key and _k2 != eof_key: m = re.match(exclude_regex,_k2) if not m: try: value = {} value[_k2] = _v2 lines = lines + self._value_to_lines(value) except: pass # 最後のコメント用の処理 if self._footer != "": if self.dop.isset(self._module,[_path,eof_key]) is False: self.dop.cdp_set(self._module,[_path,eof_key],"",force=True) eof_val = self.dop.get(self._module,[_path,eof_key]) eof_action = self.dop.action(self._module,[_path,eof_key]) eof_comment = self.dop.comment(self._module,[_path,eof_key]) try: key = " %s - %s on %s" % (self._footer,self._module,time.strftime("%c",time.localtime())) value = {} value[key] = {} value[key]["value"] = eof_val value[key]["action"] = eof_action value[key]["comment"] = eof_comment self.set_new_delim(delim=" ") lines = lines + self._value_to_lines(value) except: pass if dryrun is False: if len(lines) > 0: ConfigFile(_path).write("\n".join(lines) + "\n") else: #pass print "\n".join(lines) return retval
def process(self): (opts, args) = getopts() chkopts(opts) self.up_progress(10) dev_list = comma_split(opts.dev) if len(dev_list) < 2: # TRANSLATORS: # bondingするためのdeviceが少ないです raise KssCommandOptException('ERROR: Small device for bonding. - dev=%s' % (opts.dev)) interface_list = get_ifconfig_info() for dev in dev_list: if dev not in interface_list: raise KssCommandOptException('ERROR: Bonding target device not found. - dev=%s' % (dev)) if opts.primary not in dev_list: raise KssCommandOptException('ERROR: Primary device not found in bonding device. - primary=%s dev=%s' % (opts.primary, opts.dev)) exist_bond_max_num = -1 exist_bond_list = get_ifconfig_info("regex:^bond") for bond_name in exist_bond_list.keys(): try: num = int(bond_name.replace("bond","")) except ValueError: continue if exist_bond_max_num < num: exist_bond_max_num = num self.up_progress(10) physical_bond_name = "bond%s" % (exist_bond_max_num + 1) bridge_bond_name = "bondbr%s" % (exist_bond_max_num + 1) bond_options = '"mode=%s primary=%s miimon=%s"' % (opts.mode, opts.primary, BONDING_CONFIG_MII_DEFAULT) self.up_progress(10) dop = DictOp() ifcfg_parser = ifcfgParser() modprobe_parser = modprobe_confParser() dop.addconf("ifcfg", ifcfg_parser.read_conf()) if dop.getconf("ifcfg") == {}: raise KssCommandException('Failure read network config file.') dop.addconf("modprobe_conf", modprobe_parser.read_conf()) if dop.getconf("modprobe_conf") == {}: raise KssCommandException('Failure read modprobe config file.') self.up_progress(10) eth_conf_copykey = ["HWADDR", "BOOTPROTO", "ONBOOT", "USERCTL", ] bond_conf_nocopykey = ["TYPE", "HWADDR", "MACADDR", "ETHTOOL_OPTS", "ESSID", "CHANNEL", ] self.up_progress(10) for dev in dev_list: conf = dop.get("ifcfg", dev) if dev == opts.primary: primary_conf = copy.deepcopy(conf) dop.unset("ifcfg", dev) dop.set("ifcfg", [dev, "DEVICE"], conf["DEVICE"]["value"]) for key in eth_conf_copykey: if key in conf: dop.set("ifcfg", [dev, key], conf[key]["value"]) dop.set("ifcfg", [dev, "MASTER"], physical_bond_name) dop.set("ifcfg", [dev, "SLAVE"], "yes") dop.set("ifcfg", [dev, "BOOTPROTO"], "none") if dop.get("ifcfg", "p%s" % (dev)): hwaddr = dop.get("ifcfg", ["p%s" % (dev), "HWADDR"]) if hwaddr: dop.set("ifcfg", [dev, "HWADDR"], hwaddr) dop.unset("ifcfg", "p%s" % (dev)) for key in bond_conf_nocopykey: if key in primary_conf: del primary_conf[key] dop.set("ifcfg", bridge_bond_name, primary_conf) dop.set("ifcfg", [bridge_bond_name, "DEVICE"], bridge_bond_name) dop.set("ifcfg", [bridge_bond_name, "TYPE"], "Bridge") dop.set("ifcfg", [physical_bond_name, "DEVICE"], physical_bond_name) dop.set("ifcfg", [physical_bond_name, "BRIDGE"], bridge_bond_name) dop.set("ifcfg", [physical_bond_name, "BOOTPROTO"], "none") dop.set("ifcfg", [physical_bond_name, "ONBOOT"], dop.get("ifcfg", [bridge_bond_name, "ONBOOT"])) dop.set("ifcfg", [physical_bond_name, "BONDING_OPTS"], bond_options) self.up_progress(10) dop.set("modprobe_conf", ["alias", physical_bond_name], "bonding") for dev in dev_list: if os.path.isfile("%s/ifcfg-%s" % (NETWORK_IFCFG_DIR, dev)): copy_file("%s/ifcfg-%s" % (NETWORK_IFCFG_DIR, dev), VENDOR_DATA_BONDING_EVACUATION_DIR) if os.path.isfile("%s/ifcfg-p%s" % (NETWORK_IFCFG_DIR, dev)): move_file("%s/ifcfg-p%s" % (NETWORK_IFCFG_DIR, dev), VENDOR_DATA_BONDING_EVACUATION_DIR) if ifcfg_parser.write_conf(dop.getconf("ifcfg")) is False: raise KssCommandException('Failure write network config file.') if modprobe_parser.write_conf(dop.getconf("modprobe_conf")) is False: raise KssCommandException('Failure write modprobe config file.') self.up_progress(10) # # Delete bridge device # bridge_list = get_bridge_info() for dev in dev_list: if dev in bridge_list: ifdown_cmd = (NETWORK_IFDOWN_COMMAND, dev, ) (ifdown_rc, ifdown_res) = execute_command(ifdown_cmd) if ifdown_rc != 0: raise KssCommandException('Failure stop interface. interface:%s' % (dev)) for brif in bridge_list[dev]: brctl_delif_cmd = (NETWORK_BRCTL_COMMAND, "delif", dev, brif, ) (brctl_rc, brctl_res) = execute_command(brctl_delif_cmd) if brctl_rc != 0: raise KssCommandException('Failure delete bridge port. bridge:%s port:%s' % (dev, brif)) brctl_delbr_cmd = (NETWORK_BRCTL_COMMAND, "delbr", dev, ) (brctl_rc, brctl_res) = execute_command(brctl_delbr_cmd) if brctl_rc != 0: raise KssCommandException('Failure delete bridge. bridge:%s' % (dev, brif)) self.up_progress(10) # # Restart network # network_restart_cmd = (NETWORK_COMMAND, "restart", ) (net_rc, net_res) = execute_command(network_restart_cmd) if net_rc != 0: raise KssCommandException('Failure restart network.') self.logger.info("Created bonding device. - dev=%s bond=%s" % (opts.dev, bridge_bond_name)) print >>sys.stdout, _("Created bonding device. - dev=%s bond=%s" % (opts.dev, bridge_bond_name)) return True
class lineParser: _comment = "" _module = "line_parser" def __init__(self,paths=[]): self.dop = DictOp() self.dop.addconf(self._module,{}) self.set_source_file(paths) def set_comment(self, comment=""): self._comment = comment def set_source_file(self,paths=[]): if type(paths) == str: paths = [paths] self.paths = paths return True def get_source_file(self): return self.paths def source_file(self): return self.get_source_file() def read_conf(self): retval = {} for _afile in self.source_file(): if _afile[0:4] == "cmd:": command_args = _afile[4:].split() (ret,res) = execute_command(command_args) else: res = ConfigFile(_afile).read() new_res = [] for _aline in res: _aline = _aline.rstrip('\r\n') if self._comment != "" and not _aline.rfind(self._comment) == -1: _aline = _aline[:_aline.rfind(self._comment)] if _aline != "": new_res.append(_aline) self.dop.set(self._module,[_afile],new_res) #self.dop.preprint_r(self._module) return self.dop.getconf(self._module) def write_conf(self,conf_arr={},dryrun=False): retval = True for _path,_v in conf_arr.iteritems(): if _path[0:1] != "/": continue try: _v['value'] except: continue if dryrun is False: ConfigFile(_path).write("\n".join(_v['value']) + "\n") else: print "\n".join(_v['value']) return retval
try: self.dop.addconf("parser",{}) self.dop.set("parser",[PARSER_HOSTS_CONF],conf_arr) #self.dop.preprint_r("parser") arr = self.dop.getconf("parser") self.parser.write_conf(arr,dryrun=dryrun) except: pass return retval """ """ if __name__ == '__main__': """Testing """ parser = hostsParser() dop = DictOp() dop.addconf("dum",parser.read_conf()) dop.add("dum",['key'],['value',[['comment foo','comment bar'],'comment hoge']]) print dop.cdp_get("dum",['key']) print dop.cdp_get_pre_comment("dum",['key']) print dop.cdp_get_post_comment("dum",['key']) print dop.cdp_set("dum",['key'],"value2") print dop.cdp_set_pre_comment("dum",['key'],["comment foo2","comment bar2","a"]) print dop.cdp_set_post_comment("dum",['key'],"comment fuga") conf = dop.getconf("dum") preprint_r(conf) parser.write_conf(conf,dryrun=True)
def process(self): (opts, args) = getopts() chkopts(opts) self.up_progress(10) original_parser = iscsidParser() new_parser = iscsidParser() dop = DictOp() dop.addconf("original", original_parser.read_conf()) dop.addconf("new", new_parser.read_conf()) self.up_progress(10) dop.cdp_set("new", ISCSI_CONFIG_KEY_AUTH_METHOD, opts.auth) if opts.auth == ISCSI_CONFIG_VALUE_AUTH_METHOD_CHAP: password = "" if opts.password is not None: password = opts.password elif opts.password_file is not None and is_readable(opts.password_file): try: fp = open(opts.password_file, "r") try: fcntl.lockf(fp.fileno(), fcntl.LOCK_SH) try: password = fp.readline().strip("\n") finally: fcntl.lockf(fp.fileno(), fcntl.LOCK_UN) self.up_progress(10) finally: fp.close() except: raise KssCommandException('Failed to read file. - target host=%s password_file=%s' \ % (opts.host,opts.password_file)) try: os.remove(opts.password_file) except: raise KssCommandException('Failed to remove file. - target host=%s password_file=%s' \ % (opts.host,opts.password_file)) dop.cdp_set("new", ISCSI_CONFIG_KEY_AUTH_METHOD, opts.auth) dop.cdp_set("new", ISCSI_CONFIG_KEY_AUTH_USER, opts.user) dop.cdp_set("new", ISCSI_CONFIG_KEY_AUTH_PASSWORD, password) else: dop.comment("new", ISCSI_CONFIG_KEY_AUTH_USER) dop.comment("new", ISCSI_CONFIG_KEY_AUTH_PASSWORD) self.up_progress(10) if opts.autostart: dop.cdp_set("new", ISCSI_CONFIG_KEY_SATRTUP, ISCSI_CONFIG_VALUE_SATRTUP_ON) else: dop.cdp_set("new", ISCSI_CONFIG_KEY_SATRTUP, ISCSI_CONFIG_VALUE_SATRTUP_OFF) new_parser.write_conf(dop.getconf("new")) self.up_progress(10) discovery_command_args = (ISCSI_CMD, ISCSI_CMD_OPTION_MODE, ISCSI_CMD_OPTION_MODE_DISCOVERY, ISCSI_CMD_OPTION_TYPE, ISCSI_CMD_OPTION_TYPE_SENDTARGETS, ISCSI_CMD_OPTION_PORTAL, opts.host ) (discovery_rc,discovery_res) = execute_command(discovery_command_args) self.up_progress(10) original_parser.write_conf(dop.getconf("original")) self.up_progress(10) if discovery_rc != 0: raise KssCommandException('Failed to add iSCSI. - host=%s message=%s' % (opts.host, discovery_res)) if discovery_res == []: raise KssCommandException('Failed to add iSCSI. - host=%s message=No exist permit iSCSI disk for target.' % (opts.host)) for node_line in discovery_res: if not node_line: continue try: node = iscsi_parse_node(node_line) except: self.logger.warn('Failed to parse iSCSI discovery command response. message="%s"' % (node_line)) continue self.logger.info("%s" % (iscsi_print_format_node(node))) print >>sys.stdout, _("%s") % (iscsi_print_format_node(node)) return True
def _read_conf(self,lines,level=0): dop = DictOp() dop.addconf("__",{}) pre_comment = [] # 設定の前のコメント リスト配列 post_comment = None # 設定行のコメント 文字列 _in_section = False _res = [] for _aline in lines: if _in_section is True: regex = "[ \t]*(?P<comment>#*)[ \t]*</(?P<key>%s)>" % _section_key #'|'.join(self.opt_sect) _regex = re.compile(r"%s" % regex) m = _regex.match(_aline) if m: _comment = m.group('comment') _key = m.group('key').strip() values = self.build_value(self._read_conf(_res,level),pre_comment,post_comment) dop.set("__",[_key,_section_val],values) if _comment != "": dop.comment("__",[_key,_section_val]) if level == 1: self.orders.append([_key,_section_val]) pre_comment = [] post_comment = None _in_section = False _res = [] level = level - 1 else: _res.append(_aline) else: _aline = _aline.rstrip('\r\n') if _aline.strip() == "": pre_comment.append(_aline) continue match = False for _type in ['uni','multi','sect']: exec("regex = '|'.join(self.opt_%s)" % _type) if _type == "sect": regex = "[ \t]*(?P<comment>#*)[ \t]*<(?P<key>%s)(?P<section>.*)>" % regex elif _type == "multi": regex = "[ \t]*(?P<comment>#*)[ \t]*(?P<key>%s)[ \t]+(?P<value>.+)" % regex elif _type == "uni": regex = "[ \t]*(?P<comment>#*)[ \t]*(?P<key>%s)[ \t]+(?P<value>.+)" % regex _regex = re.compile(r"%s" % regex) m = _regex.match(_aline) if m: match = True _comment = m.group('comment') _key = m.group('key').strip() if _type == "sect": _section_key = _key _section_val = re.sub(r"[\"']","",m.group('section').strip()) _in_section = True level = level + 1 elif _type == "multi": _value = m.group('value').strip() if _value.find(self._comment) > 0: post_comment = _value[_value.find(self._comment):] _value = re.sub("%s$" % post_comment, "", _value).rstrip() values = self.build_value(_value,pre_comment,post_comment) dop.set("__",[_key,_value],values) if _comment != "": dop.comment("__",[_key,_value]) if level == 0: self.orders.append([_key,_value]) pre_comment = [] post_comment = None elif _type == "uni": _value = m.group('value').strip() if _value.find(self._comment) > 0: post_comment = _value[_value.find(self._comment):] _value = re.sub("%s$" % post_comment, "", _value).rstrip() values = self.build_value(_value,pre_comment,post_comment) dop.set("__",[_key],values) if _comment != "": dop.comment("__",[_key]) if level == 0: self.orders.append([_key]) pre_comment = [] post_comment = None break if match is False: # ブラケットディレクティブのパラメータは除外する (よって、ブラケットディレクティブは全ての定義が必要!) # example: "<undefined_directive 'foobar'>" regex_exclude1 = "[ \t]*(?P<comment>#*)[ \t]*(?P<key>%s)[ \t]" % '|'.join(self.opt_sect) _regex_exclude1 = re.compile(r"%s" % regex_exclude1) # 未定義のパラメータの値がクオートせずにスペース区切りで3つ以上の値を指定している場合はコメント行とみなす # example: "# Read this configuration file" regex_exclude2 = "[ \t]*#+[ \t]*[^ \t]+([ \t]+[^ \t]+){3,}" _regex_exclude2 = re.compile(r"%s" % regex_exclude2) # 未定義のパラメータの値がクオートせずにスペース区切りで2つ以上の値を指定していて、かつ、最後が:で終わる場合はコメント行とみなす # example: "# Read this configuration:" regex_exclude3 = "[ \t]*#+[ \t]*[^ \t]+([ \t]+[^ \t]+){2,}:$" _regex_exclude3 = re.compile(r"%s" % regex_exclude3) # 未定義のパラメータの値が0個以上で、かつ、最後が:で終わる場合はコメント行とみなす # example: "# Read #" regex_exclude4 = "[ \t]*#+[ \t]*[^ \t]+.+[ \t]+#+$" _regex_exclude4 = re.compile(r"%s" % regex_exclude4) m1 = _regex_exclude1.match(_aline) m2 = _regex_exclude2.match(_aline) m3 = _regex_exclude3.match(_aline) m4 = _regex_exclude4.match(_aline) if not m1 and not m2 and not m3 and not m4: # opt_xxxに未定義のパラメータはuniパラメータとする regex = "[ \t]*(?P<comment>#*)[ \t]*(?P<key>[A-Z][^ \t]+)[ \t]+(?P<value>.+)" _regex = re.compile(r"%s" % regex) m = _regex.match(_aline) if m: _comment = m.group('comment') _key = m.group('key').strip() _value = m.group('value').strip() if _value.find(self._comment) > 0: post_comment = _value[_value.find(self._comment):] _value = re.sub("%s$" % post_comment, "", _value).rstrip() values = self.build_value(_value,pre_comment,post_comment) dop.set("__",[_key],values) if _comment != "": dop.comment("__",[_key]) if level == 0: self.orders.append([_key]) pre_comment = [] post_comment = None match = True if match is False: if _aline.lstrip()[0:1] == self._comment: footer_regex = re.compile(self._footer) m = footer_regex.search(_aline) if not m: comment = _aline[_aline.find(self._comment):] pre_comment.append(comment) continue if len(pre_comment) > 0: eof_key = "%sEOF" % (self._reserved_key_prefix,) new_value = self.build_value("",pre_comment,post_comment) dop.set("__",[eof_key],new_value) return dop.getconf("__")
class collectdpluginParser: _module = "collectdplugin" def __init__(self): self.dop = DictOp() self.dop.addconf(self._module, {}) self.parser = Parser() self.parser.set_delim("[ \t]+") self.parser.set_new_delim("\t") self.parser.set_comment("#") self.base_parser_name = self.parser.__class__.__name__ from karesansui.lib.parser.collectd import collectdParser collectdp = collectdParser() self.parser.set_opt_uni(collectdp.opt_uni) self.parser.set_opt_multi(collectdp.opt_multi) self.parser.set_opt_sect(collectdp.opt_sect) pass def set_footer(self, footer=""): self.parser.set_footer(footer) def source_file(self): retval = [] glob_str = "%s/*.conf" % (PARSER_COLLECTD_PLUGIN_DIR, ) for _afile in glob.glob(glob_str): retval.append(_afile) return retval def read_conf(self, extra_args=None): retval = {} for _afile in self.source_file(): plugin_name = re.sub("\.conf$", "", os.path.basename(_afile)) try: extra_args['include'] if not re.search(extra_args['include'], plugin_name): continue except: pass self.parser.set_source_file([_afile]) conf_arr = self.parser.read_conf() try: self.dop.set(self._module, [plugin_name], conf_arr[_afile]['value']) except: pass self.dop.set(self._module, ['@BASE_PARSER'], self.base_parser_name) #self.dop.preprint_r(self._module) return self.dop.getconf(self._module) def _pre_write_conf(self, conf_arr={}): # Change permission to be able to read/write data kss group. if os.path.exists(COLLECTD_DATA_DIR): if os.getuid() == 0: r_chgrp(COLLECTD_DATA_DIR, KARESANSUI_GROUP) r_chmod(COLLECTD_DATA_DIR, "g+rwx") r_chmod(COLLECTD_DATA_DIR, "o-rwx") dop = DictOp() dop.addconf("__", conf_arr) if dop.isset("__", ["python"]) is True: dop.cdp_unset("__", ["python", "Plugin", "python", "@ORDERS"], multiple_file=True) orders = [] orders.append(['Encoding']) orders.append(['LogTraces']) orders.append(['Interactive']) orders.append(['ModulePath']) orders.append(['Import']) orders.append(['Module']) dop.cdp_set("__", ["python", "Plugin", "python", "@ORDERS"], orders, is_opt_multi=True, multiple_file=True) return dop.getconf("__") def write_conf(self, conf_arr={}, extra_args=None, dryrun=False): retval = True conf_arr = self._pre_write_conf(conf_arr) for plugin_name, _v in conf_arr.iteritems(): _afile = "%s/%s.conf" % ( PARSER_COLLECTD_PLUGIN_DIR, plugin_name, ) try: _v['action'] if _v['action'] == "delete": if os.path.exists(_afile): os.unlink(_afile) continue except: pass #continue try: _v['value'] self.dop.addconf("parser", {}) self.dop.set("parser", [_afile], _v['value']) #self.dop.preprint_r("parser") arr = self.dop.getconf("parser") self.parser.write_conf(arr, dryrun=dryrun) except: pass return retval
Subject: Hello, World!! MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_0_22060966.1231404007271" ------=_Part_0_22060966.1231404007271 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit E-Mail created by Application ------=_Part_0_22060966.1231404007271 Content-Type: application/pdf; name=HelloWorld_007.pdf Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=HelloWorld_007.pdf Content-ID: Attachment JVBERi0xLjMgCiXi48/TIAo3IDAgb2JqCjw8Ci9Db250ZW50cyBbIDggMCBSIF0gCi9QYXJlbnQg ------=_Part_0_22060966.1231404007271-- """ parser = emlParser() dop = DictOp() eml = "/tmp/test2.eml" extra_args = {"message":message} extra_args = {"file":eml} extra_args = {"message":open(eml).read()} dop.addconf("dum",parser.read_conf(extra_args=extra_args)) conf = dop.getconf("dum") preprint_r(conf)
class genericConfParser: _delim = " " _new_delim = " " _comment = "#" _reserved_key_prefix = "@" _multi_param = False _module = "generic_conf_parser" def __init__(self, paths=[]): self.dop = DictOp() self.dop.addconf(self._module, {}) self.set_source_file(paths) def set_delim(self, delim=" "): self._delim = delim def set_new_delim(self, delim=" "): self._new_delim = delim def set_comment(self, comment="#"): self._comment = comment def set_reserved_key_prefix(self, prefix="@"): self._reserved_key_prefix = prefix def set_source_file(self, paths=[]): if type(paths) == str: paths = [paths] self.paths = paths return True def get_source_file(self): return self.paths def source_file(self): return self.get_source_file() def read_conf(self): retval = {} for _afile in self.source_file(): res = ConfigFile(_afile).read() regex_str = "^(?P<comment>%s)?[ \t]*(?P<key>[^%s]+)[ \t]*%s[ \t]*(?P<value>.*)$" % ( self._comment, self._delim, self._delim, ) orders = [] for _aline in res: _aline = _aline.rstrip('\r\n') regex = re.compile(r"%s" % regex_str) m = regex.match(_aline) if m: comment = m.group('comment') key = m.group('key') value = m.group('value') pieces = re.split("[ \t]*%s[ \t]*" % (self._delim), value, 1) if not value.rfind(self._comment) == -1: value = value[:value.rfind(self._comment)] if len(pieces) == 2 and pieces[1] != "": keys = [_afile, key, pieces[0]] new_value = pieces[1] else: if self._multi_param is True: keys = [_afile, key] if self.dop.isset(self._module, keys): old = self.dop.get(self._module, keys) new_value = old + [value] else: new_value = [value] else: keys = [_afile, key, pieces[0]] new_value = "" self.dop.set(self._module, keys, new_value) if not key in orders: orders.append(key) if comment is not None: self.dop.comment(self._module, keys) orders_key = "%sORDERS" % (self._reserved_key_prefix, ) self.dop.set(self._module, [_afile, orders_key], orders) #self.dop.preprint_r(self._module) return self.dop.getconf(self._module) def _value_to_lines(self, value): lines = [] for _k, _v in value.iteritems(): try: if _v['action'] == "delete": continue except: pass try: val = _v['value'] comment = False try: if _v['comment'] is True: comment = True except: pass if type(val) == list: for _val in val: aline = "%s%s%s" % ( _k, self._new_delim, _val, ) if comment is True: aline = "%s%s" % ( self._comment, aline, ) lines.append(aline) elif type(val) == dict: for _key in sorted(val.keys()): _val = val[_key] """ for _key,_val in val.iteritems(): """ try: if _val['action'] == "delete": continue except: pass _comment = False try: if _val['comment'] is True: _comment = True except: pass if _val['value'] == "": aline = "%s%s%s" % ( _k, self._new_delim, _key, ) else: aline = "%s%s%s%s%s" % ( _k, self._new_delim, _key, self._new_delim, _val['value'], ) if comment is True or _comment is True: aline = "%s%s" % ( self._comment, aline, ) lines.append(aline) else: aline = "%s%s%s" % ( _k, self._new_delim, val, ) lines.append(aline) except: pass return lines def write_conf(self, conf_arr={}, dryrun=False): retval = True self.dop.addconf(self._module, conf_arr) orders_key = "%sORDERS" % (self._reserved_key_prefix, ) for _path, _v in conf_arr.iteritems(): if _path[0:1] != "/": continue lines = [] try: _v['value'] except: continue exclude_regex = "^%s[A-Z0-9\_]+$" % self._reserved_key_prefix # まずはオーダの順 if self.dop.isset(self._module, [_path, orders_key]) is True: for _k2 in self.dop.get(self._module, [_path, orders_key]): m = re.match(exclude_regex, _k2) if not m: try: value = {} value[_k2] = _v['value'][_k2] lines = lines + self._value_to_lines(value) self.dop.unset(self._module, [_path, _k2]) except: pass # オーダにないものは最後に追加 for _k2, _v2 in self.dop.get(self._module, [_path]).iteritems(): m = re.match(exclude_regex, _k2) if not m: try: value = {} value[_k2] = _v2 lines = lines + self._value_to_lines(value) except: pass if dryrun is False: if len(lines) > 0: ConfigFile(_path).write("\n".join(lines) + "\n") if len(lines) == 0: ConfigFile(_path).write("") else: if len(lines) > 0: print "\n".join(lines) if len(lines) == 0: print "" return retval
def process(self): (opts, args) = getopts() chkopts(opts) self.up_progress(10) exist_bond_list = get_ifconfig_info("regex:^bond") if opts.dev not in exist_bond_list: raise KssCommandOptException( 'Target bonding device not found. target=%s' % opts.dev) self.up_progress(10) dop = DictOp() ifcfg_parser = ifcfgParser() dop.addconf("ifcfg", ifcfg_parser.read_conf()) if dop.getconf("ifcfg") == {}: raise KssCommandException('Failure read network config file.') if dop.get("ifcfg", opts.dev) is False: raise KssCommandException('Target device ifcfg file not found.') self.up_progress(10) restore_dev_list = [] for dev in dop.getconf("ifcfg").keys(): if dop.get("ifcfg", [dev, "MASTER"]) == opts.dev: restore_dev_list.append(dev) self.up_progress(10) if opts.succession is True: bond_bridge = dop.get("ifcfg", [opts.dev, "BRIDGE"]) bond_dev = opts.dev if bond_bridge: bond_dev = bond_bridge ipaddr = dop.get("ifcfg", [bond_dev, "IPADDR"]) netmask = dop.get("ifcfg", [bond_dev, "NETMASK"]) gateway = dop.get("ifcfg", [bond_dev, "GATEWAY"]) bonding_opts = dop.get("ifcfg", [opts.dev, "BONDING_OPTS"]) bonding_opts = bonding_opts.strip('"') primary_dev = None for combination in bonding_opts.split(" "): if re.match("primary", combination): (key, val) = combination.split("=") val = val.strip() primary_dev = val self.up_progress(10) for restore_dev in restore_dev_list: if move_file( "%s/ifcfg-%s" % (VENDOR_DATA_BONDING_EVACUATION_DIR, restore_dev), NETWORK_IFCFG_DIR) is False: raise KssCommandException('Failure restore ifcfg file.') if os.path.isfile( "%s/ifcfg-p%s" % (VENDOR_DATA_BONDING_EVACUATION_DIR, restore_dev)): if move_file( "%s/ifcfg-p%s" % (VENDOR_DATA_BONDING_EVACUATION_DIR, restore_dev), NETWORK_IFCFG_DIR) is False: raise KssCommandException('Failure restore ifcfg file.') self.up_progress(10) if opts.succession is True and primary_dev is not None: dop = DictOp() ifcfg_parser = ifcfgParser() dop.addconf("ifcfg", ifcfg_parser.read_conf()) if dop.getconf("ifcfg") == {}: raise KssCommandException('Failure read network config file.') if ipaddr: dop.set("ifcfg", [primary_dev, "IPADDR"], ipaddr) if netmask: dop.set("ifcfg", [primary_dev, "NETMASK"], netmask) if gateway: dop.set("ifcfg", [primary_dev, "GATEWAY"], gateway) if ifcfg_parser.write_conf(dop.getconf("ifcfg")) is False: raise KssCommandException('Failure write network config file.') self.up_progress(10) remove_file("%s/ifcfg-%s" % (NETWORK_IFCFG_DIR, opts.dev)) self.up_progress(10) dop = DictOp() modprobe_parser = modprobe_confParser() dop.addconf("modprobe_conf", modprobe_parser.read_conf()) if dop.getconf("modprobe_conf") == {}: raise KssCommandException('Failure read modprobe config file.') dop.unset("modprobe_conf", ["alias", opts.dev]) if modprobe_parser.write_conf(dop.getconf("modprobe_conf")) is False: raise KssCommandException('Failure write modprobe config file.') self.up_progress(10) # # Delete bridge device # bridge_list = get_bridge_info() bond_bridge = None for bridge in bridge_list: if opts.dev in bridge_list[bridge]: bond_bridge = bridge if bond_bridge: ifdown_cmd = ( NETWORK_IFDOWN_COMMAND, bond_bridge, ) (ifdown_rc, ifdown_res) = execute_command(ifdown_cmd) if ifdown_rc != 0: raise KssCommandException( 'Failure stop interface. interface:%s' % (dev)) for brif in bridge_list[bond_bridge]: brctl_delif_cmd = ( NETWORK_BRCTL_COMMAND, "delif", bond_bridge, brif, ) (brctl_rc, brctl_res) = execute_command(brctl_delif_cmd) if brctl_rc != 0: raise KssCommandException( 'Failure delete bridge port. bridge:%s port:%s' % (dev, brif)) brctl_delbr_cmd = ( NETWORK_BRCTL_COMMAND, "delbr", bond_bridge, ) (brctl_rc, brctl_res) = execute_command(brctl_delbr_cmd) if brctl_rc != 0: raise KssCommandException('Failure delete bridge. bridge:%s' % (dev, brif)) remove_file("%s/ifcfg-%s" % (NETWORK_IFCFG_DIR, bond_bridge)) # # Unload bonding module # remove_bonding_cmd = ( SYSTEM_COMMAND_REMOVE_MODULE, "bonding", ) (rmmod_rc, rmmod_res) = execute_command(remove_bonding_cmd) if rmmod_rc != 0: raise KssCommandException('Failure remove bonding module.') # # Restart network # network_restart_cmd = ( NETWORK_COMMAND, "restart", ) (net_rc, net_res) = execute_command(network_restart_cmd) if net_rc != 0: raise KssCommandException('Failure restart network.') self.logger.info("Deleted bonding device. - bond=%s dev=%s" % (opts.dev, ','.join(restore_dev_list))) print >> sys.stdout, _("Deleted bonding device. - bond=%s dev=%s" % (opts.dev, ','.join(restore_dev_list))) return True
return retval """ """ if __name__ == '__main__': """Testing """ parser = staticrouteParser() preprint_r(parser.do_status()) parser.do_add("eth0","5.6.7.0","172.16.0.1") parser.do_del("eth0","5.6.7.0") preprint_r(parser.do_status()) conf_arr = parser.read_conf() preprint_r(conf_arr) dop = DictOp() dop.addconf("parser",conf_arr) dop.add("parser",["eth1","2.3.4.5/32"],"172.16.0.10") dop.add("parser",["eth1","2.3.4.6/32"],"172.16.0.10") dop.add("parser",["eth1","2.3.4.7/32"],"172.16.0.10") #dop.insert_order("parser",["eth1","2.3.4.5/32"],0,is_parent_parser=True) #dop.insert_order("parser",["eth1","2.3.4.6/32"],0,is_parent_parser=True) dop.insert_order("parser",["eth1","2.3.4.7/32"],1,is_parent_parser=True) #dop.delete("parser",["eth1","2.3.4.5/32"]) #dop.delete("parser",["eth1","2.3.4.6/32"]) conf_arr = dop.getconf("parser") preprint_r(conf_arr) parser.write_conf(conf_arr,dryrun=True)
#self.dop.preprint_r(self._module) return self.dop.getconf(self._module) def write_conf(self,conf_arr={},extra_args=None,dryrun=False): retval = True try: self.dop.addconf("parser",{}) self.dop.set("parser",[PARSER_RESOLV_CONF],conf_arr) #self.dop.preprint_r("parser") arr = self.dop.getconf("parser") self.parser.write_conf(arr,dryrun=dryrun) except: pass return retval """ """ if __name__ == '__main__': """Testing """ parser = resolvParser() dop = DictOp() dop.addconf("dum",parser.read_conf()) dop.comment("dum","search") dop.comment("dum","nameserver") dop.add("dum","domain","example.com localdomain") conf = dop.getconf("dum") parser.write_conf(conf,dryrun=True)
def process(self): (opts, args) = getopts() chkopts(opts) self.up_progress(10) config_path = iscsi_get_config_path(opts.host, opts.iqn, opts.port, opts.tpgt) parser = iscsidParser() dop = DictOp() dop.addconf("new", parser.read_conf(config_path)) self.up_progress(10) dop.cdp_set("new", ISCSI_CONFIG_KEY_AUTH_METHOD, opts.auth) if opts.auth == ISCSI_CONFIG_VALUE_AUTH_METHOD_CHAP: password = "" if opts.password is not None: password = opts.password elif opts.password_file is not None and is_readable( opts.password_file): try: fp = open(opts.password_file, "r") try: fcntl.lockf(fp.fileno(), fcntl.LOCK_SH) try: password = fp.readline().strip("\n") finally: fcntl.lockf(fp.fileno(), fcntl.LOCK_UN) self.up_progress(10) finally: fp.close() except: raise KssCommandException('Failed to read file. - target host=%s password_file=%s' \ % (opts.host,opts.password_file)) try: os.remove(opts.password_file) except: raise KssCommandException('Failed to remove file. - target host=%s password_file=%s' \ % (opts.host,opts.password_file)) dop.cdp_set("new", ISCSI_CONFIG_KEY_AUTH_USER, opts.user) dop.cdp_set("new", ISCSI_CONFIG_KEY_AUTH_PASSWORD, password) else: dop.comment("new", ISCSI_CONFIG_KEY_AUTH_USER) dop.comment("new", ISCSI_CONFIG_KEY_AUTH_PASSWORD) self.up_progress(10) if opts.autostart: dop.cdp_set("new", ISCSI_CONFIG_KEY_SATRTUP, ISCSI_CONFIG_VALUE_SATRTUP_ON) else: dop.cdp_set("new", ISCSI_CONFIG_KEY_SATRTUP, ISCSI_CONFIG_VALUE_SATRTUP_OFF) self.up_progress(10) parser.write_conf(dop.getconf("new"), config_path) self.up_progress(30) self.logger.info("Updated iSCSI node. - host=%s iqn=%s" % (opts.host, opts.iqn)) print >> sys.stdout, _("Updated iSCSI node. - host=%s iqn=%s") % ( opts.host, opts.iqn) return True
class ifcfgParser: _module = "ifcfg" def __init__(self): self.dop = DictOp() self.dop.addconf(self._module, {}) self.parser = Parser() self.exclude_device_regex = "\.old|\.bak|\.rpm.*|lo|\.20" self.exclude_device_regex = "\.old|\.bak|\.rpm.*|\.20" self.base_parser_name = self.parser.__class__.__name__ pass def source_file(self): retval = [] glob_str = "%s/%s" % (PARSER_IFCFG_DIR, PARSER_IFCFG_FILE_PREFIX) for _afile in glob.glob("%s*" % glob_str): device_name = _afile.replace(glob_str, "") if re.search(r"%s" % self.exclude_device_regex, device_name) is None: retval.append(_afile) return retval def read_conf(self, extra_args=None): retval = {} for _afile in self.source_file(): device_name = os.path.basename(_afile).replace(PARSER_IFCFG_FILE_PREFIX, "") self.parser.set_source_file([_afile]) conf_arr = self.parser.read_conf() try: self.dop.set(self._module, [device_name], conf_arr[_afile]["value"]) except: pass self.dop.set(self._module, ["@BASE_PARSER"], self.base_parser_name) # self.dop.preprint_r(self._module) return self.dop.getconf(self._module) def write_conf(self, conf_arr={}, extra_args=None, dryrun=False): retval = True for device_name, _v in conf_arr.iteritems(): _afile = "%s/%s%s" % (PARSER_IFCFG_DIR, PARSER_IFCFG_FILE_PREFIX, device_name) try: _v["action"] if _v["action"] == "delete": if os.path.exists(_afile): os.unlink(_afile) # pass except: continue try: _v["value"] self.dop.addconf("parser", {}) self.dop.set("parser", [_afile], _v["value"]) # self.dop.preprint_r("parser") arr = self.dop.getconf("parser") self.parser.write_conf(arr, dryrun=dryrun) except: pass return retval
class iptablesParser: _module = "iptables" def __init__(self): self.dop = DictOp() self.dop.addconf(self._module, {}) self.parser = Parser() self.base_parser_name = self.parser.__class__.__name__ pass def source_file(self): retval = [PARSER_IPTABLES_CONF] return retval def read_conf(self, extra_args=None): retval = {} self.parser.set_source_file([PARSER_IPTABLES_CONF]) self.dop.addconf(self._module, {}) conf_arr = self.parser.read_conf() try: lines = conf_arr[PARSER_IPTABLES_CONF]['value'] lint = self.do_lint("\n".join(lines)) self.dop.set(self._module, ["config"], lines) self.dop.set(self._module, ["lint"], lint) except: pass cmdfile = "cmd:%s" % PARSER_COMMAND_IPTABLES_SAVE self.parser.set_source_file([cmdfile]) conf_arr = self.parser.read_conf() try: lines = conf_arr[cmdfile]['value'] self.dop.set(self._module, ["status"], lines) except: pass self.parser.set_source_file([PARSER_IPTABLES_CONF]) self.dop.set(self._module, ['@BASE_PARSER'], self.base_parser_name) #self.dop.preprint_r(self._module) return self.dop.getconf(self._module) def write_conf(self, conf_arr={}, extra_args=None, dryrun=False): retval = True now = time.strftime("%c", time.localtime()) try: self.dop.addconf("parser", {}) lines = conf_arr["config"]["value"] lines = array_replace(lines, PARSER_IPTABLES_CONF_HEADER, "# Generated by karesansui on %s" % (now, )) lines = array_replace(lines, PARSER_IPTABLES_CONF_FOOTER, "# Completed on %s" % (now, )) self.dop.set("parser", [PARSER_IPTABLES_CONF], lines) #self.dop.preprint_r("parser") arr = self.dop.getconf("parser") self.parser.write_conf(arr, dryrun=dryrun) self.do_condrestart() except: pass return retval def do_start(self): return self._do("start") def do_stop(self): return self._do("stop") def do_restart(self): return self._do("restart") def do_condrestart(self): return self._do("condrestart") def do_status(self): return self._do("status") def is_running(self): return self.do_status()[0] def _do(self, action=None): from karesansui.lib.utils import execute_command retval = False res = [] if re.match("^(%s)$" % PARSER_IPTABLES_INITRD_ACTIONS, action): command_args = [PARSER_IPTABLES_INITRD, action] (ret, res) = execute_command(command_args) if ret == 0: retval = True return [retval, res] # reverseがFalseなら設定ファイルをもとに、システムに反映(condrestart) # reverseがTrueならシステムの状態をもとに、設定ファイルに反映 def do_sync(self, reverse=False): try: self.dop.addconf("parser", self.read_conf()) if reverse is False: self.do_restart() else: lines = self.dop.get("parser", ["status"]) self.dop.set("parser", ["config"], lines) conf = self.dop.getconf("parser") self.write_conf(conf) return True except: return False def do_lint(self, string, lint=True): import signal import subprocess retval = [] if lint is True: (old_ret, old_res) = self.do_status() if old_ret is True: old_lines = [] cmdfile = "cmd:%s" % PARSER_COMMAND_IPTABLES_SAVE self.parser.set_source_file([cmdfile]) conf_arr = self.parser.read_conf() try: old_lines = conf_arr[cmdfile]['value'] except: pass self.parser.set_source_file([PARSER_IPTABLES_CONF]) signal.alarm(10) if lint is True: command_args = [PARSER_COMMAND_IPTABLES_RESTORE, "--test"] else: command_args = [PARSER_COMMAND_IPTABLES_RESTORE] proc = subprocess.Popen(command_args, bufsize=1, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) #proc.stdin.write(string) (stdout, stderr) = proc.communicate(string) ret = proc.wait() signal.alarm(0) exclude_strings = [ "Try `iptables-restore -h' or 'iptables-restore --help' for more information.", "iptables-restore v[0-9\.]+: iptables-restore:", "iptables-restore v[0-9\.]+: ", ] new_stderr = [] for _aline in re.split("[\r\n]+", stderr): new_stderr.append(_aline) new_stderr = array_replace(new_stderr, exclude_strings, ["", "", ""]) stderr = "\n".join(new_stderr) """ """ retval = [ret, stdout, stderr] if lint is True: if old_ret is True and len(old_lines) != 0: self.do_lint("\n".join(old_lines), lint=False) elif old_ret is False: self.do_stop() return retval
class shConfParser: _delim = "=" _new_delim = "=" _comment = "#" _multidefine = False _reserved_key_prefix = "@" _module = "sh_conf_parser" def __init__(self,paths=[]): self.dop = DictOp() self.dop.addconf(self._module,{}) self.set_source_file(paths) def set_delim(self, delim="="): self._delim = delim def set_new_delim(self, delim="="): self._new_delim = delim def set_comment(self, comment="#"): self._comment = comment def set_multidefine(self, multidefine=False): self._multidefine = multidefine def set_reserved_key_prefix(self, prefix="@"): self._reserved_key_prefix = prefix def set_source_file(self,paths=[]): if type(paths) == str: paths = [paths] self.paths = paths return True def get_source_file(self): return self.paths def source_file(self): return self.get_source_file() def read_conf(self): retval = {} for _afile in self.source_file(): res = ConfigFile(_afile).read() orders = [] for _aline in res: _aline = _aline.rstrip('\r\n') regex_str = "^(?P<comment>%s)?[ \t]*(?P<key>[^%s ]+)[ \t]*%s *(?P<value>.*)$" % (self._comment,self._delim,self._delim,) regex = re.compile(r"%s" % regex_str) m = regex.match(_aline) if m: comment = m.group('comment') key = m.group('key') value = m.group('value') if not value.rfind(self._comment) == -1: value = value[:value.rfind(self._comment)] if self._multidefine and self.dop.isset(self._module,[_afile,key]) is True: new_value = self.dop.get(self._module,[_afile,key]) if type(new_value) == str: new_value = [new_value] if not value in new_value: new_value.append(value) else: new_value = value self.dop.set(self._module,[_afile,key],new_value) if not key in orders: orders.append(key) if comment is not None: self.dop.comment(self._module,[_afile,key]) orders_key = "%sORDERS" % (self._reserved_key_prefix,) self.dop.set(self._module,[_afile,orders_key],orders) #self.dop.preprint_r(self._module) return self.dop.getconf(self._module) def _value_to_lines(self,value): lines = [] for _k,_v in value.iteritems(): try: if _v['action'] == "delete": continue except: pass try: val = _v['value'] comment = False try: if _v['comment'] is True: comment = True except: pass if type(val) == list: for _val in val: aline = "%s%s%s" % (_k,self._new_delim,_val,) if comment is True: aline = "%s%s" % (self._comment,aline,) lines.append(aline) else: aline = "%s%s%s" % (_k,self._new_delim,val,) lines.append(aline) except: pass return lines def write_conf(self,conf_arr={},dryrun=False): retval = True self.dop.addconf(self._module,conf_arr) orders_key = "%sORDERS" % (self._reserved_key_prefix,) for _path,_v in conf_arr.iteritems(): if _path[0:1] != "/": continue lines = [] try: _v['value'] except: continue exclude_regex = "^%s[A-Z0-9\_]+$" % self._reserved_key_prefix # まずはオーダの順 if self.dop.isset(self._module,[_path,orders_key]) is True: for _k2 in self.dop.get(self._module,[_path,orders_key]): m = re.match(exclude_regex,_k2) if not m: try: if type(_k2) == list: _k2 = _k2.pop() value = {} value[_k2] = _v['value'][_k2] lines = lines + self._value_to_lines(value) self.dop.unset(self._module,[_path,_k2]) except: pass # オーダにないものは最後に追加 for _k2,_v2 in self.dop.get(self._module,[_path]).iteritems(): m = re.match(exclude_regex,_k2) if not m: try: value = {} value[_k2] = _v2 lines = lines + self._value_to_lines(value) except: pass if dryrun is False: if len(lines) > 0: ConfigFile(_path).write("\n".join(lines) + "\n") if len(lines) == 0: ConfigFile(_path).write("") else: if len(lines) > 0: print "\n".join(lines) if len(lines) == 0: print "" return retval
class commentDealParser: _delim = "[ \t]+" _new_delim = " " _comment = "#" _reserved_key_prefix = "@" _module = "comment_deal_parser" _footer = "-- Generated by karesansui" def __init__(self, paths=[]): self.dop = DictOp() self.dop.addconf(self._module, {}) self.set_source_file(paths) def set_delim(self, delim=" "): self._delim = delim def set_new_delim(self, delim=" "): self._new_delim = delim def set_comment(self, comment="#"): self._comment = comment def set_reserved_key_prefix(self, prefix="@"): self._reserved_key_prefix = prefix def set_footer(self, footer=""): self._footer = footer def set_source_file(self, paths=[]): if type(paths) == str: paths = [paths] self.paths = paths return True def get_source_file(self): return self.paths def source_file(self): return self.get_source_file() def build_value(self, string, precomment=[], postcomment=None): if type(precomment) == str: precomment = [precomment] return [ string, [precomment, postcomment], ] def read_conf(self): retval = {} for _afile in self.source_file(): res = ConfigFile(_afile).read() orders = [] comment_1 = [] # 設定の前のコメント リスト配列 comment_2 = None # 設定行のコメント 文字列 for _aline in res: _aline = _aline.rstrip('\r\n') if _aline.strip() == "": comment_1.append(_aline) continue if _aline.lstrip()[0:1] == self._comment: footer_regex = re.compile(self._footer) m = footer_regex.search(_aline) if not m: comment = _aline[_aline.rfind(self._comment):] comment_1.append(comment) continue regex_str = "^(?P<key>[^ \t]+)%s(?P<value>.*)$" % ( self._delim, ) regex = re.compile(r"%s" % regex_str) m = regex.match(_aline) if m: key = m.group('key') value = m.group('value') if not value.rfind(self._comment) == -1: comment_2 = value[value.rfind(self._comment):] value = value[:value.rfind(self._comment)] new_value = self.build_value(value, comment_1, comment_2) if new_value is not False: self.dop.set(self._module, [_afile, key], new_value) orders.append(key) comment_1 = [] comment_2 = None if len(comment_1) > 0: eof_key = "%sEOF" % (self._reserved_key_prefix, ) new_value = self.build_value("", comment_1, comment_2) self.dop.set(self._module, [_afile, eof_key], new_value) orders_key = "%sORDERS" % (self._reserved_key_prefix, ) self.dop.set(self._module, [_afile, orders_key], orders) #self.dop.preprint_r(self._module) return self.dop.getconf(self._module) def _value_to_lines(self, value): lines = [] for _k, _v in value.iteritems(): try: if _v['action'] == "delete": continue except: pass iscomment = False try: iscomment = _v['comment'] except: pass _prefix = "" if iscomment is True: _prefix += self._comment try: val = _v['value'][0] comment_1 = [] try: for com1_aline in _v['value'][1][0]: if com1_aline.strip() == "": pass elif com1_aline[0:1] != self._comment: com1_aline = "%s %s" % ( self._comment, com1_aline, ) comment_1.append(com1_aline) except: pass comment_2 = _v['value'][1][1] try: if comment_2[0:1] != self._comment: comment_2 = "%s %s" % ( self._comment, comment_2, ) except: pass lines = lines + comment_1 aline = "%s%s%s%s" % ( _prefix, _k, self._new_delim, val, ) if comment_2 is not None: aline = "%s %s" % ( aline, comment_2, ) lines.append(aline) except: pass return lines def write_conf(self, conf_arr={}, dryrun=False): retval = True self.dop.addconf(self._module, conf_arr) orders_key = "%sORDERS" % (self._reserved_key_prefix, ) eof_key = "%sEOF" % (self._reserved_key_prefix, ) for _path, _v in conf_arr.iteritems(): if _path[0:1] != "/": continue lines = [] try: _v['value'] except: continue exclude_regex = "^%s[A-Z0-9\_]+$" % self._reserved_key_prefix # まずはオーダの順 if self.dop.isset(self._module, [_path, orders_key]) is True: for _k2 in self.dop.get(self._module, [_path, orders_key]): m = re.match(exclude_regex, _k2) if not m: try: if type(_k2) == list: _k2 = _k2.pop() value = {} value[_k2] = _v['value'][_k2] lines = lines + self._value_to_lines(value) self.dop.unset(self._module, [_path, _k2]) except: pass # オーダにないものは最後に追加 for _k2, _v2 in self.dop.get(self._module, [_path]).iteritems(): #if _k2 != orders_key and _k2 != eof_key: m = re.match(exclude_regex, _k2) if not m: try: value = {} value[_k2] = _v2 lines = lines + self._value_to_lines(value) except: pass # 最後のコメント用の処理 if self._footer != "": if self.dop.isset(self._module, [_path, eof_key]) is False: self.dop.cdp_set(self._module, [_path, eof_key], "", force=True) eof_val = self.dop.get(self._module, [_path, eof_key]) eof_action = self.dop.action(self._module, [_path, eof_key]) eof_comment = self.dop.comment(self._module, [_path, eof_key]) try: key = " %s - %s on %s" % (self._footer, self._module, time.strftime( "%c", time.localtime())) value = {} value[key] = {} value[key]["value"] = eof_val value[key]["action"] = eof_action value[key]["comment"] = eof_comment self.set_new_delim(delim=" ") lines = lines + self._value_to_lines(value) except: pass if dryrun is False: if len(lines) > 0: ConfigFile(_path).write("\n".join(lines) + "\n") else: #pass print "\n".join(lines) return retval