Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add real-life examples of Python RPM #54

Closed

Conversation

FrostyX
Copy link
Member

@FrostyX FrostyX commented Jun 13, 2024

After a discussion with @ffesti on DevConf, I am adding a collection of real-life examples of how Python RPM can be used.

f"Group : {hdr[rpm.RPMTAG_GROUP]}\n"
f"Size : {hdr[rpm.RPMTAG_SIZE]}\n"
f"License : {hdr[rpm.RPMTAG_LICENSE]}\n"
f"Signature : TODO\n"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the correct tag here, please?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strictly speaking I don't think there is "a" correct tag, depends on whether the package is signed with RSA or EdDSA.

But as most packages are signed with RSA, you can probably go with rpm.RPMTAG_RSAHEADER

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. There is also a rpm.RPMTAG_SIGPGP tag which returns a similar value. However they both look something like this:

b"\x89\x023\x04\x00\x01\x08\x00\x1d\x16!\x04\x11]\xf9\xae\xf8W\x85>\xe8D]\n\x07'p~\xa1[y\xcc\x05\x02e\xb1\x9c\xc4\x00\n\t\x10\x07'p~\xa1[y\xccF\x12\x10\x00\xab\xf7\x00\xaa0)|\x141\xa5G#!\r\xf80\x1c\xecA$\xc8\xe2\x91\xbae\xa9I\xc8\xbf\xdd\x8f[\xbegN\xb3\x14b\xb1h\xe7\x1e\xa0\x9aaDr\xd6\xd5\x98c\x19[\xdc\xf2\x84G\xb6\xafpz\xd1a\xfaD\x91\xf6\xc2\xf9C\xb5\xc4IB(\xdc#\xe1\xca\xdb:@\x08V\x9f\xdfsbB\xc3\xfe\xe8\x9b!\xba\xad\xc3Zm}d\t\xaa9L1L\xdc\x87g\xd3\x98\xa6\xe3\xb8\x91\x96\xe9\x1b\x1f\x8dv\x02r!\xec+g2\xb7%\x15>.\x06$\x94\x92\xd10\xa7\xa7\xb2\xe1\xa1\x04\xbdp\xf01\x1d\x1ca\xcam4^\xa4\x9b\xe5\r\xbd\xda\x99\x05\xedB\x88\xa5\xf6\xd5\xa9W\xa0\x081A\x90\xd0\xdf2\xdex\xe8\xba\x99\xd4\x01\x03\xb2M\xe1\x05\xb3c\xc0\x00\x91\x84Y\xab\x8eu!*\x0e\x13\x99\x1av\x8f\\e\xdf\xe2\xdf\xfe\x97\xdf\xeby\xfd\x07\xaf\x85wB\x98\x1fz\xfe\xcf\xb8\x83\xb6O\x80_\x11\x14\xac\xa6\x00|\xb5\x1b\xa2\xe3\xc1\x0c\x18\x04\xcaX\xea\x0c\xa7\xa1G\xfb#\x14:gW\x0e\xfe\xf4S\r\xa3\xc3V\x12U:gC\x08\x15\x91Q\xaev\x13Sn\r\xfe \xa7\x0e\x07*\x80\xbe-Q\xde\x8d\xfc\x90\xbf\xbep\xdf\\\x03r\xcfw\x9fW\x06\xd4mo\x87\xf5\xcdc!\x87\x872\xdeD\x12{\x00\xad,\x1f\xf8NY\x94Y\x87,T\x99\xd1TFOE\xd1\xec\x8a(z\xd0\xbf\x19\x82\xcf\xa5_\x0cj\xe52\x86\xb5\x92V\xbf'9\xab\x95\xd8\x96\x84\xc3!\xb1\xe6QX\x8a\xe9\xe2\xb2;\t\x11\x0b\x00T\t\xbbJ|\xf8\x92\xa4\xf1d\xf0+2\x1b_x\xb4\xa9\n?`P|p\x89\xbc\xca\xbc\xee\x1f\xc8\xfb\xc6\xf6\x9a\xac`\x97z\x82\xa2?(z\x91\xe2F\t\xb2\xb1!\xd0\x9c9\xd1\xc3Lo*\xa5\x81~:\x99\xa1f\x13\xf89\xd4\xac\xcc\x96\xd8\xc6Z\xe3>\xc5\xddh\xc9^\x95\xd1pA\xc3\xb1\x0e\xf3\xd0o\xed(\x85\xa9'N\xb9\x9e\xe2\x96\x1e\x9d\xb3G\xeep\xdd\xca\xe1\xea\x94j\r\x0fU\x03\x85\xf3x"

I can't figure out how to parse something like this from it

Signature   : RSA/SHA256, Thu 25 Jan 2024 12:27:00 AM CET, Key ID 0727707ea15b79cc

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's legacy, ignore it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The signature tags are binary OpenPGP signature blobs. To get something human readable out of them, you need to parse them with something. Python gpgme bindings will do the trick no doubt, but to output something similar as rpm's 'rpm -qi ' does, you'd use rpm's queryformat engine:

print(h.format('%{rsaheader:pgpsig}'))

The .format() argument is exactly what you'd put into --queryformat, which can do all sorts of stuff: https://rpm-software-management.github.io/rpm/manual/queryformat.html

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I worked on this recently, and pysequoia can do this now! wiktor-k/pysequoia#27


# FIXME this snippet fails with
TypeError: 'NoneType' object cannot be interpreted as an integer
FATAL ERROR: python callback ??? failed, aborting!
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have never actually installed anything through the Python API so I am not sure why this fails. The snippet should IMHO be close enough though. Can you please help me fix it?

@@ -29,6 +29,7 @@ This page attempts to track the various relevant documentation that exists for R
* [How to ensure Large File Support for tools using the rpm API](devel_doc/large_files.html)

## RPM Language Bindings
* [RPM Python examples](python.html) - A showcase of real-life Python RPM examples
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't figure out how to build the website, so I don't know if the link is correct. IMHO it should be.

@pmatilai
Copy link
Member

I think real-life examples belong to https://github.com/rpm-software-management/rpm/tree/master/python/examples

@FrostyX
Copy link
Member Author

FrostyX commented Jun 19, 2024

Personally, I'd prefer them directly in the documentation (assuming the page supports syntax highlighting) but I don't object to having them in the repository you linked. But in that case, we have to improve their discoverability. For example, it would be nice if both the documentation and the Doxygen documentation could both mention it.

To be honest, the python-related links in the documentation

RPM Python slideset / tutorial by Paul Nasrat (2004)
Programming RPM with Python from Fedora RPM Guide

and the Doxygen documentation which is the first google result for "python rpm API" are basically unusable for the end user. The real-life examples should be the first thing they find.

@ffesti
Copy link
Contributor

ffesti commented Jun 19, 2024

They should be in the main repo as proper Python files and be linked more prominently. If they are in the main repo they will also get installed locally. Let's concentrate on that first and look at how to integrate them into the docs a s a second step. We want to integrate the C API docs better anyway. So there will be some changes in that area and we can then find a nice place for these Python examples while at it.

@ffesti
Copy link
Contributor

ffesti commented Jun 19, 2024

Simply having a link to https://github.com/rpm-software-management/rpm/tree/master/python/examples or text linking to the single files on GH is a quick and dirty solution. We do want something better ofc but that might be a first step to make this accessible right away.

@FrostyX
Copy link
Member Author

FrostyX commented Jun 19, 2024

Sounds good. I will create a PR to https://github.com/rpm-software-management/rpm/tree/master/python/examples and we can continue there.

@FrostyX
Copy link
Member Author

FrostyX commented Jun 21, 2024

I submitted rpm-software-management/rpm#3177

@@ -29,6 +29,7 @@ This page attempts to track the various relevant documentation that exists for R
* [How to ensure Large File Support for tools using the rpm API](devel_doc/large_files.html)

## RPM Language Bindings
* [RPM Python examples](python.html) - A showcase of real-life Python RPM examples
* [RPM Python](https://web.archive.org/web/20050320013335/http://www.ukuug.org/events/linux2004/programme/paper-PNasrat-1/rpm-python-slides/frames.html) slideset / tutorial by Paul Nasrat (2004)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to not continue linking 20-year-old resources as well, if this new material covers the same ground.

f"Bug URL : {hdr[rpm.RPMTAG_BUGURL]}\n"
f"Summary : {hdr[rpm.RPMTAG_SUMMARY]}\n"
f"Description :\n{hdr[rpm.RPMTAG_DESCRIPTION]}\n"
)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How challenging would it be to provide an example of iterating over files in the payload, or changelog entries?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So basically examples showing how to implement rpm -ql hello and rpm -q --changelog hello in Python? No idea, I haven't needed it so far. But I will try to add them as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dralley , see https://github.com/rpm-software-management/rpm/tree/master/python/examples for examples of iterating over the payload, and -qlv style output.

Copy link
Member

@pmatilai pmatilai Jun 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no high-level API for changelogs, but iterating over them is just walking through the three header arrays the data is stored in. This dumps the raw data, for real-world example you'd probably want to pretty it up a bit:

chl = zip(h['changelogtime'], h['changelogname'], h['changelogtext'])
for item in chl:
    print(item)

For merely printing, the easiest way is to let rpm do it (copy-pasted from /usr/lib/rpm/rpmpopt*, hence the case difference):

print(h.format('[* %{CHANGELOGTIME:day} %{CHANGELOGNAME}\n%{CHANGELOGTEXT}\n\n]'))

@ffesti
Copy link
Contributor

ffesti commented Jul 23, 2024

This has moved to the RPM main repositiory. Closing here.

@ffesti ffesti closed this Jul 23, 2024
FrostyX added a commit to FrostyX/rpm that referenced this pull request Aug 3, 2024
FrostyX added a commit to FrostyX/rpm that referenced this pull request Aug 7, 2024
FrostyX added a commit to FrostyX/rpm that referenced this pull request Aug 22, 2024
pmatilai pushed a commit to rpm-software-management/rpm that referenced this pull request Aug 26, 2024
dmnks pushed a commit to dmnks/rpm that referenced this pull request Aug 29, 2024
dmnks pushed a commit to rpm-software-management/rpm that referenced this pull request Aug 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants