1 |
If a CONFIG_PROTECTed file was installed but no longer exists in the |
2 |
file system, then it may have been deleted or renamed by the admin. |
3 |
Therefore, force the file to be merged with a ._cfg name, so that the |
4 |
admin will be prompted for this update. |
5 |
|
6 |
X-Gentoo-Bug: 523684 |
7 |
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=523684 |
8 |
--- |
9 |
pym/portage/dbapi/vartree.py | 32 ++++++++++++++++++++++++-------- |
10 |
pym/portage/tests/emerge/test_simple.py | 19 +++++++++++++++++-- |
11 |
2 files changed, 41 insertions(+), 10 deletions(-) |
12 |
|
13 |
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py |
14 |
index b46ba0b..11384bf 100644 |
15 |
--- a/pym/portage/dbapi/vartree.py |
16 |
+++ b/pym/portage/dbapi/vartree.py |
17 |
@@ -4687,10 +4687,7 @@ class dblink(object): |
18 |
zing = "!!!" |
19 |
mymtime = None |
20 |
protected = self.isprotected(mydest) |
21 |
- if mydmode != None: |
22 |
- # destination file exists |
23 |
- |
24 |
- if stat.S_ISDIR(mydmode): |
25 |
+ if mydmode is not None and stat.S_ISDIR(mydmode): |
26 |
# install of destination is blocked by an existing directory with the same name |
27 |
newdest = self._new_backup_path(mydest) |
28 |
msg = [] |
29 |
@@ -4703,12 +4700,15 @@ class dblink(object): |
30 |
self._eerror("preinst", msg) |
31 |
mydest = newdest |
32 |
|
33 |
- elif stat.S_ISREG(mydmode) or (stat.S_ISLNK(mydmode) and os.path.exists(mydest) and stat.S_ISREG(os.stat(mydest)[stat.ST_MODE])): |
34 |
+ elif mydmode is None or stat.S_ISREG(mydmode) or \ |
35 |
+ (stat.S_ISLNK(mydmode) and os.path.exists(mydest) |
36 |
+ and stat.S_ISREG(os.stat(mydest)[stat.ST_MODE])): |
37 |
# install of destination is blocked by an existing regular file, |
38 |
# or by a symlink to an existing regular file; |
39 |
# now, config file management may come into play. |
40 |
# we only need to tweak mydest if cfg file management is in play. |
41 |
- if protected: |
42 |
+ destmd5 = None |
43 |
+ if protected and mydmode is not None: |
44 |
destmd5 = perform_md5(mydest, calc_prelink=calc_prelink) |
45 |
if protect_if_modified: |
46 |
contents_key = \ |
47 |
@@ -4721,7 +4721,21 @@ class dblink(object): |
48 |
if protected: |
49 |
# we have a protection path; enable config file management. |
50 |
cfgprot = 0 |
51 |
- if mymd5 == destmd5: |
52 |
+ cfgprot_force = False |
53 |
+ if mydmode is None: |
54 |
+ if self._installed_instance is not None and \ |
55 |
+ self._installed_instance._match_contents( |
56 |
+ myrealdest) is not False: |
57 |
+ # If the file doesn't exist, then it may |
58 |
+ # have been deleted or renamed by the |
59 |
+ # admin. Therefore, force the file to be |
60 |
+ # merged with a ._cfg name, so that the |
61 |
+ # admin will be prompted for this update |
62 |
+ # (see bug #523684). |
63 |
+ cfgprot_force = True |
64 |
+ moveme = True |
65 |
+ cfgprot = True |
66 |
+ elif mymd5 == destmd5: |
67 |
#file already in place; simply update mtimes of destination |
68 |
moveme = 1 |
69 |
else: |
70 |
@@ -4749,7 +4763,9 @@ class dblink(object): |
71 |
del cfgfiledict[myrealdest] |
72 |
|
73 |
if cfgprot: |
74 |
- mydest = new_protect_filename(mydest, newmd5=mymd5) |
75 |
+ mydest = new_protect_filename(mydest, |
76 |
+ newmd5=mymd5, |
77 |
+ force=cfgprot_force) |
78 |
|
79 |
# whether config protection or not, we merge the new file the |
80 |
# same way. Unless moveme=0 (blocking directory) |
81 |
diff --git a/pym/portage/tests/emerge/test_simple.py b/pym/portage/tests/emerge/test_simple.py |
82 |
index 0bb83ae..6fc81ab 100644 |
83 |
--- a/pym/portage/tests/emerge/test_simple.py |
84 |
+++ b/pym/portage/tests/emerge/test_simple.py |
85 |
@@ -12,7 +12,8 @@ from portage.const import (BASH_BINARY, PORTAGE_BASE_PATH, |
86 |
from portage.process import find_binary |
87 |
from portage.tests import TestCase |
88 |
from portage.tests.resolver.ResolverPlayground import ResolverPlayground |
89 |
-from portage.util import ensure_dirs |
90 |
+from portage.util import (ensure_dirs, find_updated_config_files, |
91 |
+ shlex_split) |
92 |
|
93 |
class SimpleEmergeTestCase(TestCase): |
94 |
|
95 |
@@ -42,6 +43,10 @@ src_install() { |
96 |
doins "${T}"/regular-file |
97 |
dosym regular-file /usr/lib/${P}/symlink || die |
98 |
|
99 |
+ # Test CONFIG_PROTECT |
100 |
+ insinto /etc |
101 |
+ newins "${T}"/regular-file ${PN}-${SLOT%/*} |
102 |
+ |
103 |
# Test code for bug #381629, using a copyright symbol encoded with latin-1. |
104 |
# We use $(printf "\\xa9") rather than $'\\xa9', since printf apparently |
105 |
# works in any case, while $'\\xa9' transforms to \\xef\\xbf\\xbd under |
106 |
@@ -267,8 +272,18 @@ pkg_preinst() { |
107 |
emerge_cmd + ("--pretend", "--depclean", "--verbose", "dev-libs/B"), |
108 |
emerge_cmd + ("--pretend", "--depclean",), |
109 |
emerge_cmd + ("--depclean",), |
110 |
- quickpkg_cmd + ("dev-libs/A",), |
111 |
+ quickpkg_cmd + ("--include-config", "y", "dev-libs/A",), |
112 |
+ # Test bug #523684, where a file renamed or removed by the |
113 |
+ # admin forces replacement files to be merged with config |
114 |
+ # protection. |
115 |
+ lambda: self.assertEqual(0, |
116 |
+ len(list(find_updated_config_files(eroot, |
117 |
+ shlex_split(settings["CONFIG_PROTECT"]))))), |
118 |
+ lambda: os.unlink(os.path.join(eprefix, "etc", "A-0")), |
119 |
emerge_cmd + ("--usepkgonly", "dev-libs/A"), |
120 |
+ lambda: self.assertEqual(1, |
121 |
+ len(list(find_updated_config_files(eroot, |
122 |
+ shlex_split(settings["CONFIG_PROTECT"]))))), |
123 |
emaint_cmd + ("--check", "all"), |
124 |
emaint_cmd + ("--fix", "all"), |
125 |
fixpackages_cmd, |
126 |
-- |
127 |
1.8.5.5 |