3.1 Shadowing and Deriving

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:

After you have determined what kind of changes you need to make, use the following sections for instructions on deriving and shadowing.

3.1.1 Derive a Package

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.

3.1.1.1 Derive with rBuild

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.

Leave _ROOT_ for reference

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.

3.1.1.2 Derive with Conary (cvc)

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:

  1. Use cvc shadow to shadow the package from the "parent" label to your own development label...

  2. Check out the shadowed package in your Conary context where you are doing other packaging work.

  3. Use cvc remove to remove any of the packaged files in the checkout that you do not need to modify from the original package.

  4. Modify the files that you do need to modify, and add files if necessary.

  5. Modify the recipe to change it to a derived package recipe, using the following steps:

    1. 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.

    2. Add any method calls needed to apply the changes, such as addSource() lines to add new files.

    3. 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.

3.1.1.3 Updaing Package Versions for Derived Packages

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.

3.1.2 Shadow a Package

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.

3.1.2.1 Shadow with rBuild

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.

3.1.2.2 Shadow with Conary (cvc)

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:

  1. Use cvc shadow to shadow the package from the "parent" label to your own development label...

  2. Check out the shadowed package in your Conary context where you are doing other packaging work.

  3. 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.