Gentoo Archives: gentoo-portage-dev

From: "Étienne Buira" <etienne.buira@×××××.com>
To: gentoo-portage-dev@l.g.o
Subject: [gentoo-portage-dev] [PATCH] conf: Enable to set rsync extra opts per repository
Date: Wed, 17 Jun 2015 18:40:36
Message-Id: 20150617184030.GC26811@rcKGHUlyQfVFW
1 ---
2 man/portage.5 | 5 +++
3 pym/portage/package/ebuild/config.py | 2 +
4 pym/portage/repository/config.py | 24 +++++++---
5 pym/portage/sync/modules/rsync/rsync.py | 6 ++-
6 pym/portage/tests/sync/test_sync_local.py | 73 ++++++++++++++++++++++++++++---
7 5 files changed, 95 insertions(+), 15 deletions(-)
8
9 diff --git a/man/portage.5 b/man/portage.5
10 index e77fc6e..e84142a 100644
11 --- a/man/portage.5
12 +++ b/man/portage.5
13 @@ -1021,6 +1021,11 @@ group id will be changed.
14 .br
15 This key takes precedence over FEATURES=userpriv. If user or group id
16 is provided, Portage no longer uses owner of the directory.
17 +.TP
18 +.B sync-rsync-extra-opts
19 +Extra options to give to rsync on repository synchronization. It takes
20 +precedence over a declaration in [DEFAULT] section, that takes
21 +precedence over PORTAGE_RSYNC_EXTRA_OPTS.
22 .RE
23
24 .I Example:
25 diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py
26 index 3a4007b..08db363 100644
27 --- a/pym/portage/package/ebuild/config.py
28 +++ b/pym/portage/package/ebuild/config.py
29 @@ -515,6 +515,8 @@ class config(object):
30 v = confs.get("SYNC")
31 if v is not None:
32 portdir_sync = v
33 + if 'PORTAGE_RSYNC_EXTRA_OPTS' in confs:
34 + self['PORTAGE_RSYNC_EXTRA_OPTS'] = confs['PORTAGE_RSYNC_EXTRA_OPTS']
35
36 self["PORTDIR"] = portdir
37 self["PORTDIR_OVERLAY"] = portdir_overlay
38 diff --git a/pym/portage/repository/config.py b/pym/portage/repository/config.py
39 index b7c969d..196b87a 100644
40 --- a/pym/portage/repository/config.py
41 +++ b/pym/portage/repository/config.py
42 @@ -87,7 +87,7 @@ class RepoConfig(object):
43 'main_repo', 'manifest_hashes', 'masters', 'missing_repo_name',
44 'name', 'portage1_profiles', 'portage1_profiles_compat', 'priority',
45 'profile_formats', 'sign_commit', 'sign_manifest', 'sync_cvs_repo',
46 - 'sync_depth',
47 + 'sync_depth', 'sync_rsync_extra_opts',
48 'sync_type', 'sync_umask', 'sync_uri', 'sync_user', 'thin_manifest',
49 'update_changelog', 'user_location', '_eapis_banned',
50 '_eapis_deprecated', '_masters_orig')
51 @@ -180,6 +180,8 @@ class RepoConfig(object):
52
53 self.sync_depth = repo_opts.get('sync-depth')
54
55 + self.sync_rsync_extra_opts = repo_opts.get('sync-rsync-extra-opts', None)
56 +
57 # Not implemented.
58 format = repo_opts.get('format')
59 if format is not None:
60 @@ -415,6 +417,8 @@ class RepoConfig(object):
61 repo_msg.append(indent + "sync-umask: " + self.sync_umask)
62 if self.sync_uri:
63 repo_msg.append(indent + "sync-uri: " + self.sync_uri)
64 + if self.sync_rsync_extra_opts:
65 + repo_msg.append(indent + "sync-rsync-extra-opts: " + self.sync_rsync_extra_opts)
66 if self.sync_user:
67 repo_msg.append(indent + "sync-user: " + self.sync_user)
68 if self.masters:
69 @@ -477,6 +481,9 @@ class RepoConfigLoader(object):
70 if prepos['DEFAULT'].masters is not None:
71 default_repo_opts['masters'] = \
72 ' '.join(prepos['DEFAULT'].masters)
73 + if prepos['DEFAULT'].sync_rsync_extra_opts is not None:
74 + default_repo_opts['sync-rsync-extra-opts'] = \
75 + prepos['DEFAULT'].sync_rsync_extra_opts
76
77 if overlays:
78 # We need a copy of the original repos.conf data, since we're
79 @@ -504,7 +511,7 @@ class RepoConfigLoader(object):
80 # repos.conf is allowed to override.
81 for k in ('aliases', 'auto_sync', 'eclass_overrides',
82 'force', 'masters', 'priority', 'sync_cvs_repo',
83 - 'sync_depth',
84 + 'sync_depth', 'sync_rsync_extra_opts',
85 'sync_type', 'sync_umask', 'sync_uri', 'sync_user',
86 ):
87 v = getattr(repos_conf_opts, k, None)
88 @@ -543,9 +550,9 @@ class RepoConfigLoader(object):
89 return portdir
90
91 @staticmethod
92 - def _parse(paths, prepos, ignored_map, ignored_location_map, local_config, portdir):
93 + def _parse(paths, prepos, ignored_map, ignored_location_map, local_config, portdir, default_opts):
94 """Parse files in paths to load config"""
95 - parser = SafeConfigParser()
96 + parser = SafeConfigParser(defaults=default_opts)
97
98 # use read_file/readfp in order to control decoding of unicode
99 try:
100 @@ -615,6 +622,7 @@ class RepoConfigLoader(object):
101 treemap = {}
102 ignored_map = {}
103 ignored_location_map = {}
104 + default_opts = {}
105
106 if "PORTAGE_REPOSITORIES" in settings:
107 portdir = ""
108 @@ -627,10 +635,13 @@ class RepoConfigLoader(object):
109 # deprecated portdir_sync
110 portdir_sync = settings.get("SYNC", "")
111
112 + default_opts['sync-rsync-extra-opts'] = \
113 + settings.get("PORTAGE_RSYNC_EXTRA_OPTS", None)
114 +
115 try:
116 self._parse(paths, prepos, ignored_map,
117 ignored_location_map, settings.local_config,
118 - portdir)
119 + portdir, default_opts)
120 except ConfigParserError as e:
121 writemsg(
122 _("!!! Error while reading repo config file: %s\n") % e,
123 @@ -962,7 +973,8 @@ class RepoConfigLoader(object):
124 def config_string(self):
125 str_or_int_keys = ("auto_sync", "format", "location",
126 "main_repo", "priority", "sync_cvs_repo",
127 - "sync_type", "sync_umask", "sync_uri", 'sync_user')
128 + "sync_type", "sync_umask", "sync_uri", 'sync_user',
129 + 'sync_rsync_extra_opts')
130 str_tuple_keys = ("aliases", "eclass_overrides", "force")
131 repo_config_tuple_keys = ("masters",)
132 keys = str_or_int_keys + str_tuple_keys + repo_config_tuple_keys
133 diff --git a/pym/portage/sync/modules/rsync/rsync.py b/pym/portage/sync/modules/rsync/rsync.py
134 index d84c36d..1f09f60 100644
135 --- a/pym/portage/sync/modules/rsync/rsync.py
136 +++ b/pym/portage/sync/modules/rsync/rsync.py
137 @@ -72,8 +72,10 @@ class RsyncSync(NewBase):
138 rsync_opts = self._validate_rsync_opts(rsync_opts, syncuri)
139 self.rsync_opts = self._rsync_opts_extend(opts, rsync_opts)
140
141 - self.extra_rsync_opts = portage.util.shlex_split(
142 - self.settings.get("PORTAGE_RSYNC_EXTRA_OPTS",""))
143 + self.extra_rsync_opts = list()
144 + if self.repo.sync_rsync_extra_opts is not None:
145 + self.extra_rsync_opts.extend(portage.util.shlex_split(
146 + self.repo.sync_rsync_extra_opts))
147
148 # Real local timestamp file.
149 self.servertimestampfile = os.path.join(
150 diff --git a/pym/portage/tests/sync/test_sync_local.py b/pym/portage/tests/sync/test_sync_local.py
151 index 65c20f8..f50caba 100644
152 --- a/pym/portage/tests/sync/test_sync_local.py
153 +++ b/pym/portage/tests/sync/test_sync_local.py
154 @@ -7,7 +7,7 @@ import textwrap
155 import time
156
157 import portage
158 -from portage import os, shutil
159 +from portage import os, shutil, _shell_quote
160 from portage import _unicode_decode
161 from portage.const import PORTAGE_PYM_PATH, TIMESTAMP_FORMAT
162 from portage.process import find_binary
163 @@ -36,11 +36,14 @@ class SyncLocalTestCase(TestCase):
164 return
165
166 repos_conf = textwrap.dedent("""
167 + [DEFAULT]
168 + %(default_keys)s
169 [test_repo]
170 location = %(EPREFIX)s/var/repositories/test_repo
171 sync-type = %(sync-type)s
172 sync-uri = file:/%(EPREFIX)s/var/repositories/test_repo_sync
173 auto-sync = yes
174 + %(repo_extra_keys)s
175 """)
176
177 profile = {
178 @@ -73,9 +76,17 @@ class SyncLocalTestCase(TestCase):
179 committer_name = "Gentoo Dev"
180 committer_email = "gentoo-dev@g.o"
181
182 - def change_sync_type(sync_type):
183 - env["PORTAGE_REPOSITORIES"] = repos_conf % \
184 - {"EPREFIX": eprefix, "sync-type": sync_type}
185 + def repos_set_conf(sync_type, dflt_keys=None, xtra_keys=None):
186 + env["PORTAGE_REPOSITORIES"] = repos_conf % {\
187 + "EPREFIX": eprefix, "sync-type": sync_type,
188 + "default_keys": "" if dflt_keys is None else dflt_keys,
189 + "repo_extra_keys": "" if xtra_keys is None else xtra_keys}
190 +
191 + def alter_ebuild():
192 + with open(os.path.join(repo.location + "_sync",
193 + "dev-libs", "A", "A-0.ebuild"), "a") as f:
194 + f.write("\n")
195 + os.unlink(os.path.join(metadata_dir, 'timestamp.chk'))
196
197 sync_cmds = (
198 (homedir, cmds["emerge"] + ("--sync",)),
199 @@ -90,6 +101,53 @@ class SyncLocalTestCase(TestCase):
200 repo.location + "_sync")),
201 )
202
203 + rsync_opts_repos = (
204 + (homedir, alter_ebuild),
205 + (homedir, lambda: repos_set_conf("rsync", None,
206 + "sync-rsync-extra-opts = --backup --backup-dir=%s" %
207 + _shell_quote(repo.location + "_back"))),
208 + (homedir, cmds['emerge'] + ("--sync",)),
209 + (homedir, lambda: self.assertTrue(os.path.exists(
210 + repo.location + "_back"))),
211 + (homedir, lambda: shutil.rmtree(repo.location + "_back")),
212 + (homedir, lambda: repos_set_conf("rsync")),
213 + )
214 +
215 + rsync_opts_repos_default = (
216 + (homedir, alter_ebuild),
217 + (homedir, lambda: repos_set_conf("rsync",
218 + "sync-rsync-extra-opts = --backup --backup-dir=%s" %
219 + _shell_quote(repo.location+"_back"))),
220 + (homedir, cmds['emerge'] + ("--sync",)),
221 + (homedir, lambda: self.assertTrue(os.path.exists(repo.location + "_back"))),
222 + (homedir, lambda: shutil.rmtree(repo.location + "_back")),
223 + (homedir, lambda: repos_set_conf("rsync")),
224 + )
225 +
226 + rsync_opts_repos_default_ovr = (
227 + (homedir, alter_ebuild),
228 + (homedir, lambda: repos_set_conf("rsync",
229 + "sync-rsync-extra-opts = --backup --backup-dir=%s" %
230 + _shell_quote(repo.location + "_back_nowhere"),
231 + "sync-rsync-extra-opts = --backup --backup-dir=%s" %
232 + _shell_quote(repo.location + "_back"))),
233 + (homedir, cmds['emerge'] + ("--sync",)),
234 + (homedir, lambda: self.assertTrue(os.path.exists(repo.location + "_back"))),
235 + (homedir, lambda: shutil.rmtree(repo.location + "_back")),
236 + (homedir, lambda: repos_set_conf("rsync")),
237 + )
238 +
239 + rsync_opts_repos_default_cancel = (
240 + (homedir, alter_ebuild),
241 + (homedir, lambda: repos_set_conf("rsync",
242 + "sync-rsync-extra-opts = --backup --backup-dir=%s" %
243 + _shell_quote(repo.location + "_back_nowhere"),
244 + "sync-rsync-extra-opts = ")),
245 + (homedir, cmds['emerge'] + ("--sync",)),
246 + (homedir, lambda: self.assertFalse(os.path.exists(repo.location + "_back"))),
247 + (homedir, lambda: repos_set_conf("rsync")),
248 + )
249 +
250 delete_sync_repo = (
251 (homedir, lambda: shutil.rmtree(
252 repo.location + "_sync")),
253 @@ -107,7 +165,7 @@ class SyncLocalTestCase(TestCase):
254 )
255
256 sync_type_git = (
257 - (homedir, lambda: change_sync_type("git")),
258 + (homedir, lambda: repos_set_conf("git")),
259 )
260
261 pythonpath = os.environ.get("PYTHONPATH")
262 @@ -132,10 +190,9 @@ class SyncLocalTestCase(TestCase):
263 "PATH" : os.environ["PATH"],
264 "PORTAGE_GRPNAME" : os.environ["PORTAGE_GRPNAME"],
265 "PORTAGE_USERNAME" : os.environ["PORTAGE_USERNAME"],
266 - "PORTAGE_REPOSITORIES" : repos_conf %
267 - {"EPREFIX": eprefix, "sync-type": "rsync"},
268 "PYTHONPATH" : pythonpath,
269 }
270 + repos_set_conf("rsync")
271
272 if os.environ.get("SANDBOX_ON") == "1":
273 # avoid problems from nested sandbox instances
274 @@ -160,6 +217,8 @@ class SyncLocalTestCase(TestCase):
275 stdout = subprocess.PIPE
276
277 for cwd, cmd in rename_repo + sync_cmds + \
278 + rsync_opts_repos + rsync_opts_repos_default + \
279 + rsync_opts_repos_default_ovr + rsync_opts_repos_default_cancel + \
280 delete_sync_repo + git_repo_create + sync_type_git + \
281 rename_repo + sync_cmds:

Replies