When you are creating several packages or groups that repeat a lot of the same recipe code, you can create a factory of your own to reduce the amount of recipe code you have to maintain for each package. To create and use factories, you can still work with rBuild and rMake for building, but you must create the package with Conary's native cvc newpkg command.
Use the following steps and template to create your own factory:
Change to the context where you want to develop your factory, such as your appliance's Development checkout. In that directory, use the following command to create the factory, replacing sample-types with the name of your choice:
$> cvc newpkg --factory=factory factory-sample-types
Change to the new factory's subdirectory and open its recipe file for editing. For factory-sample-types, the recipe should be factory-sample-types.recipe.
Start with the following template, and use its included comments as a guide to developing your new factory:
# FACTORY TEMPLATE # Replace the SampleTypesFactory class name with your desired # factory class name class SampleTypesFactory(Factory): def getRecipeClass(self): # Designate a manifest file to be used with the factory # when applicable. This example assumes the manifest file # is a text file with a list of filenames or URIs. # manifest = self.openSourceFile('manifest') # Because your manifest is read as a string from the above # line of code, set another variable that will separate that # string by newline characters and create a parse-friendly # list of the items in your manifest file. # manifestLines = [ x.strip() for x in manifest.readlines() ] # The common recipe code for packages using this factory # goes here. Replace "CustomRecipeClass" with your desired # custom class name. Also, replace "PackageRecipe" with # "GroupRecipe" if you are defining a factory for groups. # class CustomRecipeClass(PackageRecipe): # Repeatable items for the recipe go here, including # any actions taken on the manifest contents. The # example here assumes that the file list from # manifest should be unpacked in /srv/ # def setup(r): for fileURI in manifestLines: r.addArchive(fileURI, '%(servicedir)s/') # The return value for the factory is the recipe class # you just defined. Replace "CustomRecipeClass" with the # class name you defined above. # return CustomRecipeClass
Add your new recipe file to Conary's version control (cvc add), and then check in the factory (cvc ci). No build process is necessary as all you're doing is creating code that gets used by other packages or groups. The following shows these two commands for factory-sample-type:
$> cvc add factory-sample-type.recipe $> cvc ci
The contents of your factory is up to you. If you're new to Python, you'll probably want to grab a reference to Python syntax and programming to use as a guide, such as Dive Into Python, available online at diveintopython.org. Here are just a few of the things you can add to your factory to optimize your automation experience:
Automate setting the package name and version: In your factory class, either before or after your getRecipeClass method, define a method that will look through the contents of your manifest file (parts of file names) and return the appropriate package name and version value that Conary should use when creating your package. Then, call that method in getRecipeClass to set variables like pkgname and pkgversion, which you can use in factory's custom recipe where you might otherwise use %(name)s and %(version)s.
Provide an override recipe option for each package: In your factory's custom recipe, before or after the setup method, define methods that can potentially override or supplement your factory's actions. Start by leaving them blank (use the keyword "pass" as the only thing in the method), as in the following:
def preProcess(r): pass def postProcess(r): pass
Then, in the setup method itself, call these at the beginning and end of your code, as in the following:
def setup(r):
r.preProcess()
# Other recipe actions
r.postProcess()
With this code in place, you can create a target package to use your custom factory that can, when necessary, include an override recipe like those you can write against rPath's factories (see Section 6.1, “Find and Use Factories from rPath”).
If you are creating a factory to generate a group recipe (instead of a package recipe), these steps are similar. For a group, you might choose to make your manifest file a list of packages to include in your group.