Skip to content
This repository was archived by the owner on Oct 10, 2020. It is now read-only.

Replace rpmbuild dependency with new rpmwriter module#1005

Closed
giuseppe wants to merge 7 commits intoprojectatomic:masterfrom
giuseppe:replace-rpmbuild-with-rpmwriter
Closed

Replace rpmbuild dependency with new rpmwriter module#1005
giuseppe wants to merge 7 commits intoprojectatomic:masterfrom
giuseppe:replace-rpmbuild-with-rpmwriter

Conversation

@giuseppe
Copy link
Collaborator

@giuseppe giuseppe commented May 17, 2017

Description

Replace rpmbuild dependency with a simpler module to write directly an RPM file.

We lose the capability of building an RPM from a spec file, but this was really an over-engineered solution, so better drop it before it is too late.

Users who want a more complex RPM file, then they must provide it as part of the image itself '/exports/container.rpm'

Related Issue Numbers

#981

@giuseppe
Copy link
Collaborator Author

@cgwalters @baude this is the WIP for replacing rpmbuild, I need to add tests

@giuseppe giuseppe force-pushed the replace-rpmbuild-with-rpmwriter branch 8 times, most recently from 464c98a to bc385e9 Compare May 18, 2017 14:17
@giuseppe giuseppe changed the title [WIP] Replace rpmbuild dependency with new rpmwriter module Replace rpmbuild dependency with new rpmwriter module May 18, 2017
@giuseppe
Copy link
Collaborator Author

I've adapted the tests to work with the new module. There are quite a few tests to cover the rpm generation. Dropping the WIP and ready for review

@giuseppe
Copy link
Collaborator Author

The CI failure is unrelated to the PR

@ashcrow
Copy link
Contributor

ashcrow commented May 18, 2017

+ '[' /var/mnt /sysroot/ostree/deploy/centos-atomic-host/var/mnt ']'
./tests/integration/test_storage.sh: line 39: [: /var/mnt: unary operator expected
+ wipefs -a /dev/vdb
wipefs: error: /dev/vdb: probing initialization failed: Device or resource busy

@ashcrow
Copy link
Contributor

ashcrow commented May 18, 2017

Related: ostreedev/ostree#859

@giuseppe giuseppe force-pushed the replace-rpmbuild-with-rpmwriter branch from bc385e9 to d2bca31 Compare May 18, 2017 20:20
@baude
Copy link
Member

baude commented May 18, 2017

@giuseppe assuming #1008 merges, just rebase and you should be good.

@giuseppe
Copy link
Collaborator Author

rebased on master so that the storage test is disabled ⬆️

@cgwalters
Copy link
Member

cgwalters commented May 19, 2017

How did you come up with rpmwriter.py? Did you just reverse-engineer librpm and translate to Python? A few comments about how you did it would help maintenance.

Down the line...I'd like to change things so that the "synthesize an RPM" code lives in rpm-ostree in that case. Basically have atomic pass the metadata as JSON/GVariant/whatever + path to rootfs.

For now though this seems pretty sane to me.

@giuseppe
Copy link
Collaborator Author

@cgwalters I've used the documentation here as a starting point: http://ftp.rpm.org/max-rpm/s1-rpm-file-format-rpm-file-format.html

I got stuck a few times so I added more debug messages to rpm that helped me, but in general the file format documentation + rpmtag.h was enough to write rpmwriter.h. I've added a fixup patch to add more info about it

RPMTAG_REQUIRENAME = 1049
RPMTAG_REQUIREVERSION = 1050
RPMTAG_CONFLICTFLAGS = 1053
RPMTAG_CONFLICTNAME = 1054

Choose a reason for hiding this comment

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

micro nit. You've an extra tab it looks like between the variable and the equals for a few of these definitions. I personally like this style and would ask that you do the same for the group of variables above too (lines 40->62)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've pushed a fixup patch to use the same style for all variables


def add_header(self, tag, typ, count, value, pad=1):
try:
# this fails on python3

Choose a reason for hiding this comment

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

Should a TODO comment be added to fix in python3?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

no, this is the desired behavior. The try inhibits the exception to be raised as there is no unicode in python3

Choose a reason for hiding this comment

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

Ah, I read it to mean you were having unexpected issues here. Perhaps change the comment to something like:

"The next line is expected to always fail under python3, in that case just continue."

or something similar. Another nit, not a hold the merge comment.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

@@ -0,0 +1,369 @@
import os

Choose a reason for hiding this comment

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

Do you need to have a shebang here declaring the version of python you're supporting? Perhaps:

#!/usr/bin/env python2

Given your python3 issue noted below?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

atomic must support both versions. On RHEL we have python2, on Fedora python3

Choose a reason for hiding this comment

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

Sounds good, I misunderstood your comment on the python3 failure. Given that it would stlll be good to have some kind of shebang statement at the top of the file. Perhaps:

#!/usr/bin/env python

But certainly not a comment to hold the merge for.

Copy link
Contributor

Choose a reason for hiding this comment

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

What's the point of having shebang if the file is not meant to be run directly?

@giuseppe giuseppe force-pushed the replace-rpmbuild-with-rpmwriter branch from 3dafbd5 to 637647f Compare May 22, 2017 13:44
rpm_name = "atomic-container-%s" % name
rpm_out = os.path.join(result_dir, "%s.rpm" % rpm_name)
def split_name_version(pkg):
r = r"([abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\-\._\+]+)(.*)"
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: This regex could be shortened to ([a-zA-Z0-9_\-\.\+]+)(.*)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

thanks, pushed a fixup patch.

rpm_file = RPMHostInstall.find_rpm(rpm_root)
if rpm_file:
dest_path = os.path.join(destination, "container.rpm")
orig_name = "atomic-container-%s.rpm" % name
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I recommend using {} and format with string formatting unless there is a need to hold compatibility with very old Python versions.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

change included in the fixup patch

def add_conflict(self, name, version):
self.conflict.append([name, version])

def __init__(self, out, root, name, version, release, summary='', description='', license_='gpl2', changelog='', url='', group='', stderr=sys.stderr, whitelist=None):
Copy link
Contributor

Choose a reason for hiding this comment

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

I ❤️ GPL but why default to gpl2 if no license is provided?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

rpm complains if no license is specified, so I've just used the same license of atomic itself

@giuseppe giuseppe force-pushed the replace-rpmbuild-with-rpmwriter branch from 637647f to 271ebdb Compare May 22, 2017 14:01
@TomSweeneyRedHat
Copy link

LGTM, assuming happy test results. Thanks for the nit touch ups.

@giuseppe
Copy link
Collaborator Author

@rhatdan what do you think of this change?

@rhatdan
Copy link
Member

rhatdan commented May 23, 2017

@giuseppe Can this handle dependencies? IE Can I build a "spec" file that says it requires "foobar" package be installed?

@giuseppe
Copy link
Collaborator Author

@rhatdan the rpmwriter doesn't use a spec file to build the .rpm file. It creates the cpio archive given a rootfs and the metadata is read from labels and injected in the .rpm:

LABEL atomic.requires=foo>1,bar<2

We support: summary, version, release, license, url, requires, provides, conflicts, description.

I'll document this once the PR looks fine.

@TomasTomecek

# The complete list is available here:
# https://github.com/rpm-software-management/rpm/blob/master/lib/rpmtag.h

class RpmWriter(object):
Copy link
Contributor

Choose a reason for hiding this comment

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

My opinion is that this module should be a separate project. If you look at it, it's not tight to atomic in any way. I think that plenty of other users and projects could benefit from a lightweight and friendler user-experience interaction with rpm builds. Even further, it would be awesome if rpm team reviewed this piece of code and ack'd it.

Copy link
Member

Choose a reason for hiding this comment

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

We're not building here though. More like just repacking binaries. What other use cases are there where one isn't using a spec file? Or without wanting a dependency on rpmbuild?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've created a separate repository here: https://github.com/giuseppe/tinyrpmbuild, if someone is really interested in it.

I agree with @cgwalters, this is not a replacement for rpmbuild, it is really implementing the minimum necessary to get an installable .rpm file. Not sure how many other users will have the same requirement of building an .rpm on the fly without using rpmbuild.

def try_read(stdout, gzip_out):
written = 0
while True:
readable, _, _ = select.select([stdout], [], [], 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

Wow, is select needed here? I would assume that simple pipe with reads and writes is just enough.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I want it to not block on _try_read, just read as much as it is available. In this way I can feed more data to the cpio process through cpio_process.stdin.write(filename.encode() + b"\n")

import shutil

# More information on the RPM file format can be found here:
# http://ftp.rpm.org/max-rpm/s1-rpm-file-format-rpm-file-format.html
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this spec backwards and forward compatible?

@baude
Copy link
Member

baude commented May 30, 2017

@rh-atomic-bot r+ 8537474

@rh-atomic-bot
Copy link

🙀 8537474 is not a valid commit SHA. Please try again with 271ebdb.

@baude
Copy link
Member

baude commented May 30, 2017

@rh-atomic-bot r+ 271ebdb

@rh-atomic-bot
Copy link

🔒 Merge conflict

giuseppe added 7 commits May 30, 2017 20:40
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Closes: projectatomic#981

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Since we don't use it anymore, run all the tests

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
@giuseppe giuseppe force-pushed the replace-rpmbuild-with-rpmwriter branch from 271ebdb to be51f9c Compare May 30, 2017 18:42
@giuseppe
Copy link
Collaborator Author

@baude thanks for the r+, I've manually fixed the conflicts with the fixup patches. Pushed a new version ⬆️

@rhatdan
Copy link
Member

rhatdan commented May 30, 2017

@rh-atomic-bot retry

@rhatdan
Copy link
Member

rhatdan commented May 30, 2017

@rh-atomic-bot r+ be51f9c

@rh-atomic-bot
Copy link

⌛ Testing commit be51f9c with merge 3d1ca35...

rh-atomic-bot pushed a commit that referenced this pull request May 30, 2017
Closes: #981

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>

Closes: #1005
Approved by: rhatdan
rh-atomic-bot pushed a commit that referenced this pull request May 30, 2017
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>

Closes: #1005
Approved by: rhatdan
rh-atomic-bot pushed a commit that referenced this pull request May 30, 2017
Since we don't use it anymore, run all the tests

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>

Closes: #1005
Approved by: rhatdan
rh-atomic-bot pushed a commit that referenced this pull request May 30, 2017
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>

Closes: #1005
Approved by: rhatdan
rh-atomic-bot pushed a commit that referenced this pull request May 30, 2017
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>

Closes: #1005
Approved by: rhatdan
rh-atomic-bot pushed a commit that referenced this pull request May 30, 2017
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>

Closes: #1005
Approved by: rhatdan
@rh-atomic-bot
Copy link

☀️ Test successful - status-redhatci
Approved by: rhatdan
Pushing 3d1ca35 to master...

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants