First off, let me be very clear up-front: normally, I write my blog articles to be approachable by readers of varying levels of technical background (or none at all). This will not be one of those. This will be a deep dive into the very bowels of the sausage factory.
This blog post is a continuation of the Introduction to building modules in Fedora entry I wrote last month. It will assume a familiarity with all of the concepts discussed there.
Analyzing a more complicated module
Last time, we picked an extremely simple package to create. The
talloc module needed to contain only a single RPM, since all the dependencies necessary both at build-time and runtime were available from the existing
This time, we will pick a slightly more complicated example that will require exploring some of the concepts around building with package dependencies. For this purpose, I am selecting the
sscg package (one of my own and discussed previously on this blog in the article “Self-Signed SSL/TLS Certificates: Why they are terrible and a better alternative“).
We will start by analyzing
sscg‘s dependencies. As you probably recall from the earlier post, we can do this with
dnf repoquery --requires sscg.x86_64 --resolve
Which returns with:
glibc-0:2.25-6.fc26.i686 glibc-0:2.25-6.fc26.x86_64 libpath_utils-0:0.2.1-30.fc26.x86_64 libtalloc-0:2.1.9-1.fc26.x86_64 openssl-libs-1:1.1.0f-4.fc26.x86_64 popt-0:1.16-8.fc26.x86_64
and then also get the build-time dependencies with:
dnf repoquery --requires --enablerepo=fedora-source --enablerepo=updates-source sscg.src --resolve
Which returns with:/home/sgallagh/modulebuild/builds/module-talloc-master-20170526153440/results/module-build-macros-mock-stderr.log
gcc-0:7.1.1-3.fc26.i686 gcc-0:7.1.1-3.fc26.x86_64 libpath_utils-devel-0:0.2.1-30.fc26.i686 libpath_utils-devel-0:0.2.1-30.fc26.x86_64 libtalloc-devel-0:2.1.9-1.fc26.i686 libtalloc-devel-0:2.1.9-1.fc26.x86_64 openssl-devel-1:1.1.0f-4.fc26.i686 openssl-devel-1:1.1.0f-4.fc26.x86_64 popt-devel-0:1.16-8.fc26.i686 popt-devel-0:1.16-8.fc26.x86_64
So let’s start by narrowing down the set of dependencies we already have by comparing them to the three foundational modules. The base-runtime module provides
popt-devel . The shared-userspace module provides
libpath_utils-devel as well, which leaves us with only
libtalloc as an unsatisfied dependency. Wow, what a convenient and totally unexpected outcome when I chose this package at random! Kidding aside, in most real-world situations this would be the point at which we would start recursively going through the leftover packages and seeing what their dependencies are. In this particular case, we know from the previous article that
libtalloc is self-contained, so we will only need to include
libtalloc in the module.
As with the
libtalloc example, we need to now clone the dist-git repositories of both packages and determine the git hash that we intend to use for building the
sscg module. See the previous blog post for details on this.
Creating a module with internal dependencies
Now let’s set up our git repository for our new module:
mkdir sscg && cd sscg touch sscg.yaml git init git add sscg.yaml git commit -m "Initial setup of the module"
And then we’ll edit the
sscg.yaml the same way we did for the
document: modulemd version: 1 data: summary: Simple SSL certificate generator description: A utility to aid in the creation of more secure "self-signed" certificates. The certificates created by this tool are generated in a way so as to create a CA certificate that can be safely imported into a client machine to trust the service certificate without needing to set up a full PKI environment and without exposing the machine to a risk of false signatures from the service certificate. stream: '' version: 0 license: module: - GPLv3+ references: community: https://github.com/sgallagher/sscg documentation: https://github.com/sgallagher/sscg/blob/master/README.md tracker: https://github.com/sgallagher/sscg/issues dependencies: buildrequires: base-runtime: f26 shared-userspace: f26 common-build-dependencies: f26 perl: f26 requires: base-runtime: f26 shared-userspace: f26 api: rpms: - sscg profiles: default: - sscg components: rpms: libtalloc: rationale: Provides a hierarchical memory allocator with destructors. Dependency of sscg. ref: f284a27d9aad2c16ba357aaebfd127e4f47e3eff buildorder: 0 sscg: rationale: Purpose of this module. Provides certificate generation helpers. ref: d09681020cf3fd33caea33fef5a8139ec5515f7b buildorder: 1
There are several changes from the libtalloc example in this modulemd, so let’s go through them one at a time.
The first you may notice is the addition of
perl in the
buildrequires: dependencies. This is actually a workaround at the moment for a bug in the module-build-service where not all of the runtime requirements of the modules specified as
buildrequires: are properly installed into the buildroot. It’s unfortunate, but it should be fixed in the near future and I will try to remember to update this blog post when it happens.
You may also notice that the
api section only includes
sscg and not the packages from the
libtalloc component. This is intentional. For the purposes of this module,
libtalloc satisfies some dependencies for
sscg, but as the module owner I do not want to treat libtalloc as a feature of this module (and by extension, support its use for anything other than the portions of the library used by
sscg). It remains possible for consumers of the module to link against it and use it for their own purposes, but they are doing so without any guarantee that the interfaces will remain stable or even be present on the next release of the module.
Next on the list is the addition of the entirely-new
profiles section. Profiles are a way to indicate to the package manager (DNF) that some packages from this module should automatically be installed when the module is activated if a certain system profile is enabled. The ‘default’ profile will take effect if no other profile is explicitly set. So in this case, the expectation if a user did
dnf module install sscg would be to activate this module and install the
sscg package (along with its runtime dependencies) immediately.
Lastly, under the RPM components there is a new option,
buildorder. This is used to inform the MBS that some packages are dependent upon others in the module when building. In our case, we need
libtalloc to be built and added into the buildroot before we can build
sscg or else the build will fail and we will be sad. By adding
buildorder, we tell the MBS: it’s okay to build any of the packages with the same
buildorder value concurrently, but we should not attempt to build anything with a higher
buildorder value until all of those lower have completed. Once all packages in a
buildorder level are complete, the MBS will generate a private buildroot repository for the next buildorder to use which includes these packages. If the
buildorder value is left out of the modulemd file, it is treated as being
At this point, you should be able to go ahead and commit this modulemd file to git and run
mbs-build local successfully. Enjoy!