Gentoo Archives: gentoo-commits

From: "Michał Górny" <mgorny@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage:master commit in: man/, lib/portage/, bin/, lib/portage/util/
Date: Sun, 22 Aug 2021 15:32:30
Message-Id: 1629646327.6e86186244d048e3edd5c11c18cfb4eee98a0d56.mgorny@gentoo
1 commit: 6e86186244d048e3edd5c11c18cfb4eee98a0d56
2 Author: Florian Schmaus <flo <AT> geekplace <DOT> eu>
3 AuthorDate: Sun Mar 28 12:55:04 2021 +0000
4 Commit: Michał Górny <mgorny <AT> gentoo <DOT> org>
5 CommitDate: Sun Aug 22 15:32:07 2021 +0000
6 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=6e861862
7
8 dispatch-conf: Add support for conf-update.d hook directory
9
10 Those hooks can be used by tools that manage /etc to get notified
11 about updated configuration files. For example, etckeeper could hook
12 this mechanism like the following:
13
14 /etc/portage/conf-update.d/etckeeper
15 case "${1}" in
16 pre-update)
17 etckeeper pre-install
18 ;;
19 post-update)
20 etckeeper post-install
21 ;;
22 esac
23
24 Currently conf-update.d hooks are called with 4 different events:
25 - pre-session
26 - post-session
27 - pre-update
28 - post-update
29
30 The *-session events are emitted prior starting a new configuration
31 update sesssion, and when it is finished. That is, the pre-session
32 event is emitted just before dispatch-conf displays the first
33 configuration file, and right before it exists.
34
35 The *-update events are emitted before and after a configuration file
36 has been updated. The path of the configuration file is provided as
37 second hook argument.
38
39 Signed-off-by: Florian Schmaus <flo <AT> geekplace.eu>
40 Closes: https://bugs.gentoo.org/698316
41 Bug: https://bugs.gentoo.org/260623
42 Closes: https://github.com/gentoo/portage/pull/689
43 Signed-off-by: Michał Górny <mgorny <AT> gentoo.org>
44
45 bin/dispatch-conf | 13 ++++++++++++-
46 lib/portage/dispatch_conf.py | 14 ++++++++++++++
47 lib/portage/util/hooks.py | 12 ++++++++++++
48 man/dispatch-conf.1 | 5 +++++
49 4 files changed, 43 insertions(+), 1 deletion(-)
50
51 diff --git a/bin/dispatch-conf b/bin/dispatch-conf
52 index 0fdfbaa81..f36815a52 100755
53 --- a/bin/dispatch-conf
54 +++ b/bin/dispatch-conf
55 @@ -34,7 +34,8 @@ import portage
56 portage._internal_caller = True
57 from portage import os, shutil
58 from portage import _encodings, _unicode_decode
59 -from portage.dispatch_conf import diffstatusoutput, diff_mixed_wrapper
60 +from portage.dispatch_conf import (diffstatusoutput, diff_mixed_wrapper,
61 + perform_conf_update_hooks, perform_conf_update_session_hooks)
62 from portage.process import find_binary, spawn
63 from portage.util import writemsg, writemsg_stdout
64
65 @@ -97,6 +98,8 @@ class dispatch:
66 confs = []
67 count = 0
68
69 + perform_conf_update_session_hooks("pre-session")
70 +
71 config_root = portage.settings["EPREFIX"] or os.sep
72 self.options = portage.dispatch_conf.read_config(MANDATORY_OPTS)
73
74 @@ -317,6 +320,7 @@ class dispatch:
75 break
76
77 if c == 'q':
78 + perform_conf_update_session_hooks("post-session")
79 sys.exit (0)
80 if c == 'h':
81 self.do_help ()
82 @@ -378,6 +382,8 @@ class dispatch:
83 writemsg_stdout(" * '%s'\n" % frozen, noiselevel=-1)
84 print()
85
86 + perform_conf_update_session_hooks("post-session")
87 +
88 def replace (self, newconf, curconf):
89 """Replace current config with the new/merged version. Also logs
90 the diff of what changed into the configured log file."""
91 @@ -387,11 +393,16 @@ class dispatch:
92 encoding=_encodings["stdio"]) as f:
93 f.write(output + "\n")
94
95 + perform_conf_update_hooks("pre-update", curconf)
96 +
97 try:
98 os.rename(newconf, curconf)
99 except (IOError, os.error) as why:
100 writemsg('dispatch-conf: Error renaming %s to %s: %s; fatal\n' % \
101 (newconf, curconf, str(why)), noiselevel=-1)
102 + return
103 +
104 + perform_conf_update_hooks("post-update", curconf)
105
106
107 def post_process(self, curconf):
108
109 diff --git a/lib/portage/dispatch_conf.py b/lib/portage/dispatch_conf.py
110 index 3ef659852..851e6c747 100644
111 --- a/lib/portage/dispatch_conf.py
112 +++ b/lib/portage/dispatch_conf.py
113 @@ -384,3 +384,17 @@ def file_archive_post_process(archive):
114 if os.path.isdir(dest) and not os.path.islink(dest):
115 _file_archive_rotate(dest)
116 os.rename(archive + '.dist.new', dest)
117 +
118 +
119 +def perform_conf_update_hooks(kind, conf):
120 + """Invoke the hooks in the conf-update.d directory. The notification
121 + 'kind' must either be 'pre-update' or 'post-update'. And 'conf' is the
122 + absolute path to the configuration file that is going to be or was
123 + updated."""
124 + perform_hooks("conf-update.d", kind, conf)
125 +
126 +
127 +def perform_conf_update_session_hooks(kind):
128 + """Invoke the hooks in the conf-update-session.d directory. The
129 + notification 'kind' must either be 'pre-session' or 'post-session'."""
130 + perform_hooks("conf-update.d", kind)
131
132 diff --git a/lib/portage/util/hooks.py b/lib/portage/util/hooks.py
133 index d10ec7a59..942b15543 100644
134 --- a/lib/portage/util/hooks.py
135 +++ b/lib/portage/util/hooks.py
136 @@ -12,6 +12,7 @@ from portage.output import create_color_func
137 from portage.util import writemsg_level, _recursive_file_list
138 from warnings import warn
139
140 +bad = create_color_func("BAD")
141 warn = create_color_func("WARN")
142
143
144 @@ -29,3 +30,14 @@ def get_hooks_from_dir(rel_directory, prefix="/"):
145 level=logging.WARN, noiselevel=2)
146
147 return hooks
148 +
149 +
150 +def perform_hooks(rel_directory, *argv, prefix="/"):
151 + for filepath, name in get_hooks_from_dir(rel_directory, prefix).items():
152 + hook_command = filepath + " " + " ".join(map(str, argv))
153 + retval = portage.process.spawn(hook_command)
154 +
155 + if retval != portage.os.EX_OK:
156 + writemsg_level(" %s Spawn failed for: %s, %s\n" % \
157 + (bad("*"), name, filepath),
158 + level=logging.ERROR, noiselevel=-1)
159
160 diff --git a/man/dispatch-conf.1 b/man/dispatch-conf.1
161 index a3d233bc0..b877b6942 100644
162 --- a/man/dispatch-conf.1
163 +++ b/man/dispatch-conf.1
164 @@ -70,6 +70,11 @@ older permissions of the first check in may be inherited. As
165 mentioned in the \fBci\fR(1) man page, users can control access
166 to RCS files by setting the permissions of the directory
167 containing the files.
168 +.SH "CONF-UPDATE HOOKS"
169 +\fIdispatch\-conf\fR will run hooks in \fB/etc/portage/conf-update.d\fR.
170 +The first argument of the hook is either \fIpre-session\fR, \fIpost-ression\fR,
171 +\fIpre-update\fR, or, \fIpost-update\fR. In case of *-update events, a second
172 +argument containing the path of the configuration file is also provided.
173 .SH "REPORTING BUGS"
174 Please report bugs via https://bugs.gentoo.org/
175 .SH "AUTHORS"