Conary:Group Scripts
From rPath Wiki
|
Starting with version 1.1.20, Conary includes the group script feature for group recipes to run scripts when Conary install, update, and rollback commands are performed on the group. This feature is available for groups only (not for packages). The following shows example syntax for including group scripts in a group recipe:
class GroupExample(GroupRecipe) name = 'group-example' def setup(r): r.addPreUpdateScript(contents = '''#!/bin/bash echo now > /tmp/state ''') r.setCompatibilityClass(2, groupName = 'group-example') r.addPostInstallScript(contents = '''#!/bin/bash echo now > /tmp/state ''', groupName = 'group-example') r.addPostUpdateScript(contents = '''#!/bin/bash echo now > /tmp/state ''') r.addPostRollbackScript(contents = '''#!/bin/bash echo now > /tmp/state ''', toClass = 1)
Methods
Developers can use one of each kind of script per group: one for the group created by the group recipe, and one for each additional group created in the group recipe. Use the following methods to include group scripts:
| setCompatibilityClass(<compatibility class>, groupName = <sub-group name>) | Set the compatibility class of the group groupName is an optional argument to attach the script to an additional group created in the recipe (the default group can be set by r.setDefaultGroup()) Read more |
| addPreUpdateScript(contents = <script>, groupName = <sub-group name>) | Run the script when a Conary update is launched on the group, before Conary starts the update groupName is an optional argument to attach the script to an additional group created in the recipe (the default group can be set by r.setDefaultGroup()) Read more |
| addPostInstallScript(contents = <script>, groupName = <sub-group name>) | Run the script after the group is initially installed groupName is an optional argument to attach the script to an additional group created in the recipe (the default group can be set by r.setDefaultGroup()) Read more |
| addPostUpdateScript(contents = <script>, groupName = <sub-group name>) | Run the script after a Conary update on the group groupName is an optional argument to attach the script to an additional group created in the recipe (the default group can be set by r.setDefaultGroup()) Read more |
| addPostRollbackScript(contents = <script>, groupName = <sub-group name>, toClass = <compatibility class>) | Run the script after a Conary rollback on the group groupName is an optional argument to attach the script to an additional group created in the recipe (the default group can be set by r.setDefaultGroup()) Read more toClass is an optional argument to define which compatibility classes (default value is 0) Read more |
Script Syntax
The script uses Python's multiple-line quote syntax (triple single quotes) to allow the contents to span multiple lines.
r.addPreUpdateScript(contents = '''#!/bin/bash echo now > /tmp/state ''')
Be aware that the syntax between the triple single quotes is independent of Python formatting and should reflect the desired contents of the script. For example, there should be no newline after the opening triple single quotes and before the line defining the shell interpreter ("shebang"). Also, Python's normal indentation is not necessary between the triple single quotes.
Group Name
Use groupName, optional in each function, to attach the script to an additional group defined in the recipe, such as a sub-group or related group. If a groupName value is not specified, the script is attached to the primary group associated with the recipe.
r.addPostInstallScript(contents = <script>, groupName = 'group-example')
Compatibility Classes
Compatibility classes can be set in a group to instruct Conary what rollbacks a group should be able to perform. If no compatibility class is specified, it is assumed to be zero (0). Because of this assumption, all groups created without setCompatibilityClass are in compatibility class zero.
Use setCompatibilityClass with the compatibility class value that should be associated with this version of the group recipe.
Use the toClass optional argument for addPostRollbackScript to declare which compatibility classes in previous group versions can keep their rollbacks available if they are updated to this group version. If the group that is updated to this version is of a compatibility class not specified in this version, the rollbacks will be invalidated, making them no longer available for Conary (or rAP) rollback operations.
For example, suppose this group version is set to compatibility class 2 and has a post rollback script with toClass with the single value of 1:
r.setCompatibility(2, groupName = 'group-example') r.addPostRollbackScript(contents=<script>, toClass = 1)
The following results would occur if groups of compatibility classes 0 and 1 update to this group version:
- If the group is updated from compatibility class 0, the rollbacks would be invalidated and no longer available. Rollback data is preserved even though rollbacks are unavailable.
- If the group is updated from compatibility class 1, the rollbacks would be available.
Scripts are run regardless of the compatibility classes defined. Developers should use the environment variables to determine if compatibility class has changed.
If the post-rollback script handles multiple compatibility classes, the toClass argument can be a list of integers.
Execution Process
Conary writes all scripts to its temporary directory (set to /tmp) and executes them from there.
Script Actions During Updates
The pre update script always runs before any update that includes the group. Pre update scripts run in an undetermined order, though all pre update scripts attached to a group will execute before those attached to its subgroups.
Only one of the post scripts runs, based on the action taken in Conary (install, update, or rollback). The database is available for Conary query operations while pre and post scripts are running.
Conary's update sequence is as follows:
- Run the pre update scripts for the target group version
Example: When updating from version 1 to version 2, run the pre update scripts for version 2. - Update individual packages and subgroups under the group to match the target group version
Example: When updating from version 1 to version 2, update the installed components managed by group version 1 to match group version 2 (including adding any components that were not in version 1 or removing any components that are not in version 2) - Update the group itself to the target version
Example: When updating from version 1 to version 2, change the installed version information to version 2. - Run the post update scripts from the target version
Example: When updating from version 1 to version 2, run the post update scripts for version 2.
In Conary 2.0.7 and earlier, no pre or post update scripts are executed at the time of a rollback. In Conary 2.0.8 and later, when a group is rolled back to a previously installed version, Conary runs the pre and post update scripts for that earlier version, though in a different sequence than used during updates. Conary's rollback sequence in version 2.0.8 and later is as follows:
- Run the pre update scripts from the previously installed version
Example: When rolling back to version 1 from version 2, run the pre update scripts from version 1. - Update the group itself to the previously installed version
Example: When rolling back to version 1 from version 2, change the installed version information back to version 1. - Run the post update scripts from the previously installed version
Example: When rolling back to version 1 from version 2, run the post update scripts from version 1. - Update individual packages and subgroups under the group to match the previous group version
Example: When rolling back to version 1 from version 2, ensure all the installed components managed by version 2 of the group are rolled back to the components specified in version 1 of the group (including are removing them if they do not exist in version 1, or adding them if they do not exist in version 2) - Run the post rollback scripts for the group version prior to the rollback
Example: When rolling back to version 1 from version 2, run the version 2 rollback script
Reference how group scripts fit into the process of updating a group.
| Conary group redirects are always considered new group installs, even if the group name is the same as a currently installed group. |
Scripts are run only if they are provided in the update target. If an installed group does not have a script, but an update to the group includes one or more scripts, the new scripts are run as provided in the group recipe (including any pre update scripts). Likewise, if an installed group has scripts, but an update to the group does not, no scripts are run.
Points of Failure Considerations
Scripts must return an exit code of 0 to indicate success; any other value is interpreted as a failure. Consider these other points of failure:
- If an install fails for a package in the group, the entire update operation is aborted, and Conary takes no further actions. If a pre-update script is associated with a group that has not yet been updated, the pre-script will be re-executed when the update process is restarted.
- If a pre-update script fails, the entire update operation is aborted, and Conary takes no further actions. Since a pre-update script can possibly run several times, the developer should take care to write pre-update scripts in a manner that makes them robust when run multiple times.
- Failures in post scripts are ignored, though they are reported to the user.
The post-rollback script for a group is guaranteed to be run if at least part of the group was installed. If a group update fails after installing some of the packages, and the update operation is resumed, the rollback script may be executed multiple times. The reason for this is the fact that the script is probably trying to undo a certain action for a package that may have been installed already.
To deal with the potential for multiple execution, rollback scripts should be designed to be idempotent - that is, running them a second time should not result in negative effects. If the post-rollback scripts depend on the current version of the appliance, they should confirm that the appliance is currently at the state that they expect.
Environment Variables
Recall that a group is unique given its Conary name, version, and flavor. These environment variables are set during the run of all scripts:
- CONARY_NEW_NAME
- CONARY_NEW VERSION
- CONARY_NEW_FLAVOR
- CONARY_NEW_COMPATIBILITY_CLASS
These environment variables are set during the run of all scripts when an installed (old) group is updated or rolled back:
- CONARY_OLD VERSION
- CONARY_OLD_FLAVOR
- CONARY_OLD_COMPATIBILITY_CLASS
The PATH environment variable for all scripts is set to /usr/bin:/usr/sbin:/bin:/sbin. No additional environment variables are set unless they are set by the script itself or the script interpreter.
Conary Developer Notes
If a root is specified during an update (using --root), scripts are executed in a change root (chroot) if the process is running as root. Otherwise the scripts are silently ignored.
Use --tag-script <filename> with a conary update command to write all scripts to /tmp and to generate the tag script file <filename> to run them. When the option is used, the tag script file and group scripts are not run. Also, pre script invocations are commented out in the tag script as they are normally used for initial installs.
Pre script invocations should be self contained. A group script can be updated from any previous version (including absolutely nothing for a fresh install). Making assumptions about what libraries will be available leads to errors. A pre-update script failure prevents the group from being installed (see Points of Failure Considerations)
