Gentoo Archives: gentoo-portage-dev

From: Florian Schmaus <flo@×××××××××.eu>
To: gentoo-portage-dev@l.g.o
Cc: Florian Schmaus <flo@×××××××××.eu>
Subject: [gentoo-portage-dev] [PATCH] dispatch-conf: Add support for update-conf.d hook directory
Date: Mon, 03 Aug 2020 08:14:19
Message-Id: 20200803081400.160146-2-flo@geekplace.eu
In Reply to: [gentoo-portage-dev] RFC: conf-update.d hook dir for dispatch-conf by Florian Schmaus
1 Those hooks can be used by tools that manage /etc to get notified
2 about updated configuration files. For example, etckeeper could hook
3 this mechanism like the following:
4
5 /etc/portage/conf-update.d/etckeeper
6 case "${1}" in
7 pre-update)
8 etckeeper pre-install
9 ;;
10 post-update)
11 etckeeper post-install
12 ;;
13 esac
14
15 Signed-off-by: Florian Schmaus <flo@×××××××××.eu>
16 Closes: https://bugs.gentoo.org/698316
17 ---
18 bin/dispatch-conf | 8 +++++++-
19 lib/portage/dispatch_conf.py | 25 ++++++++++++++++++++++++-
20 2 files changed, 31 insertions(+), 2 deletions(-)
21
22 diff --git a/bin/dispatch-conf b/bin/dispatch-conf
23 index 1759b89b8..ff9698f14 100755
24 --- a/bin/dispatch-conf
25 +++ b/bin/dispatch-conf
26 @@ -29,7 +29,7 @@ import portage
27 portage._internal_caller = True
28 from portage import os, shutil
29 from portage import _encodings, _unicode_decode
30 -from portage.dispatch_conf import diffstatusoutput, diff_mixed_wrapper
31 +from portage.dispatch_conf import diffstatusoutput, diff_mixed_wrapper, perform_conf_update_hooks
32 from portage.process import find_binary, spawn
33 from portage.util import writemsg, writemsg_stdout
34
35 @@ -382,11 +382,17 @@ class dispatch:
36 encoding=_encodings["stdio"]) as f:
37 f.write(output + "\n")
38
39 + perform_conf_update_hooks("pre-update", curconf)
40 +
41 try:
42 os.rename(newconf, curconf)
43 except (IOError, os.error) as why:
44 writemsg('dispatch-conf: Error renaming %s to %s: %s; fatal\n' % \
45 (newconf, curconf, str(why)), noiselevel=-1)
46 + return
47 +
48 + perform_conf_update_hooks("post-update", curconf)
49 +
50
51
52 def post_process(self, curconf):
53 diff --git a/lib/portage/dispatch_conf.py b/lib/portage/dispatch_conf.py
54 index 71693bb36..8f40c7724 100644
55 --- a/lib/portage/dispatch_conf.py
56 +++ b/lib/portage/dispatch_conf.py
57 @@ -16,11 +16,13 @@ import subprocess
58 import sys
59 import tempfile
60
61 +from collections import OrderedDict
62 +
63 import portage
64 from portage import _encodings, os, shutil
65 from portage.env.loaders import KeyValuePairFileLoader
66 from portage.localization import _
67 -from portage.util import shlex_split, varexpand
68 +from portage.util import shlex_split, varexpand, _recursive_file_list
69 from portage.util.path import iter_parents
70
71 RCS_BRANCH = '1.1.1'
72 @@ -386,3 +388,24 @@ def file_archive_post_process(archive):
73 if os.path.isdir(dest) and not os.path.islink(dest):
74 _file_archive_rotate(dest)
75 os.rename(archive + '.dist.new', dest)
76 +
77 +def perform_conf_update_hooks(kind, conf):
78 + conf_update_dir = os.path.join(portage.settings["PORTAGE_CONFIGROOT"],
79 + portage.USER_CONFIG_PATH, "conf-update.d")
80 + hooks = OrderedDict()
81 + for filepath in _recursive_file_list(conf_update_dir):
82 + name = filepath.split(conf_update_dir)[1].lstrip(os.sep)
83 + if os.access(filepath, os.X_OK):
84 + hooks[filepath] = name
85 + else:
86 + writemsg_level(" %s %s hook: '%s' is not executable\n"
87 + % (warn("*"), _dir, _unicode_decode(name),),
88 + level=logging.WARN, noiselevel=2)
89 +
90 + for filepath in hooks:
91 + retval = portage.process.spawn([filepath, kind, conf])
92 +
93 + if retval != os.EX_OK:
94 + writemsg_level(" %s Spawn failed for: %s, %s\n" % (bad("*"),
95 + _unicode_decode(_hooks[filepath]), filepath),
96 + level=logging.ERROR, noiselevel=-1)
97 --
98 2.26.2