python-smartpm: remove the recipe

(From OE-Core rev: 9ff0e8b4012f1e68f6caebc3027f9d1bada00f13)

Signed-off-by: Alexander Kanavin <alexander.kanavin@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Alexander Kanavin 2017-01-02 15:14:41 +02:00 committed by Richard Purdie
parent b70f96a17f
commit 372bcd3c97
15 changed files with 0 additions and 1355 deletions

View File

@ -1,38 +0,0 @@
channels/rpm_sys: use md5sum instead of mtime as the digest
Use the internal getFileDigest() function (which defaults to md5) instead of
mtime for getting the file digest. On some systems mtime proved to be
unreliable because of delayed update. This caused smart to miss rpm db updates
and thus get its understanding of installed packages out of sync.
Upstream-Status: Pending
Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com>
---
smart/channels/rpm_sys.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/smart/channels/rpm_sys.py b/smart/channels/rpm_sys.py
index b9fda27..6f1fe94 100644
--- a/smart/channels/rpm_sys.py
+++ b/smart/channels/rpm_sys.py
@@ -22,6 +22,7 @@
from smart.backends.rpm.header import RPMDBLoader
from smart.backends.rpm.base import getTS, rpm_join_dbpath
from smart.channel import PackageChannel
+from smart.util.filetools import getFileDigest
from smart import *
import os
@@ -35,7 +36,7 @@ class RPMSysChannel(PackageChannel):
dbdir = rpm_join_dbpath(sysconf.get("rpm-root", "/"),
sysconf.get("rpm-dbpath", "var/lib/rpm"))
path = os.path.join(dbdir, "Packages")
- digest = os.path.getmtime(path)
+ digest = getFileDigest(path)
if digest == self._digest:
return True
self.removeLoaders()
--
2.6.6

View File

@ -1,47 +0,0 @@
From 01e51afd03131947f8d74b9a23fdbc0078249499 Mon Sep 17 00:00:00 2001
From: Mariano Lopez <mariano.lopez@linux.intel.com>
Date: Wed, 3 Aug 2016 07:47:09 +0000
Subject: [PATCH] fetcher.py: Add debugging when targetpath is empty
There are several errors when openining files or manipulating
path strings, those errors point targetpath passed to
setSucceeded() is empty. This patch won't solve the problems,
but will add debugging to give an idea why is failing.
Upstream-Status: Inappropriate [debugging]
Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com>
---
smart/fetcher.py | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/smart/fetcher.py b/smart/fetcher.py
index dd3ff6b..64aa979 100644
--- a/smart/fetcher.py
+++ b/smart/fetcher.py
@@ -594,6 +594,22 @@ class FetchItem(object):
self._eta = None
def setSucceeded(self, targetpath, fetchedsize=0):
+ # It seems the in some odd cases targetpath here
+ # is empty, this will lead to bugs in several places
+ if not targetpath:
+ import traceback
+ tb_str = ""
+ for threadId, stack in sys._current_frames().items():
+ tb_str += '\nThreadID: %s' % threadId
+ for filename, lineno, name, line in traceback.extract_stack(stack):
+ tb_str += '\nFile: "%s", line %d, in %s' % (filename, lineno, name)
+ if line:
+ tb_str += "\n %s" % line.strip()
+ error_string = ["No file path specified",
+ "URL: %s" % self._url,
+ "Status: %s" % self._status,
+ "Traceback: %s" % tb_str]
+ raise Error, _("\n".join(error_string))
if self._status is not FAILED:
self._status = SUCCEEDED
self._targetpath = targetpath
--
2.6.6

View File

@ -1,35 +0,0 @@
python-smartpm: Add checking for "rpm-ignoresize" option
The do_rootfs takes a very long time when build host has mounted many NFS
devices. syscall lstat() was being called on every filesystem mounted on the
build host during building.
The reason for the lstat() is that rpm is verifying that enough free disk space
is available to do the install. However, since the install is into the target
rootfs it should not matter how much free space there is in the host mounts.
Add checking for "rpm-ignoresize", by it, smart can make whether RPM skip
checking for diskspace when install a rpm package.
Upstream-Status: Pending
Signed-off-by: wenlin.kang <wenlin.kang@windriver.com>
Signed-off-by: Chong Lu <Chong.Lu@windriver.com>
---
smart/backends/rpm/pm.py | 4 ++++
1 file changed, 4 insertions(+)
Index: git/smart/backends/rpm/pm.py
===================================================================
--- git.orig/smart/backends/rpm/pm.py
+++ git/smart/backends/rpm/pm.py
@@ -233,6 +233,11 @@ class RPMPackageManager(PackageManager):
if sysconf.get("rpm-order"):
ts.order()
probfilter = rpm.RPMPROB_FILTER_OLDPACKAGE
+
+ if sysconf.get("rpm-ignoresize", False):
+ probfilter |= rpm.RPMPROB_FILTER_DISKNODES
+ probfilter |= rpm.RPMPROB_FILTER_DISKSPACE
+
if force or reinstall:
probfilter |= rpm.RPMPROB_FILTER_REPLACEPKG
probfilter |= rpm.RPMPROB_FILTER_REPLACEOLDFILES

View File

@ -1,54 +0,0 @@
From a74a9a9eb9d75964a0e978950e8b191d7a18d763 Mon Sep 17 00:00:00 2001
From: Paul Eggleton <paul.eggleton@linux.intel.com>
Date: Fri, 5 Jun 2015 17:07:16 +0100
Subject: [PATCH] smart: change "is already installed" message from warning to
info
This doesn't need to be a warning.
Upstream-Status: Pending
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
---
smart/commands/install.py | 4 ++--
smart/interfaces/text/interactive.py | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/smart/commands/install.py b/smart/commands/install.py
index 6ef9682..80d456b 100644
--- a/smart/commands/install.py
+++ b/smart/commands/install.py
@@ -152,7 +152,7 @@ def main(ctrl, opts):
for obj in results:
for pkg in obj.packages:
if pkg.installed:
- iface.warning(_("%s (for %s) is already installed")
+ iface.info(_("%s (for %s) is already installed")
% (pkg, arg))
installed = True
break
@@ -184,7 +184,7 @@ def main(ctrl, opts):
for name in names:
pkg = names[name][0]
if pkg.installed:
- iface.warning(_("%s is already installed") % pkg)
+ iface.info(_("%s is already installed") % pkg)
else:
trans.enqueue(pkg, INSTALL)
diff --git a/smart/interfaces/text/interactive.py b/smart/interfaces/text/interactive.py
index 9865584..190867b 100644
--- a/smart/interfaces/text/interactive.py
+++ b/smart/interfaces/text/interactive.py
@@ -278,7 +278,7 @@ class Interpreter(Cmd):
for name in names:
pkg = names[name][0]
if pkg.installed:
- iface.warning(_("%s is already installed") % pkg)
+ iface.info(_("%s is already installed") % pkg)
else:
found = True
transaction.enqueue(pkg, INSTALL)
--
2.1.0

View File

@ -1,158 +0,0 @@
Sadly, smart is not deterministic so the same build can go down multiple different
pathways. We'd expect to see the same warnings however depending on the pathway
taken, it may or may not warn, particularly with Recommends since they're optional.
For example, where a Recommended package is available but has Conflicts, we'd expect
to see an warning that we couldn't install it. Some code paths silently hide this
(its a LOCKED_CONFLICT). We add printing of warnings for this case.
Also, if there are two compatible feeds available (e.g. i586 and core2_32), this
changes the code path from direct _install() to _pending() since there are multiple
providers. This patch adds warning handling to _pending() so we don't hit hard
failures there. This is as seen with the mysterious libspeexdsp failures for x86-lsb
on the autobuilder.
Upstream-Status: Pending
RP
2015/7/16
Index: git/smart/transaction.py
===================================================================
--- git.orig/smart/transaction.py
+++ git/smart/transaction.py
@@ -651,13 +651,14 @@ class Transaction(object):
if not prvpkgs:
# No packages provide it at all. Give up.
+
+ reasons = []
+ for prv in req.providedby:
+ for prvpkg in prv.packages:
+ lockedres = lockedpkgs.get(prvpkg, None)
+ if lockedres:
+ reasons.append(lock_reason(prvpkg, lockedres))
if reqrequired:
- reasons = []
- for prv in req.providedby:
- for prvpkg in prv.packages:
- lockedres = lockedpkgs.get(prvpkg, None)
- if lockedres:
- reasons.append(lock_reason(prvpkg, lockedres))
if reasons:
raise Failed, _("Can't install %s: unable to install provider for %s:\n %s") % \
(pkg, req, '\n '.join(reasons))
@@ -665,7 +666,11 @@ class Transaction(object):
raise Failed, _("Can't install %s: no package provides %s") % \
(pkg, req)
else:
+ if reasons:
+ iface.warning(_("Can't install %s: unable to install provider for %s:\n %s") % \
+ (pkg, req, '\n '.join(reasons)))
+
# It's only a recommend, skip
continue
if len(prvpkgs) == 1:
@@ -846,6 +852,14 @@ class Transaction(object):
isinst = changeset.installed
getweight = self._policy.getWeight
+ attempt = sysconf.has("attempt-install", soft=True)
+
+ def handle_failure(msg):
+ if attempt:
+ iface.warning(msg)
+ else:
+ raise Failed, msg
+
updown = []
while pending:
item = pending.pop(0)
@@ -870,8 +884,9 @@ class Transaction(object):
if not prvpkgs:
# No packages provide it at all. Give up.
- raise Failed, _("Can't install %s: no package "
- "provides %s") % (pkg, req)
+ handle_failure(_("Can't install %s: no package "
+ "provides %s") % (pkg, req))
+ continue
if len(prvpkgs) > 1:
# More than one package provide it. We use _pending here,
@@ -894,9 +909,10 @@ class Transaction(object):
keeporder, cs, lk))
keeporder += 0.000001
if not alternatives:
- raise Failed, _("Can't install %s: all packages "
+ handle_failure(_("Can't install %s: all packages "
"providing %s failed to install:\n%s")\
- % (pkg, req, "\n".join(failures))
+ % (pkg, req, "\n".join(failures)))
+ continue
alternatives.sort()
changeset.setState(alternatives[0][1])
if len(alternatives) == 1:
@@ -954,18 +970,20 @@ class Transaction(object):
for reqpkg in reqpkgs:
if reqpkg in locked and isinst(reqpkg):
- raise Failed, _("Can't remove %s: requiring "
+ handle_failure(_("Can't remove %s: requiring "
"package %s is locked") % \
- (pkg, reqpkg)
+ (pkg, reqpkg))
+ continue
for reqpkg in reqpkgs:
# We check again, since other actions may have
# changed their state.
if not isinst(reqpkg):
continue
if reqpkg in locked:
- raise Failed, _("Can't remove %s: requiring "
+ handle_failure(_("Can't remove %s: requiring "
"package %s is locked") % \
- (pkg, reqpkg)
+ (pkg, reqpkg))
+ continue
self._remove(reqpkg, changeset, locked,
pending, depth)
continue
@@ -978,12 +996,14 @@ class Transaction(object):
try:
for reqpkg in reqpkgs:
if reqpkg in locked and isinst(reqpkg):
- raise Failed, _("%s is locked") % reqpkg
+ handle_failure(_("%s is locked") % reqpkg)
+ continue
for reqpkg in reqpkgs:
if not cs.installed(reqpkg):
continue
if reqpkg in lk:
- raise Failed, _("%s is locked") % reqpkg
+ handle_failure(_("%s is locked") % reqpkg)
+ continue
self._remove(reqpkg, cs, lk, None, depth)
except Failed, e:
failures.append(unicode(e))
@@ -991,9 +1011,10 @@ class Transaction(object):
alternatives.append((getweight(cs), cs, lk))
if not alternatives:
- raise Failed, _("Can't install %s: all packages providing "
+ handle_failure(_("Can't install %s: all packages providing "
"%s failed to install:\n%s") \
- % (pkg, prv, "\n".join(failures))
+ % (pkg, prv, "\n".join(failures)))
+ continue
alternatives.sort()
changeset.setState(alternatives[0][1])
@@ -1246,6 +1267,7 @@ class Transaction(object):
changeset.setRequested(pkg, True)
except Failed, e:
if sysconf.has("attempt-install", soft=True):
+ iface.warning(_("Can't install %s: %s") % (pkg, str(e)))
if pkg in changeset:
del changeset[pkg]
continue

View File

@ -1,185 +0,0 @@
From b105e7fe812da3ccaf7155c0fe14c8728b0d39a5 Mon Sep 17 00:00:00 2001
From: Mark Hatle <mark.hatle@windriver.com>
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.
If a complementary install fails, an actual error occurred, one that
we can't ignore without losing the entire attempted transaction. Keep
this as an error so that we can catch these cases in the futre.
Upstream-Status: Pending
Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
---
backends/rpm/pm.py | 35 ++++++++++++++++++++++++++++++++++-
transaction.py | 50 +++++++++++++++++++++++++++++++++++++-------------
2 files changed, 71 insertions(+), 14 deletions(-)
diff --git a/smart/backends/rpm/pm.py b/smart/backends/rpm/pm.py
index 9bbd952..ba6405a 100644
--- a/smart/backends/rpm/pm.py
+++ b/smart/backends/rpm/pm.py
@@ -241,15 +241,56 @@ class RPMPackageManager(PackageManager):
cb = RPMCallback(prog, upgradednames)
cb.grabOutput(True)
probs = None
+ retry = 0
try:
probs = ts.run(cb, None)
finally:
del getTS.ts
cb.grabOutput(False)
+ # If there are file conflicts, and we're attempting installation,
+ # remove conflicting packages from the transaction and retry
+ # If there are other problems returned by ts.run(), that are not
+ # linked with packages/files conflicts (the returned list is empty),
+ # then don't retry
+ if (probs is not None) and (len(probs) != 0) and sysconf.has("attempt-install", soft=True):
+ def remove_conflict(pkgNEVR):
+ for key in changeset.keys():
+ if pkgNEVR == str(key):
+ del changeset[key]
+ del pkgpaths[key]
+ iface.warning("Removing %s due to file %s conflicting with %s" % (pkgNEVR, fname, altNEVR))
+ break
+
+ retry = 1
+ for prob in probs:
+ if prob[1][0] == rpm.RPMPROB_NEW_FILE_CONFLICT:
+ msg = prob[0].split()
+ fname = msg[1]
+ pkgNEVR = msg[7]
+ altNEVR = msg[9]
+ pkgNEVR = pkgNEVR.rsplit('.', 1)[0] + '@' + pkgNEVR.rsplit('.', 1)[1]
+ altNEVR = altNEVR.rsplit('.', 1)[0] + '@' + altNEVR.rsplit('.', 1)[1]
+ remove_conflict(pkgNEVR)
+ elif prob[1][0] == rpm.RPMPROB_FILE_CONFLICT:
+ msg = prob[0].split()
+ fname = msg[1]
+ pkgNEVR = msg[5]
+ altNEVR = msg[11]
+ pkgNEVR = pkgNEVR.rsplit('.', 1)[0] + '@' + pkgNEVR.rsplit('.', 1)[1]
+ altNEVR = altNEVR.rsplit('.', 1)[0] + '@' + altNEVR.rsplit('.', 1)[1]
+ remove_conflict(pkgNEVR)
+ else:
+ retry = 0
+
prog.setDone()
- if probs is not None:
+ # If there are other problems than packages/files conflicts
+ # returned by ts.run(), the returned list is empty, and if
+ # we're only attempting installation, then don't raise any error
+ if (probs is not None) and ((len(probs) != 0) or not sysconf.has("attempt-install", soft=True)) and (not retry):
raise Error, "\n".join([x[0] for x in probs])
prog.stop()
+ if retry and len(changeset):
+ self.commit(changeset, pkgpaths)
class RPMCallback:
def __init__(self, prog, upgradednames):
diff --git a/smart/transaction.py b/smart/transaction.py
index 4b90cb7..3e043e9 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:

View File

@ -1,43 +0,0 @@
From ee05e55e84b53f4bb0d0baba13ca47a8f84b7cb4 Mon Sep 17 00:00:00 2001
From: Robert Yang <liezhi.yang@windriver.com>
Date: Wed, 30 Sep 2015 01:12:52 -0700
Subject: [PATCH] smart:cache.py: getPackages() matches name + arch
It only matched name ony in the past, for example:
smart install busybox (matched)
but:
smart install busybox@core2_64 (didn't match)
The installation is very slow when no match since it would seach all the
packages in the repo
This patch makes it match both.
Upstream-Status: Pending
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
smart/cache.py | 3 ++-
smart/ccache.c | 9 ++++++++-
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/smart/control.py b/smart/control.py
index d44abe7..f23a604 100644
--- a/smart/control.py
+++ b/smart/control.py
@@ -876,9 +876,13 @@ class Control(object):
objects = []
# If we find packages with exactly the given
- # name or name-version, use them.
- for pkg in self._cache.getPackages(s):
- if pkg.name == s or "%s-%s" % (pkg.name, pkg.version) == s:
+ # name, name-version, or name@arch, use them.
+ s_name = s
+ if "@" in s:
+ s_name = s.split("@")[0]
+ for pkg in self._cache.getPackages(s_name):
+ if pkg.name == s or "%s-%s" % (pkg.name, pkg.version) == s \
+ or "%s@%s" % (pkg.name, pkg.version.split('@')[1]) == s:
objects.append((1.0, pkg))
if not objects:

View File

@ -1,33 +0,0 @@
From 6d2363a705697f615d9e5af5d6703b291e618b46 Mon Sep 17 00:00:00 2001
From: Daniel Klauer <daniel.klauer@gin.de>
Date: Thu, 12 May 2016 17:55:01 +0200
Subject: [PATCH] Fix channel command --remove-all option parsing
Option.take_action() stores a list of options given for validation later.
It strips leading dashes and turns remaining dashes into underscores.
This list is what ensure_action() will compare its arguments against,
thus we must use underscores here.
Upstream-Status: Pending
Signed-off-by: Daniel Klauer <daniel.klauer@gin.de>
---
smart/commands/channel.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/smart/commands/channel.py b/smart/commands/channel.py
index 108f3f1..6234f69 100644
--- a/smart/commands/channel.py
+++ b/smart/commands/channel.py
@@ -164,7 +164,7 @@ def main(ctrl, opts):
opts.check_args_of_option("edit", 0)
opts.check_args_of_option("enable", -1)
opts.check_args_of_option("disable", -1)
- opts.ensure_action("channel", ["add", "set", "remove", "remove-all",
+ opts.ensure_action("channel", ["add", "set", "remove", "remove_all",
"list", "show", "yaml", "enable", "disable"])
opts.check_remaining_args()
--
1.9.1

View File

@ -1,24 +0,0 @@
Make CHANNELSDIR in smart empty, since this causes host contamination issues
on some RPM-based hosts on which smart is already installed.
[YOCTO #3881]
Upstream-Status: Inappropriate [embedded specific]
diff --git a/smart/plugins/channelsync.py b/smart/plugins/channelsync.py
index 3ba95ff..646d696 100644
--- a/smart/plugins/channelsync.py
+++ b/smart/plugins/channelsync.py
@@ -23,7 +23,11 @@ from smart.channel import *
from smart import *
import os
-CHANNELSDIR = "/etc/smart/channels/"
+# For now, we leave the definition of CHANNELSDIR empty. This prevents smart
+# from erroneously consider the build host's channels while setting up its
+# channels [YOCTO #3881]. If this feature will be used in the future, CHANNELSDIR
+# should be set to a proper value.
+CHANNELSDIR = ""
def syncChannels(channelsdir, force=None):

View File

@ -1,27 +0,0 @@
rpm or commands run by rpm can use output which isn't strictly acsii such
as quotation characters around expression which are character 0xe2.
Use utf-8 as an encoding rather than whatever the system suggests to
ensure smart copes with this rather than erroring with unicode errors.
RP 2016/5/19
Upstream-Status: Pending
Index: git/smart/backends/rpm/pm.py
===================================================================
--- git.orig/smart/backends/rpm/pm.py
+++ git/smart/backends/rpm/pm.py
@@ -32,11 +32,7 @@ from smart.pm import PackageManager
from smart import sysconf, iface, Error, _
-try:
- ENCODING = locale.getpreferredencoding()
-except locale.Error:
- ENCODING = "ascii"
-
+ENCODING = "utf-8"
def get_public_key(header):
return header.sprintf("%|DSAHEADER?{%{DSAHEADER:pgpsig}}:"

View File

@ -1,381 +0,0 @@
Handle recommended packages in core and rpm backends
Identify and store recommended packages in the cache, add a query option
to read them and ignore them if they are not present when installing.
Initial identification code from Mark Hatle <mark.hatle@windriver.com>.
Upstream-Status: Pending
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
diff --git a/smart/backends/rpm/base.py b/smart/backends/rpm/base.py
index 9332ea0..4fcfbee 100644
--- a/smart/backends/rpm/base.py
+++ b/smart/backends/rpm/base.py
@@ -225,6 +225,52 @@ class RPMPackage(Package):
break
else:
return False
+ srecs = fk(self.recommends)
+ orecs = fk(other.recommends)
+ if srecs != orecs:
+ for srec in srecs:
+ if srec.name[0] == "/" or srec in orecs:
+ continue
+ for orec in orecs:
+ if (srec.name == orec.name and
+ srec.relation == orec.relation and
+ checkver(srec.version, orec.version)):
+ break
+ else:
+ return False
+ for orec in orecs:
+ if orec.name[0] == "/" or orec in srecs:
+ continue
+ for srec in srecs:
+ if (srec.name == orec.name and
+ srec.relation == orec.relation and
+ checkver(srec.version, orec.version)):
+ break
+ else:
+ return False
+ srecs = fk(self.recommends)
+ orecs = fk(other.recommends)
+ if srecs != orecs:
+ for srec in srecs:
+ if srec.name[0] == "/" or srec in orecs:
+ continue
+ for orec in orecs:
+ if (srec.name == orec.name and
+ srec.relation == orec.relation and
+ checkver(srec.version, orec.version)):
+ break
+ else:
+ return False
+ for orec in orecs:
+ if orec.name[0] == "/" or orec in srecs:
+ continue
+ for srec in srecs:
+ if (srec.name == orec.name and
+ srec.relation == orec.relation and
+ checkver(srec.version, orec.version)):
+ break
+ else:
+ return False
return True
def coexists(self, other):
diff --git a/smart/ccache.c b/smart/ccache.c
index 7193185..8b66515 100644
--- a/smart/ccache.c
+++ b/smart/ccache.c
@@ -500,6 +500,46 @@ Package_equals(PackageObject *self, PackageObject *other)
}
}
+ ilen = 0;
+ jlen = 0;
+ for (i = 0; i != PyList_GET_SIZE(self->recommends); i++) {
+ PyObject *item = PyList_GET_ITEM(self->recommends, i);
+ if (!PyObject_IsInstance(item, (PyObject *)&Depends_Type)) {
+ PyErr_SetString(PyExc_TypeError, "Depends instance expected");
+ return NULL;
+ }
+ if (STR(((DependsObject *)item)->name)[0] != '/')
+ ilen += 1;
+ }
+ for (j = 0; j != PyList_GET_SIZE(other->recommends); j++) {
+ PyObject *item = PyList_GET_ITEM(other->recommends, j);
+ if (!PyObject_IsInstance(item, (PyObject *)&Depends_Type)) {
+ PyErr_SetString(PyExc_TypeError, "Depends instance expected");
+ return NULL;
+ }
+ if (STR(((DependsObject *)item)->name)[0] != '/')
+ jlen += 1;
+ }
+ if (ilen != jlen) {
+ ret = Py_False;
+ goto exit;
+ }
+
+ ilen = PyList_GET_SIZE(self->recommends);
+ jlen = PyList_GET_SIZE(other->recommends);
+ for (i = 0; i != ilen; i++) {
+ PyObject *item = PyList_GET_ITEM(self->recommends, i);
+ if (STR(((DependsObject *)item)->name)[0] != '/') {
+ for (j = 0; j != jlen; j++)
+ if (item == PyList_GET_ITEM(other->recommends, j))
+ break;
+ if (j == jlen) {
+ ret = Py_False;
+ goto exit;
+ }
+ }
+ }
+
exit:
Py_INCREF(ret);
return ret;
@@ -1813,6 +1853,59 @@ Loader_buildPackage(LoaderObject *self, PyObject *args)
}
}
+ /* if recargs: */
+ if (recargs) {
+ int i = 0;
+ int len = PyList_GET_SIZE(recargs);
+ /* pkg.recommends = [] */
+ Py_DECREF(pkgobj->recommends);
+ pkgobj->recommends = PyList_New(len);
+ /* for args in recargs: */
+ for (; i != len; i++) {
+ PyObject *args = PyList_GET_ITEM(recargs, i);
+ DependsObject *recobj;
+ PyObject *rec;
+
+ if (!PyTuple_Check(args)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Item in recargs is not a tuple");
+ return NULL;
+ }
+
+ /* rec = cache._objmap.get(args) */
+ rec = PyDict_GetItem(cache->_objmap, args);
+ recobj = (DependsObject *)rec;
+
+ /* if not rec: */
+ if (!rec) {
+ if (!PyTuple_Check(args) || PyTuple_GET_SIZE(args) < 2) {
+ PyErr_SetString(PyExc_ValueError, "Invalid recargs tuple");
+ return NULL;
+ }
+ /* rec = args[0](*args[1:]) */
+ callargs = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
+ rec = PyObject_CallObject(PyTuple_GET_ITEM(args, 0), callargs);
+ Py_DECREF(callargs);
+ if (!rec) return NULL;
+ recobj = (DependsObject *)rec;
+
+ /* cache._objmap[args] = rec */
+ PyDict_SetItem(cache->_objmap, args, rec);
+ Py_DECREF(rec);
+
+ /* cache._recommends.append(rec) */
+ PyList_Append(cache->_recommends, rec);
+ }
+
+ /* relpkgs.append(rec.packages) */
+ PyList_Append(relpkgs, recobj->packages);
+
+ /* pkg.recommends.append(rec) */
+ Py_INCREF(rec);
+ PyList_SET_ITEM(pkgobj->recommends, i, rec);
+ }
+ }
+
/* if upgargs: */
if (upgargs) {
int i = 0;
@@ -2592,6 +2685,16 @@ Cache_reset(CacheObject *self, PyObject *args)
if (PyList_Check(reqobj->providedby))
LIST_CLEAR(reqobj->providedby);
}
+ len = PyList_GET_SIZE(self->_recommends);
+ for (i = 0; i != len; i++) {
+ DependsObject *reqobj;
+ PyObject *req;
+ req = PyList_GET_ITEM(self->_recommends, i);
+ reqobj = (DependsObject *)req;
+ LIST_CLEAR(reqobj->packages);
+ if (PyList_Check(reqobj->providedby))
+ LIST_CLEAR(reqobj->providedby);
+ }
len = PyList_GET_SIZE(self->_upgrades);
for (i = 0; i != len; i++) {
DependsObject *upgobj;
@@ -2834,6 +2937,30 @@ Cache__reload(CacheObject *self, PyObject *args)
}
/*
+ for rec in pkg.recommends:
+ rec.packages.append(pkg)
+ if rec not in recommends:
+ recommends[rec] = True
+ objmap[rec.getInitArgs()] = rec
+ */
+ if (PyList_Check(pkg->recommends)) {
+ klen = PyList_GET_SIZE(pkg->recommends);
+ for (k = 0; k != klen; k++) {
+ PyObject *rec = PyList_GET_ITEM(pkg->recommends, k);
+ PyList_Append(((DependsObject *)rec)->packages,
+ (PyObject *)pkg);
+ if (!PyDict_GetItem(recommends, rec)) {
+ PyDict_SetItem(recommends, rec, Py_True);
+ args = PyObject_CallMethod(rec, "getInitArgs",
+ NULL);
+ if (!args) return NULL;
+ PyDict_SetItem(objmap, args, rec);
+ Py_DECREF(args);
+ }
+ }
+ }
+
+ /*
for upg in pkg.upgrades:
upg.packages.append(pkg)
if upg not in upgrades:
@@ -3097,6 +3224,47 @@ Cache_linkDeps(CacheObject *self, PyObject *args)
Py_DECREF(seq);
}
+ /* recnames = {} */
+ recnames = PyDict_New();
+ /* for rec in self._recommends: */
+ len = PyList_GET_SIZE(self->_recommends);
+ for (i = 0; i != len; i++) {
+ PyObject *rec = PyList_GET_ITEM(self->_recommends, i);
+
+ /* for name in rec.getMatchNames(): */
+ PyObject *names = PyObject_CallMethod(rec, "getMatchNames", NULL);
+ PyObject *seq = PySequence_Fast(names, "getMatchNames() returned "
+ "non-sequence object");
+ int nameslen;
+ if (!seq) return NULL;
+ nameslen = PySequence_Fast_GET_SIZE(seq);
+ for (j = 0; j != nameslen; j++) {
+ PyObject *name = PySequence_Fast_GET_ITEM(seq, j);
+
+ /* lst = recnames.get(name) */
+ lst = PyDict_GetItem(recnames, name);
+
+ /*
+ if lst:
+ lst.append(rec)
+ else:
+ recnames[name] = [rec]
+ */
+ if (lst) {
+ PyList_Append(lst, rec);
+ } else {
+ lst = PyList_New(1);
+ Py_INCREF(rec);
+ PyList_SET_ITEM(lst, 0, rec);
+ PyDict_SetItem(recnames, name, lst);
+ Py_DECREF(lst);
+ }
+ }
+
+ Py_DECREF(names);
+ Py_DECREF(seq);
+ }
+
/* upgnames = {} */
upgnames = PyDict_New();
/* for upg in self._upgrades: */
@@ -3286,6 +3454,56 @@ Cache_linkDeps(CacheObject *self, PyObject *args)
}
}
+ /* lst = recnames.get(prv.name) */
+ lst = PyDict_GetItem(recnames, prv->name);
+
+ /* if lst: */
+ if (lst) {
+ /* for rec in lst: */
+ int reclen = PyList_GET_SIZE(lst);
+ for (j = 0; j != reclen; j++) {
+ DependsObject *rec = (DependsObject *)PyList_GET_ITEM(lst, j);
+ /* if rec.matches(prv): */
+ PyObject *ret = PyObject_CallMethod((PyObject *)rec, "matches",
+ "O", (PyObject *)prv);
+ if (!ret) return NULL;
+ if (PyObject_IsTrue(ret)) {
+ /*
+ if rec.providedby:
+ rec.providedby.append(prv)
+ else:
+ rec.providedby = [prv]
+ */
+ if (PyList_Check(rec->providedby)) {
+ PyList_Append(rec->providedby, (PyObject *)prv);
+ } else {
+ PyObject *_lst = PyList_New(1);
+ Py_INCREF(prv);
+ PyList_SET_ITEM(_lst, 0, (PyObject *)prv);
+ Py_DECREF(rec->providedby);
+ rec->providedby = _lst;
+ }
+
+ /*
+ if prv.recommendedby:
+ prv.recommendedby.append(prv)
+ else:
+ prv.recommendedby = [prv]
+ */
+ if (PyList_Check(prv->recommendedby)) {
+ PyList_Append(prv->recommendedby, (PyObject *)rec);
+ } else {
+ PyObject *_lst = PyList_New(1);
+ Py_INCREF(rec);
+ PyList_SET_ITEM(_lst, 0, (PyObject *)rec);
+ Py_DECREF(prv->recommendedby);
+ prv->recommendedby = _lst;
+ }
+ }
+ Py_DECREF(ret);
+ }
+ }
+
/* lst = upgnames.get(prv.name) */
lst = PyDict_GetItem(upgnames, prv->name);
@@ -3821,6 +4094,21 @@ Cache__setstate__(CacheObject *self, PyObject *state)
}
/*
+ for rec in pkg.recommends:
+ rec.packages.append(pkg)
+ recommends[rec] = True
+ */
+ if (PyList_Check(pkgobj->recommends)) {
+ jlen = PyList_GET_SIZE(pkgobj->recommends);
+ for (j = 0; j != jlen; j++) {
+ PyObject *rec = PyList_GET_ITEM(pkgobj->recommends, j);
+ DependsObject *recobj = (DependsObject *)rec;
+ PyList_Append(recobj->packages, pkg);
+ PyDict_SetItem(recommends, rec, Py_True);
+ }
+ }
+
+ /*
for upg in pkg.upgrades:
upg.packages.append(pkg)
upgrades[upg] = True
diff --git a/smart/commands/query.py b/smart/commands/query.py
index 9265cd9..b6f5697 100644
--- a/smart/commands/query.py
+++ b/smart/commands/query.py
@@ -750,6 +750,22 @@ class TextOutput(NullOutput):
name = str(prvpkg)
print " ", "%s (%s)" % (name, prv)
+ def showRecommends(self, pkg, rec):
+ if self._firstrecommends:
+ self._firstrecommends = False
+ print " ", _("Recommends:")
+ print " ", rec
+
+ def showRecommendsProvidedBy(self, pkg, req, prv, prvpkg):
+ if self._firstrecommendsprovidedby:
+ self._firstrecommendsprovidedby = False
+ print " ", _("Provided By:")
+ if self.opts.hide_version:
+ name = prvpkg.name
+ else:
+ name = str(prvpkg)
+ print " ", "%s (%s)" % (name, prv)
+
def showUpgrades(self, pkg, upg):
if self._firstupgrades:
self._firstupgrades = False

View File

@ -1,57 +0,0 @@
From 0c55d7e18f40465e95e8e4bf22af01f5d4477d3c Mon Sep 17 00:00:00 2001
From: Daniel Klauer <daniel.klauer@gin.de>
Date: Wed, 11 May 2016 17:22:49 +0200
Subject: [PATCH] rpm: Don't ignore transaction error with empty problems list
SmartPM could misinterpret RPM transaction error as success,
if ts.run() (RPM Python API) returns an empty problems list,
because of incorrect check for None which treated empty list
to be the same as None when it has different meaning.
ts.run() returns:
* None in case of success
* problems list in case of error, may be empty
(look at rpmts_Run() in rpm-5.4.14/python/rpmts-py.c [1])
"if mylist" is not good enough to check for error here, because it will
treat an empty list as "false" because its len() == 0 [2].
ts.check() seems to be different (it's ok for it to return an empty list),
but for consistency it should be made clear that it can return either None,
an empty list or a non-empty list.
[1] http://rpm5.org/cvs/fileview?f=rpm/python/rpmts-py.c&v=1.111.2.3
[2] https://docs.python.org/2/library/stdtypes.html#truth-value-testing
Upstream-Status: Pending
Signed-off-by: Daniel Klauer <daniel.klauer@gin.de>
---
smart/backends/rpm/pm.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/smart/backends/rpm/pm.py b/smart/backends/rpm/pm.py
index 9bbd952..635f726 100644
--- a/smart/backends/rpm/pm.py
+++ b/smart/backends/rpm/pm.py
@@ -208,7 +208,7 @@ class RPMPackageManager(PackageManager):
force = sysconf.get("rpm-force", False)
if not force:
probs = ts.check()
- if probs:
+ if (probs is not None) and (len(probs) != 0):
problines = []
for prob in probs:
name1 = "%s-%s-%s" % prob[0]
@@ -247,7 +247,7 @@ class RPMPackageManager(PackageManager):
del getTS.ts
cb.grabOutput(False)
prog.setDone()
- if probs:
+ if probs is not None:
raise Error, "\n".join([x[0] for x in probs])
prog.stop()
--
1.9.1

View File

@ -1,20 +0,0 @@
Set NOPROGRESS for pycurl just as same as default operation in pycurl module itself.
If set NOPROGRESS with 0 for pycurl, it causes dead lock issue of Python GIL when
call smart library by python gui just like pygtk.
Upstream-Status: Pending
Signed-off-by: Kai Kang <kai.kang@windriver.com>
---
diff -u smart-1.4.1/smart.orig/fetcher.py smart-1.4.1/smart/fetcher.py
--- smart-1.4.1/smart.orig/fetcher.py 2014-07-15 16:42:19.240437080 +0800
+++ smart-1.4.1/smart/fetcher.py 2014-07-15 17:02:37.812470289 +0800
@@ -1720,7 +1720,7 @@
handle.setopt(pycurl.OPT_FILETIME, 1)
handle.setopt(pycurl.LOW_SPEED_LIMIT, 1)
handle.setopt(pycurl.LOW_SPEED_TIME, SOCKETTIMEOUT)
- handle.setopt(pycurl.NOPROGRESS, 0)
+ handle.setopt(pycurl.NOPROGRESS, 1)
handle.setopt(pycurl.PROGRESSFUNCTION, progress)
handle.setopt(pycurl.WRITEDATA, local)
handle.setopt(pycurl.FOLLOWLOCATION, 1)

View File

@ -1,112 +0,0 @@
From 5b79e28bd70a0ec5b34c5ff19b66cbbdd1e48835 Mon Sep 17 00:00:00 2001
From: Haiqing Bai <Haiqing.Bai@windriver.com>
Date: Fri, 18 Mar 2016 13:34:07 +0800
Subject: [PATCH] Make smartpm to support check signatures of rpmv5.
The original support for 'rpm-check-signatures' has been
disabled for the RPMv5 does not support '_RPMVSF_NOSIGNATURES'
now. This fix replaces the '_RPMVSF_NOSIGNATURES' with
rpm VS flags set:RPMVSF_NODSAHEADER|RPMVSF_NORSAHEADER|
RPMVSF_NODSA|RPMVSF_NORSA.
Upstream-Status: Pending
Signed-off-by: Haiqing Bai <Haiqing.Bai@windriver.com>
---
smart/backends/rpm/base.py | 43 +++++++++++++++++++++++++++++++----------
smart/backends/rpm/pm.py | 2 +-
smart/plugins/yumchannelsync.py | 5 +++--
3 files changed, 37 insertions(+), 13 deletions(-)
diff --git a/smart/backends/rpm/base.py b/smart/backends/rpm/base.py
index 85f4d49..dbd6165 100644
--- a/smart/backends/rpm/base.py
+++ b/smart/backends/rpm/base.py
@@ -63,11 +63,23 @@ def getTS(new=False):
if sysconf.get("rpm-dbpath"):
rpm.addMacro('_dbpath', "/" + sysconf.get("rpm-dbpath"))
getTS.ts = rpm.ts(getTS.root)
- if not sysconf.get("rpm-check-signatures", False):
- if hasattr(rpm, '_RPMVSF_NOSIGNATURES'):
- getTS.ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
- else:
- raise Error, _("rpm requires checking signatures")
+
+ # _RPMVSF_NOSIGNATURES is not supported in RPMv5, so here uses
+ # RPMVSF_NODSAHEADER|RPMVSF_NORSAHEADER|RPMVSF_NODSA|RPMVSF_NORSA
+ # to replace '_RPMVSF_NOSIGNATURES' to continue to support check
+ # rpm signatures
+
+ #if not sysconf.get("rpm-check-signatures", False):
+ # if hasattr(rpm, '_RPMVSF_NOSIGNATURES'):
+ # getTS.ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
+ # else:
+ # raise Error, _("rpm requires checking signatures")
+ if sysconf.get("rpm-check-signatures") == False:
+ getTS.ts.setVSFlags(rpm.RPMVSF_NODSAHEADER|rpm.RPMVSF_NORSAHEADER|\
+ rpm.RPMVSF_NODSA|rpm.RPMVSF_NORSA)
+ else:
+ getTS.ts.setVSFlags(0)
+
rpm_dbpath = sysconf.get("rpm-dbpath", "var/lib/rpm")
dbdir = rpm_join_dbpath(getTS.root, rpm_dbpath)
if not os.path.isdir(dbdir):
@@ -89,11 +101,22 @@ def getTS(new=False):
if sysconf.get("rpm-dbpath"):
rpm.addMacro('_dbpath', "/" + sysconf.get("rpm-dbpath"))
ts = rpm.ts(getTS.root)
- if not sysconf.get("rpm-check-signatures", False):
- if hasattr(rpm, '_RPMVSF_NOSIGNATURES'):
- ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
- else:
- raise Error, _("rpm requires checking signatures")
+
+ # _RPMVSF_NOSIGNATURES is not supported in RPMv5, so here uses
+ # RPMVSF_NODSAHEADER|RPMVSF_NORSAHEADER|RPMVSF_NODSA|RPMVSF_NORSA
+ # to replace '_RPMVSF_NOSIGNATURES' to continue to support check
+ # rpm signatures
+
+ #if not sysconf.get("rpm-check-signatures", False):
+ # if hasattr(rpm, '_RPMVSF_NOSIGNATURES'):
+ # ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
+ # else:
+ # raise Error, _("rpm requires checking signatures")
+ if sysconf.get("rpm-check-signatures") == False:
+ ts.setVSFlags(rpm.RPMVSF_NODSAHEADER|rpm.RPMVSF_NORSAHEADER|\
+ rpm.RPMVSF_NODSA|rpm.RPMVSF_NORSA)
+ else:
+ ts.setVSFlags(0)
return ts
else:
return getTS.ts
diff --git a/smart/backends/rpm/pm.py b/smart/backends/rpm/pm.py
index b57a844..7b651b5 100644
--- a/smart/backends/rpm/pm.py
+++ b/smart/backends/rpm/pm.py
@@ -180,7 +180,7 @@ class RPMPackageManager(PackageManager):
fd = os.open(path, os.O_RDONLY)
try:
h = ts.hdrFromFdno(fd)
- if sysconf.get("rpm-check-signatures", False):
+ if sysconf.get("rpm-check-signatures", True):
if get_public_key(h) == '(none)':
raise rpm.error('package is not signed')
except rpm.error, e:
diff --git a/smart/plugins/yumchannelsync.py b/smart/plugins/yumchannelsync.py
index f8107e6..2dc5482 100644
--- a/smart/plugins/yumchannelsync.py
+++ b/smart/plugins/yumchannelsync.py
@@ -56,8 +56,9 @@ def _getreleasever():
rpmroot = sysconf.get("rpm-root", "/")
ts = rpmUtils.transaction.initReadOnlyTransaction(root=rpmroot)
- if hasattr(rpm, '_RPMVSF_NOSIGNATURES') and hasattr(rpm, '_RPMVSF_NODIGESTS'):
- ts.pushVSFlags(~(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS))
+ #_RPMVSF_NOSIGNATURES is not supported in RPMv5
+ #if hasattr(rpm, '_RPMVSF_NOSIGNATURES') and hasattr(rpm, '_RPMVSF_NODIGESTS'):
+ # ts.pushVSFlags(~(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS))
releasever = None
# HACK: we're hard-coding the most used distros, will add more if needed
idx = ts.dbMatch('provides', 'fedora-release')
--
1.9.1

View File

@ -1,141 +0,0 @@
SUMMARY = "The Smart Package Manager"
DESCRIPTION = "The Smart Package Manager project has the ambitious objective of creating \
smart and portable algorithms for solving adequately the problem of managing software \
upgrades and installation."
HOMEPAGE = "http://labix.org/smart/"
SECTION = "devel/python"
LICENSE = "GPLv2"
LIC_FILES_CHKSUM = "file://LICENSE;md5=393a5ca445f6965873eca0259a17f833"
DEPENDS = "python rpm gettext-native python-rpm"
SRCNAME = "smart"
SRC_URI = "\
git://github.com/smartpm/smart.git \
file://smart-recommends.patch \
file://smart-channelsdir.patch \
file://smart-rpm-transaction-failure-check.patch \
file://smart-attempt.patch \
file://smart-attempt-fix.patch \
file://smart-add-for-rpm-ignoresize-check.patch \
file://smart-already-installed-message.patch \
file://smart-set-noprogress-for-pycurl.patch \
file://smart-cache.py-getPackages-matches-name-version.patch \
file://smart-channel-remove-all.patch \
file://smart-locale.patch \
file://smartpm-rpm5-support-check-signatures.patch \
file://smart-add-deugging-when-targetpath-is-empty.patch \
file://channels-rpm_sys-use-md5sum-instead-of-mtime-as-the-.patch \
"
SRCREV = "407a7eca766431257dcd1da15175cc36a1bb22d0"
PV = "1.5+git${SRCPV}"
S = "${WORKDIR}/git"
# Options - rpm, qt4, gtk
PACKAGECONFIG ??= "rpm"
RPM_RDEP = "${PN}-backend-rpm"
QT_RDEP = "${PN}-interface-qt4"
GTK_RDEP = "${PN}-interface-gtk"
RPM_RDEP_class-native = ""
QT_RDEP_class-native = ""
GTK_RDEP_class-native = ""
RPM_RDEP_class-nativesdk = ""
QT_RDEP_class-nativesdk = ""
GTK_RDEP_class-nativesdk = ""
PACKAGECONFIG[rpm] = ",,rpm,${RPM_RDEP}"
PACKAGECONFIG[qt4] = ",,qt4-x11,${QT_RDEP}"
PACKAGECONFIG[gtk] = ",,gtk+,${GTK_RDEP}"
inherit distutils
do_install_append() {
# We don't support the following items
rm -rf ${D}${PYTHON_SITEPACKAGES_DIR}/smart/backends/slack
rm -rf ${D}${PYTHON_SITEPACKAGES_DIR}/smart/backends/arch
rm -rf ${D}${PYTHON_SITEPACKAGES_DIR}/smart/interfaces/qt
# Temporary, debian support in OE is missing the python module
rm -f ${D}${PYTHON_SITEPACKAGES_DIR}/smart/plugins/aptchannelsync.py*
rm -f ${D}${PYTHON_SITEPACKAGES_DIR}/smart/plugins/debdir.py*
rm -rf ${D}${PYTHON_SITEPACKAGES_DIR}/smart/backends/deb
# Disable automatic channel detection
rm -f ${D}${PYTHON_SITEPACKAGES_DIR}/smart/plugins/detectsys.py*
# Disable landscape support
rm -f ${D}${PYTHON_SITEPACKAGES_DIR}/smart/plugins/landscape.py*
# Disable urpmi channel support
rm -f ${D}${PYTHON_SITEPACKAGES_DIR}/smart/plugins/urpmichannelsync.py*
# Disable yum channel support
rm -f ${D}${PYTHON_SITEPACKAGES_DIR}/smart/plugins/yumchannelsync.py*
# Disable zypper channel support
rm -f ${D}${PYTHON_SITEPACKAGES_DIR}/smart/plugins/zyppchannelsync.py*
if [ -z "${@bb.utils.filter('PACKAGECONFIG', 'rpm', d)}" ]; then
rm -f ${D}${PYTHON_SITEPACKAGES_DIR}/smart/plugins/rpmdir.py*
rm -rf ${D}${PYTHON_SITEPACKAGES_DIR}/smart/backends/rpm
fi
if [ -z "${@bb.utils.filter('PACKAGECONFIG', 'qt4', d)}" ]; then
rm -rf ${D}${PYTHON_SITEPACKAGES_DIR}/smart/interfaces/qt4
fi
if [ -z "${@bb.utils.contains('PACKAGECONFIG', 'gtk+', 'gtk', '', d)}" ]; then
rm -rf ${D}${PYTHON_SITEPACKAGES_DIR}/smart/interfaces/gtk
fi
}
add_native_wrapper() {
create_wrapper ${D}/${bindir}/smart \
RPM_USRLIBRPM='`dirname $''realpath`'/${@os.path.relpath(d.getVar('libdir'), d.getVar('bindir'))}/rpm \
RPM_ETCRPM='$'{RPM_ETCRPM-'`dirname $''realpath`'/${@os.path.relpath(d.getVar('sysconfdir'), d.getVar('bindir'))}/rpm} \
RPM_LOCALEDIRRPM='`dirname $''realpath`'/${@os.path.relpath(d.getVar('datadir'), d.getVar('bindir'))}/locale
}
do_install_append_class-native() {
sed -i -e 's|^#!.*/usr/bin/env python|#! /usr/bin/env nativepython|' ${D}${bindir}/smart
add_native_wrapper
}
do_install_append_class-nativesdk() {
add_native_wrapper
}
PACKAGES = "${PN}-dev ${PN}-dbg ${PN}-doc smartpm \
${@bb.utils.contains('PACKAGECONFIG', 'rpm', '${PN}-backend-rpm', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'qt4', '${PN}-interface-qt4', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'gtk', '${PN}-interface-gtk', '', d)} \
${PN}-interface-images ${PN}"
RDEPENDS_smartpm = "${PN}"
RDEPENDS_${PN} += "${PN}-backend-rpm python-codecs python-textutils python-xml python-fcntl \
python-pickle python-crypt python-compression python-shell \
python-resource python-netclient python-threading python-unixadmin python-pprint"
RDEPENDS_${PN}_class-native = ""
RDEPENDS_${PN}-backend-rpm = "python-rpm"
RDEPENDS_${PN}-interface-qt4 = "qt4-x11 ${PN}-interface-images"
RDEPENDS_${PN}-interface-gtk = "gtk+ ${PN}-interface-images"
FILES_smartpm = "${bindir}/smart"
FILES_${PN}-backend-rpm = "${PYTHON_SITEPACKAGES_DIR}/smart/backends/rpm"
FILES_${PN}-interface-qt4 = "${PYTHON_SITEPACKAGES_DIR}/smart/interfaces/qt4"
FILES_${PN}-interface-gtk = "${PYTHON_SITEPACKAGES_DIR}/smart/interfaces/gtk"
FILES_${PN}-interface-images = "${datadir}/${baselib}/python*/site-packages/smart/interfaces/images"
BBCLASSEXTEND = "native nativesdk"