Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Zac Medico <zmedico@g.o>
Subject: [gentoo-portage-dev] [PATCH v4] egencache: add --stable-mtime option
Date: Mon, 21 Dec 2015 19:57:58
Message-Id: 1450727857-22680-1-git-send-email-zmedico@gentoo.org
In Reply to: [gentoo-portage-dev] [PATCH] egencache: add --stable-mtime option by Zac Medico
1 Since the Manifest "stable mtime" behavior could have undiscovered
2 bugs, disable it by default, and add a corresponding egencache option.
3
4 Suggested-by: Michał Górny <mgorny@g.o>
5 ---
6 [PATCH v4] fixes english børk in the Manifest.write comment block.
7
8 bin/egencache | 6 +++++-
9 man/egencache.1 | 3 +++
10 pym/portage/manifest.py | 23 +++++++++++++++++-----
11 .../ebuild/_parallel_manifest/ManifestProcess.py | 6 ++++--
12 .../ebuild/_parallel_manifest/ManifestScheduler.py | 7 +++++--
13 .../ebuild/_parallel_manifest/ManifestTask.py | 8 +++++---
14 6 files changed, 40 insertions(+), 13 deletions(-)
15
16 diff --git a/bin/egencache b/bin/egencache
17 index 7e3387e..07665e8 100755
18 --- a/bin/egencache
19 +++ b/bin/egencache
20 @@ -120,6 +120,9 @@ def parse_args(args):
21 choices=('y', 'n'),
22 metavar="<y|n>",
23 help="manually override layout.conf sign-manifests setting")
24 + common.add_argument("--stable-mtime",
25 + action="store_true",
26 + help="apply stable mtime to generated manifests (for rsync)")
27 common.add_argument("--strict-manifests",
28 choices=('y', 'n'),
29 metavar="<y|n>",
30 @@ -1151,7 +1154,8 @@ def egencache_main(args):
31 force_sign_key=force_sign_key,
32 max_jobs=options.jobs,
33 max_load=options.load_average,
34 - event_loop=event_loop)
35 + event_loop=event_loop,
36 + manifest_kwargs=dict(stable_mtime=options.stable_mtime))
37
38 signum = run_main_scheduler(scheduler)
39 if signum is not None:
40 diff --git a/man/egencache.1 b/man/egencache.1
41 index 7fd17c2..081e8c1 100644
42 --- a/man/egencache.1
43 +++ b/man/egencache.1
44 @@ -100,6 +100,9 @@ Manually override layout.conf sign-manifests setting.
45 .BR "\-\-strict\-manifests< y | n >"
46 Manually override "strict" FEATURES setting.
47 .TP
48 +.BR "\-\-stable\-mtime"
49 +Apply stable mtime to generated manifests (for rsync).
50 +.TP
51 .BR "\-\-thin\-manifests< y | n >"
52 Manually override layout.conf thin-manifests setting.
53 .TP
54 diff --git a/pym/portage/manifest.py b/pym/portage/manifest.py
55 index f696f84..eaeecc5 100644
56 --- a/pym/portage/manifest.py
57 +++ b/pym/portage/manifest.py
58 @@ -128,7 +128,7 @@ class Manifest(object):
59 def __init__(self, pkgdir, distdir=None, fetchlist_dict=None,
60 manifest1_compat=DeprecationWarning, from_scratch=False, thin=False,
61 allow_missing=False, allow_create=True, hashes=None,
62 - find_invalid_path_char=None):
63 + find_invalid_path_char=None, stable_mtime=False):
64 """ Create new Manifest instance for package in pkgdir.
65 Do not parse Manifest file if from_scratch == True (only for internal use)
66 The fetchlist_dict parameter is required only for generation of
67 @@ -145,6 +145,7 @@ class Manifest(object):
68 find_invalid_path_char = _find_invalid_path_char
69 self._find_invalid_path_char = find_invalid_path_char
70 self.pkgdir = _unicode_decode(pkgdir).rstrip(os.sep) + os.sep
71 + self.stable_mtime = stable_mtime
72 self.fhashdict = {}
73 self.hashes = set()
74
75 @@ -283,7 +284,16 @@ class Manifest(object):
76 myentries = list(self._createManifestEntries())
77 update_manifest = True
78 preserved_stats = {}
79 - preserved_stats[self.pkgdir.rstrip(os.sep)] = os.stat(self.pkgdir)
80 + if self.stable_mtime:
81 + # The pre-existing mtime of self.pkgdir is included in the
82 + # max mtime calculation in order to account for anything
83 + # that may have been renamed or removed in this directory
84 + # (including the Manifest itself). Note that the mtime of
85 + # this directory will always be bumped as a side-effect of
86 + # writing the Manifest (since write_atomic uses a rename
87 + # operation for atomicity), therefore it must be preserved
88 + # before writing the Manifest.
89 + preserved_stats[self.pkgdir.rstrip(os.sep)] = os.stat(self.pkgdir)
90 if myentries and not force:
91 try:
92 f = io.open(_unicode_encode(self.getFullname(),
93 @@ -291,7 +301,8 @@ class Manifest(object):
94 mode='r', encoding=_encodings['repo.content'],
95 errors='replace')
96 oldentries = list(self._parseManifestLines(f))
97 - preserved_stats[self.getFullname()] = os.fstat(f.fileno())
98 + if self.stable_mtime:
99 + preserved_stats[self.getFullname()] = os.fstat(f.fileno())
100 f.close()
101 if len(oldentries) == len(myentries):
102 update_manifest = False
103 @@ -313,7 +324,8 @@ class Manifest(object):
104 # non-empty for all currently known use cases.
105 write_atomic(self.getFullname(), "".join("%s\n" %
106 _unicode(myentry) for myentry in myentries))
107 - self._apply_max_mtime(preserved_stats, myentries)
108 + if self.stable_mtime:
109 + self._apply_max_mtime(preserved_stats, myentries)
110 rval = True
111 else:
112 # With thin manifest, there's no need to have
113 @@ -450,7 +462,8 @@ class Manifest(object):
114 fetchlist_dict=self.fetchlist_dict, from_scratch=True,
115 thin=self.thin, allow_missing=self.allow_missing,
116 allow_create=self.allow_create, hashes=self.hashes,
117 - find_invalid_path_char=self._find_invalid_path_char)
118 + find_invalid_path_char=self._find_invalid_path_char,
119 + stable_mtime=self.stable_mtime)
120 pn = os.path.basename(self.pkgdir.rstrip(os.path.sep))
121 cat = self._pkgdir_category()
122
123 diff --git a/pym/portage/package/ebuild/_parallel_manifest/ManifestProcess.py b/pym/portage/package/ebuild/_parallel_manifest/ManifestProcess.py
124 index 44e2576..01595a3 100644
125 --- a/pym/portage/package/ebuild/_parallel_manifest/ManifestProcess.py
126 +++ b/pym/portage/package/ebuild/_parallel_manifest/ManifestProcess.py
127 @@ -10,14 +10,16 @@ from portage.util._async.ForkProcess import ForkProcess
128
129 class ManifestProcess(ForkProcess):
130
131 - __slots__ = ("cp", "distdir", "fetchlist_dict", "repo_config")
132 + __slots__ = ("cp", "distdir", "fetchlist_dict", "manifest_kwargs",
133 + "repo_config")
134
135 MODIFIED = 16
136
137 def _run(self):
138 mf = self.repo_config.load_manifest(
139 os.path.join(self.repo_config.location, self.cp),
140 - self.distdir, fetchlist_dict=self.fetchlist_dict)
141 + self.distdir, fetchlist_dict=self.fetchlist_dict,
142 + **(self.manifest_kwargs or {}))
143
144 try:
145 mf.create(assumeDistHashesAlways=True)
146 diff --git a/pym/portage/package/ebuild/_parallel_manifest/ManifestScheduler.py b/pym/portage/package/ebuild/_parallel_manifest/ManifestScheduler.py
147 index 38ac482..8a1c1d0 100644
148 --- a/pym/portage/package/ebuild/_parallel_manifest/ManifestScheduler.py
149 +++ b/pym/portage/package/ebuild/_parallel_manifest/ManifestScheduler.py
150 @@ -12,11 +12,13 @@ from .ManifestTask import ManifestTask
151 class ManifestScheduler(AsyncScheduler):
152
153 def __init__(self, portdb, cp_iter=None,
154 - gpg_cmd=None, gpg_vars=None, force_sign_key=None, **kwargs):
155 + gpg_cmd=None, gpg_vars=None, force_sign_key=None,
156 + manifest_kwargs=None, **kwargs):
157
158 AsyncScheduler.__init__(self, **kwargs)
159
160 self._portdb = portdb
161 + self._manifest_kwargs = manifest_kwargs
162
163 if cp_iter is None:
164 cp_iter = self._iter_every_cp()
165 @@ -79,7 +81,8 @@ class ManifestScheduler(AsyncScheduler):
166 yield ManifestTask(cp=cp, distdir=distdir,
167 fetchlist_dict=fetchlist_dict, repo_config=repo_config,
168 gpg_cmd=self._gpg_cmd, gpg_vars=self._gpg_vars,
169 - force_sign_key=self._force_sign_key)
170 + force_sign_key=self._force_sign_key,
171 + manifest_kwargs=self._manifest_kwargs)
172
173 def _task_exit(self, task):
174
175 diff --git a/pym/portage/package/ebuild/_parallel_manifest/ManifestTask.py b/pym/portage/package/ebuild/_parallel_manifest/ManifestTask.py
176 index 0ee2b91..fb5e16e 100644
177 --- a/pym/portage/package/ebuild/_parallel_manifest/ManifestTask.py
178 +++ b/pym/portage/package/ebuild/_parallel_manifest/ManifestTask.py
179 @@ -18,8 +18,8 @@ from .ManifestProcess import ManifestProcess
180
181 class ManifestTask(CompositeTask):
182
183 - __slots__ = ("cp", "distdir", "fetchlist_dict", "gpg_cmd",
184 - "gpg_vars", "repo_config", "force_sign_key", "_manifest_path")
185 + __slots__ = ("cp", "distdir", "fetchlist_dict", "force_sign_key",
186 + "gpg_cmd", "gpg_vars", "manifest_kwargs", "repo_config", "_manifest_path")
187
188 _PGP_HEADER = b"BEGIN PGP SIGNED MESSAGE"
189 _manifest_line_re = re.compile(r'^(%s) ' % "|".join(MANIFEST2_IDENTIFIERS))
190 @@ -30,7 +30,9 @@ class ManifestTask(CompositeTask):
191 self._manifest_path = os.path.join(self.repo_config.location,
192 self.cp, "Manifest")
193 manifest_proc = ManifestProcess(cp=self.cp, distdir=self.distdir,
194 - fetchlist_dict=self.fetchlist_dict, repo_config=self.repo_config,
195 + fetchlist_dict=self.fetchlist_dict,
196 + manifest_kwargs=self.manifest_kwargs,
197 + repo_config=self.repo_config,
198 scheduler=self.scheduler)
199 self._start_task(manifest_proc, self._manifest_proc_exit)
200
201 --
202 2.4.10

Replies

Subject Author
Re: [gentoo-portage-dev] [PATCH v4] egencache: add --stable-mtime option Alexander Berntsen <bernalex@g.o>