Both a shadow and a derived package start with a shadowing operation in Conary. If you're using rBuild, though, separate commands ensure you don't have to make manual changes that turn the shadow into a derived package.
But, how do you know whether to shadow or derive before you customize? Here are some hints to help you decide:
A derived package is sufficient for minor changes to a package, such as switching out image files or adding a custom configuration.
A derived package starts with the original package at it would install on an existing system, and then applies your custom changes.
A shadow lets you recompile application source code with different options, or build the package with new requirements.
A derived package version must match its parent package, while a shadow's version can increment over time.
After you have determined what kind of changes you need to make, use the following sections for instructions on deriving and shadowing.
As previously stated, the process of creating a derived package starts by creating a full shadow of the original package, including the recipe and all other package source files. Then, you can check out the shadow, remove anything that should stay the same, modify the files that should be different, and adjust the recipe to add your customizations.
rBuild automates several of these tasks, and it is the recommended way to derive
packages. You can also use cvc shadow and a series of manual steps. The
sections that follow provide instructions for each of these options.
If you're developing appliances with rBuilder, you should use rBuild when deriving packages. If you haven't yet, see how rBuild is used in the rBuilder Package and Automation guide associated with your version of rBuilder, published at docs.rpath.com/rbuilder. This document is an assumed prerequisite to the information in this section.
Use the --derive option with rbuild checkout to
create the derived package. Change to the Development stage directory of your appliance
checkout to run the command, and use the appropriate label or full version string to
identify the parent branch from which you're deriving. The following shows deriving the
splashy-theme package from the rPath Linux platform to the Example appliance:
$> cd example-1/Development $> rbuild checkout --derive splashy-theme=conary.rpath.com@rpl:2 $> ls group-example-appliance splashy-theme $> cd splashy-theme $> ls CONARY _ROOT_ splashy-theme.recipe
rBuild automatically makes a checkout with your new derived package. Here's what you'll have in that checkout:
CONARY state file, as in all packages and groups (Do not modify or remove this file.)
_ROOT_ directory with a copy of all the files as they would be installed on the target system (This represents the files that will be installed and managed by the final package build on the parent branch.)
The package recipe file, recreated as a derived package recipe that uses the same package name and version
If you need to modify a file, copy it from the _ROOT_ directory
your package checkout alongside the recipe file. Then, make your modifications to that
copy, and add an r.addSource line to your package recipe to add that
file to the appropriate location on the target filesystem.
Do not make your changes directly in the _ROOT_ directory. Leave that directory as the representation of the package which you are deriving.
After you make your adjustments, build your derived package as you would any other package for your appliance. Note that you may see a warning that you have not yet added the derived package to your appliance group recipe:
$> rbuild build packages splashy-theme
Be sure to add your derived package to your appliance. If you are editing your recipe
directly (recommended), use r.add or r.replace as
approriate. Even if the package was originally added automatically from your platform
repository, you will need to use an r.replace line to indicate that the
package should come from your appliance repository instead:
class OverrideRecipe(FactoryRecipeClass):
def addRecipePackages(r):
r.replace('splashy-theme')
See Section 3.1.1.3, “Updaing Package Versions for Derived Packages” for information about using newer versions of the parent branch over time, including examples of derived package recipes, and see Section 3.2, “Merging Changes from Upstream” for instructions on bringing in upstream changes from the parent branch.
If you're packaging for Conary outside of rBuilder's recommended appliance development work, you may also want to use Conary's cvc commands to derive the package. You can do this in three steps:
Use cvc shadow to shadow the package from the "parent" label to
your own development label...
Check out the shadowed package in your Conary context where you are doing other packaging work.
Use cvc remove to remove any of the packaged files in the
checkout that you do not need to modify from the original
package.
Modify the files that you do need to modify, and add files if necessary.
Modify the recipe to change it to a derived package recipe, using the following steps:
Remove any method calls not related to the modifications you made to the package files. Typically, this means you would remove all the method calls except for those that directly affect the files you modified.
Add any method calls needed to apply the changes, such as addSource() lines to add new files.
Change the inherited package recipe class to DerivedPackageRecipe. DO NOT modify the package name or version from the original recipe. This is critical to ensure that Conary can find the correct binary of the original package on the parent branch.
After you modify the checkout of your derived package, build and test it as you would any other package. See Section 3.1.1.3, “Updaing Package Versions for Derived Packages” for examples of derived package recipes, and see Section 3.2, “Merging Changes from Upstream” for instructions on bringing in upstream changes from the parent branch.
To use your new derived package, be sure to install the package from your derived label rather from the parent label. Use r.add() or r.replace() as appropriate when adding the package to groups.
Because the derived package is a completely new package created from a shdow, there is
no need to merge changes from the parent branch. However, when the parent branch releases
a new version of the package, you may want to update the version line
in your derived package recipe, and then rebuild the package to derive from that newer
version:
class SplashyTheme(DerivedPackageRecipe):
name = 'splashy-theme'
version = '0.3.5'
def setup(r):
r.addSource('background.png', dest='%(datadir)s/splashy/themes/background.png')
r.addSource('background.png', dest='/boot/extlinux/background.png')
class SplashyTheme(DerivedPackageRecipe):
name = 'splashy-theme'
version = '0.4.1'
def setup(r):
r.addSource('background.png', dest='%(datadir)s/splashy/themes/background.png')
r.addSource('background.png', dest='/boot/extlinux/background.png')
See Section 3.2, “Merging Changes from Upstream” for instructions on bringing in upstream changes from the parent branch.
When you use a full shadow instead of a derived package, your package build will perform the original build actions used to build the package, just with your modifications added. This is usually only necessary if you need to change the way the package builds, such as by adding compiler options.
rBuild is the recommended way to derive packages for those developing appliances with
rBuilder. You can also use cvc shadow, especially if you are packaging
separate from an appliance. The sections that follow provide instructions for each of these
options.
If you're developing appliances with rBuilder, you should use rBuild when shadowing packages. If you haven't yet, see how rBuild is used in the rBuilder Package and Automation guide associated with your version of rBuilder, published at docs.rpath.com/rbuilder. This document is an assumed prerequisite to the information in this section.
Use the --shadow option with rbuild checkout to
shadow the package to your appliance repository. Change to the Development stage directory
of your appliance checkout to run the command, and use the appropriate label or full
version string to identify the parent branch from which you're shadowing. The following
shows shadowing the splashy package from the rPath Linux platform to the Example
appliance:
$> cd example-1/Development $> rbuild checkout --derive splashy=conary.rpath.com@rpl:2 $> ls group-example-appliance splashy-theme splashy
rBuild automatically makes a checkout with your new derived package. Change to the checkout to work with the package files, making the modifications you need.
After you make your adjustments, build your modified shadow just as you would any other package for your appliance. Note that you may see a warning that you have not yet added the shadowed package to your appliance group recipe:
$> rbuild build packages splashy
Be sure to add your modified shadow package to your appliance. If you are editing your
recipe directly (recommended), use r.add or
r.replace as approriate. Even if the package was originally added
automatically from your platform repository, you will need to use an
r.replace line to indicate that the package should come from your
appliance repository instead:
class OverrideRecipe(FactoryRecipeClass):
def addRecipePackages(r):
r.replace('splashy-theme')
r.replace('splashy')
See Section 3.2, “Merging Changes from Upstream” for instructions on bringing in upstream changes from the parent branch.
If you're packaging for Conary outside of rBuilder's recommended appliance development work, you may also want to use Conary's cvc commands to shadow the package. You can do this in three steps:
Use cvc shadow to shadow the package from the "parent" label to
your own development label...
Check out the shadowed package in your Conary context where you are doing other packaging work.
Modify the packaged files as needed, just as in other packaging work.
After you modify the checkout of your shadow, build and test it as you would any other package.
To use your new shadow, be sure to install the package from your shadowed label rather from the parent label. Use r.add() or r.replace() as appropriate when adding the package to groups.
See Section 3.2, “Merging Changes from Upstream” for instructions on bringing in upstream changes from the parent branch.