python/lib/cloudutils/configFileOps.py (142 lines of code) (raw):

# Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. import re import os import tempfile import shutil from .utilities import bash class configFileOps: class entry: def __init__(self, name, value, op, separator): self.name = name self.value = value self.state = "new" self.op = op self.separator = separator def setState(self, state): self.state = state def getState(self): return self.state def __init__(self, fileName, cfg=None): self.fileName = fileName self.entries = [] self.backups = [] if cfg is not None: cfg.cfoHandlers.append(self) def addEntry(self, name, value, separator="="): e = self.entry(name, value, "add", separator) self.entries.append(e) def rmEntry(self, name, value, separator="="): entry = self.entry(name, value, "rm", separator) self.entries.append(entry) def getEntry(self, name, separator="="): try: ctx = open(self.fileName).read(-1) match = re.search("^" + name + ".*", ctx, re.MULTILINE) if match is None: return "" line = match.group(0).split(separator, 1) return line[1] except: return "" def save(self): newLines = [] if os.path.exists(self.fileName) and os.path.isfile(self.fileName): fp = open(self.fileName, "r") for line in fp.readlines(): matched = False for entry in self.entries: if entry.op == "add": if entry.separator == "=": matchString = "^\ *" + entry.name + ".*" elif entry.separator == " ": matchString = "^\ *" + entry.name + "\ *" + entry.value else: if entry.separator == "=": matchString = "^\ *" + entry.name + "\ *=\ *" + entry.value else: matchString = "^\ *" + entry.name + "\ *" + entry.value match = re.match(matchString, line) if match is not None: if entry.op == "add" and entry.separator == "=": newline = "\n" + entry.name + "=" + entry.value + "\n" entry.setState("set") newLines.append(newline) self.backups.append([line, newline]) matched = True break elif entry.op == "rm": entry.setState("set") self.backups.append([line, None]) matched = True break if not matched: newLines.append(line) fp.close() for entry in self.entries: if entry.getState() != "set": if entry.op == "add": newline = entry.name + entry.separator + entry.value + "\n" newLines.append(newline) self.backups.append([None, newline]) entry.setState("set") open(self.fileName, "w").writelines(newLines) def replace_line(self, startswith,stanza,always_add=False): lines = [ s.strip() for s in open(self.fileName).readlines() ] newlines = [] replaced = False for line in lines: if re.search(startswith, line): if stanza is not None: newlines.append(stanza) self.backups.append([line, stanza]) replaced = True else: newlines.append(line) if not replaced and always_add: newlines.append(stanza) self.backups.append([None, stanza]) newlines = [ s + '\n' for s in newlines ] open(self.fileName,"w").writelines(newlines) def replace_or_add_line(self, startswith,stanza): return self.replace_line(startswith,stanza,always_add=True) def add_lines(self, lines, addToBackup=True): fp = open(self.fileName).read(-1) sh = re.escape(lines) match = re.search(sh, fp, re.MULTILINE) if match is not None: return fp += lines open(self.fileName, "w").write(fp) self.backups.append([None, lines]) def replace_lines(self, src, dst, addToBackup=True): fp = open(self.fileName).read(-1) sh = re.escape(src) if dst is None: dst = "" repl,nums = re.subn(sh, dst, fp) if nums <=0: return open(self.fileName, "w").write(repl) if addToBackup: self.backups.append([src, dst]) def append_lines(self, match_lines, append_lines): fp = open(self.fileName).read(-1) sh = re.escape(match_lines) match = re.search(sh, fp, re.MULTILINE) if match is None: return sh = re.escape(append_lines) if re.search(sh, fp, re.MULTILINE) is not None: return newlines = [] for line in open(self.fileName).readlines(): if re.search(match_lines, line) is not None: newlines.append(line + append_lines) self.backups.append([line, line + append_lines]) else: newlines.append(line) open(self.fileName, "w").writelines(newlines) def backup(self): for oldLine, newLine in self.backups: if newLine is None: self.add_lines(oldLine, False) else: self.replace_lines(newLine, oldLine, False)