Conary:Derived Packages
From rPath Wiki
|
Conary packagers can use derived packages to make a relatively small modification to an original package recipe without recompiling a complete shadow. A derived package inherits everything from the original package, then allows modifications to the inherited contents. At cook time, Conary obtains the compiled binary of the package from the parent branch, then applies the modifications specified in the derived package recipe.
Shadow or Derive?
If the modifications needed to the package involve things that cannot be done as a derived package, using a complete shadow is necessary. Such cases include:
- Recompiling with different options
- Changing the package version
- Building with new requirements
In all other cases, maintaining a shadow may not be necessary, and a derived package provides more efficient building and maintenance than a shadow.
Steps to Create a Derived Package
The basic steps to create a derived package are as follows:
- In the Conary build environment, shadow and check out the package from which to derive.
- Remove any files in the checkout that do not require modification.
- Modify any files other than the recipe that need modification.
- Modify the recipe to be a derived package recipe that does no more than incorporate the modifications.
- Check in (commit) and cvc cook or build the derived package just as with other packages. Be sure to use cvc add and cvc remove as necessary for files that were added or removed when modifying the shadow to make the derived package.
Derived Package Recipe
A derived package is adapted from an original package, so there is no need for a full recipe template to copy and adapt. The only actions required to adapt the package recipe to make it a derived package are:
- Remove any method calls not related to the modifications made by the derived package. Normally, remove all the method calls. The most likely exception is addSource() for a source file that you modify rather than remove from the package.
- 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 binary of the original package on the parent branch of the shadow.
- Implement the setup() method; DerivedPackageRecipe does not call methods such as configure(), make(), or makeinstall().
Example with httpd.conf
A common scenario in which derived packages would be useful is adapting httpd.conf in the package httpd. In this example scenario, developers can use the following steps to create a derived package that modifies only httpd.conf:
- Shadow and check out apache.
$> cvc shadow example.rpath.org@corp:devel httpd:source=conary.rpath.com@rpl:1/2.0.55-7
$> cvc co httpd=example.rpath.org@corp:devel
$> cd httpd - Remove all files in the checkout other than httpd.conf, which will be modified.
$> cvc remove index.html Makefile.ssl modssl-req.conf httpd.init.patch - Modify httpd.conf.
- Modify the recipe to do no more than install the modified httpd.conf file. (See the following example recipe.)
- Commit and cook the httpd package:
$> cvc ci
$> cvc cook httpd
The following is the derived package recipe used for this example:
class Httpd(DerivedPackageRecipe): name = 'httpd' version = '2.0.55' def setup(r): r.addSource('httpd.conf', macros=True, dir='%(sysconfdir)s/httpd/conf/')
In this example, Conary obtains compiled binary for version 2.0.55 of the httpd package on the label conary.rpath.com@rpl:1. It then applies the modifications specified in the derived package recipe.
Query Derived Packages
Use the --file-versions option with a cvc repquery command to see what files are different between original and derived packages.
In the following example, the user is querying httpd:runtime to see what has changed. The output shows that the file httpd.conf has a derived version on example.rpath.org@corp:devel while the file magic is obtained from the parent branch (conary.rpath.com@rpl:devel//1):
$> conary rq httpd:runtime=example.rpath.org@corp:devel --file-versions --full-versions /etc/httpd/conf/httpd.conf /conary.rpath.com@rpl:devel//1//example.rpath.org@corp:devel/2.0.55-7.0.1-1 /etc/httpd/conf/magic /conary.rpath.com@rpl:devel//1//2.0.54-2-2
Merging Updates from Upstream
Because the derived package is a completely new package, merging upstream changes is not a patch process applied to the upstream source. Instead, Conary just updates the derived package version to reflect the newer version of original package on the parent branch.
The following is an example of a merge and subsequent diff for the httpd derived package mentioned in the previous examples:
$> cvc merge
$> cvc diff
(working version) Mon Jan 15 14:00:39 2007 (no log message)
httpd.recipe: changed
Index: httpd.recipe
====================================================================
contents(sha1)
inode(mtime)
--- httpd.recipe /conary.rpath.com@rpl:devel//1//example.rpath.org@corp:devel/2.0.55-7.0.1
+++ httpd.recipe @NEW@
@@ -1,6 +1,6 @@
class Httpd(DerivedPackageRecipe):
name = 'httpd'
- version = '2.0.55'
+ version = '2.0.59'
def setup(r):
r.addSource('httpd.conf')
As after other merge operations, commit and cook the package after the merge operation.
