[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [p2-dev] Custom touchpoints, metaRequirements, and the collect phase

Great post, thanks David.

Before I get into answering questions you mention bug 275404 and I really would suggest anyone writing custom touchpoints and actions to follow that bug.

> David Kennedy

> Greetings,
> We have a question about the interaction between metaRequirements and
> the collect phase of p2 installation.
> Right now, we are trying to implement a set of custom touchpoint actions
> to install binary artifacts (similar to the native unzip and cleanupzip
> actions, but with a number of additional behaviours). In order to get
> this working, we are using the metaRequirements elements in content.xml
> to ensure that the IU containing the custom touchpoint actions is
> installed and activated before attempting to install the binary
> artifacts IUs.
> Here are a few snippets from the content.xml:
> ===========================
> <unit id='com.test.p2.install' version='1.0.0'>
>   ...
>   <provides size=7>
>     <provided namespace='org.eclipse.equinox.p2.engine.actions'
> name='com.test.p2.install.installzip' version='1.0.0'/>
>     <provided namespace='org.eclipse.equinox.p2.engine.actions'
> name='com.test.p2.install.uninstallzip' version='1.0.0'/>
>     ...
>   </provides>
>   ...
> </unit>
> <unit id='com.test.binaryfiles_root' version='1.0.0'>
>   <metaRequirement size='2'>
>     <required namespace='org.eclipse.equinox.p2.engine.actions'
> name='com.test.p2.install.installzip' range='[1.0.0,1.0.1)'/>
>     <required namespace='org.eclipse.equinox.p2.engine.actions'
> name='com.test.p2.install.uninstallzip' range='[1.0.0,1.0.1)'/>
>   </metaRequirement>
>   <provides size='1'>
>     <provided namespace='org.eclipse.equinox.p2.iu'
> name='com.test.binaryfiles_root' version='1.0.0'/>
>   </provides>
>   <artifacts size='1'>
>     <artifact classifier='binary' id='com.test.binaryfiles_root'
> version='1.0.0'/>
>   </artifacts>
>   <touchpoint id='org.eclipse.equinox.p2.native' version='1.0.0'/>
>   <touchpointData size='1'>
>     <instructions size='2'>
>       <instruction key='install'
> import='com.test.p2.install.installzip'>
>         installzip(source:@artifact, target:${installFolder});
>       </instruction>
>       <instruction key='uninstall'
> import='com.test.p2.install.uninstallzip'>
>         uninstallzip(source:@artifact, target:${installFolder});
>       </instruction>
>     </instructions>
>   </touchpointData>
> </unit>
> ===========================
> We are concerned about this line:
>   <touchpoint id='org.eclipse.equinox.p2.native' version='1.0.0'/>
And rightly so. For now, I'd suggest using it or otherwise you'll end up having to clone the collect action.

Going forward I think we might consider moving the code in the native collect action directly into the collect phase and using it as default behavior.

> Here is why we seem to need this line:
> Our installzip action is looking for the artifact file when it starts.
> In theory, this artifact file should have been downloaded during the
> collect phase. In the current implementation, we are specifying the
> native touchpoint, meaning that the native touchpoint downloads the file
> in its collect action, and our installzip action grabs it from the
> native plugin's download cache.
> We have tried the following to eliminate this dependency on the native
> touchpoint:
> 1. Specify our own touchpoint instead of org.eclipse.equinox.p2.native,
> and implement (read clone) the collect action that performs the same
> actions as in the native touchpoint. When we do this, P2 complains that
> the touchpoint is unknown when it try to install the IU. Obviously, the
> com.test.p2.install IU has not been installed yet, because we are only
> at the collect phase.
Hmm... this should work as we can dynamically install a touchpoint as part of the metaRequirements. One of the examples I posted for our teams test runs does this since the bundle that contains the metaRequired actions also contains a touchpoint that's needed by the actions. I'll do some more testing this weekend but again I'm pretty sure this works so I'm not sure what went wrong.

Also instead of cloning the Collect action you might use "qualifyAction" to turn a request for "collect" into "org.eclipse.equinox.p2.touchpoint.natives.collect" Take a look at EclipseTouchpoint.qualifyAction to get some ideas.

> 2. Specify no touchpoint (<touchpoint id='null'/>). Specify an
> <instruction key='collect'...> similar to the install and uninstall
> instructions. Implement (clone) the collect action. Again, P2 complains
> that the collect action is unknown when it try to install the IU. Again,
> we think that this is because the IU has not been downloaded and
> installed before the collect phase.
I like this approach. Not sure why the touchpoint/actions were not automagically installed.

> Here is why we are concerned:
> This creates an implicit dependency on the native touchpoint behaviour.
> If the native touchpoint's download cache implementation ever changes,
> our installzip action might stop working.
> Here are our questions:
> 1. Can we safely assume that the native touchpoint's download cache
> implementation will never change?
I think you can rely on the implementation changing. What I'm hoping you can rely on is that there will be a download cache where you can lookup your artifact's location. We'll likely make some effort to keep things consistent but follow the changes in 275404 and ideally work with us to make sure we do the right thing.

> 2. Is there a better way to do this?
> 3. Or is this the intended way of doing things?

I think the best way for "now" is to use the native touchpoint/native collect action. Finding the artifact location is probably best done by Util.getDownloadCacheRepo as I think we might have changes in the repo backing the download cache. These changes will be discussed in 275404.

> In some ways, this relates to issue 275404
> (https://bugs.eclipse.org/bugs/show_bug.cgi?id=275404). There is no
> default handling of artifacts, so the touchpoint is responsible for
> downloading the artifact during the collect phase. Using
> metaRequirements to activate an IU required to install another IU only
> occurs during the install phase (as we understand it), so there is no
> way for a custom touchpoint to do anything during the collect phase
> unless the IU is installed separately.

Hmm, you shouldn't have to worry about collect vs. install. When metarequirements are involved we end up doing the operation in two transactions:
1) First, we install the IUs to satisfy the metarequiremnts and apply the configuration
2) Second, we install the IUs we were asked to install in the first place and where needed use the newly install actions (if that's what the metarequirements brought in)

This is made to appear seamless in the UI so it appears to happen in one shot. By the time the second transaction starts the touchpoints/actions are available for all phases.

> i.e. it seems that the current metaRequirements mechanism for supporting
> custom touchpoints is not sufficient for handling IUs containing
> artifacts, unless the native touchpoint's collect behaviour can be used
> and trusted not to change.
> Unless we are missing something, of course.
I think you generally are on the right track and have correctly identified a real problem. The good news is that we're also very much aware of it and planning to do something about it in the maintenance release. For now, and until the maintenance release is available unfortunately I think the safest approach is to depend on the native touchpoint, it's collect action, and it's artifact lookup behavior.