RPM

6 posts

New version of Maven RPM builder

I just released a new version of the Maven RPM builder. Version 0.6.0 allows one to influence the way the RPM release information is generated during a SNAPSHOT build (also see issue #2).

While the default behavior is still the same, it is now possible to specify the snapshotBuildId, which will then be added as release suffix instead of the current timestamp. Setting forceRelease can be used to disable the SNAPSHOT specific logic altogether and just use the provided release information.

Writing RPM files … in plain Java … on Maven Central

A few weeks back I wrote a blog post about writing RPM files in plain Java.

What was left over was the fact that the library was not available outside of Package Drone itself. Although it was created as a stand alone functionality you would need to fetch the JAR and somehow integrate it into your build.

With the recent release of Package Drone 0.13.0 I was finally able to officially push the module to Maven Central.


<dependency>
<groupId>org.eclipse.packagedrone</groupId>
<artifactId>org.eclipse.packagedrone.utils.rpm</artifactId>
<version>0.13.0</version>
</dependency>

In the meanwhile I did work on a Maven RPM builder plugin, which allows creating RPM files on any platform. The newest version (0.5.0) has been released today as well, which already uses the new library.

So working with RPM files just got a bit easier 😉

Building RPMs on any platform with Maven

In several occasions I had to build RPM packages for installing software. In the past I mostly did it with a Maven build using the RPM Maven Plugin.

The process is simple: At the end of your build you gather up all resources, try to understand the mapping configuration, bang your head a few times in order to figure out way to work with -SNAPSHOT versions and that’s it. In the end you have a few RPM files.

The only problem is, that the plugin actually creates a spec file and runs the rpmbuild command line tool. Which is, of course, only available on an RPM like system. Fortunately Debian/Ubuntu based distributions, although they use something different, provide at least the rpmbuild tool.

On Windows or Mac OS the situation looks different. Adding rpmbuild to Windows can be quite a task. Still the question remains, why this is necessary since Java can run on all platforms.

So time to write a Maven plugin which does not the rpmbuild tool, but create RPM packages native in Java:

de.dentrassi.maven:rpm is a Maven Plugin which does create RPM packages using plain Java as a Maven Plugin. The process is simply and fast and does not require additional command line tool. The plugin is open source and the source code is available on GitHub ctron/rpm-builder.

Writing RPM files … in plain Java

Now creating an RPM file is easy. There are a lot of tutorials out there on how write a SPEC file and build your RPM. Even when you are using Maven … with the exception that when you are on Windows or Mac OS X, the Maven RPM plugin will still try to invoke rpmbuild in order to actually build the RPM file. The maven bundle simply creates a SPEC file, layout out the payload data and lets rpmbuild do the processing.

My task now was to make it possible for Eclipse NeoSCADA to create configuration RPMs directly from inside the Eclipse IDE (running in Java), without the need to have rpmbuild on a Windows platform. Since I did write an RPM reader for Package Drone before, I did know a bit about the RPM file format. So this shouldn’t be a big deal?! … How naive 😉

Continue reading

Parsing RPMs in Java

RPMThe core idea of Package Drone is to extract meta data from files and generated some sort of repository index. And although Package Drone’s main focus is on OSGi, we did want to implement a YUM repository adapter and for this we needed to extract metadata from RPM files.

Package Drone itself is written in Java. So I wanted some sort of Java approach. Of course it would be possible to run the rpm command in the background, parse the output somehow and gather the meta data information from that. Or make a JNI wrapper to librpm and extract the information with a native library call. However this is not only prone to error, but also a nightmare when it comes to porting.

So I really was looking for a plain Java solution, which also was compatible with the license of Eclipse (EPL). I came across jRPM and redline.

jRPM was last updated around 2005, still has an Apache 1.1 license and simply stuck in the past. redline is more up to date and sounded promising at first, but then the library is really more like a jar file with some “main” entry points and an ant task. There is no clear API for programmatically reading the RPM files. And the legal aspect was a little bit troublesome to me. 28 contributors according to GitHub, no CLA, an “MIT license” from a company simple named “FreeCompany” and the Google Tracking code backed right into the Maven POM file. So, I had to do it myself 😉

A fresh start

So not to fall into the same pitfalls, I did start to write a parsing library first, instead of directly writing the Package Drone extractor module. This way there is now a clean library which can parse RPM files. It also is an OSGi bundle, which was necessary for Package Drone, but does not make use of any OSGi functionality. So it still can be used as a simple JAR file. Licensed under the EPL, as requirement for Eclipse projects anyway and the Eclipse CLA and IP process to take care of the legal aspects. And if you are an Eclipse project, you even don’t need a CQ to use it.

What’s the catch?

I did implement what I needed. And that was reading RPM metadata and building a YUM repository index. So writing RPM files or reading/writing signatures is not possible at the moment. However there are plans to sign YUM repositories and RPM files as well. So this limitation is only a matter of time. Also are there some fields which are not mapped to enums. RPM used numeric IDs internally, many are mapped, but not all. You can still access those, but by number not by enum in that case.

Also is this library currently not on maven central. But again, I am also working an a “deploy to Maven Central” feature in Package Drone, which will clear that blocker.

So where are we now?

So the code is right here on GitHub. In a few weeks we will have a binary download, but right now the Eclipse IP process has to clear the way first.

Looking at the source code of the test case you can see how this library works. Instead of working on a plain File, it can work on an InputStream, which can be important if your RPM file comes from a remote location.

The following example shows how to extract metadata and content from an RPM file.


try(RpmInputStream in = new RpmInputStream(new FileInputStream("file.rpm"))) {
String name = (String)in.getPayloadHeader ().getTag (RpmTag.NAME);

CpioArchiveInputStream cpio = in.getCpioStream ();
CpioArchiveEntry entry;
while ((entry = cpio.getNextCPIOEntry ()) != null) {
process ( entry );
}
}

There is also the older JavaDoc, which has to be updated to reflect the change to org.eclipse.packagedrone.

What’s next?

Of course a binary release at Eclipse, an updated JavaDoc and publishing the binaries to Maven Central. Beside extending the library to be able to sign and write RPM files.

If you like to help or need some help using it, just let me know!