1 |
Support customization of fetchcommand and resumecommand in |
2 |
binrepos.conf, allowing customized authentication mechanisms for |
3 |
each repository. |
4 |
|
5 |
Bug: https://bugs.gentoo.org/661332 |
6 |
Signed-off-by: Zac Medico <zmedico@g.o> |
7 |
--- |
8 |
lib/_emerge/BinpkgFetcher.py | 29 +++++++++++++++++++---------- |
9 |
lib/portage/binrepo/config.py | 2 ++ |
10 |
lib/portage/dbapi/bintree.py | 34 +++++++++++++++++++++++++--------- |
11 |
man/portage.5 | 14 ++++++++++++++ |
12 |
4 files changed, 60 insertions(+), 19 deletions(-) |
13 |
|
14 |
diff --git a/lib/_emerge/BinpkgFetcher.py b/lib/_emerge/BinpkgFetcher.py |
15 |
index 218d4d2ab..9a96bde28 100644 |
16 |
--- a/lib/_emerge/BinpkgFetcher.py |
17 |
+++ b/lib/_emerge/BinpkgFetcher.py |
18 |
@@ -96,14 +96,17 @@ class _BinpkgFetcherProcess(SpawnProcess): |
19 |
|
20 |
# urljoin doesn't work correctly with |
21 |
# unrecognized protocols like sftp |
22 |
+ fetchcommand = None |
23 |
+ resumecommand = None |
24 |
if bintree._remote_has_index: |
25 |
- instance_key = bintree.dbapi._instance_key(pkg.cpv) |
26 |
- rel_uri = bintree._remotepkgs[instance_key].get("PATH") |
27 |
+ remote_metadata = bintree._remotepkgs[bintree.dbapi._instance_key(pkg.cpv)] |
28 |
+ rel_uri = remote_metadata.get("PATH") |
29 |
if not rel_uri: |
30 |
rel_uri = pkg.cpv + ".tbz2" |
31 |
- remote_base_uri = bintree._remotepkgs[ |
32 |
- instance_key]["BASE_URI"] |
33 |
+ remote_base_uri = remote_metadata["BASE_URI"] |
34 |
uri = remote_base_uri.rstrip("/") + "/" + rel_uri.lstrip("/") |
35 |
+ fetchcommand = remote_metadata.get('FETCHCOMMAND') |
36 |
+ resumecommand = remote_metadata.get('RESUMECOMMAND') |
37 |
else: |
38 |
uri = settings["PORTAGE_BINHOST"].rstrip("/") + \ |
39 |
"/" + pkg.pf + ".tbz2" |
40 |
@@ -114,13 +117,19 @@ class _BinpkgFetcherProcess(SpawnProcess): |
41 |
self._async_wait() |
42 |
return |
43 |
|
44 |
- protocol = urllib_parse_urlparse(uri)[0] |
45 |
- fcmd_prefix = "FETCHCOMMAND" |
46 |
+ fcmd = None |
47 |
if resume: |
48 |
- fcmd_prefix = "RESUMECOMMAND" |
49 |
- fcmd = settings.get(fcmd_prefix + "_" + protocol.upper()) |
50 |
- if not fcmd: |
51 |
- fcmd = settings.get(fcmd_prefix) |
52 |
+ fcmd = resumecommand |
53 |
+ else: |
54 |
+ fcmd = fetchcommand |
55 |
+ if fcmd is None: |
56 |
+ protocol = urllib_parse_urlparse(uri)[0] |
57 |
+ fcmd_prefix = "FETCHCOMMAND" |
58 |
+ if resume: |
59 |
+ fcmd_prefix = "RESUMECOMMAND" |
60 |
+ fcmd = settings.get(fcmd_prefix + "_" + protocol.upper()) |
61 |
+ if not fcmd: |
62 |
+ fcmd = settings.get(fcmd_prefix) |
63 |
|
64 |
fcmd_vars = { |
65 |
"DISTDIR" : os.path.dirname(pkg_path), |
66 |
diff --git a/lib/portage/binrepo/config.py b/lib/portage/binrepo/config.py |
67 |
index aa3ff7a77..0c01f6fae 100644 |
68 |
--- a/lib/portage/binrepo/config.py |
69 |
+++ b/lib/portage/binrepo/config.py |
70 |
@@ -15,7 +15,9 @@ class BinRepoConfig: |
71 |
__slots__ = ( |
72 |
'name', |
73 |
'name_fallback', |
74 |
+ 'fetchcommand', |
75 |
'priority', |
76 |
+ 'resumecommand', |
77 |
'sync_uri', |
78 |
) |
79 |
def __init__(self, opts): |
80 |
diff --git a/lib/portage/dbapi/bintree.py b/lib/portage/dbapi/bintree.py |
81 |
index a96183561..ebc6765b6 100644 |
82 |
--- a/lib/portage/dbapi/bintree.py |
83 |
+++ b/lib/portage/dbapi/bintree.py |
84 |
@@ -382,10 +382,10 @@ class binarytree: |
85 |
self._pkgindex_keys.update(["CPV", "SIZE"]) |
86 |
self._pkgindex_aux_keys = \ |
87 |
["BASE_URI", "BDEPEND", "BUILD_ID", "BUILD_TIME", "CHOST", |
88 |
- "DEFINED_PHASES", "DEPEND", "DESCRIPTION", "EAPI", |
89 |
+ "DEFINED_PHASES", "DEPEND", "DESCRIPTION", "EAPI", "FETCHCOMMAND", |
90 |
"IUSE", "KEYWORDS", "LICENSE", "PDEPEND", |
91 |
"PKGINDEX_URI", "PROPERTIES", "PROVIDES", |
92 |
- "RDEPEND", "repository", "REQUIRES", "RESTRICT", |
93 |
+ "RDEPEND", "repository", "REQUIRES", "RESTRICT", "RESUMECOMMAND", |
94 |
"SIZE", "SLOT", "USE"] |
95 |
self._pkgindex_aux_keys = list(self._pkgindex_aux_keys) |
96 |
self._pkgindex_use_evaluated_keys = \ |
97 |
@@ -972,7 +972,7 @@ class binarytree: |
98 |
|
99 |
# Don't use urlopen for https, unless |
100 |
# PEP 476 is supported (bug #469888). |
101 |
- if parsed_url.scheme not in ('https',) or _have_pep_476(): |
102 |
+ if repo.fetchcommand is None and (parsed_url.scheme not in ('https',) or _have_pep_476()): |
103 |
try: |
104 |
f = _urlopen(url, if_modified_since=local_timestamp) |
105 |
if hasattr(f, 'headers') and f.headers.get('timestamp', ''): |
106 |
@@ -997,7 +997,7 @@ class binarytree: |
107 |
|
108 |
path = parsed_url.path.rstrip("/") + "/Packages" |
109 |
|
110 |
- if parsed_url.scheme == 'ssh': |
111 |
+ if repo.fetchcommand is None and parsed_url.scheme == 'ssh': |
112 |
# Use a pipe so that we can terminate the download |
113 |
# early if we detect that the TIMESTAMP header |
114 |
# matches that of the cached Packages file. |
115 |
@@ -1016,12 +1016,15 @@ class binarytree: |
116 |
stdout=subprocess.PIPE) |
117 |
f = proc.stdout |
118 |
else: |
119 |
- setting = 'FETCHCOMMAND_' + parsed_url.scheme.upper() |
120 |
- fcmd = self.settings.get(setting) |
121 |
- if not fcmd: |
122 |
- fcmd = self.settings.get('FETCHCOMMAND') |
123 |
+ if repo.fetchcommand is None: |
124 |
+ setting = 'FETCHCOMMAND_' + parsed_url.scheme.upper() |
125 |
+ fcmd = self.settings.get(setting) |
126 |
if not fcmd: |
127 |
- raise EnvironmentError("FETCHCOMMAND is unset") |
128 |
+ fcmd = self.settings.get('FETCHCOMMAND') |
129 |
+ if not fcmd: |
130 |
+ raise EnvironmentError("FETCHCOMMAND is unset") |
131 |
+ else: |
132 |
+ fcmd = repo.fetchcommand |
133 |
|
134 |
fd, tmp_filename = tempfile.mkstemp() |
135 |
tmp_dirname, tmp_basename = os.path.split(tmp_filename) |
136 |
@@ -1135,6 +1138,19 @@ class binarytree: |
137 |
d["CPV"] = cpv |
138 |
d["BASE_URI"] = remote_base_uri |
139 |
d["PKGINDEX_URI"] = url |
140 |
+ # FETCHCOMMAND and RESUMECOMMAND may be specified |
141 |
+ # by binrepos.conf, and otherwise ensure that they |
142 |
+ # do not propagate from the Packages index since |
143 |
+ # it may be unsafe to execute remotely specified |
144 |
+ # commands. |
145 |
+ if repo.fetchcommand is None: |
146 |
+ d.pop('FETCHCOMMAND', None) |
147 |
+ else: |
148 |
+ d['FETCHCOMMAND'] = repo.fetchcommand |
149 |
+ if repo.resumecommand is None: |
150 |
+ d.pop('RESUMECOMMAND', None) |
151 |
+ else: |
152 |
+ d['RESUMECOMMAND'] = repo.resumecommand |
153 |
self._remotepkgs[self.dbapi._instance_key(cpv)] = d |
154 |
self.dbapi.cpv_inject(cpv) |
155 |
|
156 |
diff --git a/man/portage.5 b/man/portage.5 |
157 |
index 890a22adb..9c88bc3dc 100644 |
158 |
--- a/man/portage.5 |
159 |
+++ b/man/portage.5 |
160 |
@@ -634,6 +634,20 @@ is intended to be used as a replacement for the \fBmake.conf\fR(5) |
161 |
\- attributes are specified in "${attribute} = ${value}" format |
162 |
.fi |
163 |
|
164 |
+.RS |
165 |
+.I Attributes supported in DEFAULT section: |
166 |
+.RS |
167 |
+.TP |
168 |
+.B fetchcommand |
169 |
+Specifies a \fBFETCHCOMMAND\fR used to fetch files from a repository, |
170 |
+overriding the value from \fBmake.conf\fR(5). |
171 |
+.TP |
172 |
+.B resumecommand |
173 |
+Specifies a \fBRESUMECOMMAND\fR used to fetch files from a repository, |
174 |
+overriding the value from \fBmake.conf\fR(5). |
175 |
+.RE |
176 |
+.RE |
177 |
+ |
178 |
.RS |
179 |
.I Attributes supported in sections of repositories: |
180 |
.RS |
181 |
-- |
182 |
2.25.3 |