Home » Eclipse Projects » Equinox » Any way to force P2 to install new packages?
|
Re: Any way to force P2 to install new packages? [message #929601 is a reply to message #897617] |
Mon, 01 October 2012 15:49 |
Erik Emanuelsson Messages: 4 Registered: October 2012 |
Junior Member |
|
|
I do not know if this is still a problem for you, but as we recently implemented auto install and update functionality to our RCP app maybe I can contribute a bit in this area. The code is based on stuff from the org.eclipse.equinox.p2.examples.rcp-projects.
First we made it possible to get control of the available update sites by a help method.
/**
* Sets the update site list. Both enabled and disabled update sites can be added and the method also provides a flag that if set removes all previous
* update sites.
*
* @param enabledUpdateSites
* @param disabledUpdateSites
* @param clearExistingUpdateSites If set, all currently existing update sites are removed.
*/
public static void setUpdateSites( Collection<URI> enabledUpdateSites, List<URI> disabledUpdateSites, boolean clearExistingUpdateSites )
{
List<MetadataRepositoryElement> repositoryElements = new ArrayList<MetadataRepositoryElement>();
// AviXPlugin.getLog4J().debug( "setUpdateSitesClear BEGIN" ); //$NON-NLS-1$
// AviXPlugin.getLog4J().info( MessageFormat.format( "Clear existing update sites = {0}", clearExistingUpdateSites ) ); //$NON-NLS-1$
ProvisioningUI provisioningUI = ProvisioningUI.getDefaultUI();
if ( !clearExistingUpdateSites ) {
// Add already known update sites
IMetadataRepositoryManager metaManager = ProvUI.getMetadataRepositoryManager(provisioningUI.getSession());
int visibilityFlags = provisioningUI.getRepositoryTracker().getMetadataRepositoryFlags();
URI[] currentlyEnabled = metaManager.getKnownRepositories(visibilityFlags);
URI[] currentlyDisabled = metaManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_DISABLED | visibilityFlags);
// AviXPlugin.getLog4J().info( "Adding existing enabled update sites..." ); //$NON-NLS-1$
for ( URI uri : currentlyEnabled ) {
MetadataRepositoryElement metadataRepositoryElement = new MetadataRepositoryElement( null, uri, true );
// AviXPlugin.getLog4J().info( MessageFormat.format( "enabled: {0}", uri ) ); //$NON-NLS-1$
repositoryElements.add( metadataRepositoryElement );
}
// AviXPlugin.getLog4J().info( "Adding existing disabled update sites..." ); //$NON-NLS-1$
for ( URI uri : currentlyDisabled ) {
MetadataRepositoryElement metadataRepositoryElement = new MetadataRepositoryElement( null, uri, false );
// AviXPlugin.getLog4J().info( MessageFormat.format( "disabled: {0}", uri ) ); //$NON-NLS-1$
repositoryElements.add( metadataRepositoryElement );
}
}
// AviXPlugin.getLog4J().info( "Adding enabled update sites..." ); //$NON-NLS-1$
if ( enabledUpdateSites != null ) {
for ( URI uri : enabledUpdateSites ) {
MetadataRepositoryElement metadataRepositoryElement = new MetadataRepositoryElement( null, uri, true );
// AviXPlugin.getLog4J().info( MessageFormat.format( "enabled: {0}", uri ) ); //$NON-NLS-1$
repositoryElements.add( metadataRepositoryElement );
}
}
// AviXPlugin.getLog4J().info( "Adding disabled update sites..." ); //$NON-NLS-1$
if ( disabledUpdateSites != null ) {
for ( URI uri : disabledUpdateSites ) {
MetadataRepositoryElement metadataRepositoryElement = new MetadataRepositoryElement( null, uri, false );
// AviXPlugin.getLog4J().info( MessageFormat.format( "disabled: {0}", uri ) ); //$NON-NLS-1$
repositoryElements.add( metadataRepositoryElement );
}
}
// Set the update site list.
MetadataRepositoryElement[] elements = repositoryElements.toArray( new MetadataRepositoryElement[repositoryElements.size()] );
ElementUtils.updateRepositoryUsingElements( provisioningUI, elements, null );
// AviXPlugin.getLog4J().debug( "setUpdateSitesClear END" ); //$NON-NLS-1$
}
Sorry for the commented logging statements, but we have found it very good to log a lot during start of the application to help customers with support issues.
Then we have a help method that helps us filter out only the latest version of all currently non installed IUs available in all enabled update sites. As I am not that familiar with the Query-stuff, it only handles IUGroups and it does not check dependencies of found IUs.
/**
* Tries to dig out all installable IU groups from the currently enabled update sites.<br>
* <br>
* Note: The IUs are not currently tested for dependencies so they may not be able to be installed.
* @param agent
* @param monitor
* @return All {@link IInstallableUnit}s that are found in the enabled update sites that are of type "IUGroup" and are not already installed.
*/
public static List<IInstallableUnit> getNonInstalledInstallableUnits( IProvisioningAgent agent, IProgressMonitor monitor )
{
List<IInstallableUnit> result = Collections.emptyList();
ProvisioningUI provisioningUI = ProvisioningUI.getDefaultUI();
IMetadataRepositoryManager metaManager = ProvUI.getMetadataRepositoryManager(provisioningUI.getSession());
// IQueryResult<IInstallableUnit> queryResultAll = metaManager.query( QueryUtil.createIUAnyQuery(), monitor );
// Set<IInstallableUnit> allInstallableUnits = queryResultAll.toUnmodifiableSet();
// int size = allInstallableUnits.size();
IQueryResult<IInstallableUnit> queryResult = metaManager.query( QueryUtil.createIUGroupQuery(), monitor );
Set<IInstallableUnit> installableUnits = queryResult.toUnmodifiableSet();
List<IInstallableUnit> notInstalledInstallableUnits = new ArrayList<IInstallableUnit>();
for ( IInstallableUnit installableUnit : installableUnits ) {
if (isInstalled( agent, monitor, installableUnit ) ) {
continue;
}
notInstalledInstallableUnits.add( installableUnit );
}
// Filter out only last version of the installable units
Map<String, IInstallableUnit> installableUnitMap = new HashMap<String, IInstallableUnit>();
for ( IInstallableUnit installableUnit : notInstalledInstallableUnits ) {
String id = installableUnit.getId();
Version iuVersion = installableUnit.getVersion();
IInstallableUnit mapInstallableUnit = installableUnitMap.get( id );
if ( mapInstallableUnit != null ) {
Version mapIUVersion = mapInstallableUnit.getVersion();
if ( mapIUVersion.compareTo( iuVersion ) < 0 ) {
installableUnitMap.put( id, installableUnit );
}
}
else {
installableUnitMap.put( id, installableUnit );
}
}
// TODO: Filter out IUs that cannot be installed due to dependencies
if ( !installableUnitMap.isEmpty() ) {
result = new ArrayList<IInstallableUnit>( installableUnitMap.values() );
}
return result;
}
The installation of IUs are handled by another help method
/**
* Installs installable units in a synchronous manner. It is up to the caller to run this in a job if a background job is desired.
* @param agent
* @param monitor
* @param installableUnits
* @return
* @throws OperationCanceledException
*/
public static IStatus installInstallableUnits(IProvisioningAgent agent, IProgressMonitor monitor, List<IInstallableUnit> installableUnits ) throws OperationCanceledException
{
ProvisioningSession session = new ProvisioningSession( agent );
InstallOperation operation = new InstallOperation( session, installableUnits );
SubMonitor sub = SubMonitor.convert( monitor, "Installing new software...", 200 );
IStatus status = operation.resolveModal( sub.newChild( 100 ) );
if ( status.getCode() == UpdateOperation.STATUS_NOTHING_TO_UPDATE ) {
return status;
}
if ( status.getSeverity() == IStatus.CANCEL )
throw new OperationCanceledException();
if ( status.getSeverity() != IStatus.ERROR ) {
// More complex status handling might include showing the user what updates
// are available if there are multiples, differentiating patches vs. updates, etc.
// In this example, we simply update as suggested by the operation.
ProvisioningJob job = operation.getProvisioningJob( null );
status = job.runModal( sub.newChild( 100 ) );
if ( status.getSeverity() == IStatus.CANCEL )
throw new OperationCanceledException();
}
return status;
}
and the update of IUs by yet another help method
/**
* Checks for updates and performs updates synchronously. It is up to the caller to run this in a job if a background job is desired.<br>
* <br>
* Code stolen from the example RCPMail application with prestartupdate in P2.
*
* @param agent
* @param monitor
* @return
* @throws OperationCanceledException
*/
public static IStatus checkForUpdates(IProvisioningAgent agent, IProgressMonitor monitor) throws OperationCanceledException
{
ProvisioningSession session = new ProvisioningSession( agent );
// the default update operation looks for updates to the currently
// running profile, using the default profile root marker. To change
// which installable units are being updated, use the more detailed
// constructors.
UpdateOperation operation = new UpdateOperation( session );
SubMonitor sub = SubMonitor.convert( monitor, "Checking for updates...", 200 );
IStatus status = operation.resolveModal( sub.newChild( 100 ) );
if ( status.getCode() == UpdateOperation.STATUS_NOTHING_TO_UPDATE ) {
return status;
}
if ( status.getSeverity() == IStatus.CANCEL )
throw new OperationCanceledException();
if ( status.getSeverity() != IStatus.ERROR ) {
// More complex status handling might include showing the user what updates
// are available if there are multiples, differentiating patches vs. updates, etc.
// In this example, we simply update as suggested by the operation.
ProvisioningJob job = operation.getProvisioningJob( null );
status = job.runModal( sub.newChild( 100 ) );
if ( status.getSeverity() == IStatus.CANCEL )
throw new OperationCanceledException();
}
return status;
}
The actual code that calls these help methods are in turn called via a startup extension point we have that is called from the WorkbenchAdvisor.preStartup(). The method that does the work look like this for us. There are some stuff that I have left out like the properties code that enables the functionality based on settings, but I am pretty sure you can work around that if you make your own version of the code.
public void preStartup()
{
// Perform update related stuff on application startup.
// - Add update sites from preferences
// - If enabled, perform auto update
// Initialize the update sites. This can add update sites specified in the preferences.
UpdateManager.initializeUpdateSites();
if ( UpdateManager.isInstallOnStartup() || UpdateManager.isUpdateOnStartup() ) {
// The AviXPlugin.bundleContext used below is a public variable in the product plugin activator. It is initialized in AviXPlugin.start( BundleContext context ). Just make it available in your own activator and fix the code.
final IProvisioningAgent agent = (IProvisioningAgent)ServiceHelper.getService( AviXPlugin.bundleContext, IProvisioningAgent.SERVICE_NAME );
if (agent == null) {
// AviXPlugin.getLog4J().warn("No provisioning agent found. Application is not setup to handle automatic installations." ); //$NON-NLS-1$
}
else if ( !UpdateManager.isJustUpdated() ) {
final IRunnableWithProgress runnable = new IRunnableWithProgress() {
public void run( IProgressMonitor monitor ) throws InvocationTargetException, InterruptedException
{
// Check for new things to install.
boolean restart = false;
if ( UpdateManager.isInstallOnStartup() ) {
// AviXPlugin.getLog4J().info("Checking for installable IUs..." ); //$NON-NLS-1$
List<IInstallableUnit> installableUnits = UpdateManager.getNonInstalledInstallableUnits( agent, monitor );
if ( !installableUnits.isEmpty() ) {
IStatus installStatus = UpdateManager.installInstallableUnits( agent, monitor, installableUnits );
if ( installStatus.getCode() == UpdateOperation.STATUS_NOTHING_TO_UPDATE ) {
PlatformUI.getWorkbench().getDisplay().asyncExec( new Runnable() {
public void run()
{
// AviXPlugin.getLog4J().info("No new IUs to install were found." ); //$NON-NLS-1$
// MessageDialog.openInformation( null, "Updates", "No updates were found" );
}
} );
}
else if ( installStatus.getSeverity() != IStatus.ERROR ) {
// AviXPlugin.getLog4J().info("New IUs installed. Restarting workbench." ); //$NON-NLS-1$
UpdateManager.setJustUpdated( true );
restart = true;
}
else {
// AviXPlugin.getLog4J().info("Error occured during install operation: " + installStatus.getMessage() ); //$NON-NLS-1$
// AviXPlugin.getLog4J().info( installStatus );
}
}
}
if ( UpdateManager.isUpdateOnStartup() ) {
// AviXPlugin.getLog4J().info("Checking for updates..." ); //$NON-NLS-1$
IStatus updateStatus = UpdateManager.checkForUpdates( agent, monitor );
if ( updateStatus.getCode() == UpdateOperation.STATUS_NOTHING_TO_UPDATE ) {
PlatformUI.getWorkbench().getDisplay().asyncExec( new Runnable() {
public void run()
{
// AviXPlugin.getLog4J().info("No new IUs to install were found." ); //$NON-NLS-1$
// MessageDialog.openInformation( null, "Updates", "No updates were found" );
}
} );
}
else if ( updateStatus.getSeverity() != IStatus.ERROR ) {
// AviXPlugin.getLog4J().info("Updates installed. Restarting workbench." ); //$NON-NLS-1$
UpdateManager.setJustUpdated( true );
restart = true;
}
else {
// AviXPlugin.getLog4J().info("Error occured during update operation: " + updateStatus.getMessage() ); //$NON-NLS-1$
// AviXPlugin.getLog4J().info( updateStatus );
}
}
if ( restart ) {
// Make sure the restart call is made by the UI thread.
PlatformUI.getWorkbench().getDisplay().asyncExec( new Runnable() {
@Override
public void run()
{
// AviXPlugin.getLog4J().info("Waiting for user input to restart..." ); //$NON-NLS-1$
MessageDialog.openInformation( null, "Updates", "Application will now restart to complete the installation of updates." );
// AviXPlugin.getLog4J().info("Performing restart of workbench." ); //$NON-NLS-1$
PlatformUI.getWorkbench().restart();
}
} );
}
}
};
// Execute in UI thread
Display.getCurrent().asyncExec( new Runnable() {
@Override
public void run()
{
try {
// AviXPlugin.getLog4J().info("Showing progress bar for update check." ); //$NON-NLS-1$
// Gives thread access errors
new ProgressMonitorDialog(null).run(true, true, runnable);
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InterruptedException e) {
}
}
} );
}
else {
UpdateManager.setJustUpdated( false );
// AviXPlugin.getLog4J().info("Do not check for installable IUs or updates this time as application was just restarted after updates/installations were made. Application will check for updates again next time it is started." ); //$NON-NLS-1$
}
}
}
If you got this far I hope it helped you a little.
Edits:
* Fixed a code error in the update site help method
* Added a code comment about AviXPlugin.bundleContext in the preStartup method
* Fixed some obvious spelling errors
[Updated on: Mon, 01 October 2012 17:35] Report message to a moderator
|
|
|
Goto Forum:
Current Time: Thu Apr 18 13:50:18 GMT 2024
Powered by FUDForum. Page generated in 0.04875 seconds
|