summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/python/python-smartpm/smart-attempt.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/python/python-smartpm/smart-attempt.patch')
-rw-r--r--meta/recipes-devtools/python/python-smartpm/smart-attempt.patch223
1 files changed, 223 insertions, 0 deletions
diff --git a/meta/recipes-devtools/python/python-smartpm/smart-attempt.patch b/meta/recipes-devtools/python/python-smartpm/smart-attempt.patch
new file mode 100644
index 0000000000..82d2e6cf31
--- /dev/null
+++ b/meta/recipes-devtools/python/python-smartpm/smart-attempt.patch
@@ -0,0 +1,223 @@
1From b105e7fe812da3ccaf7155c0fe14c8728b0d39a5 Mon Sep 17 00:00:00 2001
2From: Mark Hatle <mark.hatle@windriver.com>
3Date: Mon, 20 Jan 2014 14:30:52 +0000
4Subject: [PATCH] Add mechanism to attempt install without failing
5
6In OpenEmbedded, for complementary and 'attemptonly' package processing,
7we need a way to instruct smart to try to install, but ignore any
8failures (usually conflicts).
9
10This option only works for the install operation.
11
12If a complementary install fails, an actual error occurred, one that
13we can't ignore without losing the entire attempted transaction. Keep
14this as an error so that we can catch these cases in the futre.
15
16Upstream-Status: Pending
17
18Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
19Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
20---
21 smart.py | 5 +++-
22 smart/commands/install.py | 5 ++++
23 smart/transaction.py | 65 +++++++++++++++++++++++++++++++++++------------
24 3 files changed, 58 insertions(+), 17 deletions(-)
25
26Index: smart-1.4.1/smart/commands/install.py
27===================================================================
28--- smart-1.4.1.orig/smart/commands/install.py
29+++ smart-1.4.1/smart/commands/install.py
30@@ -50,6 +50,8 @@ def option_parser():
31 parser = OptionParser(usage=USAGE,
32 description=DESCRIPTION,
33 examples=EXAMPLES)
34+ parser.add_option("--attempt", action="store_true",
35+ help=_("attempt to install packages, ignore failures"))
36 parser.add_option("--stepped", action="store_true",
37 help=_("split operation in steps"))
38 parser.add_option("--urls", action="store_true",
39@@ -80,6 +82,9 @@ def main(ctrl, opts):
40 if not opts.args:
41 raise Error, _("no package(s) given")
42
43+ if opts.attempt:
44+ sysconf.set("attempt-install", True, soft=True)
45+
46 if opts.explain:
47 sysconf.set("explain-changesets", True, soft=True)
48
49Index: smart-1.4.1/smart/transaction.py
50===================================================================
51--- smart-1.4.1.orig/smart/transaction.py
52+++ smart-1.4.1/smart/transaction.py
53@@ -555,6 +555,8 @@ class Transaction(object):
54 changeset.set(pkg, INSTALL)
55 isinst = changeset.installed
56
57+ attempt = sysconf.has("attempt-install", soft=True)
58+
59 # Remove packages conflicted by this one.
60 for cnf in pkg.conflicts:
61 for prv in cnf.providedby:
62@@ -564,11 +566,16 @@ class Transaction(object):
63 if not isinst(prvpkg):
64 locked[prvpkg] = (LOCKED_CONFLICT_BY, pkg)
65 continue
66- if prvpkg in locked:
67- raise Failed, _("Can't install %s: conflicted package "
68- "%s is locked") % (pkg, prvpkg)
69- self._remove(prvpkg, changeset, locked, pending, depth)
70- pending.append((PENDING_UPDOWN, prvpkg))
71+ if attempt:
72+ del changeset[pkg]
73+ raise Failed, _("Can't install %s: it conflicts with package "
74+ "%s") % (pkg, prvpkg)
75+ else:
76+ if prvpkg in locked:
77+ raise Failed, _("Can't install %s: conflicted package "
78+ "%s is locked") % (pkg, prvpkg)
79+ self._remove(prvpkg, changeset, locked, pending, depth)
80+ pending.append((PENDING_UPDOWN, prvpkg))
81
82 # Remove packages conflicting with this one.
83 for prv in pkg.provides:
84@@ -579,12 +586,18 @@ class Transaction(object):
85 if not isinst(cnfpkg):
86 locked[cnfpkg] = (LOCKED_CONFLICT, pkg)
87 continue
88- if cnfpkg in locked:
89+ if attempt:
90+ del changeset[pkg]
91 raise Failed, _("Can't install %s: it's conflicted by "
92- "the locked package %s") \
93- % (pkg, cnfpkg)
94- self._remove(cnfpkg, changeset, locked, pending, depth)
95- pending.append((PENDING_UPDOWN, cnfpkg))
96+ "the package %s") \
97+ % (pkg, cnfpkg)
98+ else:
99+ if cnfpkg in locked:
100+ raise Failed, _("Can't install %s: it's conflicted by "
101+ "the locked package %s") \
102+ % (pkg, cnfpkg)
103+ self._remove(cnfpkg, changeset, locked, pending, depth)
104+ pending.append((PENDING_UPDOWN, cnfpkg))
105
106 # Remove packages with the same name that can't
107 # coexist with this one.
108@@ -594,10 +607,15 @@ class Transaction(object):
109 if not isinst(namepkg):
110 locked[namepkg] = (LOCKED_NO_COEXIST, pkg)
111 continue
112- if namepkg in locked:
113+ if attempt:
114+ del changeset[pkg]
115 raise Failed, _("Can't install %s: it can't coexist "
116 "with %s") % (pkg, namepkg)
117- self._remove(namepkg, changeset, locked, pending, depth)
118+ else:
119+ if namepkg in locked:
120+ raise Failed, _("Can't install %s: it can't coexist "
121+ "with %s") % (pkg, namepkg)
122+ self._remove(namepkg, changeset, locked, pending, depth)
123
124 # Install packages required by this one.
125 for req in pkg.requires + pkg.recommends:
126@@ -1176,6 +1194,8 @@ class Transaction(object):
127
128 self._policy.runStarting()
129
130+ attempt = sysconf.has("attempt-install", soft=True)
131+
132 try:
133 changeset = self._changeset.copy()
134 isinst = changeset.installed
135@@ -1190,7 +1210,11 @@ class Transaction(object):
136 locked[pkg] = (LOCKED_KEEP, None)
137 elif op is INSTALL:
138 if not isinst(pkg) and pkg in locked:
139- raise Failed, _("Can't install %s: it's locked") % pkg
140+ if attempt:
141+ iface.warning(_("Can't install %s: it's locked") % pkg)
142+ del changeset[pkg]
143+ else:
144+ raise Failed, _("Can't install %s: it's locked") % pkg
145 changeset.set(pkg, INSTALL)
146 locked[pkg] = (LOCKED_INSTALL, None)
147 elif op is REMOVE:
148@@ -1216,9 +1240,18 @@ class Transaction(object):
149 else:
150 op = REMOVE
151 if op is INSTALL or op is REINSTALL:
152- self._install(pkg, changeset, locked, pending)
153- if pkg in changeset:
154- changeset.setRequested(pkg, True)
155+ try:
156+ self._install(pkg, changeset, locked, pending)
157+ if pkg in changeset:
158+ changeset.setRequested(pkg, True)
159+ except Failed, e:
160+ if attempt:
161+ iface.warning(_("Can't install %s: %s") % (pkg, e))
162+ if pkg in changeset:
163+ del changeset[pkg]
164+ continue
165+ else:
166+ raise Failed, e
167 elif op is REMOVE:
168 self._remove(pkg, changeset, locked, pending)
169 elif op is UPGRADE:
170Index: smart-1.4.1/smart/backends/rpm/pm.py
171===================================================================
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):