Naming and identifying modules in Fedora
Modules are uniquely identified by NSVCA which stands for name, stream, version, context, and architecture. This page describes both the source-level ID (NSV) and the binary-level ID (NSVCA).
At the source level, modules are only identified by the first three: name, stream, and version. Name is defined as a name of the module’s repository in DistGit, stream is a name of the branch in DistGit, and version is the timestamp of a commit.
Name of the module corresponds to the name of the application or the language stack it represents.
An example of a name could be postgresql for a PostgreSQL database module, or nodejs for a Node.js runtime.
Streams are variants of a module with a certain promise.
In most cases, streams promise backwards compatibility with a major version of the application or the language stack they provide. For example, let’s say the Node.js runtime is supported in two major versions: 6 and 8. In this case, the module nodejs would have two streams: 6 and 8.
However, streams can also promise different things such as stability. A good example of this is the calc package in Fedora which is maintained in two upstream branches: stable for the latest stable release and unstable for the latest development version. Using modularity, this package could be built as a calc module in two different streams: stable and unstable.
In addition to the version promise, streams are also a way for packagers to communicate the level of maintenance. Does the maintainer plan to apply every minor patch? Will they apply security fixes quickly? Or is the module updated only twice a year? This can also be part of the promise.
Other different example could be a stream that provides the software compiled using some experimental flags increasing the performance.
Anyway, you get the idea. Streams are very flexible and powerful tool. Use them wisely.
Building a module from one source can result in multiple different binaries. Different binaries are typically produced for different architectures (i.e. x86_64, armv7hl, etc.) and different Fedora releases (i.e. Fedora 28, Fedora 29, EPEL 7, etc.).
Module binaries use the full NSVCA — so in addition to the name, stream, and version fields described above, there are two more for binaries: architecture and context.
Fedora is built for many different architectures. The architecture field simply distinguishes architecture-specific binaries from each other.
The value is typically the same as with RPM packages, i.e. x86_64, armv7hl, etc.
Context is used to distinguish binaries built for different Fedora releases. Thanks to stream expansion, modules can also be built against multiple streams of other modules, i.e. different versions of a language runtime etc.
The value is generated by the build system and is usually hidden from the user as it doesn’t have any informational value by itself — it is a hash. However, the client tooling consuming this value can present it in a useful way.
One way of representing the context could be listing the Fedora releases for which a certain module has been built.