summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'pym/dispatch_conf.py')
-rw-r--r--pym/dispatch_conf.py162
1 files changed, 162 insertions, 0 deletions
diff --git a/pym/dispatch_conf.py b/pym/dispatch_conf.py
new file mode 100644
index 00000000..27d73712
--- /dev/null
+++ b/pym/dispatch_conf.py
@@ -0,0 +1,162 @@
+# archive_conf.py -- functionality common to archive-conf and dispatch-conf
+# Copyright 2003-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/pym/dispatch_conf.py,v 1.3.2.3 2005/04/29 03:37:30 jstubbs Exp $
+cvs_id_string="$Id: dispatch_conf.py,v 1.3.2.3 2005/04/29 03:37:30 jstubbs Exp $"[5:-2]
+
+# Library by Wayne Davison <gentoo@blorf.net>, derived from code
+# written by Jeremy Wohl (http://igmus.org)
+
+from stat import *
+import os, sys, commands, shutil
+
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+import portage
+
+RCS_BRANCH = '1.1.1'
+RCS_LOCK = 'rcs -ko -M -l'
+RCS_PUT = 'ci -t-"Archived config file." -m"dispatch-conf update."'
+RCS_GET = 'co'
+RCS_MERGE = 'rcsmerge -p -r' + RCS_BRANCH + ' %s >%s'
+
+DIFF3_MERGE = 'diff3 -mE %s %s %s >%s'
+
+def read_config(mandatory_opts):
+ try:
+ opts = portage.getconfig('/etc/dispatch-conf.conf')
+ except:
+ opts = None
+
+ if not opts:
+ print >> sys.stderr, 'dispatch-conf: Error reading /etc/dispatch-conf.conf; fatal'
+ sys.exit(1)
+
+ for key in mandatory_opts:
+ if not opts.has_key(key):
+ if key == "merge":
+ opts["merge"] = "sdiff --suppress-common-lines --output=%s %s %s"
+ else:
+ print >> sys.stderr, 'dispatch-conf: Missing option "%s" in /etc/dispatch-conf.conf; fatal' % (key,)
+
+ if not os.path.exists(opts['archive-dir']):
+ os.mkdir(opts['archive-dir'])
+ elif not os.path.isdir(opts['archive-dir']):
+ print >> sys.stderr, 'dispatch-conf: Config archive dir [%s] must exist; fatal' % (opts['archive-dir'],)
+ sys.exit(1)
+
+ return opts
+
+
+def rcs_archive(archive, curconf, newconf, mrgconf):
+ """Archive existing config in rcs (on trunk). Then, if mrgconf is
+ specified and an old branch version exists, merge the user's changes
+ and the distributed changes and put the result into mrgconf. Lastly,
+ if newconf was specified, leave it in the archive dir with a .dist.new
+ suffix along with the last 1.1.1 branch version with a .dist suffix."""
+
+ try:
+ os.makedirs(os.path.dirname(archive))
+ except:
+ pass
+
+ try:
+ shutil.copy2(curconf, archive)
+ except(IOError, os.error), why:
+ print >> sys.stderr, 'dispatch-conf: Error copying %s to %s: %s; fatal' % \
+ (curconf, archive, str(why))
+ if os.path.exists(archive + ',v'):
+ os.system(RCS_LOCK + ' ' + archive)
+ os.system(RCS_PUT + ' ' + archive)
+
+ ret = 0
+ if newconf != '':
+ os.system(RCS_GET + ' -r' + RCS_BRANCH + ' ' + archive)
+ has_branch = os.path.exists(archive)
+ if has_branch:
+ os.rename(archive, archive + '.dist')
+
+ try:
+ shutil.copy2(newconf, archive)
+ except(IOError, os.error), why:
+ print >> sys.stderr, 'dispatch-conf: Error copying %s to %s: %s; fatal' % \
+ (newconf, archive, str(why))
+
+ if has_branch:
+ if mrgconf != '':
+ # This puts the results of the merge into mrgconf.
+ ret = os.system(RCS_MERGE % (archive, mrgconf))
+ mystat = os.lstat(newconf)
+ os.chmod(mrgconf, mystat[ST_MODE])
+ os.chown(mrgconf, mystat[ST_UID], mystat[ST_GID])
+ os.rename(archive, archive + '.dist.new')
+ return ret
+
+
+def file_archive(archive, curconf, newconf, mrgconf):
+ """Archive existing config to the archive-dir, bumping old versions
+ out of the way into .# versions (log-rotate style). Then, if mrgconf
+ was specified and there is a .dist version, merge the user's changes
+ and the distributed changes and put the result into mrgconf. Lastly,
+ if newconf was specified, archive it as a .dist.new version (which
+ gets moved to the .dist version at the end of the processing)."""
+
+ try:
+ os.makedirs(os.path.dirname(archive))
+ except:
+ pass
+
+ # Archive the current config file if it isn't already saved
+ if os.path.exists(archive) \
+ and len(commands.getoutput('diff -aq %s %s' % (curconf,archive))) != 0:
+ suf = 1
+ while suf < 9 and os.path.exists(archive + '.' + str(suf)):
+ suf += 1
+
+ while suf > 1:
+ os.rename(archive + '.' + str(suf-1), archive + '.' + str(suf))
+ suf -= 1
+
+ os.rename(archive, archive + '.1')
+
+ try:
+ shutil.copy2(curconf, archive)
+ except(IOError, os.error), why:
+ print >> sys.stderr, 'dispatch-conf: Error copying %s to %s: %s; fatal' % \
+ (curconf, archive, str(why))
+
+ if newconf != '':
+ # Save off new config file in the archive dir with .dist.new suffix
+ try:
+ shutil.copy2(newconf, archive + '.dist.new')
+ except(IOError, os.error), why:
+ print >> sys.stderr, 'dispatch-conf: Error copying %s to %s: %s; fatal' % \
+ (newconf, archive + '.dist.new', str(why))
+
+ ret = 0
+ if mrgconf != '' and os.path.exists(archive + '.dist'):
+ # This puts the results of the merge into mrgconf.
+ ret = os.system(DIFF3_MERGE % (curconf, archive + '.dist', newconf, mrgconf))
+ mystat = os.lstat(newconf)
+ os.chmod(mrgconf, mystat[ST_MODE])
+ os.chown(mrgconf, mystat[ST_UID], mystat[ST_GID])
+
+ return ret
+
+
+def rcs_archive_post_process(archive):
+ """Check in the archive file with the .dist.new suffix on the branch
+ and remove the one with the .dist suffix."""
+ os.rename(archive + '.dist.new', archive)
+ if os.path.exists(archive + '.dist'):
+ # Commit the last-distributed version onto the branch.
+ os.system(RCS_LOCK + RCS_BRANCH + ' ' + archive)
+ os.system(RCS_PUT + ' -r' + RCS_BRANCH + ' ' + archive)
+ os.unlink(archive + '.dist')
+ else:
+ # Forcefully commit the last-distributed version onto the branch.
+ os.system(RCS_PUT + ' -f -r' + RCS_BRANCH + ' ' + archive)
+
+
+def file_archive_post_process(archive):
+ """Rename the archive file with the .dist.new suffix to a .dist suffix"""
+ os.rename(archive + '.dist.new', archive + '.dist')