Commit Graph

991 Commits

Author SHA1 Message Date
Panu Matilainen ee5dd3ccb9 Improve error handling in Python pubkey constructor
pkgParsePkts() only parses the PGP armor, the actual pubkey is only
parsed as a part of rpmPubkeyNew() whose return we need to check for
separately. Emit different messages in these cases.

Thanks to @KOLANICH for pointing this out and initial patch.
2020-11-23 16:00:38 +02:00
Panu Matilainen 4821d42abb Replace uses of deprecated PyEval_CallObject() with PyObject_Call()
Python 3.9 has deprecated PyEval_CallObject(), replace with a more
modern and documented interface (https://bugs.python.org/issue29548).
2020-10-28 10:40:22 +02:00
Panu Matilainen ef3ea9c69b Implement alternative transaction callback style with transaction elements
Add API to get and set callback style, defaulting to the good ole
header first style and add a new style where a transaction element
is passed in place of the header, allowing a much saner interaction.

This is doubly so in Python, where the old style callback is a
braindamaged mess. In the new mode the "key" is not passed as separate
argument at all, it can be just as well retrieved via te.Key() for
the callbacks needing it.
2020-10-05 12:21:18 +03:00
Panu Matilainen 45449d5acf Add support for application private user data in transaction elements
The "key" passed to rpmtsAddInstallEleemnt() and associated with transaction
elements is sometimes mistaken for user data, but it is not, as rpm relies
on it having a very specific meaning and is passed around with that very
assumption.

API users have all sorts of (legit!) needs, lets add a proper application
private user data member to transaction elements.

The Python bindings to this are kinda dangerous if you liberally mix Python
and C as we can't know whether the pointer is an actual Python object or not
so we can only assume it is and hope for the best. Of course nobody in their
right mind should be setting user data from one language and accessing it
from another, really...
2020-09-28 11:17:24 +03:00
Panu Matilainen 262d4855cd Add RPMTRANS_FLAG_NOARTIFACTS symbol to Python bindings
Should've been in commit 07ed169da3
2020-06-26 14:43:10 +02:00
Panu Matilainen 09a3d5c23b Fix python ts.addErase() not raising exception on not-found packages
The code would only raise an exception if TransactionSetCore.addErase()
returned an error, but the catch is that with many kinds of argument
types we'd silently skip the whole addition because no headers were found.
This looks to be a regression introduced some eleven years ago in
commit 9b20c706a4.

As a special case, a match iterator argument will not raise an exception
if it doesn't actually match anything.

Fixes: #1214
2020-06-04 13:50:13 +02:00
Panu Matilainen 25e856a6d4 Unify Python addInstall/Reinstall/Erase exception message format
addErase() claimed package not installed for failures, but there could
be other reasons, and for eg. headers coming from match iterators
failure to add cannot be "not installed".

Use a common message format that actually states which operation failed.
2020-06-04 13:50:13 +02:00
Panu Matilainen 4f7a500c75 Support EVR strings to Python labelCompare()
Use the newly added version converter function for parsing labelCompare()
arguments, gaining automatic access to all formats that we support
in rpm.ver() constructor. Currently this means (E,V,R) tuples which
labelCompare() always used, plus plain old strings. In future, might
be something more.
2020-05-27 14:14:00 +02:00
Panu Matilainen a837ec978d Add Python bindings for the new version API 2020-05-27 14:14:00 +02:00
Panu Matilainen 74dd240d00 Refactor python labelCompare() to use the new version API, add more tests 2020-05-27 14:14:00 +02:00
Panu Matilainen 6800e0a4df Axe --nopromote and most of the related infrastructure
Epoch promotion was a thing around and before the turn of the millenium,
we really shouldn't be carrying that cruft around anymore.

Remove all traces that we can without too much guilt about breaking
ABI/API and not bumping soname which we dont want to do for this
stupid old thing: all the symbols are left in place, they just don't
work anymore. Nobody should notice as nobody can have been using this
stuff in the last 15+ years.
2020-05-27 14:14:00 +02:00
Panu Matilainen 95df3dcb9d Add license to Python distutils module description
Fixes: #1236
2020-05-26 12:08:43 +03:00
Panu Matilainen 233ee5516f .gitignore cleanup
Lots of cruft here - the build-aux move related changes from commit
cd6e4eb9e0, and all manner of historical
cruft that hasn't existed in over a decade. While at it, consolidate
it all to the toplevel .gitignore.
2020-04-09 14:27:09 +03:00
Panu Matilainen aa71073ca5 Replace all PyInt_* uses with PyLong_* in the codebase
Up to now we handled this via Python 3 compatibility defines in
rpmsystem-py.h but now that Python 2 is no longer supported, actually
update the codebase. No functional changes.
2019-08-12 09:54:44 +03:00
Panu Matilainen 67f8f2b01d Axe support for Python 2
Python 2 will be EOL by the time of the next major rpm release,
time to retire the Python 2 bindings. Specifically we require
Python >= 3.1 for surrogateescape-support.
2019-08-12 09:54:44 +03:00
Igor Gnatenko c4f7f871e0 python: Reference proper spec-py.c filename
Fixes: 73a41da965
Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
2019-06-02 16:18:25 +02:00
Florian Festi dd17c738c6 Pass rpmts object to rpmSpecBuild()
Add rpmtsFromPyObject
No functional change. Needed to move BuildRequires check to librpmbuild
2019-05-28 09:24:01 +03:00
Panu Matilainen d1ebf65598 Implement a database cookie API for determining whether rpmdb has changed
Add rpmdbCookie() public function and matching python bindings.
The returned value is an opaque string which changes any time the rpmdb
is changed (eg packages added or removed, rebuild changes things etc).
A key point is that this is entirely database backend agnostic.

The actual implementation here is an SHA1 hash of RPMDBI_NAME keys and
the corresponding package offsets, but this is an implementation detail
that can be changed anytime and callers must not rely on. The only thing
that matters is whether the string equals an earlier cookie value or not.
A cryptographic hash seems like an overkill, but then it saves us the
headaches of coming up with something that reflects order changes etc.

Closes: #388
2019-05-27 14:58:27 +02:00
Panu Matilainen 1d6fde768c Un-inline utf8FromString() python helper now that we can
Since commit 73a41da965 this doesn't need
to be inline with murky linkage across different modules. With this,
it'd now be possible to add some central control too if we wanted.
2019-05-27 14:08:41 +02:00
Panu Matilainen dbb12c6231 Drop unused rpmtd python object remnants
Should've been in commit 71ff0b7e73
but better late than never.
2019-05-27 14:08:41 +02:00
Panu Matilainen 3cc55f7b6d Drop now unnecessary PyCapsule foobar from python spec bindings
Since commit 73a41da965 we don't need
to import rpm or wrap our headers through capsules since its all in
one module. Good riddance, including the capsule wrapping in header
creation which was an anomaly wrt reference counting too.
No functional changes.
2019-05-27 14:08:41 +02:00
Igor Gnatenko 73a41da965 python: Merge all py modules
The split is causing more and more issues over the years. It simply
doesn't make much sense to split them. When using python-rpm, it doesn't
matter whether it brings some additional tools like gpg because you
already have python installed.

Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
2019-04-29 11:43:25 +03:00
Panu Matilainen eecd3d5d05 Add python bindings for rpmteVerified(), export RPMSIG_UNVERIFIED_TYPE 2019-04-09 11:04:02 +02:00
Panu Matilainen aea53a4aea Return NULL string as None from utf8FromString()
Commit 84920f8983 regressed dnf install
to segfault at the end due to some NULL string passed to strlen().
Check for NULL and return it as None, make it an inline function
to make this saner.
2019-02-26 11:31:50 +02:00
Panu Matilainen 84920f8983 In Python 3, return all our string data as surrogate-escaped utf-8 strings
In the almost ten years of rpm sort of supporting Python 3 bindings, quite
obviously nobody has actually tried to use them. There's a major mismatch
between what the header API outputs (bytes) and what all the other APIs
accept (strings), resulting in hysterical TypeErrors all over the place,
including but not limited to labelCompare() (RhBug:1631292). Also a huge
number of other places have been returning strings and silently assuming
utf-8 through use of Py_BuildValue("s", ...), which will just irrevocably
fail when non-utf8 data is encountered.

The politically Python 3-correct solution would be declaring all our data
as bytes with unspecified encoding - that's exactly what it historically is.
However doing so would by definition break every single rpm script people
have developed on Python 2. And when 99% of the rpm content in the world
actually is utf-8 encoded even if it doesn't say so (and in recent times
packages even advertise themselves as utf-8 encoded), the bytes-only route
seems a wee bit too draconian, even to this grumpy old fella.

Instead, route all our string returns through a single helper macro
which on Python 2 just does what we always did, but in Python 3 converts
the data to surrogate-escaped utf-8 strings. This makes stuff "just work"
out of the box pretty much everywhere even with Python 3 (including
our own test-suite!), while still allowing to handle the non-utf8 case.
Handling the non-utf8 case is a bit more uglier but still possible,
which is exactly how you want corner-cases to be. There might be some
uses for retrieving raw byte data from the header, but worrying about
such an API is a case for some other rainy day, for now we mostly only
care that stuff works again.

Also add test-cases for mixed data source labelCompare() and
non-utf8 insert to + retrieve from header.
2019-02-22 20:37:20 +02:00
Panu Matilainen 3f3cb3eabf Bump the minimum Python version requirement to 2.7
Older Python versions are long since past their EOL, we don't need to
support them either. Python 2.7 is also the least incompatible version
compared to Python 3, going forward. Nuke the now unnecessary compat
macros.
2018-10-04 18:05:37 +03:00
Panu Matilainen 531dc8495c Fix ancient python GIL locking bug on callback (RhBug:1632488)
Introduced in commit c7881d8017 back in 2002,
synthesizing a python object for the callback occurs before retaking
the GIL lock, which is not allowed. Somehow this has managed to stay
latent all these years, and even now requires fairly specific conditions:
when the callback gets called without an associated key, such as erasures
or file trigger script start/stop events (in the case of RhBug:1632488),
when Python 3 is running in PYTHONMALLOC=debug mode,
it crashes with "Python memory allocator called without holding the GIL".

Simply retake the lock before any Python operations take place to fix.
2018-10-03 11:51:38 +03:00
Panu Matilainen e681e6a95a While we're at it, add rpmdsIsReverse() + python bindings too 2018-09-18 12:10:24 +03:00
Panu Matilainen c7e6875458 Add python bindings + tests for rpmdsIsWeak() and rpmdsIsRich() 2018-09-18 11:59:02 +03:00
Jan Pazdziora 5b9053e36e rpm.spec's .prep seems to be an attribute.
Addressing
Traceback (most recent call last):
  File "test.py", line 7, in <module>
    print(s.prep())
TypeError: 'str' object is not callable
2018-08-08 14:59:11 +02:00
Jan Pazdziora 66b5a7750a Make python examples run with python 3, the print commands.
Addressing things like
    print s.prep()
          ^
SyntaxError: invalid syntax
2018-08-08 13:02:50 +03:00
Panu Matilainen f9f85af2d3 Add a public API for controlling package verification flags
We can't use the existing transaction vsflags for package verification
purposes due to legacy misuses and fundamental differences - vsflags
defaults are very different and change can't really be relied on as
this is all tangled up in legacy issues, misuses and misunderstandings
in 3rd party code and whatnot. I dont see a way to unify them in
foreseeable future, unfortunately. So add another API...

Rename _vsflags_pkgverify to _pkgverify_flags to differentiate it from
the other vsflags (because it is different), add get/set API for it in
transaction sets and use where immediately obvious (but there's
the rpm cli install case left to deal with)
2018-06-27 14:49:39 +03:00
Panu Matilainen 60cbee1576 Rename vslevel back to vfylevel everywhere, sigh
rpmtsVSFlags() doesn't actually control what happens with the package
verification that vslevel/vfylevel relates to, it controls
the verification that happens on header/package read. We actually
need a separate API for controlling the flags that control the
operation that verify level is associated with, so to avoid total
confusion as to what is what... paving way for adding rpmtsVfyFlags(),
but that's not added in this commit - rename only.
2018-06-27 13:45:28 +03:00
Panu Matilainen b4baabbbab Oops, add verification callback symbols to python bindings
Should've been in commit 765e2c72ae
or thereabouts at least.
2018-06-20 12:36:29 +03:00
Panu Matilainen 4cd124145d Add Python bindings + simple testcase for the verification level API 2018-06-20 11:47:26 +03:00
Florian Festi 6cd94fbe4d Expose new RPMVSF_MASK_* constants in Python binding
Fixes #440
2018-06-05 11:16:36 +02:00
Panu Matilainen 765e2c72ae Add package verification step to transactions
Adds a separate package verification phase to rpmtsRun() which runs
as part of normal problem checking and performs package verification
as per configuration. Verification problems are returned in the API as
rpm problem objects.

The verification is done according to the configurable verification level
implemented in commit ac280c42e3, ie if
active, it's an enforcing check that cannot bypassed with previously
available means, you need to specifically filter the new problem class or
change configuration. This is intentional to actually enforce the
verification step on all existing API users regardless of their
default settings (it's common to just disable everything in vsflags etc).

The two big things here are:
- rpm FINALLY supports an enforcing signature policy mode
- if at least digest level is specified, packages with malformed payload
  will be detected before any scriptlets run or any files get laid down

Note that this commit does not change the default verification level,
and thus should NOT affect any functionality unless manually enabled.
Also worth noting is that this all will almost surely require further
tweaking to get all the corner cases and upper level depsolver interactions
straight...
2018-05-09 14:16:07 +03:00
Panu Matilainen 585ff8399d Make python addSign() and delSign() actually work (RhBug:1558126)
Argument parsing condition reversed, doh. Means there's simply no way
anybody could've used these for anything at all... Actual testcases
would not hurt.
2018-03-20 09:32:26 +02:00
Panu Matilainen 58d9a79233 Eliminate useless VERIFY_DIGEST and VERIFY_SIGNATURE constants from python
AFAICS there are no python interfaces where those two values would be
useful, as rpmcliVerify() and rpmcliQuery() are not exported to python.
The relevant constants are the _RPMVSF_NODIGEST/NOSIGNATURES.
2017-11-13 16:39:11 +02:00
Panu Matilainen 3c0bdacc3f Move rpmVerifyAttrs enumeration to rpmfiles.h where it belongs
These are exported file verify attributes in packages and also
used for rpmfilesVerify(), separate rpmvf.h makes little sense.
2017-11-13 14:44:37 +02:00
Panu Matilainen 6f1e75ddd2 Add support for new virtual file attribute "%artifact"
This can be used to differentiate files that are not natural parts of
packages but created as by-products of our processing so they're easy
to filter out of queries.

Possible candidates include build-ids, byte compiled files etc, but this
nothing is automatically marked as artifact in this commit.
2017-11-08 11:02:10 +02:00
Jun Aruga 56f9e21031 Fix Python bindings library path for custom prefix.
This causes the Python bindings ModuleNotFoundError for custom prefix.
The Extension class libraries does not accepti library file or directory path.
2017-11-03 12:27:44 +02:00
Panu Matilainen f064492a50 Add TR_RPMDB element type for representing packages from the rpmdb
These are not transaction members in the traditional sense as they
simply represent a package that is in the rpmdb and cannot actually
be members of a transaction set (at least not currently). But packages
from the rpmdb can and do participate in the transaction in the form of
triggers and file triggers, and abusing TR_REMOVED for the purpose is
just that - abuse.

This is not supposed to actually change any behavior though.
2017-10-03 16:13:19 +03:00
Panu Matilainen c54581ce18 rpmteDBOffset() is perfectly legal for TR_ADDED too, fix the docs
rpmteDBOffset() simply returns zero for non-installed packages, which
is actually useful for determining whether a TR_ADDED package has
already been installed or not, rpm even relies on this. Remove a couple
of other questionable TR_REMOVED comments too.
2017-10-03 14:49:11 +03:00
Panu Matilainen 62b6ec76e4 Remove long since dead code
rpmteAddedKey() was axed more than eight years ago in commit
3e37044eb9, remove the leftovers
from python bindings too.
2017-10-03 14:37:13 +03:00
Panu Matilainen 80b5c12eaa Use pkg-config for figuring python cflags and libs
Simplifies things a bit and also makes "PYTHON=python3 ./configure" work,
whereas it previously barfed on figuring the library names like
"libpython3.6m"
2017-09-05 12:00:30 +03:00
Panu Matilainen eadee821b3 Export rpmsqBlock() to python bindings as blockSignals() 2017-08-23 13:02:24 +03:00
Panu Matilainen 23dc36f0d5 Pass sign arguments to signature deletion too
Refactor rpmsign and python bindings to be more similar on both
addsign/delsign operations, and always pass the signing arguments
along. Deletion doesn't actually (yet) use the arguments for anything
but makes things more symmetric (I remember having doubts about
this when adding - reminder to self: if in doubt, add more arguments ;)

Yet another API break, but what the hey... Other than that, behavior is
not supposed to change here.
2017-05-29 16:11:55 +03:00
Panu Matilainen 95f4e6c6d6 Eliminate now unnecessary rpmtdFreeData() calls 2017-05-26 12:40:36 +03:00
Per Øyvind Karlsen a6a71bf6f0 fix comparison between signed and unsigned integer expressions 2017-05-18 13:45:37 +02:00