diff options
author | Mark Hatle <mark.hatle@windriver.com> | 2015-01-22 16:10:34 -0600 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2015-01-29 15:36:48 +0000 |
commit | 2af94b0af6422862810acfc90f31fa659f31e46e (patch) | |
tree | b4f31ff545e5d3773e2362285f47de9982a26338 | |
parent | 5656567104a7cee09662831a14d4e21dd6bfd354 (diff) | |
download | poky-2af94b0af6422862810acfc90f31fa659f31e46e.tar.gz |
python-smartpm: Fix attemptonly builds when file conflicts occur
[YOCTO #7299]
When file conflicts occur, the RPM transaction aborts. Instead of
simply accepting the failure, we now identify, capture, and remove
the offending package(s) from the transaction and retry.
(From OE-Core rev: cd475aea5f5bc4b6a2dd3e576070a117ae079597)
Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r-- | meta/recipes-devtools/python/python-smartpm/smart-attempt.patch | 97 |
1 files changed, 66 insertions, 31 deletions
diff --git a/meta/recipes-devtools/python/python-smartpm/smart-attempt.patch b/meta/recipes-devtools/python/python-smartpm/smart-attempt.patch index 45f794787c..82d2e6cf31 100644 --- a/meta/recipes-devtools/python/python-smartpm/smart-attempt.patch +++ b/meta/recipes-devtools/python/python-smartpm/smart-attempt.patch | |||
@@ -9,40 +9,24 @@ failures (usually conflicts). | |||
9 | 9 | ||
10 | This option only works for the install operation. | 10 | This option only works for the install operation. |
11 | 11 | ||
12 | If a complementary install fails, an actual error occurred, one that | ||
13 | we can't ignore without losing the entire attempted transaction. Keep | ||
14 | this as an error so that we can catch these cases in the futre. | ||
15 | |||
12 | Upstream-Status: Pending | 16 | Upstream-Status: Pending |
13 | 17 | ||
14 | Signed-off-by: Mark Hatle <mark.hatle@windriver.com> | 18 | Signed-off-by: Mark Hatle <mark.hatle@windriver.com> |
15 | Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> | 19 | Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> |
16 | |||
17 | For complementary and 'attemptonly' package processing, we should | ||
18 | make sure the warn rather than error reported. | ||
19 | Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> | ||
20 | --- | 20 | --- |
21 | smart.py | 5 +++- | 21 | smart.py | 5 +++- |
22 | smart/commands/install.py | 5 ++++ | 22 | smart/commands/install.py | 5 ++++ |
23 | smart/transaction.py | 65 +++++++++++++++++++++++++++++++++++------------ | 23 | smart/transaction.py | 65 +++++++++++++++++++++++++++++++++++------------ |
24 | 3 files changed, 58 insertions(+), 17 deletions(-) | 24 | 3 files changed, 58 insertions(+), 17 deletions(-) |
25 | 25 | ||
26 | diff --git a/smart.py b/smart.py | 26 | Index: smart-1.4.1/smart/commands/install.py |
27 | index c5c7a02..7e7fd34 100755 | 27 | =================================================================== |
28 | --- a/smart.py | 28 | --- smart-1.4.1.orig/smart/commands/install.py |
29 | +++ b/smart.py | 29 | +++ smart-1.4.1/smart/commands/install.py |
30 | @@ -179,7 +179,10 @@ def main(argv): | ||
31 | if opts and opts.log_level == "debug": | ||
32 | import traceback | ||
33 | traceback.print_exc() | ||
34 | - if iface.object: | ||
35 | + if iface.object and sysconf.has("attempt-install", soft=True): | ||
36 | + iface.warning(unicode(e)) | ||
37 | + exitcode = 0 | ||
38 | + elif iface.object: | ||
39 | iface.error(unicode(e)) | ||
40 | else: | ||
41 | sys.stderr.write(_("error: %s\n") % e) | ||
42 | diff --git a/smart/commands/install.py b/smart/commands/install.py | ||
43 | index 590222c..6ef9682 100644 | ||
44 | --- a/smart/commands/install.py | ||
45 | +++ b/smart/commands/install.py | ||
46 | @@ -50,6 +50,8 @@ def option_parser(): | 30 | @@ -50,6 +50,8 @@ def option_parser(): |
47 | parser = OptionParser(usage=USAGE, | 31 | parser = OptionParser(usage=USAGE, |
48 | description=DESCRIPTION, | 32 | description=DESCRIPTION, |
@@ -62,10 +46,10 @@ index 590222c..6ef9682 100644 | |||
62 | if opts.explain: | 46 | if opts.explain: |
63 | sysconf.set("explain-changesets", True, soft=True) | 47 | sysconf.set("explain-changesets", True, soft=True) |
64 | 48 | ||
65 | diff --git a/smart/transaction.py b/smart/transaction.py | 49 | Index: smart-1.4.1/smart/transaction.py |
66 | index 5730a42..e3e61c6 100644 | 50 | =================================================================== |
67 | --- a/smart/transaction.py | 51 | --- smart-1.4.1.orig/smart/transaction.py |
68 | +++ b/smart/transaction.py | 52 | +++ smart-1.4.1/smart/transaction.py |
69 | @@ -555,6 +555,8 @@ class Transaction(object): | 53 | @@ -555,6 +555,8 @@ class Transaction(object): |
70 | changeset.set(pkg, INSTALL) | 54 | changeset.set(pkg, INSTALL) |
71 | isinst = changeset.installed | 55 | isinst = changeset.installed |
@@ -183,6 +167,57 @@ index 5730a42..e3e61c6 100644 | |||
183 | elif op is REMOVE: | 167 | elif op is REMOVE: |
184 | self._remove(pkg, changeset, locked, pending) | 168 | self._remove(pkg, changeset, locked, pending) |
185 | elif op is UPGRADE: | 169 | elif op is UPGRADE: |
186 | -- | 170 | Index: smart-1.4.1/smart/backends/rpm/pm.py |
187 | 1.9.1 | 171 | =================================================================== |
188 | 172 | --- smart-1.4.1.orig/smart/backends/rpm/pm.py | |
173 | +++ smart-1.4.1/smart/backends/rpm/pm.py | ||
174 | @@ -243,15 +253,48 @@ class RPMPackageManager(PackageManager): | ||
175 | cb = RPMCallback(prog, upgradednames) | ||
176 | cb.grabOutput(True) | ||
177 | probs = None | ||
178 | + retry = 0 | ||
179 | try: | ||
180 | probs = ts.run(cb, None) | ||
181 | finally: | ||
182 | del getTS.ts | ||
183 | cb.grabOutput(False) | ||
184 | + if probs and sysconf.has("attempt-install", soft=True): | ||
185 | + def remove_conflict(pkgNEVR): | ||
186 | + for key in changeset.keys(): | ||
187 | + if pkgNEVR == str(key): | ||
188 | + del changeset[key] | ||
189 | + del pkgpaths[key] | ||
190 | + iface.warning("Removing %s due to file %s conflicting with %s" % (pkgNEVR, fname, altNEVR)) | ||
191 | + break | ||
192 | + | ||
193 | + retry = 1 | ||
194 | + for prob in probs: | ||
195 | + if prob[1][0] == rpm.RPMPROB_NEW_FILE_CONFLICT: | ||
196 | + msg = prob[0].split() | ||
197 | + fname = msg[1] | ||
198 | + pkgNEVR = msg[7] | ||
199 | + altNEVR = msg[9] | ||
200 | + pkgNEVR = pkgNEVR.rsplit('.', 1)[0] + '@' + pkgNEVR.rsplit('.', 1)[1] | ||
201 | + altNEVR = altNEVR.rsplit('.', 1)[0] + '@' + altNEVR.rsplit('.', 1)[1] | ||
202 | + remove_conflict(pkgNEVR) | ||
203 | + elif prob[1][0] == rpm.RPMPROB_FILE_CONFLICT: | ||
204 | + msg = prob[0].split() | ||
205 | + fname = msg[1] | ||
206 | + pkgNEVR = msg[5] | ||
207 | + altNEVR = msg[11] | ||
208 | + pkgNEVR = pkgNEVR.rsplit('.', 1)[0] + '@' + pkgNEVR.rsplit('.', 1)[1] | ||
209 | + altNEVR = altNEVR.rsplit('.', 1)[0] + '@' + altNEVR.rsplit('.', 1)[1] | ||
210 | + remove_conflict(pkgNEVR) | ||
211 | + else: | ||
212 | + retry = 0 | ||
213 | + | ||
214 | prog.setDone() | ||
215 | - if probs: | ||
216 | + if probs and (not retry): | ||
217 | raise Error, "\n".join([x[0] for x in probs]) | ||
218 | prog.stop() | ||
219 | + if retry and len(changeset): | ||
220 | + self.commit(changeset, pkgpaths) | ||
221 | |||
222 | class RPMCallback: | ||
223 | def __init__(self, prog, upgradednames): | ||