Conary:Flavor Rank Spec
From rPath Wiki
| Conary Developer Community | Go to the community main page |
Flavors are attributes that Conary applies both to troves and to the entire system in order to solve the problem of installing the most appropriate version of a trove on a system. For example, a trove may be cooked once with the x86 flavor, and again with the x86_64 flavor. Similarly, a Conary-based system may also have the x86 flavor.
When troves are cooked multiple times with different flavors specified, the troves are created with each flavor particularly suited for a specific environment. During installation of such troves, Conary uses flavor affinity and ranking to install the most suitable flavor for the running system. Thus, it will only install an x86-flavored trove on an x86 system, and similarly, it will only install an x86_64-flavored trove on an x86_64 system.
Ranking Flavors
When you ask Conary to install a trove from the repository, it might find itself with a choice of multiple flavors that satisfy your request. When this happens, we have to rank the flavors to choose the best flavor for your system. If you are updating instead of installing, this needs to take into account both your system and the flavor of the current trove, so that you get the best match for the existing trove that is compatible with your system.
Part of the definition of a flavor are three sets of "flags": the Use flags, the Arch flags, and the Local flags for that trove:
- Use flags have a uniform definition across the system, and include things like
Use.gnome,Use.ssl, andUse.builddocs - Arch flags define the instruction set capabilities that the trove is built for, like
Arch.x86orArch.x86.mmx - Local flags are like Use flags, except that they are recipe-specific, like
kernel.smp
Any flag has a setting in a flavor of a trove, and also has a setting on the system. One important idea is that flag settings on a file/trove are fundamentally different from the same flags settings on the system. The settings on a trove are kind of like a statement of requirement ("Requires"), and the settings on the system are kind of like a statement of capability ("Provides"). They aren't quite the same as requires/provides, but they have the same asymmetric nature.
Originally, flags were either on or off, but that did not capture the necessary semantics sufficiently. Some flags are an absolute requirement; others are merely "optimized for". The "~" character, when prepended to a flag, expresses preference. So you can build a component that requires that a flag be enabled on the system in order to function, or a component that merely prefers that a flag be enabled on the system but can function even with it off. The system can be set to prefer trove flavors with a particular flag enabled, or it can require that if that flag is mentioned for a package, it must be enabled.
First a description of the semantics we defined and then, the syntax we created:
A flag setting on a file/trove can have one of four choices:
- Capability is required to be on the system
- Capability is required not to be on the system
- Capability is desired to be on the system
- Capability is desired not to be on the system
Similarly, a flag setting on a system can have one of four choices:
- The capability is provided, and if the trove is built with respect to this capability (i.e. this flag is mentioned) it must be enabled in the trove. (e.g.
Use.ssl) - The capability is not provided, and troves that are built with respect to this capability must not be installed if the capability is enabled in the trove. (e.g.
Use.nptl,kernel.smpon uniprocessor systems that cannot boot an SMP kernel.) You might call this an "incompatible capability". - The capability is provided, and troves that use this flag are preferred, but both will work. (e.g.
Use.gtk) - The capability is not provided, but troves that use this capability will still function, though perhaps not optimally, so they are not the best options given all possible choices. (e.g.
kernel.smpon most uniprocessor systems)
Note, from the kernel.smp example, that the choice between these options for each flag needs to be per-system. We can have a default for each, but it is important to be able to override the default for
any system.
To implement those semantics, we provide the following syntax (using F as the meta-variable for a flag):
- For troves:
- Flag required:
F - Flag forbidden:
!F - Flag desired:
~F - Flag undesired:
~!F
- Flag required:
- For the system:
- Capability available and Flag required to be enabled:
F - Capability unavailable and Flag required to be disabled:
!F - Capability available and Flag preferred to be enabled:
~F - Capability unavailable and Flag preferred to be disabled:
~!F
- Capability available and Flag required to be enabled:
The semantics have three purposes: to rank the available flavors, to come up with a best match, to remove from consideration flavors that the system administrator simply never wants on the system; and to throw away any flavors that would not pass a dependency check, since dependency checking is much more expensive than flavor ranking.
The idea is that for each flavor, Conary will iterate over the flags mentioned in the flavor, and for each flag will do one of:
- Promote the flavor (add to the flavor's current "score")
- Demote the flavor (subtract from the flavor's current "score")
- Disallow the flavor (immediately remove this flavor from consideration, without considering any more flags from this flavor)
- Do nothing (do not change the flavor's current "score")
What to do in each case depends on the following matrix:
System flag settings will be considered in this order:
- Flag settings from the command line override any
- flags settings in
/etc/conary/distro/use- flags settings in
/etc/conary/use
- flags settings in
- flags settings in
This means that we can provide reasonable defaults, where the defaults for different flags can reasonably be provided by different packages and repositories (this is important both for package-local flags like kernel.smp and for repositories that have flags that are not specified in the default Conary set), and where the flags can reasonably be overridden. The default set is provided by Conary, but can be overridden and augmented by the distribution.

