c69f4a3cfc0812b56ff426bc1ad1710c848d6b56
[portage.git] / pym / portage / elog / mod_save.py
1 # elog/mod_save.py - elog dispatch module
2 # Copyright 2006-2011 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4
5 import io
6 import time
7 import portage
8 from portage import os
9 from portage import _encodings
10 from portage import _unicode_decode
11 from portage import _unicode_encode
12 from portage.data import portage_gid, portage_uid
13 from portage.package.ebuild.prepare_build_dirs import _ensure_log_subdirs
14 from portage.util import apply_permissions, ensure_dirs, normalize_path
15
16 def process(mysettings, key, logentries, fulltext):
17
18         if mysettings.get("PORT_LOGDIR"):
19                 logdir = normalize_path(mysettings["PORT_LOGDIR"])
20         else:
21                 logdir = os.path.join(os.sep, mysettings["EPREFIX"].lstrip(os.sep),
22                         "var", "log", "portage")
23
24         if not os.path.isdir(logdir):
25                 # Only initialize group/mode if the directory doesn't
26                 # exist, so that we don't override permissions if they
27                 # were previously set by the administrator.
28                 # NOTE: These permissions should be compatible with our
29                 # default logrotate config as discussed in bug 374287.
30                 uid = -1
31                 if portage.data.secpass >= 2:
32                         uid = portage_uid
33                 ensure_dirs(logdir, uid=uid, gid=portage_gid, mode=0o2770)
34
35         cat = mysettings['CATEGORY']
36         pf = mysettings['PF']
37
38         elogfilename = pf + ":" + _unicode_decode(
39                 time.strftime("%Y%m%d-%H%M%S", time.gmtime(time.time())),
40                 encoding=_encodings['content'], errors='replace') + ".log"
41
42         if "split-elog" in mysettings.features:
43                 log_subdir = os.path.join(logdir, "elog", cat)
44                 elogfilename = os.path.join(log_subdir, elogfilename)
45         else:
46                 log_subdir = os.path.join(logdir, "elog")
47                 elogfilename = os.path.join(log_subdir, cat + ':' + elogfilename)
48         _ensure_log_subdirs(logdir, log_subdir)
49
50         elogfile = io.open(_unicode_encode(elogfilename,
51                 encoding=_encodings['fs'], errors='strict'),
52                 mode='w', encoding=_encodings['content'], errors='backslashreplace')
53         elogfile.write(_unicode_decode(fulltext))
54         elogfile.close()
55
56         # Copy group permission bits from parent directory.
57         elogdir_st = os.stat(log_subdir)
58         elogdir_gid = elogdir_st.st_gid
59         elogdir_grp_mode = 0o060 & elogdir_st.st_mode
60
61         # Copy the uid from the parent directory if we have privileges
62         # to do so, for compatibility with our default logrotate
63         # config (see bug 378451). With the "su portage portage"
64         # directive and logrotate-3.8.0, logrotate's chown call during
65         # the compression phase will only succeed if the log file's uid
66         # is portage_uid.
67         logfile_uid = -1
68         if portage.data.secpass >= 2:
69                 logfile_uid = elogdir_st.st_uid
70         apply_permissions(elogfilename, uid=logfile_uid, gid=elogdir_gid,
71                 mode=elogdir_grp_mode, mask=0)
72
73         return elogfilename