diff options
Diffstat (limited to 'meta/recipes-devtools/python/python-smartpm/smart-attempt.patch')
| -rw-r--r-- | meta/recipes-devtools/python/python-smartpm/smart-attempt.patch | 185 |
1 files changed, 0 insertions, 185 deletions
diff --git a/meta/recipes-devtools/python/python-smartpm/smart-attempt.patch b/meta/recipes-devtools/python/python-smartpm/smart-attempt.patch deleted file mode 100644 index e1182041bc..0000000000 --- a/meta/recipes-devtools/python/python-smartpm/smart-attempt.patch +++ /dev/null | |||
| @@ -1,185 +0,0 @@ | |||
| 1 | From b105e7fe812da3ccaf7155c0fe14c8728b0d39a5 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Mark Hatle <mark.hatle@windriver.com> | ||
| 3 | Date: Mon, 20 Jan 2014 14:30:52 +0000 | ||
| 4 | Subject: [PATCH] Add mechanism to attempt install without failing | ||
| 5 | |||
| 6 | In OpenEmbedded, for complementary and 'attemptonly' package processing, | ||
| 7 | we need a way to instruct smart to try to install, but ignore any | ||
| 8 | failures (usually conflicts). | ||
| 9 | |||
| 10 | This option only works for the install operation. | ||
| 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 | |||
| 16 | Upstream-Status: Pending | ||
| 17 | |||
| 18 | Signed-off-by: Mark Hatle <mark.hatle@windriver.com> | ||
| 19 | Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> | ||
| 20 | --- | ||
| 21 | backends/rpm/pm.py | 35 ++++++++++++++++++++++++++++++++++- | ||
| 22 | transaction.py | 50 +++++++++++++++++++++++++++++++++++++------------- | ||
| 23 | 2 files changed, 71 insertions(+), 14 deletions(-) | ||
| 24 | |||
| 25 | diff --git a/smart/backends/rpm/pm.py b/smart/backends/rpm/pm.py | ||
| 26 | index 9bbd952..ba6405a 100644 | ||
| 27 | --- a/smart/backends/rpm/pm.py | ||
| 28 | +++ b/smart/backends/rpm/pm.py | ||
| 29 | @@ -241,15 +241,56 @@ class RPMPackageManager(PackageManager): | ||
| 30 | cb = RPMCallback(prog, upgradednames) | ||
| 31 | cb.grabOutput(True) | ||
| 32 | probs = None | ||
| 33 | + retry = 0 | ||
| 34 | try: | ||
| 35 | probs = ts.run(cb, None) | ||
| 36 | finally: | ||
| 37 | del getTS.ts | ||
| 38 | cb.grabOutput(False) | ||
| 39 | + # If there are file conflicts, and we're attempting installation, | ||
| 40 | + # remove conflicting packages from the transaction and retry | ||
| 41 | + # If there are other problems returned by ts.run(), that are not | ||
| 42 | + # linked with packages/files conflicts (the returned list is empty), | ||
| 43 | + # then don't retry | ||
| 44 | + if (probs is not None) and (len(probs) != 0) and sysconf.has("attempt-install", soft=True): | ||
| 45 | + def remove_conflict(pkgNEVR): | ||
| 46 | + for key in changeset.keys(): | ||
| 47 | + if pkgNEVR == str(key): | ||
| 48 | + del changeset[key] | ||
| 49 | + del pkgpaths[key] | ||
| 50 | + iface.warning("Removing %s due to file %s conflicting with %s" % (pkgNEVR, fname, altNEVR)) | ||
| 51 | + break | ||
| 52 | + | ||
| 53 | + retry = 1 | ||
| 54 | + for prob in probs: | ||
| 55 | + if prob[1][0] == rpm.RPMPROB_NEW_FILE_CONFLICT: | ||
| 56 | + msg = prob[0].split() | ||
| 57 | + fname = msg[1] | ||
| 58 | + pkgNEVR = msg[7] | ||
| 59 | + altNEVR = msg[9] | ||
| 60 | + pkgNEVR = pkgNEVR.rsplit('.', 1)[0] + '@' + pkgNEVR.rsplit('.', 1)[1] | ||
| 61 | + altNEVR = altNEVR.rsplit('.', 1)[0] + '@' + altNEVR.rsplit('.', 1)[1] | ||
| 62 | + remove_conflict(pkgNEVR) | ||
| 63 | + elif prob[1][0] == rpm.RPMPROB_FILE_CONFLICT: | ||
| 64 | + msg = prob[0].split() | ||
| 65 | + fname = msg[1] | ||
| 66 | + pkgNEVR = msg[5] | ||
| 67 | + altNEVR = msg[11] | ||
| 68 | + pkgNEVR = pkgNEVR.rsplit('.', 1)[0] + '@' + pkgNEVR.rsplit('.', 1)[1] | ||
| 69 | + altNEVR = altNEVR.rsplit('.', 1)[0] + '@' + altNEVR.rsplit('.', 1)[1] | ||
| 70 | + remove_conflict(pkgNEVR) | ||
| 71 | + else: | ||
| 72 | + retry = 0 | ||
| 73 | + | ||
| 74 | prog.setDone() | ||
| 75 | - if probs is not None: | ||
| 76 | + # If there are other problems than packages/files conflicts | ||
| 77 | + # returned by ts.run(), the returned list is empty, and if | ||
| 78 | + # we're only attempting installation, then don't raise any error | ||
| 79 | + if (probs is not None) and ((len(probs) != 0) or not sysconf.has("attempt-install", soft=True)) and (not retry): | ||
| 80 | raise Error, "\n".join([x[0] for x in probs]) | ||
| 81 | prog.stop() | ||
| 82 | + if retry and len(changeset): | ||
| 83 | + self.commit(changeset, pkgpaths) | ||
| 84 | |||
| 85 | class RPMCallback: | ||
| 86 | def __init__(self, prog, upgradednames): | ||
| 87 | diff --git a/smart/transaction.py b/smart/transaction.py | ||
| 88 | index 4b90cb7..3e043e9 100644 | ||
| 89 | --- a/smart/transaction.py | ||
| 90 | +++ b/smart/transaction.py | ||
| 91 | @@ -555,6 +555,8 @@ class Transaction(object): | ||
| 92 | changeset.set(pkg, INSTALL) | ||
| 93 | isinst = changeset.installed | ||
| 94 | |||
| 95 | + attempt = sysconf.has("attempt-install", soft=True) | ||
| 96 | + | ||
| 97 | # Remove packages conflicted by this one. | ||
| 98 | for cnf in pkg.conflicts: | ||
| 99 | for prv in cnf.providedby: | ||
| 100 | @@ -564,11 +566,16 @@ class Transaction(object): | ||
| 101 | if not isinst(prvpkg): | ||
| 102 | locked[prvpkg] = (LOCKED_CONFLICT_BY, pkg) | ||
| 103 | continue | ||
| 104 | - if prvpkg in locked: | ||
| 105 | - raise Failed, _("Can't install %s: conflicted package " | ||
| 106 | - "%s is locked") % (pkg, prvpkg) | ||
| 107 | - self._remove(prvpkg, changeset, locked, pending, depth) | ||
| 108 | - pending.append((PENDING_UPDOWN, prvpkg)) | ||
| 109 | + if attempt: | ||
| 110 | + del changeset[pkg] | ||
| 111 | + raise Failed, _("Can't install %s: it conflicts with package " | ||
| 112 | + "%s") % (pkg, prvpkg) | ||
| 113 | + else: | ||
| 114 | + if prvpkg in locked: | ||
| 115 | + raise Failed, _("Can't install %s: conflicted package " | ||
| 116 | + "%s is locked") % (pkg, prvpkg) | ||
| 117 | + self._remove(prvpkg, changeset, locked, pending, depth) | ||
| 118 | + pending.append((PENDING_UPDOWN, prvpkg)) | ||
| 119 | |||
| 120 | # Remove packages conflicting with this one. | ||
| 121 | for prv in pkg.provides: | ||
| 122 | @@ -579,12 +586,18 @@ class Transaction(object): | ||
| 123 | if not isinst(cnfpkg): | ||
| 124 | locked[cnfpkg] = (LOCKED_CONFLICT, pkg) | ||
| 125 | continue | ||
| 126 | - if cnfpkg in locked: | ||
| 127 | + if attempt: | ||
| 128 | + del changeset[pkg] | ||
| 129 | raise Failed, _("Can't install %s: it's conflicted by " | ||
| 130 | - "the locked package %s") \ | ||
| 131 | - % (pkg, cnfpkg) | ||
| 132 | - self._remove(cnfpkg, changeset, locked, pending, depth) | ||
| 133 | - pending.append((PENDING_UPDOWN, cnfpkg)) | ||
| 134 | + "the package %s") \ | ||
| 135 | + % (pkg, cnfpkg) | ||
| 136 | + else: | ||
| 137 | + if cnfpkg in locked: | ||
| 138 | + raise Failed, _("Can't install %s: it's conflicted by " | ||
| 139 | + "the locked package %s") \ | ||
| 140 | + % (pkg, cnfpkg) | ||
| 141 | + self._remove(cnfpkg, changeset, locked, pending, depth) | ||
| 142 | + pending.append((PENDING_UPDOWN, cnfpkg)) | ||
| 143 | |||
| 144 | # Remove packages with the same name that can't | ||
| 145 | # coexist with this one. | ||
| 146 | @@ -594,10 +607,15 @@ class Transaction(object): | ||
| 147 | if not isinst(namepkg): | ||
| 148 | locked[namepkg] = (LOCKED_NO_COEXIST, pkg) | ||
| 149 | continue | ||
| 150 | - if namepkg in locked: | ||
| 151 | + if attempt: | ||
| 152 | + del changeset[pkg] | ||
| 153 | raise Failed, _("Can't install %s: it can't coexist " | ||
| 154 | "with %s") % (pkg, namepkg) | ||
| 155 | - self._remove(namepkg, changeset, locked, pending, depth) | ||
| 156 | + else: | ||
| 157 | + if namepkg in locked: | ||
| 158 | + raise Failed, _("Can't install %s: it can't coexist " | ||
| 159 | + "with %s") % (pkg, namepkg) | ||
| 160 | + self._remove(namepkg, changeset, locked, pending, depth) | ||
| 161 | |||
| 162 | # Install packages required by this one. | ||
| 163 | for req in pkg.requires + pkg.recommends: | ||
| 164 | @@ -1176,6 +1194,8 @@ class Transaction(object): | ||
| 165 | |||
| 166 | self._policy.runStarting() | ||
| 167 | |||
| 168 | + attempt = sysconf.has("attempt-install", soft=True) | ||
| 169 | + | ||
| 170 | try: | ||
| 171 | changeset = self._changeset.copy() | ||
| 172 | isinst = changeset.installed | ||
| 173 | @@ -1190,7 +1210,11 @@ class Transaction(object): | ||
| 174 | locked[pkg] = (LOCKED_KEEP, None) | ||
| 175 | elif op is INSTALL: | ||
| 176 | if not isinst(pkg) and pkg in locked: | ||
| 177 | - raise Failed, _("Can't install %s: it's locked") % pkg | ||
| 178 | + if attempt: | ||
| 179 | + iface.warning(_("Can't install %s: it's locked") % pkg) | ||
| 180 | + del changeset[pkg] | ||
| 181 | + else: | ||
| 182 | + raise Failed, _("Can't install %s: it's locked") % pkg | ||
| 183 | changeset.set(pkg, INSTALL) | ||
| 184 | locked[pkg] = (LOCKED_INSTALL, None) | ||
| 185 | elif op is REMOVE: | ||
