Erste feature-komplette Alpha

This commit is contained in:
Marcus Stoegbauer 2013-01-12 23:21:20 +00:00
parent 30785db477
commit 4f082dfce9
2 changed files with 189 additions and 101 deletions

147
Tools.py Normal file
View File

@ -0,0 +1,147 @@
#!/usr/bin/env python
# encoding: utf-8
# $Id$
# $URL$
"""
Tools.py
Created by Marcus Stoegbauer on 2013-01-12.
Copyright (c) 2013 __MyCompanyName__. All rights reserved.
"""
import sys
import os
import cfgfile
import filecmp
import re
import time
import shutil
class Debug(object):
verbose = 0
def __init__(self, verbose=0):
self.setverbose(verbose)
# def __init__
def setverbose(self, verbose):
"""docstring for setverbose"""
self.verbose = verbose
# def setverbose
def debug(self, out, level=0):
"""docstring for debug"""
if self.verbose:
if level > 0:
print "*"*level,out
else:
print out
# if verbose
# def debug
# class Debug
def error(out):
"""Print error on stderr"""
print >> sys.stderr, str(out)+"\n"
# def error
def getConfig(filename):
"""reads filename as config, checks for DEST parameter and returns cfgfile object"""
try:
ret = cfgfile.Conf(filename)
except:
error("Error reading config file %s" % filename)
return False
# try
# check for DEST parameter
if not ret.check("Main", "DEST"):
error("No DEST in config file %s" % filename)
return False
# if no DEST
# replace $HOME with real home directory
if ret.get("Main", "DEST") == "$HOME":
ret.set("Main", "DEST", os.environ['HOME'])
# if $HOME
# make sure DEST ends with /
if not ret.get("Main", "DEST").endswith("/"):
ret.set("Main", "DEST", ret.get("Main", "DEST")+"/")
# if not /
return ret
# def getConfig
def diff(destfile, tempfile, commentstring, debug):
"""diff destfile and tempfile, returns True if files differ, False if they are the same"""
# FIXME: filter out comments?
debug.debug("Diffing %s and %s" % (destfile, tempfile))
if not os.path.isfile(destfile):
debug.debug("Destfile %s does not exist, returning True." % destfile)
# destfile does not exist -> copy tempfile over
return True
# if not destfile
if not os.path.isfile(tempfile):
# tempfile does not exist, this should never happen
error("Temporary file %s does not exist, this should not happen." % tempfile)
sys.exit(1)
# if not tempfile
return not filecmp.cmp(tempfile, destfile)
# def diff
def userConfigGenerated(filename, cfg):
"""returns True if filename has been generated by userconfig, False else"""
if not os.path.isfile(filename):
# filename does not exist, so it was not generated by userconfig
return False
# if not filename
if not cfg.check("Main","STAMP"):
# no STAMP in userconfig.cfg, so no way to check if file was generated by userconfig
return False
# no STAMP
fp = open(filename, "r")
for line in fp:
if re.search(re.escape(cfg.get("Main","STAMP")), line):
return True
# if search
# for line
return False
# def userConfigGenerated
def backupFile(filename, debug):
"""make backup of filename, returns True if backup is successful, False else"""
if os.path.isfile(filename):
backupname = filename+".userconfig."+time.strftime("%F")
testbackupname = backupname
counter = 0
while os.path.isfile(testbackupname):
counter+=1
testbackupname=backupname+"."+str(counter)
# while
debug.debug("Renaming %s to %s" % (filename, testbackupname))
os.rename(filename, testbackupname)
return True
# if filename
return False
# def backupFile
def copyFile(sourcefile, destfile, debug):
"""copy sourcefile to destfile, returns True if successful, False else"""
if os.path.isfile(sourcefile):
# sourcefile exists
if os.access(destfile, os.W_OK):
debug.debug("Copying %s to %s" % (sourcefile, destfile))
shutil.copy(sourcefile, destfile)
return True
# destfile is writable
# if write ok
return False
# def copyFile

View File

@ -19,66 +19,25 @@ import getopt
# #
import cfgfile import cfgfile
from checks import checks from checks import checks
import Tools
debug = Tools.Debug()
classchecks = checks() classchecks = checks()
cfg = cfgfile.Conf() cfg = cfgfile.Conf()
verbose = 0
hostclasses = classchecks.__classesForHost__() hostclasses = classchecks.__classesForHost__()
class Usage(Exception): class Usage(Exception):
def __init__(self, msg): def __init__(self, msg):
self.msg = msg self.msg = msg
# def __init__
help_message = """ help_message = """
-h help -h help
-d debug -d debug
-c userconfig.cfg config file -c userconfig.cfg config file
""" """
# class Usage
def debug(out, level=0):
"""docstring for debug"""
if verbose:
if level > 0:
print "*"*level,out
else:
print out
# if verbose
# def debug
def error(out):
"""Print error on stderr"""
print >> sys.stderr, str(out)+"\n"
# def error
def getConfig(filename):
"""reads filename as config, checks for DEST parameter and returns cfgfile object"""
try:
ret = cfgfile.Conf(filename)
except:
error("Error reading config file %s" % filename)
return False
# try
# check for DEST parameter
if not ret.check("Main", "DEST"):
error("No DEST in config file %s" % filename)
return False
# if no DEST
# replace $HOME with real home directory
if ret.get("Main", "DEST") == "$HOME":
ret.set("Main", "DEST", os.environ['HOME'])
# if $HOME
# make sure DEST ends with /
if not ret.get("Main", "DEST").endswith("/"):
ret.set("Main", "DEST", ret.get("Main", "DEST")+"/")
# if not /
return ret
# def getConfig
def workconf(directory, depth=2): def workconf(directory, depth=2):
"""walks through directory, collecting all filenames, returns list of all filenames""" """walks through directory, collecting all filenames, returns list of all filenames"""
@ -91,7 +50,7 @@ def workconf(directory, depth=2):
workconf(name, depth+1) workconf(name, depth+1)
# if dir # if dir
ret.append(name) ret.append(name)
debug("workconf: found file %s" % name, depth) debug.debug("workconf: found file %s" % name, depth)
# for d # for d
return ret return ret
# def workconf # def workconf
@ -101,19 +60,19 @@ def workdir(directory):
then collect all filenames within this directory and return a dict of all files for this then collect all filenames within this directory and return a dict of all files for this
directory directory
""" """
debug("===============================", 1) debug.debug("===============================", 1)
# skip directory if no CONFIGFILE present # skip directory if no CONFIGFILE present
if not os.path.isfile(directory+"/"+cfg.get("Main", "CONFIGFILE")): if not os.path.isfile(directory+"/"+cfg.get("Main", "CONFIGFILE")):
debug("No %s in %s, skipping." % (cfg.get("Main", "CONFIGFILE"), directory), 1) debug.debug("No %s in %s, skipping." % (cfg.get("Main", "CONFIGFILE"), directory), 1)
return {} return ({},{})
# if not DEST # if not DEST
# get config file for directory # get config file for directory
dirConfig = getConfig(directory+"/"+cfg.get("Main", "CONFIGFILE")) dirConfig = Tools.getConfig(directory+"/"+cfg.get("Main", "CONFIGFILE"))
if not dirConfig: if not dirConfig:
debug("Cannot read %s in %s, skipping." % (cfg.get("Main", "CONFIGFILE"), directory), 1) debug.debug("Cannot read %s in %s, skipping." % (cfg.get("Main", "CONFIGFILE"), directory), 1)
return {} return ({},{})
# if not dirConfig # if not dirConfig
destdir = dirConfig.get("Main","DEST") destdir = dirConfig.get("Main","DEST")
@ -133,7 +92,7 @@ def workdir(directory):
# if class directory exists # if class directory exists
if os.path.isdir(classdir): if os.path.isdir(classdir):
debug("workdir: %s" % classdir, 1) debug.debug("workdir: %s" % classdir, 1)
# get list of files within this class directory # get list of files within this class directory
tempfiles = workconf(classdir) tempfiles = workconf(classdir)
@ -148,9 +107,9 @@ def workdir(directory):
# if classdir # if classdir
# for hostclasses # for hostclasses
debug("workdir: %s, Files: %s" % (directory, str(destfiles))) debug.debug("workdir: %s, Files: %s" % (directory, str(destfiles)))
debug("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^", 1) debug.debug("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^", 1)
return destfiles return (destfiles, dirConfig)
# def work # def work
def buildFile(classfiles, destfile): def buildFile(classfiles, destfile):
@ -175,7 +134,7 @@ def buildFile(classfiles, destfile):
try: try:
fp = os.fdopen(tempfd, "w") fp = os.fdopen(tempfd, "w")
except: except:
error("Cannot write to temporary file %s" % tempfilename) Tools.error("Cannot write to temporary file %s" % tempfilename)
os.remove(tempfilename) os.remove(tempfilename)
return False return False
# try # try
@ -189,52 +148,34 @@ def buildFile(classfiles, destfile):
return tempfilename return tempfilename
# def buildFile # def buildFile
def diff(fileA, fileB): def processAllFiles(destfiles, dirConfig):
"""diff fileA and fileB, returns True if files differ, False if they are the same"""
# FIXME: write
# FIXME: filter out comments?
# FIXME: COMMENTSTRING in config?
return False
# def diff
def userConfigGenerated(filename):
"""returns True if filename has been generated by userconfig, False else"""
# FIXME: write
return True
# def userConfigGenerated
def backupFile(filename):
"""make backup of filename, returns True if backup is successful, False else"""
# FIXME: write
return True
# def backupFile
def copyFile(sourcefile, destfile):
"""copy sourcefile to destfile, returns True if successful, False else"""
return True
# def copyFile
def processAllFiles(destfiles):
"""processes all files in destfiles, generate files from classes, compare and copy if necessary""" """processes all files in destfiles, generate files from classes, compare and copy if necessary"""
for df in destfiles.keys(): for df in destfiles.keys():
# assemble file to tmp # assemble file to tmp
tempfilename = buildFile(destfiles[df], df) tempfilename = buildFile(destfiles[df], df)
if not tempfilename: if not tempfilename:
debug("Error while creating temp file for %s, skipping." % df) debug.debug("Error while creating temp file for %s, skipping." % df)
continue continue
# if not tempfilename # if not tempfilename
commentstring = ""
if dirConfig.check("Main", "COMMENSTRING"):
commentstring = dirConfig.get("Main", "COMMENTSTRING")
# if COMMENTSTRNIG
# diff assembled file and config file # diff assembled file and config file
if diff(df, tempfilename): if Tools.diff(df, tempfilename, commentstring, debug):
if not userConfigGenerated(df): debug.debug("%s changed." % df)
if not Tools.userConfigGenerated(df, cfg):
debug.debug("%s not generated by userconfig, backing up." % df)
# file not generated from userconfig -> back up # file not generated from userconfig -> back up
backupFile(df) Tools.backupFile(df, debug)
# if not userConfigGenerated # if not userConfigGenerated
# copy tmp file to real location # copy tmp file to real location
copyFile(tempfilename, df) Tools.copyFile(tempfilename, df, debug)
# if diff
# remove tmp # remove tmp
os.remove(tempfilename) os.remove(tempfilename)
# if diff
# for df # for df
# def buildAllFiles # def buildAllFiles
@ -251,28 +192,28 @@ def main():
for option, value in opts: for option, value in opts:
if option == "-v": if option == "-v":
verbose = 1 debug.setverbose(1)
if option in ("-h", "--help"): if option in ("-h", "--help"):
raise Usage(help_message) raise Usage(help_message)
if option in ("-d", "--debug"): if option in ("-d", "--debug.debug"):
pass pass
if option in ("-c", "--config"): if option in ("-c", "--config"):
configfile = value configfile = value
# if # if
# for option, value # for option, value
except Usage, err: except Usage, err:
error(sys.argv[0].split("/")[-1] + ": " + str(err.msg)) Tools.error(sys.argv[0].split("/")[-1] + ": " + str(err.msg))
error("\t for help use --help") Tools.error("\t for help use --help")
return 2 return 2
# try # try
if configfile == "": if configfile == "":
error( "No config file specified.") Tools.error( "No config file specified.")
return 2 return 2
# if configfile # if configfile
cfg.setfilename(configfile) cfg.setfilename(configfile)
debug("Classes for host: %s" % hostclasses) debug.debug("Classes for host: %s" % hostclasses)
configdir = cfg.get("Main", "CONFIGDIR") configdir = cfg.get("Main", "CONFIGDIR")
for d in os.listdir(configdir): for d in os.listdir(configdir):
name = configdir+d name = configdir+d
@ -283,9 +224,9 @@ def main():
elif os.path.isfile(name+"/.ignore"): elif os.path.isfile(name+"/.ignore"):
continue continue
else: else:
debug("main: %s" % name) debug.debug("main: %s" % name)
destfiles = workdir(name) (destfiles, dirConfig) = workdir(name)
processAllFiles(destfiles) processAllFiles(destfiles, dirConfig)
# if # if
# for d # for d
# def main # def main