The same version of a package or group can be built simultaneously for multiple deployment conditions, such as for a 64-bit architecture or deployment as part of a VMware virtual machine. Each condition is called a flavor specification, and all possible conditions together make up a flavor of that package or group.
rBuilder controls flavors for you automatically. When you create image definitions for your appliance in rBuilder, each definition groups together the appropriate flavor specifications to represent each image definition. Then, rBuilder builds each package and group for all the flavors, thus covering all the image definitions.
There are only three reasons you'd need to concern yourself with flavors outside of this automated process:
You are querying to get package or group information, and you need to know the differences between any two flavors of the same version of that package or group
You need to adjust a specification included in rPath Linux, but not set by the image definitions (such as kernel.pae which determines if you are building for a system that does or does not have a PAE kernel); this is rare
You want to create your own build conditionals by writing your own flavor specifications
When querying information about a component, package, or group, its
associated flavor is a string of values separated by commas in square
brackets. Use the --flavors option to reveal the flavor
that aligns with the flavor specs of your current Conary-based system, and
use --all-flavors to show all flavors in a
repository:
$> conary q group-core --flavors group-core=2.1.1-0.133-2[~!dom0,~!domU,~!vmware,~!xen is: x86(i486,i586,i686,sse,sse2) x86_64] $> conary rq group-dist=conary.rpath.com@rpl:2 --flavors group-core=2.0.1-0.3-1[~!dom0,~!domU,~!vmware,~!xen is: x86(i486,i586,i686,sse,sse2) x86_64] $> conary rq group-dist=conary.rpath.com@rpl:2 --all-flavorsgroup-dist=2.0.1-0.3-1[dom0,~!domU,~!vmware,xen] group-dist=2.0.1-0.3-1[~!dom0,domU,~!vmware,xen] group-dist=2.0.1-0.3-1[~!dom0,~!domU,vmware,~!xen] group-dist=2.0.1-0.3-1[~!dom0,~!domU,~!vmware,~!xen] group-dist=2.0.1-0.3-1[dom0,~!domU,~!vmware,xen is: x86 x86_64] group-dist=2.0.1-0.3-1[~!dom0,domU,~!vmware,xen is: x86 x86_64] group-dist=2.0.1-0.3-1[~!dom0,~!domU,vmware,~!xen is: x86 x86_64] group-dist=2.0.1-0.3-1[~!dom0,~!domU,~!vmware,~!xen is: x86 x86_64]
The most recent versions of Conary shorten these flavors to show only the specifications that are relevant.
When reading a flavor, note the following mnemonics for each flavor specification, using the example "vmware" which refers to conditions that prepare the software to be part of a VMware virtual machine:
Table 1.1. Mnemonics for reading flavor specifications
| Mnemonic | Example | How it reads |
|---|---|---|
| (no preceding mark) | vmware | vmware -- must be built for VMware; if this condition cannot be met, let the build fail |
| ~ | ~vmware | prefers vmware -- preferred built for VMware; if this condition cannot be met, don't let that stop building |
| ! | !vmware | not vmware -- must not be built for VMware; if this condition cannot be met, let the build fail |
| ~! | ~!vmware | prefers not vmware -- preferred not built for VMware; if this condition cannot be met, don't let that stop building |
To see all the flavor specifications built into a platform, beyond the automatically-abbreviated list of relevant flavor specs, you need to locate the recipe used to build the platform. Browse the repository to find the groups in the platform and to read the group recipes. For example, group-dist:source is used to build rPath Linux 2 on conary.rpath.com@rpl:2. In the recipe code, find the "if," "elif," and "else" lines that define these flags (generally following the consistent pattern for recipes in the Conary API).
FIXME: Example here? More to come in future drafts.
The abbreviated list usually includes specifications for the architecture (is: x86 or is: x86_64), for VMware (vmware), and Xen (xen and domU). Add flavor specifications to your product definition to ensure certain conditions are met that aren't already specified by the abbreviated list. To do this, use the following steps:
Check out your product-definition.
Open the product definition XML file in a text editor.
Locate the flavors defined in the file.
Add the extra flavor specification to each flavor shown:
Select any mnemonics you need to set the appropriate condition for that flavor spec (use "~" and "!" as previously described).
Place the specification in the comma separated list, keeping the "is:" and architecture at the end separated only by a space from the last flavor spec before it.
Check in your product-definition, and rebuild your appliance to test your new conditions.
If you choose to use rMake instead of rBuild to build your appliance, rMake will not use your product definition as a guide. Instead, you will need to use flavors in your rMake build command, or define rMake contexts. For more information, see rMake documentation at the rPath Wiki.
As a packager, you can create your own conditional statements independent from those pre-defined in your selected platform. There is an object called "Flags" from the Conary API you can use to create each new flag of your own, which in turn becomes flavor specification for your appliance.
An example of using this would be to build a single package with multiple configurations. Suppose the package example-package needs a configuration for marketing users and a different configuration for IT users. The recipe for example-package can use a conditional that identifies adding two specific configurations as well as adding a default configuration. The following is an example of such a recipe:
class ExamplePackage(PackageRecipe):
name = 'example-package'
version = '1.0'
Flags.marketing = False #default flavor is not marketing
Flags.it = False #default flavor is not it
def setup():
# Assert that marketing and it configurations cannot both be included
assert not (Flags.marketing and Flags.it)
# Set a macro identifying where to unpack the archive for the application
r.macros.exampledir = '%(servicedir)s/%(name)s'
r.addArchive('http://www.example.com/download/%(name)s_%(upver)s_install.tar.gz',
dir='%(exampledir)s/')
# In this example, no additional commands are required to set up the application
# Include the configuration appropriate to the build flavor
if Flags.marketing:
r.addSource('marketing-config', dest'%(exampledir)s/config.file')
elif Flags.it:
r.addSource('it-config', dest'%(exampledir)s/config.file')
else:
r.addSource('default-config', dest'%(exampledir)s/config.file')
The following are the flavor specifications resulting from the example-package. Note that because these specifications are part of the example-package recipe class, they require "example-package" as part of each flavor specification. Add these as appropriate to the flavors in your product definition:
For Marketing, choose example-package.marketing, ~example-package.marketing, !example-package.marketing, or ~!example-package.marketing
For IT, choose example-package.it, ~example-package.it, !example-package.it, or ~!example-package.it
For Marketing or IT (the default), either put nothing, or explicitly use the "not" or "prefers not" for each of the two flavors specs