Jump to: navigation, search

Equinox/p2/Engine/Touchpoint Instructions

Under update for 3.5

Introduction

A p2 Installable Unit (IU) is installed using the facilities provided by a touchpoint. The IU metadata consists of a reference to the touchpoint (Touchpoint Type) which also defines the version of the touchpoint (i.e an expectancy that it supports a certain set of operations), and describes instructions to execute in various p2 engine phases. The instructions are named after the phases - the phases "install", "uninstall", "configure", "unconfigure" are of interest when authoring, but there are also some internal phases such as "collect" and "checktrust" executed by the engine. Each instruction (e.g. "install") describes a sequence of actions to execute on the referenced touchpoint. Examples of actions are create and remove directories, change permissons, install and remove bundles. Currently, two touchpoints (native, and eclipse) have been implemented. The native touchpoint has approximately 5 different actions, and the eclipse touchpoint has approximately 20. Most of these actions take parameters. This wiki page describes these actions in detail.

The instructions are grouped and described in a Touchpoint Data Element. The touchpoint data element uses a Map where the key is the name of a p2 engine phase (such as "install"), and the value is a string representation of a sequence of actions. Using multiple touchpoint data elements is useful as it allows separation between sets of actions for install/uninstall/configure/unconfigure which makes it easier to maintain the meta data.

This wiki page describes the two touchpoints, the instructions they understand, and the format used to represent an action sequence.

Actions

Native Touchpoint Actions

The native touchpoint is used to install things "outside of eclipse".

instruction parameters description
cleanupzip source, target removes unzipped files and directories that where unzipped from source into target - i.e. an "undo operation" of an unzip instruction.
unzip source, target unzips the source into the target directory. The source can be the special @artifact source path, which denotes the download cache location for the first artifact key in the IU. Comments in code indicates that the use of @artifact may be deprecated.
mkdir path Creates the directory specified by the parameter path.
rmdir path Removes the directory specified by the parameter path. Action has no effect if the referenced directory contains files. Use the remove action for a forced recursive remove.
link targetDir, linkTarget, linkName, force Performs the system action ln -s with the parameters linkTarget being the source-file, targetDir is the directory where the symbolic link will be created, and linkName is the name of the resulting link in the targetDir. The force parameter is a boolean in string form (i.e. "true"/"false") and indicates if an existing link with the same name should be removed before the new link is created.
the parameter names are quite confusing
This action executes the system command ln -s, and is not available on platforms that does not have this (i.e. Windows)
chmod targetDir, targetFile, permissions, options Changes permission on a file using the system chmod command. The targetDir parameter is either a path, or the special @artifact which is a reference to the directory where the first artifact included in the installable unit is located. The parameter targetFile is the name of a file, and permissions is written like for the chmod system command. The options parameter is new since 3.5M6 and allows passing additional options like "-R" for recursive operation. If multiple parameters are needed separate them with a space (like on the command line).
This action executes the system command chmod, and is not available on platforms that does not have this (i.e. Windows)
remove path Removes a file, or a directory (and all files under this directory) as referenced by the parameter path.
(Since 3.5 M7)
copy source, target, overwrite Copies a file or a directory (and all of its content) denoted by source path to the target path.

The boolean flag overwrite should be set to true if the copy action should overwrite existing files. If overwrite is false the operation will fail with an IO error in the files already exists.
(Since 3.5 M7)

cleanupcopy source, target Cleans up what was installed earlier with a copy from source to target. I.e. this is an "undo" of a copy operation.


(Since 3.5 M7)

collect - collects all associated artifacts for an IU and places them in a local touchpoint addressable cache. This action is not meant to be called directly and is used as part of the main Collect and Sizing phases.

Eclipse Touchpoint Actions

instruction parameters description
collect - collects all associated artifacts for an IU and places them in a local touchpoint addressable cache. This action is not meant to be called directly and is used as part of the main Collect and Sizing phases.
installBundle bundle Installs a bundle artifact specified by the parameter bundle
uninstallBundle bundle Uninstalls a bundle artifact with a bundle-id specified by the paramter bundle
addSourceBundle bundle Installs a source bundle artifact with the bundle-id specified by the parameter bundle
removeSourceBundle bundle Removes/uninstalls the source bundle artifact with the bundle-id specified by the parameter bundle
installFeature feature, featureId, version Installs the feature referenced by the parameter feature (matched against artifacts in the iu). The feature is installed with the id specified by the parameter featureId, or if this parameter has the value default, with the id specified in the artifact referenced by feature. The features is installed with the version specified in version, or with the version specified in the artifact referenced by the feature parameter if the version parameter has the value default
uninstallFeature feature, featureId, version Uninstalls a feature. Parameters have the same meaning as for the command installFeature
setLauncherName name Sets the name of the launcher to name. The launcher name is used to configure launcher name specific ini files.
addProgramArg programArg Adds the string specified in the parameter programArg as an argument to the program. If the parameters is the special value @artifact, the location of the artifact referenced by the first artifact key in the IU is used as the parameter value.
removeProgramArg programArg Removes the program argument specified in the string programArg - if the parameters is the special value @artifact, the location of the artifact referenced by the first artifact key in the IU is used as the parameter value.
setStartLevel startLevel Sets the start level to the integer value specified in the parameter startValue
markStarted started Marks the bundle referenced by the first artifact key in the IU as started / not started, as controlled by the boolean parameter started (in string form i.e. "true"/"false").
setFrameworkDependentProperty propName, propValue Sets the framework dependant property named propName to the value specified in propValue. Framework dependent properties are properties specific to the Equinox implementation of the OSGi framework.
setFrameworkIndependentProperty propName, propValue Sets the framework independant property named propName to the value specified in propValue. Framework independent properties do not specifically target Eclipse and are generally applicable to other OSGi frameworks.
setProgramProperty propName, propValue Sets the program property named propName to the value specified in propValue. Program properties are used by the executable program to among other things locate the jars needed to start Eclipse.
addJVMArg jvmArg Adds the string specified in the parameter jvmArg to the arguments passed to the JVM.
removeJVMArg jvmArg Removes the string specified in the parameter jvmArg from the arguments passed to the JVM.
checkTrust - collects the set of bundle files on which the signature trust check should be performed. The checkTrust action is not meant to be user callable and is done as part of the CheckTrust phase.
addRepository location, type, enabled Adds the repository at location of type type to the list of known repositories. The repository will then be available when installing or updating the profile in the future. The enabled parameter takes a boolean value ("true" or "false") indicating whether the add repository should be enabled. The value of the location parameter must be a well-formed URI. The type parameter value must be the value of one of the IRepository.TYPE_* constants, Specifically, type "0" indicates a metadata repository, and type "1" indicates an artifact repository.
removeRepository location, type Removes the repository at location of type type from the list of known

repositories. The value of the location parameter must be a well-formed URI. The type parameter value must be the value of one of the IRepository.TYPE_* constants, Specifically, type "0" indicates a metadata repository, and type "1" indicates an artifact repository.

Action Format

The Touchpoint Data Element has a Map that describes the actions to execute in the various p2 engine phases (e.g. "install", "uninstall", "configure", "unconfigure", "collect" and "checktrust"). The key of the Map entry is the name of a phase (i.e. when the actions should be executed), and the value is a statement-sequence:

  statement-sequence :
      | statement ';'
      | statement-sequence statement
      ;

Where a statement is of the format:

  statement :
      | actionName '(' parameters ')'
      ;
  parameters :
      | // empty
      | parameter
      | parameters ',' parameter
      ;
   parameter : 
      | paramName ':' paramValue
      ;

 actionName, paramName, paramValue :
      | String 
      ;

In the p2 engine, the Phase will lookup the "actionName" using it's own phase specific actions (e.g. "collect") and also those made available by the associated touchpoint (e.g. "mkdir" in the native touchpoint, and "installBundle" in the Eclipse touchpoint) .

As an example - an "install" instruction for a bundle might consist of the following statement:

  installBundle(bundle:${artifact});
  • installBundle is the action name
  • bundle is the parameter name
  • ${artifact} is the parameter value. The value ${artifact} signifies the use of a pre-defined variable named "artifact".

Built-in Action Variables

What follows is a catalog of the variables made available by the phases and touchpoints. Many of these are mostly useful to the implementor of new actions and touchpoint types.

Variables Available in all phases

variable description
#nnnn the unicode value of a character.

Note: This is especially important for the six characters that require escaping.

  1. $ = ${#36}
  2. , = ${#44}
  3.  : = ${#58}
  4.  ; = ${#59}
  5. { = ${#123}
  6. } = ${#125}
profile the profile being modified.
phaseId the name of the phase e.g. collect, install, etc.
operand the actions operand (e.g. IU pair)
touchpoint the touchpoint associated with the IUs in the operand

Variables Available in all installable unit phases

e.g. collect, unconfigure, uninstall, install, configure, ...

variable description
installFolder the root folder for this profile.

Collect Phase Variables

variable description
artifactRequests A list that a touchpoints "collect" action will use to add mirroring requests to.

Unconfigure Phase Variables

variable description
iu The IU being unconfigured. This is set from the first IU of the operand pair.
artifact The artifact id of the first artifact listed in the IU.

Uninstall Phase Variables

variable description
iu The IU being uninstalled. This is set from the first IU of the operand pair.
artifact The artifact id of the first artifact listed in the IU.

Install Phase Variables

variable description
iu The IU being installed. This is set from the second IU of the operand pair.
artifact The artifact id of the first artifact listed in the IU.

Configure Phase Variables

variable description
iu The IU being configured. This is set from the second IU of the operand pair.
artifact The artifact id of the first artifact listed in the IU.

Eclipse Touchpoint Variables

variable description
manipulator an instance of the Manipulator class used to alter the configuration of an Eclipse install.

Native Touchpoint Variables

variable description
backup the BackupStore used to save transaction state during native file operations.

Authoring touchpoint data

Touchpoint advice file format

An Installable Unit can be augmented at generation timeby writing a p2 advice file (p2.inf). The format of this file is java properties file containing key=value pairs.

Two special value parameters are supported:

  1. $version$ - returns the string form of the containing IU's version
  2. $qualifier$ - returns just the string form of the qualifier of the containing IU's version

For the 3.5 release the p2.inf file can be use to augment an Installable Units: capabilites, properties, and instructions. In addition support is provided for defining additional installable units that are in some way related to the container IU.

Capability Advice: There are three different type of capability advice:

  1. "provides" - these are capabilities that an IU will offer to satisfy the needs of other IUs
  2. "requires" - these are the capabilities that an IU requires from other IUs in order to resolve correctly
  3. "metaRequirements" - these are capabilities that the IU puts on the profile that must already be installed before this IU can be installed.

Capability advice will "replace" an existing capability of the same type on the IU if the name/namespace match.

 provides.<#>.namespace = <namespace>
 provides.<#>.name = <name>
 provides.<#>.version = <version> (optional / default: 1.0.0)
 requires.<#>.namespace = <namespace>
 requires.<#>.name = <name>
 requires.<#>.range = <range> [[(optional / default: 0.0.0]
 requires.<#>.greedy = <true|false> (optional / default: true
 requires.<#>.optional = <true|false> (optional / default: false
 requires.<#>.multiple = <true|false>  (optional / default: false
 metaRequirements.<#>.namespace = <namespace>
 metaRequirements.<#>.name = <name>
 metaRequirements.<#>.range = <range> (optional / default: 0.0.0
 metaRequirements.<#>.greedy = <true|false> (optional / default: true
 metaRequirements.<#>.optional = <true|false> (optional / default: false
 metaRequirements.<#>.multiple = <true|false>  (optional / default: false

Where <#> is an index for the property, <namespace>, and <name> are the associated named strings, <version> and <range> are version and version range strings respectively.

For example:

 provides.0.namespace = testNamespace1
 provides.0.name = testName1
 provides.0.version = 1.2.3.$qualifier$
 provides.1.namespace = testNamespace2
 provides.1.name = testName2
 provides.1.version = $version$
 requires.0.namespace = testNamespace1
 requires.0.name = testName1
 requires.0.range = [1.2.3.$qualifier$, 2)
 requires.0.greedy = true
 requires.0.optional = true
 requires.0.multiple = true
 requires.1.namespace = testNamespace2
 requires.1.name = testName2
 requires.1.range = [$version$, $version$]
 requires.1.greedy = false
 metaRequirements.0.namespace = testNamespace1
 metaRequirements.0.name = testName1
 metaRequirements.0.range = [1.2.3, 2)
 metaRequirements.0.greedy = true
 metaRequirements.0.optional = true
 metaRequirements.0.multiple = true
 metaRequirements.1.namespace = testNamespace2
 metaRequirements.1.name = testName2
 metaRequirements.1.range = $version$
 metaRequirements.1.greedy = false

Property Advice:

 properties.<#>.name = <propertyName>
 properties.<#>.value = <propertyValue>

Where <#> is an index for the property, <propertyName>, and <propertyValue> hold the name and value strings for the property.

For example:

 properties.0.name = testName1
 properties.0.value = testValue1
 properties.1.name = testName2
 properties.1.value = testValue2

Touchpoint Instruction Advice:

 instructions.<phase> = <raw actions>
 instructions.<phase>.import = <qualified action name> [,<qualified action name>]* (optional)

Where <phase> is a p2 phases (collect, configure, install, uninstall, unconfigure, etc).

Note:

  • The <raw actions> will be "appended" to the end of any instructions already being generated.
  • The qualified action names for the IU's touchpoint type are implicitly imported. All other actions need to be imported.

For example:

 instructions.install = \
    ln(targetDir:@artifact,linkTarget:foo/lib.1.so,linkName:lib.so);\
    chmod(targetDir:@artifact,targetFile:lib/lib.so,permissions:755);
 instructions.install.import= \
    org.eclipse.equinox.p2.touchpoint.natives.ln,\
    org.eclipse.equinox.p2.touchpoint.natives.chmod


Additional Installable Unit Advice: In addition to customizing attributes of the containing IU one can also author addtional installable units that work with the container IU. Typically this mechanism is used to author an IUFragment that customizes the containing IU or one of it's dependencies.

 iu.<#>.id= <identifier> 
 iu.<#>.version= <version> (optional)

Where <#> is an index for the Installable Unit, so multiple Installable Units can be declared. A fairly full range of IU customizations are supported including:

 id
 version
 singleton
 copyright
 licenses
 filter
 touchpoint
 update
 artifacts
 properties
 provides
 requires
 metaRequirements
 hostRequirements - Providing a host requirement implies that this is an IUFragment
 instructions

To illustrate all the various settings for these customizations here's a more complete example of: (unit.0) a minimal IU and (unit.1) a full featured IU:

 units.0.id = testid0
 units.0.version = 1.2.3
 units.1.id = testid1
 units.1.version = 1.2.4
 units.1.singleton = true
 units.1.copyright = testCopyright
 units.1.copyright.location = http://localhost/test
 units.1.filter = test=testFilter
 units.1.touchpoint.id = testTouchpointId
 units.1.touchpoint.version = 1.2.5
 units.1.update.id = testid1
 units.1.update.range = (1,2)
 units.1.update.severity = 2
 units.1.update.description = some description
 units.1.artifacts.0.id = testArtifact1
 units.1.artifacts.0.version = 1.2.6
 units.1.artifacts.0.classifier = testClassifier1
 units.1.artifacts.1.id = testArtifact2
 units.1.artifacts.1.version = 1.2.7
 units.1.artifacts.1.classifier = testClassifier2
 units.1.licenses.0 = testLicense
 units.1.licenses.0.location = http://localhost/license
 units.1.properties.0.name = testName1
 units.1.properties.0.value = testValue1
 units.1.properties.1.name = testName2
 units.1.properties.1.value = testValue2
 units.1.requires.0.namespace = testNamespace1
 units.1.requires.0.name = testName1
 units.1.requires.0.range = [1.2.3.$qualifier$, 2)
 units.1.requires.0.greedy = true
 units.1.requires.0.optional = true
 units.1.requires.0.multiple = true
 units.1.requires.1.namespace = testNamespace2
 units.1.requires.1.name = testName2
 units.1.requires.1.range = $version$
 units.1.requires.1.greedy = false
 units.1.requires.1.optional = false
 units.1.metaRequirements.0.namespace = testNamespace1
 units.1.metaRequirements.0.name = testName1
 units.1.metaRequirements.0.range = [1.2.3.$qualifier$, 2)
 units.1.metaRequirements.0.greedy = true
 units.1.metaRequirements.0.optional = true
 units.1.metaRequirements.0.multiple = true
 units.1.metaRequirements.1.namespace = testNamespace2
 units.1.metaRequirements.1.name = testName2
 units.1.metaRequirements.1.range = $version$
 units.1.metaRequirements.1.greedy = false
 units.1.metaRequirements.1.optional = false
 units.1.provides.0.namespace = testNamespace1
 units.1.provides.0.name = testName1
 units.1.provides.0.version = 1.2.3.$qualifier$
 units.1.provides.1.namespace = testNamespace2
 units.1.provides.1.name = testName2
 units.1.provides.1.version = $version$
 units.1.instructions.configure = addProgramArg(programArg:-startup); addProgramArg(programArg:@artifact);
 units.1.instructions.unconfigure = removeProgramArg(programArg:-startup); removeProgramArg(programArg:@artifact);)
 units.1.instructions.unconfigure.import = some.removeProgramArg
 units.1.hostRequirements.0.namespace = testNamespace1
 units.1.hostRequirements.0.name = testName1
 units.1.hostRequirements.0.range = [1.2.3.$qualifier$, 2)
 units.1.hostRequirements.0.greedy = true
 units.1.hostRequirements.0.optional = true
 units.1.hostRequirements.0.multiple = true

Where the touchpoint advice file can be used

In Eclipse 3.4, touchpoint advice files were only supported in bundles. An advice file placed in the bundle at META-INF/p2.inf would be processed at PDE build time to add the instructions to the installable unit corresponding to the bundle. In Eclipse 3.5, touchpoint advice files can be placed:

  • In bundles (META-INF/p2.inf): The instructions are added to the installable unit for the bundle
  • In features (a p2.inf file co-located with the feature.xml): The instructions are added to the installable unit for the feature group
  • In products (a p2.inf file co-located with the .product file): The instructions are added to the root installable unit for that product.

Backup

Since 3.5 M7.
The Native Touchpoint stores a temporary backup of files that are deleted or overwritten during the installation process. If an installation succeeds the backup is simply removed. If however the installation fails, the files in backup are restored to their original location. If the restore works as expected, the backup copy is also removed. Two "disaster" cases remains:

  • It was not possible to restore files (probably because of faulty hardware, running of out disk, or manual tampering with files during the installation).
  • The system crashed during the install

The backup is placed in a directory under the directory referenced by the system property "java.io.tmpdir". The backup directory has a name with the prefix ".p2bu" which is followed by a unique key per running backup instance. Under the ".p2bu..." directory files are stored in a hierarchy that reflects their original location.

In both of the disaster cases, the backup store under java.io.tempdir will contain copies of all files that were not automatically restored. If a restore is wanted, this can be performed manually by copying the content back to their original position (which is evident from the structure under ".p2bu"). This can be made with tools like zip (simply zip everything relative to .p2bu, and the then unzip it from the real file system root).

In case something goes wrong during restore of a backup, the event is logged with details of what needs to be manually restored. (In case or a system crash, you are on your own though....)