1 # elog/mod_save_summary.py - elog dispatch module
2 # Copyright 2006-2012 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
10 from portage import _encodings
11 from portage import _unicode_decode
12 from portage import _unicode_encode
13 from portage.data import portage_gid, portage_uid
14 from portage.localization import _
15 from portage.package.ebuild.prepare_build_dirs import _ensure_log_subdirs
16 from portage.util import apply_permissions, ensure_dirs, normalize_path
18 def process(mysettings, key, logentries, fulltext):
19 if mysettings.get("PORT_LOGDIR"):
20 logdir = normalize_path(mysettings["PORT_LOGDIR"])
22 logdir = os.path.join(os.sep, mysettings["EPREFIX"].lstrip(os.sep),
23 "var", "log", "portage")
25 if not os.path.isdir(logdir):
26 # Only initialize group/mode if the directory doesn't
27 # exist, so that we don't override permissions if they
28 # were previously set by the administrator.
29 # NOTE: These permissions should be compatible with our
30 # default logrotate config as discussed in bug 374287.
32 if portage.data.secpass >= 2:
33 logdir_uid = portage_uid
34 ensure_dirs(logdir, uid=logdir_uid, gid=portage_gid, mode=0o2770)
36 elogdir = os.path.join(logdir, "elog")
37 _ensure_log_subdirs(logdir, elogdir)
40 elogfilename = elogdir+"/summary.log"
42 elogfile = io.open(_unicode_encode(elogfilename,
43 encoding=_encodings['fs'], errors='strict'),
44 mode='a', encoding=_encodings['content'],
45 errors='backslashreplace')
47 func_call = "open('%s', 'a')" % elogfilename
48 if e.errno == errno.EACCES:
49 raise portage.exception.PermissionDenied(func_call)
50 elif e.errno == errno.EPERM:
51 raise portage.exception.OperationNotPermitted(func_call)
52 elif e.errno == errno.EROFS:
53 raise portage.exception.ReadOnlyFileSystem(func_call)
57 # Copy group permission bits from parent directory.
58 elogdir_st = os.stat(elogdir)
59 elogdir_gid = elogdir_st.st_gid
60 elogdir_grp_mode = 0o060 & elogdir_st.st_mode
62 # Copy the uid from the parent directory if we have privileges
63 # to do so, for compatibility with our default logrotate
64 # config (see bug 378451). With the "su portage portage"
65 # directive and logrotate-3.8.0, logrotate's chown call during
66 # the compression phase will only succeed if the log file's uid
69 if portage.data.secpass >= 2:
70 logfile_uid = elogdir_st.st_uid
71 apply_permissions(elogfilename, uid=logfile_uid, gid=elogdir_gid,
72 mode=elogdir_grp_mode, mask=0)
74 time_str = time.strftime("%Y-%m-%d %H:%M:%S %Z",
75 time.localtime(time.time()))
76 # Avoid potential UnicodeDecodeError later.
77 time_str = _unicode_decode(time_str,
78 encoding=_encodings['content'], errors='replace')
79 elogfile.write(_unicode_decode(
80 _(">>> Messages generated by process " +
81 "%(pid)d on %(time)s for package %(pkg)s:\n\n") %
82 {"pid": os.getpid(), "time": time_str, "pkg": key}))
83 elogfile.write(_unicode_decode(fulltext))
84 elogfile.write(_unicode_decode("\n"))