summaryrefslogtreecommitdiffstats
path: root/pym/portage/elog
diff options
context:
space:
mode:
authorMarius Mauch <genone@gentoo.org>2007-02-11 01:13:56 +0000
committerMarius Mauch <genone@gentoo.org>2007-02-11 01:13:56 +0000
commit54421fd308149c4b6623557f072a64131bd728ab (patch)
tree902f4eae8a0cbbc8bd7196988387332658b698e4 /pym/portage/elog
parent7b492bc9dec901aa1e94e09a8d8e1dfb0f2478f8 (diff)
downloadportage-54421fd308149c4b6623557f072a64131bd728ab.tar.gz
portage-54421fd308149c4b6623557f072a64131bd728ab.tar.bz2
portage-54421fd308149c4b6623557f072a64131bd728ab.zip
Make subpackage naming consistent
svn path=/main/trunk/; revision=5955
Diffstat (limited to 'pym/portage/elog')
-rw-r--r--pym/portage/elog/__init__.py111
-rw-r--r--pym/portage/elog/mod_custom.py16
-rw-r--r--pym/portage/elog/mod_mail.py22
-rw-r--r--pym/portage/elog/mod_mail_summary.py40
-rw-r--r--pym/portage/elog/mod_save.py21
-rw-r--r--pym/portage/elog/mod_save_summary.py23
-rw-r--r--pym/portage/elog/mod_syslog.py17
7 files changed, 250 insertions, 0 deletions
diff --git a/pym/portage/elog/__init__.py b/pym/portage/elog/__init__.py
new file mode 100644
index 000000000..5ba49793d
--- /dev/null
+++ b/pym/portage/elog/__init__.py
@@ -0,0 +1,111 @@
+from portage.const import EBUILD_PHASES
+from portage.exception import PortageException
+from portage.process import atexit_register
+from portage.util import writemsg
+
+from portage import listdir
+
+import os
+
+_elog_atexit_handlers = []
+def elog_process(cpv, mysettings):
+ mylogfiles = listdir(mysettings["T"]+"/logging/")
+ # shortcut for packages without any messages
+ if len(mylogfiles) == 0:
+ return
+ # exploit listdir() file order so we process log entries in chronological order
+ mylogfiles.reverse()
+ all_logentries = {}
+ for f in mylogfiles:
+ msgfunction, msgtype = f.split(".")
+ if msgfunction not in EBUILD_PHASES:
+ writemsg("!!! can't process invalid log file: %s\n" % f,
+ noiselevel=-1)
+ continue
+ if not msgfunction in all_logentries:
+ all_logentries[msgfunction] = []
+ msgcontent = open(mysettings["T"]+"/logging/"+f, "r").readlines()
+ all_logentries[msgfunction].append((msgtype, msgcontent))
+
+ def filter_loglevels(logentries, loglevels):
+ # remove unwanted entries from all logentries
+ rValue = {}
+ loglevels = map(str.upper, loglevels)
+ for phase in logentries.keys():
+ for msgtype, msgcontent in logentries[phase]:
+ if msgtype.upper() in loglevels or "*" in loglevels:
+ if not rValue.has_key(phase):
+ rValue[phase] = []
+ rValue[phase].append((msgtype, msgcontent))
+ return rValue
+
+ my_elog_classes = set(mysettings.get("PORTAGE_ELOG_CLASSES", "").split())
+ default_logentries = filter_loglevels(all_logentries, my_elog_classes)
+
+ # in case the filters matched all messages and no module overrides exist
+ if len(default_logentries) == 0 and (not ":" in mysettings.get("PORTAGE_ELOG_SYSTEM", "")):
+ return
+
+ def combine_logentries(logentries):
+ # generate a single string with all log messages
+ rValue = ""
+ for phase in EBUILD_PHASES:
+ if not phase in logentries:
+ continue
+ for msgtype, msgcontent in logentries[phase]:
+ rValue += "%s: %s\n" % (msgtype, phase)
+ for line in msgcontent:
+ rValue += line
+ rValue += "\n"
+ return rValue
+
+ default_fulllog = combine_logentries(default_logentries)
+
+ # pass the processing to the individual modules
+ logsystems = mysettings["PORTAGE_ELOG_SYSTEM"].split()
+ for s in logsystems:
+ # allow per module overrides of PORTAGE_ELOG_CLASSES
+ if ":" in s:
+ s, levels = s.split(":", 1)
+ levels = levels.split(",")
+ mod_logentries = filter_loglevels(all_logentries, levels)
+ mod_fulllog = combine_logentries(mod_logentries)
+ else:
+ mod_logentries = default_logentries
+ mod_fulllog = default_fulllog
+ if len(mod_logentries) == 0:
+ continue
+ # - is nicer than _ for module names, so allow people to use it.
+ s = s.replace("-", "_")
+ try:
+ # FIXME: ugly ad.hoc import code
+ # TODO: implement a common portage module loader
+ logmodule = __import__("portage.elog.mod_"+s)
+ m = getattr(logmodule, "mod_"+s)
+ def timeout_handler(signum, frame):
+ raise PortageException("Timeout in elog_process for system '%s'" % s)
+ import signal
+ signal.signal(signal.SIGALRM, timeout_handler)
+ # Timeout after one minute (in case something like the mail
+ # module gets hung).
+ signal.alarm(60)
+ try:
+ m.process(mysettings, cpv, mod_logentries, mod_fulllog)
+ finally:
+ signal.alarm(0)
+ if hasattr(m, "finalize") and not m.finalize in _elog_atexit_handlers:
+ _elog_atexit_handlers.append(m.finalize)
+ atexit_register(m.finalize, mysettings)
+ except (ImportError, AttributeError), e:
+ writemsg("!!! Error while importing logging modules " + \
+ "while loading \"mod_%s\":\n" % str(s))
+ writemsg("%s\n" % str(e), noiselevel=-1)
+ except portage.exception.PortageException, e:
+ writemsg("%s\n" % str(e), noiselevel=-1)
+
+ # clean logfiles to avoid repetitions
+ for f in mylogfiles:
+ try:
+ os.unlink(os.path.join(mysettings["T"], "logging", f))
+ except OSError:
+ pass
diff --git a/pym/portage/elog/mod_custom.py b/pym/portage/elog/mod_custom.py
new file mode 100644
index 000000000..5fae84078
--- /dev/null
+++ b/pym/portage/elog/mod_custom.py
@@ -0,0 +1,16 @@
+import portage.elog_modules.mod_save, portage.process, portage.exception
+
+def process(mysettings, cpv, logentries, fulltext):
+ elogfilename = portage.elog_modules.mod_save.process(mysettings, cpv, logentries, fulltext)
+
+ if (not "PORTAGE_ELOG_COMMAND" in mysettings.keys()) \
+ or len(mysettings["PORTAGE_ELOG_COMMAND"]) == 0:
+ raise portage.exception.MissingParameter("!!! Custom logging requested but PORTAGE_ELOG_COMMAND is not defined")
+ else:
+ mylogcmd = mysettings["PORTAGE_ELOG_COMMAND"]
+ mylogcmd = mylogcmd.replace("${LOGFILE}", elogfilename)
+ mylogcmd = mylogcmd.replace("${PACKAGE}", cpv)
+ retval = portage.process.spawn_bash(mylogcmd)
+ if retval != 0:
+ raise portage.exception.PortageException("!!! PORTAGE_ELOG_COMMAND failed with exitcode %d" % retval)
+ return
diff --git a/pym/portage/elog/mod_mail.py b/pym/portage/elog/mod_mail.py
new file mode 100644
index 000000000..b84555e8c
--- /dev/null
+++ b/pym/portage/elog/mod_mail.py
@@ -0,0 +1,22 @@
+# portage.py -- core Portage functionality
+# Copyright 1998-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+import portage.mail, socket
+
+def process(mysettings, cpv, logentries, fulltext):
+ if mysettings.has_key("PORTAGE_ELOG_MAILURI"):
+ myrecipient = mysettings["PORTAGE_ELOG_MAILURI"].split()[0]
+ else:
+ myrecipient = "root@localhost"
+
+ myfrom = mysettings["PORTAGE_ELOG_MAILFROM"]
+ mysubject = mysettings["PORTAGE_ELOG_MAILSUBJECT"]
+ mysubject = mysubject.replace("${PACKAGE}", cpv)
+ mysubject = mysubject.replace("${HOST}", socket.getfqdn())
+
+ mymessage = portage.mail.create_message(myfrom, myrecipient, mysubject, fulltext)
+ portage.mail.send_mail(mysettings, mymessage)
+
+ return
diff --git a/pym/portage/elog/mod_mail_summary.py b/pym/portage/elog/mod_mail_summary.py
new file mode 100644
index 000000000..99c285642
--- /dev/null
+++ b/pym/portage/elog/mod_mail_summary.py
@@ -0,0 +1,40 @@
+# portage.py -- core Portage functionality
+# Copyright 1998-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id: mod_mail.py 3484 2006-06-10 22:38:44Z genone $
+
+import portage.mail, socket, os, time
+from email.MIMEText import MIMEText as TextMessage
+
+_items = {}
+def process(mysettings, cpv, logentries, fulltext):
+ header = ">>> Messages generated for package %s by process %d on %s:\n\n" % \
+ (cpv, os.getpid(), time.strftime("%Y%m%d-%H%M%S", time.gmtime(time.time())))
+ _items[cpv] = header + fulltext
+
+def finalize(mysettings):
+ if len(_items) == 0:
+ return
+ elif len(_items) == 1:
+ count = "one package"
+ else:
+ count = "multiple packages"
+ if mysettings.has_key("PORTAGE_ELOG_MAILURI"):
+ myrecipient = mysettings["PORTAGE_ELOG_MAILURI"].split()[0]
+ else:
+ myrecipient = "root@localhost"
+
+ myfrom = mysettings["PORTAGE_ELOG_MAILFROM"]
+ mysubject = mysettings["PORTAGE_ELOG_MAILSUBJECT"]
+ mysubject = mysubject.replace("${PACKAGE}", count)
+ mysubject = mysubject.replace("${HOST}", socket.getfqdn())
+
+ mybody = "elog messages for the following packages generated by " + \
+ "process %d on host %s:\n" % (os.getpid(), socket.getfqdn())
+ for cpv in _items.keys():
+ mybody += "- %s\n" % cpv
+
+ mymessage = portage.mail.create_message(myfrom, myrecipient, mysubject, mybody, attachments=_items.values())
+ portage.mail.send_mail(mysettings, mymessage)
+
+ return
diff --git a/pym/portage/elog/mod_save.py b/pym/portage/elog/mod_save.py
new file mode 100644
index 000000000..2993b45db
--- /dev/null
+++ b/pym/portage/elog/mod_save.py
@@ -0,0 +1,21 @@
+import os, time
+from portage.data import portage_uid, portage_gid
+
+def process(mysettings, cpv, logentries, fulltext):
+ cpv_path = cpv.replace("/", ":")
+
+ if mysettings["PORT_LOGDIR"] != "":
+ elogdir = os.path.join(mysettings["PORT_LOGDIR"], "elog")
+ else:
+ elogdir = os.path.join(os.sep, "var", "log", "portage", "elog")
+ if not os.path.exists(elogdir):
+ os.makedirs(elogdir)
+ os.chown(elogdir, portage_uid, portage_gid)
+ os.chmod(elogdir, 02770)
+
+ elogfilename = elogdir+"/"+cpv_path+":"+time.strftime("%Y%m%d-%H%M%S", time.gmtime(time.time()))+".log"
+ elogfile = open(elogfilename, "w")
+ elogfile.write(fulltext)
+ elogfile.close()
+
+ return elogfilename
diff --git a/pym/portage/elog/mod_save_summary.py b/pym/portage/elog/mod_save_summary.py
new file mode 100644
index 000000000..eb453e587
--- /dev/null
+++ b/pym/portage/elog/mod_save_summary.py
@@ -0,0 +1,23 @@
+import os, time
+from portage.data import portage_uid, portage_gid
+
+def process(mysettings, cpv, logentries, fulltext):
+ if mysettings["PORT_LOGDIR"] != "":
+ elogdir = os.path.join(mysettings["PORT_LOGDIR"], "elog")
+ else:
+ elogdir = os.path.join(os.sep, "var", "log", "portage", "elog")
+ if not os.path.exists(elogdir):
+ os.makedirs(elogdir)
+ os.chown(elogdir, portage_uid, portage_gid)
+ os.chmod(elogdir, 02770)
+
+ # TODO: Locking
+ elogfilename = elogdir+"/summary.log"
+ elogfile = open(elogfilename, "a")
+ elogfile.write(">>> Messages generated by process %d on %s for package %s:\n\n" % \
+ (os.getpid(), time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(time.time())), cpv))
+ elogfile.write(fulltext)
+ elogfile.write("\n")
+ elogfile.close()
+
+ return elogfilename
diff --git a/pym/portage/elog/mod_syslog.py b/pym/portage/elog/mod_syslog.py
new file mode 100644
index 000000000..77e1d4ea6
--- /dev/null
+++ b/pym/portage/elog/mod_syslog.py
@@ -0,0 +1,17 @@
+import syslog
+from portage.const import EBUILD_PHASES
+
+def process(mysettings, cpv, logentries, fulltext):
+ syslog.openlog("portage", syslog.LOG_ERR | syslog.LOG_WARNING | syslog.LOG_INFO | syslog.LOG_NOTICE, syslog.LOG_LOCAL5)
+ for phase in EBUILD_PHASES:
+ if not phase in logentries:
+ continue
+ for msgtype,msgcontent in logentries[phase]:
+ pri = {"INFO": syslog.LOG_INFO,
+ "WARN": syslog.LOG_WARNING,
+ "ERROR": syslog.LOG_ERR,
+ "LOG": syslog.LOG_NOTICE,
+ "QA": syslog.LOG_WARNING}
+ msgtext = "".join(msgcontent)
+ syslog.syslog(pri[msgtype], "%s: %s: %s" % (cpv, phase, msgtext))
+ syslog.closelog()