From 7ee23804a06f81476cc2b31a6db11b52d7af764e Mon Sep 17 00:00:00 2001 From: Mark Hatle Date: Mon, 20 Jan 2014 14:30:52 +0000 Subject: [PATCH] Add mechanism to attempt install without failing In OpenEmbedded, for complementary and 'attemptonly' package processing, we need a way to instruct smart to try to install, but ignore any failures (usually conflicts). This option only works for the install operation. Upstream-Status: Pending Signed-off-by: Mark Hatle Signed-off-by: Paul Eggleton --- smart/commands/install.py | 5 ++++ smart/transaction.py | 65 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 54 insertions(+), 16 deletions(-) diff --git a/smart/commands/install.py b/smart/commands/install.py index 590222c..6ef9682 100644 --- a/smart/commands/install.py +++ b/smart/commands/install.py @@ -50,6 +50,8 @@ def option_parser(): parser = OptionParser(usage=USAGE, description=DESCRIPTION, examples=EXAMPLES) + parser.add_option("--attempt", action="store_true", + help=_("attempt to install packages, ignore failures")) parser.add_option("--stepped", action="store_true", help=_("split operation in steps")) parser.add_option("--urls", action="store_true", @@ -80,6 +82,9 @@ def main(ctrl, opts): if not opts.args: raise Error, _("no package(s) given") + if opts.attempt: + sysconf.set("attempt-install", True, soft=True) + if opts.explain: sysconf.set("explain-changesets", True, soft=True) diff --git a/smart/transaction.py b/smart/transaction.py index 5730a42..e3e61c6 100644 --- a/smart/transaction.py +++ b/smart/transaction.py @@ -555,6 +555,8 @@ class Transaction(object): changeset.set(pkg, INSTALL) isinst = changeset.installed + attempt = sysconf.has("attempt-install", soft=True) + # Remove packages conflicted by this one. for cnf in pkg.conflicts: for prv in cnf.providedby: @@ -564,11 +566,16 @@ class Transaction(object): if not isinst(prvpkg): locked[prvpkg] = (LOCKED_CONFLICT_BY, pkg) continue - if prvpkg in locked: - raise Failed, _("Can't install %s: conflicted package " - "%s is locked") % (pkg, prvpkg) - self._remove(prvpkg, changeset, locked, pending, depth) - pending.append((PENDING_UPDOWN, prvpkg)) + if attempt: + del changeset[pkg] + raise Failed, _("Can't install %s: it conflicts with package " + "%s") % (pkg, prvpkg) + else: + if prvpkg in locked: + raise Failed, _("Can't install %s: conflicted package " + "%s is locked") % (pkg, prvpkg) + self._remove(prvpkg, changeset, locked, pending, depth) + pending.append((PENDING_UPDOWN, prvpkg)) # Remove packages conflicting with this one. for prv in pkg.provides: @@ -579,12 +586,18 @@ class Transaction(object): if not isinst(cnfpkg): locked[cnfpkg] = (LOCKED_CONFLICT, pkg) continue - if cnfpkg in locked: + if attempt: + del changeset[pkg] raise Failed, _("Can't install %s: it's conflicted by " - "the locked package %s") \ - % (pkg, cnfpkg) - self._remove(cnfpkg, changeset, locked, pending, depth) - pending.append((PENDING_UPDOWN, cnfpkg)) + "the package %s") \ + % (pkg, cnfpkg) + else: + if cnfpkg in locked: + raise Failed, _("Can't install %s: it's conflicted by " + "the locked package %s") \ + % (pkg, cnfpkg) + self._remove(cnfpkg, changeset, locked, pending, depth) + pending.append((PENDING_UPDOWN, cnfpkg)) # Remove packages with the same name that can't # coexist with this one. @@ -594,10 +607,15 @@ class Transaction(object): if not isinst(namepkg): locked[namepkg] = (LOCKED_NO_COEXIST, pkg) continue - if namepkg in locked: + if attempt: + del changeset[pkg] raise Failed, _("Can't install %s: it can't coexist " "with %s") % (pkg, namepkg) - self._remove(namepkg, changeset, locked, pending, depth) + else: + if namepkg in locked: + raise Failed, _("Can't install %s: it can't coexist " + "with %s") % (pkg, namepkg) + self._remove(namepkg, changeset, locked, pending, depth) # Install packages required by this one. for req in pkg.requires + pkg.recommends: @@ -1176,6 +1194,8 @@ class Transaction(object): self._policy.runStarting() + attempt = sysconf.has("attempt-install", soft=True) + try: changeset = self._changeset.copy() isinst = changeset.installed @@ -1190,7 +1210,11 @@ class Transaction(object): locked[pkg] = (LOCKED_KEEP, None) elif op is INSTALL: if not isinst(pkg) and pkg in locked: - raise Failed, _("Can't install %s: it's locked") % pkg + if attempt: + iface.warning(_("Can't install %s: it's locked") % pkg) + del changeset[pkg] + else: + raise Failed, _("Can't install %s: it's locked") % pkg changeset.set(pkg, INSTALL) locked[pkg] = (LOCKED_INSTALL, None) elif op is REMOVE: @@ -1216,9 +1240,18 @@ class Transaction(object): else: op = REMOVE if op is INSTALL or op is REINSTALL: - self._install(pkg, changeset, locked, pending) - if pkg in changeset: - changeset.setRequested(pkg, True) + try: + self._install(pkg, changeset, locked, pending) + if pkg in changeset: + changeset.setRequested(pkg, True) + except Failed, e: + if attempt: + iface.warning(_("Can't install %s: %s") % (pkg, e)) + if pkg in changeset: + del changeset[pkg] + continue + else: + raise Failed, e elif op is REMOVE: self._remove(pkg, changeset, locked, pending) elif op is UPGRADE: -- 1.8.4.2