mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			186 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			186 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # 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 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 = file(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):
 | |
|         fp = open(self.fileName, "r")
 | |
|         newLines = []
 | |
|         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)
 | |
| 
 | |
|         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")
 | |
| 
 | |
|         fp.close()
 | |
|         
 | |
|         file(self.fileName, "w").writelines(newLines)
 | |
| 
 | |
|     def replace_line(self, startswith,stanza,always_add=False):
 | |
|         lines = [ s.strip() for s in file(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 ]
 | |
|         file(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 = file(self.fileName).read(-1) 
 | |
|         sh = re.escape(lines)
 | |
|         match = re.search(sh, fp, re.MULTILINE) 
 | |
|         if match is not None:
 | |
|             return
 | |
|     
 | |
|         fp += lines
 | |
|         file(self.fileName, "w").write(fp)
 | |
|         self.backups.append([None, lines])
 | |
|         
 | |
|     def replace_lines(self, src, dst, addToBackup=True):
 | |
|         fp = file(self.fileName).read(-1) 
 | |
|         sh = re.escape(src)
 | |
|         if dst is None:
 | |
|             dst = ""
 | |
|         repl,nums = re.subn(sh, dst, fp)
 | |
|         if nums <=0:
 | |
|             return
 | |
|         file(self.fileName, "w").write(repl)
 | |
|         if addToBackup:
 | |
|             self.backups.append([src, dst])
 | |
| 
 | |
|     def append_lines(self, match_lines, append_lines):
 | |
|         fp = file(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 file(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)
 | |
| 
 | |
|         file(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)
 | |
|             
 | |
| if __name__ == '__main__':
 | |
|     cfo = configFileOps("./sudoers")
 | |
|     #cloud ALL = NOPASSWD : ALL
 | |
|     cfo.addEntry("cloud ALL ", "NOPASSWD : ALL")
 | |
|     cfo.rmEntry("Defaults", "requiretty", " ")
 | |
|     #cfo.addEntry("zone", "test", " ")
 | |
|     cfo.save()
 |