From 268c7741344ca69a0c4e196d3c32287dde06e24f Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Sat, 18 Jul 2009 17:23:26 +0000 Subject: Paranoid mode: Make paranoid mode more versatile/configurable This commit adds a new [paranoid] section in bcfg2.conf. This allows you to specify a backup path other than the default as well as set a maximum number of copies to keep around. You are now allowed multiple backup copies, which are marked with a timestamp. This should help to prevent accidental deletion when running in paranoid mode multiple times. The paranoid section currently looks something like this: [paranoid] path = /my/custom/backup/path max_copies = 5 Signed-off-by: Sol Jerome git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@5345 ce84e21b-d406-0410-9b95-82705330c041 --- src/lib/Client/Tools/POSIX.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'src/lib/Client/Tools/POSIX.py') diff --git a/src/lib/Client/Tools/POSIX.py b/src/lib/Client/Tools/POSIX.py index 016d8f32a..f9a36cb15 100644 --- a/src/lib/Client/Tools/POSIX.py +++ b/src/lib/Client/Tools/POSIX.py @@ -1,6 +1,7 @@ '''All POSIX Type client support for Bcfg2''' __revision__ = '$Revision$' +from datetime import datetime from stat import S_ISVTX, S_ISGID, S_ISUID, S_IXUSR, S_IWUSR, S_IRUSR, S_IXGRP from stat import S_IWGRP, S_IRGRP, S_IXOTH, S_IWOTH, S_IROTH, ST_MODE, S_ISDIR from stat import S_IFREG, ST_UID, ST_GID, S_ISREG, S_IFDIR, S_ISLNK, ST_MTIME @@ -10,9 +11,11 @@ import grp import logging import os import pwd +import shutil import string import time import Bcfg2.Client.Tools +import Bcfg2.Options def calcPerms(initial, perms): '''This compares ondisk permissions with specified ones''' @@ -83,6 +86,14 @@ class POSIX(Bcfg2.Client.Tools.Tool): 'Permissions': ['name', 'owner', 'group', 'perms'], 'SymLink': ['name', 'to']} + # grab paranoid options from /etc/bcfg2.conf + opts = {'ppath': Bcfg2.Options.PARANOID_PATH, + 'max_copies': Bcfg2.Options.PARANOID_MAX_COPIES} + setup = Bcfg2.Options.OptionParser(opts) + setup.parse([]) + ppath = setup['ppath'] + max_copies = setup['max_copies'] + def canInstall(self, entry): '''Check if entry is complete for installation''' if Bcfg2.Client.Tools.Tool.canInstall(self, entry): @@ -444,9 +455,30 @@ class POSIX(Bcfg2.Client.Tools.Tool): if entry.get("paranoid", False) and self.setup.get("paranoid", False) \ and not (entry.get('current_exists', 'true') == 'false'): bkupnam = entry.get('name').replace('/', '_') - if self.cmd.run("cp %s /var/cache/bcfg2/%s" % (entry.get('name'), bkupnam))[0]: + # current list of backups for this ConfigFile + bkuplist = [f for f in os.listdir(self.ppath) if + f.startswith(bkupnam)] + bkuplist.sort() + if len(bkuplist) == int(self.max_copies): + # remove the oldest backup available + oldest = bkuplist.pop(0) + self.logger.info("Removing %s" % oldest) + try: + os.remove("%s/%s" % (self.ppath, oldest)) + except: + self.logger.error("Failed to remove %s/%s" % \ + (self.ppath, oldest)) + return False + try: + # backup existing file + shutil.copy(entry.get('name'), + "%s/%s_%s" % (self.ppath, bkupnam, datetime.now())) + self.logger.info("Backup of %s saved to %s" % + (entry.get('name'), self.ppath)) + except IOError, e: self.logger.error("Failed to create backup file for ConfigFile %s" % \ (entry.get('name'))) + self.logger.error(e) return False try: newfile = open("%s.new"%(entry.get('name')), 'w') -- cgit v1.2.3-1-g7c22